Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
29348 Discussions

Workaround for allocatable arrays with NAMELISTs?

gregfi04
Beginner
4,553 Views
Has anyone come up with a good way to use NAMELIST functionality with allocatable arrays? The best I can come up with is to read the values into a fixed-dimension array with NAMELIST and then transcribe them to my dynamically allocated arrays. This is will (obviously) cause problems if the input required is greater than the size of the array that's hard-coded into the program.

What's the reason for preventing the use of ALLOCATED objects with NAMELIST? Is it written that way in the standard?

Thanks,
Greg
0 Kudos
1 Solution
Steven_L_Intel1
Employee
4,553 Views
The restriction is present in Fortran 95, but removed in Fortran 2003. Version 11.1 removes the restriction.

View solution in original post

0 Kudos
15 Replies
Steven_L_Intel1
Employee
4,554 Views
The restriction is present in Fortran 95, but removed in Fortran 2003. Version 11.1 removes the restriction.
0 Kudos
joseph-krahn
New Contributor I
4,553 Views
I think that NAMELISTs were initially compler extensions, using a modification of the common-block construct, and therefore had the same fixed-size restrictions. The design of NAMELISTs are sort of "quick and dirty", and still have many quirks inherited from the old implementations.

I did not know that F2003 allowed allocatable members. The spec still says members "must have shape specified by previous specification statements", but is also somewhat vague.

