Note
Go to the end to download the full example code.
is_all_true performance benchmarks#
This example benchmarks the is_all_true performance for the different algorithms available in Shamrock
9 import json
10 import random
11 import time
12
13 import matplotlib.pyplot as plt
14 import numpy as np
15 from matplotlib import colors
16 from shamrock.utils.plot import make_std_bench_plot
17
18 import shamrock
19
20 # If we use the shamrock executable to run this script instead of the python interpreter,
21 # we should not initialize the system as the shamrock executable needs to handle specific MPI logic
22 if not shamrock.sys.is_initialized():
23 shamrock.change_loglevel(1)
24 shamrock.sys.init("0:0")
Use shamrock documentation style for matplotlib
30 shamrock.matplotlib.set_shamrock_mpl_style()
Main benchmark functions
37 def benchmark_is_all_true_random(N, nb_repeat=10):
38 times = []
39 for i in range(nb_repeat):
40 random.seed(111)
41 buf = shamrock.algs.mock_buffer_u8(random.randint(0, 1000000), N, 0, 1)
42 times.append(shamrock.algs.benchmark_is_all_true(buf, N))
43 return min(times), max(times), sum(times) / nb_repeat
44
45
46 def benchmark_is_all_true_ones(N, nb_repeat=10):
47 times = []
48 for i in range(nb_repeat):
49 buf = shamrock.backends.DeviceBuffer_u8()
50 buf.resize(N)
51 buf.fill(1)
52 times.append(shamrock.algs.benchmark_is_all_true(buf, N))
53 return min(times), max(times), sum(times) / nb_repeat
54
55
56 def benchmark_is_all_true_zeros(N, nb_repeat=10):
57 times = []
58 for i in range(nb_repeat):
59 buf = shamrock.backends.DeviceBuffer_u8()
60 buf.resize(N)
61 buf.fill(0)
62 times.append(shamrock.algs.benchmark_is_all_true(buf, N))
63 return min(times), max(times), sum(times) / nb_repeat
Run the performance test for all parameters
68 def run_performance_sweep():
69 # Define parameter ranges
70 # logspace as array
71 particle_counts = np.logspace(2, 7, 20).astype(int).tolist()
72
73 # Initialize results matrix
74 results_random = []
75 results_ones = []
76 results_zeros = []
77
78 print(f"Particle counts: {particle_counts}")
79
80 total_runs = len(particle_counts)
81 current_run = 0
82
83 for i, N in enumerate(particle_counts):
84 current_run += 1
85
86 print(
87 f"[{current_run:2d}/{total_runs}] Running N={N:5d}...",
88 end=" ",
89 )
90
91 start_time = time.time()
92 min_time, max_time, mean_time = benchmark_is_all_true_random(N)
93 results_random.append(mean_time)
94 min_time, max_time, mean_time = benchmark_is_all_true_ones(N)
95 results_ones.append(mean_time)
96 min_time, max_time, mean_time = benchmark_is_all_true_zeros(N)
97 results_zeros.append(mean_time)
98 elapsed = time.time() - start_time
99
100 print(f"mean={mean_time:.3f}s (took {elapsed:.1f}s)")
101
102 return particle_counts, results_random, results_ones, results_zeros
List current implementation
107 if not shamrock.algs.is_impl_set_is_all_true():
108 shamrock.algs.autoselect_impl_is_all_true()
109
110 current_impl = shamrock.algs.get_current_impl_is_all_true()
111
112 print(current_impl)
Info: defaulting is_all_true implementation to impl : {"implementation":"host","parameters":{}} [algs][rank=0]
{"implementation":"host","parameters":{}}
List all implementations available
116 all_default_impls = shamrock.algs.get_default_impl_list_is_all_true()
117
118 print(all_default_impls)
['{"implementation":"host","parameters":{}}', '{"implementation":"sum_reduction","parameters":{}}', '{"implementation":"atomic_early_exit","parameters":{"group_size":64}}', '{"implementation":"atomic_early_exit","parameters":{"group_size":256}}']
Run the performance benchmarks for all implementations
123 dic_bench = {}
124 for impl in all_default_impls:
125 shamrock.algs.set_impl_is_all_true(impl)
126
127 impl_json = json.loads(impl)
128 impl_name = impl_json["implementation"]
129 impl_params = impl_json.get("parameters", {})
130 if impl_params:
131 # Disambiguate implementations that expose multiple default parameter sets
132 # (e.g. several group sizes) under the same "implementation" name
133 params_str = ", ".join(f"{k}={v}" for k, v in impl_params.items())
134 impl_name = f"{impl_name} ({params_str})"
135
136 print(f"Running is_all_true performance benchmarks for {impl}...")
137
138 # Run the performance sweep
139 particle_counts, results_random, results_ones, results_zeros = run_performance_sweep()
140
141 dic_bench[impl_name] = {
142 "particle_counts": particle_counts,
143 "results_random": results_random,
144 "results_ones": results_ones,
145 "results_zeros": results_zeros,
146 }
Info: setting is_all_true implementation to impl : {"implementation":"host","parameters":{}} [algs][rank=0]
Running is_all_true performance benchmarks for {"implementation":"host","parameters":{}}...
Particle counts: [100, 183, 335, 615, 1128, 2069, 3792, 6951, 12742, 23357, 42813, 78475, 143844, 263665, 483293, 885866, 1623776, 2976351, 5455594, 10000000]
[ 1/20] Running N= 100... mean=0.000s (took 0.0s)
[ 2/20] Running N= 183... mean=0.000s (took 0.0s)
[ 3/20] Running N= 335... mean=0.000s (took 0.0s)
[ 4/20] Running N= 615... mean=0.000s (took 0.0s)
[ 5/20] Running N= 1128... mean=0.000s (took 0.0s)
[ 6/20] Running N= 2069... mean=0.000s (took 0.0s)
[ 7/20] Running N= 3792... mean=0.000s (took 0.0s)
[ 8/20] Running N= 6951... mean=0.000s (took 0.0s)
[ 9/20] Running N=12742... mean=0.000s (took 0.0s)
[10/20] Running N=23357... mean=0.000s (took 0.0s)
[11/20] Running N=42813... mean=0.000s (took 0.0s)
[12/20] Running N=78475... mean=0.000s (took 0.0s)
[13/20] Running N=143844... mean=0.000s (took 0.0s)
[14/20] Running N=263665... mean=0.000s (took 0.0s)
[15/20] Running N=483293... mean=0.000s (took 0.1s)
[16/20] Running N=885866... mean=0.000s (took 0.2s)
[17/20] Running N=1623776... mean=0.000s (took 0.3s)
[18/20] Running N=2976351... mean=0.000s (took 0.4s)
[19/20] Running N=5455594... mean=0.000s (took 0.6s)
[20/20] Running N=10000000... mean=0.003s (took 1.1s)
Info: setting is_all_true implementation to impl : {"implementation":"sum_reduction","parameters":{}} [algs][rank=0]
Running is_all_true performance benchmarks for {"implementation":"sum_reduction","parameters":{}}...
Particle counts: [100, 183, 335, 615, 1128, 2069, 3792, 6951, 12742, 23357, 42813, 78475, 143844, 263665, 483293, 885866, 1623776, 2976351, 5455594, 10000000]
[ 1/20] Running N= 100... Info: defaulting reduction implementation to impl : {"implementation":"group_reduction","parameters":{"group_size":128}} [algs][rank=0]
mean=0.000s (took 0.0s)
[ 2/20] Running N= 183... mean=0.000s (took 0.0s)
[ 3/20] Running N= 335... mean=0.000s (took 0.0s)
[ 4/20] Running N= 615... mean=0.000s (took 0.0s)
[ 5/20] Running N= 1128... mean=0.000s (took 0.0s)
[ 6/20] Running N= 2069... mean=0.000s (took 0.0s)
[ 7/20] Running N= 3792... mean=0.000s (took 0.0s)
[ 8/20] Running N= 6951... mean=0.000s (took 0.0s)
[ 9/20] Running N=12742... mean=0.000s (took 0.0s)
[10/20] Running N=23357... mean=0.000s (took 0.0s)
[11/20] Running N=42813... mean=0.000s (took 0.0s)
[12/20] Running N=78475... mean=0.000s (took 0.0s)
[13/20] Running N=143844... mean=0.000s (took 0.0s)
[14/20] Running N=263665... mean=0.000s (took 0.1s)
[15/20] Running N=483293... mean=0.001s (took 0.1s)
[16/20] Running N=885866... mean=0.001s (took 0.2s)
[17/20] Running N=1623776... mean=0.002s (took 0.3s)
[18/20] Running N=2976351... mean=0.003s (took 0.6s)
[19/20] Running N=5455594... mean=0.006s (took 1.0s)
[20/20] Running N=10000000... mean=0.016s (took 2.0s)
Info: setting is_all_true implementation to impl : {"implementation":"atomic_early_exit","parameters":{"group_size":64}} [algs][rank=0]
Running is_all_true performance benchmarks for {"implementation":"atomic_early_exit","parameters":{"group_size":64}}...
Particle counts: [100, 183, 335, 615, 1128, 2069, 3792, 6951, 12742, 23357, 42813, 78475, 143844, 263665, 483293, 885866, 1623776, 2976351, 5455594, 10000000]
[ 1/20] Running N= 100... mean=0.000s (took 0.0s)
[ 2/20] Running N= 183... mean=0.000s (took 0.0s)
[ 3/20] Running N= 335... mean=0.000s (took 0.0s)
[ 4/20] Running N= 615... mean=0.000s (took 0.0s)
[ 5/20] Running N= 1128... mean=0.000s (took 0.0s)
[ 6/20] Running N= 2069... mean=0.000s (took 0.0s)
[ 7/20] Running N= 3792... mean=0.000s (took 0.0s)
[ 8/20] Running N= 6951... mean=0.000s (took 0.0s)
[ 9/20] Running N=12742... mean=0.000s (took 0.0s)
[10/20] Running N=23357... mean=0.000s (took 0.0s)
[11/20] Running N=42813... mean=0.000s (took 0.0s)
[12/20] Running N=78475... mean=0.000s (took 0.0s)
[13/20] Running N=143844... mean=0.000s (took 0.0s)
[14/20] Running N=263665... mean=0.000s (took 0.0s)
[15/20] Running N=483293... mean=0.000s (took 0.1s)
[16/20] Running N=885866... mean=0.000s (took 0.2s)
[17/20] Running N=1623776... mean=0.000s (took 0.3s)
[18/20] Running N=2976351... mean=0.000s (took 0.5s)
[19/20] Running N=5455594... mean=0.000s (took 0.9s)
[20/20] Running N=10000000... mean=0.001s (took 1.7s)
Info: setting is_all_true implementation to impl : {"implementation":"atomic_early_exit","parameters":{"group_size":256}} [algs][rank=0]
Running is_all_true performance benchmarks for {"implementation":"atomic_early_exit","parameters":{"group_size":256}}...
Particle counts: [100, 183, 335, 615, 1128, 2069, 3792, 6951, 12742, 23357, 42813, 78475, 143844, 263665, 483293, 885866, 1623776, 2976351, 5455594, 10000000]
[ 1/20] Running N= 100... mean=0.000s (took 0.0s)
[ 2/20] Running N= 183... mean=0.000s (took 0.0s)
[ 3/20] Running N= 335... mean=0.000s (took 0.0s)
[ 4/20] Running N= 615... mean=0.000s (took 0.0s)
[ 5/20] Running N= 1128... mean=0.000s (took 0.0s)
[ 6/20] Running N= 2069... mean=0.000s (took 0.0s)
[ 7/20] Running N= 3792... mean=0.000s (took 0.0s)
[ 8/20] Running N= 6951... mean=0.000s (took 0.0s)
[ 9/20] Running N=12742... mean=0.000s (took 0.0s)
[10/20] Running N=23357... mean=0.000s (took 0.0s)
[11/20] Running N=42813... mean=0.000s (took 0.0s)
[12/20] Running N=78475... mean=0.000s (took 0.0s)
[13/20] Running N=143844... mean=0.000s (took 0.0s)
[14/20] Running N=263665... mean=0.000s (took 0.0s)
[15/20] Running N=483293... mean=0.000s (took 0.1s)
[16/20] Running N=885866... mean=0.000s (took 0.2s)
[17/20] Running N=1623776... mean=0.000s (took 0.3s)
[18/20] Running N=2976351... mean=0.000s (took 0.5s)
[19/20] Running N=5455594... mean=0.000s (took 0.9s)
[20/20] Running N=10000000... mean=0.000s (took 1.7s)
Plot results
152 color_cycle = plt.rcParams["axes.prop_cycle"].by_key()["color"]
153
154 plot_data = {}
155 for i, (label, item) in enumerate(dic_bench.items()):
156 color = color_cycle[i % len(color_cycle)]
157 plot_data[label + " (random set)"] = {
158 "x": item["particle_counts"],
159 "y": item["results_random"],
160 "color": color,
161 "label": label + " (random set)",
162 "linestyle": "--",
163 "marker": None,
164 }
165 plot_data[label + " (all ones)"] = {
166 "x": item["particle_counts"],
167 "y": item["results_ones"],
168 "color": color,
169 "label": label + " (all ones)",
170 "linestyle": "--",
171 "marker": "+",
172 }
173 plot_data[label + " (all zeros)"] = {
174 "x": item["particle_counts"],
175 "y": item["results_zeros"],
176 "color": color,
177 "label": label + " (all zeros)",
178 "linestyle": "--",
179 "marker": "o",
180 }
181
182
183 def before_plot(ax_plot):
184 particle_counts = next(iter(dic_bench.values()))["particle_counts"]
185 Nobj = np.array(particle_counts)
186 Time100M = Nobj / 1e8
187 ax_plot.plot(
188 particle_counts,
189 Time100M,
190 color="grey",
191 linestyle="-",
192 alpha=0.7,
193 label="100M obj/sec",
194 )
195
196
197 make_std_bench_plot(
198 plot_data,
199 xlabel="Number of elements",
200 ylabel="Time (s)",
201 title="is_all_true performance benchmarks",
202 end_label_fmt=lambda y: f"{y:.2e} s",
203 before_plot_func=before_plot,
204 )
205 plt.show()

Total running time of the script: (0 minutes 16.346 seconds)
Estimated memory usage: 160 MB