Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
16 changes: 15 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -200,13 +200,21 @@ add_subdirectory(axel)
# Build momentum
#===============================================================================

mt_library(
NAME progress_bar
HEADERS_VARS progress_bar_public_headers
SOURCES_VARS progress_bar_sources
PUBLIC_LINK_LIBRARIES
indicators::indicators
)

mt_library(
NAME common
HEADERS_VARS common_public_headers
SOURCES_VARS common_sources
PUBLIC_LINK_LIBRARIES
fmt::fmt-header-only
indicators::indicators
progress_bar
spdlog::spdlog_header_only
PUBLIC_COMPILE_DEFINITIONS
MOMENTUM_WITH_SPDLOG=1
Expand Down Expand Up @@ -751,6 +759,12 @@ if(MOMENTUM_BUILD_TESTING)
LINK_LIBRARIES common
)

mt_test(
NAME progress_bar_test
SOURCES_VARS progress_bar_test_sources
LINK_LIBRARIES progress_bar
)

mt_test(
NAME simd_test
SOURCES_VARS simd_test_sources
Expand Down
16 changes: 13 additions & 3 deletions cmake/build_variables.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -16,24 +16,33 @@ common_public_headers = [
"common/log.h",
"common/memory.h",
"common/profile.h",
"common/progress_bar.h",
"common/string.h",
]

common_sources = [
"common/log.cpp",
"common/progress_bar.cpp",
"common/string.cpp",
]

common_test_sources = [
"test/common/aligned_allocator_test.cpp",
"test/common/exception_test.cpp",
"test/common/log_test.cpp",
"test/common/progress_bar_test.cpp",
"test/common/string_test.cpp",
]

progress_bar_public_headers = [
"common/progress_bar.h",
]

progress_bar_sources = [
"common/progress_bar.cpp",
]

progress_bar_test_sources = [
"test/common/progress_bar_test.cpp",
]

simd_public_headers = [
"simd/simd.h",
]
Expand Down Expand Up @@ -62,6 +71,7 @@ fmt_eigen_public_headers = [
online_qr_public_headers = [
"math/online_householder_qr.h",
"math/resizeable_matrix.h",
"math/span_compat.h",
]

online_qr_sources = [
Expand Down
24 changes: 24 additions & 0 deletions momentum/common/exception.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@

#include <fmt/format.h>

#include <cstdio>
#include <cstdlib>
#include <stdexcept>

/// Throws an exception of a specified type with a formatted message.
Expand Down Expand Up @@ -54,6 +56,8 @@ namespace momentum::detail {

using DefaultException = std::runtime_error;

#if defined(__cpp_exceptions) || defined(__EXCEPTIONS) || defined(_CPPUNWIND)

// Helper function template to throw with formatted message
template <typename Exception = DefaultException, typename... Args>
[[noreturn]] void throwImpl(fmt::format_string<Args...> format, Args&&... args) {
Expand All @@ -67,4 +71,24 @@ template <typename Exception>
throw Exception{};
}

#else

// Fallback for platforms without exception support
// Log the error message to stderr and abort.
template <typename Exception = DefaultException, typename... Args>
[[noreturn]] void throwImpl(fmt::format_string<Args...> format, Args&&... args) {
std::fprintf(
stderr, "FATAL ERROR: %s\n", fmt::format(format, std::forward<Args>(args)...).c_str());
std::abort();
}

// Overload for exceptions without a message.
template <typename Exception>
[[noreturn]] void throwImpl() {
std::fputs("FATAL ERROR (no message)\n", stderr);
std::abort();
}

#endif

} // namespace momentum::detail
6 changes: 3 additions & 3 deletions momentum/math/mppca.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ template <typename T>
void MppcaT<T>::set(
const VectorX<T>& inPi,
const MatrixX<T>& mmu,
std::span<const MatrixX<T>> W,
momentum::span<const MatrixX<T>> W,
const VectorX<T>& sigma2) {
using CovarianceMatrix = LowRankCovarianceMatrixT<T>;

Expand Down Expand Up @@ -47,15 +47,15 @@ void MppcaT<T>::set(

// Rpre is the constant part of R that does not depend on the parameters, so we can precalculate
// it
Rpre(c) = std::log(inPi(c)) - 0.5 * C_logDeterminant - half_d_log_2pi;
Rpre(c) = std::log(inPi(c)) - T(0.5) * C_logDeterminant - half_d_log_2pi;
}
mu = mmu;

names = std::vector<std::string>(d);
}

template <typename T, typename T2>
std::vector<Eigen::MatrixX<T2>> castMatrices(std::span<const Eigen::MatrixX<T>> m_in) {
std::vector<Eigen::MatrixX<T2>> castMatrices(momentum::span<const Eigen::MatrixX<T>> m_in) {
std::vector<Eigen::MatrixX<T2>> result;
result.reserve(m_in.size());
for (const auto& m : m_in) {
Expand Down
2 changes: 1 addition & 1 deletion momentum/math/mppca.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ struct MppcaT {
void set(
const VectorX<T>& pi,
const MatrixX<T>& mmu,
std::span<const MatrixX<T>> W,
momentum::span<const MatrixX<T>> W,
const VectorX<T>& sigma2);

/// Converts to a different scalar type
Expand Down
2 changes: 1 addition & 1 deletion momentum/math/online_householder_qr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ void OnlineHouseholderQR<T>::reset(const Eigen::Index n, T lambda) {
y_.setZero();
}

void validateColumnIndices(std::span<const Eigen::Index> colIndices, Eigen::Index maxEntry) {
void validateColumnIndices(momentum::span<const Eigen::Index> colIndices, Eigen::Index maxEntry) {
#ifndef NDEBUG
{
for (const auto& idx : colIndices) {
Expand Down
12 changes: 7 additions & 5 deletions momentum/math/online_householder_qr.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,16 @@
#include <momentum/common/aligned.h>
#include <momentum/common/checks.h>
#include <momentum/math/resizeable_matrix.h>
#include <momentum/math/span_compat.h>

#include <Eigen/Core>
#include <span>

#include <deque>
#include <vector>

namespace momentum {

void validateColumnIndices(std::span<const Eigen::Index> colIndices, Eigen::Index maxEntry);
void validateColumnIndices(momentum::span<const Eigen::Index> colIndices, Eigen::Index maxEntry);

// Remaps the matrix such that A_new.col(i) = A_orig.col(colIndices[i]).
// This can be used to perform QR on a subset of the matrix columns.
Expand All @@ -30,7 +30,9 @@ class ColumnIndexedMatrix {

explicit ColumnIndexedMatrix(Eigen::Ref<MatrixType> mat) : mat_(mat), useColumnIndices_(false) {}

explicit ColumnIndexedMatrix(Eigen::Ref<MatrixType> mat, std::span<const Eigen::Index> colIndices)
explicit ColumnIndexedMatrix(
Eigen::Ref<MatrixType> mat,
momentum::span<const Eigen::Index> colIndices)
: mat_(mat), columnIndices_(colIndices), useColumnIndices_(true) {
validateColumnIndices(colIndices, mat.cols());
}
Expand All @@ -55,7 +57,7 @@ class ColumnIndexedMatrix {
}
}

[[nodiscard]] std::span<const Eigen::Index> columnIndices() const {
[[nodiscard]] momentum::span<const Eigen::Index> columnIndices() const {
return columnIndices_;
}

Expand All @@ -73,7 +75,7 @@ class ColumnIndexedMatrix {

private:
Eigen::Ref<MatrixType> mat_;
std::span<const Eigen::Index> columnIndices_;
momentum::span<const Eigen::Index> columnIndices_;
bool useColumnIndices_;
};

Expand Down
46 changes: 46 additions & 0 deletions momentum/math/span_compat.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

#pragma once

/// @file span_compat.h
/// @brief Provides a C++17-compatible span type alias.
///
/// This header provides `momentum::span<T>` which aliases to `std::span<T>` when
/// C++20 is available, and falls back to `gsl::span<T>` for C++17 compilers.
/// This enables cross-platform compatibility for platforms that don't yet support C++20.

// Detect C++20 support
#if __cplusplus >= 202002L || (defined(_MSVC_LANG) && _MSVC_LANG >= 202002L)
#define MOMENTUM_HAS_CPP20_SPAN 1
#else
#define MOMENTUM_HAS_CPP20_SPAN 0
#endif

#if MOMENTUM_HAS_CPP20_SPAN
#include <span>
#else
#include <gsl/span>
#endif

namespace momentum {

#if MOMENTUM_HAS_CPP20_SPAN

/// Span type alias using std::span (C++20).
template <typename T>
using span = std::span<T>;

#else

/// Span type alias using gsl::span (C++17 fallback).
template <typename T>
using span = gsl::span<T>;

#endif

} // namespace momentum
12 changes: 6 additions & 6 deletions momentum/math/transform.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -94,8 +94,8 @@ TransformT<T> TransformT<T>::inverse() const {

template <typename T>
TransformT<T> blendTransforms(
std::span<const TransformT<T>> transforms,
std::span<const T> weights) {
momentum::span<const TransformT<T>> transforms,
momentum::span<const T> weights) {
assert(transforms.size() == weights.size());
if (transforms.empty()) {
return TransformT<T>();
Expand Down Expand Up @@ -149,11 +149,11 @@ TransformT<T> slerp(const TransformT<T>& t1, const TransformT<T>& t2, T weight)
}

template TransformT<float> blendTransforms(
std::span<const TransformT<float>> transforms,
std::span<const float> weights);
momentum::span<const TransformT<float>> transforms,
momentum::span<const float> weights);
template TransformT<double> blendTransforms(
std::span<const TransformT<double>> transforms,
std::span<const double> weights);
momentum::span<const TransformT<double>> transforms,
momentum::span<const double> weights);

template TransformT<float> slerp(const TransformT<float>&, const TransformT<float>&, float);
template TransformT<double> slerp(const TransformT<double>&, const TransformT<double>&, double);
Expand Down
4 changes: 2 additions & 2 deletions momentum/math/transform.h
Original file line number Diff line number Diff line change
Expand Up @@ -216,8 +216,8 @@ using TransformListT =

template <typename T>
TransformT<T> blendTransforms(
std::span<const TransformT<T>> transforms,
std::span<const T> weights);
momentum::span<const TransformT<T>> transforms,
momentum::span<const T> weights);

/// Spherical linear interpolation between two transforms
template <typename T>
Expand Down
25 changes: 13 additions & 12 deletions momentum/math/types.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
#pragma warning(pop)
#endif

#include <span>
#include "momentum/math/span_compat.h"

//------------------------------------------------------------------------------
// Define some additional Eigen types
Expand Down Expand Up @@ -401,29 +401,30 @@ using ColorArray = Matrix3Xb;
constexpr size_t kMaxModelParams = 2048; // at most 2048 parameters per frame
using ParameterSet = std::bitset<kMaxModelParams>;

/// @brief A utility struct that facilitates the deduction of a `std::span` type from a given type.
/// @brief A utility struct that facilitates the deduction of a `momentum::span` type from a given
/// type.
///
/// This utility is particularly useful when a function accepts a `std::span<Vector3<T>>` as an
/// argument, where the template argument of `std::span` is also a template. In such cases, direct
/// deduction of the `std::span` type from other container types (e.g., `std::vector<Vector3<T>>`)
/// at the call site may fail.
/// This utility is particularly useful when a function accepts a `momentum::span<Vector3<T>>` as an
/// argument, where the template argument of `momentum::span` is also a template. In such cases,
/// direct deduction of the `momentum::span` type from other container types (e.g.,
/// `std::vector<Vector3<T>>`) at the call site may fail.
///
/// By using this utility, the appropriate `std::span` type can be deduced automatically, ensuring
/// smoother function calls and enhancing code readability.
/// By using this utility, the appropriate `momentum::span` type can be deduced automatically,
/// ensuring smoother function calls and enhancing code readability.
///
/// Example usage:
/// @code
/// void foo(DeduceSpanType<Vector3f>::type points); // Equivalent to std::span<Vector3f>
/// void foo(DeduceSpanType<Vector3f>::type points); // Equivalent to momentum::span<Vector3f>
///
/// std::vector<Vector3f> points;
/// foo(points); // This line will compile without any issues.
/// @endcode
///
/// @note The `std::span` generated by this utility gives a mutable view into the sequence. If an
/// immutable view is needed, consider using `std::span<const T>` instead.
/// @note The `momentum::span` generated by this utility gives a mutable view into the sequence. If
/// an immutable view is needed, consider using `momentum::span<const T>` instead.
template <typename T>
struct DeduceSpanType {
using type = std::span<T>;
using type = momentum::span<T>;
};

/// Casts the scalar type of objects in a container that support the `cast<>()` method.
Expand Down
2 changes: 1 addition & 1 deletion momentum/math/utility.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -394,7 +394,7 @@ Vector3<T> quaternionToEuler(const Quaternion<T>& q) {
return res;
}

Quaternionf quaternionAverage(std::span<const Quaternionf> q, std::span<const float> w) {
Quaternionf quaternionAverage(momentum::span<const Quaternionf> q, momentum::span<const float> w) {
Matrix4f Q = Matrix4f::Zero();

// calculate the matrix
Expand Down
4 changes: 2 additions & 2 deletions momentum/math/utility.h
Original file line number Diff line number Diff line change
Expand Up @@ -281,8 +281,8 @@ Vector3<T> quaternionToEuler(const Quaternion<T>& q);
/// @param w Optional weights for each quaternion (defaults to equal weights)
/// @return The average quaternion
Quaternionf quaternionAverage(
std::span<const Quaternionf> q,
std::span<const float> w = std::vector<float>());
momentum::span<const Quaternionf> q,
momentum::span<const float> w = {});

/// Returns the closest points on two line segments where the line segments are represented in
/// origin and direction
Expand Down
Loading