VMS / OpenVMS Fortran to ANSI (Intel) Fortran for Linux and Windows


VX/Fortran allows you to run OpenVMS FORTRAN applications on x86 Intel Linux without manual code changes.

VX/Fortran an VMS / OpenVMS extension to FPT (Fortran Partner™) is a Powerful Suite of Tools for Writing, Maintaining and Migrating Fortran programs. Many of the World's Leading Aerospace and High Tech Organizations use VX/Fortran for Migration and Standards Adherence.

VX/Fortran Will Migrate 100% of VMS / OpenVMS Fortran to ANSI Fortran (Such as Intel Fortran). Intel Fortran was Original VMS / OpenVMS Fortran but many of the VMS / OpenVMS extensions were disabled for ANSI compatibility.

VX/Fortran Will Convert the VMS / OpenVMS Syntax and Semantics and allow your Applications to Compile and Run virtually without Manual Remediation.

VX/Fortran has migrated HUNDREDS of MILLION of LINES of almost All Fortran Variants.

It is used extensively not just in Migration Projects but also, in Military Projects where its Semantic checking is used to ensure String Adherence to Standards.

Sector7 Licenses FPT from SIMCON International in the UK, a Partnership extending to almost 30 years. VX/Fortran extends FPT for a large number of VMS / OpenVMS runtime features.

 

Learn More

Introduction

An VMS / OpenVMS Fortran code may contain many tens of years of software investment. If this investment is to be preserved the code must be converted to run on modern hardware under modern compilers. VX/FPT and Sector7's system service library, VX/RT, make this conversion. The authors of VMS / OpenVMS Fortran made many extensions to Fortran 77 and these extensions provided important facilities which were missing from the language at that time. Some of these extensions were incorporated into Fortran 90. Some do not conflict with Fortran 90 and are supported by modern compilers. But some are incompatible with modern Fortran and either do not compile at all, or generate errors at run-time. VX/RT re-engineers the code to translate these features to modern Fortran. Examples are described in the panels which follow. VMS / OpenVMS Fortran also accessed extensive support libraries for system tasks such as inter-process communication and form and screen handling. Sector7 has developed more than 900 VMS / OpenVMS system service calls (VX/RT API's) for Linux/Windows.

Integration with VX/RT for RMS and VMS / OpenVMS API Usage

VX/Fortran automatically converts the names and directories used in INCLUDE statements in the code to Linux and Windows format. The file names written in OPEN and INQUIRE statements are wrapped in calls to VX/RT routines which change the file name and directory formats at run-time. File names in sub-program arguments may optionally be handled in the same way. VMS Fortran supports ISAM (Indexed Sequential Access Method) files. Additional keywords are added to the OPEN, READ, WRITE and INQUIRE statements to specify the file organization, the access keys and the links to be followed. However, ISAM files are not supported by any modern Fortran system. Sector7's VX/RT library provides subroutines and functions which support ISAM files. VX/FPT automatically converts all OPEN, READ, WRITE and INQUIRE statements for ISAM files to calls to these routines.

Embedded SQL to External Pro*C

VMS Fortran may contain embedded SQL database code supported by Oracle Pro*Fortran™ The code is pre-processed by the Oracle's PROFOR pre-processor before compilation by the VMS Fortran compiler. However, the PROFOR pre-processor is no longer supported by Oracle and is not compatible with modern Fortran. In particular, it generates illegal code when Fortran 90 modules are present. If PROFOR is used for the migrated code, the code is trapped in an obsolete style and the advances in Fortran programming made in Fortran 90 and later are not available. Sector7's pf2pc pre-processor copies the embedded SQL code into new C routines, and inserts calls to the C routines into the Fortran. VX/Fortran may then be used to complete the migration

Automated Test cases

VX/Fortran supports the creation of acceptance tests, and of a testing environment which may be used to identify defects. Q.A. Analysis: VX/Fortran analyses the source code and identifies many classes of programming error likely to cause problems in migration. Record/Replay: VX/Fortran captures, and then replays from file, all keystrokes, file I/O and data at chosen sub-program interfaces. A long testing session may then be replayed by a single command. Run-time Trace: The result of every computation in a run is captured to file. The run is then repeated on the migration host, comparing every value computed with that in the file. Coverage Analysis: VX/VX/Fortran measures how often each executable statement is visited during a test procedure. Entry/Exit Monitor: The entry to and exit from every routine is logged to shared memory which is available to an independent program. It is therefore available even if the main process crashes.

