Skip to content

Indexing, Sorting & Utilities ​

Indexing and slices ​

1D and 2D arrays support slicing with :, unit ranges (2:4) and integers. A slice is a view: writing to it changes the original array.

julia
A = cuNumeric.rand(Float32, 100, 100)
B = cuNumeric.rand(Float32, 2, 100)
top = A[1:10, :]               # view, no copy
A[2:3, :] = B                  # copy B into rows 2–3
A[:, 5] .= 0f0                 # fill a column
A[2:3, :] .= A[1:2, :] .+ 1f0  # broadcast into a slice

Differences from Base:

  • A slice with an integer index keeps that dimension: A[:, 2] is n×1 and A[2, :] is 1×n, not a vector.

  • Assign a scalar to a slice with .=. A[1:2, :] = 0f0 errors.

  • Not supported: step ranges (1:2:n), index or Boolean arrays, and slicing arrays with 3 or more dimensions.

  • Single elements (A[2, 3]) need @allowscalar.

Sorting and searching ​

sort, sort!, unique, searchsortedfirst, searchsortedlast and searchsorted are not Base's: call them with the cuNumeric. prefix.

julia
v = cuNumeric.rand(Float32, 1000)
s = cuNumeric.sort(v)                     # cuNumeric.sort!(v) sorts in place
i = cuNumeric.searchsortedfirst(s, 0.5f0) # 0D NDArray; fetch(i) for an Int
u = cuNumeric.unique(NDArray([3, 1, 3]))  # [1, 3], sorted

N-d arrays need dims. Sorts are unstable unless stable=true.

cuNumeric.NDArray Method
julia
NDArray{T}(undef, dims::Int...)
NDArray{T}(undef, dims::Dims)

Allocate an NDArray{T}. Storage is zero-initialized so it can be read immediately.

source
Base.:== Method
julia
==(arr::NDArray, julia_arr::Array)
==(julia_arr::Array, arr::NDArray)

Compare an NDArray and a Julia Array for element-wise equality.

Returns true if both arrays have the same shape and all corresponding elements are equal. Returns false otherwise (including if sizes differ, with a warning).

Warning

This function uses scalar indexing and should not be used in production code. This is meant for testing.

Examples

julia
arr = cuNumeric.ones(2, 2)
julia_arr = ones(2, 2)
arr == julia_arr
julia_arr == arr
julia_arr2 = zeros(2, 2)
arr == julia_arr2
source
Base.:== Method
julia
==(arr1::NDArray, arr2::NDArray)
!=(arr1::NDArray, arr2::NDArray)

Element-wise equality reduced to a 0-d NDArray{Bool} (not a Julia Bool). Same shape and values yields true; mismatched shape or rank yields false. Mixed dtypes follow Julia == (promote, then compare). Use fetch or A[] (with allowscalar) for a host value. Broadcast .== / .!= stay elementwise.

Examples

julia
a = cuNumeric.ones(2, 2)
b = cuNumeric.ones(2, 2)
a == b
c = cuNumeric.zeros(2, 2)
a == c
source
Base.copy Method
julia
Base.copy(arr::NDArray)

Create and return a deep copy of the given NDArray.

Examples

julia
a = cuNumeric.ones(2, 2)
b = copy(a)
b === a
b[1,1] == a[1,1]
source
Base.copyto! Method
julia
copyto!(arr::NDArray, other::NDArray)
copyto!(arr::NDArray, other::Array)

Overwrite arr with the values of other, which may be another NDArray or a Julia host Array of the same element type and shape. A host copy returns once the data is on the device, so other can be reused right away.

Examples

julia
a = cuNumeric.zeros(2, 2)
b = cuNumeric.ones(2, 2)
copyto!(a, b);
copyto!(a, Float32[1 2; 3 4]);
source
Base.eltype Method
julia
Base.eltype(arr::NDArray)

Returns the element type of the NDArray.

source
Base.firstindex Method
julia
Base.firstindex(arr::NDArray, dim::Integer)
Base.lastindex(arr::NDArray, dim::Integer)
Base.lastindex(arr::NDArray)

Provide the first and last valid indices along a given dimension dim for NDArray.

Examples

julia
arr = cuNumeric.rand(4, 5);
firstindex(arr, 2)
lastindex(arr, 2)
lastindex(arr)
source
Base.isapprox Method
julia
isapprox(arr1::NDArray, arr2::NDArray; atol=0, rtol=0)
isapprox(arr::NDArray, julia_array::AbstractArray; atol=0, rtol=0)
isapprox(julia_array::AbstractArray, arr::NDArray; atol=0, rtol=0)

Approximate equality comparison between two NDArrays or between an NDArray and a Julia AbstractArray.

Returns true if the arrays have the same shape and all corresponding elements are approximately equal within the given absolute tolerance atol and relative tolerance rtol.

The second and third methods handle comparisons between NDArray and Julia arrays by forwarding to a common comparison function.

Warning

This function uses scalar indexing and should not be used in production code. This is meant for testing.

Examples

julia
arr1 = cuNumeric.ones(2, 2)
arr2 = cuNumeric.ones(2, 2)
julia_arr = ones(2, 2)
isapprox(arr1, arr2)
isapprox(arr1, julia_arr)
isapprox(julia_arr, arr2)
source
Base.permutedims Method
julia
Base.permutedims(arr::NDArray, perm)

Permute the dimensions of arr according to perm, a 1-based permutation of 1:ndims(arr). Rank is preserved. See also transpose.

source
Base.size Method
julia
Base.size(arr::NDArray)
Base.size(arr::NDArray, dim::Integer)

Return the size of the given NDArray.

  • Base.size(arr) returns a tuple of dimensions of the array.

  • Base.size(arr, dim) returns the size of the array along the specified dimension dim.

Examples

julia
arr = cuNumeric.rand(3, 4, 5);
size(arr)
size(arr, 2)
source
cuNumeric.as_type Method
julia
as_type(arr::NDArray, t::Type{T}) where {T}

Convert the element type of arr to type T, returning a new NDArray with elements cast to T.

Arguments

  • arr::NDArray: Input array.

  • t::Type{T}: Target element type.

Returns

A new NDArray with the same shape as arr but with elements of type T.

Examples

julia
arr = cuNumeric.rand(4, 5);
as_type(arr, Float32)
source
cuNumeric.h5read Method
julia
h5read(path::String, dataset::String; layout::Symbol=:row) -> NDArray

Read a dataset from an HDF5 file into an NDArray.

Arguments

  • path: Path to the HDF5 file.

  • dataset: Name of the dataset to read.

Keywords

  • layout: On-disk memory order, either :row (default) or :col.
source
cuNumeric.h5write Method
julia
h5write(path::String, dataset::String, arr::NDArray)

Write an NDArray directly to an HDF5 dataset without a host copy or dimension flip.

A leftover empty or truncated .h5 from a crashed write is removed first. A valid HDF5 file is left in place so Legate can overwrite it. The *_legate_vds sidecar is not touched: it holds the payload of a VDS write.

Arguments

  • path: Path to the HDF5 file.

  • dataset: Name of the dataset to write.

  • arr: The array to write.

source
cuNumeric.ravel Method
julia
cuNumeric.ravel(arr::NDArray)

Return a flattened 1D view of the input NDArray.

source
cuNumeric.squeeze Method
julia
squeeze(arr::NDArray)
squeeze(arr::NDArray, dims)

Drop size-1 dimensions of arr. With no dims, every size-1 axis is removed. With dims (a 1-based integer or collection), only those axes are removed and each must have size 1.

See also Base.dropdims.

source
cuNumeric.transpose Method
julia
cuNumeric.transpose(arr::NDArray)

Return a new NDArray that is the transpose of the input arr.

source
cuNumeric.searchsorted Method
julia
cuNumeric.searchsorted(a::NDArray{T,1}, x::Number)

searchsortedfirst(a, x):searchsortedlast(a, x) as a UnitRange, matching Base's scalar search. Materializes two 0-d index arrays via fetch. Not Base.searchsorted.

source
cuNumeric.searchsortedfirst Method
julia
cuNumeric.searchsortedfirst(a::NDArray{T,1}, x)
cuNumeric.searchsortedlast(a::NDArray{T,1}, x)

Insertion indices into a 1-d sorted a. x may be a Number or an NDArray of needles.

Scalar queries return a 0-d NDArray{Int64} (not a Julia Int); use fetch for an Int. Array queries return an NDArray{Int64} with the shape of the needles. Indices are 1-based.

Not Base.searchsortedfirst / searchsortedlast. a must already be sorted ascending. lt / by / rev are not accepted. Complex arrays are not supported.

source
cuNumeric.sort! Method
julia
cuNumeric.sort!(v::NDArray{T,1}; stable::Bool=false)
cuNumeric.sort!(A::NDArray; dims::Integer, stable::Bool=false)

Sort A in place. Same kwargs as cuNumeric.sort. Not Base.sort!.

source
cuNumeric.sort Method
julia
cuNumeric.sort(v::NDArray{T,1}; stable::Bool=false)
cuNumeric.sort(A::NDArray; dims::Integer, stable::Bool=false)

Return a copy of A sorted in ascending order.

This is not Base.sort. Call it as cuNumeric.sort. alg, lt, by, rev, and order are not accepted.

For rank greater than 1, dims is required (Julia 1-based). stable=true sets the cupynumeric stable-sort flag (kind="stable"); the default is unstable (kind="quicksort"). These names do not run Julia's QuickSort or MergeSort. Complex values are ordered lexicographically by (real, imag).

source
cuNumeric.unique Method
julia
cuNumeric.unique(A::NDArray) -> NDArray{T,1}

Sorted unique elements of A, flattened to 1-d.

This is not Base.unique, which keeps first-occurrence order and does not sort. dims, return_index, return_inverse, and return_counts are not accepted; cupynumeric does not implement them.

source
cuNumeric._scalar_indexing_stdlib_caller Method

Best-effort: outermost Base or LinearAlgebra frame above cuNumeric scalar-index frames. Walk innermost-first, skip cuNumeric/Core (and frames with unknown module), indexing/iteration plumbing, keyword-call wrappers (kwcall), and Base loader frames (include_string, IncludeInto on Julia 1.12+, etc.). Keep updating the candidate while still in Base/LinearAlgebra (last one wins) so attribution names the user-facing API (LinearAlgebra.svd) rather than an inner helper (Base.lt) or a loader (Base.include_string). Stop at the first user/other-package frame and return that candidate, or nothing for the plain message (e.g. user Main). Check LinearAlgebra before Base — stdlibs often parent to Base.

source
cuNumeric.allowpromotion Function
julia
allowpromotion([true])
allowpromotion([true]) do
    ...
end

Use this function to allow or disallow promotion to double precision, either globally or for the duration of the do block.

See also: @allowpromotion.

source
cuNumeric.allowscalar Function
julia
allowscalar([true])
allowscalar([true]) do
    ...
end

Use this function to allow or disallow scalar indexing, either globall or for the duration of the do block.

See also: @allowscalar.

source
cuNumeric.assertpromotion Method
julia
assertpromotion(op)

Assert that a certain operation op performs promotion to a wider type. If this is not allowed, an error will be thrown (assertpromotion).

source
cuNumeric.assertscalar Method
julia
assertscalar(op::String)

Assert that a certain operation op performs scalar indexing. If this is not allowed, an error will be thrown (allowscalar).

source
cuNumeric.@allowpromotion Macro
julia
@allowpromotion() begin
    # code that can use scalar indexing
