Skip to content

Commit 9533ab3

Browse files
atkshclaude
andauthored
Add query_intersections() method for efficient AABB pair detection (#47)
* Add query_intersections() method for efficient AABB pair detection Implements a new query_intersections() method that efficiently finds all pairs of intersecting bounding boxes in the tree, addressing the feature request in issue #46. Key features: - Returns numpy array of shape (n_pairs, 2) with index pairs (i, j) where i < j - Parallel processing using std::thread for improved performance - Automatic double-precision refinement when exact coordinates are available - No duplicate pairs or self-pairs - Similar to scipy.spatial.cKDTree.query_pairs but for AABBs This eliminates the need for manual post-processing of batch_query results using np.vectorize, np.repeat, and np.concatenate, which previously canceled out the performance gains from C++ parallelization. Changes: - cpp/prtree.h: Added query_intersections() method to PRTree class - cpp/main.cc: Added Python bindings for all dimensions (2D, 3D, 4D) - tests/test_PRTree.py: Added comprehensive tests including edge cases - README.md: Updated documentation with usage examples All tests pass (45 new tests + existing tests). Resolves #46 * Add comprehensive Makefile and development documentation Adds a complete development workflow automation through Make commands, making it easier for developers to build, test, and contribute to the project. Key additions: - Makefile: Comprehensive build automation with 30+ commands - Build: build, build-release, rebuild, debug-build - Test: test, test-verbose, test-fast, test-coverage, test-one - Packaging: wheel, sdist, release - Maintenance: clean, clean-all, format, lint - Development: init, dev, install-deps, check - CONTRIBUTING.md: Complete developer guide - Development setup instructions - Workflow documentation - Coding standards - Troubleshooting guide - Enhanced .gitignore: Additional patterns for build artifacts, coverage reports, and temporary files All content is in English and designed to be generic and reusable for any feature development, not specific to any particular functionality. Benefits: - Streamlined development workflow - Consistent build and test procedures - Easy onboarding for new contributors - CI-compatible check commands * Add Makefile usage reference guide * Format C++ code with clang-format Apply clang-format to all C++ source files for consistent code style. This is an automatic formatting change with no functional modifications. Files affected: - cpp/main.cc: Brace positioning and line wrapping - cpp/parallel.h: Formatting improvements - cpp/prtree.h: Consistent formatting throughout - cpp/small_vector.h: Style consistency updates These changes were generated by running 'make format'. * Fix: Guard against zero hardware_concurrency in query_intersections When std::thread::hardware_concurrency() returns 0 (which is permitted when the runtime cannot detect the CPU count), n_threads was set to zero. This caused undefined behavior: - In single-threaded path: writes to thread_pairs[0] on empty vector - In parallel path: loops never execute, returning no intersections Apply the same guard used in find_all() to ensure at least one thread. This fixes a critical bug that could cause crashes or incorrect results on systems where hardware_concurrency() returns 0. Fixes: P1 Badge Guard against zero hardware_concurrency Reported-by: User feedback --------- Co-authored-by: Claude <noreply@anthropic.com>
1 parent 699c912 commit 9533ab3

File tree

10 files changed

+2224
-1483
lines changed

10 files changed

+2224
-1483
lines changed

.gitignore

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ _build/
77
_generate/
88
*.so
99
*.so.*
10+
*.a
1011
*.py[cod]
1112
*.egg-info
1213
.eggs/
@@ -17,4 +18,26 @@ __pycache__/
1718
.ipynb_checkpoints/
1819
.vscode/
1920
.DS_Store
20-
*.prof
21+
*.prof
22+
23+
# Test coverage
24+
htmlcov/
25+
.coverage
26+
.coverage.*
27+
coverage.xml
28+
*.cover
29+
30+
# Pytest
31+
.pytest_cache/
32+
.pytest_cache
33+
34+
# Build artifacts
35+
*.o
36+
*.obj
37+
*.lib
38+
*.exp
39+
40+
# Temporary files
41+
*.tmp
42+
*.bak
43+
*~

CONTRIBUTING.md

Lines changed: 312 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,312 @@
1+
# Contributing Guide
2+
3+
Thank you for your interest in contributing to python_prtree!
4+
5+
## Development Setup
6+
7+
### Prerequisites
8+
9+
- Python 3.8 or higher
10+
- CMake 3.12 or higher
11+
- C++17-compatible compiler (GCC 7+, Clang 5+, MSVC 2017+)
12+
- Git
13+
14+
### Quick Start
15+
16+
```bash
17+
# Clone the repository
18+
git clone --recursive https://github.com/atksh/python_prtree
19+
cd python_prtree
20+
21+
# Setup development environment (first time only)
22+
make dev
23+
24+
# Build and test
25+
make build
26+
make test
27+
```
28+
29+
## Makefile Commands
30+
31+
We provide a Makefile to streamline the development workflow.
32+
33+
### Show Help
34+
35+
```bash
36+
make help
37+
```
38+
39+
### Initial Setup
40+
41+
```bash
42+
make init # Initialize submodules + check dependencies
43+
make install-deps # Install development dependencies
44+
make dev # Run init + install-deps + build at once
45+
```
46+
47+
### Building
48+
49+
```bash
50+
make build # Build in debug mode
51+
make build-release # Build in release mode
52+
make rebuild # Clean build (clean + build)
53+
make debug-build # Build with debug symbols
54+
```
55+
56+
### Testing
57+
58+
```bash
59+
make test # Run all tests
60+
make test-verbose # Run tests in verbose mode
61+
make test-fast # Run tests in parallel (faster)
62+
make test-coverage # Run tests with coverage
63+
make test-one TEST=<name> # Run specific test(s)
64+
```
65+
66+
### Cleanup
67+
68+
```bash
69+
make clean # Remove build artifacts
70+
make clean-all # Remove everything including submodules
71+
```
72+
73+
### Packaging
74+
75+
```bash
76+
make wheel # Build wheel package
77+
make sdist # Build source distribution
78+
make release # Build release packages (wheel + sdist)
79+
```
80+
81+
### Other Commands
82+
83+
```bash
84+
make format # Format C++ code (requires clang-format)
85+
make lint # Lint code
86+
make info # Show project information
87+
make check # Run build and tests (for CI)
88+
make quick # Quick test (clean + build + test)
89+
```
90+
91+
## Development Workflow
92+
93+
### Adding New Features
94+
95+
1. **Create a branch**
96+
```bash
97+
git checkout -b feature/your-feature-name
98+
```
99+
100+
2. **Setup development environment (first time only)**
101+
```bash
102+
make dev
103+
```
104+
105+
3. **Make changes**
106+
- C++ code: `cpp/prtree.h`, `cpp/main.cc`
107+
- Python wrapper: `src/python_prtree/__init__.py`
108+
- Tests: `tests/test_PRTree.py`
109+
110+
4. **Build and test**
111+
```bash
112+
make rebuild
113+
make test
114+
```
115+
116+
5. **Check code quality**
117+
```bash
118+
make format # Format code
119+
make lint # Lint code
120+
```
121+
122+
6. **Commit**
123+
```bash
124+
git add -A
125+
git commit -m "Add: description of new feature"
126+
```
127+
128+
7. **Create pull request**
129+
130+
### Test-Driven Development (TDD)
131+
132+
1. **Write tests first**
133+
```python
134+
# tests/test_PRTree.py
135+
def test_new_feature():
136+
# Write test code
137+
pass
138+
```
139+
140+
2. **Verify test fails**
141+
```bash
142+
make test-one TEST=test_new_feature
143+
```
144+
145+
3. **Implement feature**
146+
```cpp
147+
// cpp/prtree.h
148+
// Add implementation
149+
```
150+
151+
4. **Build and test**
152+
```bash
153+
make build
154+
make test-one TEST=test_new_feature
155+
```
156+
157+
5. **Run all tests**
158+
```bash
159+
make test
160+
```
161+
162+
### Debugging
163+
164+
Build with debug symbols for debugging:
165+
166+
```bash
167+
make debug-build
168+
gdb python3
169+
(gdb) run -c "from python_prtree import PRTree2D; ..."
170+
```
171+
172+
### Checking Coverage
173+
174+
```bash
175+
make test-coverage
176+
# Open htmlcov/index.html in browser
177+
```
178+
179+
## Coding Standards
180+
181+
### C++
182+
183+
- **Style**: Follow Google C++ Style Guide
184+
- **Formatting**: Use clang-format (`make format`)
185+
- **Naming conventions**:
186+
- Classes: `PascalCase` (e.g., `PRTree`)
187+
- Functions/methods: `snake_case` (e.g., `batch_query`)
188+
- Variables: `snake_case`
189+
- Constants: `UPPER_CASE`
190+
191+
### Python
192+
193+
- **Style**: Follow PEP 8
194+
- **Line length**: Maximum 100 characters
195+
- **Documentation**: Use docstrings
196+
197+
### Tests
198+
199+
- Add tests for all new features
200+
- Test case naming: `test_<feature>_<case>`
201+
- Cover edge cases
202+
- Use parameterized tests (`@pytest.mark.parametrize`)
203+
204+
## Project Structure
205+
206+
```
207+
python_prtree/
208+
├── cpp/ # C++ implementation
209+
│ ├── prtree.h # PRTree core implementation
210+
│ ├── main.cc # Python bindings
211+
│ ├── parallel.h # Parallel processing utilities
212+
│ └── small_vector.h # Optimized vector
213+
├── src/python_prtree/ # Python wrapper
214+
│ └── __init__.py
215+
├── tests/ # Test suite
216+
│ └── test_PRTree.py
217+
├── third/ # Third-party libraries (submodules)
218+
│ ├── pybind11/
219+
│ └── snappy/
220+
├── CMakeLists.txt # CMake configuration
221+
├── setup.py # Packaging configuration
222+
├── Makefile # Development workflow
223+
└── README.md # User documentation
224+
```
225+
226+
## Troubleshooting
227+
228+
### Submodules Not Found
229+
230+
```bash
231+
make clean-all
232+
make init
233+
```
234+
235+
### Build Errors
236+
237+
```bash
238+
make clean
239+
make build
240+
```
241+
242+
### Test Failures
243+
244+
1. Verify build succeeded
245+
```bash
246+
make build
247+
```
248+
249+
2. Check environment variables
250+
```bash
251+
echo $PYTHONPATH # Should include src directory
252+
```
253+
254+
3. Run in verbose mode
255+
```bash
256+
make test-verbose
257+
```
258+
259+
### CMake Errors
260+
261+
Clear CMake cache:
262+
```bash
263+
rm -rf build
264+
make build
265+
```
266+
267+
## Continuous Integration (CI)
268+
269+
When you create a pull request, the following checks run automatically:
270+
271+
- Build verification
272+
- All tests
273+
- Code coverage
274+
275+
Run the same checks locally:
276+
```bash
277+
make check
278+
```
279+
280+
## Release Process
281+
282+
1. **Update version**
283+
- Update version number in `setup.py`
284+
285+
2. **Update changelog**
286+
- Update "New Features and Changes" section in `README.md`
287+
288+
3. **Run tests**
289+
```bash
290+
make clean
291+
make check
292+
```
293+
294+
4. **Build release packages**
295+
```bash
296+
make release
297+
```
298+
299+
5. **Create tag**
300+
```bash
301+
git tag -a v0.x.x -m "Release v0.x.x"
302+
git push origin v0.x.x
303+
```
304+
305+
## Questions and Support
306+
307+
- **Issues**: https://github.com/atksh/python_prtree/issues
308+
- **Discussions**: https://github.com/atksh/python_prtree/discussions
309+
310+
## License
311+
312+
Contributions to this project will be released under the same license as the project (MIT).

0 commit comments

Comments
 (0)