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
初學者
2,454 檢視
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 積分
20 回應
mecej4
榮譽貢獻者 III
2,445 檢視
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.

abhimodak
新貢獻者 I
2,445 檢視
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
jimdempseyatthecove
榮譽貢獻者 III
2,445 檢視
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
bendel_boy1
初學者
2,445 檢視
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 ...
ferrad01
初學者
2,445 檢視
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.
ferrad01
初學者
2,445 檢視
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.
mecej4
榮譽貢獻者 III
2,445 檢視
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]
ferrad01
初學者
2,445 檢視
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.


Lorri_M_Intel
員工
2,445 檢視
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
ferrad01
初學者
2,445 檢視
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.
abhimodak
新貢獻者 I
2,445 檢視
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
ferrad01
初學者
2,445 檢視
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?
abhimodak
新貢獻者 I
2,445 檢視
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



ferrad01
初學者
2,445 檢視
So it looks like it deals with nested USE's, so I'll look into using it now.
Thanks... ferrad
ferrad01
初學者
2,445 檢視
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.
abhimodak
新貢獻者 I
2,445 檢視
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
John4
傑出貢獻者 I
2,445 檢視
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.

ferrad01
初學者
2,445 檢視

!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)

ferrad01
初學者
2,308 檢視
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.
回覆