Skip to main content

HYCOM correctness, modernization & security

Goal

Learn how to use Codee to ensure correctness, security and modernize HYCOM, an ocean modeling system consisting of dozens of files.

Getting ready

For this demonstration, we will use HYCOM, an ocean modeling system consisting of dozens of files. Start by cloning the repository and navigating to the source code:

cd codee-demos/Fortran/HYCOM/src

Walkthrough

1. Generate the compile_commands.json

The project comes with a Makefile, so we can leverage the tool bear (version 3 or later) to generate the compile_commands.json file required by Codee:

bear -- make

It's a simple as prepending bear -- to the make invocation. This command will produce a compile_commands.json file with all the compiler invocations needed to build the source files.

2. Run the screening report

To explore the recommendations of the Open Catalog that are applicable to HYCOM, let's run Codee's screening report; use --compile-commands (or -p as its short version) to point to the compilation database:

Codee command
codee screening --compile-commands compile_commands.json
Codee output
Note: the compilation database entries will be analyzed in the order necessary to meet module dependencies between Fortran source files.
Configuration file 'compile_commands.json' successfully parsed.
Date: 2025-01-02 Codee version: 2024.4.2 License type: Modern
Performing Fortran module dependency analysis... Done

[ 1/50] mod_dimensions.F90 ... Done
[ 2/50] mod_xc.F90 ... Done
<...>
[50/50] hycom.F90 ... Done

SCREENING REPORT

---Number of files---
Total | C C++ Fortran
----- | - --- -------
50 | 1 0 49

RANKING OF QUALITY CHECKERS

Checker Category Priority AutoFixes # Title
------- ----------- -------- --------- ---- ---------------------------------------------------------------------------------------
PWR008 correctness P18 (L1) 10 196 Declare the intent for each procedure parameter
PWR007 correctness P18 (L1) 19 20 Disable implicit declaration of variables
PWR075 modern P12 (L1) 20 Avoid using GNU Fortran extensions
PWR063 modern P12 (L1) 19 Avoid using legacy Fortran constructs
PWR068 correctness P9 (L2) 192 Encapsulate procedures within modules to avoid the risks of calling implicit interfaces
PWR069 correctness P6 (L2) 146 146 Use the keyword only to explicitly state what to import from a module
PWR070 correctness P6 (L2) 74 Declare array dummy arguments as assumed-shape arrays
PWR003 modern P6 (L2) 2 Explicitly declare pure functions
PWR071 modern P3 (L3) 831 Prefer real(kind=kind_value) for declaring consistent floating types
PWR073 modern P3 (L3) 5 Transform common block into a module for better data encapsulation
PWR001 correctness P1 (L3) 188 Declare global variables as function parameters
------- ----------- -------- --------- ---- ---------------------------------------------------------------------------------------
Total 175 1693

SUGGESTIONS

Use 'roi' to get a return of investment estimation report:
codee roi --compile-commands compile_commands.json

Get a breakdown per file of the Screening Report (--verbose), focusing on one specific checker (--check-id), e.g.:
codee screening --verbose --check-id PWR008 --compile-commands compile_commands.json

50 files, 251 functions, 2058 loops, 44679 LOCs successfully analyzed (1693 checkers) and 0 non-analyzed files in 55.54 s

3. Re-run the screening report with --verbose

Let's focus the analysis on one of the reported checkers. We can filter Codee's output with the --check-id flag. For example, let's pick PWR008, for which Codee has AutoFixes available while is a checker of high priority P18 (L1). At the same time, let's add the --verbose flag, so we can see the specific list of files where at least one PWR008 was triggered.

Codee command
codee screening --verbose --compile-commands compile_commands.json --check-id PWR008
Codee output
Note: the compilation database entries will be analyzed in the order necessary to meet module dependencies between Fortran source files.
Configuration file 'compile_commands.json' successfully parsed.
Date: 2025-01-02 Codee version: 2024.4.2 License type: Modern
Performing Fortran module dependency analysis... Done

