-
Notifications
You must be signed in to change notification settings - Fork 30
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fparser will potentially read many unrelated and unexpected files. #385
Comments
Wow. Thanks very much for digging into this @hiker. Just to clarify, does fparser actually proceeds to parse any file returned by |
Yes, see one/statement.py, around line 1295:
And then a few lines further down use this information to check the imported (and renamed) symbols with the symbols provided in the module that was just read. This is all done in |
Ah, if it's in |
I just had a look, and it appears that you are right - there seems to be no analysis step in two at all, and can't see it loading any modules (I didn't realise the caller was actually in one in the debugger, I saw only |
When a
use
statement is encountered, fparser will try to find & parse the sources for this module:The constructor of
FortranReaderBase
sets.
as include directory, and the constructor ofFortranFileReader
appends the directory of the parsed file if no explicit include directories are set:The result of this is that whenever a
use
statement is encountered, fparser will read any.f
,.f90
,... file in the current directory (and the directory in which the parsed file is) and run a regexp search to find the module. In my example, I had >300 automatically created .f90 files in my current directory, resulting in a significant slowdown.A quick look indicates that this seems to be used to verify import statements, e.g. make sure if item
x
is imported from a module,x
is indeed exported from the module. Seeclass Use(Statement)
, around line 1295 for details. This is part of theanalyze
phase of fparser, which had the interesting comment in fparser parsefortran.py:I didn't check what else besides import statements will be checked by that analyze phase.
Summary: the way fparser is used in PSyclone results in potentially reading many unexpected (and unrelated) files (all .f/.f90/.. files in the current directory), which can result in a slowdown. LFRic is luckily not badly affected at the moment: when parsing the algorithm layer, an include path is provided by PSyclone (which is the kernel search directory):
parse/utils.py:
This will overwrite the default include search path in fparser (in LFRic this include path is the
.../kernel/
directory).So parsing the.x90
files will only read.f90
files in the.../kernel
directory, and all files that directory are.F90
, so de-facto this will not read any additional files (as long as there are no .f90 kernel files) - the only overhead is someglob
searches for non-existent files.BUT, when parsing a kernel file, which PSyclone does, no include directory is set in
parse/kernel.py
:Therefore the defaults will be used, which is the directory in which the kernel is, and
.
. So for any kernel all .f/.f90/... files in.../kernel
and.
will be searched. Again, since all kernels in LFRic are .F90, no files are found, nothing else is read.So we are mostly fine for now (till LFRic adds kernels with .f90 extension 😁, and/or the build system should have .f90 files in the current directory). Actually, why are the files called F90? As far as I can tell they do not contain preprocessor directives 😁
There is still
parse/lfric_builtins.f90
, which will be read (again) while searching forkernel.mod
while parsing the same file. When building gungho, I had 1762 reads of that file (i.e. reading this file to find modules while this file is being parsed by PSyclone).The text was updated successfully, but these errors were encountered: