Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .gitattributes
Original file line number Diff line number Diff line change
@@ -1,3 +1,2 @@
# Auto detect text files and perform LF normalization
* text=auto
.githash merge=ours
4 changes: 2 additions & 2 deletions benchmark/run.jl
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ function ensure_project_ready()
Pkg.PackageSpec(; path=joinpath(@__DIR__, "..", "lib", "CNPreferences")),
Pkg.PackageSpec(; path=joinpath(@__DIR__, "..")),
])
Pkg.instantiate()
return Pkg.instantiate()
end

# default env name mirrors install_cupynumeric.sh: cupynumeric-bench-<major>.<minor>
Expand All @@ -46,7 +46,7 @@ function cupynumeric_env_name()
info.version === nothing && continue
return "cupynumeric-bench-$(info.version.major).$(info.version.minor)"
end
error("could not resolve cupynumeric_jll version; set CUPYNUMERIC_ENV explicitly")
return error("could not resolve cupynumeric_jll version; set CUPYNUMERIC_ENV explicitly")
end

function dispatch(; gpus, cpus, name, T, N, M, n_iter, n_warmup, n_trial,
Expand Down
2 changes: 1 addition & 1 deletion benchmark/src/benchmarks/gemm.jl
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ dims(g::GEMM) = (g.N, g.M)
data(g::GEMM{T}) where {T} = "GEMM with T=$(T), N=$(g.N), M=$(g.M)"

function allowed_types(::Type{GEMM})
Union{cuNumeric.SUPPORTED_FLOAT_TYPES,cuNumeric.SUPPORTED_INT_TYPES}
return Union{cuNumeric.SUPPORTED_FLOAT_TYPES,cuNumeric.SUPPORTED_INT_TYPES}
end

total_flops(s::GEMM) = s.N * s.N * ((2*s.M) - 1)
Expand Down
3 changes: 2 additions & 1 deletion benchmark/src/benchmarks/grayscott.jl
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,8 @@ let body = quote
v_new[end, :] = v[2, :]
end
@eval _gs_step!(b::GrayScottBaseline, u, v, u_new, v_new, args::GSParams) = $body
@eval _gs_step!(b::GrayScottLifetimes, u, v, u_new, v_new, args::GSParams) = @analyze_lifetimes $body
@eval _gs_step!(b::GrayScottLifetimes, u, v, u_new, v_new, args::GSParams) =
@analyze_lifetimes $body
end

function run!(b::AbstractGrayScott, st::GrayScottState)
Expand Down
4 changes: 2 additions & 2 deletions benchmark/src/benchmarks/montecarlo.jl
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ end
name(::MonteCarloIntegration) = "montecarlo"
dims(mci::MonteCarloIntegration) = (mci.n_samples, 1)
function data(mci::MonteCarloIntegration{T}) where {T}
"Monte Carlo Integration with T=$(T), n_samples=$(mci.n_samples)"
return "Monte Carlo Integration with T=$(T), n_samples=$(mci.n_samples)"
end

allowed_types(::Type{MonteCarloIntegration}) = cuNumeric.SUPPORTED_FLOAT_TYPES
Expand All @@ -25,7 +25,7 @@ run!(mci::MonteCarloIntegration, x) = _domain_volume(mci) * sum(exp.(-x .^ 2))

# n_samples comes in as N; M is unused.
function build_benchmark(::Type{MonteCarloIntegration}, ::Type{T}, N, M) where {T}
MonteCarloIntegration{T}(; n_samples=N)
return MonteCarloIntegration{T}(; n_samples=N)
end

register_benchmark("montecarlo", MonteCarloIntegration)
4 changes: 2 additions & 2 deletions benchmark/src/core.jl
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,11 @@ function run! end
# registers itself via `register_benchmark`.
const BENCHMARKS = Dict{String,Type}()
function register_benchmark(key::AbstractString, ::Type{B}) where {B<:AbstractBenchmark}
BENCHMARKS[key] = B
return BENCHMARKS[key] = B
end

function build_benchmark(::Type{B}, ::Type{T}, N, M) where {B<:AbstractBenchmark,T}
B{T}(; N=N, M=M)
return B{T}(; N=N, M=M)
end

#########################################
Expand Down
2 changes: 1 addition & 1 deletion benchmark/src/parse_benchmarks.jl
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ function parse_fusion(x)
s = lowercase(string(x))
s in ("on", "true") && return true
s in ("off", "false") && return false
error("fusion must be on/off (or true/false); got $(repr(x))")
return error("fusion must be on/off (or true/false); got $(repr(x))")
end

# Value of a zipped field for sweep position `i`. length==1 field broadcasts.
Expand Down
2 changes: 1 addition & 1 deletion benchmark/src/single.jl
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ function run_single(
@printf("[%s] Mean Run Time: %.5f ± %.5f ms\n", label, mean(br.times_ms), _std(br.times_ms))
@printf("[%s] FLOPS: %.5f ± %.5f GFLOPS\n", label, mean(br.gflops), _std(br.gflops))
println("[$(label)] Correctness: $(br.correctness)")
save_result(br, gpus; mod=save_as)
return save_result(br, gpus; mod=save_as)
end

gpus = parse(Int, ARGS[1])
Expand Down
8 changes: 4 additions & 4 deletions deps/build.jl
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ function build_cpp_wrapper(
@info "libcunumeric_jl_wrapper: Building C++ Wrapper Library"
isdir(install_root) && (rm(install_root; recursive=true); mkdir(install_root))
bld_command = `$(joinpath(repo_root, "scripts/build_cpp_wrapper.sh")) $repo_root $cupynumeric_loc $legate_loc $blas_loc $install_root $(Threads.nthreads())`
BuildTools.run_build_wrapper_script(
return BuildTools.run_build_wrapper_script(
repo_root, bld_command; cuda_root, cuda_enabled, log_dir=@__DIR__
)
end
Expand All @@ -64,7 +64,7 @@ function build_deps(pkg_root, cupynumeric_root, blas_root; cuda_root=nothing, cu
install_lib;
cuda_root, cuda_enabled,
)
BuildTools.set_jll_artifact_override(:cunumeric_jl_wrapper_jll, install_lib)
return BuildTools.set_jll_artifact_override(:cunumeric_jl_wrapper_jll, install_lib)
end

function build(::CNPreferences.JLL)
Expand All @@ -90,7 +90,7 @@ function build(::CNPreferences.Conda)
#!TODO SET LocalPreferences.toml to use local CUDA libraries

is_cupynumeric_installed(cupynumeric_root; throw_errors=true)
build_deps(pkg_root, cupynumeric_root, cupynumeric_root)
return build_deps(pkg_root, cupynumeric_root, cupynumeric_root)
end

function build(::CNPreferences.Developer)
Expand All @@ -110,7 +110,7 @@ function build(::CNPreferences.Developer)
end

blas_lib = something(blas_lib, BuildTools.find_jll_artifact_dir(:OpenBLAS32_jll))
build_deps(pkg_root, cupynumeric_root, up_dir(blas_lib); cuda_root, cuda_enabled)
return build_deps(pkg_root, cupynumeric_root, up_dir(blas_lib); cuda_root, cuda_enabled)
end

const mode_str = load_preference(CNPreferences, "cunumeric_mode", CNPreferences.MODE_JLL)
Expand Down
1 change: 0 additions & 1 deletion docs/make.jl
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@ makedocs(;
"Initialization" => "examples/initialization.md",
"Monte-Carlo" => "examples/montecarlo.md",
"Gray-Scott" => "examples/grayscott.md",
"HDF5 I/O" => "examples/hdf5.md",
],
"Performance Tips" => [
"Kernel Fusion" => "perf/kernel_fusion.md",
Expand Down
52 changes: 37 additions & 15 deletions docs/src/api_hdf5.md
Original file line number Diff line number Diff line change
@@ -1,29 +1,51 @@
# HDF5

> [!NOTE]
> HDF5 support is planned. Signatures below are placeholders and will be replaced with `@docs` blocks when the API is implemented.
`h5read` and `h5write` transfer datasets between HDF5 files and runtime-managed
`NDArray`s without gathering them into Julia `Array`s.

I/O helpers for reading and writing `NDArray`s via HDF5. Prefer these over host-side gather + HDF5.jl when arrays are large or distributed.

## h5read
## Example

```julia
# Planned:
# cuNumeric.h5read(path, dataset) -> NDArray
using cuNumeric

field = cuNumeric.fill(3.5f0, 128, 64)
cuNumeric.h5write("checkpoint.h5", "field", field)
cuNumeric.Legate.runtime_sync()

restored = cuNumeric.h5read("checkpoint.h5", "field"; layout=:row)
@assert size(restored) == (128, 64)
@assert eltype(restored) == Float32
@assert cuNumeric.compare(fill(3.5f0, 128, 64), restored, 0, 0)
```

Load a dataset from an HDF5 file into an `NDArray`.
`h5write` submits work to Legate and can return before the file write has completed.
Synchronize before accessing the file outside the runtime, moving or deleting it, or
exiting immediately after the write.

## h5write
## Dataset layout

```julia
# Planned:
# cuNumeric.h5write(path, dataset, arr::NDArray)
row_major = cuNumeric.h5read("python.h5", "field")
column_major = cuNumeric.h5read("julia.h5", "field"; layout=:col)
```

Write an `NDArray` to an HDF5 dataset.
`layout=:row` is the default for NumPy/h5py, cuPyNumeric, and `cuNumeric.h5write`.
Use `layout=:col` for multidimensional datasets written by HDF5.jl. One-dimensional
datasets are unaffected. Other keywords are forwarded to `Legate.h5read`.

Tests cover `Float32`, `Float64`, `Int32`, and `Int64` arrays with one to three
dimensions. Other types depend on the Legate HDF5 backend.

## API reference

## Related
### h5read

- Example sketch: [HDF5 I/O](./examples/hdf5.md)
- Host conversion when you must leave the runtime: `Array(arr)` (see [NDArray Reference](./api.md))
```@docs
cuNumeric.h5read
```

### h5write

```@docs
cuNumeric.h5write
```
22 changes: 0 additions & 22 deletions docs/src/examples/hdf5.md

This file was deleted.

2 changes: 1 addition & 1 deletion src/cuda/cuda_util.jl
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ end
# Dense @cuda_task / RunPTXTask — MUST match CUDA.jl CuDeviceArray layout.
# Other memory types: https://github.com/JuliaGPU/CUDA.jl/blob/345c1600ebd561135148bb04ee2657f521a40e25/CUDACore/src/device/pointer.jl#L7
function ndarray_cuda_type(::Type{<:NDArray{T,N}}) where {T,N}
CUDACore.CuDeviceArray{T,N,CUDACore.AS.Global}
return CUDACore.CuDeviceArray{T,N,CUDACore.AS.Global}
end

function ndarray_cuda_type(::Type{T}) where {T}
Expand Down
11 changes: 6 additions & 5 deletions src/cuda/strided_device_array.jl
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,12 @@ Base.length(a::CuStridedDeviceArray) = a.len
Base.IndexStyle(::Type{<:CuStridedDeviceArray}) = IndexLinear()

function Base.pointer(a::CuStridedDeviceArray{T,<:Any,A}) where {T,A}
Base.unsafe_convert(CUDACore.LLVMPtr{T,A}, a)
return Base.unsafe_convert(CUDACore.LLVMPtr{T,A}, a)
end
function Base.unsafe_convert(
::Type{CUDACore.LLVMPtr{T,A}}, a::CuStridedDeviceArray{T,<:Any,A}
) where {T,A}
a.ptr
return a.ptr
end

# 0-based element offset from a 1-based linear index in Julia column-major order
Expand Down Expand Up @@ -90,9 +90,10 @@ CUDACore.@device_function @inline function _strided_arrayset(
return A
end

Base.@propagate_inbounds Base.getindex(A::CuStridedDeviceArray{T}, i::Integer) where {T} = _strided_arrayref(
A, i
)
Base.@propagate_inbounds Base.getindex(A::CuStridedDeviceArray{T}, i::Integer) where {T} =
_strided_arrayref(
A, i
)
Base.@propagate_inbounds function Base.setindex!(
A::CuStridedDeviceArray{T}, x, i::Integer
) where {T}
Expand Down
2 changes: 1 addition & 1 deletion src/memory.jl
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ function init_gc!()
total_device_bytes[] = query_total_device_memory()
total_host_bytes[] = query_total_host_memory()
# @info "[cuNumeric GC] $(total_device_bytes[]) framebuffer available"
AUTO_GC_ENABLE[] = true
return AUTO_GC_ENABLE[] = true
end

@doc"""
Expand Down
3 changes: 1 addition & 2 deletions src/ndarray/detail/ndarray.jl
Original file line number Diff line number Diff line change
Expand Up @@ -419,8 +419,7 @@ end
# return underlying logical store to the NDArray obj
function get_store(arr::NDArray)
cxx_ptr = CxxWrap.CxxPtr{CN_NDArray}(arr.ptr)
store = _get_store(cxx_ptr)
return store
return _get_store(cxx_ptr)
end

function get_ptr(arr::NDArray{T,N}) where {T,N}
Expand Down
Loading
Loading