Standards Adherence

VMS Fortran is written in fixed format. The first 5 printing columns are reserved for the statement label. Column 6 (Or the column after a tab character) is the continuation line marker, and the remainder of the line up to column 72 (or optionally column 132) contains the code. This is now considered to be archaic. Modern Fortran is usually written in free format, where no columns are reserved for specific uses. Similarly, VMS Fortran used the Fortran 77 dot-delimited relational operators, .EQ., .NE., .GT., .GE. etc. Modern practice is to use symbolic operators, ==, /=, >, >= etc.

The conversion to a modern style in these, and in many other respects may be made automatically by VX/FPT. This is partly an issue in staff training, retention and morale. It may be difficult to motivate staff to spend time on code and coding practices which they perceive to be obsolete.

Extended Functionality

Feature Description
Quality Assurance VX/Fortran detects errors not normally detected by compilers and linkers. It can guarantee that code is free of many classes of error.
Error Correction VX/Fortran can correct some errors automatically, and document the changes it has made.
Standardization VX/Fortran reformats code to a user's chosen style. It can insert declarations and re-program control constructs to conform to a house standard.
Migration/Porting VX/Fortran can make systematic changes to port code between hosts. It can automatically convert constructs from VMS, from Gould-SEL and from many other systems to standard Fortran.
Software Engineering VX/Fortran can automatically generate an interactive and command file control system for a program. It can instrument code to automate regression testing.
Optimization VX/Fortran can expand sub-programs in-line and unwind loops to optimize code to speed execution.
Report Generation Reports for program documentation include the symbol table collated across all sub-programs, COMMON block listings in address order, and the program call tree.
User Interfaces VX/Fortran troubleshoots and debugs code interactively or runs in batch mode as part of a QA or build procedure.
Security If required, VX/Fortran can protect source code by making it unintelligible, while preserving its integrity as compilable Fortran.
Hosts Supported The supported hosts include VMS, DEC Linux, HP-UX, AIX, Irix and Solaris.

The documentation is available on-line. The Tutorial Guide provides an introduction for the user's first use of Fortran on his or her own programs. The Reference Manual contains the installation procedures, and a detailed description of all VX/Fortran commands. The User's Guide describes how VX/Fortran may be used to achieve specific objectives, such as QA auditing and migration of code between platforms.

VMS / OpenVMS to Intel Fortran

File names in OPEN and INQUIRE statements: VMS:

OPEN ( UNIT=report_lun,FILE='LOGS:MONITOR.LOG',STATUS='UNKNOWN')

 

Migrated code:

OPEN (UNIT=report_lun,FILE=vxrms_translate_file_name &
('LOGS:MONITOR.LOG'),STATUS='UNKNOWN')

 

OPEN of an Indexed Sequential (ISAM) file: VMS:

OPEN(UNIT=INDXUFLUN,ACCESS='KEYED'
  1 ,FILE='INDXUF.DAT',RECL=10
  1 ,STATUS='OLD',ORGANIZATION='INDEXED'
  1 ,RECORDTYPE='FIXED',FORM='UNFORMATTED')

 

Migrated code (Note the conversion to free format):

! FPT OPEN (UNIT=INDXUFLUN,ACCESS=
'KEYED',FILE='INDXUF.DAT'
! 1,,RECL=10
! 1 ,STATUS='OLD',ORGANIZATION='INDEXED'
! 1 ,RECORDTYPE='FIXED',FORM='UNFORMATTED')

CALL VXRMS_OPEN('UNIT=',indxuflun,'ACCESS=','KEYED',   'FILE=', 'INDXUF.DAT','RECL=',10,   'STATUS=','OLD','ORGANIZATION=',   'INDEXED','RECORDTYPE=','FIXED',   'FORM=','UNFORMATTED',%VAL(0))

