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

Strange behavior of vlist argument in UDTIO

johnyb_
New Contributor I
336 Views

I have yet another problem with UDTIO. In my read procedure, I want to use the vlist argument to pass the length of a temporary character string to be used internally in the procedure. However, when I read more than one DT in a single format statement, the vlist for the second and following I/O items behaves strangely.

In my example I use different vlist numbesr to illustrate the problem and don't actually use it. In my real code vlist is used to create a temporary string and is always 1500. This results in the string for the first I/O item to be 1500 characters long, but the string for the next item is already 15 million characters. And as I use vlist also to construct a format for reading that string, instead of A1500 I get A15001500.

module m_test
    type t1
        integer :: a
      contains
        procedure, private :: r_t1
        generic :: read(formatted) => r_t1
    end type

   
    contains
        subroutine r_t1(dtv, unit, iotype, vlist, iostat, iomsg)
            class(t1),          intent(inout)   :: dtv
            integer,            intent(in)      :: unit
            character(len=*),   intent(in)      :: iotype
            integer,            intent(in)      :: vlist(:)
            integer,            intent(out)     :: iostat
            character(len=*),   intent(inout)   :: iomsg
            print *, "vlist(1)    :", vlist(1)
            print *, "entire vlist:", vlist
            read(unit, fmt="(i4)", iostat=iostat, iomsg=iomsg) dtv%a
        end subroutine
end module

program test
    use m_test
    
    character(len=:), allocatable :: str
    type(t1) :: x,y,z
    str="1111222233334444555556666"
    read(str, fmt="(DT(7),DT(8),DT(9))") x,y,z
    print *, x%a, y%a, z%a
end program
C:\TEMP>ifort test.f90 /standard-semantics
Intel(R) Visual Fortran Intel(R) 64 Compiler XE for applications running on Intel(R) 64, Version 15.0.4.221 Build 20150407
Copyright (C) 1985-2015 Intel Corporation.  All rights reserved.

Microsoft (R) Incremental Linker Version 11.00.61030.0
Copyright (C) Microsoft Corporation.  All rights reserved.

-out:test.exe
-subsystem:console
test.obj

C:\TEMP>test
 vlist(1)    : 7
 entire vlist: 7
 vlist(1)    : 77
 entire vlist: 77 8
 vlist(1)    : 77
 entire vlist: 77 87 8 9
 1111 2222 3333

C:\TEMP>

My temporary workaround will be to use DT'1500' instead of DT(1500) in my code.

 

 

0 Kudos
6 Replies
johnyb_
New Contributor I
336 Views

trying some variations, if I use two different types, each with it's own read procedure, their vlist get concatenated also:

module m_test
    type t1
        integer :: a
      contains
        procedure, private :: r_t1
        generic :: read(formatted) => r_t1
    end type
    
    type t2
        integer :: a
      contains
        procedure, private :: r_t2
        generic :: read(formatted) => r_t2
    end type
        
    contains
        subroutine r_t1(dtv, unit, iotype, vlist, iostat, iomsg)
            class(t1),          intent(inout)   :: dtv
            integer,            intent(in)      :: unit
            character(len=*),   intent(in)      :: iotype
            integer,            intent(in)      :: vlist(:)
            integer,            intent(out)     :: iostat
            character(len=*),   intent(inout)   :: iomsg
            print *, "vlist(1)     :", vlist(1)
            print *, "entire vlist:", vlist
            read(unit, fmt="(i4)", iostat=iostat, iomsg=iomsg) dtv%a
        end subroutine

        subroutine r_t2(dtv, unit, iotype, vlist, iostat, iomsg)
            class(t2),          intent(inout)   :: dtv
            integer,            intent(in)      :: unit
            character(len=*),   intent(in)      :: iotype
            integer,            intent(in)      :: vlist(:)
            integer,            intent(out)     :: iostat
            character(len=*),   intent(inout)   :: iomsg
            print *, "vlist(1)     :", vlist(1)
            print *, "entire vlist:", vlist
            read(unit, fmt="(i4)", iostat=iostat, iomsg=iomsg) dtv%a
        end subroutine
end module

program test
    use m_test
    
    character(len=:), allocatable :: str
    type(t1) :: y
    type(t2) :: xx,zz
    str="1111222233334444555556666"
    read(str, fmt="(DT(7),DT(8),DT(9))") xx,y,zz
    print *, xx%a, y%a, zz%a
end program
C:\TEMP>ifort test.f90 /standard-semantics
Intel(R) Visual Fortran Intel(R) 64 Compiler XE for applications running on Intel(R) 64, Version 15.0.4.221 Build 20150407
Copyright (C) 1985-2015 Intel Corporation.  All rights reserved.

Microsoft (R) Incremental Linker Version 11.00.61030.0
Copyright (C) Microsoft Corporation.  All rights reserved.

-out:test.exe
-subsystem:console
test.obj

C:\TEMP>test
 vlist(1)     : 7
 entire vlist: 7
 vlist(1)     : 77
 entire vlist: 77 8
 vlist(1)     : 77
 entire vlist: 77 87 8 9
 1111 2222 3333

C:\TEMP>

 

xx

xx

0 Kudos
Steven_L_Intel1
Employee
336 Views

Thanks, we'll take a look.

0 Kudos
Steven_L_Intel1
Employee
336 Views

That is indeed very strange. Escalated as issue DPD200375504. Thanks for the examples, and we apologize for the problems here.

0 Kudos
johnyb_
New Contributor I
336 Views

Apologies accepted :-)

Luckily I have a workaround so I can goon using derived type IO in our project

0 Kudos
Steven_L_Intel1
Employee
336 Views

This has been fixed - I expect the fix to appear in Update 1 to Parallel Studio XE 2017 later this year.

0 Kudos
Steven_L_Intel1
Employee
336 Views

The fix should also appear in 16.0.4.

0 Kudos
Reply