/ ========================================== \ 
   ||                                           ||
   || FCAT: FORTRAN Coverage Analysis Tool      ||
   ||                                           ||
   ||         Version 1.0. Jan 2001.            ||
   ||             Dr. Yifan Hu                  ||
   ||                                           ||
   ||                                           ||
   || Copyright: CLRC Daresbury Laboratory 2001 ||
   ||                                           ||
    \ ========================================== / 



1. SUMMARY

The FCAT tool is used for the Coverage Analysis of FORTRAN codes.
This includes

   - finding out "cold-spot" in Fortran codes (the part of 
     the codes that are never executed), and flags these
     parts line-by-line.
      

   - finding out "hot-spot" in Fortran codes (the part of 
     the codes that are most frequently executed), and gives
     a line by line profile.

It is designed to working mainly with F90/F95, even through it can
also work with fixed formatted FORTRAN, thus F77.
     
2. IS IT GOING TO BE OF ANY USE TO ME?

For FORTRAN code developer: Finding out "cold-spot" is particularly useful
for code developers during the test stage of their software in either
eliminating these "cold-spot", or in designing more complete test
suite to fully test these parts of the codes. Finding out "hot-spot"
could be useful for developers in optimizing their code.

For FORTRAN code user: Both capability also helps a user in the analysis and
understanding of codes written by other people.

FCAT is developed out of a need for a tool in analyzing "cold-spot",
although "hot-spot" capability may be useful, they could equally be
derived using a FORTRAN profiler like pixie.


3. INSTALLING

FCAT comes in a gzipped tar file fcat.tar.gz. On Unix, you need to

  % gunzip fcat.tar.gz
  % tar xvf fcat.tar

This will create a directory FCAT, which contains two subdirectory
FCAT/example and FCAT/bin. 

You then need to add the FCAT/bin in your path, depend on your system,
this may be done by (assume FCAT resides in /home/john/FCAT)

   % setenv PATH /home/john/FCAT/bin:$PATH
   % rehash

Your can avoid type this line every time you what to use the tool by
adding the path in your .cshrc file. This is again system dependent,
e.g., you may need to add the following line to the .cshrc file:

    set path=(/home/john/FCAT/bin $path)

and type 

   % source ~/.cshrc

Also modify the first line the script FCAT/bin/fcat to give the
correct path for "perl" or "perl5" (make sure your perl is of version
5 or above. You can check this by typing "perl -V"). This may be in
/usr/local/bin/perl5, or /usr/bin/perl etc, and can usually be found
out by typing

   % which perl

Suppose on your system perl is at /usr/bin/perl, then the first 
lines of the script fcat in FCAT/bin
should be "#!/usr/bin/perl".

Once the above is done, you are ready to use the tools.

4.  USING FCAT

Suppose you have the following F90 code called "a.f90"
(available in FCAT/example).

   module sub_mod            
   contains		  
     subroutine sub1(j)	  
       integer j		  
       j = 1		  
     end subroutine sub1	  
     subroutine sub2(j)	  
       integer j		  
       j = 2		  
     end subroutine sub2	  
   end module sub_mod	  
   program junk		  
     use sub_mod		  
     integer i,j		  
     do i = 1, 100		  
        if (i > 200) then	  
           call sub1(j)	  
        else		  
           call sub2(j)	  
        end if		  
     end do		  
   end program junk          

To analyse the coverage, this is what you do:

4.1) pre-process the a.f90 code and put the output in a_new.f90. 
     Usage: fcat [options] mycode.f90 > mycode2.f90
     e.g.:

     % fcat a.f90 > a_new.f90 

4.2) compiling

     % f90 -o run a_new.f90 

4.3) run and direct the input to a file     

     % run > OUTPUT   

4.4) analyse the code coverage:
     Usage: fcat  [options] mycode.f90 my_output
     e.g.

     % fcat a.f90 OUTPUT 

The last step (4.4) writes to the screen a file which is the same as
a.f90, except that any lines that were not executed are marked with
*>. Thus for our example a.f90 we have a coverage analysis in the following

   module sub_mod            
   contains               
     subroutine sub1(j)   
       integer j                  
*>       j = 1            
     end subroutine sub1          
     subroutine sub2(j)   
       integer j                  
       j = 2              
     end subroutine sub2          
   end module sub_mod     
   program junk           
     use sub_mod                  
     integer i,j                  
     do i = 1, 100                
        if (i > 200) then         
*>           call sub1(j)  
        else             
           call sub2(j)   
        end if            
     end do               
   end program junk  


5.  WORKING ITH LARGE CODES

If your code have many subroutines/functions/modules in different
files, and you use a Makefile, it is easy to incorporate FCAT
into the Makefile. What you need to do is to create a tmp directory
where your codes are by

 % mkdir tmp

