diff --git a/.github/workflows/build-quadrants.yml b/.github/workflows/build-quadrants.yml new file mode 100644 index 00000000000..4d95e5c79b1 --- /dev/null +++ b/.github/workflows/build-quadrants.yml @@ -0,0 +1,170 @@ +# SPDX-FileCopyrightText: 2026 The RISE Project +# SPDX-License-Identifier: MIT +# +# This workflow is based on: https://github.com/Genesis-Embodied-AI/quadrants/blob/v1.3.3/.github/workflows/manylinux_wheel.yml +name: Build quadrants wheels (riscv64) + +on: + workflow_dispatch: + inputs: + version: + description: 'Version glob to (re)build; empty builds every version of docs/packages/quadrants.yaml not released yet' + required: false + default: '' + pull_request: + branches: [main] + paths: + - '.github/workflows/build-quadrants.yml' + - 'docs/packages/quadrants.yaml' + - 'patches/quadrants/**' + push: + branches: [main] + paths: + - '.github/workflows/build-quadrants.yml' + - 'docs/packages/quadrants.yaml' + - 'patches/quadrants/**' + +concurrency: + group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} + cancel-in-progress: true + +permissions: + contents: read + +env: + LLVM_VERSION: 22.1.0 + +jobs: + setup: + uses: $/.github/workflows/_setup.yml + with: + package: quadrants + version: ${{ inputs.version }} + + build_llvm: + needs: [setup] + if: needs.setup.outputs.versions != '[]' + name: Build LLVM 22.1.0 for quadrants (riscv64) + runs-on: ubuntu-24.04-riscv + container: + image: quay.io/pypa/manylinux_2_39_riscv64 + timeout-minutes: 1440 # full LLVM+clang compile from source + + steps: + # quadrants-sdk-builds (download_llvm.py's own release bucket) ships no riscv64 LLVM; + # build LLVM+clang 22.1.0 ourselves with only the RISCV target and the components + # quadrants's QuadrantsCore.cmake links (Core/ExecutionEngine/OrcJIT/RuntimeDyld/...). + # No CUDA/AMDGPU/Vulkan backend exists for riscv64 (patches/quadrants disables them), so + # NVPTX/AMDGPU targets are left out too. + - name: Build and install LLVM+clang + run: | + set -euxo pipefail + dnf -y install ninja-build lld + curl -fsSL -o llvm-project.src.tar.xz \ + "https://github.com/llvm/llvm-project/releases/download/llvmorg-${LLVM_VERSION}/llvm-project-${LLVM_VERSION}.src.tar.xz" + tar xf llvm-project.src.tar.xz + cmake -S "llvm-project-${LLVM_VERSION}.src/llvm" -B build -G Ninja \ + -DLLVM_ENABLE_PROJECTS=clang \ + -DLLVM_TARGETS_TO_BUILD=RISCV \ + -DBUILD_SHARED_LIBS=OFF \ + -DLLVM_ENABLE_ZLIB=OFF \ + -DLLVM_ENABLE_ZSTD=OFF \ + -DLLVM_ENABLE_TERMINFO=OFF \ + -DLLVM_ENABLE_LIBXML2=OFF \ + -DLLVM_INCLUDE_TESTS=OFF \ + -DLLVM_INCLUDE_EXAMPLES=OFF \ + -DLLVM_INCLUDE_BENCHMARKS=OFF \ + -DLLVM_USE_LINKER=lld \ + -DLLVM_PARALLEL_LINK_JOBS=1 \ + -DCMAKE_BUILD_TYPE=Release \ + -DCMAKE_INSTALL_PREFIX="$(pwd)/llvm-install" + cmake --build build --target install -j"$(nproc)" + tar czf llvm-install.tar.gz llvm-install + + - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + with: + name: quadrants-llvm-${{ env.LLVM_VERSION }}-riscv64 + path: llvm-install.tar.gz + if-no-files-found: error + retention-days: 1 + + build_wheels: + needs: [setup, build_llvm] + if: needs.setup.outputs.versions != '[]' + strategy: + fail-fast: false + matrix: + version: ${{ fromJSON(needs.setup.outputs.versions) }} + python: ["cp310", "cp311", "cp312", "cp313"] + name: Build quadrants ${{ matrix.version }} ${{ matrix.python }}-manylinux_riscv64 + runs-on: ubuntu-24.04-riscv + container: + image: quay.io/pypa/manylinux_2_39_riscv64 + timeout-minutes: 360 + + env: + QUADRANTS_VERSION: ${{ matrix.version }} + PIP_EXTRA_INDEX_URL: https://pypi.riseproject.dev/simple/ + + steps: + - name: Checkout quadrants v${{ env.QUADRANTS_VERSION }} + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + repository: Genesis-Embodied-AI/quadrants + ref: v${{ env.QUADRANTS_VERSION }} + submodules: recursive + persist-credentials: false + + - name: Checkout python-wheels + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + path: python-wheels + persist-credentials: false + + - name: Patch quadrants source + run: git apply python-wheels/patches/quadrants/${{ env.QUADRANTS_VERSION }}/*.patch + + - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 + with: + name: quadrants-llvm-${{ env.LLVM_VERSION }}-riscv64 + + - name: Unpack LLVM, select the interpreter + run: | + tar xzf llvm-install.tar.gz + echo "LLVM_DIR=$(pwd)/llvm-install" >> "$GITHUB_ENV" + echo "/opt/python/${{ matrix.python }}-${{ matrix.python }}/bin" >> "$GITHUB_PATH" + + - name: Build and check wheel + run: | + bash .github/workflows/scripts_new/manylinux_wheel/1_prerequisites.sh + bash .github/workflows/scripts_new/manylinux_wheel/2_build.sh + bash .github/workflows/scripts_new/manylinux_wheel/3_check.sh + + - name: Smoke-test wheel + run: | + rm -f dist/*.whl + cp wheelhouse/*.whl dist/ + bash .github/workflows/scripts_new/manylinux_wheel/4_install_wheel.sh + + - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + with: + name: quadrants-${{ matrix.version }}-${{ matrix.python }}-manylinux_riscv64 + path: wheelhouse/*.whl + if-no-files-found: error + + publish: + name: Publish quadrants ${{ matrix.version }} + needs: [setup, build_wheels] + if: needs.setup.outputs.versions != '[]' + strategy: + fail-fast: false + matrix: + version: ${{ fromJSON(needs.setup.outputs.versions) }} + permissions: + contents: write + pull-requests: write + uses: $/.github/workflows/_publish-wheel.yml + secrets: + app-private-key: ${{ secrets.RISEPROJECT_APP_PRIVATE_KEY }} + with: + artifact-pattern: quadrants-${{ matrix.version }}-*-manylinux_riscv64 diff --git a/docs/packages/quadrants.yaml b/docs/packages/quadrants.yaml new file mode 100644 index 00000000000..af00d984a3f --- /dev/null +++ b/docs/packages/quadrants.yaml @@ -0,0 +1,5 @@ +package-name: quadrants +source-code: https://github.com/Genesis-Embodied-AI/quadrants +license: Apache-2.0 +versions: +- version: 1.3.3 diff --git a/patches/quadrants/1.3.3/0001-Add-a-riscv64-CPU-arch.patch b/patches/quadrants/1.3.3/0001-Add-a-riscv64-CPU-arch.patch new file mode 100644 index 00000000000..0d6d2c26de7 --- /dev/null +++ b/patches/quadrants/1.3.3/0001-Add-a-riscv64-CPU-arch.patch @@ -0,0 +1,181 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: RISE Project CI +Date: Thu, 15 Oct 2026 00:00:00 +0000 +Subject: [PATCH] Add a riscv64 CPU arch + +Quadrants' CPU-arch enum (quadrants/inc/archs.inc.h) only lists x64 and +arm64; cmake/QuadrantsCXXFlags.cmake FATAL_ERRORs on any other +CMAKE_SYSTEM_PROCESSOR, and rhi/arch.cpp's host_arch()/ +default_simd_width()/arch_is_cpu()/arch_uses_llvm() hit +RHI_NOT_IMPLEMENTED or silently exclude riscv64 from the CPU-backend +checks scattered through the LLVM codegen (program/extension.cpp, +runtime/llvm/llvm_context.cpp, runtime/llvm/adstack_lazy_claim/ +bound_eval.cpp, transforms/make_mesh_block_local.cpp). Add a riscv64 +case everywhere x64/arm64 are handled as CPU archs, so the LLVM CPU +JIT backend (orc::RTDyldObjectLinkingLayer on Linux) is reachable on +riscv64. default_simd_width() uses 4, matching arm64's conservative +choice since RV64GC has no fixed-width SIMD without RVV. The nanobind +enum binding in quadrants/python/export_lang.cpp regenerates from +archs.inc.h via the same PER_ARCH macro, so quadrants.riscv64 needs no +separate binding. + +Upstream-Status: To upstream + +Signed-off-by: RISE Project CI +--- + cmake/QuadrantsCXXFlags.cmake | 5 ++++- + quadrants/inc/archs.inc.h | 1 + + quadrants/program/extension.cpp | 3 +++ + quadrants/rhi/arch.cpp | 11 +++++++++-- + .../runtime/llvm/adstack_lazy_claim/bound_eval.cpp | 2 +- + quadrants/runtime/llvm/llvm_context.cpp | 2 +- + quadrants/transforms/make_mesh_block_local.cpp | 6 +++--- + 7 files changed, 22 insertions(+), 8 deletions(-) + +diff --git a/cmake/QuadrantsCXXFlags.cmake b/cmake/QuadrantsCXXFlags.cmake +index e4eb937..c78fbab 100644 +--- a/cmake/QuadrantsCXXFlags.cmake ++++ b/cmake/QuadrantsCXXFlags.cmake +@@ -132,12 +132,15 @@ elseif ("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "aarch64" OR "${CMAKE_SYSTEM_PROCES + elseif ("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "x86") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DQD_ARCH_x86") + set(ARCH "x86") ++elseif ("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "riscv64") ++ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DQD_ARCH_riscv64") ++ set(ARCH "riscv64") + else() + message(FATAL_ERROR "Unknown processor type ${CMAKE_SYSTEM_PROCESSOR}") + endif() + set(HOST_ARCH ${ARCH} CACHE INTERNAL "Host arch") + +-if (LINUX AND CMAKE_SYSTEM_PROCESSOR STREQUAL "aarch64") ++if (LINUX AND CMAKE_SYSTEM_PROCESSOR MATCHES "^(aarch64|riscv64)$") + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -latomic") + set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -latomic") + endif() +diff --git a/quadrants/inc/archs.inc.h b/quadrants/inc/archs.inc.h +index 919673a..7b60fa6 100644 +--- a/quadrants/inc/archs.inc.h ++++ b/quadrants/inc/archs.inc.h +@@ -3,6 +3,7 @@ + // CPU archs + PER_ARCH(x64) // a.k.a. AMD64/x86_64 + PER_ARCH(arm64) // a.k.a. Aarch64, WIP ++PER_ARCH(riscv64) // RV64GC + PER_ARCH(js) // Javascript, N/A + PER_ARCH(python) // Python + +diff --git a/quadrants/program/extension.cpp b/quadrants/program/extension.cpp +index 9a51bc2..90cf6cc 100644 +--- a/quadrants/program/extension.cpp ++++ b/quadrants/program/extension.cpp +@@ -13,6 +13,9 @@ bool is_extension_supported(Arch arch, Extension ext) { + {Arch::arm64, + {Extension::sparse, Extension::quant, Extension::quant_basic, Extension::data64, Extension::adstack, + Extension::assertion, Extension::mesh}}, ++ {Arch::riscv64, ++ {Extension::sparse, Extension::quant, Extension::quant_basic, Extension::data64, Extension::adstack, ++ Extension::assertion, Extension::mesh}}, + {Arch::cuda, + {Extension::sparse, Extension::quant, Extension::quant_basic, Extension::data64, Extension::adstack, + Extension::bls, Extension::assertion, Extension::mesh}}, +diff --git a/quadrants/rhi/arch.cpp b/quadrants/rhi/arch.cpp +index b9a4822..db48549 100644 +--- a/quadrants/rhi/arch.cpp ++++ b/quadrants/rhi/arch.cpp +@@ -39,7 +39,8 @@ Arch arch_from_name(const std::string &arch_name) { + + // Assuming a processor is either a CPU or a GPU. DSP/TPUs not considered. + bool arch_is_cpu(Arch arch) { +- if (arch == Arch::x64 || arch == Arch::arm64 || arch == Arch::js || arch == Arch::python) { ++ if (arch == Arch::x64 || arch == Arch::arm64 || arch == Arch::riscv64 || arch == Arch::js || ++ arch == Arch::python) { + return true; + } else { + return false; +@@ -59,7 +60,8 @@ bool arch_is_metal(Arch arch) { + } + + bool arch_uses_llvm(Arch arch) { +- return (arch == Arch::x64 || arch == Arch::arm64 || arch == Arch::cuda || arch == Arch::amdgpu); ++ return (arch == Arch::x64 || arch == Arch::arm64 || arch == Arch::riscv64 || arch == Arch::cuda || ++ arch == Arch::amdgpu); + } + + bool arch_is_gpu(Arch arch) { +@@ -76,6 +78,9 @@ Arch host_arch() { + #endif + #if defined(QD_ARCH_ARM) + return Arch::arm64; ++#endif ++#if defined(QD_ARCH_riscv64) ++ return Arch::riscv64; + #endif + RHI_NOT_IMPLEMENTED + } +@@ -91,6 +96,8 @@ int default_simd_width(Arch arch) { + return 32; + } else if (arch == Arch::arm64) { + return 4; ++ } else if (arch == Arch::riscv64) { ++ return 4; + } else { + RHI_NOT_IMPLEMENTED; + return -1; +diff --git a/quadrants/runtime/llvm/adstack_lazy_claim/bound_eval.cpp b/quadrants/runtime/llvm/adstack_lazy_claim/bound_eval.cpp +index 0b62054..4849e62 100644 +--- a/quadrants/runtime/llvm/adstack_lazy_claim/bound_eval.cpp ++++ b/quadrants/runtime/llvm/adstack_lazy_claim/bound_eval.cpp +@@ -38,7 +38,7 @@ uint32_t LlvmRuntimeExecutor::publish_per_task_bound_count_cpu(std::size_t task_ + // Default to UINT32_MAX (no clamp); only override on a successful host evaluation. The codegen-emitted bounds clamp + // at the float LCA-block claim site stays inert when the slot holds UINT32_MAX, so this fall-through is a no-op that + // preserves the existing behaviour. +- if (config_.arch != Arch::x64 && config_.arch != Arch::arm64) { ++ if (config_.arch != Arch::x64 && config_.arch != Arch::arm64 && config_.arch != Arch::riscv64) { + return std::numeric_limits::max(); + } + if (!ad_stack.bound_expr.has_value()) { +diff --git a/quadrants/runtime/llvm/llvm_context.cpp b/quadrants/runtime/llvm/llvm_context.cpp +index d116503..ef7070c 100644 +--- a/quadrants/runtime/llvm/llvm_context.cpp ++++ b/quadrants/runtime/llvm/llvm_context.cpp +@@ -725,7 +725,7 @@ std::unique_ptr QuadrantsLLVMContext::module_from_file(const std:: + } + + // CPU-specific intrinsics +- if (arch_ == Arch::x64 || arch_ == Arch::arm64) { ++ if (arch_ == Arch::x64 || arch_ == Arch::arm64 || arch_ == Arch::riscv64) { + auto func = module->getFunction("cpu_clock_i64"); + if (func) { + func->deleteBody(); +diff --git a/quadrants/transforms/make_mesh_block_local.cpp b/quadrants/transforms/make_mesh_block_local.cpp +index 69d713f..60724b0 100644 +--- a/quadrants/transforms/make_mesh_block_local.cpp ++++ b/quadrants/transforms/make_mesh_block_local.cpp +@@ -110,7 +110,7 @@ void MakeMeshBlockLocal::replace_global_ptrs(SNode *snode) { + } + + // in the cpu backend, atomic op in body block could be demoted to non-atomic +- if (config_.arch != Arch::x64 && config_.arch != Arch::arm64) { ++ if (config_.arch != Arch::x64 && config_.arch != Arch::arm64 && config_.arch != Arch::riscv64) { + return; + } + std::vector atomic_ops; +@@ -144,7 +144,7 @@ Stmt *MakeMeshBlockLocal::create_xlogue(Stmt *start_val, + Stmt *idx = block_->push_back(mapping_data_type_); + [[maybe_unused]] Stmt *init_val = block_->push_back(idx, start_val); + Stmt *block_dim_val; +- if (config_.arch == Arch::x64 || config_.arch == Arch::arm64) { ++ if (config_.arch == Arch::x64 || config_.arch == Arch::arm64 || config_.arch == Arch::riscv64) { + block_dim_val = block_->push_back(TypedConstant(1)); + } else { + block_dim_val = block_->push_back(TypedConstant{offload_->block_dim}); +@@ -272,7 +272,7 @@ void MakeMeshBlockLocal::fetch_mapping( + std::function)> mapping_callback_handler, + std::function attr_callback_handler) { + Stmt *thread_idx_stmt; +- if (config_.arch == Arch::x64 || config_.arch == Arch::arm64) { ++ if (config_.arch == Arch::x64 || config_.arch == Arch::arm64 || config_.arch == Arch::riscv64) { + thread_idx_stmt = block_->push_back(TypedConstant(0)); + } else { + thread_idx_stmt = block_->push_back(offload_); // Equivalent to CUDA threadIdx diff --git a/patches/quadrants/1.3.3/0002-CI-support-riscv64-in-the-LLVM-sccache-manylinux-build-scripts.patch b/patches/quadrants/1.3.3/0002-CI-support-riscv64-in-the-LLVM-sccache-manylinux-build-scripts.patch new file mode 100644 index 00000000000..9f267451d12 --- /dev/null +++ b/patches/quadrants/1.3.3/0002-CI-support-riscv64-in-the-LLVM-sccache-manylinux-build-scripts.patch @@ -0,0 +1,112 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: RISE Project CI +Date: Thu, 15 Oct 2026 00:05:00 +0000 +Subject: [PATCH] CI: support riscv64 in the LLVM/sccache/manylinux build + scripts + +quadrants-sdk-builds (the GitHub release bucket .github/workflows/ +scripts/qd_build/llvm.py downloads a prebuilt LLVM 22.1.0 from) ships +only linux-x86_64/linux-aarch64/macos-arm64/windows-amd64 archives, and +mozilla/sccache's v0.10.0 release has no riscv64 binary either. On +riscv64, setup_llvm() now expects the caller to build LLVM+clang 22.1.0 +itself and export LLVM_DIR before build.py runs, and setup_sccache() +skips the compiler-launcher wrapping instead of trying to download a +binary that doesn't exist (CMakeLists.txt's own find_program(ccache) +still caches the per-interpreter rebuilds when the image has ccache +installed). + +scripts_new/manylinux_wheel/2_build.sh's PLATFORM allowlist rejects +every arch but x86_64/aarch64; add riscv64. There is no riscv64 +CUDA/AMDGPU/Vulkan backend (the LLVM CPU JIT is the only backend +riscv64 has), so turn those three off instead of upstream's CI default +of on, and skip QD_BUILD_TESTS (a CPU-only riscv64 leg doesn't need +the GPU-aware cpp test binary) and the gcc-toolset-14 include-path +workaround (that SCL package is x86_64/aarch64-only on the manylinux +images; riscv64 needs no such workaround since it only ever uses the +clang we ourselves just built). + +Upstream-Status: Inappropriate [no riscv64 LLVM/sccache release exists to point at; this wires our own from-source riscv64 LLVM build in instead] + +Signed-off-by: RISE Project CI +--- + .github/workflows/scripts/qd_build/llvm.py | 7 +++++++ + .github/workflows/scripts/qd_build/sccache.py | 8 ++++++++ + .../scripts_new/manylinux_wheel/2_build.sh | 20 ++++++++++++------- + 3 files changed, 28 insertions(+), 7 deletions(-) + +diff --git a/.github/workflows/scripts/qd_build/llvm.py b/.github/workflows/scripts/qd_build/llvm.py +index dbb9891..487c487 100644 +--- a/.github/workflows/scripts/qd_build/llvm.py ++++ b/.github/workflows/scripts/qd_build/llvm.py +@@ -28,6 +28,13 @@ def setup_llvm() -> str: + ) + + match (u.system, u.machine): ++ case ("Linux", "riscv64"): ++ # quadrants-sdk-builds ships no riscv64 LLVM; the caller builds LLVM itself and ++ # points LLVM_DIR at the install prefix before this runs. ++ out = os.environ.get("LLVM_DIR") ++ if not out: ++ raise RuntimeError("LLVM_DIR must be set to a prebuilt LLVM install on riscv64") ++ return out + case ("Linux", "x86_64"): + out = get_cache_home() / f"llvm-{llvm_version}-x86-{build_version}" + url = release_url_template.format(platform="linux-x86_64") +diff --git a/.github/workflows/scripts/qd_build/sccache.py b/.github/workflows/scripts/qd_build/sccache.py +index b5561c7..cce2b1e 100644 +--- a/.github/workflows/scripts/qd_build/sccache.py ++++ b/.github/workflows/scripts/qd_build/sccache.py +@@ -30,6 +30,14 @@ def setup_sccache() -> Command: + else: + raise RuntimeError(f"Unsupported platform: {u.system} {u.machine}") + ++ if (u.system, u.machine) == ("Linux", "riscv64"): ++ # mozilla/sccache publishes no riscv64 binary (v0.10.0 release assets checked). Skip the ++ # compiler-launcher wrapping (entry.py's action_wheel still calls the returned command ++ # with --start-server / -s, so it must accept and ignore arbitrary args) and let ccache ++ # (installed from the manylinux image, found by CMakeLists.txt's own find_program) cache ++ # the per-interpreter rebuilds instead. ++ return sh.bake("true") ++ + if not exe.exists(): + if (u.system, u.machine) == ("Linux", "x86_64"): + url = "https://github.com/mozilla/sccache/releases/download/v0.10.0/sccache-v0.10.0-x86_64-unknown-linux-musl.tar.gz" +diff --git a/.github/workflows/scripts_new/manylinux_wheel/2_build.sh b/.github/workflows/scripts_new/manylinux_wheel/2_build.sh +index 3c030bb..3561a10 100644 +--- a/.github/workflows/scripts_new/manylinux_wheel/2_build.sh ++++ b/.github/workflows/scripts_new/manylinux_wheel/2_build.sh +@@ -3,7 +3,7 @@ + set -ex + + PLATFORM=$(uname -m) +-if [[ ! "$PLATFORM" =~ ^(x86_64|aarch64)$ ]]; then ++if [[ ! "$PLATFORM" =~ ^(x86_64|aarch64|riscv64)$ ]]; then + echo "Unsupported architecture: $PLATFORM" + exit 1 + fi +@@ -18,13 +18,19 @@ echo "Detected platform: $PLATFORM" + # Add Taichi LLVM toolchain to PATH + export PATH="$PWD/taichi-llvm-15.0.7-linux-${PLATFORM}/bin:$PATH" + +-# Taichi build options +-export CMAKE_ARGS="-DQD_WITH_VULKAN:BOOL=ON -DQD_WITH_CUDA:BOOL=ON -DQD_WITH_AMDGPU:BOOL=ON -DQD_BUILD_TESTS:BOOL=ON" ++if [[ "$PLATFORM" == "riscv64" ]]; then ++ # No riscv64 CUDA/AMDGPU/Vulkan backend exists; the LLVM CPU JIT is the only one riscv64 ++ # needs (gotcha "Add a riscv64 CPU arch" patch). ++ export CMAKE_ARGS="-DQD_WITH_VULKAN:BOOL=OFF -DQD_WITH_CUDA:BOOL=OFF -DQD_WITH_AMDGPU:BOOL=OFF -DQD_BUILD_TESTS:BOOL=OFF" ++else ++ # Taichi build options ++ export CMAKE_ARGS="-DQD_WITH_VULKAN:BOOL=ON -DQD_WITH_CUDA:BOOL=ON -DQD_WITH_AMDGPU:BOOL=ON -DQD_BUILD_TESTS:BOOL=ON" + +-# GCC toolset include paths +-inc_base="/opt/rh/gcc-toolset-14/root/usr/include/c++/14" +-extra="$inc_base:$inc_base/${PLATFORM}-redhat-linux:$inc_base/backward" ++ # GCC toolset include paths ++ inc_base="/opt/rh/gcc-toolset-14/root/usr/include/c++/14" ++ extra="$inc_base:$inc_base/${PLATFORM}-redhat-linux:$inc_base/backward" + +-export CPLUS_INCLUDE_PATH="${CPLUS_INCLUDE_PATH:+$CPLUS_INCLUDE_PATH:}$extra" ++ export CPLUS_INCLUDE_PATH="${CPLUS_INCLUDE_PATH:+$CPLUS_INCLUDE_PATH:}$extra" ++fi + + ./build.py wheel diff --git a/patches/quadrants/1.3.3/0003-CI-trim-riscv64-dev-group-install-and-drop-submodule-reinit.patch b/patches/quadrants/1.3.3/0003-CI-trim-riscv64-dev-group-install-and-drop-submodule-reinit.patch new file mode 100644 index 00000000000..19469741e34 --- /dev/null +++ b/patches/quadrants/1.3.3/0003-CI-trim-riscv64-dev-group-install-and-drop-submodule-reinit.patch @@ -0,0 +1,68 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: RISE Project CI +Date: Thu, 15 Oct 2026 00:10:00 +0000 +Subject: [PATCH] CI: trim riscv64's dev-group install and drop its submodule + re-init + +pyproject.toml's dev dependency group (installed wholesale by +1_prerequisites.sh) pulls in pyright, which ships no riscv64 wheel and +has no sdist to fall back to (it wraps a prebuilt Node binary per +platform) -- `pip install --group dev` has no partial-success mode, so +one unresolvable package fails the whole install. On riscv64, install +only what build.py's `pip wheel --no-build-isolation` actually needs: +build-system.requires (scikit-build-core, nanobind, numpy, +setuptools_scm), the cmake/ninja it drives them with, and +psutil/requests (qd_build's own non-stdlib imports). Install ccache +too: setup_sccache() (patched earlier) no-ops on riscv64, and +CMakeLists.txt's own find_program(ccache) is what caches the +per-interpreter rebuilds instead. + +The hardcoded `git config --global --add safe.directory +/__w/quadrants/quadrants` assumes upstream's own checkout path; our +workflow checks quadrants out under python-wheels' own job workspace, +not /__w/quadrants/quadrants, and actions/checkout already ran with +submodules: recursive, so the follow-up `git submodule update` is +both redundant and pointed at a path that doesn't exist here. Skip +both on riscv64. + +Upstream-Status: Inappropriate [riscv64 has no pyright wheel, and our workflow checks the repo out at a different path than upstream's own CI does] + +Signed-off-by: RISE Project CI +--- + .../manylinux_wheel/1_prerequisites.sh | 21 +++++++++++++++---- + 1 file changed, 17 insertions(+), 4 deletions(-) + +diff --git a/.github/workflows/scripts_new/manylinux_wheel/1_prerequisites.sh b/.github/workflows/scripts_new/manylinux_wheel/1_prerequisites.sh +index 03ca845..76157e2 100644 +--- a/.github/workflows/scripts_new/manylinux_wheel/1_prerequisites.sh ++++ b/.github/workflows/scripts_new/manylinux_wheel/1_prerequisites.sh +@@ -3,12 +3,25 @@ + set -ex + + pip install -U pip +-pip install --group dev ++if [[ "$(uname -m)" == "riscv64" ]]; then ++ # --group dev also pulls pyright, which ships no riscv64 wheel and no sdist to fall back ++ # to (it wraps a prebuilt Node binary); install only what `pip wheel --no-build-isolation` ++ # below actually needs: build.py's own [build-system].requires, plus the cmake/ninja it ++ # drives them with, plus psutil/requests (qd_build's own non-stdlib imports). ++ pip install "cmake<4.0.0" ninja "nanobind>=2.0.0,<2.14.0" "scikit-build-core>=0.10" \ ++ "setuptools_scm>=6.0" "numpy>=2.0.0" psutil requests ++ yum install -y ccache # setup_sccache() no-ops on riscv64; CMakeLists.txt's own ++ # find_program(ccache) picks this up as the compiler launcher instead. ++else ++ pip install --group dev ++fi + + yum install -y git wget +-# Note: following depends on the name of the repo: +-git config --global --add safe.directory /__w/quadrants/quadrants +-git submodule update --init --jobs 2 ++if [[ "$(uname -m)" != "riscv64" ]]; then ++ # Note: following depends on the name of the repo: ++ git config --global --add safe.directory /__w/quadrants/quadrants ++ git submodule update --init --jobs 2 ++fi + + LLVM_DIR=$(python download_llvm.py | tail -n 1) + export PATH=${LLVM_DIR}/bin:$PATH