Array Programming
The ROCArray type is the core of AMDGPU.jl. It is a dense, GPU-resident array that implements Julia's AbstractArray interface, so most array code written for Array works on the GPU with little or no change. This is the recommended, high-level way to use AMDGPU.jl — you rarely need to write kernels by hand.
Construction
Copy an existing array to the device by wrapping it in a ROCArray, or build one directly on the device with the familiar constructors:
julia> ROCArray([1, 2, 3, 4]) |> Array # move host array to device (shown via Array)
4-element Vector{Int64}:
1
2
3
4
julia> AMDGPU.ones(Float32, 2, 2) |> Array
2×2 Matrix{Float32}:
1.0 1.0
1.0 1.0The device-side constructors mirror Base: AMDGPU.zeros, AMDGPU.ones, AMDGPU.fill, AMDGPU.rand, AMDGPU.randn, and similar. All take an optional element type and dimensions.
Alternatively, roc copies to the device while narrowing floating-point element types to 32-bit — handy when single precision is preferred for performance. It also recurses into custom structs, converting their array fields:
julia> x = roc([1.0, 2.0, 3.0]); # Float64 host array
julia> eltype(x) # narrowed to Float32 on the device
Float32
julia> x isa ROCArray
trueAMDGPU.ROCArray Type
ROCArray{T,N,B} <: AbstractGPUArray{T,N}N-dimensional dense array of element type T stored in GPU memory (backed by buffer type B). ROCArray implements Julia's AbstractArray interface, so broadcasting, reductions, and linear algebra run on the GPU.
Copy a host array to the device by wrapping it, or allocate directly:
ROCArray([1, 2, 3]) # copy a host array to the device
ROCArray{Float32}(undef, 4, 4) # uninitialized 4×4 device matrixMove data back to the host with Array(x). See also roc, which copies to the device while narrowing floating-point types to 32-bit, and the AMDGPU.zeros / AMDGPU.ones / AMDGPU.rand constructors.
AMDGPU.roc Function
roc(x)Adapt x for the GPU: convert arrays to ROCArray while narrowing floating-point element types to 32-bit (Float64→Float32, ComplexF64→ComplexF32; Float16 is left unchanged, other element types are preserved). Like Adapt.adapt, it recurses into custom structs and converts their array fields.
This mirrors CUDA.jl's cu. Reach for it when single precision is preferred (e.g. for performance); use the ROCArray constructor directly to keep the original element type.
roc([1.0, 2.0]) # 2-element ROCArray{Float32}
roc(1:3) # non-float eltype preserved: ROCArray{Int64}Host ↔ device transfer
Wrapping a host array in ROCArray copies it to the GPU; calling Array on a ROCArray copies it back:
julia> a = ROCArray(Float32[1, 2, 3]);
julia> Array(a)
3-element Vector{Float32}:
1.0
2.0
3.0Transfers are relatively expensive — keep data on the device across as many operations as possible rather than copying back and forth.
Broadcasting
Broadcasting works exactly as on the CPU and fuses into a single kernel, so chained element-wise operations do not allocate intermediate arrays:
julia> x = ROCArray(Float32[1, 2, 3]);
julia> y = ROCArray(Float32[10, 20, 30]);
julia> Array(@. 2x + y)
3-element Vector{Float32}:
12.0
24.0
36.0Reductions, scans and sorting
Reductions (sum, prod, maximum, mapreduce, …), scans (cumsum, accumulate), sort/sortperm, and reverse all run on the GPU:
julia> sum(ROCArray(1:100))
5050
julia> mapreduce(x -> x^2, +, ROCArray(1:4))
30
julia> Array(cumsum(ROCArray([1, 2, 3, 4])))
4-element Vector{Int64}:
1
3
6
10
julia> Array(sort(ROCArray([3, 1, 2, 5, 4])))
5-element Vector{Int64}:
1
2
3
4
5Scalar indexing
Reading or writing a single element from the host (a[i]) would require a separate GPU transfer per element, which is catastrophically slow. AMDGPU.jl therefore disallows scalar indexing by default and throws an error:
julia> a = ROCArray([1, 2, 3]);
julia> a[1]
ERROR: Scalar indexing is disallowed.If you genuinely need it (e.g. in a one-off test), opt in explicitly:
AMDGPU.allowscalar(true) # globally (discouraged)
AMDGPU.@allowscalar a[1] # for a single expression (preferred)Prefer vectorized operations, broadcasting, or a custom kernel instead. See Kernel Programming for writing your own kernels.
Views and reshaping
view, reshape, reinterpret, and adjoint/transpose all work and return lazy wrappers that share the parent's memory — no copy is made:
julia> a = ROCArray(reshape(1:6, 2, 3));
julia> Array(view(a, :, 2))
2-element Vector{Int64}:
3
4Linear algebra
Matrix multiplication and factorizations dispatch to the vendor libraries (rocBLAS, rocSOLVER). Standard LinearAlgebra functions — *, mul!, \, cholesky, lu, qr — work directly on ROCArray. See Linear Algebra for the list of accelerated operations.