diff --git a/CMakeLists.txt b/CMakeLists.txt index f83b0ae..b3d1485 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -17,7 +17,7 @@ endif() # Set broad CUDA GPU architecture support (Turing, Ampere, Ada Lovelace, Hopper/Blackwell) if(NOT DEFINED CMAKE_CUDA_ARCHITECTURES) - set(CMAKE_CUDA_ARCHITECTURES "75;80;86;89") + set(CMAKE_CUDA_ARCHITECTURES "75;80;86") endif() include_directories( diff --git a/Makefile b/Makefile index 5cec1ee..2bc22c2 100644 --- a/Makefile +++ b/Makefile @@ -18,6 +18,9 @@ all: $(SHARED_LIB) $(STATIC_LIB) $(BENCH_BIN) $(BUILD_DIR)/gpu_offset.o: src/gpu_offset.cu include/gpu_offset.h src/cpu_offset.h src/vectorizer.h | $(BUILD_DIR) $(NVCC) $(NVCCFLAGS) -c $< -o $@ +$(BUILD_DIR)/gpu_sdf.o: src/gpu_sdf.cu include/gpu_sdf.h include/gpu_offset.h src/vectorizer.h | $(BUILD_DIR) + $(NVCC) $(NVCCFLAGS) -c $< -o $@ + $(BUILD_DIR)/cpu_offset.o: src/cpu_offset.cpp src/cpu_offset.h src/vectorizer.h include/gpu_offset.h | $(BUILD_DIR) $(CXX) $(CXXFLAGS) -c $< -o $@ @@ -27,10 +30,10 @@ $(BUILD_DIR)/stl_slicer.o: src/stl_slicer.cpp src/stl_slicer.h include/gpu_offse $(BUILD_DIR)/main_bench.o: src/main_bench.cpp src/stl_slicer.h include/gpu_offset.h | $(BUILD_DIR) $(CXX) $(CXXFLAGS) -c $< -o $@ -$(SHARED_LIB): $(BUILD_DIR)/gpu_offset.o $(BUILD_DIR)/cpu_offset.o | $(LIB_DIR) +$(SHARED_LIB): $(BUILD_DIR)/gpu_offset.o $(BUILD_DIR)/gpu_sdf.o $(BUILD_DIR)/cpu_offset.o | $(LIB_DIR) $(NVCC) -shared -arch=$(ARCH) -o $@ $^ -lcudart -$(STATIC_LIB): $(BUILD_DIR)/gpu_offset.o $(BUILD_DIR)/cpu_offset.o | $(LIB_DIR) +$(STATIC_LIB): $(BUILD_DIR)/gpu_offset.o $(BUILD_DIR)/gpu_sdf.o $(BUILD_DIR)/cpu_offset.o | $(LIB_DIR) ar rcs $@ $^ $(BENCH_BIN): $(BUILD_DIR)/main_bench.o $(BUILD_DIR)/stl_slicer.o $(SHARED_LIB) | $(BIN_DIR) diff --git a/build.sh b/build.sh new file mode 100755 index 0000000..ce82543 --- /dev/null +++ b/build.sh @@ -0,0 +1,212 @@ +#!/usr/bin/env bash +# ============================================================================== +# CUDASlicer Automated Build & Installation Script +# ============================================================================== +# Supports Linux and WSL environments with CUDA GPU acceleration. +# +# Usage: +# ./build.sh [OPTIONS] +# +# Options: +# --clean Clean all build artifacts before building +# --test Run test suite and benchmarks after building +# --install Install Python package into active Python environment +# --c-only Build only standalone C/C++ libraries and binaries +# --debug Build with Debug symbols (-g / -O0) +# --release Build with Release optimizations (-O3, default) +# -j, --jobs N Number of parallel compilation jobs (default: all cores) +# -h, --help Show this help message +# ============================================================================== + +set -e + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +cd "${SCRIPT_DIR}" + +# Color formatting +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +BLUE='\033[0;34m' +CYAN='\033[0;36m' +BOLD='\033[1m' +NC='\033[0m' # No Color + +# Default parameters +DO_CLEAN=false +DO_TEST=false +DO_INSTALL=false +DO_WHEEL=false +BUILD_TYPE="Release" +BUILD_C_ONLY=false +NUM_JOBS=$(nproc 2>/dev/null || sysctl -n hw.ncpu 2>/dev/null || echo 4) + +# Parse command line arguments +while [[ $# -gt 0 ]]; do + case "$1" in + --clean) + DO_CLEAN=true + shift + ;; + --test) + DO_TEST=true + shift + ;; + --install) + DO_INSTALL=true + shift + ;; + --wheel) + DO_WHEEL=true + shift + ;; + --c-only) + BUILD_C_ONLY=true + shift + ;; + --debug) + BUILD_TYPE="Debug" + shift + ;; + --release) + BUILD_TYPE="Release" + shift + ;; + -j|--jobs) + NUM_JOBS="$2" + shift 2 + ;; + -h|--help) + echo "CUDASlicer Build Script" + echo "Usage: ./build.sh [OPTIONS]" + echo "" + echo "Options:" + echo " --clean Remove build directory, libraries, and binaries first" + echo " --test Run unit tests and benchmarks upon completion" + echo " --install Install Python package into active environment via pip" + echo " --wheel Build standalone Python .whl distribution package in dist/" + echo " --c-only Build only C/C++ libraries (lib/ and bin/)" + echo " --debug Compile with Debug flags" + echo " --release Compile with Release flags (default)" + echo " -j, --jobs N Parallel build jobs (default: ${NUM_JOBS})" + echo " -h, --help Show this help message" + exit 0 + ;; + *) + echo -e "${RED}[Error] Unknown option: $1${NC}" + echo "Run './build.sh --help' for usage." + exit 1 + ;; + esac +done + +echo -e "${BOLD}${CYAN}========================================================================${NC}" +echo -e "${BOLD}${CYAN} CUDASlicer: High-Performance GPU Slicing & CSG Engine Build${NC}" +echo -e "${BOLD}${CYAN}========================================================================${NC}" + +# Check for required tools +echo -e "\n${BLUE}[1/5] Checking Build Environment & Dependencies...${NC}" + +if command -v nvcc &>/dev/null; then + NVCC_VERSION=$(nvcc --version | grep "release" | awk '{print $5}' | tr -d ',') + echo -e " * NVIDIA CUDA Compiler (NVCC): ${GREEN}Found (v${NVCC_VERSION})${NC}" +else + echo -e " * NVIDIA CUDA Compiler (NVCC): ${YELLOW}Not Found (CPU fallback only)${NC}" +fi + +if command -v cmake &>/dev/null; then + CMAKE_VERSION=$(cmake --version | head -n 1 | awk '{print $3}') + echo -e " * CMake: ${GREEN}Found (v${CMAKE_VERSION})${NC}" +else + echo -e " * CMake: ${RED}Missing! Please install cmake (sudo apt install cmake)${NC}" + exit 1 +fi + +if command -v python3 &>/dev/null; then + PY_VERSION=$(python3 -c "import sys; print(f'{sys.version_info.major}.{sys.version_info.minor}.{sys.version_info.micro}')") + echo -e " * Python: ${GREEN}Found (v${PY_VERSION})${NC}" +else + echo -e " * Python: ${YELLOW}python3 not found in PATH${NC}" +fi + +# Detect GPU Architecture if available +CUDA_ARCHS="75;80;86" +if command -v nvidia-smi &>/dev/null; then + GPU_NAME=$(nvidia-smi --query-gpu=name --format=csv,noheader 2>/dev/null | head -n 1 || true) + if [[ -n "${GPU_NAME}" ]]; then + echo -e " * Detected GPU Device: ${GREEN}${GPU_NAME}${NC}" + fi +fi + +# Handle clean +if [ "$DO_CLEAN" = true ]; then + echo -e "\n${BLUE}[2/5] Cleaning previous build artifacts...${NC}" + rm -rf build/ bin/ lib/ dist/ python/cudaslicer/*.so python/cudaslicer.egg-info + echo -e " * ${GREEN}Clean complete.${NC}" +else + echo -e "\n${BLUE}[2/5] Skipping clean (incremental build). Pass --clean to reset.${NC}" +fi + +# Configure with CMake +echo -e "\n${BLUE}[3/5] Configuring CMake (${BUILD_TYPE})...${NC}" +mkdir -p build + +CMAKE_EXTRA_ARGS=() +if [ "$BUILD_C_ONLY" = true ]; then + CMAKE_EXTRA_ARGS+=("-DBUILD_PYTHON_BINDINGS=OFF") +fi + +cmake -B build -S . \ + -DCMAKE_BUILD_TYPE="${BUILD_TYPE}" \ + -DCMAKE_CUDA_ARCHITECTURES="${CUDA_ARCHS}" \ + "${CMAKE_EXTRA_ARGS[@]}" + +# Build target binaries +echo -e "\n${BLUE}[4/5] Compiling targets with ${NUM_JOBS} parallel workers...${NC}" +cmake --build build --config "${BUILD_TYPE}" -j "${NUM_JOBS}" + +echo -e "\n${GREEN}[SUCCESS] Compilation finished successfully!${NC}" +echo -e " * Shared Library: ${CYAN}lib/libcudaslicer_offset.so${NC}" +echo -e " * Static Library: ${CYAN}lib/libcudaslicer_offset.a${NC}" +echo -e " * Benchmark Exec: ${CYAN}bin/gpu_slicer_c_bench${NC}" +if [ "$BUILD_C_ONLY" = false ]; then + echo -e " * Python Backend: ${CYAN}python/cudaslicer/_cudaslicer_backend*.so${NC}" +fi + +# Optional Python Wheel Package Build +if [ "$DO_WHEEL" = true ]; then + echo -e "\n${BLUE}[Optional] Building Python Wheel distribution (.whl)...${NC}" + mkdir -p dist + python3 setup.py bdist_wheel + WHL_FILE=$(ls -t dist/*.whl 2>/dev/null | head -n 1 || true) + if [ -n "${WHL_FILE}" ]; then + echo -e " * ${GREEN}Built Wheel Package: ${CYAN}${WHL_FILE}${NC}" + fi +fi + +# Optional Python Installation +if [ "$DO_INSTALL" = true ]; then + echo -e "\n${BLUE}[Optional] Installing Python package in editable mode...${NC}" + pip install -e . --no-build-isolation + echo -e " * ${GREEN}Package 'cudaslicer' installed into current environment.${NC}" +fi + +# Optional Tests & Benchmarks +if [ "$DO_TEST" = true ]; then + echo -e "\n${BLUE}[5/5] Running Test Suite & Benchmarks...${NC}" + + echo -e "\n--- [A] Running Python GPU SDF & CSG Unit Tests ---" + python3 tests_and_tools/test_gpu_sdf.py + + echo -e "\n--- [B] Running GPU SDF CSG Example Pipeline ---" + python3 examples/gpu_sdf_csg_example.py + + echo -e "\n--- [C] Running C++ Slicing Benchmark ---" + if [ -f "benchy.stl" ]; then + ./bin/gpu_slicer_c_bench benchy.stl + fi +fi + +echo -e "\n${BOLD}${GREEN}========================================================================${NC}" +echo -e "${BOLD}${GREEN} Build completed successfully!${NC}" +echo -e "${BOLD}${GREEN}========================================================================${NC}\n" diff --git a/pyproject.toml b/pyproject.toml index 718ec32..22b8a92 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,8 +4,8 @@ build-backend = "setuptools.build_meta" [project] name = "cudaslicer" -version = "1.0.0" -description = "GPU-Accelerated 2D/3D Slicing & Polygon Offsetting Library for Linux & Windows" +version = "1.1.0" +description = "GPU-Accelerated 2D/3D Slicing, Signed Distance Fields (SDF) & Polygon Offsetting Library" readme = "README.md" requires-python = ">=3.8" dependencies = [ diff --git a/setup.py b/setup.py index 381c82a..0bc7ead 100644 --- a/setup.py +++ b/setup.py @@ -39,7 +39,7 @@ class CMakeBuild(build_ext): setup( name="cudaslicer", - version="1.0.0", + version="1.1.0", author="CUDA Slicer Team", description="GPU-Accelerated 2D/3D Slicing & Polygon Offsetting Library", long_description=open("README.md").read() if os.path.exists("README.md") else "",