Skip to main content

Open Catalog of Code Guidelines for Correctness, Modernization, and Optimization

About

This Open Catalog is a collaborative effort to consolidate expert knowledge on code guidelines for the correctness, modernization, and optimization of code written in C, C++, and Fortran programming languages. The Catalog consists of a comprehensive set of checks (rules) that describe specific issues in the source code and provide guidance on corrective actions, along with extensive documentation, example codes and references to additional reading resources.

Benchmarks

The Open Catalog includes a suite of microbenchmarks designed to demonstrate:

  • No performance degradation when implementing the correctness and modernization recommendations.
  • Potential performance enhancements achievable through the optimization recommendations.

Checks

IDTitleCFortranC++AutoFix
PWR001Declare global variables as function parameters
PWR002Declare scalar variables in the smallest possible scope
PWR003Explicitly declare pure functions
PWR004Declare OpenMP scoping for all variables
PWR005Disable default OpenMP scoping
PWR006Avoid privatization of read-only variables
PWR007Disable implicit declaration of variables1
PWR008Declare the intent for each procedure parameter1
PWR009Use OpenMP teams to offload work to GPU
PWR010Avoid column-major array access in C/C++
PWR012Pass only required fields from derived type as parameters
PWR013Avoid copying unused variables to or from the GPU
PWR014Out-of-dimension-bounds matrix access
PWR015Avoid copying unnecessary array elements to or from the GPU
PWR016Use separate arrays instead of an Array-of-Structs
PWR017Using countable while loops instead of for loops may inhibit vectorization
PWR018Call to recursive function within a loop inhibits vectorization
PWR019Consider interchanging loops to favor vectorization by maximizing inner loop's trip count
PWR020Consider loop fission to enable vectorization
PWR021Consider loop fission with scalar to vector promotion to enable vectorization
PWR022Move invariant conditional out of the loop to facilitate vectorization
PWR023Add 'restrict' for pointer function parameters to hint the compiler that vectorization is safe
PWR024Loop can be rewritten in OpenMP canonical form
PWR025Consider annotating pure function with OpenMP 'declare simd'
PWR026Annotate function for OpenMP Offload
PWR027Annotate function for OpenACC Offload
PWR028Remove pointer increment preventing performance optimization
PWR029Remove integer increment preventing performance optimization
PWR030Remove pointer assignment preventing performance optimization for perfectly nested loops
PWR031Replace call to pow by multiplication, division and/or square root
PWR032Avoid calls to mathematical functions with higher precision than required
PWR033Move invariant conditional out of the loop to avoid redundant computations
PWR034Avoid strided array access to improve performance
PWR035Avoid non-consecutive array access to improve performance
PWR036Avoid indirect array access to improve performance
PWR037Potential precision loss in call to mathematical function
PWR039Consider loop interchange to improve the locality of reference and enable vectorization1
PWR040Consider loop tiling to improve the locality of reference
PWR042Consider loop interchange by promoting the scalar reduction variable to an array
PWR043Consider loop interchange by replacing the scalar reduction value
PWR044Avoid unnecessary floating-point data conversions involving constants
PWR045Replace division with a multiplication with a reciprocal
PWR046Replace two divisions with a division and a multiplication
PWR048Replace multiplication/addition combo with an explicit call to fused multiply-add
PWR049Move iterator-dependent condition outside of the loop
PWR050Consider applying multithreading parallelism to forall loop1
PWR051Consider applying multithreading parallelism to scalar reduction loop1
PWR052Consider applying multithreading parallelism to sparse reduction loop1
PWR053Consider applying vectorization to forall loop1
PWR054Consider applying vectorization to scalar reduction loop1
PWR055Consider applying offloading parallelism to forall loop1
PWR056Consider applying offloading parallelism to scalar reduction loop1
PWR057Consider applying offloading parallelism to sparse reduction loop1
PWR060Consider loop fission to separate gather memory access pattern
PWR062Consider loop interchange by removing accumulation on array value
PWR063Avoid using legacy Fortran constructs
PWR068Encapsulate procedures within modules to avoid the risks of calling implicit interfaces
PWR069Use the keyword only to explicitly state what to import from a module1
PWR070Declare array dummy arguments as assumed-shape arrays
PWR071Prefer real(kind=kind_value) for declaring consistent floating types
PWR072Split the variable initialization from the declaration to prevent the implicit 'save' behavior
PWR073Transform common block into a module for better data encapsulation
PWR075Avoid using GNU Fortran extensions
PWD002Unprotected multithreading reduction operation
PWD003Missing array range in data copy to the GPU
PWD004Out-of-memory-bounds array access
PWD005Array range copied to or from the GPU does not cover the used range
PWD006Missing deep copy of non-contiguous data to the GPU
PWD007Unprotected multithreading recurrence
PWD008Unprotected multithreading recurrence due to out-of-dimension-bounds array access
PWD009Incorrect privatization in parallel region
PWD010Incorrect sharing in parallel region
PWD011Missing OpenMP lastprivate clause
RMK001Loop nesting that might benefit from hybrid parallelization using multithreading and SIMD
RMK002Loop nesting that might benefit from hybrid parallelization using offloading and SIMD
RMK003Potentially privatizable temporary variable
RMK007SIMD opportunity within a multithreaded region
RMK008SIMD opportunity within an offloaded region
RMK009Outline loop to increase compiler and tooling code coverage
RMK010The vectorization cost model states the loop is not a SIMD opportunity due to strided memory accesses in the loop body
RMK012The vectorization cost model states the loop is not a SIMD opportunity because conditional execution renders vectorization inefficient
RMK013The vectorization cost model states the loop is not a SIMD opportunity because loops with low trip count unknown at compile time do not benefit from vectorization
RMK014The vectorization cost model states the loop is not a SIMD opportunity due to unpredictable memory accesses in the loop body
RMK015Tune compiler optimization flags to increase the speed of the code
RMK016Tune compiler optimization flags to avoid potential changes in floating point precision

AutoFix: Denotes tools that support automatic correction of the corresponding check. Readers are encouraged to report additional tools with autofix capabilities for these checks. The tools are tagged in the table as follows:

Contributing

We welcome and encourage contributions to the Open Catalog! Here's how you can get involved:

  1. Join the discussion:

    Got ideas, questions, or suggestions? Head over to our GitHub Discussions. It's the perfect place for open-ended conversations and brainstorming!

  2. Report issues:

    Found inaccuracies, unclear explanations, or other problems? Please open an Issue. Detailed reports help us quickly improve the quality of the project!

  3. Submit pull requests:

    Interested in solving any issues? Feel free to fork the repository, make your changes, and submit a Pull Request. We'd love to see your contributions!

Footnotes

  1. Codee 2 3 4 5 6 7 8 9 10 11 12