Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
28384 Discussions

Compiler ASSUME directive arguments

ereisch
New Contributor II
881 Views

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)?

Thanks

0 Kudos
1 Solution
ereisch
New Contributor II
652 Views

UPDATE: The ASSUME directive is a strict-enforced requirement, that will result in code elimination if it feels it can do so without violating the assumption.

Example:

!DIR$ ASSUME (N .LT. 5)
IF ( N .GE. 5 ) THEN
  <SOMETHING>
END IF​

In the above, the code for <SOMETHING> will not be emitted by the compiler.  See this and the updated documentation page for ASSUME.

The LOOP_COUNT directive has no such behavior; it is simply a hint to the optimizer.

View solution in original post

0 Kudos
6 Replies
ereisch
New Contributor II
881 Views

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.

0 Kudos
Steve_Lionel
Honored Contributor III
881 Views

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.

0 Kudos
ereisch
New Contributor II
881 Views

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?

Thanks

0 Kudos
jimdempseyatthecove
Honored Contributor III
639 Views

Somewhere at start:

 

    if(NITEMS > 100) stop "bug"

 

elsewhere:

 

   do i=1,max(nitems,100) ! nitems known not to exceed 100

 

 

Note, using FPP you can

 

   #define NITEMS max(nitems, 100)

 

Jim Dempsey

 

 

0 Kudos
Steve_Lionel
Honored Contributor III
881 Views

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.)

0 Kudos
ereisch
New Contributor II
653 Views

UPDATE: The ASSUME directive is a strict-enforced requirement, that will result in code elimination if it feels it can do so without violating the assumption.

Example:

!DIR$ ASSUME (N .LT. 5)
IF ( N .GE. 5 ) THEN
  <SOMETHING>
END IF​

In the above, the code for <SOMETHING> will not be emitted by the compiler.  See this and the updated documentation page for ASSUME.

The LOOP_COUNT directive has no such behavior; it is simply a hint to the optimizer.

0 Kudos
Reply