end

Denote which operations can use scalar indexing.

See also: allowpromotion.

source
cuNumeric.@allowscalar Macro
julia
@allowscalar() begin
    # code that can use scalar indexing
end

Denote which operations can use scalar indexing.

See also: allowscalar.

source
cuNumeric.get_time_microseconds Method

Returns the timestamp in microseconds. Blocks on all Legate operations preceding the call to this function.

source
cuNumeric.get_time_nanoseconds Method

Returns the timestamp in nanoseconds. Blocks on all Legate operations preceding the call to this function.

source
cuNumeric.issue_execution_fence Method
julia
issue_execution_fence(; block::Bool=false)

Insert a Legate execution fence. block=true waits until prior ops finish; block=false only inserts a DAG node (Julia can keep submitting).

source
cuNumeric.issue_mapping_fence Method
julia
issue_mapping_fence()

Insert a Legate mapping fence (DAG-only; does not block the Julia caller).

source
cuNumeric.map_cuda_type Method
julia
map_cuda_type(::Type{T})::Type

Recursively rewrite cuNumeric broadcast-related types for fused-broadcast PTX (e.g. mapping NDArray{...} to CuStridedDeviceArray{...}). Dense @cuda_task uses ndarray_cuda_type → CUDA.jl CuDeviceArray instead.

source
cuNumeric.disable_gc! Method
julia
disable_gc!()

Disables the automatic garbage collection heuristics. This gives the user full control over memory management.

source
cuNumeric.drain_pending_frees! Method
julia
drain_pending_frees!()

Destroy NDArray handles queued by finalizers. No-op off the launch thread. Called automatically from the op/allocation path, so user code rarely needs it.

source
cuNumeric.init_gc! Method
julia
init_gc!()

Initializes the cuNumeric garbage collector by querying the available device memory and enabling the automatic GC heuristics.

source
cuNumeric.insert_finalizers Method
julia
insert_finalizers(block::Expr)

Apply finalizer insertion to a begin ... end or :block expression.

source
cuNumeric.insert_finalizers Method
julia
insert_finalizers(stmts::Vector)

Insert cuNumeric.maybe_insert_delete(var) after the last use of each temporary variable.

source
cuNumeric.@accelerate Macro
julia
@accelerate function f(args...) ... end
@accelerate begin ... end
@accelerate let ... end
@accelerate expr

Optimize straight-line array code by coordinating CUDA broadcast fusion within expressions, fusion across broadcast statements, and scope-aware cleanup of materialized temporaries. Control flow and nested/anonymous functions are rejected.

Single-use producers may fuse across intervening read-only calculations when their inputs are unchanged. Unknown calls remain barriers. Function-form fusion across writes to other array arguments checks storage overlap at runtime and retains materialized intermediates when those arguments overlap.

Four forms determine which values must remain valid:

  • function (preferred): arguments and returned values are protected; non-returned locals may fuse into consumers or be freed after their last use.

  • begin: creates no new Julia scope, so every named binding stays live; eligible GPU chains may use one multi-output kernel that materializes them.

  • let: creates a local scope; only the result escapes, so other locals may fuse away or be freed after their last use.

  • expression: materializes and returns one expression; eligible operations fuse within it and transient temporaries are released.

julia
@accelerate function step(u, v)   # c may fuse away; the result is returned
    c = u .* v
    return c .^ 2
end
a, b = @accelerate begin          # a and b both stay live, one GPU launch
    a = x .* y
    b = a .+ 1
    (a, b)
end
result = @accelerate (x .+ y .* z)
source
cuNumeric.@show_lifetimes Macro
julia
@show_lifetimes function f(args...) ... end
@show_lifetimes begin ... end
@show_lifetimes let ... end

Print the exact expansion @accelerate produces for the same input (all forms), without running it; inserted frees are highlighted. Pure AST work.

source