diff --git a/recipes/fvdb-core/build.sh b/recipes/fvdb-core/build.sh new file mode 100644 index 0000000000000..4322e6d63a03f --- /dev/null +++ b/recipes/fvdb-core/build.sh @@ -0,0 +1,79 @@ +#!/bin/bash + +setup_parallel_build_jobs() { + # Calculate the optimal number of parallel build jobs based on available RAM + RAM_GB=$(free -g | awk '/^Mem:/{print $7}') + if [ -z "$RAM_GB" ]; then + echo "Error: Unable to determine available RAM" + exit 1 + fi + JOB_RAM_GB=3 + + # Get number of processors + NPROC=$(nproc) + + # count the number of ';' in the TORCH_CUDA_ARCH_LIST + NUM_ARCH=$(echo "$TORCH_CUDA_ARCH_LIST" | tr ';' '\n' | wc -l) + if [ "$NUM_ARCH" -lt 1 ]; then + NUM_ARCH=1 + fi + NVCC_THREADS=$NUM_ARCH + + # Check if we have enough RAM for even one job with full NVCC_THREADS + # Requirement: JOB_RAM_GB * NVCC_THREADS + MIN_RAM_REQUIRED=$((JOB_RAM_GB * NVCC_THREADS)) + + if [ "$RAM_GB" -lt "$MIN_RAM_REQUIRED" ]; then + NVCC_THREADS=1 + fi + + # Limit NVCC_THREADS to NPROC to ensure we don't oversubscribe + if [ "$NVCC_THREADS" -gt "$NPROC" ]; then + NVCC_THREADS=$NPROC + fi + + # Determine max jobs based on CPU: + # We want CMAKE_BUILD_PARALLEL_LEVEL * NVCC_THREADS <= NPROC + MAX_JOBS_CPU=$((NPROC / NVCC_THREADS)) + + # Determine max jobs based on RAM: + # Assume each job requires JOB_RAM_GB * NVCC_THREADS + MAX_JOBS_RAM=$((RAM_GB / (JOB_RAM_GB * NVCC_THREADS))) + + # Take the minimum + PARALLEL_JOBS=$((MAX_JOBS_CPU < MAX_JOBS_RAM ? MAX_JOBS_CPU : MAX_JOBS_RAM)) + + # Ensure at least 1 job + if [ "$PARALLEL_JOBS" -lt 1 ]; then + PARALLEL_JOBS=1 + fi + + # if CMAKE_BUILD_PARALLEL_LEVEL is set, use that + if [ -n "$CMAKE_BUILD_PARALLEL_LEVEL" ]; then + echo "Using CMAKE_BUILD_PARALLEL_LEVEL=$CMAKE_BUILD_PARALLEL_LEVEL" + else + + CMAKE_BUILD_PARALLEL_LEVEL=$PARALLEL_JOBS + + echo "Setting nvcc --threads to $NVCC_THREADS based on the number of CUDA architectures ($NUM_ARCH)" + echo "Setting CMAKE_BUILD_PARALLEL_LEVEL to $CMAKE_BUILD_PARALLEL_LEVEL" + echo " Constraint: Total Threads ($((CMAKE_BUILD_PARALLEL_LEVEL * NVCC_THREADS))) <= NPROC ($NPROC)" + echo " Constraint: Estimated RAM ($((CMAKE_BUILD_PARALLEL_LEVEL * NVCC_THREADS * JOB_RAM_GB))) GB <= Available RAM ($RAM_GB GB)" + + export CMAKE_BUILD_PARALLEL_LEVEL + export NVCC_THREADS + fi +} + + +setup_parallel_build_jobs +export CMAKE_GENERATOR=Ninja +# GCC 14 false positive: -Wstringop-overflow in NanoVDB headers with deep template inlining at -O3 +# See: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=118817 +export CXXFLAGS="${CXXFLAGS} -Wno-error=stringop-overflow" +$PYTHON -m pip install \ + --no-deps \ + --no-build-isolation \ + -vv \ + -C 'skbuild.ninja.make-fallback=false' \ + . diff --git a/recipes/fvdb-core/meta.yaml b/recipes/fvdb-core/meta.yaml new file mode 100644 index 0000000000000..a274d26d71792 --- /dev/null +++ b/recipes/fvdb-core/meta.yaml @@ -0,0 +1,88 @@ +{% set name = "fvdb-core" %} +{% set version = "0.3.0" %} +{% set torch_proc_type = "cuda" if cuda_compiler_version != "None" else "cpu" %} + +package: + name: {{ name }} + version: {{ version }} + +source: + url: https://pypi.org/packages/source/{{ name[0] }}/{{ name }}/fvdb_core-{{ version }}.tar.gz + sha256: f6ec0d5e6a2b601632720ed0be8aa7c8ba6f2d9bd63fac477cef2cfd088b5f16 + +build: + skip: true # [cuda_compiler_version == "None" or win or osx or py!=312] + number: 0 + script_env: + - TORCH_CUDA_ARCH_LIST=7.5;8.0;9.0;10.0;12.0+PTX + + +requirements: + build: + - python # [build_platform != target_platform] + - cross-python_{{ target_platform }} # [build_platform != target_platform] + - {{ stdlib('c') }} + - {{ compiler('c') }} + - {{ compiler('cxx') }} + - {{ compiler('cuda') }} + - cuda-version {{ cuda_compiler_version }} + - cuda-command-line-tools + - cmake >=3.25 + - ninja + - pkg-config + - git + - procps-ng # provides 'free' + - coreutils # provides 'nproc', 'awk', etc. + host: + - python + - scikit-build-core + - pip + - pytorch + - pytorch =*=*{{ torch_proc_type }}* + - numpy + - pybind11 >=2.13 + - gitpython + - cuda-version {{ cuda_compiler_version }} + - cuda-cudart-dev + - cuda-nvrtc-dev + - cuda-nvtx-dev + - libcublas-dev + - libcudnn-dev + - libcusolver-dev + - libcusparse-dev + - libpng + - zlib + run: + - python + - pytorch + - pytorch =*=*{{ torch_proc_type }}* + - {{ pin_compatible('numpy') }} + - cuda-version {{ cuda_compiler_version }} + - gitpython + - git + - parameterized + +test: + commands: + - pip check + - python run_test.py + source_files: + - tests/ + requires: + - pip + - pytest + - parameterized + - git + +about: + home: https://www.openvdb.org/ + license: Apache-2.0 + license_family: Apache + license_file: LICENSE + summary: "A deep learning framework for sparse, large-scale, high-performance spatial intelligence" + doc_url: https://fvdb.ai/ + dev_url: https://github.com/openvdb/fvdb-core + +extra: + recipe-maintainers: + - swahtz diff --git a/recipes/fvdb-core/run_test.py b/recipes/fvdb-core/run_test.py new file mode 100644 index 0000000000000..14ae0831c35e8 --- /dev/null +++ b/recipes/fvdb-core/run_test.py @@ -0,0 +1,32 @@ +import sys + +# Check for fvdb (without importing) +import pkgutil +pkgutil.find_loader("fvdb") + +# Try to import fvdb +try: + import fvdb +except ImportError: + print("Failed to import fvdb. Exiting without running tests.") + sys.exit(0) + +print(f"fvdb {fvdb.__version__} imported successfully") + +# Check for GPU availability +import torch + +if not torch.cuda.is_available(): + print("No CUDA GPU available. Exiting without running fvdb's tests.") + sys.exit(0) + +print(f"CUDA is available: {torch.cuda.get_device_name(0)}") + +# Run fvdb's test suite +# Ignore tests with unavailable optional dependencies (OpenImageIO, point_cloud_utils, torch_scatter) +import pytest +sys.exit(pytest.main([ + "tests/unit", "-v", "--tb=short", + "--ignore=tests/unit/test_gsplat.py", + "--ignore=tests/unit/test_jagged_tensor.py", +]))