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

User-Defined Derived-Type I/O problem when using ipo

Daniel_Dagnino
Beginner
1,239 Views

Dear all,
I have experienced a problem that I cannot explain and probably someone can help me or give me some insight. The simplified code which is giving me a headache is bellow and it is basically a program that writes two numbers of a derived type in a file and then it reads the file both using a user defined write and read. When I compile and execute the code with
ifort test.f90 -o test
everything is correct and the program write and read the correct values, namely 1 and 2. However when I use "ipo" optimization, it reads as
ifort test.f90 -ipo -o test
then when I execute the program it breaks at the "write" user defined i/o derived type with the following message

forrtl: severe (174): SIGSEGV, segmentation fault occurred
Image              PC                Routine            Line        Source             
test               0000000000473319  Unknown               Unknown  Unknown
test               0000000000471BEE  Unknown               Unknown  Unknown
test               00000000004300E2  Unknown               Unknown  Unknown
test               0000000000406443  Unknown               Unknown  Unknown
test               0000000000409E0B  Unknown               Unknown  Unknown
libpthread.so.0    0000003143C0F710  Unknown               Unknown  Unknown
test               00000000006A6B50  Unknown               Unknown  Unknown

I have looked for in internet and actually I am following the way of defined i/o as it is recommended in many specialize web pages however I am not able to understand why ipo fails.

Thanks,

Dani.

 

  module m_data_kind
    implicit none
    
    type field_face
      real, allocatable, dimension(:,:) :: uf
      CONTAINS
        PROCEDURE :: MY_ff_WRITE
        PROCEDURE :: MY_ff_READ
        GENERIC :: WRITE(UNFORMATTED) => MY_ff_WRITE
        GENERIC :: READ(UNFORMATTED) => MY_ff_READ
    end type field_face
    
    type field
      real, allocatable, dimension(:,:) :: u
      type(field_face)   :: f
      CONTAINS
        PROCEDURE :: MY_f_WRITE
        PROCEDURE :: MY_f_READ
        GENERIC :: WRITE(UNFORMATTED) => MY_f_WRITE
        GENERIC :: READ(UNFORMATTED) => MY_f_READ
    end type field
    
    !----------------------------------------------------------!
    CONTAINS
    
    SUBROUTINE MY_ff_WRITE( ff, UNIT, IOSTAT, IOMSG )
        CLASS(field_face), INTENT(IN)   :: ff
        INTEGER, INTENT(IN)             :: UNIT
        INTEGER, INTENT(OUT)            :: IOSTAT
        CHARACTER(LEN=*), INTENT(INOUT) :: IOMSG
        WRITE(UNIT=UNIT,IOSTAT=IOSTAT,IOMSG=IOMSG) ff%uf
    END SUBROUTINE MY_ff_WRITE
    
    SUBROUTINE MY_f_WRITE( f, UNIT, IOSTAT, IOMSG )
        CLASS(field), INTENT(IN)        :: f
        INTEGER, INTENT(IN)             :: UNIT
        INTEGER, INTENT(OUT)            :: IOSTAT
        CHARACTER(LEN=*), INTENT(INOUT) :: IOMSG
        WRITE(UNIT=UNIT,IOSTAT=IOSTAT,IOMSG=IOMSG) f%u
    END SUBROUTINE MY_f_WRITE
    
    SUBROUTINE MY_ff_read( ff, UNIT, IOSTAT, IOMSG )
        CLASS(field_face), INTENT(INOUT) :: ff
        INTEGER, INTENT(IN)              :: UNIT
        INTEGER, INTENT(OUT)             :: IOSTAT
        CHARACTER(LEN=*), INTENT(INOUT)  :: IOMSG
        read(UNIT=UNIT,IOSTAT=IOSTAT,IOMSG=IOMSG) ff%uf
    END SUBROUTINE MY_ff_read
    
    SUBROUTINE MY_f_read( f, UNIT, IOSTAT, IOMSG )
        CLASS(field), INTENT(INOUT)     :: f
        INTEGER, INTENT(IN)             :: UNIT
        INTEGER, INTENT(OUT)            :: IOSTAT
        CHARACTER(LEN=*), INTENT(INOUT) :: IOMSG
        read(UNIT=UNIT,IOSTAT=IOSTAT,IOMSG=IOMSG) f%u
    END SUBROUTINE MY_f_read

  end module m_data_kind
 
  !**********************************************************!    
   program shot
    use m_data_kind
    type(field) :: vf
    
    allocate( vf%u(5,5), vf%f%uf(5,5) )
    
    vf%u(5,1) = 1.
    vf%u(1,5) = 2.
    
    write(*,*) vf%u(5,1)
    write(*,*) vf%u(1,5)
    
    open(unit=1,file='hello.txt',status='unknown',action='write',form='unformatted')
      write(1) vf
    close(1)
    
    open(unit=1,file='hello.txt',status='unknown',action='read',form='unformatted')
      read(1) vf    
    close(1)
    
    write(*,*) vf%u(5,1)
    write(*,*) vf%u(1,5)
    
    deallocate( vf%u, vf%f%uf )
    
  end program shot

