### Install pyvkfft with GPU dependencies Source: https://pyvkfft.readthedocs.io/en/latest/_sources/index.rst.txt Example command to install pyvkfft alongside pyopencl, cupy, and a specific CUDA version. ```shell # Example also with pyopencl and cupy conda install pyvkfft pyopencl cupy cuda-version=12 ``` -------------------------------- ### Initialize FFT Backends Source: https://pyvkfft.readthedocs.io/en/latest/examples/accuracy.html Configuration dictionary setup to map backend names to their respective FFT functions based on available hardware support. ```python if has_pycuda: # CUDA device_name = "CUDA: " + cuda_device_name else: # OpenCL device_name = "OpenCL: " + cl_device_name fft_dic = {"fftw": fftwn} if has_pycuda: fft_dic["vkfft-cuda"] = fftnvcu fft_dic["vkfft-cuda-LUT"] = fftnvculut if has_cufft: fft_dic["cufft"] = fftncu if has_pyopencl: fft_dic["vkfft-opencl"] = fftnvcl fft_dic["vkfft-opencl-LUT"] = fftnvcllut ``` -------------------------------- ### Initialize Imports and Test Data Source: https://pyvkfft.readthedocs.io/en/latest/examples/tuning.html Setup required libraries and define the test array dimensions for benchmarking. ```python import timeit import numpy as np import pyopencl as cl import pyopencl.array as cla from pyvkfft.fft import fftn, ifftn from pyvkfft.opencl import VkFFTApp from pyvkfft.benchmark import bench_pyvkfft_opencl ``` ```python ctx = cl.create_some_context() gpu_name = ctx.devices[0].name print("GPU:", gpu_name) cq = cl.CommandQueue(ctx) n = 250 ``` -------------------------------- ### Install pyvkfft via PyPI Source: https://pyvkfft.readthedocs.io/en/latest/_sources/index.rst.txt Standard installation command for pyvkfft using the pip package manager. ```shell pip install pyvkfft ``` -------------------------------- ### Create environment and install all via pip Source: https://pyvkfft.readthedocs.io/en/latest/_sources/index.rst.txt Create a base environment with conda and install all GPU-related packages via pip. ```shell mamba create -n myenv python=3.11 numpy scipy matplotlib ipython psutil pyopencl cupy pycuda nvidia::cuda conda activate myenv pip install pyopencl pycuda cupy-cuda12x pyvkfft ``` -------------------------------- ### Create environment and install pyvkfft via pip Source: https://pyvkfft.readthedocs.io/en/latest/_sources/index.rst.txt Create a base environment with conda and install pyvkfft using pip. ```shell mamba create -n myenv python=3.11 numpy scipy matplotlib ipython psutil pyopencl cupy pycuda nvidia::cuda conda activate myenv pip install pyvkfft ``` -------------------------------- ### Install pyvkfft via Conda Source: https://pyvkfft.readthedocs.io/en/latest/_sources/index.rst.txt Installation command using the conda-forge channel. ```shell conda config --add channels conda-forge conda install pyvkfft ``` -------------------------------- ### Sample benchmark output table Source: https://pyvkfft.readthedocs.io/en/latest/examples/benchmark.html Example of the formatted text output generated by the benchmark script. ```text Gbytes/s and time given for a couple (FFT, iFFT), dtype=complex64 16 x N x N [2D] vkFFT.opencl gpyfft[clFFT] vkFFT.cuda skcuda[cuFFT] 16 x 16 x 16 17.37 [ 14.05 µs] 7.43 [ 32.87 µs] 26.93 [ 9.07 µs] 23.83 [ 10.24 µs] [nb=1000] 16 x 18 x 18 22.08 [ 13.99 µs] 9.27 [ 33.34 µs] 35.83 [ 8.62 µs] 27.95 [ 11.06 µs] [nb=1000] 16 x 20 x 20 27.68 [ 13.78 µs] 11.35 [ 33.62 µs] 44.56 [ 8.56 µs] 35.40 [ 10.77 µs] [nb=1000] 16 x 21 x 21 30.73 [ 13.69 µs] 12.28 [ 34.25 µs] 44.27 [ 9.50 µs] 37.12 [ 11.33 µs] [nb=1000] 16 x 24 x 24 38.59 [ 14.23 µs] 16.41 [ 33.47 µs] 60.57 [ 9.07 µs] 52.16 [ 10.53 µs] [nb=1000] 16 x 25 x 25 41.75 [ 14.28 µs] 17.21 [ 34.63 µs] 65.74 [ 9.07 µs] 58.28 [ 10.23 µs] [nb=1000] 16 x 27 x 27 49.26 [ 14.11 µs] 19.91 [ 34.92 µs] 75.13 [ 9.25 µs] 67.06 [ 10.37 µs] [nb=1000] 16 x 28 x 28 52.65 [ 14.20 µs] 21.57 [ 34.66 µs] 78.34 [ 9.54 µs] 66.11 [ 11.31 µs] [nb=1000] 16 x 30 x 30 61.19 [ 14.03 µs] 25.50 [ 33.66 µs] 87.13 [ 9.85 µs] 73.64 [ 11.66 µs] [nb=1000] 16 x 32 x 32 70.43 [ 13.87 µs] 28.57 [ 34.18 µs] 105.78 [ 9.23 µs] 86.82 [ 11.25 µs] [nb=1000] 16 x 35 x 35 83.83 [ 13.94 µs] 34.04 [ 34.32 µs] 108.79 [ 10.74 µs] 94.36 [ 12.38 µs] [nb=1000] 16 x 36 x 36 88.17 [ 14.02 µs] 35.76 [ 34.56 µs] 124.87 [ 9.90 µs] 114.77 [ 10.77 µs] [nb=1000] 16 x 40 x 40 109.30 [ 13.96 µs] 44.30 [ 34.45 µs] 135.87 [ 11.23 µs] 124.65 [ 12.24 µs] [nb=1000] 16 x 42 x 42 120.19 [ 14.00 µs] 49.04 [ 34.31 µs] 156.20 [ 10.77 µs] 137.46 [ 12.24 µs] [nb=1000] ``` -------------------------------- ### Initialize CuPy and PyCUDA environments Source: https://pyvkfft.readthedocs.io/en/latest/examples/cupy-pycuda.html Setup the necessary imports and initialize the CUDA contexts for both CuPy and PyCUDA. ```python %matplotlib notebook import numpy as np try: from scipy.datasets import ascent except ImportError: from scipy.misc import ascent from scipy.fft import fftn, ifftn, rfftn, irfftn, fftshift from matplotlib.colors import LogNorm import matplotlib.pyplot as plt import cupy as cp # This forces the CuPy context init cupy_array = cp.zeros((4,4)) import pycuda import pycuda.autoinit import pycuda.gpuarray as cua from pyvkfft.cuda import * ``` -------------------------------- ### Configure auto-tuning parameters Source: https://pyvkfft.readthedocs.io/en/latest/api/core-fft.html Examples of dictionary configurations for the tune parameter to optimize FFT performance across different backends. ```python tune={'backend':'cupy'} ``` ```python tune={'backend':'pycuda', 'warpSize':[8,16,32,64,128]} ``` ```python tune={'backend':'pyopencl', 'aimThreads':[32,64,128,256]} ``` ```python tune={'backend':'cupy', 'groupedBatch':[[-1,-1,-1],[8,8,8], [4,16,16]} ``` ```python tune={'backend':'cupy, 'warpSize':[8,16,32,64,128], 'src':a} ``` -------------------------------- ### Install pyvkfft on Google Colab Source: https://pyvkfft.readthedocs.io/en/latest/examples/pyvkfft-fft.html Use this snippet to install pyvkfft and its dependencies in a Google Colab environment. ```python if False: # Install pyvkfft & dependencies only once using pip import os if not os.path.exists('dev/pyvkfft'): !mkdir dev !cd dev && git clone --recursive https://github.com/vincefn/pyvkfft.git !pip install pycuda # !pip install cupy !cd dev/pyvkfft && pip install . # scipy, matplotlib not required for pyvkfft, but for tests !pip install scipy matplotlib ``` -------------------------------- ### Perform FFT transforms with CuPy Source: https://pyvkfft.readthedocs.io/en/latest/examples/pyvkfft-fft.html Demonstrates C2C and R2C FFT transforms using CuPy arrays. Requires the cupy library to be installed and available. ```python try: import cupy as cp has_cupy = True except: has_cupy = False if has_cupy: print("C2C transform") d = cp.array(ascent().astype(np.complex64)) do_fft_and_plot(d) print("R2C transform, out-of-place in auto-allocated array") d = cp.array(ascent().astype(np.float32)) do_rfft_and_plot(d) print("R2C transform, out-of-place") dr = cp.array(ascent().astype(np.float32)) sh = (dr.shape[0], dr.shape[1]//2+1) dc = cp.empty(sh, dtype=np.complex64) do_rfft_and_plot(dr, dc) print("R2C transform, inplace") dr = cp.array(ascent().astype(np.float32)) do_rfft_and_plot(dr, dr) else: print("CuPy is not available") ``` -------------------------------- ### Initialize environment and imports Source: https://pyvkfft.readthedocs.io/en/latest/examples/accuracy.html Imports necessary libraries for FFT benchmarking and configures the display environment. ```python %matplotlib notebook import numpy as np import matplotlib.pyplot as plt # pyfftw supports long double accuracy from pyfftw.interfaces.scipy_fft import fftn as fftwn, ifftn as ifftwn from scipy.fft import fftn as fftsn, ifftn as ifftsn from scipy import stats from pyvkfft.fft import fftn as vkfftn, ifftn as ivkfftn from pyvkfft.base import primes from pyvkfft.version import __version__, vkfft_version from IPython.display import display, HTML display(HTML("")) print("pyvkfft %s, VkFFT %s" % (__version__, vkfft_version())) ``` -------------------------------- ### Command-line Usage Help Source: https://pyvkfft.readthedocs.io/en/latest/scripts/test-suite.html Display the available command-line arguments and options for the test suite. ```text usage: pyvkfft-test-suite [-h] [--gpu GPU] [--nproc NPROC] [--gpumem GPUMEM] --backend {pycuda,cupy,pyopencl} [--opencl_platform OPENCL_PLATFORM] [--transform {c2c,r2c,dct,dst} [{c2c,r2c,dct,dst} ...]] [--radix] [--single] [--ndim {1,2,3} [{1,2,3} ...]] [--fast-random FAST_RANDOM] [--dry-run] [--skip] ``` -------------------------------- ### Initialize Benchmark Environment Source: https://pyvkfft.readthedocs.io/en/latest/examples/benchmark.html Imports necessary libraries for CUDA and OpenCL support and checks for the availability of pyvkfft, skcuda, and gpyfft. ```python %matplotlib notebook gpu_name = None import os import platform import gc from itertools import permutations try: import pycuda.driver as cu_drv import pycuda.gpuarray as cua from pycuda import curandom import pyvkfft.cuda from pyvkfft.cuda import VkFFTApp as cuVkFFTApp from pyvkfft.base import primes has_pyvkfft_cuda = True except ImportError: has_pyvkfft_cuda = False try: import pyopencl as cl import pyopencl.array as cla from pyopencl import clrandom import pyvkfft.opencl from pyvkfft.opencl import VkFFTApp as clVkFFTApp from pyvkfft.base import primes has_pyvkfft_opencl = True except ImportError: has_pyvkfft_opencl = False try: import pycuda.autoinit import pycuda.driver as cu_drv import pycuda.gpuarray as cua from pycuda import curandom import skcuda.fft as cu_fft has_skcuda = True except: has_skcuda = False try: import pyopencl as cl import pyopencl.array as cla from pyopencl import clrandom import gpyfft has_gpyfft = True except: has_gpyfft = False import matplotlib.pyplot as plt import numpy as np import timeit ``` -------------------------------- ### Run pyvkfft-test command-line help Source: https://pyvkfft.readthedocs.io/en/latest/scripts/test.html Displays the usage and available arguments for the pyvkfft-test utility. ```bash usage: pyvkfft-test [-h] [--colour] [--html [HTML ...]] [--gpu GPU] [--opencl_platform OPENCL_PLATFORM] [--mailto MAILTO] [--mailto_fail MAILTO_FAIL] [--mailto_smtp MAILTO_SMTP] [--nproc NPROC] [--silent] [--c2c] [--systematic] [--quick] [--axes [AXES ...]] [--backend {pycuda,cupy,pyopencl} [{pycuda,cupy,pyopencl} ...]] [--bluestein] [--db [DB ...]] [--dct [{1,2,3,4}]] [--dst [{1,2,3,4}]] [--double] [--dry-run] [--fast-random FAST_RANDOM] [--inplace] [--graph [GRAPH]] [--lut] [--max-nb-tests MAX_NB_TESTS] [--ndim {1,2,3,12,123}] [--norm {0,1}] [--ref-long-double] [--r2c] [--fstride] [--radix [{2,3,5,7,11,13} ...]] [--radix-max-pow RADIX_MAX_POW] [--range RANGE RANGE] [--range-mb RANGE_MB RANGE_MB] [--range-nd-narrow RANGE_ND_NARROW RANGE_ND_NARROW] [--serial] [--timeout TIMEOUT] ``` -------------------------------- ### Create environment with all packages via Mamba Source: https://pyvkfft.readthedocs.io/en/latest/_sources/index.rst.txt Full environment creation including pyvkfft and all necessary GPU computing libraries. ```shell mamba create -n myenv python=3.11 numpy scipy matplotlib ipython psutil pyopencl cupy pycuda nvidia::cuda pyvkfft ``` -------------------------------- ### Initialize OpenCL and Benchmark FFT Source: https://pyvkfft.readthedocs.io/en/latest/examples/pyvkfft-tests-OpenCL.html Sets up an OpenCL context and defines a speed test function to measure FFT performance. ```python # Uncomment to have interactive plots: #%matplotlib widget import pyopencl as cl import pyopencl.array as cla import pyvkfft.opencl from pyvkfft.fft import fftn as vkfftn, ifftn as vkifftn, rfftn as vkrfftn, irfftn as vkirfftn from pyvkfft.opencl import VkFFTApp from pyvkfft.accuracy import l2, li import matplotlib.pyplot as plt from matplotlib.colors import LogNorm try: from scipy.datasets import ascent except: from scipy.misc import ascent import numpy as np from scipy.fft import fftn, ifftn, fftshift, rfftn, irfftn, dctn, idctn, dstn, idstn import timeit import os # os.environ['PYOPENCL_CTX']=':1' # Create some context on the first available GPU if 'PYOPENCL_CTX' in os.environ: ctx = cl.create_some_context() else: ctx = None # Find the first OpenCL GPU available and use it, unless for p in cl.get_platforms(): for d in p.get_devices(): if d.type & cl.device_type.GPU == 0: continue print("Selected device: ", d.name) ctx = cl.Context(devices=(d,)) break if ctx is not None: break cq = cl.CommandQueue(ctx) def speed(shape, ndim, queue, nb=10, inplace=True, norm=0): """ Perform a speed test using VkFFT ( :param shape: array shape to use :param ndim: number of dimensions for the FFT (e.g. can be 1, 2 or 3 for a 3D array, etc..) :param nb: number of repeats for timing :param stream: the pycuda.driver.Stream to be sued for calculations. If None, the default stream for the active context will be used. :param inplace: if True (default), do an in-place FFT :param norm: norm=0 will have the L2 norm multiplied by the FT size for each transform, whereas norm=1 will divide the L2 norm by the FT size for a backwards transform, similarly to numpy's fft norm='backwards'. :return: a tuple with the time per couple of FFT and iFFT, and the idealised memory throughput assuming one read and one write of the array per transform axis, in Gbytes/s. """ d = cla.to_device(queue, np.random.uniform(0, 1, shape).astype(np.complex64)) if not inplace: d1 = cla.empty_like(d) # print(d.shape) app = VkFFTApp(d.shape, d.dtype, queue=queue, ndim=ndim, inplace=inplace, norm=norm) queue.finish() t0 = timeit.default_timer() for i in range(nb): if inplace: d = app.ifft(d) d = app.fft(d) else: d1 = app.ifft(d, d1) d = app.fft(d1, d) queue.finish() dt = timeit.default_timer() - t0 shape = list(shape) if len(shape) < 3: shape += [1] * (3 - len(shape)) gbps = d.nbytes * nb * ndim * 2 * 2 / dt / 1024 ** 3 s = "" if not inplace: s= "[out-of-place]" print("(%4d %4d %4d)[%dD] dt=%6.2f ms %7.2f Gbytes/s %s [norm=%d]" % (shape[2], shape[1], shape[0], ndim, dt / nb * 1000, gbps, s, norm)) return dt, gbps #speed((16, 512, 512), 2, cq, inplace=True) #speed((256, 256, 256), 3, cq, inplace=True) speed((16, 768, 800), 2, cq, inplace=True) ``` -------------------------------- ### Initialize OpenCL environment Source: https://pyvkfft.readthedocs.io/en/latest/examples/accuracy.html Configures PyOpenCL to select a GPU device and provides wrapper functions for FFT execution. ```python # Init pyopencl cl_device_name = None try: import pyopencl as cl import pyopencl.array as cla import os from pyvkfft.opencl import VkFFTApp as VkFFTAppcl # Create some context on the first available GPU if 'PYOPENCL_CTX' in os.environ: ctx = cl.create_some_context() else: ctx = None # Find the first OpenCL GPU available and use it, unless for p in cl.get_platforms(): for d in p.get_devices(): if d.type & cl.device_type.GPU == 0: continue cl_device_name = d.name print("Selected OpenCL device: ", d.name) ctx = cl.Context(devices=(d,)) break if ctx is not None: break cq = cl.CommandQueue(ctx) def fftnvcl(d): dcl = cla.to_device(cq, d) #return vkfftn(d).get() app = VkFFTAppcl(d.shape, d.dtype, queue=cq, useLUT=0) return app.fft(dcl).get() def fftnvcllut(d): dcl = cla.to_device(cq, d) app = VkFFTAppcl(d.shape, d.dtype, queue=cq, useLUT=1) return app.fft(dcl).get() has_pyopencl = True except: print("OpenCL is not available") has_pyopencl = False ``` -------------------------------- ### Accuracy Benchmark Output Source: https://pyvkfft.readthedocs.io/en/latest/examples/accuracy.html Example output showing the L2 norm error for different FFT backends compared to FFTW. ```text N fftw vkfft-cuda vkfft-cuda-LUT vkfft-opencl vkfft-opencl-LUT cufft 8 5.661812e-08 4.771311e-08 4.771311e-08 4.771311e-08 4.771311e-08 4.538441e-08 9 6.925965e-08 7.249566e-08 7.249566e-08 7.422968e-08 7.422968e-08 8.148424e-08 12 6.159262e-08 6.638158e-08 6.638158e-08 6.638158e-08 6.638158e-08 7.102478e-08 16 6.543330e-08 1.039333e-07 8.245534e-08 1.031274e-07 8.245534e-08 1.048754e-07 18 6.431882e-08 1.475902e-07 9.247269e-08 1.475902e-07 1.026794e-07 7.987485e-08 24 7.437298e-08 1.118194e-07 7.039635e-08 1.063454e-07 7.663216e-08 9.952901e-08 27 1.101631e-07 2.058048e-07 7.791600e-08 1.934317e-07 8.185001e-08 8.483861e-08 32 8.698629e-08 1.209513e-07 6.916893e-08 1.241982e-07 8.133395e-08 1.410946e-07 36 7.085077e-08 2.411464e-07 9.978294e-08 2.446531e-07 9.479782e-08 1.257602e-07 48 8.651990e-08 1.417475e-07 7.830167e-08 1.494853e-07 8.045021e-08 1.064689e-07 54 8.836157e-08 2.339144e-07 8.168266e-08 2.323761e-07 8.433767e-08 1.439560e-07 64 1.022756e-07 1.441626e-07 9.541947e-08 1.436288e-07 9.778236e-08 1.194721e-07 72 8.032949e-08 1.897170e-07 8.997575e-08 1.934350e-07 9.029303e-08 1.011575e-07 81 9.224252e-08 2.426904e-07 1.057223e-07 2.317988e-07 9.535692e-08 1.291147e-07 96 9.801735e-08 2.243387e-07 9.796188e-08 2.162218e-07 1.000744e-07 1.313988e-07 108 1.095297e-07 2.498205e-07 1.109149e-07 2.554678e-07 1.061535e-07 1.772444e-07 128 9.785448e-08 1.850773e-07 9.511398e-08 1.859862e-07 9.421877e-08 1.527004e-07 144 1.153802e-07 2.039221e-07 9.885693e-08 2.074026e-07 9.331911e-08 1.763623e-07 162 1.058271e-07 2.952651e-07 1.100295e-07 2.893044e-07 1.089239e-07 1.298426e-07 192 1.034159e-07 2.286529e-07 9.648514e-08 2.320203e-07 9.776815e-08 1.936020e-07 216 1.026397e-07 3.446967e-07 1.136366e-07 3.540606e-07 1.162158e-07 1.348444e-07 ``` -------------------------------- ### Execute PyCUDA FFT transforms Source: https://pyvkfft.readthedocs.io/en/latest/examples/pyvkfft-fft.html Example script to perform various FFT transforms using PyCUDA GPU arrays. ```python try: import pycuda.autoinit import pycuda.gpuarray as cua has_pycuda = True except: has_pycuda = False if has_pycuda: print("C2C transform") d = cua.to_gpu(ascent().astype(np.complex64)) do_fft_and_plot(d) print("R2C transform, out-of-place in auto-allocated array") d = cua.to_gpu(ascent().astype(np.float32)) do_rfft_and_plot(d) print("R2C transform, out-of-place") dr = cua.to_gpu(ascent().astype(np.float32)) sh = (dr.shape[0], dr.shape[1]//2+1) dc = cua.empty(sh, dtype=np.complex64) do_rfft_and_plot(dr, dc) print("R2C transform, inplace") dr = cua.to_gpu(ascent().astype(np.float32)) do_rfft_and_plot(dr, dr) else: print("PyCUDA is not available") ``` -------------------------------- ### Initialize CUDA environment Source: https://pyvkfft.readthedocs.io/en/latest/examples/accuracy.html Sets up PyCUDA and scikit-cuda for GPU-accelerated FFT operations, including workarounds for cuFFT memory management. ```python # Init pycuda cuda_device_name = None try: import pycuda.autoinit import pycuda.gpuarray as cua from pyvkfft.cuda import VkFFTApp as VkFFTAppcu has_pycuda = True cuda_device_name = pycuda.autoinit.device.name() print("Selected CUDA device: ", cuda_device_name) v_cufft_plan = [] def fftncu(d): dcu = cua.to_gpu(d) plan = cu_fft.Plan(d.shape, d.dtype, d.dtype) cu_fft.fft(dcu, dcu, plan, scale=False) if cu_fft.cufft.cufftGetVersion() >= 10200: v_cufft_plan.append(plan) return dcu.get() def fftnvcu(d): dcu = cua.to_gpu(d) #return vkfftn(dcu).get() app = VkFFTAppcu(d.shape, d.dtype, useLUT=0) return app.fft(dcu).get() def fftnvculut(d): dcu = cua.to_gpu(d) app = VkFFTAppcu(d.shape, d.dtype, useLUT=1) return app.fft(dcu).get() try: import skcuda.fft as cu_fft has_cufft = True if cu_fft.cufft.cufftGetVersion() >= 10200: print("WARNING: cuFFT plans destruction is inhibited as a workaround for " "an issue with CUDA>=11.0. See https://github.com/lebedov/scikit-cuda/issues/308\n" "=> all cuFFT plans will be kept in GPU memory, effectively creating a memory leak " "(this should be fine to run this notebook)") except: has_cufft = False except: print("CUDA is not available") has_pycuda = False has_cufft = False ``` -------------------------------- ### Sample 1D Non-Radix Accuracy Output Source: https://pyvkfft.readthedocs.io/en/latest/examples/accuracy.html Example output showing the accuracy comparison across different FFT backends for various transform sizes (N). ```text N fftw vkfft-cuda vkfft-cuda-LUT vkfft-opencl vkfft-opencl-LUT cufft 17 6.254615e-08 1.015721e-07 1.102006e-07 1.102006e-07 1.102006e-07 7.038351e-08 19 8.248360e-08 1.645417e-07 1.248262e-07 1.105743e-07 1.105743e-07 7.713461e-08 23 9.364838e-08 2.120295e-07 1.265788e-07 1.307243e-07 1.307243e-07 9.525661e-08 29 9.151393e-08 1.697528e-07 1.473385e-07 1.526987e-07 1.526987e-07 6.975211e-08 31 9.476318e-08 2.802384e-07 1.140413e-07 1.201944e-07 1.201944e-07 7.906383e-08 34 7.735947e-08 1.776248e-07 1.045113e-07 1.034587e-07 1.034587e-07 8.285427e-08 37 1.484575e-07 3.000786e-07 1.426029e-07 1.731795e-07 1.731795e-07 9.075627e-08 38 9.740193e-08 2.774460e-07 1.702731e-07 1.763272e-07 1.763272e-07 1.093944e-07 41 1.353334e-07 3.260490e-07 1.226760e-07 1.258329e-07 1.258329e-07 9.509407e-08 43 9.872378e-08 2.399786e-07 1.835915e-07 1.852351e-07 1.852351e-07 1.046902e-07 46 8.949255e-08 2.700867e-07 1.125207e-07 1.034681e-07 1.034681e-07 1.174656e-07 47 1.830142e-07 1.198861e-07 1.198861e-07 1.198861e-07 1.198861e-07 1.057758e-07 51 8.422249e-08 2.138944e-07 1.312271e-07 1.413012e-07 1.413012e-07 9.646047e-08 53 2.024566e-07 2.477728e-07 1.450103e-07 1.570705e-07 1.570705e-07 1.102411e-07 57 9.803056e-08 3.179224e-07 1.579285e-07 1.649120e-07 1.649120e-07 9.402163e-08 58 9.713275e-08 2.461764e-07 1.489107e-07 1.607300e-07 1.607300e-07 1.089946e-07 59 1.950429e-07 1.029824e-07 1.029824e-07 1.029824e-07 1.029824e-07 1.092878e-07 61 1.497549e-07 2.960745e-07 1.713226e-07 1.514671e-07 1.514671e-07 1.104706e-07 62 1.136793e-07 2.791304e-07 1.393296e-07 1.469882e-07 1.469882e-07 1.049168e-07 67 2.155272e-07 3.261446e-07 1.541285e-07 1.611212e-07 1.611212e-07 1.426873e-07 68 9.695182e-08 2.457007e-07 1.163033e-07 1.161389e-07 1.161389e-07 1.830814e-07 69 9.709617e-08 3.187640e-07 1.400185e-07 1.366575e-07 1.366575e-07 1.235348e-07 71 2.174195e-07 2.688835e-07 2.061562e-07 1.606750e-07 1.606750e-07 1.163606e-07 73 1.692324e-07 3.746569e-07 1.741872e-07 1.690175e-07 1.690175e-07 1.162877e-07 74 1.575586e-07 3.353020e-07 1.659695e-07 1.662891e-07 1.662891e-07 1.084640e-07 ``` -------------------------------- ### Initialize benchmark result headers Source: https://pyvkfft.readthedocs.io/en/latest/examples/benchmark.html Constructs the header string for benchmark output based on the number of dimensions. ```python if ndim == 1: header_results = "%4d x%4d x%4s [%dD]" % (nz, nz, "N", ndim) elif ndim ==2: header_results = "%4d x%4s x%4s [%dD]" % (nz, "N", "N", ndim) else: header_results = "%4s x%4s x%4s [%dD]" % ("N", "N", "N", ndim) for b in results.keys(): if b != "n" and "-dt" not in b: header_results += "%17s " % b print("Gbytes/s and time given for a couple (FFT, iFFT), dtype=%s" % np.dtype(np.complex64).name) print() print(header_results) ``` -------------------------------- ### Run Full Test Suite Source: https://pyvkfft.readthedocs.io/en/latest/scripts/test-suite.html Execute the full test suite using the pycuda backend on a V100 GPU with 32GB of memory. ```bash pyvkfft-test-suite --gpumem 32 --backend pycuda --gpu V100 ``` -------------------------------- ### pyvkfft-benchmark Source: https://pyvkfft.readthedocs.io/en/latest/_sources/scripts/benchmark.rst.txt The pyvkfft-benchmark command-line tool allows users to run performance benchmarks for VkFFT transforms. ```APIDOC ## pyvkfft-benchmark ### Description A command-line utility to benchmark VkFFT performance. It utilizes the `pyvkfft.scripts.pyvkfft_benchmark` module to execute performance tests. ### Usage `pyvkfft-benchmark [options]` ### Options Refer to the standard argparse output generated by the `make_parser` function in `pyvkfft.scripts.pyvkfft_benchmark` for specific flags and arguments. ``` -------------------------------- ### Benchmark with Default Parameters Source: https://pyvkfft.readthedocs.io/en/latest/examples/tuning.html Execute a baseline benchmark to measure performance without custom tuning. ```python res = bench_pyvkfft_opencl((n,n,n),ndim=2,gpu_name=gpu_name) print(f"Speed with default parameters: {res[1]:6.1f} Gbytes/s") ``` -------------------------------- ### Perform FFT transforms with PyOpenCL Source: https://pyvkfft.readthedocs.io/en/latest/examples/pyvkfft-fft.html Demonstrates C2C and R2C FFT transforms using PyOpenCL arrays. Requires a valid OpenCL context and command queue. ```python try: import pyopencl as cl import pyopencl.array as cla import os # Create some context on the first available GPU if 'PYOPENCL_CTX' in os.environ: ctx = cl.create_some_context() else: ctx = None # Find the first OpenCL GPU available and use it, unless for p in cl.get_platforms(): for d in p.get_devices(): if d.type & cl.device_type.GPU == 0: continue print("Selected device: ", d.name) ctx = cl.Context(devices=(d,)) break if ctx is not None: break cq = cl.CommandQueue(ctx) has_pyopencl = True except: has_pyopencl = False if has_pyopencl: print("C2C transform") d = cla.to_device(cq, ascent().astype(np.complex64)) do_fft_and_plot(d) print("R2C transform, out-of-place in auto-allocated array") d = cla.to_device(cq, ascent().astype(np.float32)) do_rfft_and_plot(d) print("R2C transform, out-of-place") dr = cla.to_device(cq, ascent().astype(np.float32)) sh = (dr.shape[0], dr.shape[1]//2+1) dc = cla.empty(cq, sh, dtype=np.complex64) do_rfft_and_plot(dr, dc) print("R2C transform, inplace") dr = cla.to_device(cq, ascent().astype(np.float32)) do_rfft_and_plot(dr, dr) else: print("PyOpenCL is not available") ``` -------------------------------- ### Import pyvkfft and dependencies Source: https://pyvkfft.readthedocs.io/en/latest/examples/pyvkfft-fft.html Standard imports for performing FFT operations and visualizing results with matplotlib. ```python from pyvkfft.fft import fftn, ifftn, rfftn, irfftn import numpy as np try: from scipy.datasets import ascent except ImportError: from scipy.misc import ascent from numpy.fft import fftshift %matplotlib notebook import matplotlib.pyplot as plt from matplotlib.colors import LogNorm ``` -------------------------------- ### Run standard and quick tests Source: https://pyvkfft.readthedocs.io/en/latest/scripts/test.html Executes the full suite of FFT interface tests or a faster subset for quick verification. ```bash pyvkfft-test ``` ```bash pyvkfft-test --quick ``` -------------------------------- ### Select GPU Device Source: https://pyvkfft.readthedocs.io/en/latest/examples/benchmark.html Configures the OpenCL or CUDA context based on available hardware and environment variables. ```python gpu_name_real = None if has_pyvkfft_opencl or has_gpyfft: # Create some context on the first available GPU if 'PYOPENCL_CTX' in os.environ: cl_ctx = cl.create_some_context() else: cl_ctx = None # Find the first OpenCL GPU available and use it, unless for p in cl.get_platforms(): for d in p.get_devices(): if d.type & cl.device_type.GPU == 0: continue gpu_name_real = d.name print("Selected OpenCL device: ", d.name) cl_ctx = cl.Context(devices=(d,)) break if cl_ctx is not None: break cq = cl.CommandQueue(cl_ctx) if has_pyvkfft_cuda or has_skcuda: if gpu_name is None: d = cu_drv.Device(0) gpu_name_real = d.name() print("Selected CUDA device: ", d.name()) cu_ctx = d.make_context() else: for i in range(cu_drv.Device.count()): d = cu_drv.Device(i) if gpu_name.lower() in d.name().lower(): gpu_name_real = d.name() print("Selected CUDA device: ", d.name()) cu_ctx = d.make_context() break ``` -------------------------------- ### Configure Benchmark Parameters Source: https://pyvkfft.readthedocs.io/en/latest/examples/benchmark.html Sets the dimensions, data types, and result storage structures for the FFT benchmark. ```python ndim = 2 # Dimensions for the FFT (1, 2 or 3) nmax = 3072 # Maximum FFT size (e.g. 512 for 3D, 4096 for 2D,...) - nmax is included dtype = np.complex64 # Data type radix_max = 7 # Largest allowed prime factor: use 2 for quick tests or 7 (13 is also possible) cl_platform = None # If None, the first OpenCL platform with a GPU is selected. Otherwise match part of the platform name nb_repeat = 3 # Perform nb_repeat tests, keep best time # number of parallel arrays for 2D (nz, n, n) and 1D (nz, nz, n) transforms nz = 16 plt.figure(figsize=(9.5, 8)) results = {"n": []} if "vkFFT.opencl" not in results and has_pyvkfft_opencl: results["vkFFT.opencl"] = [] results["vkFFT.opencl-dt"] = [] if "gpyfft[clFFT]" not in results and has_gpyfft: results["gpyfft[clFFT]"] = [] results["gpyfft[clFFT]-dt"] = [] if "vkFFT.cuda" not in results and has_pyvkfft_cuda: results["vkFFT.cuda"] = [] results["vkFFT.cuda-dt"] = [] if "skcuda[cuFFT]" not in results and has_skcuda: results["skcuda[cuFFT]"] = [] results["skcuda[cuFFT]-dt"] = [] plans_skcuda = [] ```