READ of an Indexed Sequential (ISAM) file: VMS:

C FPT READ (KEYGT=3,KEYID=1,UNIT=INDXUFLUN)
CALL VXRMS_READ('I4KEYGT=',3,'KEYID=', 1,'UNIT=',indxuflun,%VAL(0))

 

System library call with missing arguments: VMS:

Migrated code:

j_ret_stat = lib$set_logical(prim_log(1:12),
. primary_file,
%VAL(0),%VAL(0),%VAL(0))

 

Unsafe execution order

(The array la has bounds (1:3) ): VMS:

IF ((i > 0) .AND. (i≤3) .AND. la(i)) THEN

 

Migrated code (The original crashes under ifort when i == 1) :

! FPT IF ((i>0) .AND. (i<=3) .AND.
la(i)) THEN
!------------^------------------------
!!! FPT - 3837 .AND. or .OR. re-programmed to
enforce order of
evaluation
!-------------------------------------
fpt_temp_l(1)=(i>0) .AND. (i<=3)
IF (fpt_temp_l(1)) THEN
fpt_temp_l(1)=la(i)
ENDIF
IF (fpt_temp_l(1)) THEN

 

Testing - Tracing execution - VMS:

IF ( ABS ( p2 ( 3, i ) -
p1 ( 3, i ) ).LT. crita ) THEN
  s = 0.0
  DO 10 j = 1, 2
  s = s + ( p1 ( j, i ) - p2 ( j, i ) ) * h( p1 ( j, i ) - p2 ( j, i ) ) 10 CONTINUE
  mindis = SQRT ( s )
  IF ( mindis .LT. crith )
  RETURN 1
ELSE
  mindis = 1.0E38
ENDIF
C
RETURN

Migrated code:

CALL trace_start_sub_program(7) !
IF (ABS(p2(3,i)-p1(3,i)) .LT. crita) THEN
  s=0.0
  CALL trace_r4_data(s,53)
  DO 10 j=1,2
    CALL trace_i4_data(j,54)
    s=s+(p1(j,i)-p2(j,i))*(p1(j,i)- &
    p2(j,i))
    CALL trace_r4_data(s,55)
10 CONTINUE
  mindis=SQRT(s)
  CALL trace_r4_data(mindis,56)
  IF (mindis .LT. crith) THEN
    CALL trace_return_sub_program(8)
  RETURN 1
ENDIF
ELSE
  mindis=1.0E38
  CALL trace_r4_data(mindis,57)
  ENDIF
  CALL trace_return_sub_program(9)
!
RETURN

Optimization

VX/Fortran carries out in-line expansion of subroutines and functions, and unwinds DO loops, to optimise code for speed of execution. The effects of the optimisations depend on the host architecture. There are trade-offs between processor speed, memory speed and instruction cache size. Run times are typically improved by 20% to 40%, and by as much as a factor of two or more on high performance processors inhibited by memory speed.

Sub-program calls may interfere seriously with compiler optimisations. For example:

 

R=R0+ALPH(I1,I2,I3,CELL) FR=INTERP1(TYRESPEED,TYREVBP,TYREFRICT) ALPH(I1,I2,I3,CELL)=FR*T0

 

In this example 'ALPH' is an array and the indices, 'I1', 'I2', 'I3' and 'CELL' are variables in a COMMON block. The compiler must generate code to re compute the indexed address within 'ALPH' in case the COMMON block variables are modified during the call to the function 'INTERP1'. When 'INTERP1' is expanded in-line the memory address of the array element can be saved in a register for re use.

VX/Fortran comments the changes that it makes in the expanded code, so that it remains readable for debugging. The linear interpolation function, 'INTERP1' called in the example above is:

 

REAL*4 FUNCTION INTERP1(INPUT,BP,FUNTAB)
REAL*4 INPUT
REAL*4 BP(*)
REAL*4 FUNTAB(*)
I=1
DO WHILE (BP(I) .LT. INPUT)
  I=I+1
ENDDO
INTERP1=FUNTAB(I-1)+(FUNTAB(I)-FUNTAB(I-1))*
  1 (INPUT-BP(I-1))/(BP(I)-BP(I-1))