Joe Krahn
0 Kudos
Steven_L_Intel1
Employee
4,553 Views
NAMELIST started life as an IBM extension in the mid-1970s and was picked up by many vendors, including DEC. (Designing and implementing VAX FORTRAN's NAMELIST run-time support was one of my first big tasks for DEC.) It became standardized as of Fortran 90, though in a form slightly different from IBM's.

Fortran 95 says:

Constraint: A namelist-group-object shall not be an array dummy argument with a nonconstant
bound, a variable with nonconstant character length, an automatic object, a pointer, a
variable of a type that has an ultimate component that is a pointer, or an allocatable
array.

Fortran 2003 says only:

C574 (R553) A namelist-group-object shall not be an assumed-size array.

The text you cite about shape is this:

19 A namelist group object shall either be accessed by use or host association or shall have its type, type
20 parameters, and shape specified by previous specification statements or the procedure heading in the
21 same scoping unit or by the implicit typing rules in effect for the scoping unit. If a namelist group object
22 is typed by the implicit typing rules, its appearance in any subsequent type declaration statement shall
23 confirm the implied type and type parameters.

The "previous specification statements" is a restriction similar to that for variables used in specification expressions such as array bounds and allows a compiler to complete processing of the NAMELIST group member without having to look forward in the source for more declarations.
0 Kudos
roddur
Beginner
4,553 Views
The restriction is present in Fortran 95, but removed in Fortran 2003. Version 11.1 removes the restriction.
Hi Steve,
I am a bit confused. As far as I know, namelist was not a part of f95. So how come the restriction?
0 Kudos
Steven_L_Intel1
Employee
4,553 Views
NAMELIST was part of F90 and thus succeeding revisions of the standard.
0 Kudos
Nikita_Tropin
Novice
4,553 Views

It seems that this is not mentioned in Intel Fortran Compiler User Guide for Windows. I have 11.1 and still have the following in NAMELIST page:

The following variables cannot be specified in a namelist group:

  • An array dummy argument with nonconstant bounds

  • A variable with assumed character length

  • An allocatable array

  • A pointer

  • A variable of a type that has a pointer as an ultimate component

  • A subobject of any of the above objects

0 Kudos
Steven_L_Intel1
Employee
4,553 Views
Yes, I've already mentioned that to the writers.
0 Kudos
Tripp_L_
Beginner
4,553 Views

When I try to use this feature in Intel Visual Fortran compiler 13.0, and have turned on the "enable F2003 Semantics" it gives me the error: "error #5415: Feature not yet implemented: Allocatable or pointer fields require user-defined derived-type I/O procedure". Any suggestions?

0 Kudos
Steven_L_Intel1
Employee
4,553 Views

Your question is a bit different from what this thread was about. Ordinary allocatable arrays can be used in NAMELIST. But if you have a derived type with allocatable or pointer components, the language requires that you have user-defined derived type I/O procedures for the type. This feature was added in compiler version 14.0.

11 • If a list item of derived type in a formatted input/output statement is not processed by a defined
12 input/output procedure, that list item is treated as if all of the components of the list item were specified
13 in the list in component order; those components shall be accessible in the scoping unit containing the
14 input/output statement and shall not be pointers or allocatable.

0 Kudos
John4
Valued Contributor I
4,553 Views

Which means a derived type with allocatable components is not compatible with the namelist feature, am I right?

A parameterized derived type could solve the issue.  Too bad it's a feature nobody seems to want to implement.

 

0 Kudos
Steven_L_Intel1
Employee
4,553 Views

They are compatible if you use derived type I/O procedures.

As for PDTs, we're implementing them -  beta starts soon if you're interested. Watch this forum for the announcement.

0 Kudos
John4
Valued Contributor I
4,553 Views

I apologize in advance if I'm bothering too much, but I still fail to see how to make namelists work with allocatable components.  In the following example (which ifort compiles just fine), what should be added to address the "!FIXME:" lines?

module mymod

    implicit none
    private
    save

    type, public :: mytype
        character(260), allocatable :: filelist(:)
    contains
        procedure, private :: mytype_write_nml
        generic :: read(formatted) => mytype_write_nml
    end type

contains
    !--------------------------------------------------------------------------
    subroutine mytype_write_nml(dtv, unit, iotype, v_list, iostat, iomsg)
        class(mytype) , INTENT(INOUT) :: dtv
        integer, intent(in) :: unit
        character (len=*), intent(in) :: iotype
        integer, intent(in) :: v_list(:)
        integer, intent(out) :: iostat
        character (len=*), intent(inout) :: iomsg

    continue
        iostat = 0
        select case (iotype)
            case ('NAMELIST')
                if (ALLOCATED(dtv%filelist)) then
                    !FIXME: what should go here?
                else
                    iostat = 1
                    iomsg = 'filelist not allocated'
                endif
        end select
    end subroutine

end module mymod

use mymod
use iso_fortran_env

implicit none

integer :: tmp_unit, ios
character(260) :: msg
type(mytype) :: t

namelist / NML_INPUT /t

allocate (t%filelist(100))

t%filelist = ''

open (NEWUNIT = tmp_unit, FILE = 'input.txt', STATUS = 'OLD', &
      ACCESS = 'SEQUENTIAL', ACTION ='READ', RECL = 512, IOSTAT = ios, &
      IOMSG = msg)
    if (ios /= 0) then
        write (ERROR_UNIT, '(1X,"ERRORS:"/A)') TRIM(msg)
        stop -1
    endif

    !FIXME: FMT= is not allowed, so what do I need here?
    read (tmp_unit, NML_INPUT, IOSTAT = ios, IOMSG = msg)
close (tmp_unit)

if (ios /= 0) then
    write (ERROR_UNIT, '(1X,"ERRORS:"/A)') TRIM(msg)
    stop -1
endif

write (OUTPUT_UNIT, '(1X,"There are ",I0," files considered")') &
    COUNT (t%filelist /= '')

end


 

0 Kudos
IanH
Honored Contributor III
4,553 Views

You need to decide on the formatted representation of the derived type, and then write the appropriate procedures to implement reading (and presumably writing) using formatted read (and write) statements.

(Your procedure name doesn't really line up with the name of the binding that it is associated with.)

An example attached.  If Dr Fortran is reading... the commented out ###A and ###B appear to show a problem with the handling of allocatable components around structure constructors, and perhaps simple assignment to a allocatable component respectively

(My chosen format isn't particularly nice or robust - but this should give you the idea.)

0 Kudos
John4
Valued Contributor I
4,553 Views

IanH wrote:

You need to decide on the formatted representation of the derived type, and then write the appropriate procedures to implement reading (and presumably writing) using formatted read (and write) statements.

(Your procedure name doesn't really line up with the name of the binding that it is associated with.)

An example attached.  If Dr Fortran is reading... the commented out ###A and ###B appear to show a problem with the handling of allocatable components around structure constructors, and perhaps simple assignment to a allocatable component respectively

(My chosen format isn't particularly nice or robust - but this should give you the idea.)

Sorry, I meant, "mytype_read_nml", although it doesn't really matter (since the INTENT for the first argument is right).

So, according to your code, it can be done, but not in the expected way. The main benefit of the NAMELIST feature is in the names and the comments, which is the part I couldn't figure out when it came to reading .  All the DT write seems to be doing is prefixing the data with "&NML_INPUT T =" and adding / at the end.

In your code, adding DELIM='APOSTROPHE' to the first OPEN statement doesn't seem to have any effect.

I added a component n to your example (see attached), in order to store the size of the array, and modified accordingly.  Trying to read the following file doesn't work:

 &NML_INPUT
 T%N = 3,
 !The first file is for de dimensions of the problem
 T%FILELIST(1) = './dimensions.dat',

 !The second file is for the actual data
 T%FILELIST(2) = './data.dat',

 The third file is for the results
 T%FILELIST(3) = './results.out'
 /

I get "invalid reference to variable in NAMELIST input, unit -130, file /home/jwm/input.txt, line 2, position 6".

And the mix of structure constructors with array seems to be the #1 issue these days ---when I'm lucky, in some of my code I get it to work in debug mode, but not when I switch to release.

0 Kudos
Steven_L_Intel1
Employee
4,553 Views

I think we have a bug in our implementation of this - the developers are looking at it now.

0 Kudos
Reply