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

Tool to add IMPLICIT NONE ?

ferrad01
Beginner
1,629 Views
I have inherited a large amount to F77 code which does not use IMPLICIT NONE. Is there a tool to automatically add IMPLICIT NONE and the relevant variable definitions to all the source?
0 Kudos
20 Replies
mecej4
Honored Contributor III
1,620 Views
Polyhedron's SPAG can do this and more.

However, just adding declarations using a tool will not do away with the need for manual intervention to detect and remove unused variables, incorrect declarations or slightly misspelled variable names.

0 Kudos
abhimodak
New Contributor I
1,620 Views
Hi

This is probably not "diplomatically correct" -- but check-out refactoring tools provided by Photran 6.0. You can do quite a few things including adding implicit none and removal of unused variables. Of course, no-one (including SPAG other such tools) gives 100% guarantee.

Abhi
0 Kudos
jimdempseyatthecove
Honored Contributor III
1,620 Views
Using Visual Studio's Find in Files for entire solution for "subroutine"
Insert IMPLICIT NONE in the first appropriate file
Copy to Paste buffer
Then click on next file, look and conditionally paste.

The do the same thing for "function".

You should be able to do this in under 5 seconds per occurance.
720 subroutines/functions per hour.

Also, the walk-though may be beneficial for noticing additional conversion/maintenance issues.

I'd suggest putting comment markers in a side file (issues file)as you detect issues. Use a unique comment indicator, perhaps your nameinitials plus sequence number. Paste a copy of the new comment into the source file for use later.
The when prior issue detected simply copy and paste the comment into the file as you perform the insertion of IMPLICIT NONE.

When you have the IMPLICIT NONE pass complete, save your comments file.

I would suggest attempting a Build before addressing the additional issues in the issues file.
Note, your first issue might read"

! Ferrad 001 - Insert IMPLICIT NONE in subroutines and functions (copy and paste from following line)
IMPLICIT NONE

! Ferrad 002 - Move COMMON to Module

! Ferrad 002 - ...

and so on.

Jim
0 Kudos
bendel_boy1
Beginner
1,620 Views
You could also look at the fntcheck tool for Fortran 77, or the various f77 to f90 free tools.

Or write a small utility in (say) Basic to open all your .f?? files and write IMPLICIT NONE after the first PROGRAM, SUBROUTINE or FUNCTION statements - you may want to check for multi-line statements ...
0 Kudos
ferrad01
Beginner
1,620 Views
I tried SPAG but unfortunately it does not look (consistently) inside USE'd modules for variables and inserts declarations in the SUBROUTINE as well, so I end up with vast amounts of duplicate variables.
0 Kudos
ferrad01
Beginner
1,620 Views
Thanks Jim, but I actually want the declarations too. I looked at SPAG but it has problems with modules, so I'll take a look at Photran.
0 Kudos
mecej4
Honored Contributor III
1,620 Views
I am not sure what you tried; perhaps you can show a small example for which your SPAG run produced duplicate variables. Secondly, modules are an extension to Fortran 77, so there is a question as to which extension of Fortran-77 you use.

Nevertheless, given the input
[fortran]      module mymod
      integer a,b
      end
c
      program myprog
      use mymod
      a = 15
      b = a+20
      write(*,*)a,b
      end[/fortran]
the command
[bash]spag 4=2 ferrad.f[/bash]
produces the output (with SPAG-added comments removed)

[fxfortran]      MODULE MYMOD
IMPLICIT NONE
INTEGER a , b
END
c
PROGRAM MYPROG
USE MYMOD
IMPLICIT NONE
a = 15
b = a + 20
WRITE (*,*) a , b
END[/fxfortran]
0 Kudos
ferrad01
Beginner
1,620 Views
The problem appears to be caused by modules which USE other modules. Example below:

ALLMODU.FOR:

module MaxMaterialCodes
INTEGER, PARAMETER :: NNMATC = 10
end module MaxMaterialCodes

MODULE PROBOL
USE MaxMaterialCodes
INTEGER NNIN
END MODULE PROBOL


REDMATC.FOR:
SUBROUTINE REDMATC
USE PROBOL

IMPLICIT REAL(8) (A-H,O-Z)

DO 100 j = 1 , NU
DO 50 i = 1 , nnmatc
NCUmp = NCOmp+1
50 CONTINUE
100 CONTINUE