0 Kudos
6 Replies
pbkenned1
Employee
1,239 Views

Probably just an IPO bug.  How many files are in play?  In particular, is the module code in one file, and the main program in a separate file?

Patrick

0 Kudos
pbkenned1
Employee
1,239 Views

Strike my last comment.  I can see from the command line only one file is in play.  Let me investigate.

Patrick

0 Kudos
pbkenned1
Employee
1,239 Views

I split up the code into two files in an attempt to better isolate the alleged -ipo bug.  It appears that -ipo is doing something incorrect across contained module SUBROUTINE MY_f_WRITE() and the 'write(1) vf' statement in the main program (both files need to be compiled with -ipo to reproduce the SEGV).

-ip is a workaround if everything is left in a single file. 

[DPD200363107]$ ifort -ip U535190.f90 && ./a.out
   1.000000
   2.000000
   1.000000
   2.000000
[DPD200363107]$
 

Problem reported to the IPO lead developer,  tracking id DPD200363107.

Patrick

0 Kudos
Daniel_Dagnino
Beginner
1,239 Views

Thanks a lot Patrick.

Finally I have declared every one of the derived-type write and read for every variable since the original code has not one but many file, I sent only the problematic part. In other words, now I use:

write(1) a%a%a(1:nx,1,ny,1:nz)

write(1) a%a%b(1:nx,1,ny,1:nz)

write(1) a%a%c(1:nx,1,ny,1:nz)

...

In case I use -ip instead of -ipo I lose ~10% of performance (the execution time changes from 300.5s to 328.7s using 3CPUs with OpenMP). It is not a elegant way to do it but it works.

Dani.

0 Kudos
pbkenned1
Employee
1,239 Views

This issue is now targeted to be fixed in the 15.0 compiler. 

>>>In case I use -ip instead of -ipo I lose ~10% of performance

Thanks for that data point.  I'm a bit surprised though, since -ip shouldn't be all that different from -ipo when only a single file is involved.

Patrick

0 Kudos
pbkenned1
Employee
1,239 Views

This is resolved in IPS XE 2015 update #2, so I am closing this ticket now.

Patrick

[U535190]$ ifort -V
Intel(R) Fortran Intel(R) 64 Compiler XE for applications running on Intel(R) 64, Version 15.0.2.164 Build 20150121
Copyright (C) 1985-2015 Intel Corporation.  All rights reserved.

[U535190]$ ifort -ipo U535190.f90 -o U535190.f90.x
[U535190]$ ./U535190.f90.x
   1.000000
   2.000000
   1.000000
   2.000000
[U535190]$

0 Kudos
Reply