RETURN
END

 

VX/Fortran expands the call to read:

 

R=R0+ALPH(I1,I2,I3,CELL)
C C FR=INTERP1(TYRESPEED,TYREVBP,TYREFRICT) C I=1 DO WHILE (TYREVBP(I) .LT. TYRESPEED)   I=I+1 ENDDO INTERP1_VAL=TYREFRICT(I-1)+(TYREFRICT(I)-      TYREFRICT(I-1))* 1 (TYRESPEED-TYREVBP(I-1))/(TYREVBP(I)-TYREVBP(I-1)) C RETURN INTERP1 C FR=INTERP1_VAL C ALPH(I1,I2,I3,CELL)=FR*T0

 

Note that the modified code is marked by bars across the text, and the original statement, the assignment of 'FR', remains in place but is commented-out. The formal arguments in the function have been replaced by the actual arguments to the call.

In this example, there was no variable named 'I' in the scope of the expanded statement, so the name of the variable 'I' in the function was retained. Variables are renamed if name clashes occur. Declarations of variables used in the expansion are inserted in the routines which require them, and they are moved to COMMON blocks if they have a SAVE attribute or are SAVED by default.

In-line expansion may be carried out quickly and easily, and it is recommended that users maintain code in unexpanded form. VX/Fortran may therefore be used to resolve a common conflict in the maintenance of large programs. It is good practice to encapsulate small, frequently used operations, such as accesses to data structures, in subroutines or functions. Maintenance changes are then made in only one place. However, a large number of sub-program calls slow down program execution.

With VX/Fortran, users may choose to encapsulate primitive operations and to expand the calls in-line before the release of production code.

In-line expansion and loop unwinding are controlled by the VX/Fortran commands Expand inline and Unwind marked loops. The commands Inline and Unwind are written in the code to mark candidate routines and loops for expansion.

Error Correction / Standardization

VX/Fortran identifies errors and inconsistencies in Fortran code (Please see Quality Assurance ). It may be used to correct some classes of error automatically. The most important corrections are to sub-program arguments. Consider the function call:

The function BOUND is a limiter, which is used to keep the input to ACOS within the range zero to one. It is coded as:

 

FUNCTION BOUND( LOW, INPUT, HIGH )
    REAL LOW,INPUT,HIGH
    BOUND = MIN ( HIGH, MAX ( LOW, INPUT ) )
RETURN
END
            

 

The problem is that all three arguments to BOUND should be real, but BOUND has been called with the arguments integer 0, real HDOT/V and integer 1. The integer value of zero is unlikely to cause a problem. Most systems treat integer zero as equivalent to real zero. The integer 1 will usually cause an error.

The VX/Fortran command to correct problems like this is " Correct inconsistent arguments ". VX/Fortran checks all arguments in the entire program. Corrections are made by re-writing the arguments or by inserting calls to intrinsic functions (e.g. REAL(), DBLE(), INT() etc.). Inconsistent arguments which cannot be corrected are marked by diagnostics.

 

ALPHA = ACOS ( BOUND ( 0, HDOT / V, 1 ) )

The call above is re-written as:

ALPHA = ACOS ( BOUND ( 0.0, HDOT / V, 1.0 ) )
!!! VX/Fortran - 1873 Actual
argument has been changed to match formal argument.
!!! VX/Fortran - 1873 Actual
argument has been changed to match formal argument.

 

A large Fortran program has many authors and a lifetime of many years. Code is inherited from other projects. Differences in style, in management and in the available programming tools lead to the creation of a dusty deck. The indentations may no longer represent the control structures; to find all the assignments of 'THETA' you may need to search for

 

'THETA =', 'Theta=', 'theta=' ...

 

VX/Fortran makes maintenance of such code manageable.

VX/Fortran automatically reformats source code to a consistent set of standards requested by the user. It deals with indentations, adds or removes spaces before and after tokens, checks line lengths, allows specifications of upper or lower case keywords and variables. It changes the format of real numbers, handles continuation lines, deals with the renumbering of statement labels and with many other issues to make life easier for the Fortran programmer. It also contains a language sensitive editor which allows Fortran identifiers to be renamed systematically. Each user works in his or her own coding style, and the code is reformatted to a company standard before release.

