Workaround for allocatable arrays with NAMELISTs?

Workaround for allocatable arrays with NAMELISTs?

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

16 posts / 0 new
Last post
For more complete information about compiler optimizations, see our Optimization Notice.
Best Reply

The restriction is present in Fortran 95, but removed in Fortran 2003. Version 11.1 removes the restriction.

Steve - Intel Developer Support

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

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.

Steve - Intel Developer Support

Quoting - Steve Lionel (Intel)
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?

NAMELIST was part of F90 and thus succeeding revisions of the standard.

Steve - Intel Developer Support

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

Yes, I've already mentioned that to the writers.

Steve - Intel Developer Support

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?

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.

Steve - Intel Developer Support

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.

 

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.

Steve - Intel Developer Support

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

 

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.)

Attachments: 

Quote:

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.

Attachments: 

AttachmentSize
Download namelist2.f901.33 KB
Download input_1.txt257 bytes

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

Steve - Intel Developer Support

Leave a Comment

Please sign in to add a comment. Not a member? Join today