Then modify your make file so that each .f90 code is preprocessed with
FCAT first and directed to the tmp directory. The compile the
preprocessed code. FCAT/example contains a simple Makefile which can
be used to do coverage analysis for two F90 code b.f90 and c.f90, and
the original Makefile (in Makefile.old). The crucial lines are

.f90.o:
	fcat  $< > tmp/$*.f90 && \
	$(F90) $(F90FLAGS) -c tmp/$*.f90 &&\
	rm -f tmp/$*.f90



You can see the difference of the original "Makefile.old" and the
"Makefile" for coverage analysis by comparing the difference of the
two files. After making the excutable, the coverage analysis of
any of the codes works in the same way as explained before, e.g.,
to analysis the code b.f90:

   %fcat b.f90 OUTPUT

where OUTPUT is the screen OUTPUT of your excutable saved earlier.

If you are interested in analysing only a few codes out of many, you
can "treat" and compile these fews codes only, then analysis them as
detailed before.


6.  OTHER OPTIONS

A number of extra options are available, for example, for
"hot-spot" analysis. They are listed the the following

6.1 Dealing with fixed format FORTRAN

For preprocessing: 

         fcat -fixedform (or -fixedformat) mycode.f90 > my_newcode.f90

and for post-processing:

         fcat -fixedform (or -fixedformat) mycode.f90 > myoutput 


This option should be used when pre/post processing FORTRAN
in fixed format.

6.2 "Hot-spot" analysis

The options "-count" can be used for "hot-spot analysis". To use this
option, you must PUT THE CODE YOU WANT TO ANALYSE TOGETHER WITH THE
MAIN PROCEDURE IN ONE FILE!

For preprocessing:

       fcat -count mycode.f90 > my_newcode.f90 

and for post-processing:

       fcat -count mycode.f90 myoutput

Which will write out "mycode.f90" with each executable line marked 
either with "*>" for not being executed, or an integer count of
the number of time this line has been executed.

Furthermore, you can also get a list of lines in decreasing ordering 
of the number of times each line is executed by post-processing with

       fcat -count -report mycode.f90 myoutput

For example, applying fcat with -count for preprocessing and with
-count -report for post-processing on the previous code a.f0 gives:

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

             FCAT REPORT
      a list of executable lines
  sorted by number of time each is executed

line_num  procedure_name  count
-------------------------------
22  main  100
21  main  100
20  main  100
19  main  100
17  main  100
10  sub2  100
16  main  1
=========================================

             FCAT SUMMARY REPORT

   Code a.f90 has 24 lines: 
   8 are executable lines
   of which 2 are not executed
=========================================

7. COVERAGE ANALYSIS FOR PARALLEL CODES

FCAT offers some facility for the coverage analysis of parallel codes.
It treats a line as being excuted if at least one processor has
excuted it. The counter for the line is taken as the maximum of the
number of times this line has been excuted over all processors. E.g.,
if the code has been run on two processors and a line was excuted 5
times on processor one and 0 times on processor two, then the counter
for this line is 5.

WARNING: because the output of the instrumented code of all processors
is written to the same standard output, on some parallel computers an
output string may be half-written, then followed by another
string. This is can cause problem to FCAT. In such event you may
have to run the code again (no need to recompile) and hopefully the
problem will not repeat itself.

More comprehensive support for parallel analysis may be added if there
is a sufficient demand.


8. OTHER INFORMATION AND TROUBLE SHOOTING

8.1 File suffix

FCAT can work with file suffix of .F, .f, .F90, .f90. 

8.2 Restriction

FCAT may not work very well with "statement functions", which is
deprecated in F90. Should you program contain such functions and the
compilation failed on a preprocessed file at one of these functions,
you could edit out calls of the form "FCAT_XXX(XXX)" just before the
statement function (you compiler will fail on these lines and will
tell you where they are) from the preprocessed files, before try to
compiling the file again on its own.

8.3 Trouble shooting

If you see "fcat command not find", it is most likely that either

*) fcat is not in your path, type
    % which fcat
   to see if the correct fcat path is given

*) Or you have not modified the first line of 
      FCAT/bin/fcat 
   to give the correct path for Perl.
   
8.4 Bug reporting

While FCAT has been tested on ~300K lines of FORTRAN codes (mostly F90)
written by many different people, it is impossible to guarantee that
it will work correctly on your code. Should you experience problem,
please send me an e-mail together with the offending code.  I would
also like to hear from you comments and success stories!

Enjoy!


ACKNOWLEDGEMENT:

Thanks are due to my colleagues, particularly Dr. Robert Allan and
Prof. John Reid, for testing this software and giving valuable
comments.