Does ifort support automatic code generation for only covered code for a particular run? I would like to hack a project down into smaller pieces that I most frequently used. For my current needs I only use maybe 10% percent of a particular code. It would be good to automate the generation of a reduced version that wouldn't include the remaining 90%....
Lets say I have a program that uses 4 modules but only covers code from 2 of them for a particular run:
file: test.f90 program test use module1 use module2 use module3 use module4 call prinstuff1() call prinstuff2() end program test
file: module1.f90 module module1 contains subroutine prinstuff1 print *, 'I am module 1' end subroutine end module
file: module2.f90 module module2 contains subroutine prinstuff2 print *, 'I am module 2' end subroutine end module
file: module3.f90 module module3 contains subroutine prinstuff3 print *, 'I am module 3' end subroutine end module
file: module4.f90 module module4 contains subroutine prinstuff4 print *, 'I am module 4' end subroutine end module
The main program only calls routines from modules 1 and 2. After this kind of functionality I am seeking it would result in the following:
file:test_1.f90 program test use module1 use module2 call prinstuff1() call prinstuff2() end program test
file:module1_1.f90 module module1 contains subroutine prinstuff1 print *, 'I am module 1' end subroutine end module
file:module2_1.f90 module module2 contains subroutine prinstuff2 print *, 'I am module 2' end subroutine end module
Which is what I mean when I say "hack it down" into a smaller version of the same program. Anything remotely close to this in ifort? Short of copying and pasting covered code from a coverage run manually (which could take days)....
What you might be interested in is automatic code refactoring: if so, you can look elsewhere for help, say starting here - https://en.wikipedia.org/wiki/Code_refactoring#Automated_code_refactoring
For the kind of code you show in Quote #3, I would strongly suggest TWO basic coding aspects as a starting point toward code refactorng:
So the code will then appear:
module module1 implicit none (type, external) contains subroutine prinstuff1 print *, 'I am module 1' end subroutine end module module module2 implicit none (type, external) contains subroutine prinstuff2 print *, 'I am module 2' end subroutine end module
And initially the test.f90 can be refactored to include IMPLICIT NONE (TYPE, EXTERNAL) as well as 'empty' USE <xx>, ONLY : statements:
program test ! Iteration 1 use module1, only : use module2, only : use module3, only : use module4, only : implicit none (type, external) call prinstuff1() call prinstuff2() end program test
which will then lead to compilation errors along the lines of
test.f90:31:17: call prinstuff1() 1 Error: Procedure 'prinstuff1' called at (1) is not explicitly declared test.f90:32:17: call prinstuff2() 1 Error: Procedure 'prinstuff2' called at (1) is not explicitly declared
Coder can then easily fix the above with
program test use module1, only : prinstuff1 use module2, only : prinstuff2 use module3, only : use module4, only : implicit none (type, external) call prinstuff1() call prinstuff2() end program test
leading to successful compilation. Then the programmer can strip all the 'empty' USE statements to yield:
program test use module1, only : prinstuff1 use module2, only : prinstuff2 implicit none (type, external) call prinstuff1() call prinstuff2() end program test
Clearly it can be painstaking to do such refactoring for large codes but it is feasible nonetheless. But I personally doubt there are any tools that can automatically and reliably refactor the Fortran code like so, but readers can investigate and report here if they locate any. Also, some bravhearts might be motivated to automate the above steps, good luck to them!
I agree with FortranFan that you should manually refactor the code (barring you locating a tool elsewhere).
Coding with a list of USE statements that encompass all available modules is bad practice and can get you into trouble in the event that your modules may come from different vendors and which may have the same entry point names and/or variable names.
I haven't used the empty ONLY clause. I prefer to simply comment out the USE statement(s) until all errors resolved. Then I remove the unnecessary ones.
Note, it may be confusing for the next code maintainer to have a USE statement referencing a missing module file.
Thanks for your responses. It sounds like this is not such an easy task and might need additional investigation. @gib, I would like to do this because I have inherited a large, badly documented program that I need to work on. It uses a number of finite element routines to simulate solid and fluid mechanics problems. I only use the dynamic solid mechanics portion of the code to do dynamic simulation of buildings under hurricane loads, for example. I also use a couple of add-ons but this only amounts to about 10% of the code as I mentioned.
Also the code is so interrelated and the modules are quite dis-organized since the developers who created this code are not necessarily software engineers who know what they're doing. Mostly Fortran enthusiasts and amateurs. I need to basically dumb the code down to something restricted and manageable, suited to my own purposes. I would eventually like to simplify that dumbed down version and then apply the same to other parts of the code as needed.
OK, I understand. It sounds to me like a lot a manual work. Presumably you can identify modules that are obviously part of the fluid mechanics functionality, and remove them. The complication would arise when these modules contain procedures that are used for the solid mechanics as well. Compilation would reveal those missing procedures, which you'd then have to move to another module. I can see that it could get complicated.