Nvfortran compile issues with UDDTIO

Hello,

We are trying to add UDDTIO to our MAS ( MAS/src at main · predsci/MAS · GitHub ) code. Below, I have included a small reproducing example that demonstrates the issue we are encountering.

When compiling with NVFORTRAN, we receive the following errors:

NVFORTRAN-S-0084-Illegal use of symbol r_profile (test_heatsource_uddtio.f90: 65)

NVFORTRAN-S-0084-Illegal use of symbol r_profile (test_heatsource_uddtio.f90: 65)

NVFORTRAN-S-0084-Illegal use of symbol r_profile (test_heatsource_uddtio.f90: 65)

NVFORTRAN-S-0084-Illegal use of symbol r_profile (test_heatsource_uddtio.f90: 65)

0 inform, 0 warnings, 4 severes, 0 fatal for test_heatsource_uddtio

The code compiles and runs correctly with gfortran, so we are unsure whether we are using UDDTIO incorrectly or if this may be a compiler-specific issue.

Any guidance or clarification would be greatly appreciated.

Best,

Miko Stulajter

Compile:
nvfortran -O3 test_heatsource_uddtio.f90 -o test_heatsource_uddtio

Run:

./test

Input file:

&test_nml
  heatsource(2)%r_profile%active = .true.
/

Fortran code:

module profile_def
  implicit none

  type :: profile
    logical :: active=.false.
    real :: f(3)=1.0
    real :: x(2)=(/-1.e20,1.e20/)
    real :: w(2)=1.0
  end type

  interface read(formatted)
    module procedure read_profile_formatted
  end interface

  interface write(formatted)
    module procedure write_profile_formatted
  end interface

contains

  subroutine read_profile_formatted (dtv, unit, iotype, v_list, iostat, iomsg)
    class(profile), intent(inout) :: dtv
    integer, intent(in) :: unit
    character(*), intent(in) :: iotype
    integer, intent(in) :: v_list(:)
    integer, intent(out) :: iostat
    character(*), intent(inout) :: iomsg
    iostat = 0
    iomsg = ' '
    read (unit, *, iostat=iostat, iomsg=iomsg) dtv%active, dtv%f, dtv%x, dtv%w
  end subroutine read_profile_formatted

  subroutine write_profile_formatted (dtv, unit, iotype, v_list, iostat, iomsg)
    class(profile), intent(in) :: dtv
    integer, intent(in) :: unit
    character(*), intent(in) :: iotype
    integer, intent(in) :: v_list(:)
    integer, intent(out) :: iostat
    character(*), intent(inout) :: iomsg
    iostat = 0
    iomsg = ' '
    write (unit, *, iostat=iostat, iomsg=iomsg) dtv%active, dtv%f, dtv%x, dtv%w
  end subroutine write_profile_formatted

end module

module heat_source_module
  use profile_def
  implicit none

  type :: heat_source
    type(profile) :: r_profile
  end type

  type(heat_source), dimension(2) :: heatsource

end module

program test_heatsource_uddtio
  use heat_source_module
  implicit none

  integer :: iostat
  character(256) :: iomsg
  namelist /test_nml/ heatsource

  open(unit=10, file='test_input.in', status='old', iostat=iostat)
  read(unit=10, nml=test_nml, iostat=iostat, iomsg=iomsg)
  close(unit=10)

  open(unit=11, file='test_output.out', status='replace', iostat=iostat)
  write(unit=11, nml=test_nml, iostat=iostat, iomsg=iomsg)
  close(unit=11)

end program

Hi Miko,

I’m not too familiar with UDDTIO myself, so not sure if this is a compiler bug, unsupported feature, or an issue with the code. The person I normally ask these types of question is out for the holidays, so don’t have an answer.

Though given the code works with gfortran and our upcoming LLVM based nvfortran, I’m leaning towards compiler issue or unsupported feature. I filed a report, TPR #38094, and sent it to engineering.

Once I hear back, I’ll let you know.

-Mat

Hi Miko,

Engineering let me know that this one will be difficult to get to work in our current PGI based nvfortran so we’ll need to wait for the LLVM base nvfortran’s release.

However, then did provide a work around by creating wrappers for the I/O as shown in the following example:

module profile_def
  implicit none

  type :: profile
    logical :: active=.false.
    real :: f(3)=1.0
    real :: x(2)=(/-1.e20,1.e20/)
    real :: w(2)=1.0
    contains
  end type

  type :: heat_source
    type(profile) :: r_profile
  end type


  interface read(formatted)
    module procedure read_profile_formatted
    module procedure read_heat_source_formatted
  end interface

  interface write(formatted)
    module procedure write_profile_formatted
    module procedure write_heat_source_formatted
  end interface

contains

  subroutine read_profile_formatted (dtv, unit, iotype, v_list, iostat, iomsg)
    class(profile), intent(inout) :: dtv
    integer, intent(in) :: unit
    character(*), intent(in) :: iotype
    integer, intent(in) :: v_list(:)
    integer, intent(out) :: iostat
    character(*), intent(inout) :: iomsg
    iostat = 0
    iomsg = ' '
    read (unit, *, iostat=iostat, iomsg=iomsg) dtv%active, dtv%f, dtv%x, dtv%w
  end subroutine read_profile_formatted

  subroutine write_profile_formatted (dtv, unit, iotype, v_list, iostat, iomsg)
    class(profile), intent(in) :: dtv
    integer, intent(in) :: unit
    character(*), intent(in) :: iotype
    integer, intent(in) :: v_list(:)
    integer, intent(out) :: iostat
    character(*), intent(inout) :: iomsg
    iostat = 0
    iomsg = ' '
    write (unit, *, iostat=iostat, iomsg=iomsg) dtv%active, dtv%f, dtv%x, dtv%w
  end subroutine write_profile_formatted

  subroutine read_heat_source_formatted (dtv, unit, iotype, v_list, iostat, iomsg)
    class(heat_source), intent(inout) :: dtv
    integer, intent(in) :: unit
    character(*), intent(in) :: iotype
    integer, intent(in) :: v_list(:)
    integer, intent(out) :: iostat
    character(*), intent(inout) :: iomsg
    call read_profile_formatted(dtv%r_profile, unit, iotype, v_list, iostat, iomsg)
  end subroutine read_heat_source_formatted

  subroutine write_heat_source_formatted (dtv, unit, iotype, v_list, iostat, iomsg)
    class(heat_source), intent(in) :: dtv
    integer, intent(in) :: unit
    character(*), intent(in) :: iotype
    integer, intent(in) :: v_list(:)
    integer, intent(out) :: iostat
    character(*), intent(inout) :: iomsg
    call write_profile_formatted(dtv%r_profile, unit, iotype, v_list, iostat, iomsg)
  end subroutine write_heat_source_formatted
end module

module heat_source_module
  use profile_def
  implicit none

!  type :: heat_source
!    type(profile) :: r_profile
!  end type

  type(heat_source), dimension(2) :: heatsource

end module

program test_heatsource_uddtio
  use heat_source_module
  implicit none

  integer :: iostat
  character(256) :: iomsg
  namelist /test_nml/ heatsource

  open(unit=10, file='test_input.in', status='old', iostat=iostat)
  read(unit=10, nml=test_nml, iostat=iostat, iomsg=iomsg)
  close(unit=10)

  open(unit=11, file='test_output.out', status='replace', iostat=iostat)
  write(unit=11, nml=test_nml, iostat=iostat, iomsg=iomsg)
  close(unit=11)

end program

-Mat