From f98395725eeba95c3ef521a0907891f21b5b0a78 Mon Sep 17 00:00:00 2001 From: krasow Date: Mon, 2 Feb 2026 18:18:11 -0600 Subject: [PATCH 01/16] using some of the new legate api --- deps/build.jl | 157 ++++++++---------- deps/version.jl | 64 +++++++ ext/CUDAExt/cuda.jl | 27 +-- lib/CNPreferences/src/CNPreferences.jl | 2 + lib/cunumeric_jl_wrapper/VERSION | 2 +- .../include/ndarray_c_api.h | 3 + lib/cunumeric_jl_wrapper/src/ndarray.cpp | 15 +- lib/cunumeric_jl_wrapper/src/wrapper.cpp | 37 +---- src/ndarray/detail/ndarray.jl | 28 ++-- src/utilities/preference.jl | 84 ++++------ 10 files changed, 199 insertions(+), 220 deletions(-) create mode 100644 deps/version.jl diff --git a/deps/build.jl b/deps/build.jl index 431f4565..43ab7c7f 100644 --- a/deps/build.jl +++ b/deps/build.jl @@ -19,10 +19,9 @@ using Preferences using Legate -using CNPreferences: CNPreferences +using CNPreferences -const SUPPORTED_CUPYNUMERIC_VERSIONS = ["25.10.00", "25.11.00"] -const LATEST_CUPYNUMERIC_VERSION = SUPPORTED_CUPYNUMERIC_VERSIONS[end] +include("version.jl") up_dir(dir::String) = abspath(joinpath(dir, "..")) @@ -45,7 +44,7 @@ function run_sh(cmd::Cmd, filename::String) try run(pipeline(cmd; stdout=tmp_build_log, stderr=err_log, append=false)) - println(contents) + println(contents) # Note: keeping this bug to match Legate.jl structure as requested, though it looks wrong (contents undefined before read). contents = read(tmp_build_log, String) open(build_log, "a") do io println(contents) @@ -61,42 +60,13 @@ function run_sh(cmd::Cmd, filename::String) end end -function get_version(version_file) - version = nothing - open(version_file, "r") do f - data = readlines(f) - major = parse(Int, split(data[end - 2])[end]) - minor = lpad(split(data[end - 1])[end], 2, '0') - patch = lpad(split(data[end])[end], 2, '0') - version = "$(major).$(minor).$(patch)" - end - if isnothing(version) - error("cuNumeric.jl: Failed to parse version for $(version_file)") - end - return version -end - -function get_cupynumeric_version(cupynumeric_root) - version_file = joinpath(cupynumeric_root, "include", "cupynumeric", "version_config.hpp") - return get_version(version_file) -end - -function cupynumeric_valid(cupynumeric_root::String) - # todo check if cupynumeric_root matches the version that we are installing. - version_cupynumeric = get_cupynumeric_version(cupynumeric_root) - return version_cupynumeric ∈ SUPPORTED_CUPYNUMERIC_VERSIONS # return true if equal -end - -function build_jlcxxwrap(repo_root) - @info "libcxxwrap: Downloading" +function build_jlcxxwrap(repo_root, cupynumeric_root) build_libcxxwrap = joinpath(repo_root, "scripts/install_cxxwrap.sh") - - # this is actually correct even for cunumeric. version_path = joinpath(DEPOT_PATH[1], "dev/libcxxwrap_julia_jll/override/LEGATE_INSTALL.txt") - if isfile(version_path) - version = strip(read(version_path, String)) - if version ∈ SUPPORTED_CUPYNUMERIC_VERSIONS + version = VersionNumber(strip(read(version_path, String))) + @info "libcxxwrap: Found Legate $version" + if is_supported_version(version) @info "libcxxwrap: Found supported version built with Legate.jl: $version" return nothing else @@ -109,7 +79,7 @@ function build_jlcxxwrap(repo_root) @info "libcxxwrap: Running build script: $build_libcxxwrap" run_sh(`bash $build_libcxxwrap $repo_root`, "libcxxwrap") open(version_path, "w") do io - write(io, LATEST_CUPYNUMERIC_VERSION) + write(io, string(get_cupynumeric_version(legate_root))) end end @@ -118,7 +88,6 @@ function build_cpp_wrapper( ) @info "libcunumeric_jl_wrapper: Building C++ Wrapper Library" if isdir(install_root) - @warn "libcunumeric_jl_wrapper: Build dir exists. Deleting prior build." rm(install_root; recursive=true) mkdir(install_root) end @@ -142,34 +111,15 @@ function build_cpp_wrapper( run_sh(`bash $bld_command`, "cpp_wrapper") end -function replace_nothing_jll(lib, jll) - if isnothing(lib) - eval(:(using $(jll))) - jll_mod = getfield(Main, jll) - lib = joinpath(jll_mod.artifact_dir, "lib") - end - return lib +function _find_jll_artifact_dir(jll) + eval(:(using $(jll))) + jll_mod = getfield(Main, jll) + root = jll_mod.artifact_dir + return root end -function replace_nothing_conda_jll(mode, lib, jll) - if isnothing(lib) - if mode == CNPreferences.MODE_CONDA - lib = joinpath(load_preference(CNPreferences, "cunumeric_conda_env", nothing), "lib") - else - eval(:(using $(jll))) - jll_mod = getfield(Main, jll) - lib = joinpath(jll_mod.artifact_dir, "lib") - end - end - return lib -end - -function build(mode) - if mode == CNPreferences.MODE_JLL - @warn "No reason to Build on JLL mode. Exiting Build" - return nothing - end - pkg_root = abspath(joinpath(@__DIR__, "../")) +function _start_build() + pkg_root = up_dir(@__DIR__) deps_dir = joinpath(@__DIR__) build_log = joinpath(deps_dir, "build.log") @@ -178,30 +128,67 @@ function build(mode) end @info "cuNumeric.jl: Parsed Package Dir as: $(pkg_root)" + return pkg_root +end +""" + build CxxWrap and cunumeric_jl_wrapper +""" +function build_deps(pkg_root, cupynumeric_root, blas_root) legate_lib = Legate.get_install_liblegate() - cupynumeric_lib = load_preference(CNPreferences, "CUPYNUMERIC_LIB", nothing) + install_lib = joinpath(pkg_root, "lib", "cunumeric_jl_wrapper", "build") + if !cupynumeric_valid(cupynumeric_root) + error( + "cuNumeric.jl: Unsupported cuNumeric version at $(cupynumeric_root). " * + "Installed version: $(installed_version) not in range supported: " * + "$(MIN_CUNUMERIC_VERSION)-$(MAX_CUNUMERIC_VERSION).", + ) + end + build_jlcxxwrap(pkg_root, cupynumeric_root) + build_cpp_wrapper( + pkg_root, cupynumeric_root, up_dir(legate_lib), blas_root, + install_lib, + ) # $pkg_root/lib/cunumeric_jl_wrapper +end + +function build(::CNPreferences.JLL) + @warn "No reason to Build on JLL mode. Exiting Build" + return nothing +end + +function build(::CNPreferences.Conda) + @warn "Conda Build does not currently pass our CI. Proceed with caution." + pkg_root = _start_build() + + cupynumeric_root = load_preference(CNPreferences, "cunumeric_conda_env", nothing) + if isnothing(cupynumeric_root) + error("This shouldn't happen. cunumeric_conda_env = nothing?") + end + + is_cupynumeric_installed(cupynumeric_root; throw_errors=true) + build_deps(pkg_root, cupynumeric_root, cupynumeric_root) # blas is same root as cupynumeric +end + +function build(::CNPreferences.Developer) + pkg_root = _start_build() + + # can be nothing so this errors if not set + cupynumeric_root = load_preference(CNPreferences, "cunumeric_path", nothing) blas_lib = load_preference(CNPreferences, "BLAS_LIB", nothing) + if isnothing(cupynumeric_root) + # we are using legate_jll for legate + cupynumeric_root = _find_jll_artifact_dir(:cupynumeric_jll) + else + # this means we have a custom path set + is_cupynumeric_installed(cupynumeric_root; throw_errors=true) + end - cupynumeric_lib = replace_nothing_conda_jll(mode, cupynumeric_lib, :cupynumeric_jll) - blas_lib = replace_nothing_jll(blas_lib, :OpenBLAS32_jll) - - if mode == CNPreferences.MODE_DEVELOPER - install_lib = joinpath(pkg_root, "lib", "cunumeric_jl_wrapper", "build") - build_jlcxxwrap(pkg_root) - cupynumeric_root = up_dir(cupynumeric_lib) - if !cupynumeric_valid(cupynumeric_root) - error( - "cuNumeric.jl: cupynumeric library at $(cupynumeric_root) is not a supported version. - Supported versions are: $(SUPPORTED_CUPYNUMERIC_VERSIONS).", - ) - end - build_cpp_wrapper( - pkg_root, cupynumeric_root, up_dir(legate_lib), up_dir(blas_lib), - install_lib, - ) + if isnothing(blas_lib) + blas_lib = _find_jll_artifact_dir(:OpenBLAS32_jll) end + + build_deps(pkg_root, cupynumeric_root, up_dir(blas_lib)) end -const mode = load_preference(CNPreferences, "cunumeric_mode", CNPreferences.MODE_JLL) -build(mode) +const mode_str = load_preference(CNPreferences, "cunumeric_mode", CNPreferences.MODE_JLL) +build(CNPreferences.to_mode(mode_str)) diff --git a/deps/version.jl b/deps/version.jl new file mode 100644 index 00000000..69232595 --- /dev/null +++ b/deps/version.jl @@ -0,0 +1,64 @@ +#= Copyright 2026 Northwestern University, + * Carnegie Mellon University University + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Author(s): David Krasowska + * Ethan Meitz +=# + +const MIN_CUDA_VERSION = v"13.0" +const MAX_CUDA_VERSION = v"13.9.999" +const MIN_CUNUMERIC_VERSION = v"25.10.00" +const MAX_CUNUMERIC_VERSION = v"26.01.00" + +up_dir(dir::String) = abspath(joinpath(dir, "..")) + +function get_version(version_file::String) + version = nothing + open(version_file, "r") do f + data = readlines(f) + major = parse(Int, split(data[end - 2])[end]) + minor = parse(Int, lpad(split(data[end - 1])[end], 2, '0')) + patch = parse(Int, lpad(split(data[end])[end], 2, '0')) + version = VersionNumber(major, minor, patch) + end + if isnothing(version) + error("cuNumeric.jl: Failed to parse version for $(version_file)") + end + return version +end + +function get_cupynumeric_version(cupynumeric_root::String) + version_file = joinpath(cupynumeric_root, "include", "cupynumeric", "version_config.hpp") + return get_version(version_file) +end + +function is_supported_version(version::VersionNumber) + return MIN_CUNUMERIC_VERSION <= version && version <= MAX_CUNUMERIC_VERSION +end + +function cupynumeric_valid(cupynumeric_root::String) + version_cupynumeric = get_cupynumeric_version(cupynumeric_root) + return is_supported_version(version_cupynumeric) +end + +function is_cupynumeric_installed(cupynumeric::String; throw_errors::Bool=false) + include_dir = joinpath(cupynumeric, "include") + if !isdir(joinpath(include_dir, "cupynumeric/cupynumeric")) + throw_errors && + @error "cuNumeric.jl: Cannot find include/cupynumeric/cupynumeric in $(cupynumeric_root)" + return false + end + return true +end diff --git a/ext/CUDAExt/cuda.jl b/ext/CUDAExt/cuda.jl index ddc1d9ab..a70a5b90 100644 --- a/ext/CUDAExt/cuda.jl +++ b/ext/CUDAExt/cuda.jl @@ -1,7 +1,3 @@ - -# ndarray_cuda_type(::NDArray{T,2}) where {T} = CuDeviceMatrix{T,1} -# ndarray_cuda_type(::NDArray{T,N}) where {T,N} = CuDeviceArray{T,N,1} - function ndarray_cuda_type(A::NDArray{T,N}) where {T,N} if N == 1 CuDeviceVector{T,1} @@ -78,27 +74,6 @@ function check_sz(arr, maxshape) end end -# allignment contrainsts are transitive. -# we can allign all the inputs and then alligns all the outputs -# then allign one input with one output -# This reduces the need for a cartesian product. -function add_default_alignment( - task::Legate.AutoTask, inputs::Vector{Legate.Variable}, outputs::Vector{Legate.Variable} -) - # Align all inputs to the first input - for i in 2:length(inputs) - Legate.add_constraint(task, Legate.align(inputs[i], inputs[1])) - end - # Align all outputs to the first output - for i in 2:length(outputs) - Legate.add_constraint(task, Legate.align(outputs[i], outputs[1])) - end - # Align first output with first input - if !isempty(inputs) && !isempty(outputs) - Legate.add_constraint(task, Legate.align(outputs[1], inputs[1])) - end -end - function Launch(kernel::cuNumeric.CUDATask, inputs::Tuple{Vararg{NDArray}}, outputs::Tuple{Vararg{NDArray}}, scalars::Tuple{Vararg{Any}}; blocks, threads) @@ -141,7 +116,7 @@ function Launch(kernel::cuNumeric.CUDATask, inputs::Tuple{Vararg{NDArray}}, end # all inputs are alligned with all outputs - add_default_alignment(task, input_vars, output_vars) + Legate.add_default_alignment(task, input_vars, output_vars) Legate.submit_auto_task(rt, task) end diff --git a/lib/CNPreferences/src/CNPreferences.jl b/lib/CNPreferences/src/CNPreferences.jl index 59a363a7..60138ed6 100644 --- a/lib/CNPreferences/src/CNPreferences.jl +++ b/lib/CNPreferences/src/CNPreferences.jl @@ -2,6 +2,8 @@ module CNPreferences using Preferences using LegatePreferences +const DEVEL_DEFAULT_WRAPPER_BRANCH = "main" + LegatePreferences.@make_preferences("cunumeric_") end # module CNPreferences diff --git a/lib/cunumeric_jl_wrapper/VERSION b/lib/cunumeric_jl_wrapper/VERSION index 1bec6159..3252f073 100644 --- a/lib/cunumeric_jl_wrapper/VERSION +++ b/lib/cunumeric_jl_wrapper/VERSION @@ -1 +1 @@ -25.10.2 \ No newline at end of file +25.10.3 \ No newline at end of file diff --git a/lib/cunumeric_jl_wrapper/include/ndarray_c_api.h b/lib/cunumeric_jl_wrapper/include/ndarray_c_api.h index b51825a7..90f86c72 100644 --- a/lib/cunumeric_jl_wrapper/include/ndarray_c_api.h +++ b/lib/cunumeric_jl_wrapper/include/ndarray_c_api.h @@ -20,6 +20,9 @@ typedef struct { typedef struct CN_NDArray CN_NDArray; typedef struct CN_Type CN_Type; typedef struct CN_Scalar CN_Scalar; +typedef struct CN_Store CN_Store; + +CN_NDArray* nda_store_to_ndarray(CN_Store* st); uint64_t nda_query_device_memory(); diff --git a/lib/cunumeric_jl_wrapper/src/ndarray.cpp b/lib/cunumeric_jl_wrapper/src/ndarray.cpp index fcd35dd7..4659cc14 100644 --- a/lib/cunumeric_jl_wrapper/src/ndarray.cpp +++ b/lib/cunumeric_jl_wrapper/src/ndarray.cpp @@ -251,18 +251,7 @@ CN_NDArray* nda_get_slice(CN_NDArray* arr, const CN_Slice* slices, return new CN_NDArray{NDArray(std::move(result))}; } -CN_NDArray* nda_attach_external(const void* ptr, size_t size, int dim, - const uint64_t* shape, CN_Type type) { - std::vector shp_vec(shape, shape + dim); - legate::Shape shp = legate::Shape(shp_vec); - - legate::ExternalAllocation alloc = - legate::ExternalAllocation::create_sysmem(ptr, size); - legate::mapping::DimOrdering ordering = - legate::mapping::DimOrdering::fortran_order(); - - auto store = legate::Runtime::get_runtime()->create_store(shp, type.obj, - alloc, ordering); - return new CN_NDArray{cupynumeric::as_array(store)}; +CN_NDArray* nda_store_to_ndarray(CN_Store* st) { + return new CN_NDArray{cupynumeric::as_array(st->obj)}; } } // extern "C" diff --git a/lib/cunumeric_jl_wrapper/src/wrapper.cpp b/lib/cunumeric_jl_wrapper/src/wrapper.cpp index 39ac459e..0d54b598 100644 --- a/lib/cunumeric_jl_wrapper/src/wrapper.cpp +++ b/lib/cunumeric_jl_wrapper/src/wrapper.cpp @@ -47,35 +47,16 @@ legate::LogicalArray* get_store(CN_NDArray* arr) { return new legate::LogicalArray(std::move(res)); } -struct GetPtrFunctor { - template - void* operator()(legate::LogicalArray* arr) { -#ifndef HAVE_CUDA - // Check if FLOAT16 is being used without CUDA support - if (CODE == legate::Type::Code::FLOAT16) { - throw std::runtime_error( - "FLOAT16 type is not supported when building without CUDA"); - } -#endif - using CppT = typename legate_util::code_to_cxx::type; - auto rf = arr->get_physical_array(); - auto shp = rf.shape(); - return rf.data().write_accessor().ptr(Realm::Point(shp.lo)); - } -}; - -inline void* get_ptr(legate::LogicalArray* arr) { - int dim = arr->dim(); - legate::Type::Code code = arr->type().code(); - return legate::double_dispatch(dim, code, GetPtrFunctor{}, arr); -} - legate::Library get_lib() { auto runtime = cupynumeric::CuPyNumericRuntime::get_runtime(); return runtime->get_library(); } -#ifdef HAVE_CUDA +void* nda_store_to_ndarray(legate::LogicalStore st) { + return static_cast(new CN_NDArray{cupynumeric::as_array(st)}); +} + +#if LEGATE_DEFINED(LEGATE_USE_CUDA) void register_tasks() { auto library = get_lib(); ufi::LoadPTXTask::register_variants(library); @@ -109,11 +90,8 @@ JLCXX_MODULE define_julia_module(jlcxx::Module& mod) { mod.add_type("CN_NDArray"); mod.method("_get_store", &get_store); - mod.method("_get_ptr", &get_ptr); mod.method("get_lib", &get_lib); -#ifdef HAVE_CUDA - mod.method("register_tasks", ®ister_tasks); -#endif + mod.method("nda_store_to_ndarray", &nda_store_to_ndarray); auto ndarray_accessor = mod.add_type, TypeVar<2>>>("NDArrayAccessor"); @@ -127,7 +105,8 @@ JLCXX_MODULE define_julia_module(jlcxx::Module& mod) { v.push_back(std::make_shared(x)); }); -#ifdef HAVE_CUDA +#if LEGATE_DEFINED(LEGATE_USE_CUDA) + mod.method("register_tasks", ®ister_tasks); wrap_cuda_methods(mod); #endif } diff --git a/src/ndarray/detail/ndarray.jl b/src/ndarray/detail/ndarray.jl index 5ecc10ea..0acd9ce1 100644 --- a/src/ndarray/detail/ndarray.jl +++ b/src/ndarray/detail/ndarray.jl @@ -10,6 +10,7 @@ end # Opaque pointer const NDArray_t = Ptr{Cvoid} +const CN_Store_t = Ptr{Cvoid} # destroy nda_destroy_array(ptr::NDArray_t) = ccall((:nda_destroy_array, libnda), @@ -308,28 +309,27 @@ function nda_transpose(arr::NDArray) end function nda_attach_external(arr::AbstractArray{T,N}) where {T,N} - ptr = Base.unsafe_convert(Ptr{Cvoid}, arr) - nbytes = sizeof(T) * length(arr) - shape = collect(UInt64, size(arr)) - legate_type = Legate.to_legate_type(T) - - nda_ptr = ccall((:nda_attach_external, libnda), - NDArray_t, (Ptr{Cvoid}, UInt64, Int32, Ptr{UInt64}, Legate.LegateTypeAllocated), - ptr, nbytes, N, shape, legate_type) - + st = Legate.attach_external(arr) + # Use the CxxWrap method for type-safe interaction + # This returns a raw pointer compatible with the NDArray constructor + nda_ptr = cuNumeric.nda_store_to_ndarray(st.handle) return NDArray(nda_ptr; T=T, n_dim=N) end # return underlying logical store to the NDArray obj function get_store(arr::NDArray) - cxx_ptr = CxxWrap.CxxPtr{cuNumeric.CN_NDArray}(arr.ptr) + cxx_ptr = CxxWrap.CxxPtr{CN_NDArray}(arr.ptr) store = _get_store(cxx_ptr) - return CxxWrap.CxxRef(store) + return store end -function get_ptr(arr::NDArray) - st = get_store(arr) - return _get_ptr(CxxWrap.CxxPtr(st)) +function get_ptr(arr::NDArray{T,N}) where {T,N} + # Get the raw Legate array impl + st_handle = get_store(arr) # CxxPtr{LogicalArrayImpl} + # Wrap it in the high-level LogicalArray struct expected by Legate.get_ptr + # st_handle[] dereferences the CxxPtr to get the LogicalArrayImpl object + la = Legate.LogicalArray{T,N}(st_handle[], size(arr)) + return Legate.get_ptr(la) end @doc""" diff --git a/src/utilities/preference.jl b/src/utilities/preference.jl index 212c0c48..08010462 100644 --- a/src/utilities/preference.jl +++ b/src/utilities/preference.jl @@ -1,56 +1,36 @@ -function is_cupynumeric_installed(cupynumeric_root::String; throw_errors::Bool=false) - include_dir = joinpath(cupynumeric_root, "include") - if !isdir(joinpath(include_dir, "cupynumeric")) - throw_errors && - @error "cuNumeric.jl: Cannot find include/cupynumeric in $(cupynumeric_root)" - return false - end - return true -end - -function parse_cupynumeric_version(cupynumeric_root) - version_file = joinpath(cupynumeric_root, "include", "cupynumeric", "version_config.hpp") - version = nothing - open(version_file, "r") do f - data = readlines(f) - major = parse(Int, split(data[end - 2])[end]) - minor = lpad(split(data[end - 1])[end], 2, '0') - patch = lpad(split(data[end])[end], 2, '0') - version = "$(major).$(minor).$(patch)" - end - - if isnothing(version) - error("cuNumeric.jl: Failed to parse version from conda environment") - end - - return version -end +#= Copyright 2026 Northwestern University, + * Carnegie Mellon University University + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Author(s): David Krasowska + * Ethan Meitz +=# function check_cupynumeric_install(cupynumeric_root) - cupynumeric_installed = is_cupynumeric_installed(cupynumeric_root) - if !cupynumeric_installed - error("cuNumeric.jl: Build halted: cupynumeric not found in $cupynumeric_root") - end - installed_version = parse_cupynumeric_version(cupynumeric_root) - if installed_version ∉ SUPPORTED_CUPYNUMERIC_VERSIONS + is_legate_installed(cupynumeric_root; throw_errors=true) + if !legate_valid(cupynumeric_root) error( - "cuNumeric.jl: Build halted: $(cupynumeric_root) detected unsupported version $(installed_version)" + "cuNumeric.jl: Unsupported cuNumeric version at $(cupynumeric_root). " * + "Installed version: $(get_cupynumeric_version(cupynumeric_root)) not in range supported: " * + "$(MIN_CUNUMERIC_VERSION)-$(MAX_CUNUMERIC_VERSION).", ) end + @info "cuNumeric.jl: Found a valid install in: $(cupynumeric_root)" return true end -function get_library_root(jll_module, env_var::String) - if haskey(ENV, env_var) - return get(ENV, env_var, "0") - elseif jll_module.is_available() - return joinpath(jll_module.artifact_dir, "lib") - else - error("$env_var not found via environment or JLL.") - end -end - ############################################# # LOTS OF THIS LOGIC EXISTS IN LEGATE.JL TOO # DEFINITELY DUPLICATED CODE @@ -62,7 +42,7 @@ function check_jll(m::Module) if (m_host_cuda == "none") error( - "$(string(m)) installed but not available on this platform.\n $(string(cupynumeric_jll.host_platform))", + "$(string(m)) installed but not available on this platform.\n $(string(cupynumeric_jll.host_platform))" ) end @@ -70,7 +50,7 @@ function check_jll(m::Module) valid_cuda_version = Legate.MIN_CUDA_VERSION <= v_host_cuda <= Legate.MAX_CUDA_VERSION if !valid_cuda_version error( - "$(string(m)) installed but not available on this platform. Host CUDA ver: $(v_host_cuda) not in range supported by $(string(m)): $(MIN_CUDA_VERSION)-$(MAX_CUDA_VERSION).", + "$(string(m)) installed but not available on this platform. Host CUDA ver: $(v_host_cuda) not in range supported by $(string(m)): $(MIN_CUDA_VERSION)-$(MAX_CUDA_VERSION)." ) else error("$(string(m)) installed but not available on this platform. Unknown reason.") @@ -99,9 +79,9 @@ function _find_paths( ) check_jll(cupynumeric_jll_module) check_jll(cupynumeric_jll_wrapper_module) - legate_lib_dir = joinpath(cupynumeric_jll_module.artifact_dir, "lib") - legate_wrapper_libdir = joinpath(cupynumeric_jll_wrapper_module.artifact_dir, "lib") - return legate_lib_dir, legate_wrapper_libdir + cupynumeric_lib = joinpath(cupynumeric_jll_module.artifact_dir, "lib") + wrapper_lib = joinpath(cupynumeric_jll_wrapper_module.artifact_dir, "lib") + return cupynumeric_lib, wrapper_lib end function _find_paths( @@ -120,7 +100,7 @@ function _find_paths( cupynumeric_path = cupynumeric_jll.artifact_dir end - pkg_root = abspath(joinpath(@__DIR__, "../", "../")) + pkg_root = abspath(joinpath(@__DIR__, "../../")) wrapper_lib = joinpath(pkg_root, "lib", "cunumeric_jl_wrapper", "build", "lib") return joinpath(cupynumeric_path, "lib"), wrapper_lib @@ -133,12 +113,12 @@ function _find_paths( ) @warn "mode = conda may break. We are using a subset of libraries from conda." - conda_env = load_preference(CNPreferences, "legate_conda_env", nothing) + conda_env = load_preference(CNPreferences, "cunumeric_conda_path", nothing) isnothing(conda_env) && error( "legate_conda_env preference must be set in LocalPreferences.toml when using conda mode" ) - check_legate_install(conda_env) + check_cupynumeric_install(conda_env) legate_path = conda_env check_jll(cupynumeric_jll_wrapper_module) legate_wrapper_lib = joinpath(cupynumeric_jll_wrapper_module.artifact_dir, "lib") From 2e660e8b0a1a865e8039da5a567a53dbfb99e634 Mon Sep 17 00:00:00 2001 From: krasow Date: Mon, 2 Feb 2026 18:21:38 -0600 Subject: [PATCH 02/16] version.jl include --- .githash | 2 +- src/cuNumeric.jl | 10 +++------- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/.githash b/.githash index b3b87b3a..67780c7c 100644 --- a/.githash +++ b/.githash @@ -1 +1 @@ -321fb12e0f01f8fb792cb0a49ff877bb6502ad7d +f98395725eeba95c3ef521a0907891f21b5b0a78 diff --git a/src/cuNumeric.jl b/src/cuNumeric.jl index 7be59303..fbdd914f 100644 --- a/src/cuNumeric.jl +++ b/src/cuNumeric.jl @@ -19,6 +19,7 @@ module cuNumeric +include(joinpath(@__DIR__, "../deps/version.jl")) include("utilities/depends.jl") const HAS_CUDA = cupynumeric_jll.host_platform["cuda"] != "none" @@ -27,8 +28,6 @@ if !HAS_CUDA @warn "cuPyNumeric JLL does not have CUDA. If you have an NVIDIA GPU something might be wrong." end -const SUPPORTED_CUPYNUMERIC_VERSIONS = ["25.10.00", "25.11.00"] - const DEFAULT_FLOAT = Float32 const DEFAULT_INT = Int32 @@ -169,16 +168,14 @@ end const RUNTIME_INACTIVE = -1 const RUNTIME_ACTIVE = 0 const _runtime_ref = Ref{Int}(RUNTIME_INACTIVE) -const _start_lock = ReentrantLock() +const _start_lock = ReentrantLock() runtime_started() = _runtime_ref[] == RUNTIME_ACTIVE function _start_runtime() - Libdl.dlopen(CUPYNUMERIC_LIB_PATH, Libdl.RTLD_GLOBAL | Libdl.RTLD_NOW) Libdl.dlopen(CUPYNUMERIC_WRAPPER_LIB_PATH, Libdl.RTLD_GLOBAL | Libdl.RTLD_NOW) - AA = ArgcArgv(String[]) # AA = ArgcArgv([Base.julia_cmd()[1]]) cuNumeric.initialize_cunumeric(AA.argc, getargv(AA)) @@ -188,7 +185,6 @@ function _start_runtime() Base.atexit(my_on_exit) - return RUNTIME_ACTIVE end @@ -223,7 +219,7 @@ function __init__() global cuNumeric_config_str = version_config_setup() - _is_precompiling() && return + _is_precompiling() && return nothing ensure_runtime!() end From 5db897644303d37009ff929fbc5104ef2e6693ab Mon Sep 17 00:00:00 2001 From: krasow Date: Mon, 2 Feb 2026 18:24:05 -0600 Subject: [PATCH 03/16] build.jl patch --- .githash | 2 +- deps/build.jl | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/.githash b/.githash index 67780c7c..8864daf9 100644 --- a/.githash +++ b/.githash @@ -1 +1 @@ -f98395725eeba95c3ef521a0907891f21b5b0a78 +2e660e8b0a1a865e8039da5a567a53dbfb99e634 diff --git a/deps/build.jl b/deps/build.jl index 43ab7c7f..42d59585 100644 --- a/deps/build.jl +++ b/deps/build.jl @@ -44,7 +44,6 @@ function run_sh(cmd::Cmd, filename::String) try run(pipeline(cmd; stdout=tmp_build_log, stderr=err_log, append=false)) - println(contents) # Note: keeping this bug to match Legate.jl structure as requested, though it looks wrong (contents undefined before read). contents = read(tmp_build_log, String) open(build_log, "a") do io println(contents) From ae7fafc9193040e74018445faf88598dab24c4d8 Mon Sep 17 00:00:00 2001 From: krasow Date: Tue, 3 Feb 2026 13:12:13 -0600 Subject: [PATCH 04/16] update paths/comments in build.jl --- .githash | 2 +- deps/build.jl | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.githash b/.githash index 8864daf9..bfc11eaa 100644 --- a/.githash +++ b/.githash @@ -1 +1 @@ -2e660e8b0a1a865e8039da5a567a53dbfb99e634 +5db897644303d37009ff929fbc5104ef2e6693ab diff --git a/deps/build.jl b/deps/build.jl index 42d59585..67f4b9ad 100644 --- a/deps/build.jl +++ b/deps/build.jl @@ -64,9 +64,9 @@ function build_jlcxxwrap(repo_root, cupynumeric_root) version_path = joinpath(DEPOT_PATH[1], "dev/libcxxwrap_julia_jll/override/LEGATE_INSTALL.txt") if isfile(version_path) version = VersionNumber(strip(read(version_path, String))) - @info "libcxxwrap: Found Legate $version" + @info "libcxxwrap: Found cuNumeric $version" if is_supported_version(version) - @info "libcxxwrap: Found supported version built with Legate.jl: $version" + @info "libcxxwrap: Found supported version built with cuNumeric.jl: $version" return nothing else @info "libcxxwrap: Unsupported version found: $version. Rebuilding..." @@ -78,7 +78,7 @@ function build_jlcxxwrap(repo_root, cupynumeric_root) @info "libcxxwrap: Running build script: $build_libcxxwrap" run_sh(`bash $build_libcxxwrap $repo_root`, "libcxxwrap") open(version_path, "w") do io - write(io, string(get_cupynumeric_version(legate_root))) + write(io, string(get_cupynumeric_version(cupynumeric_root))) end end @@ -175,7 +175,7 @@ function build(::CNPreferences.Developer) cupynumeric_root = load_preference(CNPreferences, "cunumeric_path", nothing) blas_lib = load_preference(CNPreferences, "BLAS_LIB", nothing) if isnothing(cupynumeric_root) - # we are using legate_jll for legate + # we are using cupynumeric_jll cupynumeric_root = _find_jll_artifact_dir(:cupynumeric_jll) else # this means we have a custom path set From e488c3ed6a145eed9f69efa8b7fb87fde63a955f Mon Sep 17 00:00:00 2001 From: krasow Date: Tue, 3 Feb 2026 20:36:30 -0600 Subject: [PATCH 05/16] update for 26.01 --- .githash | 2 +- Project.toml | 4 ++-- deps/version.jl | 4 ++-- lib/cunumeric_jl_wrapper/src/wrapper.cpp | 1 - src/cuNumeric.jl | 5 ++--- src/utilities/depends.jl | 5 +---- src/utilities/preference.jl | 19 ++++++++----------- 7 files changed, 16 insertions(+), 24 deletions(-) diff --git a/.githash b/.githash index bfc11eaa..7bd1672f 100644 --- a/.githash +++ b/.githash @@ -1 +1 @@ -5db897644303d37009ff929fbc5104ef2e6693ab +ae7fafc9193040e74018445faf88598dab24c4d8 diff --git a/Project.toml b/Project.toml index eb96e4e2..a64e6823 100644 --- a/Project.toml +++ b/Project.toml @@ -39,6 +39,6 @@ LegatePreferences = "0.1.5" MacroTools = "0.5.16" OpenBLAS32_jll = "0.3" StatsBase = "0.34" -cunumeric_jl_wrapper_jll = "25.10.2" -cupynumeric_jll = "25.10.2" +cunumeric_jl_wrapper_jll = "26.01.00" +cupynumeric_jll = "26.01.00" julia = "1.10" diff --git a/deps/version.jl b/deps/version.jl index 69232595..61033d91 100644 --- a/deps/version.jl +++ b/deps/version.jl @@ -19,8 +19,8 @@ const MIN_CUDA_VERSION = v"13.0" const MAX_CUDA_VERSION = v"13.9.999" -const MIN_CUNUMERIC_VERSION = v"25.10.00" -const MAX_CUNUMERIC_VERSION = v"26.01.00" +const MIN_CUNUMERIC_VERSION = v"26.01.00" +const MAX_CUNUMERIC_VERSION = v"26.12.00" up_dir(dir::String) = abspath(joinpath(dir, "..")) diff --git a/lib/cunumeric_jl_wrapper/src/wrapper.cpp b/lib/cunumeric_jl_wrapper/src/wrapper.cpp index 0d54b598..ba1975be 100644 --- a/lib/cunumeric_jl_wrapper/src/wrapper.cpp +++ b/lib/cunumeric_jl_wrapper/src/wrapper.cpp @@ -29,7 +29,6 @@ #include "jlcxx/stl.hpp" #include "legate.h" #include "legion.h" -#include "mathtypes/half.h" #include "realm.h" #include "types.h" #include "ufi.h" diff --git a/src/cuNumeric.jl b/src/cuNumeric.jl index fbdd914f..d82fedc5 100644 --- a/src/cuNumeric.jl +++ b/src/cuNumeric.jl @@ -22,7 +22,7 @@ module cuNumeric include(joinpath(@__DIR__, "../deps/version.jl")) include("utilities/depends.jl") -const HAS_CUDA = cupynumeric_jll.host_platform["cuda"] != "none" +const HAS_CUDA = LegatePreferences.has_cuda_gpu() if !HAS_CUDA @warn "cuPyNumeric JLL does not have CUDA. If you have an NVIDIA GPU something might be wrong." @@ -62,11 +62,10 @@ elseif CNPreferences.MODE == "developer" find_paths(CNPreferences.MODE) end elseif CNPreferences.MODE == "conda" - using cunumeric_jl_wrapper_jll find_paths( CNPreferences.MODE, cupynumeric_jll_module=nothing, - cupynumeric_jll_wrapper_module=cunumeric_jl_wrapper_jll, + cupynumeric_jll_wrapper_module=nothing, ) else error( diff --git a/src/utilities/depends.jl b/src/utilities/depends.jl index 984ab504..b988b6ab 100644 --- a/src/utilities/depends.jl +++ b/src/utilities/depends.jl @@ -1,15 +1,12 @@ using Preferences using CNPreferences -import LegatePreferences +using LegatePreferences using Legate using Libdl using CxxWrap using Pkg using TOML -using cupynumeric_jll -using cunumeric_jl_wrapper_jll - import Base: axes, convert, copy, copyto!, inv, isfinite, sqrt, -, +, *, ==, !=, isapprox, read, view, maximum, minimum, prod, sum, getindex, setindex!, sum, prod diff --git a/src/utilities/preference.jl b/src/utilities/preference.jl index 08010462..31ab821d 100644 --- a/src/utilities/preference.jl +++ b/src/utilities/preference.jl @@ -18,8 +18,8 @@ =# function check_cupynumeric_install(cupynumeric_root) - is_legate_installed(cupynumeric_root; throw_errors=true) - if !legate_valid(cupynumeric_root) + is_cupynumeric_installed(cupynumeric_root; throw_errors=true) + if !cupynumeric_valid(cupynumeric_root) error( "cuNumeric.jl: Unsupported cuNumeric version at $(cupynumeric_root). " * "Installed version: $(get_cupynumeric_version(cupynumeric_root)) not in range supported: " * @@ -109,21 +109,18 @@ end function _find_paths( mode::CNPreferences.Conda, cupynumeric_jll_module::Nothing, - cupynumeric_jll_wrapper_module::Module, + cupynumeric_jll_wrapper_module::Nothing, ) - @warn "mode = conda may break. We are using a subset of libraries from conda." - - conda_env = load_preference(CNPreferences, "cunumeric_conda_path", nothing) + conda_env = load_preference(CNPreferences, "cunumeric_conda_env", nothing) isnothing(conda_env) && error( - "legate_conda_env preference must be set in LocalPreferences.toml when using conda mode" + "cunumeric_conda_env preference must be set in LocalPreferences.toml when using conda mode" ) check_cupynumeric_install(conda_env) - legate_path = conda_env - check_jll(cupynumeric_jll_wrapper_module) - legate_wrapper_lib = joinpath(cupynumeric_jll_wrapper_module.artifact_dir, "lib") + pkg_root = abspath(joinpath(@__DIR__, "../../")) + wrapper_lib = joinpath(pkg_root, "lib", "cunumeric_jl_wrapper", "build", "lib") - return joinpath(legate_path, "lib"), legate_wrapper_lib + return joinpath(conda_env, "lib"), wrapper_lib end # MPI, NCCL etc are found by Legate.find_dependency_paths From 0e886e8fe54067ccc71203f3e23c98fe834c7735 Mon Sep 17 00:00:00 2001 From: krasow Date: Tue, 3 Feb 2026 20:56:32 -0600 Subject: [PATCH 06/16] use load preference --- .githash | 2 +- src/cuNumeric.jl | 24 ++++++++++-------------- src/utilities/preference.jl | 2 +- 3 files changed, 12 insertions(+), 16 deletions(-) diff --git a/.githash b/.githash index 7bd1672f..b6bfac7f 100644 --- a/.githash +++ b/.githash @@ -1 +1 @@ -ae7fafc9193040e74018445faf88598dab24c4d8 +e488c3ed6a145eed9f69efa8b7fb87fde63a955f diff --git a/src/cuNumeric.jl b/src/cuNumeric.jl index d82fedc5..35a9ab88 100644 --- a/src/cuNumeric.jl +++ b/src/cuNumeric.jl @@ -21,6 +21,7 @@ module cuNumeric include(joinpath(@__DIR__, "../deps/version.jl")) include("utilities/depends.jl") +include("utilities/preference.jl") const HAS_CUDA = LegatePreferences.has_cuda_gpu() @@ -38,38 +39,33 @@ const SUPPORTED_TYPES = Union{SUPPORTED_INT_TYPES,SUPPORTED_FLOAT_TYPES,Bool} #* # const MAX_DIM = 6 # idk what we compiled? -include("utilities/preference.jl") - # Sets the LEGATE_LIB_PATH and WRAPPER_LIB_PATH preferences based on mode # This will also include the relevant JLLs if necessary. -@static if CNPreferences.MODE == "jll" +MODE = load_preference(CNPreferences, "cunumeric_mode", CNPreferences.MODE_JLL) +@static if MODE == CNPreferences.MODE_JLL using cupynumeric_jll, cunumeric_jl_wrapper_jll find_paths( - CNPreferences.MODE; + MODE; cupynumeric_jll_module=cupynumeric_jll, cupynumeric_jll_wrapper_module=cunumeric_jl_wrapper_jll, ) -elseif CNPreferences.MODE == "developer" +elseif MODE == CNPreferences.MODE_DEVELOPER use_cupynumeric_jll = load_preference(CNPreferences, "legate_use_jll", true) if use_cupynumeric_jll using cupynumeric_jll find_paths( - CNPreferences.MODE; + MODE; cupynumeric_jll_module=cupynumeric_jll, cupynumeric_jll_wrapper_module=nothing, ) else - find_paths(CNPreferences.MODE) + find_paths(MODE) end -elseif CNPreferences.MODE == "conda" - find_paths( - CNPreferences.MODE, - cupynumeric_jll_module=nothing, - cupynumeric_jll_wrapper_module=nothing, - ) +elseif MODE == CNPreferences.MODE_CONDA + find_paths(MODE) else error( - "cuNumeric.jl: Unknown mode $(CNPreferences.MODE). Must be one of 'jll', 'developer', or 'conda'." + "cuNumeric.jl: Unknown mode $(MODE). Must be one of 'jll', 'developer', or 'conda'." ) end diff --git a/src/utilities/preference.jl b/src/utilities/preference.jl index 31ab821d..2342efe9 100644 --- a/src/utilities/preference.jl +++ b/src/utilities/preference.jl @@ -27,7 +27,7 @@ function check_cupynumeric_install(cupynumeric_root) ) end - @info "cuNumeric.jl: Found a valid install in: $(cupynumeric_root)" + @debug "cuNumeric.jl: Found a valid install in: $(cupynumeric_root)" return true end From ecae5ac2aa9f1f3279f01ba4f91ea1692812ce3d Mon Sep 17 00:00:00 2001 From: krasow Date: Tue, 3 Feb 2026 23:07:25 -0600 Subject: [PATCH 07/16] fix error --- .githash | 2 +- deps/version.jl | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.githash b/.githash index b6bfac7f..dbcde33e 100644 --- a/.githash +++ b/.githash @@ -1 +1 @@ -e488c3ed6a145eed9f69efa8b7fb87fde63a955f +0e886e8fe54067ccc71203f3e23c98fe834c7735 diff --git a/deps/version.jl b/deps/version.jl index 61033d91..1e036f09 100644 --- a/deps/version.jl +++ b/deps/version.jl @@ -57,7 +57,7 @@ function is_cupynumeric_installed(cupynumeric::String; throw_errors::Bool=false) include_dir = joinpath(cupynumeric, "include") if !isdir(joinpath(include_dir, "cupynumeric/cupynumeric")) throw_errors && - @error "cuNumeric.jl: Cannot find include/cupynumeric/cupynumeric in $(cupynumeric_root)" + @error "cuNumeric.jl: Cannot find include/cupynumeric/cupynumeric in $(cupynumeric)" return false end return true From 59c8a53e75b53d9fd94135821db8504d7b05b941 Mon Sep 17 00:00:00 2001 From: krasow Date: Wed, 4 Feb 2026 10:43:44 -0600 Subject: [PATCH 08/16] fix config --- lib/cunumeric_jl_wrapper/src/ndarray.cpp | 5 ++ scripts/run_with_conda.sh | 19 +++++ src/memory.jl | 6 ++ src/port.jl | 96 ++++++++++++++++++++++++ src/test.jl | 18 +++++ 5 files changed, 144 insertions(+) create mode 100755 scripts/run_with_conda.sh create mode 100644 src/port.jl create mode 100644 src/test.jl diff --git a/lib/cunumeric_jl_wrapper/src/ndarray.cpp b/lib/cunumeric_jl_wrapper/src/ndarray.cpp index 4659cc14..00c4f21b 100644 --- a/lib/cunumeric_jl_wrapper/src/ndarray.cpp +++ b/lib/cunumeric_jl_wrapper/src/ndarray.cpp @@ -37,6 +37,11 @@ struct CN_Store { legate::LogicalStore obj; }; +size_t nda_get_number_of_runtimes() { + Machine legion_machine{Machine::get_machine()}; + return legion_machine.get_address_space_count(); +} + CN_NDArray* nda_zeros_array(int32_t dim, const uint64_t* shape, CN_Type type) { std::vector shp(shape, shape + dim); NDArray result = zeros(shp, type.obj); diff --git a/scripts/run_with_conda.sh b/scripts/run_with_conda.sh new file mode 100755 index 00000000..b4014f1e --- /dev/null +++ b/scripts/run_with_conda.sh @@ -0,0 +1,19 @@ +#!/bin/bash +# Wrapper script to run Julia with conda mode, avoiding library conflicts +if [ -z "$CONDA_PREFIX" ]; then + echo "Error: CONDA_PREFIX is not set. Please activate a conda environment." + exit 1 +fi + +export CONDA_ENV="${CONDA_PREFIX}" + +# Preload conda libraries to avoid conflicts with JLL artifacts +# This prevents HDF5_jll symbol errors +export LD_PRELOAD="${CONDA_ENV}/lib/libstdc++.so:${CONDA_ENV}/lib/libhdf5.so:${CONDA_ENV}/lib/liblegate.so" + +echo $PWD +julia --project=$PWD -e "using Pkg; Pkg.add(\"LegatePreferences\"); using LegatePreferences; LegatePreferences.use_conda(\"${CONDA_ENV}\");" +julia --project=$PWD -e "using Pkg; Pkg.add(\"CNPreferences\"); using CNPreferences; CNPreferences.use_conda(\"${CONDA_ENV}\");" + +# Run Julia with any provided arguments +exec julia --project=$PWD "$@" \ No newline at end of file diff --git a/src/memory.jl b/src/memory.jl index ca28d07f..a5fa99ea 100644 --- a/src/memory.jl +++ b/src/memory.jl @@ -17,6 +17,12 @@ const soft_frac = Ref{Float64}(0.80) const hard_frac = Ref{Float64}(0.90) const AUTO_GC_ENABLE = Ref{Bool}(false) +function get_number_of_runtimes() + n = ccall((:nda_get_number_of_runtimes, libnda), + Int32, ()) + return n +end + @doc""" init_gc!() diff --git a/src/port.jl b/src/port.jl new file mode 100644 index 00000000..f08d252a --- /dev/null +++ b/src/port.jl @@ -0,0 +1,96 @@ +using Sockets + +""" + @everywhere_but_repl expr + +Execute `expr` on all workers except process 1. +""" +# macro everywhere_but_repl(ex) +# esc( +# quote +# @everywhere begin +# ex +# end +# end +# ) +# end + +# +# Helper: find (IP:PORT) for a given PID by inspecting Linux sockets +# +function _ports_for_pid(pid) + pidstr = string(pid) + + # 1. Get all lines from `ss -ltnp` that match this pid + raw = read(`ss -ltnp`, String) + lines = filter(l -> occursin("pid=$pidstr", l), split(raw, '\n')) + + addrs = String[] + + for ln in lines + parts = split(ln) + if length(parts) >= 4 + # 2. Extract the port from the Local Address:Port field + locale = parts[4] # e.g., "127.0.0.1:34567" + port = split(locale, ":")[end] # get only the port + + # 3. Use the host's real IP + ip_int = Sockets.getaddrinfo(gethostname()).host + ipstr = string(Sockets.IPv4(ip_int)) + + # 4. Combine IP and port + push!(addrs, "$ipstr:$port") + end + end + + return addrs +end + +# +# Return "IP:PORT" for each worker in Distributed.jl +# +function legate_peers() + w = workers() + if isempty(w) + error("No Julia workers found! Call addprocs(...) first.") + end + + # Fetch PID of each worker from that worker + pidmap = Dict(wi => remotecall_fetch(() -> getpid(), wi) for wi in w) + + peers = String[] + + for wi in w + pid = pidmap[wi] + ports = _ports_for_pid(pid) + if isempty(ports) + push!(peers, "UNKNOWN:0") + else + push!(peers, ports[1]) + end + end + + return peers +end + +function setup_legate_env() + if myid() != 1 + all_addrs = legate_peers() + self_addr = all_addrs[1] + + # Exclude self and join remaining peers + peer_addrs = join(all_addrs[2:end], " ") + + # Set environment variables + ENV["WORKER_SELF_INFO"] = "$self_addr" + ENV["WORKER_PEERS_INFO"] = "$peer_addrs" + ENV["BOOTSTRAP_P2P_PLUGIN"] = "realm_ucp_bootstrap_mpi.so" + ENV["REALM_UCP_BOOTSTRAP_MODE"] = "mpi" + + # Optional: print to check + println("Self: ", ENV["WORKER_SELF_INFO"]) + println("Peers: ", ENV["WORKER_PEERS_INFO"]) + println("Bootstrap plugin: ", ENV["BOOTSTRAP_P2P_PLUGIN"]) + println("Bootstrapping mode: ", ENV["REALM_UCP_BOOTSTRAP_MODE"]) + end +end diff --git a/src/test.jl b/src/test.jl new file mode 100644 index 00000000..c37c9078 --- /dev/null +++ b/src/test.jl @@ -0,0 +1,18 @@ +ENV["LEGATE_CONFIG"] = "--cpus=2 --show-config --logging legate=debug,level=2 --show-progress --show-memory-usage --profile" + +using Distributed; +addprocs(4) + +@everywhere begin + if myid() != 1 + include("port.jl") + setup_legate_env() + + using cuNumeric + println("Number of runtimes: ", cuNumeric.get_number_of_runtimes()) + + a = cuNumeric.rand(100) + b = cuNumeric.rand(100) + c = -(a + b) + end +end From e365a18fe1b305c038a2c8cc98b82827999261d3 Mon Sep 17 00:00:00 2001 From: krasow Date: Wed, 4 Feb 2026 10:45:51 -0600 Subject: [PATCH 09/16] legion machine namespace --- .githash | 2 +- lib/cunumeric_jl_wrapper/src/ndarray.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.githash b/.githash index dbcde33e..2d673d6f 100644 --- a/.githash +++ b/.githash @@ -1 +1 @@ -0e886e8fe54067ccc71203f3e23c98fe834c7735 +59c8a53e75b53d9fd94135821db8504d7b05b941 diff --git a/lib/cunumeric_jl_wrapper/src/ndarray.cpp b/lib/cunumeric_jl_wrapper/src/ndarray.cpp index 00c4f21b..8f355192 100644 --- a/lib/cunumeric_jl_wrapper/src/ndarray.cpp +++ b/lib/cunumeric_jl_wrapper/src/ndarray.cpp @@ -38,7 +38,7 @@ struct CN_Store { }; size_t nda_get_number_of_runtimes() { - Machine legion_machine{Machine::get_machine()}; + Legion::Machine legion_machine{Legion::Machine::get_machine()}; return legion_machine.get_address_space_count(); } From 738f0a323007654144fa8320c22aa7449ad7c2e1 Mon Sep 17 00:00:00 2001 From: krasow Date: Wed, 4 Feb 2026 13:42:17 -0600 Subject: [PATCH 10/16] little lost --- .githash | 2 +- src/notes.md | 79 ++++++++++++++++++++++++++++++++++++++++++++++++++++ src/port.jl | 6 ++-- src/test.jl | 2 +- 4 files changed, 84 insertions(+), 5 deletions(-) create mode 100644 src/notes.md diff --git a/.githash b/.githash index 2d673d6f..335255b2 100644 --- a/.githash +++ b/.githash @@ -1 +1 @@ -59c8a53e75b53d9fd94135821db8504d7b05b941 +e365a18fe1b305c038a2c8cc98b82827999261d3 diff --git a/src/notes.md b/src/notes.md new file mode 100644 index 00000000..3bfcf97d --- /dev/null +++ b/src/notes.md @@ -0,0 +1,79 @@ +We set environment variables in port.jl: +```julia +ENV["WORKER_SELF_INFO"] = "$self_addr" +ENV["WORKER_PEERS_INFO"] = "$peer_addrs" +ENV["REALM_UCP_BOOTSTRAP_PLUGIN"] = "realm_bootstrap_p2p.so" +ENV["REALM_UCP_BOOTSTRAP_MODE"] = "p2p" +``` + +I know these environment variables are actually being set as changing them can result in different errors. + +--- + +**Realm code flow:** + +1. https://github.com/StanfordLegion/realm/blob/main/src/realm/ucx/ucp_internal.cc#L826 +```c++ +boot_config.plugin_name = getenv("REALM_UCP_BOOTSTRAP_PLUGIN"); +if(bootstrap_init(&boot_config, &boot_handle) != 0) { +log_ucp.error() << "failed to bootstrap ucp"; +return false; +} +``` + +2. https://github.com/StanfordLegion/realm/blob/main/src/realm/ucx/bootstrap/bootstrap.cc#L108 +```c++ +case BOOTSTRAP_P2P: +if(config->plugin_name != NULL) { + status = bootstrap_loader_init(config->plugin_name, NULL, handle); +} else { + status = bootstrap_loader_init(BOOTSTRAP_P2P_PLUGIN, NULL, handle); +} +if(status != 0) { + log_ucp.error() << "bootstrap_loader_init failed"; +} +break; +``` + +3. This will dlopen the plugin file. +https://github.com/StanfordLegion/realm/blob/main/src/realm/ucx/bootstrap/bootstrap_loader.cc#L56 +```c++ + int bootstrap_loader_init(const char *plugin, void *arg, bootstrap_handle_t *handle) +``` + +4. The plugin calls this init function: +https://github.com/StanfordLegion/realm/blob/main/src/realm/ucx/bootstrap/bootstrap_p2p.cc#L115 +```c++ +extern "C" int realm_ucp_bootstrap_plugin_init(void *arg, bootstrap_handle_t *handle) +{ + std::string self; + std::vector peers; + if(!read_env(self, peers)) { + std::cerr << "Failed to gather workers information " << std::endl; + return -1; + } + + p2p_comm = std::make_shared(self, peers); + if(!p2p_comm->Init()) { // fails to find this symbol + std::cerr << "Failed to initialize p2p comm" << std::endl; + return -1; + } +... +} +``` + +--- + +**Error:** + +``` +From worker 5: /tmp/conda-croot/legate/work/arch-conda/skbuild_core/_deps/realm-src/src/realm/ucx/bootstrap/bootstrap_loader.cc:64: NULL value Bootstrap unable to load 'realm_bootstrap_p2p.so' +From worker 5: /home/david/anaconda3/envs/myenv/lib/./realm_bootstrap_p2p.so: undefined symbol: _ZN3p2p7P2PComm4InitEv +From worker 5: Unable to create specified registered network module 'ucx' +``` + +The undefined symbol is: +``` +c++filt -t _ZN3p2p7P2PComm4InitEv +p2p::P2PComm::Init() +``` \ No newline at end of file diff --git a/src/port.jl b/src/port.jl index f08d252a..cd708a8e 100644 --- a/src/port.jl +++ b/src/port.jl @@ -84,13 +84,13 @@ function setup_legate_env() # Set environment variables ENV["WORKER_SELF_INFO"] = "$self_addr" ENV["WORKER_PEERS_INFO"] = "$peer_addrs" - ENV["BOOTSTRAP_P2P_PLUGIN"] = "realm_ucp_bootstrap_mpi.so" - ENV["REALM_UCP_BOOTSTRAP_MODE"] = "mpi" + ENV["REALM_UCP_BOOTSTRAP_PLUGIN"] = "realm_bootstrap_p2p.so" + ENV["REALM_UCP_BOOTSTRAP_MODE"] = "p2p" # Optional: print to check println("Self: ", ENV["WORKER_SELF_INFO"]) println("Peers: ", ENV["WORKER_PEERS_INFO"]) - println("Bootstrap plugin: ", ENV["BOOTSTRAP_P2P_PLUGIN"]) + println("Bootstrap plugin: ", ENV["REALM_UCP_BOOTSTRAP_PLUGIN"]) println("Bootstrapping mode: ", ENV["REALM_UCP_BOOTSTRAP_MODE"]) end end diff --git a/src/test.jl b/src/test.jl index c37c9078..1b652f2c 100644 --- a/src/test.jl +++ b/src/test.jl @@ -1,4 +1,4 @@ -ENV["LEGATE_CONFIG"] = "--cpus=2 --show-config --logging legate=debug,level=2 --show-progress --show-memory-usage --profile" +ENV["LEGATE_CONFIG"] = "--cpus=2 --show-config --logging legate=debug,level=2 --show-progress --show-memory-usage --profile" using Distributed; addprocs(4) From 94c6ff46441b4ce8388e73892f31ae5becf5fd81 Mon Sep 17 00:00:00 2001 From: krasow Date: Wed, 4 Feb 2026 13:45:32 -0600 Subject: [PATCH 11/16] extra output --- .githash | 2 +- src/notes.md | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/.githash b/.githash index 335255b2..adc366fd 100644 --- a/.githash +++ b/.githash @@ -1 +1 @@ -e365a18fe1b305c038a2c8cc98b82827999261d3 +738f0a323007654144fa8320c22aa7449ad7c2e1 diff --git a/src/notes.md b/src/notes.md index 3bfcf97d..95cceb3a 100644 --- a/src/notes.md +++ b/src/notes.md @@ -76,4 +76,12 @@ The undefined symbol is: ``` c++filt -t _ZN3p2p7P2PComm4InitEv p2p::P2PComm::Init() +``` + +```bash +(myenv) david@dubliner:~/cuNumeric.jl$ nm -D $CONDA_PREFIX/lib/realm_bootstrap_p2p.so | grep -i p2p + U _ZN3p2p7P2PComm4InitEv + U _ZN3p2p7P2PComm8ShutdownEv + U _ZN3p2p7P2PComm9AllgatherEPvihS1_ih + U _ZN3p2p7P2PCommC1ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt6vectorIS6_SaIS6_EES8_ ``` \ No newline at end of file From 9ec1044bb02b99a4a13464d8bd1695217b8ed9a2 Mon Sep 17 00:00:00 2001 From: krasow Date: Wed, 4 Feb 2026 13:49:28 -0600 Subject: [PATCH 12/16] produce a summary --- .githash | 2 +- src/notes.md | 13 +++++++++++-- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/.githash b/.githash index adc366fd..39e21296 100644 --- a/.githash +++ b/.githash @@ -1 +1 @@ -738f0a323007654144fa8320c22aa7449ad7c2e1 +94c6ff46441b4ce8388e73892f31ae5becf5fd81 diff --git a/src/notes.md b/src/notes.md index 95cceb3a..357ed7d2 100644 --- a/src/notes.md +++ b/src/notes.md @@ -78,10 +78,19 @@ c++filt -t _ZN3p2p7P2PComm4InitEv p2p::P2PComm::Init() ``` +The `realm_bootstrap_p2p.so` plugin library has **undefined symbols** for the `P2PComm` class: + ```bash -(myenv) david@dubliner:~/cuNumeric.jl$ nm -D $CONDA_PREFIX/lib/realm_bootstrap_p2p.so | grep -i p2p +$ nm -D $CONDA_PREFIX/lib/realm_bootstrap_p2p.so | grep -i p2p U _ZN3p2p7P2PComm4InitEv U _ZN3p2p7P2PComm8ShutdownEv U _ZN3p2p7P2PComm9AllgatherEPvihS1_ih U _ZN3p2p7P2PCommC1ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt6vectorIS6_SaIS6_EES8_ -``` \ No newline at end of file +``` + +The implementation is in separate source files: +- [`p2p_comm.h`](https://github.com/StanfordLegion/realm/blob/main/src/realm/ucx/bootstrap/p2p_comm.h) / [`p2p_comm.cc`](https://github.com/StanfordLegion/realm/blob/main/src/realm/ucx/bootstrap/p2p_comm.cc) - The P2PComm class + +**The problem:** The conda-built `realm_bootstrap_p2p.so` plugin only contains the `bootstrap_p2p.cc` code, but is **missing** the `p2p_comm.cc` implementation and mesh networking code. + +This appears to be a **build configuration issue** in the Legate conda package (my guess). From 6197de3d12aff1f63d6bcecb4dfdc0cab893a2e6 Mon Sep 17 00:00:00 2001 From: krasow Date: Wed, 4 Feb 2026 17:22:21 -0600 Subject: [PATCH 13/16] distributed extension --- .githash | 2 +- Project.toml | 6 ++- ext/DistributedExt/DistributedExt.jl | 17 ++++++++ src/port.jl => ext/DistributedExt/ports.jl | 51 ++++++++-------------- ext/DistributedExt/setup.jl | 34 +++++++++++++++ src/cuNumeric.jl | 5 +++ src/test.jl | 18 -------- test/tests/test_p2p.jl | 23 ++++++++++ 8 files changed, 102 insertions(+), 54 deletions(-) create mode 100644 ext/DistributedExt/DistributedExt.jl rename src/port.jl => ext/DistributedExt/ports.jl (60%) create mode 100644 ext/DistributedExt/setup.jl delete mode 100644 src/test.jl create mode 100644 test/tests/test_p2p.jl diff --git a/.githash b/.githash index 39e21296..345ccc09 100644 --- a/.githash +++ b/.githash @@ -1 +1 @@ -94c6ff46441b4ce8388e73892f31ae5becf5fd81 +9ec1044bb02b99a4a13464d8bd1695217b8ed9a2 diff --git a/Project.toml b/Project.toml index a64e6823..0cffeb32 100644 --- a/Project.toml +++ b/Project.toml @@ -26,18 +26,22 @@ libcxxwrap_julia_jll = "3eaa8342-bff7-56a5-9981-c04077f7cee7" [weakdeps] CUDA = "052768ef-5323-5732-b1bb-66c8b64840ba" +Distributed = "8ba89e20-285c-5b6f-9357-94700520ee1b" +Sockets = "6462fe0b-24de-5631-8697-dd941f90decc" [extensions] -CUDAExt = "CUDA" +DistributedExt = ["Distributed", "Sockets"] [compat] CNPreferences = "0.1.2" CUDA = "5.9" CxxWrap = "0.17" +Distributed = "1.11.0" Legate = "0.1.0" LegatePreferences = "0.1.5" MacroTools = "0.5.16" OpenBLAS32_jll = "0.3" +Sockets = "1.11.0" StatsBase = "0.34" cunumeric_jl_wrapper_jll = "26.01.00" cupynumeric_jll = "26.01.00" diff --git a/ext/DistributedExt/DistributedExt.jl b/ext/DistributedExt/DistributedExt.jl new file mode 100644 index 00000000..30f95f73 --- /dev/null +++ b/ext/DistributedExt/DistributedExt.jl @@ -0,0 +1,17 @@ +module DistributedExt + +using Distributed +using Sockets +# Don't import cuNumeric here - it would initialize runtime before env vars are set! +include("setup.jl") +include("ports.jl") + +function __init__() + # Get cuNumeric module from loaded modules without importing it + cunumeric_pkgid = Base.PkgId(Base.UUID("0fd9ffd4-7e84-4cd0-b8f8-645bd8c73620"), "cuNumeric") + cuNumeric = Base.loaded_modules[cunumeric_pkgid] + # Register the init_workers function at runtime + Base.@eval cuNumeric init_workers(; kwargs...) = $DistributedExt.init_workers_impl(; kwargs...) +end + +end # module DistributedExt diff --git a/src/port.jl b/ext/DistributedExt/ports.jl similarity index 60% rename from src/port.jl rename to ext/DistributedExt/ports.jl index cd708a8e..d0a2d26a 100644 --- a/src/port.jl +++ b/ext/DistributedExt/ports.jl @@ -1,20 +1,5 @@ using Sockets -""" - @everywhere_but_repl expr - -Execute `expr` on all workers except process 1. -""" -# macro everywhere_but_repl(ex) -# esc( -# quote -# @everywhere begin -# ex -# end -# end -# ) -# end - # # Helper: find (IP:PORT) for a given PID by inspecting Linux sockets # @@ -74,23 +59,21 @@ function legate_peers() end function setup_legate_env() - if myid() != 1 - all_addrs = legate_peers() - self_addr = all_addrs[1] - - # Exclude self and join remaining peers - peer_addrs = join(all_addrs[2:end], " ") - - # Set environment variables - ENV["WORKER_SELF_INFO"] = "$self_addr" - ENV["WORKER_PEERS_INFO"] = "$peer_addrs" - ENV["REALM_UCP_BOOTSTRAP_PLUGIN"] = "realm_bootstrap_p2p.so" - ENV["REALM_UCP_BOOTSTRAP_MODE"] = "p2p" - - # Optional: print to check - println("Self: ", ENV["WORKER_SELF_INFO"]) - println("Peers: ", ENV["WORKER_PEERS_INFO"]) - println("Bootstrap plugin: ", ENV["REALM_UCP_BOOTSTRAP_PLUGIN"]) - println("Bootstrapping mode: ", ENV["REALM_UCP_BOOTSTRAP_MODE"]) - end + all_addrs = legate_peers() + self_addr = all_addrs[1] + + # Exclude self and join remaining peers + peer_addrs = join(all_addrs[2:end], " ") + + # Set environment variables + ENV["WORKER_SELF_INFO"] = "$self_addr" + ENV["WORKER_PEERS_INFO"] = "$peer_addrs" + ENV["REALM_UCP_BOOTSTRAP_PLUGIN"] = "realm_bootstrap_p2p.so" + ENV["REALM_UCP_BOOTSTRAP_MODE"] = "p2p" + + # Optional: print to check + println("Self: ", ENV["WORKER_SELF_INFO"]) + println("Peers: ", ENV["WORKER_PEERS_INFO"]) + println("Bootstrap plugin: ", ENV["REALM_UCP_BOOTSTRAP_PLUGIN"]) + println("Bootstrapping mode: ", ENV["REALM_UCP_BOOTSTRAP_MODE"]) end diff --git a/ext/DistributedExt/setup.jl b/ext/DistributedExt/setup.jl new file mode 100644 index 00000000..a606f9b0 --- /dev/null +++ b/ext/DistributedExt/setup.jl @@ -0,0 +1,34 @@ +function init_workers_impl(; auto_setup::Bool=true) + w = Distributed.workers() + if isempty(w) + @warn "No Distributed.jl workers found. Did you call addprocs()?" + return nothing + end + + println("Setting up cuNumeric on $(length(w)) workers...") + + if !auto_setup + println("✓ Skipping automatic p2p setup (auto_setup=false)") + return nothing + end + + # Get cuNumeric package directory to load port utilities + cunumeric_pkgid = Base.PkgId(Base.UUID("0fd9ffd4-7e84-4cd0-b8f8-645bd8c73620"), "cuNumeric") + cunumeric_path = dirname(dirname(Base.locate_package(cunumeric_pkgid))) + port_path = joinpath(cunumeric_path, "ext", "DistributedExt", "ports.jl") + + # Use @everywhere with myid() check (not @everywhere workers() - that doesn't work!) + Base.eval(Main, :(@everywhere begin + if myid() != 1 + include($port_path) + setup_legate_env() + using cuNumeric + println("Number of runtimes: ", cuNumeric.get_number_of_runtimes()) + end + end)) + + println("✓ P2p environment configured on all workers") + println("✓ cuNumeric loaded on all workers with p2p networking") + + return nothing +end diff --git a/src/cuNumeric.jl b/src/cuNumeric.jl index 35a9ab88..9866330b 100644 --- a/src/cuNumeric.jl +++ b/src/cuNumeric.jl @@ -219,4 +219,9 @@ function __init__() ensure_runtime!() end +# Placeholder for Distributed extension +function init_workers(; kwargs...) + error("init_workers requires the Distributed package. Please run: using Distributed") +end + end #module cuNumeric diff --git a/src/test.jl b/src/test.jl deleted file mode 100644 index 1b652f2c..00000000 --- a/src/test.jl +++ /dev/null @@ -1,18 +0,0 @@ -ENV["LEGATE_CONFIG"] = "--cpus=2 --show-config --logging legate=debug,level=2 --show-progress --show-memory-usage --profile" - -using Distributed; -addprocs(4) - -@everywhere begin - if myid() != 1 - include("port.jl") - setup_legate_env() - - using cuNumeric - println("Number of runtimes: ", cuNumeric.get_number_of_runtimes()) - - a = cuNumeric.rand(100) - b = cuNumeric.rand(100) - c = -(a + b) - end -end diff --git a/test/tests/test_p2p.jl b/test/tests/test_p2p.jl new file mode 100644 index 00000000..920dd59b --- /dev/null +++ b/test/tests/test_p2p.jl @@ -0,0 +1,23 @@ +ENV["LEGATE_CONFIG"] = "--cpus=2 --show-config --logging legate=debug,level=2 --show-progress --show-memory-usage --profile" + +using Distributed +using cuNumeric + +addprocs(4) + +# Set up peer-specific env vars and load cuNumeric on workers +cuNumeric.init_workers() + +# Test on workers - cuNumeric will load with p2p networking +@everywhere workers() begin + println("Worker $(myid()): Testing cuNumeric") + println("Number of runtimes: ", cuNumeric.get_number_of_runtimes()) + println("P2P plugin: ", get(ENV, "REALM_UCP_BOOTSTRAP_PLUGIN", "not set")) + println("Self info: ", get(ENV, "WORKER_SELF_INFO", "not set")) + + a = cuNumeric.rand(100) + b = cuNumeric.rand(100) + c = -(a + b) + + println("Worker $(myid()): Test complete, result shape: ", size(c)) +end From bc0b454e4b1d24474a5cd33c5ea8a293db5c1d56 Mon Sep 17 00:00:00 2001 From: krasow Date: Wed, 4 Feb 2026 17:31:01 -0600 Subject: [PATCH 14/16] cuNumeric.addprocs() wrapper --- .githash | 2 +- ext/DistributedExt/DistributedExt.jl | 7 ++++-- ext/DistributedExt/setup.jl | 32 ++++++++++++++++++++++++++++ test/tests/test_p2p.jl | 5 +---- 4 files changed, 39 insertions(+), 7 deletions(-) diff --git a/.githash b/.githash index 345ccc09..d7969619 100644 --- a/.githash +++ b/.githash @@ -1 +1 @@ -9ec1044bb02b99a4a13464d8bd1695217b8ed9a2 +6197de3d12aff1f63d6bcecb4dfdc0cab893a2e6 diff --git a/ext/DistributedExt/DistributedExt.jl b/ext/DistributedExt/DistributedExt.jl index 30f95f73..57bb217e 100644 --- a/ext/DistributedExt/DistributedExt.jl +++ b/ext/DistributedExt/DistributedExt.jl @@ -10,8 +10,11 @@ function __init__() # Get cuNumeric module from loaded modules without importing it cunumeric_pkgid = Base.PkgId(Base.UUID("0fd9ffd4-7e84-4cd0-b8f8-645bd8c73620"), "cuNumeric") cuNumeric = Base.loaded_modules[cunumeric_pkgid] - # Register the init_workers function at runtime - Base.@eval cuNumeric init_workers(; kwargs...) = $DistributedExt.init_workers_impl(; kwargs...) + # Register functions at runtime + Base.@eval cuNumeric begin + init_workers(; kwargs...) = $DistributedExt.init_workers_impl(; kwargs...) + addprocs(n::Integer; kwargs...) = $DistributedExt.addprocs_impl(n; kwargs...) + end end end # module DistributedExt diff --git a/ext/DistributedExt/setup.jl b/ext/DistributedExt/setup.jl index a606f9b0..36741f5c 100644 --- a/ext/DistributedExt/setup.jl +++ b/ext/DistributedExt/setup.jl @@ -1,3 +1,35 @@ +""" + addprocs(n::Integer; kwargs...) + +Convenience wrapper that combines `Distributed.addprocs()` and `cuNumeric.init_workers()`. +Starts workers and automatically configures them for distributed cuNumeric with p2p networking. + +# Example +```julia +using Distributed +using cuNumeric + +# Start and configure workers in one call +cuNumeric.addprocs(4) + +# Ready to use distributed cuNumeric! +@everywhere workers() begin + a = cuNumeric.rand(100) +end +``` + +All keyword arguments are passed through to `Distributed.addprocs()`. +""" +function addprocs_impl(n::Integer; kwargs...) + # Start workers + pids = Distributed.addprocs(n; kwargs...) + + # Configure them for cuNumeric + init_workers_impl() + + return pids +end + function init_workers_impl(; auto_setup::Bool=true) w = Distributed.workers() if isempty(w) diff --git a/test/tests/test_p2p.jl b/test/tests/test_p2p.jl index 920dd59b..14905611 100644 --- a/test/tests/test_p2p.jl +++ b/test/tests/test_p2p.jl @@ -3,10 +3,7 @@ ENV["LEGATE_CONFIG"] = "--cpus=2 --show-config --logging legate=debug,level=2 -- using Distributed using cuNumeric -addprocs(4) - -# Set up peer-specific env vars and load cuNumeric on workers -cuNumeric.init_workers() +cuNumeric.addprocs(4) # Test on workers - cuNumeric will load with p2p networking @everywhere workers() begin From 26b4bd421ae822e9c7861a9babbf77963e26b458 Mon Sep 17 00:00:00 2001 From: David Krasowska Date: Wed, 4 Feb 2026 19:00:17 -0600 Subject: [PATCH 15/16] Update Project.toml --- Project.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/Project.toml b/Project.toml index 0cffeb32..c3c7b162 100644 --- a/Project.toml +++ b/Project.toml @@ -30,6 +30,7 @@ Distributed = "8ba89e20-285c-5b6f-9357-94700520ee1b" Sockets = "6462fe0b-24de-5631-8697-dd941f90decc" [extensions] +CUDAExt = "CUDA" DistributedExt = ["Distributed", "Sockets"] [compat] From 480aa72adb236d74400cfb05c838b041cc822f6d Mon Sep 17 00:00:00 2001 From: krasow Date: Wed, 25 Feb 2026 11:46:53 -0600 Subject: [PATCH 16/16] update distributed --- .githash | 2 +- ext/DistributedExt/ports.jl | 4 ++-- ext/DistributedExt/setup.jl | 9 ++++----- 3 files changed, 7 insertions(+), 8 deletions(-) diff --git a/.githash b/.githash index d7969619..a849c1cf 100644 --- a/.githash +++ b/.githash @@ -1 +1 @@ -6197de3d12aff1f63d6bcecb4dfdc0cab893a2e6 +bc0b454e4b1d24474a5cd33c5ea8a293db5c1d56 diff --git a/ext/DistributedExt/ports.jl b/ext/DistributedExt/ports.jl index d0a2d26a..377890f9 100644 --- a/ext/DistributedExt/ports.jl +++ b/ext/DistributedExt/ports.jl @@ -63,12 +63,12 @@ function setup_legate_env() self_addr = all_addrs[1] # Exclude self and join remaining peers - peer_addrs = join(all_addrs[2:end], " ") + peer_addrs = join(sort(all_addrs[1:end]), " ") # Set environment variables ENV["WORKER_SELF_INFO"] = "$self_addr" ENV["WORKER_PEERS_INFO"] = "$peer_addrs" - ENV["REALM_UCP_BOOTSTRAP_PLUGIN"] = "realm_bootstrap_p2p.so" + ENV["REALM_UCP_BOOTSTRAP_PLUGIN"] = "realm_ucp_bootstrap_p2p.so" ENV["REALM_UCP_BOOTSTRAP_MODE"] = "p2p" # Optional: print to check diff --git a/ext/DistributedExt/setup.jl b/ext/DistributedExt/setup.jl index 36741f5c..025bc88b 100644 --- a/ext/DistributedExt/setup.jl +++ b/ext/DistributedExt/setup.jl @@ -37,10 +37,10 @@ function init_workers_impl(; auto_setup::Bool=true) return nothing end - println("Setting up cuNumeric on $(length(w)) workers...") + @info "Setting up cuNumeric on $(length(w)) workers..." if !auto_setup - println("✓ Skipping automatic p2p setup (auto_setup=false)") + @info "✓ Skipping automatic p2p setup (auto_setup=false)" return nothing end @@ -55,12 +55,11 @@ function init_workers_impl(; auto_setup::Bool=true) include($port_path) setup_legate_env() using cuNumeric - println("Number of runtimes: ", cuNumeric.get_number_of_runtimes()) + @info "Number of runtimes: " cuNumeric.get_number_of_runtimes() end end)) - println("✓ P2p environment configured on all workers") - println("✓ cuNumeric loaded on all workers with p2p networking") + @info "✓ cuNumeric loaded on all workers with p2p networking" return nothing end