Contributing to torchsparsegradutils ===================================== We welcome contributions to torchsparsegradutils! This guide will help you get started. Development Setup ----------------- #### Option 1: Development Containers (Recommended) For a consistent development environment with GPU support and all dependencies pre-installed, use VS Code Dev Containers: **Prerequisites:** - `Docker `_ with NVIDIA Container Toolkit (for GPU support) - `VS Code `_ with the `Dev Containers extension `_ **Quick Start:** 1. Clone the repository and open in VS Code: .. code-block:: bash git clone https://github.com/cai4cai/torchsparsegradutils cd torchsparsegradutils code . 2. When prompted, click **"Reopen in Container"** or use the Command Palette: - Press ``Ctrl+Shift+P`` (or ``Cmd+Shift+P`` on macOS) - Type "Dev Containers: Reopen in Container" **Available Configurations:** - ``.devcontainer/Dockerfile.stable`` (default): Uses stable PyTorch with CUDA 12.8 support - ``.devcontainer/Dockerfile.nightly``: Uses nightly PyTorch builds for latest features To switch configurations, modify the ``dockerfile`` field in ``.devcontainer/devcontainer.json``: .. code-block:: json "build": { "dockerfile": "./Dockerfile.nightly", // or "./Dockerfile.stable" "context": "." } **What's Included:** - **CUDA 12.8**: Full GPU development support with NVIDIA drivers - **Pre-installed Dependencies**: PyTorch, CuPy, JAX, SciPy, and all development tools - **VS Code Extensions**: Python, Pylance, Jupyter, GitHub Copilot, and code formatting tools - **Development Tools**: pytest, black, flake8, pre-commit hooks - **Python Environment**: Python 3.10+ with all optional dependencies **Benefits:** - ✅ **Consistent Environment**: Same setup across different machines - ✅ **GPU Support**: Pre-configured CUDA environment - ✅ **Zero Setup**: All dependencies and tools pre-installed - ✅ **Isolated**: No conflicts with host system packages - ✅ **VS Code Integration**: Seamless debugging, IntelliSense, and testing #### Option 2: Local Development If you prefer local development: .. code-block:: bash git clone https://github.com/cai4cai/torchsparsegradutils cd torchsparsegradutils # Create a virtual environment python -m venv venv source venv/bin/activate # On Windows: venv\\Scripts\\activate # Install in development mode pip install -e ".[dev]" # Install in development mode pre-commit install # Install pre-commit hooks Development Workflow -------------------- 1. Create a new branch for your feature: .. code-block:: bash git checkout -b feature/your-feature-name 2. Make your changes 3. Run tests and ensure they pass 4. Add tests for new functionality 5. Update documentation if needed 6. Submit a pull request Code Style ---------- We use several tools to maintain code quality: **Black** for code formatting: .. code-block:: bash black torchsparsegradutils/ tests/ **Type hints** are encouraged: .. code-block:: python def sparse_mm(A: torch.Tensor, B: torch.Tensor) -> torch.Tensor: """Matrix multiplication with type hints.""" pass **Docstring format** follows Google style: .. code-block:: python def example_function(param1: int, param2: str) -> bool: """Example function with Google-style docstring. Args: param1: The first parameter. param2: The second parameter. Returns: The return value description. Raises: ValueError: If param1 is negative. """ pass Testing ------- We use pytest for testing. Tests are organized by module: .. code-block:: bash # Run all tests pytest # Run specific test file pytest tests/test_sparse_matmul.py # Run with coverage pytest --cov=torchsparsegradutils **Writing Tests** Follow these guidelines: 1. Test both CPU and GPU (when available) 2. Test different sparse formats (COO, CSR) 3. Test edge cases (empty matrices, single elements) 4. Test gradients and backpropagation 5. Include numerical accuracy tests Example test structure: .. code-block:: python import torch import pytest from torchsparsegradutils import sparse_mm class TestSparseMatmul: @pytest.mark.parametrize("device", ["cpu", "cuda"]) def test_basic_multiplication(self, device): if device == "cuda" and not torch.cuda.is_available(): pytest.skip("CUDA not available") # Test setup A = create_test_sparse_matrix().to(device) B = torch.randn(3, 4).to(device) # Test result = sparse_mm(A, B) expected = torch.sparse.mm(A, B) # Assertions assert torch.allclose(result, expected) def test_gradient_sparsity(self): """Test that gradients preserve sparsity.""" A = create_test_sparse_matrix(requires_grad=True) B = torch.randn(3, 4, requires_grad=True) result = sparse_mm(A, B) loss = result.sum() loss.backward() assert A.grad.is_sparse assert A.grad._nnz() == A._nnz() Documentation ------------- Documentation is built with Sphinx. To build locally: .. code-block:: bash cd docs/ make html # Open docs/_build/html/index.html **Documentation Guidelines** 1. All public functions must have docstrings 2. Include mathematical notation where appropriate 3. Provide usage examples 4. Document parameters, return values, and exceptions **Adding Examples** Add examples to the docstrings: .. code-block:: python def sparse_triangular_solve(A, B, upper=False): """Solve triangular sparse linear system. Args: A: Sparse triangular matrix B: Dense right-hand side upper: Whether A is upper triangular Returns: Solution tensor X such that AX = B Example: >>> import torch >>> from torchsparsegradutils import sparse_triangular_solve >>> # Create lower triangular matrix >>> indices = torch.tensor([[0, 1, 1, 2], [0, 0, 1, 2]]) >>> values = torch.tensor([1., 2., 3., 4.]) >>> A = torch.sparse_coo_tensor(indices, values, (3, 3)) >>> B = torch.randn(3, 2) >>> X = sparse_triangular_solve(A, B, upper=False) """ Adding New Features ------------------- When adding new functionality: 1. **Start with an issue** describing the feature 2. **Design the API** - consider consistency with existing functions 3. **Implement core functionality** with appropriate error handling 4. **Add comprehensive tests** covering edge cases 5. **Document thoroughly** with examples and mathematical background 6. **Benchmark performance** against alternatives when relevant Example feature addition: .. code-block:: python # 1. Core implementation def new_sparse_operation(A, B, option="default"): """New sparse operation description.""" # Input validation if not A.is_sparse: raise ValueError("A must be sparse") # Implementation result = _compute_operation(A, B, option) return result # 2. Tests def test_new_sparse_operation(): # Basic functionality test # Edge case tests # Gradient tests # Performance test pass # 3. Documentation # Add to API docs, tutorials, examples Benchmarking New Features ------------------------- Include benchmarks for new operations: .. code-block:: python # benchmarks/benchmark_new_feature.py import time import torch from torchsparsegradutils import new_sparse_operation def benchmark_new_operation(): sizes = [100, 500, 1000, 5000] results = [] for n in sizes: A = create_sparse_matrix(n, n) B = torch.randn(n, n) # Timing start = time.time() result = new_sparse_operation(A, B) end = time.time() results.append((n, end - start)) return results Continuous Integration ---------------------- Our CI pipeline runs: 1. **Code formatting** checks (Black) 2. **Type checking** (mypy, when available) 3. **Unit tests** on multiple Python versions 4. **Integration tests** with different PyTorch versions 5. **Documentation** building 6. **Benchmark** regression tests All checks must pass before merging. Submitting Pull Requests ------------------------ 1. **Ensure all tests pass** locally 2. **Write clear commit messages** 3. **Reference related issues** PR template checklist: - [ ] Tests added/updated - [ ] Documentation updated - [ ] All CI checks pass - [ ] Backwards compatibility maintained Code Review Process ------------------- 1. **Maintainer review** for architecture and design 2. **Automated checks** must pass 3. **Community review** welcome for all PRs 4. **Final approval** from project maintainers Common review feedback: - **Performance considerations** for sparse operations - **Memory efficiency** improvements - **Numerical stability** concerns - **API consistency** with existing functions Issue Reporting --------------- When reporting bugs: 1. **Check existing issues** first 2. **Provide minimal reproducible example** 3. **Include system information** (Python version, PyTorch version, OS) 4. **Describe expected vs. actual behavior** Example bug report: .. code-block:: python # System info Python 3.10.0 PyTorch 2.5.0 CUDA 12.1 (if relevant) # Minimal example import torch from torchsparsegradutils import sparse_mm A = torch.sparse_coo_tensor(...) B = torch.randn(...) # This fails with error message: result = sparse_mm(A, B) Feature Requests ---------------- For feature requests: 1. **Describe the use case** and motivation 2. **Propose API design** if applicable 3. **Consider implementation complexity** 4. **Reference relevant literature** for mathematical operations Release Process --------------- Releases follow semantic versioning: - **Major** (X.0.0): Breaking changes - **Minor** (0.X.0): New features, backwards compatible - **Patch** (0.0.X): Bug fixes Release checklist: 1. Update version numbers 2. Run full test suite 3. Build documentation 4. Create GitHub release 5. Publish to PyPI Getting Help ------------ - **Documentation**: Read the docs first - **GitHub Discussions**: For questions and design discussions - **GitHub Issues**: For bug reports and feature requests Thank you for contributing to torchsparsegradutils!