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

Errors using GETPID()

Vishnu
Novice
3,588 Views

GETPID() is a function that is part of the IFPORT module. I am using this function in a module called 'random.f90', which in-turn is USEd in the main program 'test_rand.f90'

  1. Upon not USEing IFPORT, compilation of the moduled results in the following error:
    $ ifort -c random.f90 
    random.f90(47): error #6404: This name does not have a type, and must have an explicit type.   [GETPID]
                pid = GETPID()
    ------------------^
    compilation aborted for random.f90 (code 1)
  2.  But if I add a USE IFPORT statement at the beginning, the compilation goes through without any errors, but linking results in an error I don't understand:
    $ ifort random.mod test_rand.f90 
    test_rand.f90(3): error #6406: Conflicting attributes or multiple declaration of name.   [RANDOM]
        USE random
    --------^
    compilation aborted for test_rand.f90 (code 1)

According to the IFPORT article, they are both valid way of using functions from the Portability module, but both run into errors. I am using the GETPID() function exactly as described in its Intel reference, with the variable 'pid' defined as an INTEGER.

Using Gfortran, the code compiles and runs correctly (of course, without the USE IFPORT statement), so, for portability, I would like to get it working without the explicit USE statement. Any ideas on what I might be doing wrong?

0 Kudos
1 Solution
Kevin_D_Intel
Employee
3,588 Views

You can make use of your own predefine to control the inclusion of the IFPORT module compile with either ifort or gfortran using the appropriate preprocessor options. The example below uses a predefine of IFORT to control inclusion of IFPORT. Use the additional compiler options -fpp -D IFORT with ifort and -cpp with gfortran as shown below.

module my_module
contains

  function get_pid() result(ipid)
#ifdef IFORT
    USE IFPORT
#endif
    INTEGER(4) ipid

    ipid = GETPID()
  end function get_pid

end module my_module

program example
use my_module

print *,'my pid=',get_pid()
end program example
$ ifort -fpp -D IFORT ex_getpid.f90 &&  ./a.out
 my pid=       29421

$ gfortran -cpp ex_getpid.f90 && ./a.out
 my pid=       29430

 

View solution in original post

0 Kudos
17 Replies
Kevin_D_Intel
Employee
3,588 Views

You didn’t show your actual code but part of the problem relates to naming your module "random" within random.f90 and then the reference to that module in test_rand.f90 conflicts with the portability library name RANDOM hence you received the error #6406. Rename your module to something like "my_random" and change the usage to USE my_random.

Once that is corrected you will hit an new error with your compilation command line. You do not include the .mod file on the command line but rather the .o associated with the module definition. So assuming you rename only the module within your source file named random.f90, your command-line should be: ifort random.o test_rand.f90

To eliminate confusion you might want to rename your module as suggested and also the source file name to something like my_random.f90.

0 Kudos
Vishnu
Novice
3,588 Views

Ah! Okay, so I changed it to 'random_init', both the name of module, as well as the module file. Now it works, but only if I add a 'USE IFPORT' at the beginning. Is there any way I can get it to work without it?

0 Kudos
Laura_S_3
Beginner
3,588 Views
Yes, you could declare GETPID at the top: integer, external :: GETPID but that is NOT recommended. What is your reason for not wanting to "use IFPORT"?
0 Kudos
Vishnu
Novice
3,588 Views

Laura S. wrote:

Yes, you could declare GETPID at the top:

integer, external :: GETPID

but that is NOT recommended. What is your reason for not wanting to "use IFPORT"?

Why exactly is it not recommended? I do not want to 'USE IFPORT' because I want my code to also compile on gfortran without any errors.

0 Kudos
Laura_S_3
Beginner
3,588 Views

When you use the "USE IFPORT" statement, then the compiler will be getting the information about GETPID from the IFPORT module. Presumably, the IFPORT module will have accurate information about GETPID. The "integer, external :: GETPID" way could tell the compiler incorrect information about GETPID, for example, if it is "integer(8)" instead of "integer". If the compiler has incorrect information, then your program is likely to run incorrectly.

Needing to be able to compile under gfortran is an important consideration. I suspect there is a safer way than to just state "integer, external :: GETPID" but I don't know it. Hopefully, one of the experts here will have a better way. Is it just gfortran and Intel Fortran you need to be able to compile with, or are there others?

Good luck!

Laura

0 Kudos
Steve_Lionel
Honored Contributor III
3,588 Views

There is no guarantee that any of the "portability" procedures are implemented the same with other compilers. There are several I know of that have different interfaces and behaviors depending on the compiler. You're not guaranteeing portability by avoiding IFPORT.

 

0 Kudos
Vishnu
Novice
3,588 Views

Laura S. wrote:

you could declare GETPID at the top:

integer, external :: GETPID

I'm putting it at the very top of the MODULE file, after the IMPLICIT NONE and before the CONTAINS statement. Is that the right place? It complies and runs well with ifort, but under gfortran, the module file compiles, but linking gives errors, since GETPID is an intrinsic pocedure there.

$ gfortran random_init.o test_rand.f90 
random_init.o: In function `__random_init_MOD_init_random_seed':
random_init.f90:(.text+0x96b): undefined reference to `getpid_'
collect2: error: ld returned 1 exit status

Laura S. wrote:

 Is it just gfortran and Intel Fortran you need to be able to compile with, or are there others?

Yep, it is just ifort and gfortran.

Steve Lionel (Ret.) wrote:

There is no guarantee that any of the "portability" procedures are implemented the same with other compilers. There are several I know of that have different interfaces and behaviors depending on the compiler. You're not guaranteeing portability by avoiding IFPORT.

I only need the code to also complie well in gfortran. Compliling and linking using gfortran requires no other statements. Is there any way I can write things that are only visible to ifort, but will be ignored by anyother compiler? Or: some way to write a line such that it will be ignored by gfortran, but be compiled by others?

0 Kudos
Kevin_D_Intel
Employee
3,589 Views

You can make use of your own predefine to control the inclusion of the IFPORT module compile with either ifort or gfortran using the appropriate preprocessor options. The example below uses a predefine of IFORT to control inclusion of IFPORT. Use the additional compiler options -fpp -D IFORT with ifort and -cpp with gfortran as shown below.

module my_module
contains

  function get_pid() result(ipid)
#ifdef IFORT
    USE IFPORT
#endif
    INTEGER(4) ipid

    ipid = GETPID()
  end function get_pid

end module my_module

program example
use my_module

print *,'my pid=',get_pid()
end program example
$ ifort -fpp -D IFORT ex_getpid.f90 &&  ./a.out
 my pid=       29421

$ gfortran -cpp ex_getpid.f90 && ./a.out
 my pid=       29430

 

0 Kudos
Dandy_E_
Beginner
3,588 Views

Kevin D (Intel) wrote:

You can make use of your own predefine to control the inclusion of the IFPORT module compile with either ifort or gfortran using the appropriate preprocessor options. The example below uses a predefine of IFORT to control inclusion of IFPORT. Use the additional compiler options -fpp -D IFORT with ifort and -cpp with gfortran as shown below.

module my_module
contains

  function get_pid() result(ipid)
#ifdef IFORT
    USE IFPORT
#endif
    INTEGER(4) ipid

    ipid = GETPID()
  end function get_pid

end module my_module

program example
use my_module

print *,'my pid=',get_pid()
end program example
$ ifort -fpp -D IFORT ex_getpid.f90 &&  ./a.out
 my pid=       29421

$ gfortran -cpp ex_getpid.f90 && ./a.out
 my pid=       29430

 

To avoid having to specify -DIFORT, one could use
 

#ifdef __INTEL_COMPILER
      USE IFPORT
#endif

where __INTEL_COMPILER is already/aotumatically defined by the intel compiler itself.

 

0 Kudos
Vishnu
Novice
3,588 Views

Dandy, that works! Thanks!

Kevin, i'm able to use those pre-processor directives only if I put them before the CONTAINS and IMPLICIT NONE statements:

MODULE random_init

#ifdef __INTEL_COMPILER
    USE IFPORT
#endif

    IMPLICIT NONE

CONTAINS

    SUBROUTINE init_random_seed()

        USE iso_fortran_env, ONLY: int64

        INTEGER, DIMENSION(:), ALLOCATABLE :: seed
.
.
.

 

0 Kudos
Kevin_D_Intel
Employee
3,588 Views

Glad the predefine works for you. The #ifdef/endif directives are position-able anywhere within a source file. I'd have to see the explicit example where they were problematic for you to understand what the issue was. You would not want to include IMPLICIT NONE or the CONTAINS within the #ifdef/endif as that excludes them from the compiled source and at least w/o CONTAINS that breaks the source snippet shown and generates other compilation errors.

Anyway, glad you found a usable solution.

0 Kudos
jimdempseyatthecove
Honored Contributor III
3,588 Views

You should be able to use strictly Fortran directives

!DIR$ IF DEFINED(__INTEL_COMPILER)
  USE IFPORT
!DIR$ ENDIF

Sometimes use of a preprocessor has undesirable side effects.

Jim Dempsey

0 Kudos
Vishnu
Novice
3,588 Views

Using this, I don't have to pass the -fpp or -cpp flags. That is really nice! Is that because those others are C directives?

EDIT: Oh, but there's another issue. Doing it this way breaks gfortran compatibility. It ow sees the 'USE IFPORT' line, and so returns an error. So looks like i'll have to use the earlier method.

Doesn't gfortran recognize !DIR$ ?

0 Kudos
jimdempseyatthecove
Honored Contributor III
3,588 Views

Ahh..., See: https://software.intel.com/en-us/forums/intel-visual-fortran-compiler-for-windows/topic/533979

Repeat Offender suggests:

!DEC$ IF(.FALSE.)
module ifport
end module ifport
!DEC$ ENDIF

FortranFan suggests writing your own interface.

Jim Dempsey

 

0 Kudos
Vishnu
Novice
3,588 Views

So why does gfortran not see these compiler directives? Are they not part of the fortran standard? Or are they very new?

Does the Intel reference page I linked to, put it in green because it is old stuff, or because it is specific to Intel-Fortran?

0 Kudos
jimdempseyatthecove
Honored Contributor III
3,588 Views

Try !DIR$ in place of !DEC$

!DEC$ was used by Compaq Digital Fortran (which acquired Digital Equipment Corporation, aka DEC, Fortran). Intel acquired Compaq Digital Fortran. The !DEC$ ... was an inherited legacy.

Jim Dempsey

0 Kudos
Steve_Lionel
Honored Contributor III
3,588 Views

In this case, I would recommend !DEC$. gfortran may recognize !DIR$. (I know it also recognizes !GCC$.) However, the _INTEL_FORTRAN preprocessor symbol won't be predefined in gfortran, so it doesn't matter whether or not gfortran recognizes the directive.

0 Kudos
Reply