RETURN
END

SPAG *.for returns:

ALLMODU.SPG:
!*==MAXMATERIALCODES.spg processed by SPAG 6.60Dc at 13:36 on 13 Sep 2010
MODULE MAXMATERIALCODES
IMPLICIT NONE
!*--MAXMATERIALCODES4
INTEGER , PARAMETER :: NNMATC = 10
END
!*==PROBOL.spg processed by SPAG 6.60Dc at 13:36 on 13 Sep 2010
c
MODULE PROBOL
USE MAXMATERIALCODES
IMPLICIT NONE
!*--PROBOL12

INTEGER nnin
END


REDMATC.SPG:

!*==REDMATC.spg processed by SPAG 6.60Dc at 13:36 on 13 Sep 2010
C
SUBROUTINE REDMATC

USE PROBOL
IMPLICIT NONE
!*--REDMATC7
C*** Start of declarations inserted by SPAG
INTEGER i , j , ncomp , ncump , nnmatc , nu
C*** End of declarations inserted by SPAG

DO 100 j = 1 , nu
DO 50 i = 1 , nnmatc
ncump = ncomp + 1
50 CONTINUE
100 CONTINUE

RETURN
END




Note NNMATC is declared twice resulting in a compilation error.


0 Kudos
Lorri_M_Intel
Employee
1,620 Views
To rewind back to your original question ... you can try using the command line option

/warn:declarations

That essentially does an "implicit none" for each program unit.

-- Lorri
0 Kudos
ferrad01
Beginner
1,620 Views
Yes, good idea. However it means I'll have to write a parser to convert the compiler output into the relevant declarations and put them into the code.
0 Kudos
abhimodak
New Contributor I
1,620 Views
Hi ferrad01

Did you try Photran? Below are two sample results.

Abhi


======

Case 1:

Subroutine Test
do i=1,N
NC = NC + 1
end do
End Subroutine Test

Refactoring (Introduce Implicit None) gives

Subroutine Test
implicit none
integer :: i
integer :: n
integer :: nc
do i=1,N
NC = NC + 1
end do
End Subroutine Test

------

Case 2:

Module OM
Integer :: N
End Module OM
Subroutine Test
Use OM
do i=1,N
NC = NC + 1
end do
End Subroutine Test

Refactoring yields--

Module OM
Integer :: N
End Module OM
Subroutine Test
implicit none
integer :: i
integer :: nc
Use OM
do i=1,N
NC = NC + 1
end do
End Subroutine Test
0 Kudos
ferrad01
Beginner
1,620 Views
Before I jump through the hoops required to install this, can it do nested modules as in my simple example I posted above which fails in SPAG?
0 Kudos
abhimodak
New Contributor I
1,620 Views
Hi ferrad

Below is the result of another test and your sample.

Abhi


---

Module Water
Integer :: N
End Module Water

Module Earth
Use Water
Integer :: M
End Module Earth

Subroutine Test
Use Earth
do j=1,M
do i=1,N
NC = NC + (i+j)
end do
end do
End Subroutine Test

Reactoring gives =>

Module Water
Integer :: N
End Module Water

Module Earth
Use Water
Integer :: M
End Module Earth

Subroutine Test
Use Earth
implicit none
integer :: i
integer :: j
integer :: nc
do j=1,M
do i=1,N
NC = NC + (i+j)
end do
end do
End Subroutine Test

(In the test, if use Earth is commented out then M and N are added as well.)


====

Your sample gets refactored to =>

module MaxMaterialCodes
INTEGER, PARAMETER :: NNMATC = 10
end module MaxMaterialCodes

MODULE PROBOL
USE MaxMaterialCodes
INTEGER NNIN
END MODULE PROBOL

SUBROUTINE REDMATC
USE PROBOL
implicit none
integer :: i
integer :: j
integer :: ncomp
integer :: ncump
integer :: nu
DO 100 j = 1 , NU
DO 50 i = 1 , nnmatc
NCUmp = NCOmp+1
50 CONTINUE
100 CONTINUE

RETURN
END



0 Kudos
ferrad01
Beginner
1,620 Views
So it looks like it deals with nested USE's, so I'll look into using it now.
Thanks... ferrad
0 Kudos
ferrad01
Beginner
1,620 Views
It just fails when I try my full project. I get:

