Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adds How-To for using OpenMP to calculate PI #128

Merged
merged 1 commit into from
Oct 12, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 51 additions & 0 deletions pages/how-to/compute-pi-openmp.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# Computing PI with OpenMP

This is a simple example of how to use OpenMP with fpm.
It is an adapted version of the OpenMP example that can be found
[here](https://github.com/gjbex/Fortran-MOOC/blob/master/source_code/computing_pi/compute_pi_omp.f90) under a
[CC-BY-4.0](https://github.com/gjbex/Fortran-MOOC/blob/master/LICENSE) license.

The code approximates the value of PI by performing parallelized numerical
integration over a quarter of the unit circle.
The code is structured as follows:

```{literalinclude} ../../src/how-to/compute-pi-openmp/app/main.f90
:language: fortran
:caption: app/main.f90
```

## Using OpenMP as a dependency

To use OpenMP in your project, you need to add the `openmp` dependency to your `fpm.toml` file:

```{literalinclude} ../../src/how-to/compute-pi-openmp/fpm.toml
:language: toml
:caption: fpm.toml
:emphasize-lines: 4-5
```

OpenMP is a _built-in dependency_ (i.e. metapackage), which means the above
syntax needs to be used. To find out more about metapackages, see [](../spec/metapackages).

## Building and running the code

To build and run the code, one can use the following commands:

```{code-block} text
❯ fpm run
Project is up to date
Iterations: 10000, PI: 3.141391477611324
Took: 0.092s, with absolute error: 2.0E-04
```

And increasing the number of iterations for the approximation while
simultaneously enabling compiler optimizations with `--profile-release`

```{code-block} text
❯ fpm run --profile-release -- 1000000000
main.f90 done.
compute-pi-openmp done.
[100%] Project compiled successfully.
Iterations: 1000000000, PI: 3.141592651589789
Took: 3.511s, with absolute error: 2.0E-09
```
4 changes: 3 additions & 1 deletion pages/how-to/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

# How-To guides

:::{note}
This section contains practical guides and recipes for solving specific problems with fpm.

:::{toctree}
compute-pi-openmp
:::
41 changes: 41 additions & 0 deletions src/how-to/compute-pi-openmp/app/main.f90
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
program compute_pi_openmp
use, intrinsic :: iso_fortran_env, only: dp => real64, i8 => int64, real128
implicit none
integer(kind=i8) :: i, n_iterations
real(kind=dp) :: delta, x, pi
real(kind=dp) :: start, end

pi = 0.0_dp
n_iterations = get_iterations(10000_i8)
delta = 1.0_dp / n_iterations
x = 0.0_dp

call cpu_time(start)
!$omp parallel do default(none) private(x) shared(delta, n_iterations) reduction(+:pi)
do i = 1, n_iterations
x = i * delta
pi = pi + sqrt(1.0_dp - x**2)
end do
!$omp end parallel do
call cpu_time(end)

pi = 4.0_dp * pi / n_iterations
print "(A, I16, A, F25.15)", "Iterations: ", n_iterations, ", PI: ", pi
print "(A, F8.3, A, ES8.1)", "Took: ", end - start, "s, with absolute error: ", acos(-1.0_real128) - pi

contains

integer(i8) function get_iterations(default_iterations)
integer(kind=i8), intent(in) :: default_iterations
character(len=100) :: buffer, msg
integer :: stat

get_iterations = default_iterations
if (command_argument_count() >= 1) then
call get_command_argument(1, buffer)
read (buffer, fmt=*, iostat=stat, iomsg=msg) get_iterations
if (stat /= 0) stop msg
end if
end function get_iterations

end program compute_pi_openmp
8 changes: 8 additions & 0 deletions src/how-to/compute-pi-openmp/fpm.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
name = "compute-pi-openmp"
version = "0.1.0"

[dependencies]
openmp = "*"

[[executable]]
name = "compute-pi-openmp"
Loading