Skip to content

davidpfister/benchmark.f

Contributors Forks Stargazers Issues MIT License


Benchmark.f

A KISS library for benchmarking Fortran functions and subroutines with precision.
Explore the project »

[TOC]

Introduction

About the Project

Fortran is the fastest language on earth, so they say. But can we prove it?

Despite its legendary speed when crunching numbers, Fortran is no exception when it comes to writing code: it's also very possible to write terribly slow pieces of code. This is where benchmarking different implementations of the same function can help developing better and faster algorithms.

This project aims at providing an easy interface to benchmark functions and subroutines while taking care of warming up the machine, collecting system information, computing statistics and reporting results.

  • fpm
  • ifort
  • gfortran

Getting Started

Requirements

To build that library you need

  • a Fortran 2008 compliant compiler, or better, a Fortran 2018 compliant compiler (Intel Fortran compiler is known to work well for benchmark.f. gfortran has some limitations when using implicit procedures and unlimited polymorphic arguments. Please refer to the documentation to see the difference between compilers).

The following compilers are tested on the default branch of benchmark.f:

Name Version Platform Architecture
GCC Fortran (MinGW) 14 Windows 10 x86_64
Intel oneAPI classic 2021.5 Windows 10 x86_64
  • a preprocessor. benchmark.f uses quite some preprocessor macros. It is known to work both with intel fpp and cpp.

Unit test rely on the the header file assertion.inc. Since the whole framework fits in a single file, it has been added directly to the repo.

Linting, indentation, and styling is done with fprettify with the following settings

fprettify .\src\ -r --case 1 1 1 1 -i 4 --strict-indent --enable-replacements --strip-comments --c-relations

Usage

Running the benchmark could not be simpler.

  1. Start by including the file benchmark.inc into your code
  2. Instantiate a benchmark runner
  3. Run the benchmark

The first step is to create a test function. It can be a function or a subroutine (gfortran only handles subroutine. For more issues related to gfortran, see this article ) with any number of arguments between 0 and 7.

!the funcion to be benchmarked
subroutine test_function()
...
end subroutine

And then simply call the benchmark macro.

#include <benchmark.inc>
program test
use benchmark_library

type(runner) :: br

benchmark(br, run(test_function))

This will generate this kind of table:

 |         Method Name      |          Mean          |    Standard Deviation  |
 |__________________________|________________________|________________________|
 |test_function()           |           217350.000 us|          +/- 161306.626|

For more examples, please refer to the Documentation

The library takes care of everything else for you

  • Collection of system information
  • Collection of compiler information
  • Collection of compilation options
  • Reporting

Installation

Get the code

git clone https://github.com/davidpfister/benchmark.f
cd benchmark.f

Build with fpm

The repo can be build using fpm

fpm build --flag '-ffree-line-length-none'

For convenience, the repo also contains a response file that can be invoked as follows:

fpm @build

(For the Windows users, that command does not work in Powershell since '@' is a reserved symbol. One should use the '--%' as follows: fpm --% @build. This is linked to the following issue)

Building with ifort requires to specify the compiler name (gfortran by default)

fpm @build --compiler ifort

Alternatively, the compiler can be set using fpm environment variables.

set FPM_FC=ifort

Besides the build command, several commands are also available:

@pretiffy
system fprettify .\examples\ -r --case 1 1 1 1 -i 4 --strict-indent --enable-replacements --strip-comments --c-relations
system fprettify .\src\ -r --case 1 1 1 1 -i 4 --strict-indent --enable-replacements --strip-comments --c-relations
system fprettify .\tests\ -r --case 1 1 1 1 -i 4 --strict-indent --enable-replacements --strip-comments --c-relations

@clean
option clean --all

@rebuild
system rmdir /s /q build
option build --flag '-ffree-line-length-none'

@build
option build --flag '-ffree-line-length-none'

@test
options test --flag '-ffree-line-length-none'

@doc
option clean --all
system cd ./.dox & doxygen ./Doxyfile.in & cd ..

The toml files contains two items that are worth commenting:

  1. The settings to the cpp preprocessor are specified in the file.
[preprocess]
cpp.suffixes = ["F90", "f90"]
cpp.macros = ["_FPM"]

The _FPM macro is used to differentiate the build when compiling with fpm or Visual Studio. This is mostly present to adapt the hard coded paths that differs in both cases.

  1. The code must also be compiled allowing implicit procedures. This is reflected in the following option.
[fortran]
implicit-external = true

In order to be able to benchmark functions AND subroutines with any number of dummy arguments (0 to 7 at the moment) of any types (intrinsic or derived types), implicit procedures are a must. While this may be considered as bad practice and a remainder from F77 and the good old external, there would be no other way to provide a generic library without this option.

Build with Visual Studio 2019

The project was originally developed on Windows with Visual Studio 2019. The repo contains the solution file (Benchmark.f.sln) to get you started with Visual Studio 2019.

Contributing

Contributions are what make the open source community such an amazing place to learn, inspire, and create. Any contributions you make are greatly appreciated. So, thank you for considering contributing to fpm-modules. Please review and follow these guidelines to make the contribution process simple and effective for all involved. In return, the developers will help address your problem, evaluate changes, and guide you through your pull requests.

License

Distributed under the MIT License.

About

Benchmarking library for fortran code

Topics

Resources

License

Code of conduct

Contributing

Stars

Watchers

Forks

Contributors