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

Many subprograms require IFPORT or IFCORE

Jay_B_
Beginner
4,212 Views

Greetings.  A little background, if I may:  I am porting a legacy Fortran application that is over 30 years old, with some components that date back almost 40 years, even prior to the FORTRAN 77 standard (no congratulations necessary :--))  One of its developers has been porting it from Alpha OpenVMS to Linux using g77 with many switches to accept "ugly" usages.  I was asked to provide Linux expertise, and one of the first points I made was the obsolescence of g77.  I am recommending Intel Fortran because it supports legacy usages, especially the old DEC FORTRAN compiler, while remaining current.   Intel Fortran would also support modernization (unlike g77).

Many of the application's subroutines and functions invoke Fortran library components that Intel Fortran can link in if I specify USE IFPORT and/or USE IFCORE.  But from what I can see, one or both of these statements needs to be added to every subprogram that invokes these functions, usually implicitly.  Can I, instead, specify a link-time or compile-time option to use these modules?

Thanks,
Jay

0 Kudos
12 Replies
Steven_L_Intel1
Employee
4,212 Views

IFPORT should not be necessary unless you call a portability library routine that has alternate signatures, as described in our documentation. IFCORE wouldn't be used for g77 code that you are simply compiling with ifort. The portability library is linked in by default.

What happens if you don't add the USE?

0 Kudos
Jay_B_
Beginner
4,212 Views

Hello, Steve.  Thanks so much for your interest in this issue.

In attempting to re-create this issue with a small test case, I might have further insight.  It's possible that this has to do with gnu functions that this app is invoking.

I am working on Linux, Red Hat v5.10, which uses version 4.1.2-55 of the various gnu products.

Here is a little fixed-format program that does nothing useful:

      PROGRAM GE

      CHARACTER*400 MSG

      CALL GERROR(MSG)

      END

 

