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

Intel(R) Fortran 2018 and FLUSH

rferrer
Beginner
774 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
774 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 I
774 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
774 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
774 Views

Here is some information on NAG
 

NAG Fortran Compiler Release 6.2(Chiyoda) Build 6207

 

0 Kudos
Juergen_R_R
Valued Contributor I
774 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. 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_UNITOUTPUT_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 I
774 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
775 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
774 Views

How do I proceed to report this behavior to Intel?

0 Kudos
Juergen_R_R
Valued Contributor I
774 Views
0 Kudos
Steve_Lionel
Honored Contributor III
774 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