Performances of 2D integration vs 1D integration#

This is dependent on:

  • Number of azimuthal bins

  • Pixel splitting

  • Algorithm

  • Implementation (i.e. programming language)

  • Hardware used

Thus there is no general answer. But here is a quick benchmark to evaluate the penalty on performances:

import sys import os import time import numpy import fabio import pyFAI from pyFAI.test.utilstest import UtilsTest import pyFAI.method_registry import pyFAI.integrator.azimuthal print(f”Python version: {sys.version}”) print(f”PyFAI version: {pyFAI.version}”) start_time = time.perf_counter()

import sys
import os
import time

os.environ["PYOPENCL_COMPILER_OUTPUT"] = "0"
start_time = time.perf_counter()
import fabio
import pyFAI
from pyFAI.test.utilstest import UtilsTest
import pyFAI.method_registry
import pyFAI.integrator.azimuthal
print(f"Python version: {sys.version}")
print(f"PyFAI version: {pyFAI.version}")
Python version: 3.14.0 | packaged by conda-forge | (main, Oct 22 2025, 23:24:08) [GCC 14.3.0]
PyFAI version: 2026.8.0-dev0
print("Number of way to performing integration:", len(pyFAI.method_registry.IntegrationMethod.list_available()))
Number of way to performing integration: 95
ai = pyFAI.load(UtilsTest.getimage("Pilatus1M.poni"))
img = fabio.open(UtilsTest.getimage("Pilatus1M.edf")).data
ai
Detector Pilatus 1M	 PixelSize= 172µm, 172µm	 BottomRight (3)
Wavelength= 1.000000 Å
SampleDetDist= 1.583231e+00 m	PONI= 3.341702e-02, 4.122778e-02 m	rot1=0.006487  rot2=0.007558  rot3=0.000000 rad
DirectBeamDist= 1583.310 mm	Center: x=179.981, y=263.859 pix	Tilt= 0.571° tiltPlanRotation= 130.640° λ= 1.000Å
%%time
#Tune those parameters to match your needs:
kw1 = {"data": img, "npt":1000}
kw2 = {"data": img, "npt_rad":1000}
#Actual benchmark:
res = {}
for k,v in pyFAI.method_registry.IntegrationMethod._registry.items():
    print(k)
    if k.dim == 1:
        res[k] = %timeit -o ai.integrate1d(method=v, **kw1)
    else:
        res[k] = %timeit -o ai.integrate2d(method=v, **kw2)