[ 1/50] mod_dimensions.F90 ... Done
[ 2/50] mod_xc.F90 ... Done
<...>
[50/50] hycom.F90 ... Done

SCREENING REPORT

---Number of files---
Total | C C++ Fortran
----- | - --- -------
50 | 1 0 49

Target # checks Check IDs
------------------ -------- ----------
forfun.F90 23 PWR008(23)
s8gefs.F90 18 PWR008(18)
hybgen.F90 11 PWR008(11)
mxkprf.F90 11 PWR008(11)
mod_floats.F90 10 PWR008(10)
diapfl.F90 10 PWR008(10)
mod_tides.F90 9 PWR008(9)

<...>
------------------ -------- ----------
Total 196

Target : analyzed directory or source code file
# checks : total actionable items (opportunities, recommendations, defects and remarks) detected
Check IDs : list of checks reported for the target

RANKING OF QUALITY CHECKERS

Checker Category Priority AutoFixes # Title
------- ----------- -------- --------- --- -----------------------------------------------
PWR008 correctness P18 (L1) 10 196 Declare the intent for each procedure parameter
------- ----------- -------- --------- --- -----------------------------------------------
Total 10 196

SUGGESTIONS

Use 'roi' to get a return of investment estimation report:
codee roi --verbose --compile-commands compile_commands.json --check-id PWR008

Run the 'checks' report to list the checkers on screen pinpointing lines of code of a given file:
codee checks /user/codee-demos/Fortran/HYCOM/src/forfun.F90 --verbose --compile-commands compile_commands.json --check-id PWR008

50 files, 251 functions, 2058 loops, 44679 LOCs successfully analyzed (196 checkers) and 0 non-analyzed files in 45.05 s

4. Run the checks report

Use Codee's checks report to see the list of checkers reported for the file s8gefs.F90, which in this case was one of the files with the highest number of PWR008 reported:

Codee command
codee checks --compile-commands compile_commands.json --check-id PWR008 s8gefs.F90 --verbose
Codee output
Note: the compilation database entries will be analyzed in the order necessary to meet module dependencies between Fortran source files.
Configuration file 'compile_commands.json' successfully parsed.
Date: 2024-11-14 Codee version: 2024.4 License type: Modern

<...>
s8gefs.F90:955:7 [PWR008] (level: L1): Declare the intent for each procedure parameter
Suggestion: Add the missing INTENT for parameter of the procedure 'I8MACH':
intent in: 'I'
Documentation: https://github.com/codee-com/open-catalog/tree/main/Checks/PWR008
AutoFix:
codee rewrite --modernization argument-intent --in-place s8gefs.F90:I8MACH --compile-commands compile_commands.json
<...>

1 file, 19 functions, 40 loops, 597 LOCs successfully analyzed (18 checkers) and 0 non-analyzed files in 1775 ms

Pick one of the occurrences of PWR008 that has an AutoFix (for example, the one pinpointing s8gefs.F90:955:7), and apply it (running the suggested codee rewrite command).

5. Autofix

Let's use Codee's autofix capabilities to automatically modernize the code:

Codee command
codee rewrite --modernization argument-intent --in-place s8gefs.F90:I8MACH --compile-commands compile_commands.json
Codee output
Note: the compilation database entries will be analyzed in the order necessary to meet module dependencies between Fortran source files.
Configuration file 'compile_commands.json' successfully parsed.
Date: 2024-11-14 Codee version: 2024.4 License type: Modern

Results for file 's8gefs.F90':
Successfully applied AutoFix to the procedure at 's8gefs.F90:955:7' [using insert argument intent]

Successfully updated s8gefs.F90

We can review the code changes to verify correctness:

diff command
git diff .
diff output
 !***ROUTINES CALLED  (NONE)
!***END PROLOGUE I8MACH
!
+ ! Codee: Added argument declaration with intent (2024-11-13 12:04:28)
+ integer, intent(in) :: I
INTEGER IMACH(16),OUTPUT
EQUIVALENCE (IMACH(4),OUTPUT)
!