CTMD(Compile-Time Multi-Dimensional matrix library) is a header-only C++ library for multi-dimensional matrix operations and broadcasting. Built on C++23’s std::mdspan and C++26's std::mdarray and std::submdspan, it enables both compile-time and run-time matrix computations. CTMD also supports acceleration through Eigen and OpenMP.
- NumPy-like Syntax: Designed with a familiar NumPy-style API for intuitive usage.
- Compile-Time Computation: Enables compile-time operations when possible for maximum efficiency.
- Flexibility: Seamlessly supports constexpr and non-constexpr contexts, diverse data types, and both static and dynamic extents.
- High Performance: Optimized for fast execution, leveraging modern C++ and hardware acceleration.
- Modern C++ Support: Fully compatible with C++23 and ready to adopt future features like std::linalg.
- A single vector has 1D extents, while a single matrix has 2D extents.
- Broadcasting applies to the leftmost dimensions of the operands, following the rules of std::linalg rather than covering all NumPy-like broadcasting scenarios.
CTMD is a header-only library, so you can start using it by simply including ctmd/ctmd.hpp in your project.
To integrate CTMD into a Bazel project, add it as a dependency in your WORKSPACE file. Ensure your compiler supports C++23. For specific setup requirements, refer to the .devcontainer/DockerFile file. Alternatively, you can use the provided development container to automatically configure your environment.
-
Matrix addition
Code:
#include "ctmd/ctmd.hpp" namespace md = ctmd; constexpr auto a = md::full<int, md::extents<size_t, 3, 1, 2>>(1); constexpr auto b = md::full<int, md::extents<size_t, 2, 1>>(2); constexpr auto c = md::add(a, b); constexpr auto c_expect = md::full<int, md::extents<size_t, 3, 2, 2>>(3); constexpr bool is_allclose = md::allclose(c, c_expect); std::cout << "a extents: " << md::to_string(a.extents()) << std::endl; std::cout << "a: " << md::to_string(a) << std::endl << std::endl; std::cout << "b extents: " << md::to_string(b.extents()) << std::endl; std::cout << "b: " << md::to_string(b) << std::endl << std::endl; std::cout << "c extents: " << md::to_string(c.extents()) << std::endl; std::cout << "c: " << md::to_string(c) << std::endl; static_assert(is_allclose);
Output:
a extents: (3, 1, 2) a: [[[1, 1]], [[1, 1]], [[1, 1]]] b extents: (2, 1) b: [[2], [2]] c extents: (3, 2, 2) c: [[[3, 3], [3, 3]], [[3, 3], [3, 3]], [[3, 3], [3, 3]]]
CTMD uses GoogleTest for unit tests, located in the tests/ directory. Run all tests using Bazel:
bazel test ...
Benchmarks (in benchmarks/) are written using GoogleBenchmark. To run a benchmark (e.g., matrix addition in double precision):
bazel run benchmarks/add:pd
This project is developed and maintained by Uon robotics, South Korea. As a robotics company, we are committed to building robust, efficient software — and we believe in the power of open-source collaboration.
CTMD is in active development, and contributions are welcome! Feel free to open issues or pull requests — whether for bug reports, feature ideas, or code improvements.
CTMD is licensed under the Apache 2.0 License. See the LICENSE file for full details.