Using Different Backends

For any of the examples here, simply use a different GPU array and AcceleratedKernels.jl will pick the right backend:

# Intel Graphicsusing oneAPIv = oneArray{Int32}(undef, 100_000)             # Empty array# AMD ROCmusing AMDGPUv = ROCArray{Float64}(1:100_000)                # A range converted to Float64# Apple Metalusing Metalv = MtlArray(rand(Float32, 100_000))            # Transfer from host to device# NVidia CUDAusing CUDAv = CuArray{UInt32}(0:5:100_000)                # Range with explicit step size# OpenCL, here on the CPU through PoCLusing OpenCL, pocl_jllv = CLArray(rand(Float32, 100_000))# Transfer GPU array backv_host = Array(v)

All publicly-exposed functions also run on host arrays, with the same interface:

import AcceleratedKernels as AKv = Vector(-1000:1000)                          # Normal CPU arrayAK.reduce(+, v; init=0)AK.reduce(+, v; init=0, alg=AK.CPUThreads.Partitioned(max_tasks=4))   # at most 4 tasks

On the host, operations run on Julia threads and by default use as many tasks as Julia has threads. See Algorithms and backends for the algorithms and their settings.

AcceleratedKernels re-exports two KernelAbstractions functions: AK.get_backend(v) returns the backend of an array, to pass as backend to an operation over a range (see foreachindex), and AK.synchronize(backend) waits for the work queued on it. Operations return without waiting for their kernels where their result does not need it, as GPU array libraries do, so call synchronize before timing them.