Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
251bf43
Initial plan
Copilot Jan 5, 2026
3eaab37
Add Python package build infrastructure
Copilot Jan 5, 2026
d16db4b
Fix float4 type caster size check bug
Copilot Jan 5, 2026
36944f0
Clean up bindings: remove duplicate include and fix typo
Copilot Jan 5, 2026
d557b2e
Improve robustness and reduce code duplication
Copilot Jan 5, 2026
cca3939
Address code review feedback: improve messages and documentation
Copilot Jan 5, 2026
b34ad2b
Add implementation notes and complete Python package support
Copilot Jan 5, 2026
64aef4c
Add missing DEMSolver methods to Python bindings and conda recipe
Copilot Jan 5, 2026
d35b19b
Update documentation with new methods and conda installation
Copilot Jan 5, 2026
7c8ff07
Fix typo: thinckness -> thickness
Copilot Jan 5, 2026
fa7eb4c
Merge branch 'Mesh_Particles' into copilot/modify-cmake-for-python-pa…
Ruochun Jan 6, 2026
aa6079f
Merge branch 'copilot/modify-cmake-for-python-package' of https://git…
Ruochun Jan 6, 2026
b6eba7e
Fix some inclusion errors
Ruochun Jan 9, 2026
c38ed5c
Merge branch 'Mesh_Particles' into copilot/modify-cmake-for-python-pa…
Ruochun Jan 9, 2026
f6bf5bc
Organize DEME paths
Ruochun Jan 9, 2026
1963016
Fix static_cast return types for DEMBoxGridSampler and DEMBoxHCPSampler
Copilot Jan 9, 2026
5cc4da9
Merge branch 'Mesh_Particles' into copilot/modify-cmake-for-python-pa…
Ruochun Jan 15, 2026
50faedd
Merge branch 'copilot/modify-cmake-for-python-package' of https://git…
Ruochun Jan 15, 2026
968fab3
Update version and fix some binding issues
Ruochun Jan 15, 2026
4ed9940
Fix contact force method signatures and add GetMass/GetMOI methods
Copilot Jan 15, 2026
36b8dcb
Fix libstdc++ dependency issue for conda package
Copilot Jan 15, 2026
f4c3dca
Make pip whl work correctly
Ruochun Jan 15, 2026
faadcdf
Document compiler setup and fix conda-build channel requirements
Copilot Jan 15, 2026
9f6b044
yaml changes to 3.0.0
Ruochun Jan 15, 2026
6ef9f59
Change version to hardcoded 3.0.0 in conda recipe
Copilot Jan 15, 2026
f50eb0c
Modify conda-build installation guide
Ruochun Feb 4, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
[submodule "thirdparty/jitify"]
path = thirdparty/jitify
url = https://github.com/Ruochun/jitify.git
[submodule "thirdparty/pybind11"]
path = thirdparty/pybind11
url = https://github.com/pybind/pybind11.git
branch = stable
76 changes: 53 additions & 23 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,18 @@ fix_ninja_colors()

find_package(CUDAToolkit REQUIRED)

# Option to build Python bindings
option(DEME_BUILD_PYTHON "Build Python bindings for DEME" OFF)

# Find Python and pybind11 if building Python bindings
if(DEME_BUILD_PYTHON)
find_package(Python COMPONENTS Interpreter Development REQUIRED)
add_subdirectory(thirdparty/pybind11)
message(STATUS "Python bindings enabled")
message(STATUS "Python version: ${Python_VERSION}")
message(STATUS "Python executable: ${Python_EXECUTABLE}")
endif()

