Skip to content

Commit 5af4fc4

Browse files
committed
add an example: transpose.py
1 parent c208ce6 commit 5af4fc4

File tree

2 files changed

+192
-4
lines changed

2 files changed

+192
-4
lines changed

examples/transpose.py

+181
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,181 @@
1+
"""
2+
Rambo benchmark
3+
4+
Examples:
5+
6+
# run 1000 iterations of 10 events and 100 outputs on sharpy backend
7+
python rambo.py -nevts 10 -nout 100 -b sharpy -i 1000
8+
9+
# MPI parallel run
10+
mpiexec -n 3 python rambo.py -nevts 64 -nout 64 -b sharpy -i 1000
11+
12+
"""
13+
14+
import argparse
15+
import time as time_mod
16+
17+
import numpy
18+
19+
import sharpy
20+
21+
try:
22+
import mpi4py
23+
24+
mpi4py.rc.finalize = False
25+
from mpi4py import MPI
26+
27+
comm_rank = MPI.COMM_WORLD.Get_rank()
28+
comm = MPI.COMM_WORLD
29+
except ImportError:
30+
comm_rank = 0
31+
comm = None
32+
33+
34+
def info(s):
35+
if comm_rank == 0:
36+
print(s)
37+
38+
39+
def sp_transpose(arr):
40+
brr = sharpy.permute_dims(arr, [1, 0])
41+
sharpy.sync()
42+
return brr
43+
44+
45+
def np_transpose(arr):
46+
return arr.transpose()
47+
48+
49+
def initialize(np, row, col, dtype):
50+
arr = np.arange(row * col, dtype=dtype)
51+
return np.reshape(arr, (row, col))
52+
53+
54+
def run(row, col, backend, iterations, datatype):
55+
if backend == "sharpy":
56+
import sharpy as np
57+
from sharpy import fini, init, sync
58+
59+
transpose = sp_transpose
60+
61+
init(False)
62+
elif backend == "numpy":
63+
import numpy as np
64+
65+
if comm is not None:
66+
assert (
67+
comm.Get_size() == 1
68+
), "Numpy backend only supports serial execution."
69+
70+
fini = sync = lambda x=None: None
71+
transpose = np_transpose
72+
else:
73+
raise ValueError(f'Unknown backend: "{backend}"')
74+
75+
dtype = {
76+
"f32": np.float32,
77+
"f64": np.float64,
78+
}[datatype]
79+
80+
info(f"Using backend: {backend}")
81+
info(f"Number of row: {row}")
82+
info(f"Number of column: {col}")
83+
info(f"Datatype: {datatype}")
84+
85+
arr = initialize(np, row, col, dtype)
86+
sync()
87+
88+
# verify
89+
if backend == "sharpy":
90+
brr = sp_transpose(arr)
91+
crr = np_transpose(sharpy.to_numpy(arr))
92+
assert numpy.allclose(sharpy.to_numpy(brr), crr)
93+
94+
def eval():
95+
tic = time_mod.perf_counter()
96+
transpose(arr)
97+
toc = time_mod.perf_counter()
98+
return toc - tic
99+
100+
# warm-up run
101+
t_warm = eval()
102+
103+
# evaluate
104+
info(f"Running {iterations} iterations")
105+
time_list = []
106+
for i in range(iterations):
107+
time_list.append(eval())
108+
109+
# get max time over mpi ranks
110+
if comm is not None:
111+
t_warm = comm.allreduce(t_warm, MPI.MAX)
112+
time_list = comm.allreduce(time_list, MPI.MAX)
113+
114+
t_min = numpy.min(time_list)
115+
t_max = numpy.max(time_list)
116+
t_med = numpy.median(time_list)
117+
init_overhead = t_warm - t_med
118+
if backend == "sharpy":
119+
info(f"Estimated initialization overhead: {init_overhead:.5f} s")
120+
info(f"Min. duration: {t_min:.5f} s")
121+
info(f"Max. duration: {t_max:.5f} s")
122+
info(f"Median duration: {t_med:.5f} s")
123+
124+
fini()
125+
126+
127+
if __name__ == "__main__":
128+
parser = argparse.ArgumentParser(
129+
description="Run transpose benchmark",
130+
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
131+
)
132+
133+
parser.add_argument(
134+
"-r",
135+
"--row",
136+
type=int,
137+
default=10000,
138+
help="Number of row.",
139+
)
140+
parser.add_argument(
141+
"-c",
142+
"--column",
143+
type=int,
144+
default=10000,
145+
help="Number of column.",
146+
)
147+
148+
parser.add_argument(
149+
"-b",
150+
"--backend",
151+
type=str,
152+
default="sharpy",
153+
choices=["sharpy", "numpy"],
154+
help="Backend to use.",
155+
)
156+
157+
parser.add_argument(
158+
"-i",
159+
"--iterations",
160+
type=int,
161+
default=10,
162+
help="Number of iterations to run.",
163+
)
164+
165+
parser.add_argument(
166+
"-d",
167+
"--datatype",
168+
type=str,
169+
default="f64",
170+
choices=["f32", "f64"],
171+
help="Datatype for model state variables",
172+
)
173+
174+
args = parser.parse_args()
175+
run(
176+
args.row,
177+
args.column,
178+
args.backend,
179+
args.iterations,
180+
args.datatype,
181+
)

sharpy/__init__.py

+11-4
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,17 @@ def _validate_device(device):
9696
raise ValueError(f"Invalid device string: {device}")
9797

9898

99+
def arange(start, stop=None, step=1, dtype=int64, device="", team=1):
100+
if stop is None:
101+
stop = start
102+
start = 0
103+
return ndarray(
104+
_csp.Creator.arange(
105+
start, stop, step, dtype, _validate_device(device), team
106+
)
107+
)
108+
109+
99110
for func in api.api_categories["Creator"]:
100111
FUNC = func.upper()
101112
if func == "full":
@@ -114,10 +125,6 @@ def _validate_device(device):
114125
exec(
115126
f"{func} = lambda shape, dtype=float64, device='', team=1: ndarray(_csp.Creator.full(shape, 0, dtype, _validate_device(device), team))"
116127
)
117-
elif func == "arange":
118-
exec(
119-
f"{func} = lambda start, end, step, dtype=int64, device='', team=1: ndarray(_csp.Creator.arange(start, end, step, dtype, _validate_device(device), team))"
120-
)
121128
elif func == "linspace":
122129
exec(
123130
f"{func} = lambda start, end, step, endpoint, dtype=float64, device='', team=1: ndarray(_csp.Creator.linspace(start, end, step, endpoint, dtype, _validate_device(device), team))"

0 commit comments

Comments
 (0)