Document the new DPF surfaces in one command set, and test the field, half-tree, and multipoint edges.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Ryan Henry 2026-09-24 23:18:10 -06:00
parent 0d8a5a8131
commit 0dff6df8ed
250 changed files with 12199 additions and 1981 deletions

View file

@ -36,14 +36,16 @@
namespace dpf
{
/// Ping-pong pivot math underflows at 0 leaves. Keep a one-node slab so the
/// @brief Ping-pong pivot math underflows at 0 leaves. Keep a one-node slab so the
/// root still has a place to land; callers never walk a 0-leaf interval.
/// @param output_len the `output_len`
/// @return Ping-pong pivot math underflows at 0 leaves
inline std::size_t interval_memoizer_slots(std::size_t output_len)
{
return output_len == 0 ? std::size_t{1} : output_len;
}
/// Interval memoizers key on the underlying DPF key type (same rule as path
/// @brief Interval memoizers key on the underlying DPF key type (same rule as path
/// memoizers): a memoizer built from `party_key<0, Key>` also accepts
/// `party_key<1, Key>` and bare `Key`.
template <typename DpfKey>
@ -161,18 +163,20 @@ struct interval_memoizer_base
std::optional<integral_type> to_;
};
/// Two-level workspace for one interval. This is what
/// @brief Two-level workspace for one interval. This is what
/// `eval_interval(key, from, to)` allocates when you omit the memoizer.
/// @tparam DpfKey DPF key type
/// @tparam interior_node interior node
template <typename DpfKey,
typename Allocator = aligned_allocator<
typename interval_memoizer_key_t<DpfKey>::interior_node>>
struct basic_interval_memoizer final : public interval_memoizer_base<DpfKey>
{
HEDLEY_PRAGMA(GCC diagnostic push)
HEDLEY_PRAGMA(GCC diagnostic ignored "-Wignored-attributes")
private:
HEDLEY_PRAGMA(GCC diagnostic push)
HEDLEY_PRAGMA(GCC diagnostic ignored "-Wignored-attributes")
using parent = interval_memoizer_base<DpfKey>;
HEDLEY_PRAGMA(GCC diagnostic pop)
HEDLEY_PRAGMA(GCC diagnostic pop)
public:
using unique_ptr = typename Allocator::unique_ptr;
using return_type = typename interval_memoizer_key_t<DpfKey>::interior_node *;
@ -241,17 +245,19 @@ HEDLEY_PRAGMA(GCC diagnostic pop)
unique_ptr buf;
};
/// Every level of the interval. `retains_all_levels` is true.
/// @brief Every level of the interval. `retains_all_levels` is true.
/// @tparam DpfKey DPF key type
/// @tparam interior_node interior node
template <typename DpfKey,
typename Allocator = aligned_allocator<
typename interval_memoizer_key_t<DpfKey>::interior_node>>
struct full_tree_interval_memoizer final : public interval_memoizer_base<DpfKey>
{
HEDLEY_PRAGMA(GCC diagnostic push)
HEDLEY_PRAGMA(GCC diagnostic ignored "-Wignored-attributes")
private:
HEDLEY_PRAGMA(GCC diagnostic push)
HEDLEY_PRAGMA(GCC diagnostic ignored "-Wignored-attributes")
using parent = interval_memoizer_base<DpfKey>;
HEDLEY_PRAGMA(GCC diagnostic pop)
HEDLEY_PRAGMA(GCC diagnostic pop)
public:
using node_type = typename interval_memoizer_key_t<DpfKey>::interior_node;
using unique_ptr = typename Allocator::unique_ptr;
@ -333,7 +339,10 @@ HEDLEY_PRAGMA(GCC diagnostic pop)
}
};
/// Interval memoizer whose leaf depth is `StopLevel` (incremental `eval_interval`).
/// @brief Interval memoizer whose leaf depth is `StopLevel` (incremental `eval_interval`).
/// @tparam DpfKey DPF key type
/// @tparam StopLevel stop level
/// @tparam interior_node interior node
template <typename DpfKey, std::size_t StopLevel,
typename Allocator = aligned_allocator<
typename interval_memoizer_key_t<DpfKey>::interior_node>>
@ -441,10 +450,13 @@ auto make_interval_memoizer(InputT from, InputT to)
} // namespace detail
/// Two-level workspace sized for the closed interval `[from, to]`.
/// @brief Two-level workspace sized for the closed interval `[from, to]`.
/// @tparam DpfKey DPF key type
/// @tparam InputT input domain type
/// @param from Inclusive start, in the key's input domain.
/// @param to Inclusive end. `to` is at least `from` in that domain.
/// @snippet evaluation/memoizers.cpp interval-memoizer
/// @return Two-level workspace sized for the closed interval `[from, to]`
template <typename DpfKey,
typename InputT>
inline auto make_basic_interval_memoizer(InputT from, InputT to)
@ -463,7 +475,9 @@ inline auto make_basic_interval_memoizer(const DpfKey &, InputT from, InputT to)
return make_basic_interval_memoizer<DpfKey>(from, to);
}
/// `make_basic_interval_memoizer` sized for the whole input domain.
/// @brief `make_basic_interval_memoizer` sized for the whole input domain.
/// @tparam DpfKey DPF key type
/// @return `make_basic_interval_memoizer` sized for the whole input domain
template <typename DpfKey>
inline auto make_basic_full_memoizer()
{
@ -480,7 +494,12 @@ inline auto make_basic_full_memoizer(const DpfKey &)
return make_basic_full_memoizer<DpfKey>();
}
/// Full-tree workspace sized for the closed interval `[from, to]`.
/// @brief Full-tree workspace sized for the closed interval `[from, to]`.
/// @tparam DpfKey DPF key type
/// @tparam InputT input domain type
/// @param from the inclusive start of the range
/// @param to the `to`
/// @return Full-tree workspace sized for the closed interval `[from, to]`
template <typename DpfKey,
typename InputT>
inline auto make_full_tree_interval_memoizer(InputT from, InputT to)
@ -499,7 +518,9 @@ inline auto make_full_tree_interval_memoizer(const DpfKey &, InputT from, InputT
return make_full_tree_interval_memoizer<DpfKey>(from, to);
}
/// `make_full_tree_interval_memoizer` sized for the whole input domain.
/// @brief `make_full_tree_interval_memoizer` sized for the whole input domain.
/// @tparam DpfKey DPF key type
/// @return `make_full_tree_interval_memoizer` sized for the whole input domain
template <typename DpfKey>
inline auto make_full_tree_full_memoizer()
{
@ -522,10 +543,17 @@ inline auto make_basic_interval_memoizer_at(std::size_t leaf_nodes)
return basic_interval_memoizer_at<DpfKey, StopLevel>(leaf_nodes);
}
/// Stop-level interval memoizer for output slot `I` of a multi-level key.
/// Sizes the ping-pong buffer for the lane-domain interval `[from, to]`
/// @brief Stop-level interval memoizer for output slot `I` of a multi-level key.
/// @details Sizes the ping-pong buffer for the lane-domain interval `[from, to]`
/// expanded to `meta[I].tree_level` (the leaf level of slot `I`). This is the
/// default memoizer for a multi-level `eval_interval(out<I>, ...)`.
/// @tparam DpfKey DPF key type
/// @tparam I output index
/// @tparam InputT input domain type
/// @tparam is_multilevel is multilevel
/// @param from the inclusive start of the range
/// @param to the `to`
/// @return Stop-level interval memoizer for output slot `I` of a multi-level key
template <typename DpfKey, std::size_t I,
typename InputT,
std::enable_if_t<DpfKey::is_multilevel, bool> = true>
@ -546,7 +574,10 @@ inline auto make_basic_interval_memoizer(InputT from, InputT to)
const bool wraps = utils::interval_wraps(from_i, to_i,
utils::bitlength_of_v<InputT>);
const auto segs = utils::split_leaf_nodes(from_node, to_node, stop, wraps);
HEDLEY_PRAGMA(GCC diagnostic push)
HEDLEY_PRAGMA(GCC diagnostic ignored "-Wignored-attributes")
return basic_interval_memoizer_at<DpfKey, stop>(segs.total);
HEDLEY_PRAGMA(GCC diagnostic pop)
}
template <typename DpfKey, std::size_t I,