Skip to content

Commit 301c1ea

Browse files
authored
Merge pull request #5 from gjbex/feature/f2py_omp
Feature/f2py omp
2 parents fa7c42e + 7deffff commit 301c1ea

File tree

7 files changed

+141
-0
lines changed

7 files changed

+141
-0
lines changed
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
F2PY = f2py3
2+
FFLAGS = -fopenmp -O2 -g
3+
VERSION = cpython-38-x86_64-linux-gnu
4+
5+
all: julia.cpython-38-x86_64-linux-gnu.so
6+
7+
julia.$(VERSION).so: julia_set_mod.f90 julia_set_omp_mod.f90
8+
$(F2PY) -c -m julia --f90flags="$(FFLAGS)" $^
9+
10+
clean:
11+
$(RM) $(wildcard *.o) $(wildcard *mod) $(wildcard *.so)
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# Julia set
2+
3+
Illustration of using f2py to interface with OpenMP code.
4+
5+
## What is it?
6+
7+
1. `julia_set_mod.f90`: Fortran module defining a function that computes a
8+
single point of a Julia set.
9+
10+
1. `julia_set_omp_mod.f90`: Fortran module that computes a Julia set
11+
parallelized with OpenMP.
12+
1. `julia_set.py`: Python script that initlalizes the arrays and computes
13+
the Julia set using the Fortran implementation.
14+
1. `Makefile`: make file to build the shared library.
15+
1. `show_julia_set.py`: Python script to visualize the result.
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
#!/usr/bin/env python
2+
3+
from argparse import ArgumentParser
4+
import numpy as np
5+
import sys
6+
7+
from julia import julia_set_omp_mod
8+
9+
10+
def init_z_values(nr_points):
11+
real = np.linspace(-1.8, 1.8, nr_points)
12+
imag = np.linspace(-1.8, 1.8, nr_points)
13+
Real, Imag = np.meshgrid(real, imag)
14+
return np.asfortranarray(Real + Imag*1.0j)
15+
16+
17+
def init_n_values(nr_points):
18+
return np.zeros((nr_points, nr_points), dtype=np.int32, order='F')
19+
20+
21+
def main():
22+
arg_parser = ArgumentParser(description='compute julia set')
23+
arg_parser.add_argument('--n', type=int, default=100,
24+
help='number of points')
25+
options = arg_parser.parse_args()
26+
z = init_z_values(options.n)
27+
n = init_n_values(options.n)
28+
julia_set_omp_mod.julia_compute(z, n)
29+
np.savetxt(sys.stdout, n, fmt='%4d')
30+
31+
32+
if __name__ == '__main__':
33+
status = main()
34+
sys.exit(status)
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
module julia_set_mod
2+
implicit none
3+
4+
private
5+
integer, parameter :: max_iters = 255
6+
real(kind=8), parameter :: max_norm = 2.0D00
7+
complex(kind=8), parameter :: C = cmplx(-0.622772D00, 0.42193D00, kind=8)
8+
9+
public :: julia_iterate
10+
11+
contains
12+
13+
elemental function julia_iterate(z0) result(n)
14+
implicit none
15+
complex(kind=8), intent(in) :: z0
16+
integer :: n
17+
complex(kind=8) :: z
18+
z = z0
19+
n = 0
20+
do while (abs(z) < max_norm .and. n < max_iters)
21+
z = z**2 + C
22+
n = n + 1
23+
end do
24+
end function julia_iterate
25+
26+
end module julia_set_mod
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
module julia_set_omp_mod
2+
use julia_set_mod
3+
implicit none
4+
5+
public :: julia_compute
6+
7+
contains
8+
9+
subroutine julia_compute(z, n)
10+
implicit none
11+
complex(kind=8), dimension(:, :), intent(in) :: z
12+
integer, dimension(:, :), intent(inout) :: n
13+
integer :: i, j
14+
15+
!$omp parallel do default(none) private(i) shared(z, n) schedule(runtime)
16+
do j = 1, size(z, 2)
17+
do i = 1, size(z, 1)
18+
n(i, j) = julia_iterate(z(i, j))
19+
end do
20+
end do
21+
!$omp end parallel do
22+
end subroutine julia_compute
23+
24+
end module julia_set_omp_mod
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
#!/usr/bin/env python
2+
3+
from argparse import ArgumentParser
4+
import matplotlib.pyplot as plt
5+
import numpy as np
6+
import sys
7+
8+
9+
def read_data(file_name):
10+
data = np.genfromtxt(file_name, dtype=np.uint8)
11+
return data
12+
13+
14+
def visualize_data(data):
15+
plt.imshow(np.log1p(data/255.0))
16+
plt.axis('off')
17+
18+
19+
def main():
20+
arg_parser = ArgumentParser(description='visualize julia set')
21+
arg_parser.add_argument('file', help='file name')
22+
options = arg_parser.parse_args()
23+
data = read_data(options.file)
24+
visualize_data(data)
25+
plt.show()
26+
return 0
27+
28+
if __name__ == '__main__':
29+
status = main()
30+
sys.exit(status)

source-code/interfaciing-c-c++-fortran/F2py/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,4 @@ What is it?
1414
is used to create a shared library and a wrapper.
1515
* `comp_pi_f2py.py`: test program to compute pi using a given number
1616
of iterations.
17+
* `Julia`: example of using Fortran OpenMP procedures from Python.

0 commit comments

Comments
 (0)