Method(dim=1, split='no', algo='histogram', impl='python', target=None)
30.3 ms ± 74.9 μs per loop (mean ± std. dev. of 7 runs, 10 loops each)
Method(dim=2, split='no', algo='histogram', impl='python', target=None)
143 ms ± 324 μs per loop (mean ± std. dev. of 7 runs, 10 loops each)
Method(dim=1, split='no', algo='histogram', impl='cython', target=None)
11.4 ms ± 13.4 μs per loop (mean ± std. dev. of 7 runs, 100 loops each)
Method(dim=2, split='no', algo='histogram', impl='cython', target=None)
16.7 ms ± 36 μs per loop (mean ± std. dev. of 7 runs, 100 loops each)
Method(dim=1, split='bbox', algo='histogram', impl='cython', target=None)
26.6 ms ± 51.2 μs per loop (mean ± std. dev. of 7 runs, 10 loops each)
Method(dim=2, split='bbox', algo='histogram', impl='cython', target=None)
33.1 ms ± 42.5 μs per loop (mean ± std. dev. of 7 runs, 10 loops each)
Method(dim=1, split='full', algo='histogram', impl='cython', target=None)
140 ms ± 78.8 μs per loop (mean ± std. dev. of 7 runs, 10 loops each)
Method(dim=2, split='full', algo='histogram', impl='cython', target=None)
282 ms ± 1.47 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
Method(dim=2, split='pseudo', algo='histogram', impl='cython', target=None)
370 ms ± 2.45 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
Method(dim=1, split='no', algo='csr', impl='cython', target=None)
15.3 ms ± 256 μs per loop (mean ± std. dev. of 7 runs, 100 loops each)
Method(dim=2, split='no', algo='csr', impl='cython', target=None)
15.8 ms ± 252 μs per loop (mean ± std. dev. of 7 runs, 100 loops each)
Method(dim=1, split='bbox', algo='csr', impl='cython', target=None)
15.3 ms ± 434 μs per loop (mean ± std. dev. of 7 runs, 100 loops each)
Method(dim=2, split='bbox', algo='csr', impl='cython', target=None)
15.2 ms ± 303 μs per loop (mean ± std. dev. of 7 runs, 100 loops each)
Method(dim=1, split='no', algo='csr', impl='python', target=None)
10.2 ms ± 81.1 μs per loop (mean ± std. dev. of 7 runs, 100 loops each)
Method(dim=2, split='no', algo='csr', impl='python', target=None)
15.2 ms ± 144 μs per loop (mean ± std. dev. of 7 runs, 100 loops each)
Method(dim=1, split='bbox', algo='csr', impl='python', target=None)
13.8 ms ± 75.8 μs per loop (mean ± std. dev. of 7 runs, 100 loops each)
Method(dim=2, split='bbox', algo='csr', impl='python', target=None)
18.1 ms ± 105 μs per loop (mean ± std. dev. of 7 runs, 1 loop each)
Method(dim=1, split='no', algo='csc', impl='cython', target=None)
7.12 ms ± 44.4 μs per loop (mean ± std. dev. of 7 runs, 100 loops each)
Method(dim=2, split='no', algo='csc', impl='cython', target=None)
9.82 ms ± 16.4 μs per loop (mean ± std. dev. of 7 runs, 100 loops each)
Method(dim=1, split='bbox', algo='csc', impl='cython', target=None)
9.48 ms ± 28.4 μs per loop (mean ± std. dev. of 7 runs, 100 loops each)
Method(dim=2, split='bbox', algo='csc', impl='cython', target=None)
12.9 ms ± 41 μs per loop (mean ± std. dev. of 7 runs, 1 loop each)
Method(dim=1, split='no', algo='csc', impl='python', target=None)
11.5 ms ± 14.6 μs per loop (mean ± std. dev. of 7 runs, 100 loops each)
Method(dim=2, split='no', algo='csc', impl='python', target=None)
14.8 ms ± 177 μs per loop (mean ± std. dev. of 7 runs, 100 loops each)
Method(dim=1, split='bbox', algo='csc', impl='python', target=None)
15.2 ms ± 14.7 μs per loop (mean ± std. dev. of 7 runs, 100 loops each)
Method(dim=2, split='bbox', algo='csc', impl='python', target=None)
22.7 ms ± 60.3 μs per loop (mean ± std. dev. of 7 runs, 1 loop each)
Method(dim=1, split='bbox', algo='lut', impl='cython', target=None)
15.5 ms ± 144 μs per loop (mean ± std. dev. of 7 runs, 100 loops each)
Method(dim=2, split='bbox', algo='lut', impl='cython', target=None)
19.5 ms ± 1.09 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
Method(dim=1, split='no', algo='lut', impl='cython', target=None)
15.7 ms ± 233 μs per loop (mean ± std. dev. of 7 runs, 100 loops each)
Method(dim=2, split='no', algo='lut', impl='cython', target=None)
16 ms ± 181 μs per loop (mean ± std. dev. of 7 runs, 100 loops each)
Method(dim=1, split='full', algo='lut', impl='cython', target=None)
16.4 ms ± 2.05 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
Method(dim=2, split='full', algo='lut', impl='cython', target=None)
18.8 ms ± 2.62 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
Method(dim=1, split='full', algo='csr', impl='cython', target=None)
15.5 ms ± 147 μs per loop (mean ± std. dev. of 7 runs, 100 loops each)
Method(dim=2, split='full', algo='csr', impl='cython', target=None)
14.1 ms ± 3.41 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
Method(dim=1, split='full', algo='csr', impl='python', target=None)
13.2 ms ± 58.2 μs per loop (mean ± std. dev. of 7 runs, 100 loops each)
Method(dim=2, split='full', algo='csr', impl='python', target=None)
17.8 ms ± 346 μs per loop (mean ± std. dev. of 7 runs, 1 loop each)
Method(dim=1, split='full', algo='csc', impl='cython', target=None)
9.14 ms ± 8.53 μs per loop (mean ± std. dev. of 7 runs, 100 loops each)
Method(dim=2, split='full', algo='csc', impl='cython', target=None)
12.8 ms ± 72.8 μs per loop (mean ± std. dev. of 7 runs, 1 loop each)
Method(dim=1, split='full', algo='csc', impl='python', target=None)
15.2 ms ± 126 μs per loop (mean ± std. dev. of 7 runs, 100 loops each)
Method(dim=2, split='full', algo='csc', impl='python', target=None)
22.1 ms ± 68.9 μs per loop (mean ± std. dev. of 7 runs, 1 loop each)
Method(dim=1, split='no', algo='histogram', impl='opencl', target=(0, 0))
8.97 ms ± 31.5 μs per loop (mean ± std. dev. of 7 runs, 100 loops each)
Method(dim=2, split='no', algo='histogram', impl='opencl', target=(0, 0))
2.75 ms ± 12.2 μs per loop (mean ± std. dev. of 7 runs, 100 loops each)
Method(dim=1, split='no', algo='histogram', impl='opencl', target=(0, 1))
8.26 ms ± 21.7 μs per loop (mean ± std. dev. of 7 runs, 100 loops each)
Method(dim=2, split='no', algo='histogram', impl='opencl', target=(0, 1))
4.22 ms ± 22 μs per loop (mean ± std. dev. of 7 runs, 100 loops each)
Method(dim=1, split='no', algo='histogram', impl='opencl', target=(1, 0))
1 error generated.
WARNING:pyFAI.opencl.azim_hist:Your OpenCL compiler wrongly claims it support 64-bit atomics. Degrading to 32 bits atomics!
15.8 ms ± 1.71 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
Method(dim=2, split='no', algo='histogram', impl='opencl', target=(1, 0))
1 error generated.
WARNING:pyFAI.opencl.azim_hist:Your OpenCL compiler wrongly claims it support 64-bit atomics. Degrading to 32 bits atomics!
/users/kieffer/.venv/py314/lib/python3.14/site-packages/pyopencl/cache.py:527: CompilerWarning: Non-empty compiler output encountered. Set the environment variable PYOPENCL_COMPILER_OUTPUT=1 to see more.
  _create_built_program_from_source_cached(
/users/kieffer/.venv/py314/lib/python3.14/site-packages/pyopencl/cache.py:531: CompilerWarning: Non-empty compiler output encountered. Set the environment variable PYOPENCL_COMPILER_OUTPUT=1 to see more.
  prg.build(options_bytes, devices)
WARNING:pyFAI.opencl.azim_hist:Your OpenCL compiler wrongly claims it support 64-bit atomics. Degrading to 32 bits atomics!
10.1 ms ± 843 μs per loop (mean ± std. dev. of 7 runs, 1 loop each)
Method(dim=1, split='no', algo='histogram', impl='opencl', target=(2, 0))
WARNING:pyFAI.opencl.azim_hist:Your OpenCL compiler wrongly claims it support 64-bit atomics. Degrading to 32 bits atomics!
11.1 ms ± 241 μs per loop (mean ± std. dev. of 7 runs, 100 loops each)
Method(dim=2, split='no', algo='histogram', impl='opencl', target=(2, 0))
5.84 ms ± 47.7 μs per loop (mean ± std. dev. of 7 runs, 100 loops each)
Method(dim=1, split='bbox', algo='csr', impl='opencl', target=(0, 0))
728 μs ± 2.73 μs per loop (mean ± std. dev. of 7 runs, 1,000 loops each)
Method(dim=2, split='bbox', algo='csr', impl='opencl', target=(0, 0))
2.67 ms ± 67.7 μs per loop (mean ± std. dev. of 7 runs, 1 loop each)
Method(dim=1, split='no', algo='csr', impl='opencl', target=(0, 0))
680 μs ± 894 ns per loop (mean ± std. dev. of 7 runs, 1,000 loops each)
Method(dim=2, split='no', algo='csr', impl='opencl', target=(0, 0))
2.47 ms ± 23.8 μs per loop (mean ± std. dev. of 7 runs, 100 loops each)
Method(dim=1, split='bbox', algo='csr', impl='opencl', target=(0, 1))
1.22 ms ± 1.2 μs per loop (mean ± std. dev. of 7 runs, 1,000 loops each)
Method(dim=2, split='bbox', algo='csr', impl='opencl', target=(0, 1))
6.13 ms ± 32.7 μs per loop (mean ± std. dev. of 7 runs, 1 loop each)
Method(dim=1, split='no', algo='csr', impl='opencl', target=(0, 1))
1.09 ms ± 865 ns per loop (mean ± std. dev. of 7 runs, 1,000 loops each)
Method(dim=2, split='no', algo='csr', impl='opencl', target=(0, 1))
6.02 ms ± 12.1 μs per loop (mean ± std. dev. of 7 runs, 100 loops each)
Method(dim=1, split='bbox', algo='csr', impl='opencl', target=(1, 0))
3.72 ms ± 25.2 μs per loop (mean ± std. dev. of 7 runs, 100 loops each)
Method(dim=2, split='bbox', algo='csr', impl='opencl', target=(1, 0))
9.17 ms ± 319 μs per loop (mean ± std. dev. of 7 runs, 1 loop each)
Method(dim=1, split='no', algo='csr', impl='opencl', target=(1, 0))
2.84 ms ± 24.2 μs per loop (mean ± std. dev. of 7 runs, 100 loops each)
Method(dim=2, split='no', algo='csr', impl='opencl', target=(1, 0))
6.16 ms ± 40.6 μs per loop (mean ± std. dev. of 7 runs, 100 loops each)
Method(dim=1, split='bbox', algo='csr', impl='opencl', target=(2, 0))
2.89 ms ± 147 μs per loop (mean ± std. dev. of 7 runs, 1 loop each)
Method(dim=2, split='bbox', algo='csr', impl='opencl', target=(2, 0))
83.7 ms ± 87.5 μs per loop (mean ± std. dev. of 7 runs, 1 loop each)
Method(dim=1, split='no', algo='csr', impl='opencl', target=(2, 0))
2.22 ms ± 114 μs per loop (mean ± std. dev. of 7 runs, 1 loop each)
Method(dim=2, split='no', algo='csr', impl='opencl', target=(2, 0))
89.7 ms ± 5.76 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
Method(dim=1, split='full', algo='csr', impl='opencl', target=(0, 0))
724 μs ± 2.26 μs per loop (mean ± std. dev. of 7 runs, 1,000 loops each)
Method(dim=2, split='full', algo='csr', impl='opencl', target=(0, 0))
2.65 ms ± 74.9 μs per loop (mean ± std. dev. of 7 runs, 1 loop each)
Method(dim=1, split='full', algo='csr', impl='opencl', target=(0, 1))
1.23 ms ± 688 ns per loop (mean ± std. dev. of 7 runs, 1,000 loops each)
Method(dim=2, split='full', algo='csr', impl='opencl', target=(0, 1))
6.13 ms ± 38 μs per loop (mean ± std. dev. of 7 runs, 1 loop each)
Method(dim=1, split='full', algo='csr', impl='opencl', target=(1, 0))
4.06 ms ± 33.8 μs per loop (mean ± std. dev. of 7 runs, 100 loops each)
Method(dim=2, split='full', algo='csr', impl='opencl', target=(1, 0))
8.84 ms ± 604 μs per loop (mean ± std. dev. of 7 runs, 1 loop each)
Method(dim=1, split='full', algo='csr', impl='opencl', target=(2, 0))
3.33 ms ± 85.2 μs per loop (mean ± std. dev. of 7 runs, 1 loop each)
Method(dim=2, split='full', algo='csr', impl='opencl', target=(2, 0))
84.6 ms ± 1.26 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
Method(dim=1, split='bbox', algo='lut', impl='opencl', target=(0, 0))
3.18 ms ± 3.83 μs per loop (mean ± std. dev. of 7 runs, 100 loops each)
Method(dim=2, split='bbox', algo='lut', impl='opencl', target=(0, 0))
365 ms ± 15.4 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
Method(dim=1, split='no', algo='lut', impl='opencl', target=(0, 0))
1.61 ms ± 2.32 μs per loop (mean ± std. dev. of 7 runs, 1,000 loops each)
Method(dim=2, split='no', algo='lut', impl='opencl', target=(0, 0))
197 ms ± 22.8 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
Method(dim=1, split='bbox', algo='lut', impl='opencl', target=(0, 1))
3.15 ms ± 8.53 μs per loop (mean ± std. dev. of 7 runs, 100 loops each)
Method(dim=2, split='bbox', algo='lut', impl='opencl', target=(0, 1))
512 ms ± 5.17 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
Method(dim=1, split='no', algo='lut', impl='opencl', target=(0, 1))
1.82 ms ± 624 ns per loop (mean ± std. dev. of 7 runs, 1,000 loops each)
Method(dim=2, split='no', algo='lut', impl='opencl', target=(0, 1))
212 ms ± 3.17 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
Method(dim=1, split='bbox', algo='lut', impl='opencl', target=(1, 0))
4.81 ms ± 93.2 μs per loop (mean ± std. dev. of 7 runs, 100 loops each)
Method(dim=2, split='bbox', algo='lut', impl='opencl', target=(1, 0))
372 ms ± 20.6 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
Method(dim=1, split='no', algo='lut', impl='opencl', target=(1, 0))
3.75 ms ± 38.5 μs per loop (mean ± std. dev. of 7 runs, 100 loops each)
Method(dim=2, split='no', algo='lut', impl='opencl', target=(1, 0))
238 ms ± 18.6 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
Method(dim=1, split='bbox', algo='lut', impl='opencl', target=(2, 0))
3.49 ms ± 114 μs per loop (mean ± std. dev. of 7 runs, 100 loops each)
Method(dim=2, split='bbox', algo='lut', impl='opencl', target=(2, 0))
447 ms ± 37.2 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
Method(dim=1, split='no', algo='lut', impl='opencl', target=(2, 0))
2.77 ms ± 60.6 μs per loop (mean ± std. dev. of 7 runs, 100 loops each)
Method(dim=2, split='no', algo='lut', impl='opencl', target=(2, 0))
317 ms ± 21.2 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
Method(dim=1, split='full', algo='lut', impl='opencl', target=(0, 0))
2.61 ms ± 4.94 μs per loop (mean ± std. dev. of 7 runs, 100 loops each)
Method(dim=2, split='full', algo='lut', impl='opencl', target=(0, 0))
342 ms ± 24.1 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
Method(dim=1, split='full', algo='lut', impl='opencl', target=(0, 1))
2.77 ms ± 115 μs per loop (mean ± std. dev. of 7 runs, 100 loops each)
Method(dim=2, split='full', algo='lut', impl='opencl', target=(0, 1))
506 ms ± 139 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
Method(dim=1, split='full', algo='lut', impl='opencl', target=(1, 0))
5.04 ms ± 179 μs per loop (mean ± std. dev. of 7 runs, 100 loops each)
Method(dim=2, split='full', algo='lut', impl='opencl', target=(1, 0))
254 ms ± 49.6 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
Method(dim=1, split='full', algo='lut', impl='opencl', target=(2, 0))
3.83 ms ± 80.3 μs per loop (mean ± std. dev. of 7 runs, 100 loops each)
Method(dim=2, split='full', algo='lut', impl='opencl', target=(2, 0))
335 ms ± 23.9 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
CPU times: user 2h 10min 38s, sys: 7min 25s, total: 2h 18min 3s
Wall time: 8min 6s
print("-"*80)
print(f"{'Split':5s} | {'Algo':9s} | {'Impl':6s}| {'1d (ms)':8s} | {'2d (ms)':8s} | {'ratio':6s} | Device")
print("-"*80)
for k in res:
    if k.dim == 1:
        k1 = k
        k2 = k._replace(dim=2)
        if k2 in res:
            print(f"{k1.split:5s} | {k1.algo:9s} | {k1.impl:6s}| {res[k1].best*1000:8.3f} | {res[k2].best*1000:8.3f} | {res[k2].best/res[k1].best:6.1f} | ",
                    end="")
        if k.target:
            print(pyFAI.method_registry.IntegrationMethod._registry.get(k).target_name)
        else:
            print()
print("-"*80)
--------------------------------------------------------------------------------
Split | Algo      | Impl  | 1d (ms)  | 2d (ms)  | ratio  | Device
--------------------------------------------------------------------------------
no    | histogram | python|   30.255 |  142.694 |    4.7 | 
no    | histogram | cython|   11.390 |   16.706 |    1.5 | 
bbox  | histogram | cython|   26.570 |   33.027 |    1.2 | 
full  | histogram | cython|  140.251 |  280.317 |    2.0 | 
no    | csr       | cython|   14.934 |   15.385 |    1.0 | 
bbox  | csr       | cython|   14.379 |   14.719 |    1.0 | 
no    | csr       | python|   10.095 |   14.901 |    1.5 | 
bbox  | csr       | python|   13.706 |   18.006 |    1.3 | 
no    | csc       | cython|    7.037 |    9.792 |    1.4 | 
bbox  | csc       | cython|    9.452 |   12.825 |    1.4 | 
no    | csc       | python|   11.449 |   14.555 |    1.3 | 
bbox  | csc       | python|   15.218 |   22.616 |    1.5 | 
bbox  | lut       | cython|   15.319 |   17.738 |    1.2 | 
no    | lut       | cython|   15.157 |   15.744 |    1.0 | 
full  | lut       | cython|   14.131 |   15.101 |    1.1 | 
full  | csr       | cython|   15.200 |    7.991 |    0.5 | 
full  | csr       | python|   13.053 |   17.323 |    1.3 | 
full  | csc       | cython|    9.129 |   12.678 |    1.4 | 
full  | csc       | python|   15.027 |   21.956 |    1.5 | 
no    | histogram | opencl|    8.936 |    2.741 |    0.3 | NVIDIA CUDA / NVIDIA RTX A5000
no    | histogram | opencl|    8.232 |    4.204 |    0.5 | NVIDIA CUDA / Quadro P2200
no    | histogram | opencl|   13.981 |    9.243 |    0.7 | Portable Computing Language / cpu-haswell-AMD Ryzen Threadripper PRO 3975WX 32-Cores
no    | histogram | opencl|   10.681 |    5.756 |    0.5 | Intel(R) OpenCL / AMD Ryzen Threadripper PRO 3975WX 32-Cores
bbox  | csr       | opencl|    0.725 |    2.626 |    3.6 | NVIDIA CUDA / NVIDIA RTX A5000
no    | csr       | opencl|    0.679 |    2.454 |    3.6 | NVIDIA CUDA / NVIDIA RTX A5000
bbox  | csr       | opencl|    1.223 |    6.115 |    5.0 | NVIDIA CUDA / Quadro P2200
no    | csr       | opencl|    1.088 |    6.007 |    5.5 | NVIDIA CUDA / Quadro P2200
bbox  | csr       | opencl|    3.686 |    8.512 |    2.3 | Portable Computing Language / cpu-haswell-AMD Ryzen Threadripper PRO 3975WX 32-Cores
no    | csr       | opencl|    2.818 |    6.107 |    2.2 | Portable Computing Language / cpu-haswell-AMD Ryzen Threadripper PRO 3975WX 32-Cores
bbox  | csr       | opencl|    2.721 |   83.607 |   30.7 | Intel(R) OpenCL / AMD Ryzen Threadripper PRO 3975WX 32-Cores
no    | csr       | opencl|    2.054 |   84.036 |   40.9 | Intel(R) OpenCL / AMD Ryzen Threadripper PRO 3975WX 32-Cores
full  | csr       | opencl|    0.721 |    2.613 |    3.6 | NVIDIA CUDA / NVIDIA RTX A5000
full  | csr       | opencl|    1.226 |    6.107 |    5.0 | NVIDIA CUDA / Quadro P2200
full  | csr       | opencl|    4.021 |    8.111 |    2.0 | Portable Computing Language / cpu-haswell-AMD Ryzen Threadripper PRO 3975WX 32-Cores
full  | csr       | opencl|    3.186 |   83.693 |   26.3 | Intel(R) OpenCL / AMD Ryzen Threadripper PRO 3975WX 32-Cores
bbox  | lut       | opencl|    3.174 |  351.847 |  110.9 | NVIDIA CUDA / NVIDIA RTX A5000
no    | lut       | opencl|    1.612 |  165.985 |  103.0 | NVIDIA CUDA / NVIDIA RTX A5000
bbox  | lut       | opencl|    3.140 |  507.098 |  161.5 | NVIDIA CUDA / Quadro P2200
no    | lut       | opencl|    1.815 |  207.240 |  114.2 | NVIDIA CUDA / Quadro P2200
bbox  | lut       | opencl|    4.701 |  342.116 |   72.8 | Portable Computing Language / cpu-haswell-AMD Ryzen Threadripper PRO 3975WX 32-Cores
no    | lut       | opencl|    3.699 |  219.792 |   59.4 | Portable Computing Language / cpu-haswell-AMD Ryzen Threadripper PRO 3975WX 32-Cores
bbox  | lut       | opencl|    3.349 |  403.993 |  120.6 | Intel(R) OpenCL / AMD Ryzen Threadripper PRO 3975WX 32-Cores
no    | lut       | opencl|    2.707 |  273.430 |  101.0 | Intel(R) OpenCL / AMD Ryzen Threadripper PRO 3975WX 32-Cores
full  | lut       | opencl|    2.610 |  309.023 |  118.4 | NVIDIA CUDA / NVIDIA RTX A5000
full  | lut       | opencl|    2.709 |  381.123 |  140.7 | NVIDIA CUDA / Quadro P2200
full  | lut       | opencl|    4.668 |  210.364 |   45.1 | Portable Computing Language / cpu-haswell-AMD Ryzen Threadripper PRO 3975WX 32-Cores
full  | lut       | opencl|    3.753 |  299.781 |   79.9 | Intel(R) OpenCL / AMD Ryzen Threadripper PRO 3975WX 32-Cores
--------------------------------------------------------------------------------
print(f"Total runtime: {time.perf_counter()-start_time:.3f}s")
Total runtime: 488.307s