Issues with nvfortran and C_F_PROCPOINTER / c_funloc

Dear all,
I am reporting a couple of “issues” related to the nvidia/portalan compiler. The first is related somehow to the following pointer conversion:

call C_F_PROCPOINTER(c_funloc(fin), f)

Indeed a bit hacky, the fin is a fortran function. Still the same code works properly using the GNU compiler. The code is the CAMB one ( GitHub - cmbant/CAMB: Code for Anisotropies in the Microwave Background ) and here my local repos where I am using some quick workaround, just duplicating the code ( https://github.com/lstorchi/CAMBand GitHub - lstorchi/forutils: Fortran 2008 utility functions and reusable classes ) that considering the final goal, i.e,. to quickly test GPU, it is right now reasonable.

Second issue is a “0: UBOUND: arg not associated with array” error, it is coming from the following:

if (.not. allocated(ajl) .or. any(ubound(ajl) < [num_xx, max_ix])) then

If allocated(ajl) is false I get the error, simply splitting the clausole with an else if solve the issue, but again the same code it is working using the gfortran compiler.

Thanks for any suggestions/comments
Loriano

Hi Loriano,

Can you please provide more details on what error you’re getting with the first case? A compile error or a runtime error?

I did try to build CAMB, but the pip install failed for me and it appears to be setup for gfortran. In case it’s compile time error, I did try compiling MathUtils.f90 from the command line, but it fails due to a missing module “MiscUtils”. I grep’d all the file in CAMB but don’t see this module defined. Presumably it’s in one of the dependencies pip was supposed to install.

If you could provide a reproducing example, that would be appreciated.

For the second issue, this is an issue with the code. Unlike C, Fortran does not enforce left-to-right evaluation nor short circuiting, so you can’t rely on this behavior. Better to split this into multiple if statement so the code is portable across other compilers.

-Mat

Dear Mat
thanks indeed for your quick reply, tomorrow I will give you all the needed information. In the meanwhile you can have a look at the CAMB issue I am also using to report all the details:

still I will surely try to give a reference to a specific tag to be easily used to reproduce the problem

Dear Mat

As said here all you need to reproduce the issue, I tested both nvfortran 25.1-0 and 23.5-0:

$ git clone git@github.com:lstorchi/CAMB.git
$ cd CAMB/
$ git checkout issuet2
$ git clone git@github.com:lstorchi/forutils.git
$ cd forutils/
$ git checkout gpuport
$ cd …/fortran/
$ make

Then using the attached
param.txt (2.1 KB)
input file just run it (I renamed it as params.txt to upload it):

$ ./camb params.ini

Here the back tracking, it is basically returning a 0x0 address:

Program received signal SIGSEGV, Segmentation fault.
0x00000000004edc62 in mathutils::integrate_romberg (obj=…, fin=4.3552442222233553e-150, a=0, b=1, tol=3.6787944117144237e-05, maxit=<error reading variable: Cannot access memory at address 0x0>, minsteps=<error reading variable: Cannot access memory at address 0x0>, abs_tol=<error reading variable: Cannot access memory at address 0x0>) at …/MathUtils.f90:47
47 gmax=h*(f(obj,a)+f(obj,b))
(gdb) bt
#0 0x00000000004edc62 in mathutils::integrate_romberg (obj=…, fin=4.3552442222233553e-150, a=0, b=1,
tol=3.6787944117144237e-05, maxit=<error reading variable: Cannot access memory at address 0x0>,
minsteps=<error reading variable: Cannot access memory at address 0x0>,
abs_tol=<error reading variable: Cannot access memory at address 0x0>) at …/MathUtils.f90:47
#1 0x000000000043375c in results::cambdata_deltaphysicaltimegyr (this=…, a1=0, a2=1,
in_tol=<error reading variable: Cannot access memory at address 0x0>) at …/results.f90:1261
#2 0x00000000004425f2 in results::thermo_init (this=…, state=…, taumin=9.5238099563149024e-05)
at …/results.f90:2760
#3 0x00000000004da845 in cambmain::initvars (state=…) at …/cmbmain.f90:816
#4 0x00000000004d401e in cambmain::cmbmain () at …/cmbmain.f90:145
#5 0x000000000040a6bf in camb::camb_getresults (outdata=…, params=…,
error=<error reading variable: Cannot access memory at address 0x0>,
onlytransfer=<error reading variable: Cannot access memory at address 0x0>,
onlytimesources=<error reading variable: Cannot access memory at address 0x0>) at …/camb.f90:109
#6 0x000000000041d40d in camb::camb_runfromini (ini=…, inputfile=…, errmsg=…) at …/camb.f90:1065
#7 0x000000000042128d in camb::camb_commandlinerun (inputfile=…) at …/camb.f90:1158
#8 0x0000000000404ef2 in driver () at …/inidriver.f90:15

There is also another issue related to the definition of the “dtauda” function but we will discuss this after that one.

Thanks indeed

Hi Loriano,

I talked with engineering. This issue is likely related to a known limitation where:

nvfortran does not support internal procedures as actual arguments to dummy arguments declared external.

Unfortunately the typical work around for this, i.e. adding an interface for the argument, didn’t work, so there’s more too this one, but highly likely related to this limitation. I added a problem report, TPR#37184.

We are in the process of replacing the current nvfortran with a new flang based Fortran compiler being jointly developed with the LLVM community. While it’s still in development, I was able to successfully build and run your code with this new compiler.

To set your expectations, unless the fix for TPR#37184 is easy and given it’s related to known limitation, engineering may not fix the error in the current nvfortran. In this case, we’ll likely need to wait for the new flang based compiler to be released, which I don’t have an ETA for.

-Mat

Dear Mat
Thanks for the quick feedback. As I said I am currently using a simple and quick workaround , the dirtiest possible as I am simply duplicating the code .Indeed, I prefer much more C/C++ and Python, but there is still some code written in Fortran, thus somehow I am forced to deal with them, so I am looking forward for the new nvidia compiler.

Hi Loriano,

Engineering wanted me to let you know that they found another work around, though it may not be portable to other compilers.

In function Integrate_Romberg() in MathUtils.f90:

Replace call C_F_PROCPOINTER(c_funloc(fin), f) with:

f ⇒ fin