Skip to content

JuliaGPU/OpenCL.jl

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

OpenCL.jl

Julia interface for the OpenCL parallel computation API

This package aims to be a complete solution for OpenCL programming in Julia, similar in scope to [PyOpenCL] for Python. It provides a high level API for OpenCL to make programing hardware accelerators, such as GPUs, FPGAs, and DSPs, as well as multicore CPUs much less onerous.

OpenCL.jl needs your help! If you can help maintaining this package, please reach out on the JuliaLang Slack #gpu channel

Also note: OpenCL.jl is currently undergoing major changes. If you have old code, developed for OpenCL.jl v0.9, please check NEWS.md for an overview of the changes.

Installation

  1. Install an OpenCL driver. You can install one system-wide, i.e., using your package manager, or use pocl_jll.jl for a CPU back-end.
  2. Add OpenCL to your Julia environment:
using Pkg
Pkg.add("OpenCL")
  1. Test your installation:
julia> OpenCL.versioninfo()
OpenCL.jl version 0.10.0

Toolchain:
 - Julia v1.10.5
 - OpenCL_jll v2024.5.8+1

Available platforms: 3
 - Portable Computing Language
   version: OpenCL 3.0 PoCL 6.0  Linux, Release, RELOC, SPIR-V, LLVM 15.0.7jl, SLEEF, DISTRO, POCL_DEBUG
   · cpu-haswell-AMD Ryzen 9 5950X 16-Core Processor (fp64, il)
 - NVIDIA CUDA
   version: OpenCL 3.0 CUDA 12.6.65
   · NVIDIA RTX 6000 Ada Generation (fp64)
 - Intel(R) OpenCL Graphics
   version: OpenCL 3.0
   · Intel(R) Arc(TM) A770 Graphics (fp16, il)

Basic example: vector add

The traditional way of using OpenCL is by writing kernel source code in OpenCL C. For example, a simple vector addition:

using OpenCL, pocl_jll

const source = """
   __kernel void vadd(__global const float *a,
                      __global const float *b,
                      __global float *c) {
      int gid = get_global_id(0);
      c[gid] = a[gid] + b[gid];
    }"""

a = rand(Float32, 50_000)
b = rand(Float32, 50_000)

d_a = CLArray(a; access=:r)
d_b = CLArray(b; access=:r)
d_c = similar(d_a; access=:w)

p = cl.Program(; source) |> cl.build!
k = cl.Kernel(p, "vadd")

clcall(k, Tuple{Ptr{Float32}, Ptr{Float32}, Ptr{Float32}},
       d_a, d_b, d_c; global_size=size(a))

c = Array(d_c)

@assert a + b  c

Native example: vector add

If your platform supports SPIR-V, it's possible to use Julia functions as kernels:

using OpenCL, pocl_jll

function vadd(a, b, c)
    gid = get_global_id(1)
    @inbounds c[gid] = a[gid] + b[gid]
    return
end

a = rand(Float32, 50_000)
b = rand(Float32, 50_000)

d_a = CLArray(a; access=:r)
d_b = CLArray(b; access=:r)
d_c = similar(d_a; access=:w)

@opencl global_size=size(a) vadd(d_a, d_b, d_c)

c = Array(d_c)

@assert a + b  c

More examples

You may want to check out the examples folder. Either git clone the repository to your local machine or navigate to the OpenCL.jl install directory via:

using OpenCL
cd(joinpath(dirname(pathof(OpenCL)), ".."))

Otherwise, feel free to take a look at the Jupyter notebooks below:

Credit

This package is heavily influenced by the work of others: