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

@ -34,7 +34,7 @@
namespace dpf
{
/// Path memoizers key on the underlying DPF key type. `party_key` wrappers
/// @brief Path memoizers key on the underlying DPF key type. `party_key` wrappers
/// share the same tree layout, so a memoizer built for party 0 also accepts
/// party 1 (and bare keys).
template <typename T>
@ -62,10 +62,11 @@ struct path_memoizer_base
virtual return_type end() const noexcept = 0;
};
/// One interior node per level. `assign_x` returns the first level that the
/// @brief One interior node per level. `assign_x` returns the first level that the
/// next walk must recompute. `filled_to` is the deepest level already
/// written for the current input. Callers pass this object to `eval_point`;
/// they do not call `assign_x` themselves.
/// @tparam DpfKey DPF key type
template <typename DpfKey>
struct alignas(alignof(typename path_memoizer_key_t<DpfKey>::interior_node))
basic_path_memoizer final
@ -143,7 +144,8 @@ HEDLEY_PRAGMA(GCC diagnostic pop)
return std::addressof(arr_[depth+1]);
}
/// Inclusive high-water: `arr_[0..filled_to_]` are valid for the current x.
/// @brief Inclusive high-water: `arr_[0..filled_to_]` are valid for the current x.
/// @return Inclusive high-water: `arr_[0..filled_to_]` are valid for the current x
HEDLEY_NO_THROW
std::size_t filled_to() const noexcept { return filled_to_; }
@ -166,7 +168,8 @@ HEDLEY_PRAGMA(GCC diagnostic ignored "-Wignored-attributes")
HEDLEY_PRAGMA(GCC diagnostic pop)
};
/// A single interior node. Every `assign_x` restarts at the root.
/// @brief A single interior node. Every `assign_x` restarts at the root.
/// @tparam DpfKey DPF key type
template <typename DpfKey>
struct nonmemoizing_path_memoizer final
: public path_memoizer_base<path_memoizer_key_t<DpfKey>>
@ -267,7 +270,13 @@ void path_note_filled_to(PathMemoizer & path, std::size_t level)
path.note_filled(level);
}
/// Walk interior nodes so `path[0..to_level]` is valid for `x`.
/// @brief Walk interior nodes so `path[0..to_level]` is valid for `x`.
/// @tparam DpfKey DPF key type
/// @tparam PathMemoizer path memoizer type
/// @param dpf the DPF key
/// @param x the `x`
/// @param path the root-to-leaf path
/// @param to_level the `to_level`
template <typename DpfKey, typename PathMemoizer>
void ensure_level(const DpfKey & dpf, typename DpfKey::input_type x,
PathMemoizer & path, std::size_t to_level)
@ -279,17 +288,21 @@ void ensure_level(const DpfKey & dpf, typename DpfKey::input_type x,
{
bool bit = !!(mask & x);
auto cw = dpf.correction_word(level_index - 1, bit);
const bool is_last = DpfKey::tree::is_last_level(level_index - 1,
dpf.depth);
path[level_index] =
DpfKey::traverse_interior(path[level_index - 1], cw, bit);
DpfKey::traverse_interior(path[level_index - 1], cw, bit, is_last);
}
path_note_filled_to(path, to_level);
}
} // namespace detail
/// Path workspace for `DpfKey`. A `party_key` argument is unwrapped, and the
/// @brief Path workspace for `DpfKey`. A `party_key` argument is unwrapped, and the
/// result accepts both parties.
/// @snippet evaluation/memoizers.cpp path-memoizer
/// @tparam DpfKey DPF key type
/// @return Path workspace for `DpfKey`
template <typename DpfKey>
auto make_basic_path_memoizer()
{
@ -302,7 +315,9 @@ auto make_basic_path_memoizer(const DpfKey &)
return make_basic_path_memoizer<DpfKey>();
}
/// Single-node path workspace. Suitable for one query.
/// @brief Single-node path workspace. Suitable for one query.
/// @tparam DpfKey DPF key type
/// @return Single-node path workspace
template <typename DpfKey>
auto make_nonmemoizing_path_memoizer()
{