# Find CUB library (this might need to be done in source-level config)
find_package(
CUB REQUIRED
Expand Down Expand Up @@ -159,26 +171,33 @@ target_include_directories(simulator_multi_gpu
PUBLIC ${CORE_INTERFACE}
)

# Determine which runtime data helper to use
if(DEME_BUILD_PYTHON)
set(RUNTIME_DATA_HELPER DEMERuntimeDataHelper_python)
else()
set(RUNTIME_DATA_HELPER DEMERuntimeDataHelper)
endif()

# Set up common link libraries
set(DEME_LINK_LIBS
CUDA::cudart
CUDA::nvrtc
CUDA::cuda_driver
${RUNTIME_DATA_HELPER}
)

# If use ChPF, inform the source
if(USE_CHPF)
target_compile_definitions(simulator_multi_gpu PUBLIC DEME_USE_CHPF)
set(USE_CHPF_STR "ON")

target_link_libraries(simulator_multi_gpu
PUBLIC CUDA::cudart
PUBLIC CUDA::nvrtc
PUBLIC CUDA::cuda_driver
PUBLIC ${DEME_LINK_LIBS}
PUBLIC ${ChPF_IMPORTED_NAME}
PUBLIC DEMERuntimeDataHelper
)
else()
set(USE_CHPF_STR "OFF")

target_link_libraries(simulator_multi_gpu
PUBLIC CUDA::cudart
PUBLIC CUDA::nvrtc
PUBLIC CUDA::cuda_driver
PUBLIC DEMERuntimeDataHelper
PUBLIC ${DEME_LINK_LIBS}
)
endif()

Expand Down Expand Up @@ -206,22 +225,33 @@ set_target_properties(simulator_multi_gpu
set(config_directory ${CMAKE_INSTALL_LIBDIR}/cmake/DEME)

# Install the library, creating an export target for it as well
install(
TARGETS simulator_multi_gpu DEMERuntimeDataHelper
EXPORT DEMETargets
LIBRARY
DESTINATION ${CMAKE_INSTALL_LIBDIR}
)
if(DEME_BUILD_PYTHON)
install(
TARGETS simulator_multi_gpu DEMERuntimeDataHelper_python
EXPORT DEMETargets
LIBRARY
DESTINATION ${CMAKE_INSTALL_LIBDIR}
)
else()
install(
TARGETS simulator_multi_gpu DEMERuntimeDataHelper
EXPORT DEMETargets
LIBRARY
DESTINATION ${CMAKE_INSTALL_LIBDIR}
)
endif()

install(CODE "message(\"Removing build-tree libraries from installation target...\")")
install(CODE "file(REMOVE \"$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}/libDEMERuntimeDataHelper.so\")")

install(
TARGETS DEMERuntimeDataHelper_install
EXPORT DEMETargets
LIBRARY
DESTINATION ${CMAKE_INSTALL_LIBDIR}
if(NOT DEME_BUILD_PYTHON)
install(CODE "file(REMOVE \"$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}/libDEMERuntimeDataHelper.so\")")

install(
TARGETS DEMERuntimeDataHelper_install
EXPORT DEMETargets
LIBRARY
DESTINATION ${CMAKE_INSTALL_LIBDIR}
)
endif()

# Export the generated library target
export(EXPORT DEMETargets
Expand Down
108 changes: 108 additions & 0 deletions IMPLEMENTATION_NOTES.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
# Python Package Implementation Summary

## Overview
This implementation adds complete Python package building capability to the DEM-Engine project, allowing users to install it via `pip install .` and distribute it as a wheel file.

## Key Architectural Decisions

### 1. Modern Python Packaging (PEP 517/518)
- Uses `pyproject.toml` instead of legacy `setup.py`
- Leverages scikit-build-core for seamless CMake integration
- Follows current Python packaging standards

### 2. CMake Integration
- Added `DEME_BUILD_PYTHON` option to conditionally enable Python builds
- Separate `DEMERuntimeDataHelper_python` target for Python-specific needs
- Minimal changes to existing build system (no breaking changes)

### 3. Code Organization
- Python bindings isolated in `src/DEM/python/bindings.cpp`
- Clean separation from C++ library code
- Easy to maintain and extend

### 4. Robustness Improvements
- Multiple fallback mechanisms for site-packages detection
- Works in various Python environments (virtualenv, conda, system)
- Informative error messages

## Files Modified/Created

### Created:
1. `pyproject.toml` - Python package configuration
2. `MANIFEST.in` - Additional files to include in package
3. `PYTHON_BUILD.md` - Build documentation
4. `src/DEM/python/bindings.cpp` - Python bindings
5. `thirdparty/pybind11/` - pybind11 submodule (git submodule)

### Modified:
1. `CMakeLists.txt` - Added Python build support
2. `src/core/CMakeLists.txt` - Added Python-specific runtime helper
3. `src/DEM/CMakeLists.txt` - Added Python module build
4. `.gitmodules` - Added pybind11 submodule

## Building and Testing

### To Build the Package:
```bash
pip install .
```

### To Create a Wheel:
```bash
pip install build
python -m build
```

### To Test (requires CUDA):
```bash
python -c "import DEME; print('Successfully imported DEME')"
```

## Advantages Over pyDEME_demo Branch

1. **Modern Standards**: Uses pyproject.toml (PEP 517/518)
2. **Cleaner Integration**: scikit-build-core vs custom setup.py
3. **Better Organization**: Bindings in separate directory
4. **Less Duplication**: Refactored CMake code
5. **More Portable**: No hardcoded conda paths
6. **More Robust**: Multiple fallbacks for environment detection
7. **Better Maintainability**: Standard Python packaging practices

## Limitations and Future Work

### Current Limitations:
1. Requires CUDA toolkit at build time
2. Platform-specific wheels (not universal)
3. Cannot be tested in CI without GPU runners

### Recommended Future Enhancements:
1. Pre-built wheels for common platforms (Linux/CUDA combinations)
2. CI/CD pipeline for automated wheel building
3. Separate the JIT kernels from the binary for easier updates
4. Optional CPU-only mode for development/testing
5. More comprehensive Python test suite

## Security Considerations

- No secrets or credentials in code
- Uses standard library constants (M_PI)
- Proper error handling for path detection
- No command injection vulnerabilities
- Safe type conversions in bindings

## Testing Recommendations

Since CUDA is required and not available in all CI environments, testing should be done on a CUDA-enabled system:

1. **Build Test**: Verify package builds successfully
2. **Import Test**: Verify module can be imported
3. **Basic Functionality**: Test DEMSolver instantiation
4. **Sampler Test**: Test various sampler functions
5. **Memory Test**: Verify no memory leaks in bindings

## Maintenance Notes

- Keep pybind11 submodule updated (currently on stable branch)
- Update Python version classifiers in pyproject.toml as needed
- Monitor scikit-build-core for API changes
- Test with new CUDA versions as they're released
7 changes: 7 additions & 0 deletions MANIFEST.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
include README.md
include LICENSE.md
include pyproject.toml
recursive-include data *
recursive-include src/kernel *.cu *.cuh
include src/DEM/Defines.h
include src/DEM/VariableTypes.h
Loading