Contributing¶
Bug reports, portability fixes, benchmark matrices and solver improvements are welcome.
Build and test¶
Build and run the suite as in the README; ctest
also runs the examples. Run one test while iterating with
./build/tests/unit_tests --gtest_filter='FactorizeTest.PermutationIsValid'.
CI builds tests/cmake_consumer to check the
CMake consumer requirements with warnings as errors. The root-embedding
consumer reuses the same alignment and original-residual checks:
cmake -S tests/cmake_subdirectory -B build-subdirectory
cmake --build build-subdirectory -j2
ctest --test-dir build-subdirectory --output-on-failure
To check native tests without CLI dependencies, repeat in a fresh build directory
with -DAPXCHOL_BUILD_TESTS=ON -DAPXCHOL_BUILD_CLI=OFF. The same consumer fixture
supports -DAPXCHOL_DEVICE=CUDA or METAL, enabling the GPU language in its
parent scope before embedding.
The workflow defines compiler and backend coverage;
the CUDA job compiles without running device tests.
Use focused regressions for changed behavior, then the relevant suite. CUDA
changes require a local CUDA build and device run. Metal changes require an
-DAPXCHOL_DEVICE=METAL build on an Apple-silicon Mac; also run the device
tests under MTL_DEBUG_LAYER=1 MTL_SHADER_VALIDATION=1. Python and Octave
compile the core sources independently; check affected binding interfaces too:
pip install -e "python[test,scipy]"
pytest python/tests
./octave/build.sh
The release version is set in cmake/apxchol_version.cmake; native builds and
Python packages share it. PyPI publication requires a matching v<version>
GitHub release tag. Manually running the publish workflow builds artifacts without publishing them.
The CLI workflow sets up each platform and calls
.github/scripts/build-cli.sh: normal CMake install, OpenMP/notices, tar and checksum.
tests/check_cli_archive.py checks relocation and the existing SDDM fixture on CPU
and Metal. The version comes from the same CMake source used by wheels.
Documentation¶
Install Doxygen, build the CLI as above, then run:
python -m pip install -r docs/requirements.txt -e ./python
python docs/build.py
python -m http.server 8000 --directory build/docs
The site reuses the repository guides, selected C++ comments, Python docstrings
and the CLI’s --help. Generated files stay in build/docs. To use another
CLI or output directory, pass them as positional arguments to docs/build.py.
Documentation CI uploads an HTML preview for review. Successful main builds
publish development documentation at /dev/. Each stable GitHub release saves
its rendered HTML as documentation.tar.gz; reruns retain the existing snapshot.
The site root serves the most recently published stable release with a snapshot,
or development documentation until the first snapshot exists. Each snapshot is
also served at /vX.Y.Z/. The sidebar version selector lists these snapshots and
development documentation; releases without a documentation asset are omitted.
Assembly updates only the marked selector in deployed HTML copies; the release
archives remain unchanged. Older HTML without the marker remains reachable from
the current site’s selector. Publishing a snapshot triggers a main documentation
build to refresh the site.
Code conventions¶
Use C++23, snake_case, namespace apxchol, and trailing underscores for
private members. C++ headers are under include/; API scope
defines the public interface. The CPU compiled core is factorization.cpp,
operator_class.cpp and solve.cpp in src/.
Register new partitioners in partitioner_list.h. The working graph uses
directed AoS adjacency. Preserve deterministic neighbor ordering, sampling
streams and thread-team behavior. Consult the
rationale in factor_options.h and the precision contract
before changing established defaults. Prefer a shared implementation over
another mode or public tuning option.
Performance¶
The benchmark suite is a separate CMake project. Use a controlled, recorded machine and keep campaign outputs outside tracked source. Interactive laptop measurements are diagnostic. Use matched, interleaved repetitions with pinned source, binaries, inputs, affinity and timing boundaries. Report setup and solve separately, together with residuals, fill, memory and control spread. Do not combine isolated speedups into an unmeasured cumulative claim.