Nvfrotran compiler passes arguments per value instead per reference

When compiling the following code the arguments number 7 and furthers are passed per value to the function instead per reference:

    PROGRAM ERR
    IMPLICIT NONE

C
INTEGER4 IND
INTEGER
8 GEO_CALC_ADR, STATUS
C
INTEGER4, PARAMETER :: MT = 2
INTEGER
4
& FIRST_COL_OUT(MT),
& FIRST_LIN_OUT(MT),
& NUM_COLS_OUT(MT),
& NUM_LINS_OUT(MT),
& FIRST_COL_IN(MT),
& FIRST_LIN_IN(MT),
& NUM_COLS_IN(MT),
& NUM_LINS_IN(MT),
& FIRST_COL_DEM(MT),
& FIRST_LIN_DEM(MT),
& NUM_COLS_DEM(MT),
& NUM_LINS_DEM(MT)
C
PRINT*, ‘starting’
FIRST_COL_OUT = 0
FIRST_LIN_OUT = 0
NUM_COLS_OUT = 0
NUM_LINS_OUT = 0
FIRST_COL_IN = 0
FIRST_LIN_IN = 0
NUM_COLS_IN = 0
NUM_LINS_IN = 0
FIRST_COL_DEM = 0
FIRST_LIN_DEM = 0
NUM_COLS_DEM = 0
NUM_LINS_DEM = 0
C
IND = 1
PRINT*,‘Calling’
STATUS = GEO_CALC_ADR (FIRST_COL_OUT(IND),FIRST_LIN_OUT(IND),
& NUM_COLS_OUT(IND),NUM_LINS_OUT(IND),
& FIRST_COL_DEM(IND),FIRST_LIN_DEM(IND),
& NUM_COLS_DEM(IND),NUM_LINS_DEM(IND),
& FIRST_COL_IN(IND),FIRST_LIN_IN(IND),
& NUM_COLS_IN(IND),NUM_LINS_IN(IND))
PRINT*,‘End’
END
C
RECURSIVE INTEGER8 FUNCTION GEO_CALC_ADR (FIRST_COL_OUT,FIRST_LIN_OUT,
& NCOLS_OUT,NLINS_OUT,
& FIRST_COL_DEM,FIRST_LIN_DEM,
& NCOLS_DEM,NLINS_DEM,
& FIRST_COL_IN,FIRST_LIN_IN,
& NCOLS_IN,NLINS_IN)
IMPLICIT NONE
INTEGER
4
& FIRST_COL_OUT,
& FIRST_LIN_OUT,
& NCOLS_OUT,
& NLINS_OUT,
& FIRST_COL_DEM,
& FIRST_LIN_DEM,
& NCOLS_DEM,
& NLINS_DEM,
& FIRST_COL_IN,
& FIRST_LIN_IN,
& NCOLS_IN,
& NLINS_IN
C
PRINT*,‘In Function’
FIRST_COL_OUT = 0
FIRST_LIN_OUT = 0
NCOLS_OUT = 0
NLINS_OUT = 0
FIRST_COL_DEM = 0
FIRST_LIN_DEM = 0
NCOLS_DEM = 0
NLINS_DEM = 0
FIRST_COL_IN = 0
FIRST_LIN_IN = 0
NCOLS_IN = 0
NLINS_IN = 0
C
GEO_CALC_ADR = -1
RETURN
END

Hi Erich.riegler,

How are to determining this? It appears correct to me. For example, if I update the values in GEO_CALC_ADR and then print them in the main routine, they do print the correct values. If the arguments were passed by value, they would not be modified.

% cat ref.f
        PROGRAM ERR
        IMPLICIT NONE
C
        INTEGER*4 IND
        INTEGER*8 GEO_CALC_ADR, STATUS
C
        INTEGER*4, PARAMETER :: MT = 2
        INTEGER*4
     & FIRST_COL_OUT(MT),
     & FIRST_LIN_OUT(MT),
     & NUM_COLS_OUT(MT),
     & NUM_LINS_OUT(MT),
     & FIRST_COL_IN(MT),
     & FIRST_LIN_IN(MT),
     & NUM_COLS_IN(MT),
     & NUM_LINS_IN(MT),
     & FIRST_COL_DEM(MT),
     & FIRST_LIN_DEM(MT),
     & NUM_COLS_DEM(MT),
     & NUM_LINS_DEM(MT)
C
       PRINT *, 'starting'
       FIRST_COL_OUT = 0
       FIRST_LIN_OUT = 0
       NUM_COLS_OUT = 0
       NUM_LINS_OUT = 0
       FIRST_COL_IN = 0
       FIRST_LIN_IN = 0
       NUM_COLS_IN = 0
       NUM_LINS_IN = 0
       FIRST_COL_DEM = 0
       FIRST_LIN_DEM = 0
       NUM_COLS_DEM = 0
       NUM_LINS_DEM = 0