The following steps complete when I use g77 (my colleague's choice of compiler before I became involved):

 

> g77 -c ge.for

> g77 -o ge ge.o

 

My first crack with ifort, even with assuming no underscores, yields:

 

> ifort -c -assume nounderscore ge.for

> ifort -o ge ge.o

ge.o: In function `MAIN__':

ge.for:(.text+0x41): undefined reference to `gerror'

 

If I add 1 line:

 

      PROGRAM GE

      USE IFCORE

      CHARACTER*400 MSG

      CALL GERROR(MSG)

      END

 

the program links cleanly.  Perhaps there is a link-time directive to use the appropriate libraries?

Jay

0 Kudos
Izaak_Beekman
New Contributor II
4,212 Views

FWIF, to maximize portability, try to avoid using compiler extensions like GERROR(). Either write your own version of GERROR that achieves the desired behavior, or find a standard language construct to replace compiler extensions. Then the code should run everywhere there is a working fortran compiler supporting the language standard/features you use (e.g., f95 vs f2003/f2008). In the case of GERROR there is no standard language construct, but some combination of STOP and WRITE(ERROR_UNIT,*) ‘Error msg’ should be able to achieve the desired functionality. (N.B., ERROR_UNIT is a constant in the ISO_FORTRAN_ENV module, added in F2003. Import it through something like: USE ISO_FORTRAN_ENV , ONLY: ERROR_UNIT)

As a first hack, you may not want to go through the effort of doing all this, so if you swap out g77-isms for ifort compiler extensions, say from the IFPORT module, I would recommend documenting which compiler extensions you use, by using the USE module_name ONLY only-list form of the use statement. This way, only items actually used in the program will be imported from the IFPORT module. Furthermore, if the names of certain procedures differ, then you can use the renaming capability in the only list: … ONLY : old-name => ifport-name

Good luck and happy hacking.

0 Kudos
Jay_B_
Beginner
4,212 Views

Hello, Zaak.  My GERROR example was meant as a simple illustration, and GERROR used in only one place.  I agree with your general recommendations about standardizing code, and intend to do that once my organization, sponsor, and especially the original author, agree that we should invest the time to adopt Intel Fortran as the best path going forward, so that we can standardize and even modernize the application in an evolutionary manner.  There are other issues as well, such as convincing him that we need to implement version control while he continues to support the g77 branch and we try to establish an Intel Fortran main development line.  And, of course, there are new requirements to satisfy, eventual adoption of laster versions of Red Hat, etc., etc., all of which have the potential to "break" g77, with no support.   (Aside: I was asked to join the effort after the g77 decision was made.  The decision had been based on a compiler evaluation of 4 or 5 alternatives, none of which was Intel Fortran.  The sponsor was willing to support a proprietary product if it was the best; I hope they still are.)

In any case, for now my question is simply of there is a way to "use" modules across an entire file of subroutines and functions, or else to specify it at link time since that is where the errors occur.

Thanks much,
Jay

0 Kudos
jimdempseyatthecove
Honored Contributor III
4,212 Views

What may work is to turn off IPO (which is on by default) and you may need to disable interface checking. Configured this way, the compiler will not attempt to check arguments (which requires it to see GERROR) and will assume GERROR is external to the compilation unit (and assume you specified the correct argument list). This then deferrers the any testing for missing GERROR to the link phase, and which Steve indicated is linked in by default.

Jim Dempsey

0 Kudos
jimdempseyatthecove
Honored Contributor III
4,212 Views

Now then >> a way to "use" modules across an entire file of subroutines and functions

This likely will be prone to failure. Think of trying to create one monolithic set of COMMONs, placed into an INCLUDE file and then auto-inserting the INCLUDE statement of that file. The name collisions would make this technique unusable in all but the simplest cases.

Jim Dempsey

0 Kudos
Jay_B_
Beginner
4,212 Views

Good point about name collisions.  I should have thought about that, especially since I recently completed some work on a Java project that heavily depended on import statements.

I once had a link to the Ifort compiler reference manual, and cannot seem to find it now.  Does anyone have a link?

Jay

0 Kudos
jimdempseyatthecove
Honored Contributor III
4,212 Views

Converting old code (60's, 70's, 80's) to new (read modules) has a long list of issues to resolve and should not be taken lightly. Due to memory constraints of the old computers it was not unusual to have the same named common mapped to different sets of variable types in addition to name changes. If (or I should say when) one is not careful, your conversion may compile but produce incorrect results that are very hard to trace back to the cause.

Years back, I found it convenient to use the preprocessor. The same source code could then be compiled the old way using COMMONs and INCLUDEs as well as the new way using modules and container object. Debugging was difficult but that was a short term issue since after conversion, the output of FPP could be saved and renamed for use as the next generation source files.

#define EL pTether.pFiniteSolution.rEL

Today it would (may) be better to use the ASSOCIATE. The preprocessor made for little edits to the original source code as possible (none in most cases). And you could unburn your bridges so to speak to run side-by-side. Then the final conversion to the new format became mostly automatic.

Jim Dempsey

0 Kudos
Kevin_D_Intel
Employee
4,212 Views

Jay B. wrote:

I once had a link to the Ifort compiler reference manual, and cannot seem to find it now.  Does anyone have a link?

Jay

The entire Intel Development Tools collection is here: https://software.intel.com/en-us/intel-software-technical-documentation

The Intel Fortran User's Guide (15.0) specifically is here: https://software.intel.com/en-us/compiler_15.0_ug_f

0 Kudos
Steven_L_Intel1
Employee
4,212 Views

GERROR seems to be rather unusual here (along with PERROR) it was moved from the portability library to the "core" library with a different name. I'm not sure why this was done, but it was some years ago. Most portability routines won't have this issue.

You can work around the GERROR issue by adding the following source to your build - you won't need to change other sources:

subroutine gerror (errmsg)
use ifcore, mygerror=>gerror
character(*) errmsg
call mygerror(errmsg)
return
end

What other routines do you have this problem with?

0 Kudos
Jay_B_
Beginner
4,212 Views

Hi, Steve.  First, w.r.t. IFCORE, the link errors might have been my own fat-finger issue, combined with the possibility that the particular program where I had these issues has not been re-built in quite some time.  I need to speak with the developer when he returns from vacation.

As for IFPORT, the USE statement eliminates compilation errors when the code refers to DTIME(), RAND(), and STSYEM().  A sample error message is:

lbsys.for(59): error #6404: This name does not have a type, and must have an explicit type.   [DTIME]

      CPUTOT =DTIME(CPUTIM) *1000.

 

Jay

 

0 Kudos
Steven_L_Intel1
Employee
4,212 Views

Ok. You have IMPLICIT NONE and don't declare these functions. Since none of those are intrinsic functions, you must give them a type. Adding USE IFPORT declares them with a type. 

My recommendation to you is to replace these with calls to the standard intrinsics CPU_TIME, RANDOM_NUMBER and EXECUTE_COMMAND_LINE. (The latter has some bugs in the initial 15.0 release, fixed in update 1 coming out very soon.) Then you won't have to worry about use of nonportable modules. As for GERROR, many of the Fortran statements and procedures have a "MSG" argument to get a text version of error messages (the spelling of the keyword varies.)

0 Kudos
Reply