Is there a way to pass hints about structure members to the compiler? Example:
STRUCTURE /FOO/ INTEGER*4 NITEMS RECORD/BAR/ ITEM(100) INTEGER*4 BLAH1 REAL*4 BLAH2 END STRUCTURE RECORD /FOO/ MYARR(20)
Is it possible to tell the compiler that any instance of NITEMS will always be less than 100? Or would I have to do ASSUME on MYARR(1)%NITEMS, and if so, would that implicitly apply to all instances of MYARR (not just 1)?
While we're on the subject, it appears as though the !DIR$ ASSUME directive is only allowed in the code section of a file; in other words, after all variables have been defined. If this doesn't break the algorithm or standard, it would be super convenient if this requirement were relaxed such that assumptions pertaining to certain variables (like NITEMS above) can be co-located with the variable definition, which might be in an INCLUDE file. We have hundreds of such variables and thousands of instantiations of them, but if we always know there will be certain constraints on it, it would help if we could just put the ASSUME line immediately after the variable definition in the INCLUDE file. That would also alleviate the problem in the original post, in that it wouldn't matter if the variable was part of a structure, an array, or otherwise; the hint will still apply to all references/instantiations of the variable.
If I understand the way ASSUME works, you want the expression to use a variable that is used in a loop count or array index. This isn't the same as an assertion or a precondition, which seems to be what you want. ASSUME's purpose is to aid optimization by giving the compiler more information than it might see otherwise.
Actually, the variables I was listing are almost exclusively used in loop counts. Usually loops will be of the form DO I = 1, NITEMS, so by "globally" hinting that NITEMS will never exceed 100, you are (in our case) hinting hundreds of DO loops across nearly as many files.
A more real-world example would be something like NFFT in a signal processing program; if it is defined in a common block and you know that NFFT will always be of a form 2**N, or will always be one of: (32, 64, 128, 256), being able to tell the compiler this is true everywhere this is used (including in loops) via hinting this to the compiler at the same location it is defined would be beneficial.
And to your first remark, there doesn't seem to be much documentation on what kind of hints for ASSUME "make sense". I know they need to evaluate to a logical TRUE or FALSE, but it is not always intuitive regarding what hints the optimizer will use, such as alignments (which was the example given in the 19.0 documentation) or such. For example, if I specify "!DIR$ ASSUME (NITEMS .LE. 100)" immediately after the variable definitions, is that handled by the optimizer in the same way as explicitly specifying "!DIR$ LOOP COUNT MAX=100" at each loop where the upper limit is NITEMS?
Also, it isn't immediately clear (to me) from the docs that if an ASSUME directive is violated at run-time, will it cause undefined behavior, or simply less efficient execution? The documentation suggests you may raise an assertion of a certain ASSUME is not valid, but if you don't enable this checking, does the code still "work" if it isn't? Example: If 99.9% of the cases a statement will evaluate to TRUE, you may want to tell the compiler this so it can order things more efficiently. But for the 0.1% of cases where it isn't, is there a [valid] alternate (albeit less efficient) code path generated?
Yes, the code still works. My understanding is that ASSUME and LOOP_COUNT affect optimization only. I'm not aware that alternate code paths are generated.
Optimization reports and/or Intel VTune Amplifier can make recommendations for directives to add (or at least they could when I last used them a few years ago.)