C
       IND = 1
       PRINT*,'Calling'
       STATUS = GEO_CALC_ADR (FIRST_COL_OUT(IND),FIRST_LIN_OUT(IND),
     & NUM_COLS_OUT(IND),NUM_LINS_OUT(IND),
     & FIRST_COL_DEM(IND),FIRST_LIN_DEM(IND),
     & NUM_COLS_DEM(IND),NUM_LINS_DEM(IND),
     & FIRST_COL_IN(IND),FIRST_LIN_IN(IND),
     & NUM_COLS_IN(IND),NUM_LINS_IN(IND))
       print *, FIRST_COL_OUT
       print *, FIRST_LIN_OUT
       print *, NUM_COLS_OUT
       print *, NUM_LINS_OUT
       print *, FIRST_COL_DEM
       print *, FIRST_LIN_DEM
       print *, NUM_COLS_DEM
       print *, NUM_LINS_DEM
       print *, FIRST_COL_IN
       print *, FIRST_LIN_IN
       print *, NUM_COLS_IN
       print *, NUM_LINS_IN
       PRINT*,'End'
       END
C
       RECURSIVE INTEGER*8 FUNCTION GEO_CALC_ADR(FIRST_COL_OUT,
     & FIRST_LIN_OUT,
     & NCOLS_OUT,NLINS_OUT,
     & FIRST_COL_DEM,FIRST_LIN_DEM,
     & NCOLS_DEM,NLINS_DEM,
     & FIRST_COL_IN,FIRST_LIN_IN,
     & NCOLS_IN,NLINS_IN)
       IMPLICIT NONE
       INTEGER*4
     & FIRST_COL_OUT,
     & FIRST_LIN_OUT,
     & NCOLS_OUT,
     & NLINS_OUT,
     & FIRST_COL_DEM,
     & FIRST_LIN_DEM,
     & NCOLS_DEM,
     & NLINS_DEM,
     & FIRST_COL_IN,
     & FIRST_LIN_IN,
     & NCOLS_IN,
     & NLINS_IN
C
       PRINT*,'In Function'
       FIRST_COL_OUT = 1
       FIRST_LIN_OUT = 2
       NCOLS_OUT = 3
       NLINS_OUT = 4
       FIRST_COL_DEM = 5
       FIRST_LIN_DEM = 6
       NCOLS_DEM = 7
       NLINS_DEM = 8
       FIRST_COL_IN = 9
       FIRST_LIN_IN = 1
       NCOLS_IN = 2
       NLINS_IN = 3
C
       GEO_CALC_ADR = -1
       RETURN
       END
% nvfortran ref.f -fast -V22.7 ; a.out
 starting
 Calling
 In Function
            1            0
            2            0
            3            0
            4            0
            5            0
            6            0
            7            0
            8            0
            9            0
            1            0
            2            0
            3            0
 End

-Mat

Hi Mat,

thank you fort he fast reply.

Indeed, if I used the code including the print-statements you inserted it works correctly.

But when I debug the code I extracted (send first) there appears the problem. In fact the code I posted is an extraction from a quite complexer code.

All passed arrays to the function are initialized to 0 in the main program.

image001.png

image002.png

image003.png

Ok, it’s not an issue with passing variables by value, but was a problem with the Dwarf debug information first reported HERE

This issue was fixed in our 22.5 release.

But I am using 22.5 release.

And the problem as described still exists.

image001.jpg

Just checked building the example with 22.5, and it looks correct when I use cuda-gdb. Not sure what accounts for the difference in what you’re seeing.

% nvfortran -V22.5 -g ref.f -o ref.out
% cuda-gdb ref.out
NVIDIA (R) CUDA Debugger
11.7 release
Portions Copyright (C) 2007-2022 NVIDIA Corporation
GNU gdb (GDB) 10.2
Copyright (C) 2021 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "x86_64-pc-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<https://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
    <http://www.gnu.org/software/gdb/documentation/>.

For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from ref.out...
(cuda-gdb) b 38
Breakpoint 1 at 0x40107d: file ref.f, line 38.
(cuda-gdb) run
Starting program: /local/home/mcolgrove/ref.out
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
 starting
 Calling

Breakpoint 1, err () at ref.f:38
38             STATUS = GEO_CALC_ADR (FIRST_COL_OUT(IND),FIRST_LIN_OUT(IND),
(cuda-gdb) s
geo_calc_adr (first_col_out=0, first_lin_out=0, ncols_out=0, nlins_out=0, first_col_dem=0, first_lin_dem=0, ncols_dem=0, nlins_dem=0,
    first_col_in=0, first_lin_in=0, ncols_in=0, nlins_in=0) at ref.f:81
81             PRINT*,'In Function'

For reference, here’s what it looked like when compiled with 22.3:

geo_calc_adr (first_col_out=0, first_lin_out=0, ncols_out=0, nlins_out=0, first_col_dem=0, first_lin_dem=0, ncols_dem=6299920, nlins_dem=6299928,
    first_col_in=6299872, first_lin_in=6299880, ncols_in=6299888, nlins_in=6299896) at ref.f:81
81             PRINT*,'In Function'

I did use version V22.5, but I did not use the command option -V22.5
The expectation was when using the call to the version 22.5 compiler default would be for generating code for this version.
I was not aware that I have explicitly to use the command option.

image001.jpg

You shouldn’t need the -V22.5. This is just a convenience flag to make is easy to switch between compiler versions. I typically use it in my post as a way to show which version I’m using.

Am I understanding correctly that the debugger information is correct after you add “-V22.5”? If so, then it implies that the version in your PATH is not 22.5 and would account for the different behavior.

What’s the output from “nvfortran -V”?