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

At what point during debugging are Functions evaluated?

Chris_H_4
Beginner
1,700 Views

I have some code that calls a passed-in function called YDDZIC inside a loop. For 22 iterations this works fine but on the 23rd it crashes out of the whole program when it hits the END statement of the YDDZIC Function. The table below shows a side-by-side comparison of the local variables on the 22nd (left) and 23rd(right) iterations. The obvious difference here is that BRTS and X_1 are undefined in the 23rd iteration, it is also notable that I5, IBODY0 and IX0 are negative, these are used as array indices.

However when I step through the code (also below) the debugger steps all the way to the END statement before it falls over and I was wondering why it doesn't fail sooner, is it that it actually performs the evaluation when the end statement is reached? That seems unlikely because the debugger needs to determine the intermediate variables values. Any other ideas why it doesn't fall over before reaching the END statement?

 

      ENTRY YDDZID ( XI )

C     Find the envelope spline bay containing XI.
      I = ISEG2

C     Use the spline coefficients to find area slope at XI.
      I5 = IBODY0 + (I-1)*5
      DX = XI - BODY(I5+1)
      DS =            BODY(I5+3) +
     +     DX*( 2.0 * BODY(I5+4) +
     +     DX*  3.0 * BODY(I5+5))

C     Ward function of X-XI
      DX = X(IX0+1) - XI
      Z  = DX*BR
      W  = (A0 + Z*(A1 + Z*A2)) /
     +     (B0 + Z*(B1 + Z*(B2 + Z*(B3 + Z*B4))))

C     Integrand in W&F linear phi' equation
      YDDZID = W*DS

      RETURN
*     ======>

      END

 

<Edit> I put the variables in as a table but they just came out as a list so I have attached an image of the variables</edit>

0 Kudos
27 Replies
jimdempseyatthecove
Honored Contributor III
381 Views

Now that we see XXMADDR I can now explain BODY and X.

BODY and X are effectively Proxies to an arbitrary array that were passed as X_1 to XXMADDR.

Your two calls to XXMADDR are placing into IBODY0 and IX0 integer indexes that can be used to index BODY and X to reach into the corresponding passed in at the time of call to XXMADDR. *** There are (at least) two requirements for this to remain valid:

a) The original arrays passed into XXMADDR must still be valid at the time of the call to YDDZID. From the information provided it appears that this is true.

b) The values you place into IBODY0 and IX0 remain unchanged between the calls to XXMADDR and use in YDDZID. This is a candidate of where the problem "might" lay. Should compiler optimization register-ize IBODY0 and/or IX0, then the indexes determined at the time of call to XXMADDR and use in YDDZID will not be valid. This can be verified by looking at the Dissassembly of code that is known to fail.

Jim Dempsey

0 Kudos
Chris_H_4
Beginner
381 Views

Steve Lionel (Intel) wrote:

You should look closer at the error message - it is rarely wrong.

When you say it is mixed code - what is it mixed with? How are the Fortran routines declared in the other language and what compile options do you use for that language?

I'm sure that the error that is being reported is genuine it's just not in the area of the code that I am currently concerned with, not saying it couldn't have an impact, just trying to take one step at a time. If I get chance I'll dig into it. The Fortran is mixed with PL/I, the Fortran builds 120+ DLLs which are called dynamically via the PL/I.

0 Kudos
Chris_H_4
Beginner
381 Views

jimdempseyatthecove wrote:

Now that we see XXMADDR I can now explain BODY and X.

BODY and X are effectively Proxies to an arbitrary array that were passed as X_1 to XXMADDR.

Your two calls to XXMADDR are placing into IBODY0 and IX0 integer indexes that can be used to index BODY and X to reach into the corresponding passed in at the time of call to XXMADDR. *** There are (at least) two requirements for this to remain valid:

a) The original arrays passed into XXMADDR must still be valid at the time of the call to YDDZID. From the information provided it appears that this is true.

b) The values you place into IBODY0 and IX0 remain unchanged between the calls to XXMADDR and use in YDDZID. This is a candidate of where the problem "might" lay. Should compiler optimization register-ize IBODY0 and/or IX0, then the indexes determined at the time of call to XXMADDR and use in YDDZID will not be valid. This can be verified by looking at the Dissassembly of code that is known to fail.

Jim Dempsey

Thanks Jim, I'll try to track what goes on between setting IBODY0 and IX0 and them being used in YDDZID

 

0 Kudos
Steven_L_Intel1
Employee
381 Views

Does your PL/I expect the calling convention to be STDCALL or C? If you had this working with CVF it might expect STDCALL.

A mismatch in types can lead to subtle data corruption.

0 Kudos
mecej4
Honored Contributor III
381 Views

Visual Age PL/I uses Optlink as the default linkage convention, but for external non/PLI external routines you can specify a function prototype and linkage convention, e.g.,

dcl psum entry(fixed bin(31)) ext('PSUM') options(linkage(cdecl));

which is not all that different from !DIR $ directives. The linkage conventions available are Cdecl, Optlink, Stdcall and System. At one time I had called IMSL routines from PL/I, and had no problems with interfacing.

0 Kudos
Steven_L_Intel1
Employee
381 Views

Ok - that looks fine.

0 Kudos
Chris_H_4
Beginner
381 Views

The CVF uses /iface:cref

0 Kudos
Reply