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

How change fortran associate target?

S__MPay
Beginner
1,074 Views

Say I want to define an associate s_yNext like this:

ascFS: associate ( s_yNext => darMatData(i) )

When i is increased how do I update the target of s_yNext ?

Actually the original code is:

s_yNext => status%darMatData(i, MATDATA_P1STRS+status%curveSection(i))

I want to avoid that long right side part by using associate. otherwise I could simply use s_yNext => darMatData

0 Kudos
1 Solution
jimdempseyatthecove
Honored Contributor III
1,074 Views

Fortran does (did?) have a feature called Statement Functions (look it up). Unfortunately, this feature is identified as obsolescent in Fortran 2008, 2003, and 95.

This leave you with coding as Arjen suggests,... or
using the Fortran PreProcessor and use a #define macro.

#define s_yNext status%darMatData(i, MATDATA_P1STRS+status%curveSection(i))

Jim Dempsey

View solution in original post

0 Kudos
8 Replies
Arjen_Markus
Honored Contributor I
1,074 Views

Once the associate statement has been run, the associations are fixed (unless I misunderstand it :)), but nothing prevents you from using associate in a loop:

do i =1,size(status%darMatdata)
     associate( s_yNext => status%darMatData(i, MATDATA_P1STRS+status%curveSection(i))
     ... do the right thing
  end associate
enddo 
0 Kudos
S__MPay
Beginner
1,074 Views

Thanks Arjen; Actually the value of status%curveSection(i) is also changed under specific circumstance.

Arjen Markus wrote:

Once the associate statement has been run, the associations are fixed (unless I misunderstand it :)), but nothing prevents you from using associate in a loop:

do i =1,size(status%darMatdata)
     associate( s_yNext => status%darMatData(i, MATDATA_P1STRS+status%curveSection(i))
     ... do the right thing
  end associate
enddo 

0 Kudos
jimdempseyatthecove
Honored Contributor III
1,075 Views

Fortran does (did?) have a feature called Statement Functions (look it up). Unfortunately, this feature is identified as obsolescent in Fortran 2008, 2003, and 95.

This leave you with coding as Arjen suggests,... or
using the Fortran PreProcessor and use a #define macro.

#define s_yNext status%darMatData(i, MATDATA_P1STRS+status%curveSection(i))

Jim Dempsey

0 Kudos
Arjen_Markus
Honored Contributor I
1,074 Views

You can still use statement functions, but there have been ample problems with them and internal routines are a much better alternative.

That said, even if you use a statement function or an internal function, then you can not change the value - they are functions after all.

An alternative might be to use a pointer variable: s_yNext => ... and update the pointer whenever status%curveSection(i) changes. A bit tricky. Perhaps the macro is the "best" option ;).

0 Kudos
jimdempseyatthecove
Honored Contributor III
1,074 Views

In the OP's case, S wanted a single token without an (argument, list). While a contained function could have access to MATDATA_P1STRS and status, it would not necessarily have the correct access to i. Note, in test code it does appear to access an indexing variable correctly (as indexed), but the standard states that the memory location of a loop control variable need only to be updated at the exit of the loop (when registerized). Therefore necessitating passing i as an argument: s_yNext(i)

Which is a code change and somewhat grammatically misleading (is the function to return i+1'th entry?).

>>but there have been ample problems

Coding is fraught with ample problems.

Jim Dempsey

0 Kudos
IanH
Honored Contributor III
1,074 Views

jimdempseyatthecove wrote:
...While a contained function could have access to MATDATA_P1STRS and status, it would not necessarily have the correct access to i. Note, in test code it does appear to access an indexing variable correctly (as indexed), but the standard states that the memory location of a loop control variable need only to be updated at the exit of the loop (when registerized). Therefore necessitating passing i as an argument: s_yNext(i)

There is no such statement in the standard. 

An internal procedure (or associate statement, or whatever) that access a loop control index by host association will access the value of the index at the time the procedure is invoked.

0 Kudos
jimdempseyatthecove
Honored Contributor III
1,074 Views

>>There is no such statement in the standard

Not explicitly, perhaps implicitly. Why then the admonishment:

The DO variable must not be redefined or become undefined during execution of the DO range.

The DO loop is controlled by an iteration counter, and not a comparison of the DO variable with a limit. So why then "must not be redefined"?

Jim Dempsey

0 Kudos
Steve_Lionel
Honored Contributor III
1,074 Views

The standard certainly has no wording about memory location. But the prohibition against redefining the loop variable inside the loop allows an implementation to use a counted loop (some architectures have special instructions for that) rather than testing the value each time. The standard DOES say that the number of iterations is determined at the start of the loop processing.

That said, some compilers (I know the DEC compilers and maybe ifort) could tell when it was possible the program, contrary to the standard, assigned to the LCV and switched from a counted to a tested loop. A program that does this is not standard-conforming.

0 Kudos
Reply