Nvfortran with unlimited polymorphic variables

I’m having issues with unlimited polymorphic variables in Nvfortran 21.7.

I have a declaration such as :

class(*) :: sVec
...

 select type(sVec)                                                                                            |
    type is (PVector_real8)     
       ! Code here
    type is (PVector_real4)     
       ! Code here
   end select

The code compiles, but during linking I get the following:

/home1/gkenway/LAVA_RESEARCH/src/curv/build/nvidia/…/…/solver/residual.F90:804: undefined reference to residualmod__residualsubmod_setturresidualinvec__f03_unl_poly_0____td557_' /home1/gkenway/LAVA_RESEARCH/src/curv/build/nvidia/../../solver/residual.F90:804: undefined reference to residualmod__residualsubmod_setturresidualinvec__f03_unl_poly_0____td557_’

The compiler is making a reference to a symbol that never ever gets created and then the executable won’t link.

Any idea to how to get around this issue?
Thanks,
Gaetan

So it looks like the issue has to do with submodules. The same code in a module doesn’t complain. So just another compiler bug.

Gaetan

Hi Gaetan,

If you can me a reproducing example, I can write up an issue report.

While I don’t see any similar issue reported, it is possible the issue has already been resolved. Hence you might consider updating to the latest release of the NV HPC SDK to check.

-Mat

Hi Mat

I’ll try to make a reproducible example. I did try it on 22.2 after and the same thing happened. I also have a few more compiler bugs I’ll try to get reproducers for as well.

Gaetan

I have a reproducer, although it wasn’t for the original issue, it is related. Turns out select type doesn’t work inside of openMP regions with nvfortran.

module types
type T1
   real :: a
end type T1

type T2
   real :: b
end type T2
contains

  subroutine select_one(T)
    class (*) :: T

    select type(T)
    type is(T1)
       print *,'serial : Type is T1'
    type is (T2)
       print *,'serial : Type is T2'
    class default
       print *,'serial: Failed to get the type'
    end select

    !$omp parallel
    select type(T)
    type is(T1)
       print *,'parallel : Type is T1'
    type is (T2)
       print *,'parallel : Type is T2'
    class default
       print *,'parallel: Failed to get the type'
    end select
    !$omp end parallel

  end subroutine select_one
end module types

program main

  use types
  type(T1) :: a
  type(T2) :: B

  call select_one(a)
  call select_one(B)

end program main

When I compile, I get the following compile error:

PBS r139i0n31:~/bug2> make
nvfortran -mp -O0 -fPIC -g   main.F90 -o bug2
/nobackupp17/gkenway/packages/nvhpc/Linux_x86_64/22.2/compilers/share/llvm/bin/llc: error: /nobackupp17/gkenway/packages/nvhpc/Linux_x86_64/22.2/compilers/share/llvm/bin/llc: /var/tmp/pbs.13244777.pbspl1.nas.nasa.gov/nvfortranFMnbD7OF0Byw.ll:306:27: error: use of undefined value '%.O0000'
        %1 = bitcast [10 x i64]* %.O0000 to i8*, !dbg !105
                                 ^
make: *** [nvidia] Error 2

The very funny thing is that in my actual code, with more variables in the openMP region, the compilation goes through, but then just the select case just doesn’t work and falls through to the default.

Guess it’s time to remove all the advanced features of my code…

Gaetan

Thanks Gaetan. I was able to reproduce the error and have sent a report to engineering (filed as TPR #31647)

Excellent! Thank you very much.

Gaetan