Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
Announcements
Important Update: Community Platform Migration​. Learn more​>

Intel(R) Fortran 2018 and FLUSH

rferrer
Beginner
4,589 Views

Intel Support,

In the process of moving from an older Intel Fortran compiler to ifort 2018, I have encountered from issues involving FLUSH. Consider the following code:
 

      program test_flush
      implicit none
      integer(4)        :: j
      integer(4)        :: nunit
      logical(4)        :: inqfls
      nunit=0
      inqfls=.true.
      do j=1,10
        call sleep  (1)
        call printsc(j,nunit,inqfls)
      enddo
      inqfls=.false.
      do j=1,10
        call sleep  (1)
        call printsc(j,nunit,inqfls)
      enddo
      !
      contains
      subroutine printsc(j,nunit,inqfls)
      implicit none
      integer(4)        :: i
      integer(4)        :: j
      integer(4)        :: nunit
      logical(4)        :: inqfls
      if (j == 1) then
        write(nunit,'(a)',advance='no')' Finished cases:'
        call flushu(nunit,inqfls)
      endif
      write(nunit,'(1i4)',advance='no') j
      call flushu(nunit,inqfls)
      call flushu(nunit,inqfls)
      return
      end subroutine printsc
      !
      subroutine flushu(nunit,inqfls)
      implicit none
      integer(4)        :: nunit
      logical(4)        :: isconn
      logical(4)        :: inqfls
      if (inqfls) then
        inquire(unit=nunit, opened=isconn)
        if (isconn) then
          call flush(nunit)
        endif
      else
        call flush(nunit)
      endif
      return
      end subroutine flushu
      !
      end program test_flush

This is only a test, as the actual code is proprietary and large. Nonetheless, the code above reproduce the problem. If I compile using a previous version of the Intel Fortran compiler,

$ ifort -V
Intel(R) Fortran Intel(R) 64 Compiler for applications running on Intel(R) 64, Version 17.0.7.259 Build 20180403
Copyright (C) 1985-2018 Intel Corporation.  All rights reserved.
$ make clean
rm -f test.exe *.mod *.o
$ make
ifort -g -C -traceback -o test.exe main.f90

The code will produce the expected results

$ ./test.exe 
 Finished cases:   1   2   3   4   5   6   7   8   9  10 Finished cases:   1   2   3   4   5   6   7   8   9  10$ 

But if I recompile with ifort 2018 and re-run the case, I find the following behavior:

$ ifort -V
Intel(R) Fortran Intel(R) 64 Compiler for applications running on Intel(R) 64, Version 18.0.3.222 Build 20180410
Copyright (C) 1985-2018 Intel Corporation.  All rights reserved.

$ make clean
rm -f test.exe *.mod *.o
$ make
ifort -g -C -traceback -o test.exe main.f90
$ ./test.exe 
 Finished cases:   1   2   3   4   5   6   7   8   9  10$ 

It seems to me that the following code is causing the problem

        inquire(unit=nunit, opened=isconn)
        if (isconn) then
          call flush(nunit)
        endif


I am running CentOS 7.5.1804 64-bit Linux. Thanks in advance.

0 Kudos
1 Solution
Steve_Lionel
Honored Contributor III
4,589 Views

Unit zero is valid - it is nonnegative. It is typically preconnected to stderr, but there's no requirement of that by the standard. If there is such a preconnection, the unit number is given by the ERORR_UNIT named constant in intrinsic module ISO_FORTRAN_ENV (if there isn't, that constant has the value -1.)

That said, there's no standard behavior of doing partial writes to units. I suggest reporting this behavior to Intel, as I think the desirable behavior is to do what the 2017 version did.

View solution in original post

0 Kudos
9 Replies
Juergen_R_R
Valued Contributor II
4,589 Views

sleep as a subroutine is a GNU extension, as well as flush as a subroutine. The F2003 flush statement has the same effect, however. But sleep is an extension, so the behaviour depends on the processor. I notice that Ifort v17 indeed has the behaviour as you describe, as does gfortran 5.4 and 9.0 (experimental). Nagfor does not compile the code, as it contains non-standardisms. In the same way gfortran -std=f2003 does not compile, and also ifort -e03. In addition, your subroutines do not have specified intent of their dummy variables, Besides this, I don't see any of the changes in the ifort v18 compared to v17 which could have triggered a different behaviour here. 

0 Kudos
rferrer
Beginner
4,589 Views

Juergen R.,

