diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile new file mode 100644 index 0000000..155bd8c --- /dev/null +++ b/.devcontainer/Dockerfile @@ -0,0 +1,170 @@ +# Stage 1: base image +FROM nvidia/cuda:12.8.0-devel-ubuntu24.04 AS base +ENV DEBIAN_FRONTEND=noninteractive + +# set labels +LABEL version="1.0" +LABEL description="DEM-Engine Development and Production Environment" +ARG CUDA_VERSION=12.8.0 +ARG UBUNTU_VERSION=24.04 +ARG CMAKE_BUILD_TYPE=Release +ARG BUILD_JOBS=0 + +# basic dependencies +RUN apt-get update && apt-get install -y --no-install-recommends \ + build-essential \ + cmake \ + ninja-build \ + git \ + ca-certificates \ + && rm -rf /var/lib/apt/lists/* + +# CUDA environment variables +ENV CUDA_HOME=/usr/local/cuda-12.8 +ENV LD_LIBRARY_PATH=${CUDA_HOME}/lib64${LD_LIBRARY_PATH:+:${LD_LIBRARY_PATH}} +ENV CPATH=/usr/local/cuda-12.8/targets/x86_64-linux/include +ENV PATH=/usr/local/cuda-12.8/bin:/usr/local/cuda-12.8/lib64/cmake:${CUDA_HOME}/bin:${PATH} + +# Stage 2: dependencies +FROM base AS deps + +# necessary libraries +RUN apt-get update && apt-get install -y --no-install-recommends \ + libeigen3-dev \ + libboost-dev \ + libboost-filesystem-dev \ + libboost-system-dev \ + libboost-thread-dev \ + && rm -rf /var/lib/apt/lists/* + +# Stage 3: CUDA headers preparation +FROM base AS cuda-headers + +# copy CUDA headers from the base image +RUN mkdir -p /cuda-headers && \ + cd /usr/local/cuda-12.8/include && \ + cp -r \ + cuda.h \ + cuda_runtime*.h \ + curand*.h \ + device_*.h \ + driver_types.h \ + vector_types.h \ + library_types.h \ + surface_types.h \ + texture_types.h \ + channel_descriptor.h \ + builtin_types.h \ + cuda_fp16.h \ + cuda_fp16.hpp \ + sm_*.h \ + cuda_device_runtime_api.h \ + cuda_texture_types.h \ + cuda_surface_types.h \ + crt \ + /cuda-headers/ + +# Stage 4: build environment +FROM deps AS builder +WORKDIR /workspace/DEM-Engine + +# copy CMake configuration files +COPY CMakeLists.txt /workspace/DEM-Engine/ +COPY cmake /workspace/DEM-Engine/cmake + +# copy source code +COPY src /workspace/DEM-Engine/src +COPY data /workspace/DEM-Engine/data +COPY thirdparty /workspace/DEM-Engine/thirdparty + +# build the project +RUN mkdir build && cd build && \ + cmake -G Ninja \ + -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE:-Release} \ + .. && \ + ninja -j${BUILD_JOBS:-$(nproc)} + +# Stage 5: runtime image +FROM nvidia/cuda:12.8.0-runtime-ubuntu24.04 AS runtime-base +ENV DEBIAN_FRONTEND=noninteractive + +# necessary runtime libraries +RUN apt-get update && apt-get install -y --no-install-recommends \ + libgomp1 \ + libboost-filesystem1.83.0 \ + libboost-system1.83.0 \ + libboost-thread1.83.0 \ + && rm -rf /var/lib/apt/lists/* + +# CUDA environment variables for runtime +ENV CUDA_HOME=/usr/local/cuda-12.8 +ENV LD_LIBRARY_PATH=${CUDA_HOME}/lib64${LD_LIBRARY_PATH:+:${LD_LIBRARY_PATH}} + +# Stage 6: production image +FROM runtime-base AS production + +# copy CUDA headers from the cuda-headers stage +COPY --from=cuda-headers /cuda-headers /usr/local/cuda-12.8/include + +# copy jitify library +COPY --from=builder /workspace/DEM-Engine/thirdparty /workspace/DEM-Engine/thirdparty + +# create directory structure +RUN mkdir -p /workspace/DEM-Engine/build/output \ + /workspace/DEM-Engine/output + +COPY --from=base /usr/local/cuda-12.8/include /usr/local/cuda-12.8/include + +# copy files from building stage +COPY --from=builder /workspace/DEM-Engine/build/bin /workspace/DEM-Engine/build/bin +COPY --from=builder /workspace/DEM-Engine/build/DEM /workspace/DEM-Engine/build/DEM +COPY --from=builder /workspace/DEM-Engine/build/kernel /workspace/DEM-Engine/build/kernel + +# set working directory +WORKDIR /workspace/DEM-Engine + +# create a wrapper script to ensure correct working directory +RUN echo '#!/bin/bash\ncd /workspace/DEM-Engine\nexec "$@"' > /usr/local/bin/dem-wrapper.sh && \ + chmod +x /usr/local/bin/dem-wrapper.sh + +# set environment variables +ENV CUDA_PATH=/usr/local/cuda-12.8 +ENV CUDA_INC_PATH=/usr/local/cuda-12.8/include +ENV JITIFY_PATH=/workspace/DEM-Engine/thirdparty/jitify +ENV PATH=/workspace/DEM-Engine/build/bin:${PATH} +ENV OMP_NUM_THREADS=8 + +ENTRYPOINT ["/usr/local/bin/dem-wrapper.sh"] +CMD ["/bin/bash"] + +# Stage 7: development image +FROM deps AS development + +# debug and development tools +RUN apt-get update && apt-get install -y --no-install-recommends \ + gdb \ + valgrind \ + vim \ + htop \ + curl \ + wget \ + python3-minimal \ + python3-pip \ + python3-numpy \ + python3-matplotlib \ + python3-pandas \ + python3-h5py \ + && rm -rf /var/lib/apt/lists/* + +# copy source code +COPY . /workspace/DEM-Engine +WORKDIR /workspace/DEM-Engine + +# create build directory +RUN mkdir -p build + +# set development environment variables +ENV CMAKE_BUILD_TYPE=Debug +ENV OMP_NUM_THREADS=8 + +CMD ["/bin/bash"] diff --git a/.devcontainer/README.md b/.devcontainer/README.md new file mode 100644 index 0000000..9d34151 --- /dev/null +++ b/.devcontainer/README.md @@ -0,0 +1,73 @@ +# Docker Support +__Run DEM-Engine in a containerized environment__ + +## Quick start +Make sure to initialize the submodule before using image. + +``` +git submodule init +git submodule update +``` + +DEM-Engine provides Docker images for both development and production use: + +
  • Production Image: Optimized runtime environment with pre-built binaries
  • + +
  • Development Image: Full build environment with debugging tools
  • + +``` +# Build and run the production image +docker-compose -f .devcontainer/docker-compose.yml up deme-production + +# Or start a development environment +docker-compose -f .devcontainer/docker-compose.yml run --rm deme-dev +``` + +## Tips +### Customize output directory & demo +There are two ways to customize the output directory and demo execution: + +#### 1. Modify docker-compose.yml +Edit the `docker-compose.yml` file to change default settings: +``` +volumes: + - ../output:/workspace/DEM-Engine/build/output # change this line to your desired output directory +command: ["/workspace/DEM-Engine/build/bin/DEMdemo_Mixer"] # replace with your production command +``` +#### 2. Override via Command Line +Use command-line overrides for more flexibility without modifying files: + +``` +# Run specific demos by overriding the command +docker-compose -f .devcontainer/docker-compose.yml run --rm deme-production \ + /workspace/DEM-Engine/build/bin/DEMdemo_BallDrop + +# Run with custom output directory +docker-compose -f .devcontainer/docker-compose.yml run --rm \ + -v $(pwd)/my_output:/workspace/DEM-Engine/build/output \ + deme-production /workspace/DEM-Engine/build/bin/DEMdemo_RotatingDrum + +# Run with both custom output directory AND specific demo +docker-compose -f .devcontainer/docker-compose.yml run --rm \ + -v $(pwd)/results/experiment1:/workspace/DEM-Engine/build/output \ + deme-production /workspace/DEM-Engine/build/bin/DEMdemo_ConePenetration +``` + +### Organizing output files + +Based on the current mount configuration, consider using nested directories in your demo scripts for better organization: + +``` +path out_dir = current_path() / "output" / "DemoOutput_Mixer"; +``` + +## Volume Mounts +The development container uses several volumes for persistence: + +
  • deme-build-cache: Caches build artifacts
  • +
  • deme-ccache: Compiler cache for faster rebuilds
  • +
  • deme-vscode-extensions: VSCode extensions
  • + + + + diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 0000000..03da7ad --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,127 @@ +{ + "name": "DEM-Engine Development", + "dockerComposeFile": "docker-compose.yml", + "service": "deme-dev", + "workspaceFolder": "/workspace/DEM-Engine", + + "features": { + // Only essential features + "ghcr.io/devcontainers/features/common-utils:2": { + "installZsh": true, + "configureZshAsDefaultShell": true, + "installOhMyZsh": true, + "upgradePackages": false + } + }, + + "customizations": { + "vscode": { + "extensions": [ + // C++ development + "ms-vscode.cpptools", + "ms-vscode.cpptools-extension-pack", + "ms-vscode.cmake-tools", + "ms-vscode.makefile-tools", + + // CUDA support + "nvidia.nsight-vscode-edition", + + // Python support + "ms-python.python", + "ms-python.vscode-pylance", + "ms-python.debugpy", + + // Docker support + "ms-azuretools.vscode-docker", + + // Visualization + "echatroner.rainbow-csv" + ], + + "settings": { + // Terminal + "terminal.integrated.defaultProfile.linux": "zsh", + + // CMake - optimized for DEM-Engine + "cmake.configureOnOpen": false, // Manual control + "cmake.buildDirectory": "${workspaceFolder}/build", + "cmake.generator": "Ninja", + "cmake.configureArgs": [ + "-DCMAKE_BUILD_TYPE=${env:CMAKE_BUILD_TYPE}", + "-DCMAKE_EXPORT_COMPILE_COMMANDS=ON", + "-DCMAKE_CUDA_ARCHITECTURES=native" // Auto-detect GPU + ], + "cmake.parallelJobs": 0, // Use all cores + + // C++ + "C_Cpp.default.configurationProvider": "ms-vscode.cmake-tools", + "C_Cpp.default.cppStandard": "c++17", + "C_Cpp.formatting": "clangFormat", + "C_Cpp.autocompleteAddParentheses": true, + + // File associations + "files.associations": { + "*.cu": "cuda-cpp", + "*.cuh": "cuda-cpp" + }, + + // Python + "python.defaultInterpreterPath": "/usr/bin/python3", + + // Editor + "editor.formatOnSave": false, // Only format manually + "editor.rulers": [100], // Single ruler at 100 + "editor.minimap.enabled": false, // Save screen space + + // Performance optimizations + "files.watcherExclude": { + "**/build/**": true, + "**/output/**": true, + "**/.git/**": true, + "**/thirdparty/**": true + }, + + "search.exclude": { + "**/build": true, + "**/output": true, + "**/thirdparty": true, + "**/*.o": true, + "**/*.so": true + }, + + // Disable telemetry for privacy + "telemetry.telemetryLevel": "off" + } + } + }, + + // Optimized mounts - only essential ones + "mounts": [ + // Cache build artifacts + "source=deme-build-cache,target=/workspace/DEM-Engine/build,type=volume", + // Persist extensions + "source=deme-vscode-extensions,target=/root/.vscode-server/extensions,type=volume" + ], + + // Simplified lifecycle commands + "postCreateCommand": "echo '🚀 DEM-Engine Dev Environment Ready' && nvcc --version", + + "postStartCommand": "git config --global --add safe.directory /workspace/DEM-Engine", + + // Only forward ports you actually use + "forwardPorts": [], + + // Environment variables + "containerEnv": { + "CUDA_VISIBLE_DEVICES": "all", + "NVIDIA_DRIVER_CAPABILITIES": "all" + }, + + "remoteUser": "root", + + "remoteEnv": { + "CMAKE_BUILD_TYPE": "${localEnv:CMAKE_BUILD_TYPE:Debug}", + "OMP_NUM_THREADS": "${localEnv:OMP_NUM_THREADS:8}", + "CUDA_LAUNCH_BLOCKING": "${localEnv:CUDA_LAUNCH_BLOCKING:0}" + } +} \ No newline at end of file diff --git a/.devcontainer/docker-compose.yml b/.devcontainer/docker-compose.yml new file mode 100644 index 0000000..c247f57 --- /dev/null +++ b/.devcontainer/docker-compose.yml @@ -0,0 +1,55 @@ +services: + # production service + deme-production: + build: + context: .. + dockerfile: .devcontainer/Dockerfile + target: production + image: deme:production + runtime: nvidia + environment: + - NVIDIA_VISIBLE_DEVICES=all + volumes: + - ..:/workspace/DEM-Engine + - ../output:/workspace/DEM-Engine/build/output # change this line to your desired output directory + command: ["/workspace/DEM-Engine/build/bin/DEMdemo_Mixer"] # replace with your production command + + # develop service + deme-dev: + build: + context: .. + dockerfile: .devcontainer/Dockerfile + target: development + image: deme:development + runtime: nvidia + environment: + - NVIDIA_VISIBLE_DEVICES=all + volumes: + - ..:/workspace/DEM-Engine + - ../output:/workspace/DEM-Engine/build/output + - deme-build-cache:/workspace/DEM-Engine/build + - deme-ccache:/root/.ccache + - deme-vscode-extensions:/root/.vscode-server/extensions + stdin_open: true + tty: true + command: ["/bin/bash"] + cap_add: + - SYS_PTRACE # gdb debugging + - SYS_ADMIN # advanced debugging + security_opt: + - seccomp:unconfined # strace debugging + privileged: false + # extra options + shm_size: '2gb' # allow larger shared memory + ulimits: + memlock: + soft: -1 + hard: -1 + stack: + soft: 67108864 + hard: 67108864 + +volumes: + deme-build-cache: + deme-ccache: + deme-vscode-extensions: diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index 3b3e392..fd8b407 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -10,3 +10,5 @@ - Joined: April 2023 - Shlok Sabarwal - Joined: June 2023 +- Peize Li (李沛泽) + - Joined: June 2025