word-break:

The same reformatting features may also be used to make code unmaintainable - to protect source code by removing the comments and encrypting the variable names, making it unintelligible to others. This has proved useful in situations where sensitive code is handed over to third parties in a compilable form (Please see Security ).

Example FPT Run

Diagnostic Summary
Total diagnostics 563 Highest severity 2

Notes 194 Warnings 344
Errors 25

Code Quality Index

Error weighting 10
Total lines 29692
Index per 1000 lines 20.005

Contributions to Code Quality Index

 

No. Description. Cnt Contrib
1457 Evaluation of this intrinsic function not supported. 3 30
1579 Optional comment delimiter D, X or Y in column 1 1
1585 Arguments inconsistent with sub-program declaration. 6 60
1873 Actual argument has been changed to match formal argument. 1 0
2241 References are made to sub-programs which have not been read. 1 0
2345 Data type of PARAMETER does not match that of the expression. 1 1
2435 Missing argument(s) inserted. 0 0
2449 Unused sub-programs encountered 1 0
2673 INTEGER used as LOGICAL corrected to LOGICAL expression 13 0
2689 Name already referenced as a FUNCTION used as a SUBROUTINE 3 3
2865 REAL value assigned to INTEGER variable - danger of overflow 15 15
2867 Incompatible data types in assignment 6 6
3039 Data type of this function conflicts with prior use 1 10
3047 Fortran 90 intrinsic name used as an identifier 1 1
3067 Loss of precision in real or complex assignment 70 0
3069 The left-hand-side variable will not have the expected precision 75 0
3073 Danger of overflow due to different integer sizes 73 73
3079 Integer result of an integer division coerced to a real value 8 1
3085 Objects of .EQ., .NE. .GT. etc. are of different data types 92 92
3087 REAL or COMPLEX quantity tested for exact equality/inequality 59 59
3089 Comparison of REAL or COMPLEX values which differ in precision 34 34
3433 No overload identified for this assignment statement 6 60
3437 Mixed real or complex sizes in expression - loss of precision 40 40
3485 Duplicate definition of a derived type 1 10
3489 Error analysing expression or sub-expression 2 20

 

End of processing
===============================================================================

Error 1585 auto fix example:

STATUS = LIB$MOVC5( %REF(0), %VAL(0), %REF(0),
1               %REF(SIZEOF(Strct.Element)),
1               %REF(Strct.Element))

After VX/Fortran:

INTEGER*2 i2_01_arg_1
INTEGER*2 i2_04_arg
i2_01_arg_1 = 0 
i2_04_arg = SIZEOF(Strct.Element)
status = lib$movc5(%REF(i2_01_arg_1),%VAL(0),%REF(0),
!-----------------------^------------------------------------------------------
!!! FPT - 1585 Arguments inconsistent with sub-program declaration.
!------------------------------------------------------------------------------
&                  %REF(i2_04_arg),
&                  %REF(Strct.Element))
===============================================================================

 

Error 2673, 2683, 2689, and 2435 auto fix example:

INTEGER*4 STATUS
IF( .NOT. STATUS ) CALL LIB$STOP( %VAL(STATUS) )

After VX/Fortran:

IF (.NOT. (IAND(status,1) /= 0))lib$stop_return = lib$stop(%VAL(status),%VAL(0))
!---------------------------^---------------------------^-------^^-------------
!!! FPT - 2673 INTEGER used as LOGICAL corrected to LOGICAL expression
!!! FPT - 2683 CALL to a function replaced by function invocation
!!! FPT - 2689 Name already referenced as a FUNCTION used as a SUBROUTINE
!!! FPT - 2435 Missing argument(s) inserted
!------------------------------------------------------------------------------

===============================================================================

Error 3085

IF ( REAL_LENGTH .GT. 0) THEN

After VX/Fortran:

IF (real_length > 0) THEN
!------------------------------------------^-----------------------------------
!!! FPT - 3085 Objects of .EQ., .NE. .GT. etc. are of different data types
!------------------------------------------------------------------------------