I have updated the test problem following your observations, see below.
 

      program test_flush
      implicit none
      integer(4)        :: j
      integer(4)        :: nunit
      logical(4)        :: inqfls
      nunit=0
      inqfls=.true.
      do j=1,10
        call printsc(j,nunit,inqfls)
      enddo
      inqfls=.false.
      do j=1,10
        call printsc(j,nunit,inqfls)
      enddo
      !
      contains
      subroutine printsc(j,nunit,inqfls)
      implicit none
      integer(4), intent(in)        :: j
      integer(4), intent(in)        :: nunit
      logical(4), intent(in)        :: inqfls
      if (j == 1) then
        write(nunit,'(a)',advance='no')' Finished cases:'
        call flushu(nunit,inqfls)
      endif
      write(nunit,'(1i4)',advance='no') j
      call flushu(nunit,inqfls)
      call flushu(nunit,inqfls)
      return
      end subroutine printsc
      !
      subroutine flushu(nunit,inqfls)
      implicit none
      integer(4), intent(in)        :: nunit
      logical(4)                    :: isconn
      logical(4), intent(in)        :: inqfls
      if (inqfls) then
        inquire(unit=nunit, opened=isconn)
        if (isconn) then
          flush(nunit)
        endif
      else
        flush(nunit)
      endif
      return
      end subroutine flushu
      !
      end program test_flush

I will also provide the contents of the Makefile
 

# Intel Fortran Compiler
#F90    = ifort
#FFLAGS = -g -C -traceback
#FFLAGS = -e03

# GFortran Compiler
#F90    = gfortran # ifort
#FFLAGS = -g -C -std=f2003

F90=nagfor
FFLAGS=

solver.exe : main.f90
        $(F90) $(FFLAGS) -o test.exe main.f90

clean:
        rm -f test.exe *.mod *.o


After the changes, I was able to compile with gfortran and -std=f2003 and produce the expected behavior, same as ifort 2017. I was also able to compile with NAGFOR and obtain the same behavior as ifort 2017. The only outlier is ifort 2018. Let me know if you find any other non-standard code.

0 Kudos
rferrer
Beginner
4,589 Views

Here is some information on NAG
 

NAG Fortran Compiler Release 6.2(Chiyoda) Build 6207

 

0 Kudos
Juergen_R_R
Valued Contributor II
4,589 Views

PGI gives also the same result. I am a bit puzzled whether unit number zero is actually allowed, according to the Fortran 2018 draft, 12.5.1.2 it is not. 

  1. A unit is either an external unit or an internal unit. An external unit is used to refer to an external file and is specified by an asterisk or a file-unit-number. The value of file-unit-number shall be nonnegative, equal to one of the named constants INPUT_UNIT, OUTPUT_UNIT, or ERROR_UNIT of the intrinsic module ISO_- FORTRAN_ENV (16.10.2), the unit argument of an active defined input/output procedure (12.6.4.8), or aNEWUNIT value (12.5.6.12). An internal unit is used to refer to an internal file and is specified by an internal- file-variable or a file-unit-number whose value is equal to the unit argument of an active defined input/outputprocedure. The value of a file-unit-number shall identify a valid unit.

0 Kudos
Juergen_R_R
Valued Contributor II
4,589 Views

I just checked that if you use e.g. 11 as unit number, a file fort.11 is written that contains your desired output even in the case of ifort v18. So I think the handling of unit number 0 changed in ifort 18, but what happens with that unit number is processor dependent anyways. 

0 Kudos
Steve_Lionel
Honored Contributor III
4,590 Views

Unit zero is valid - it is nonnegative. It is typically preconnected to stderr, but there's no requirement of that by the standard. If there is such a preconnection, the unit number is given by the ERORR_UNIT named constant in intrinsic module ISO_FORTRAN_ENV (if there isn't, that constant has the value -1.)

That said, there's no standard behavior of doing partial writes to units. I suggest reporting this behavior to Intel, as I think the desirable behavior is to do what the 2017 version did.

0 Kudos
rferrer
Beginner
4,589 Views

How do I proceed to report this behavior to Intel?

0 Kudos
Juergen_R_R
Valued Contributor II
4,589 Views
0 Kudos
Steve_Lionel
Honored Contributor III
4,589 Views

Juergen R. wrote:

http://premiersupport.intel.com

That is no longer the correct place. Use https://supporttickets.intel.com/?lang=en-US instead.

0 Kudos
Reply