An unexpected exception occurred during condition checking. See the error
log for more details.

See the error log for more details

The error log is not at all helpful.
0 Kudos
abhimodak
New Contributor I
1,620 Views
I apologize that I am perhaps taking too much liberty to discuss the issues not exactly related to IVF --

Ferrad01, what does it complain about? Java parsing error or something else? Do you get something like unexpected character in column 1 line 3? Is it possible to give some more details of the error log?

Abhi
0 Kudos
John4
Valued Contributor I
1,620 Views
Can you post the error log?

Some tips, related to eclipse/photran, that might help:

  • The latest version of eclipse tends to misbehave when installed to a read-only location ---Not sure if that might be your problem, though.
  • Try increasing the maximum amount of memory java can use ---in the past, the "implicit none" feature required about 3 GB per every 5000 lines of code (not sure if that has improved).
  • photran uses its own dialect of fpp (i.e., it gives errors for things Intel's fpp and GNU's cpp accept without problem), so that might complicate things.

0 Kudos
ferrad01
Beginner
1,620 Views

!ENTRY org.eclipse.ltk.ui.refactoring 4 10000 2010-09-14 08:24:22.721
!MESSAGE Internal Error
!STACK 0
java.lang.reflect.InvocationTargetException
at org.eclipse.jface.operation.ModalContext.run(ModalContext.java:421)
at org.eclipse.jface.dialogs.ProgressMonitorDialog.run(ProgressMonitorDialog.java:507)
at org.eclipse.ui.internal.progress.ProgressMonitorJobsDialog.run(ProgressMonitorJobsDialog.java:275)
at org.eclipse.ui.internal.progress.ProgressManager$5.run(ProgressManager.java:960)
at org.eclipse.swt.custom.BusyIndicator.showWhile(BusyIndicator.java:70)
at org.eclipse.ui.internal.progress.ProgressManager.busyCursorWhile(ProgressManager.java:995)
at org.eclipse.ui.internal.progress.ProgressManager.busyCursorWhile(ProgressManager.java:970)
at org.eclipse.ltk.ui.refactoring.RefactoringWizardOpenOperation.checkInitialConditions(RefactoringWizardOpenOperation.java:205)
at org.eclipse.ltk.ui.refactoring.RefactoringWizardOpenOperation.access$0(RefactoringWizardOpenOperation.java:200)
at org.eclipse.ltk.ui.refactoring.RefactoringWizardOpenOperation$1.run(RefactoringWizardOpenOperation.java:163)
at org.eclipse.swt.custom.BusyIndicator.showWhile(BusyIndicator.java:70)
at org.eclipse.ltk.ui.refactoring.RefactoringWizardOpenOperation.run(RefactoringWizardOpenOperation.java:192)
at org.eclipse.ltk.ui.refactoring.RefactoringWizardOpenOperation.run(RefactoringWizardOpenOperation.java:115)
at org.eclipse.rephraserengine.internal.ui.actions.RefactoringAction.run(RefactoringAction.java:140)
at org.eclipse.jface.operation.ModalContext.runInCurrentThread(ModalContext.java:464)
at org.eclipse.jface.operation.ModalContext.run(ModalContext.java:372)
at org.eclipse.jface.dialogs.ProgressMonitorDialog.run(ProgressMonitorDialog.java:507)
at org.eclipse.ui.internal.progress.ProgressMonitorJobsDialog.run(ProgressMonitorJobsDialog.java:275)
at org.eclipse.ui.internal.progress.ProgressManager.run(ProgressManager.java:1162)
at org.eclipse.ui.internal.progress.ProgressManager$RunnableWithStatus.run(ProgressManager.java:1346)
at org.eclipse.swt.custom.BusyIndicator.showWhile(BusyIndicator.java:70)
at org.eclipse.ui.internal.progress.ProgressManager$7.run(ProgressManager.java:1184)
at org.eclipse.swt.widgets.Synchronizer.syncExec(Synchronizer.java:179)
at org.eclipse.ui.internal.UISynchronizer.syncExec(UISynchronizer.java:150)
at org.eclipse.swt.widgets.Display.syncExec(Display.java:4584)
at org.eclipse.ui.internal.progress.ProgressManager.runInUI(ProgressManager.java:1182)
at org.eclipse.rephraserengine.internal.ui.actions.RefactoringAction.run(RefactoringAction.java:116)
at org.eclipse.rephraserengine.internal.ui.actions.RefactoringAction.run(RefactoringAction.java:99)
at org.eclipse.rephraserengine.ui.menus.RefactorMenu$ResourceRefactoringContributionItem$1.widgetSelected(RefactorMenu.java:282)
at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:234)
at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:84)
at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1053)
at org.eclipse.swt.widgets.Display.runDeferredEvents(Display.java:4066)
at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3657)
at org.eclipse.ui.internal.Workbench.runEventLoop(Workbench.java:2629)
at org.eclipse.ui.internal.Workbench.runUI(Workbench.java:2593)
at org.eclipse.ui.internal.Workbench.access$4(Workbench.java:2427)
at org.eclipse.ui.internal.Workbench$7.run(Workbench.java:670)
at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:332)
at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:663)
at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:149)
at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:115)
at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196)
at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:110)
at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:79)
at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:369)
at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:179)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:619)
at org.eclipse.equinox.launcher.Main.basicRun(Main.java:574)
at org.eclipse.equinox.launcher.Main.run(Main.java:1407)
Caused by: java.lang.NullPointerException
at org.eclipse.photran.internal.core.analysis.binding.BindingCollector.bind(BindingCollector.java:142)
at org.eclipse.photran.internal.core.analysis.binding.BindingCollector.bindAsParam(BindingCollector.java:162)
at org.eclipse.photran.internal.core.analysis.binding.ReferenceCollector.visitASTSubroutineStmtNode(ReferenceCollector.java:862)
at org.eclipse.photran.internal.core.parser.ASTSubroutineStmtNode.accept(ASTSubroutineStmtNode.java:95)
at org.eclipse.photran.internal.core.parser.ASTVisitor.traverseChildren(ASTVisitor.java:21)
at org.eclipse.photran.internal.core.parser.ASTVisitor.visitASTSubroutineSubprogramNode(ASTVisitor.java:359)
at org.eclipse.photran.internal.core.parser.ASTSubroutineSubprogramNode.accept(ASTSubroutineSubprogramNode.java:100)
at org.eclipse.photran.internal.core.parser.ASTVisitor.traverseChildren(ASTVisitor.java:21)
at org.eclipse.photran.internal.core.parser.ASTVisitor.visitASTListNode(ASTVisitor.java:26)
at org.eclipse.photran.internal.core.parser.ASTListNode.accept(ASTListNode.java:130)
at org.eclipse.photran.internal.core.parser.ASTVisitor.traverseChildren(ASTVisitor.java:21)
at org.eclipse.photran.internal.core.parser.ASTVisitor.visitASTExecutableProgramNode(ASTVisitor.java:176)
at org.eclipse.photran.internal.core.parser.ASTExecutableProgramNode.accept(ASTExecutableProgramNode.java:61)
at org.eclipse.photran.internal.core.FortranAST.accept(FortranAST.java:53)
at org.eclipse.photran.internal.core.analysis.binding.Binder.bind(Binder.java:55)
at org.eclipse.photran.internal.core.vpg.PhotranVPGBuilder.populateVPG(PhotranVPGBuilder.java:468)
at org.eclipse.photran.internal.core.vpg.PhotranVPGBuilder.populateVPG(PhotranVPGBuilder.java:1)
at org.eclipse.rephraserengine.core.vpg.VPG.computeEdgesAndAnnotations(VPG.java:203)
at org.eclipse.rephraserengine.core.vpg.VPG.acquireTransientAST(VPG.java:147)
at org.eclipse.rephraserengine.core.vpg.VPG.forceRecomputationOfEdgesAndAnnotations(VPG.java:292)
at org.eclipse.rephraserengine.core.vpg.eclipse.EclipseVPG.indexIfNotUpToDate(EclipseVPG.java:406)
at org.eclipse.rephraserengine.core.vpg.eclipse.EclipseVPG$WorkspaceSyncResourceVisitor.index(EclipseVPG.java:207)
at org.eclipse.rephraserengine.core.vpg.eclipse.EclipseVPG.ensureVPGIsUpToDate(EclipseVPG.java:132)
at org.eclipse.rephraserengine.core.vpg.refactoring.VPGRefactoring.checkInitialConditions(VPGRefactoring.java:63)
at org.eclipse.ltk.core.refactoring.CheckConditionsOperation.run(CheckConditionsOperation.java:83)
at org.eclipse.core.internal.resources.Workspace.run(Workspace.java:1975)
at org.eclipse.ltk.internal.ui.refactoring.WorkbenchRunnableAdapter.run(WorkbenchRunnableAdapter.java:87)
at org.eclipse.jface.operation.ModalContext$ModalContextThread.run(ModalContext.java:121)
Root exception:
java.lang.NullPointerException
at org.eclipse.photran.internal.core.analysis.binding.BindingCollector.bind(BindingCollector.java:142)
at org.eclipse.photran.internal.core.analysis.binding.BindingCollector.bindAsParam(BindingCollector.java:162)
at org.eclipse.photran.internal.core.analysis.binding.ReferenceCollector.visitASTSubroutineStmtNode(ReferenceCollector.java:862)
at org.eclipse.photran.internal.core.parser.ASTSubroutineStmtNode.accept(ASTSubroutineStmtNode.java:95)
at org.eclipse.photran.internal.core.parser.ASTVisitor.traverseChildren(ASTVisitor.java:21)
at org.eclipse.photran.internal.core.parser.ASTVisitor.visitASTSubroutineSubprogramNode(ASTVisitor.java:359)
at org.eclipse.photran.internal.core.parser.ASTSubroutineSubprogramNode.accept(ASTSubroutineSubprogramNode.java:100)
at org.eclipse.photran.internal.core.parser.ASTVisitor.traverseChildren(ASTVisitor.java:21)
at org.eclipse.photran.internal.core.parser.ASTVisitor.visitASTListNode(ASTVisitor.java:26)
at org.eclipse.photran.internal.core.parser.ASTListNode.accept(ASTListNode.java:130)
at org.eclipse.photran.internal.core.parser.ASTVisitor.traverseChildren(ASTVisitor.java:21)
at org.eclipse.photran.internal.core.parser.ASTVisitor.visitASTExecutableProgramNode(ASTVisitor.java:176)
at org.eclipse.photran.internal.core.parser.ASTExecutableProgramNode.accept(ASTExecutableProgramNode.java:61)
at org.eclipse.photran.internal.core.FortranAST.accept(FortranAST.java:53)
at org.eclipse.photran.internal.core.analysis.binding.Binder.bind(Binder.java:55)
at org.eclipse.photran.internal.core.vpg.PhotranVPGBuilder.populateVPG(PhotranVPGBuilder.java:468)
at org.eclipse.photran.internal.core.vpg.PhotranVPGBuilder.populateVPG(PhotranVPGBuilder.java:1)
at org.eclipse.rephraserengine.core.vpg.VPG.computeEdgesAndAnnotations(VPG.java:203)
at org.eclipse.rephraserengine.core.vpg.VPG.acquireTransientAST(VPG.java:147)
at org.eclipse.rephraserengine.core.vpg.VPG.forceRecomputationOfEdgesAndAnnotations(VPG.java:292)
at org.eclipse.rephraserengine.core.vpg.eclipse.EclipseVPG.indexIfNotUpToDate(EclipseVPG.java:406)
at org.eclipse.rephraserengine.core.vpg.eclipse.EclipseVPG$WorkspaceSyncResourceVisitor.index(EclipseVPG.java:207)
at org.eclipse.rephraserengine.core.vpg.eclipse.EclipseVPG.ensureVPGIsUpToDate(EclipseVPG.java:132)
at org.eclipse.rephraserengine.core.vpg.refactoring.VPGRefactoring.checkInitialConditions(VPGRefactoring.java:63)
at org.eclipse.ltk.core.refactoring.CheckConditionsOperation.run(CheckConditionsOperation.java:83)
at org.eclipse.core.internal.resources.Workspace.run(Workspace.java:1975)
at org.eclipse.ltk.internal.ui.refactoring.WorkbenchRunnableAdapter.run(WorkbenchRunnableAdapter.java:87)
at org.eclipse.jface.operation.ModalContext$ModalContextThread.run(ModalContext.java:121)

0 Kudos
ferrad01
Beginner
1,483 Views
Where do I get nag_decs95 from? NAG's website says:

NAGWare Fortran Tools

Effective 17 January 2008, NAGWare Fortran Tools has been withdrawn from the NAG product portfolio.
0 Kudos
Reply