Issue with namelist read

I’m facing a problem with a GPU port related to a reading of a buffer with namelist data. I made a simple example to point to the problem. This simple code fails on pgfortran 20.7

integer :: i,j, a, b
CHARACTER(LEN=132)    :: buff
namelist/nammpp/ i,j
namelist/namctl/ a,b

buff=' /  & nammpp i = 10 j =  4 $ / & namctl a = 5 b = 3 / '

print *, buff
read(buff,nml=nammpp)
print *, i
read(buff,nml=namctl)
print *, a,b
end

pgfortran sample.f90 ; ./a.out
/ & nammpp i = 10 j = 4 $ / & namctl a = 5 b = 3 /
FIO-F-228/namelist read/internal file/end of file reached without finding group.
In source file open1.f90, at line number 9

ifort sample.f90 ; ./a.out
/ & nammpp i = 10 j = 4 $ / & namctl a = 5 b = 3 /
10 4
5 3

After consulting with our Fortran folks here, we believe the program is not standard compliant given:

Fortran 2018 13.11.3.2 paragraph 4: “Successive namelist records are read by namelist input until a slash is encountered; the remainder of the record is ignored.”

Also since each read would start from the beginning of ‘buff’, ifort is presumably skipping over leading characters in the internal input until they arrive at the namelist group name that matches the READ statement. Though we don’t see any language in the standards that would sanction that behavior, if in fact that’s what they’re doing.

Note that gfortran 10.1 does not match ifort either:

% gfortran --version
GNU Fortran (GCC) 10.1.0
Copyright (C) 2020 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

% gfortran test.f90 ; a.out
  /  & nammpp i = 10 j =  4 $ / & namctl a = 5 b = 3 /
  1914315712        5295
  1914317076        5295

However, I have added an RFE (TPR #29067) to see if we can support what appears to be an ifort extension.

-Mat

Thanks MatColgrove,
I made a work around, but it is not the ideal. The citation you made is applied to a namelist, i.e:

read(buff,nml=namctl)

should read from “& namctl” until the first “/”. In my view, the ifort is implementing the standard.

integer :: i,j, a, b, pos
CHARACTER(LEN=80) :: buff
namelist/nammpp/ i,j
namelist/namctl/ a,b

buff=’ / &nammpp i = 10 j = 4 $ / &namctl a = 5 b = 3 / ’
pos=index(buff,’&nammpp’)
read(buff(pos:),nammpp)
print *, i, j
pos=index(buff,’&namctl’)
read(buff(pos:),namctl)
print *, a,b
end

Ok, though our engineers seem to disagree. Do you have any pointers to the Fortran standard which supports your assertion that I can send them?

I review the Fortran 2018 Interpretation Document, you guys seem right. Actually, I did not see a citation to multiple groups in the same namelist. This is implemented externally on PGI, GNU, XLF, and Ifort.

$ cat input.txt
&nammpp
i = 10
j = 4
/
&namctl
a = 5
b = 3
/

$cat open5.f90
integer :: i,j, a, b
namelist/nammpp/ i,j
namelist/namctl/ a,b

open(10, FILE=‘input.txt’)
read(10,nammpp)
print *, i, j
read(10,namctl)
print *, a,b
end

$ ./a.out
10 4
5 3

But with an input.txt without newlines, only ifort gives the desired result.

Hi MatColgrove,

I was in a discussion with the main developers from the project I’m contributing with CUDA Fortran ports and we have the following situation concerning GFORTRAN and PGFORTRAN. I understand the affirmation in the Fortran Interpretation Document, but this case works in all compilers we test, INTEL, GNU, and CRAY. Also, follow strict the document I don’t see how multiple groups in a namelist would work. Using OPEN and READ directly from a file all goes fine, even with PGI.

[bsc99214@p9login1 ~]$ cat open_buff2.f90 
integer :: i,j, a, b
CHARACTER(LEN=132)    :: buff
namelist/nammpp/ i,j
namelist/namctl/ a,b

buff=' &nammpp  i = 10  j =  4 /  &namctl  a = 5  b = 3 /'

!print *, buff
read(buff,nml=nammpp)
print *, i,j
read(buff,nml=namctl)
print *, a,b
end

With GCC

[bsc99214@p9login1 ~]$ gfortran -v
Using built-in specs.
COLLECT_GCC=gfortran
COLLECT_LTO_WRAPPER=/gpfs/apps/POWER9/GCC/10.1.0/bin/../libexec/gcc/ppc64le-redhat-linux/10.1.0/lto-wrapper
Target: ppc64le-redhat-linux
Configured with: ../configure --prefix=/apps/GCC/10.1.0 --enable-bootstrap --enable-shared --enable-threads=posix --enable-checking=release --with-system-zlib --enable-__cxa_atexit --without-system-libunwind --enable-gnu-unique-object --enable-linker-build-id --with-linker-hash-style=gnu --enable-languages=c,c++,objc,obj-c++,fortran,ada,go,lto --enable-plugin --enable-initfini-array --disable-libgcj --with-isl --enable-gnu-indirect-function --enable-secureplt --with-long-double-128 --enable-targets=powerpcle-linux --disable-multilib --with-cpu-64=power9 --with-tune-64=power9 --build=ppc64le-redhat-linux --host=ppc64le-redhat-linux --enable-ld --enable-libstdcxx-allocator=new --disable-libstdcxx-pch --enable-linux-futex --enable-lto --enable-plugin --enable-libada --enable-libssp --disable-libssp --disable-libmudflap --enable-version-specific-runtime-libs --program-suffix=-10.1
Thread model: posix
Supported LTO compression algorithms: zlib
gcc version 10.1.0 (GCC) 
[bsc99214@p9login1 ~]$ gfortran open_buff2.f90 
[bsc99214@p9login1 ~]$ ./a.out 
          10           4
           5           3

With PGFORTRAN

[bsc99214@p9login1 ~]$ pgfortran -V

pgfortran (aka nvfortran) 20.9-0 linuxpower target on Linuxpower 
PGI Compilers and Tools
Copyright (c) 2020, NVIDIA CORPORATION.  All rights reserved.
[bsc99214@p9login1 ~]$ pgfortran open_buff2.f90 
[bsc99214@p9login1 ~]$ ./a.out 
           10            4
FIO-F-228/namelist read/internal file/end of file reached without finding group.
 In source file open_buff2.f90, at line number 11

Also, follow strict the document I don’t see how multiple groups in a namelist would work.
This a pure guess and I have no insight on how other compilers implement it, but it’s probably just happenstance of their implementation. Most likely they just scan the string for the named items and ignore the constraint imposed by the Fortran Standard.

We do have RFE #29067 submitted to engineering requesting that we implement this. While we do strive to match extensions, the decision largely depends on the overall impact such extension would provide, including side effect, how widely used the extension is, if the requested has paid support, and difficulty to implement.