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:
parent
0d8a5a8131
commit
0dff6df8ed
250 changed files with 12199 additions and 1981 deletions
|
|
@ -148,8 +148,18 @@ inline auto eval_sequence(const DpfKey & dpf, ForwardIterator begin, ForwardIter
|
|||
}
|
||||
}
|
||||
|
||||
/// Evaluate the sorted range `[begin, end)`, allocating a buffer.
|
||||
/// @brief Evaluate the sorted range `[begin, end)`, allocating a buffer.
|
||||
/// @tparam I output index
|
||||
/// @tparam Is is
|
||||
/// @tparam DpfKey DPF key type
|
||||
/// @tparam ForwardIterator forward iterator type
|
||||
/// @tparam ReturnType return type
|
||||
/// @tparam DpfKey DPF key type
|
||||
/// @tparam ReturnType return type
|
||||
/// @param return_type `return_entire_node_tag_{}` or `return_output_only_tag_{}`.
|
||||
/// @param dpf the DPF key
|
||||
/// @param begin the iterator to the first query
|
||||
/// @param end the iterator past the last query
|
||||
/// @return Pair of buffer (or tuple of buffers) and an iterable in list order.
|
||||
template <std::size_t I = 0,
|
||||
std::size_t ...Is,
|
||||
|
|
@ -188,8 +198,8 @@ inline auto eval_sequence_breadth_first(const DpfKey & dpf, ForwardIterator begi
|
|||
HEDLEY_PRAGMA(GCC diagnostic push)
|
||||
HEDLEY_PRAGMA(GCC diagnostic ignored "-Wignored-attributes")
|
||||
using allocator = aligned_allocator<typename DpfKey::interior_node>;
|
||||
using unique_ptr = typename allocator::unique_ptr;
|
||||
HEDLEY_PRAGMA(GCC diagnostic pop)
|
||||
using unique_ptr = typename allocator::unique_ptr;
|
||||
allocator alloc = allocator{};
|
||||
|
||||
if (HEDLEY_UNLIKELY(!std::is_sorted(begin, end)))
|
||||
|
|
@ -219,6 +229,8 @@ HEDLEY_PRAGMA(GCC diagnostic pop)
|
|||
dpf.correction_word(level_index-1, 0),
|
||||
dpf.correction_word(level_index-1, 1)
|
||||
};
|
||||
const bool is_last = dpf_type::tree::is_last_level(level_index - 1,
|
||||
dpf_type::depth);
|
||||
// `lower` and `upper` are always adjacent elements of `splits` with `lower` < `upper`
|
||||
// [lower, upper) = "block"
|
||||
for (auto upper = std::begin(splits), lower = upper++; upper != std::end(splits); lower = upper++)
|
||||
|
|
@ -228,16 +240,16 @@ HEDLEY_PRAGMA(GCC diagnostic pop)
|
|||
[&flip](auto a, auto b){ return static_cast<bool>(a&b) ^ flip; });
|
||||
if (it == *lower) // right only since first element in "block" requires right traversal
|
||||
{
|
||||
memo[curhalf*nodes_in_sequence + i++] = dpf_type::traverse_interior(memo[!curhalf*nodes_in_sequence + j++], cw[1], 1);
|
||||
memo[curhalf*nodes_in_sequence + i++] = dpf_type::traverse_interior(memo[!curhalf*nodes_in_sequence + j++], cw[1], 1, is_last);
|
||||
}
|
||||
else if (it == *upper) // left only since no element in "block" requires right traversal
|
||||
{
|
||||
memo[curhalf*nodes_in_sequence + i++] = dpf_type::traverse_interior(memo[!curhalf*nodes_in_sequence + j++], cw[0], 0);
|
||||
memo[curhalf*nodes_in_sequence + i++] = dpf_type::traverse_interior(memo[!curhalf*nodes_in_sequence + j++], cw[0], 0, is_last);
|
||||
}
|
||||
else // both ways since some (non-lower) element within "block" requires right traversal
|
||||
{
|
||||
auto cur_node = memo[!curhalf*nodes_in_sequence + j++];
|
||||
auto kids = dpf_type::traverse_interior01(cur_node, cw[0], cw[1]);
|
||||
auto kids = dpf_type::traverse_interior01(cur_node, cw[0], cw[1], is_last);
|
||||
memo[curhalf*nodes_in_sequence + i++] = kids[0];
|
||||
memo[curhalf*nodes_in_sequence + i++] = kids[1];
|
||||
splits.insert(upper, it);
|
||||
|
|
@ -259,6 +271,7 @@ HEDLEY_PRAGMA(GCC diagnostic pop)
|
|||
HEDLEY_PRAGMA(GCC diagnostic push)
|
||||
HEDLEY_PRAGMA(GCC diagnostic ignored "-Wignored-attributes")
|
||||
auto cw = dpf.template leaf<I>();
|
||||
HEDLEY_PRAGMA(GCC diagnostic pop)
|
||||
auto buf = memo.get();
|
||||
|
||||
constexpr auto clz = utils::countl_zero_symmetric_difference<input_type>{};
|
||||
|
|
@ -278,7 +291,6 @@ HEDLEY_PRAGMA(GCC diagnostic ignored "-Wignored-attributes")
|
|||
}
|
||||
prev = curr++;
|
||||
}
|
||||
HEDLEY_PRAGMA(GCC diagnostic pop)
|
||||
|
||||
return subsequence_iterable<DpfKey, decltype(std::begin(outbuf)), ForwardIterator>(std::begin(outbuf), begin, end);
|
||||
}
|
||||
|
|
@ -324,6 +336,8 @@ inline auto eval_sequence_interior(const DpfKey & dpf, const sequence_recipe & r
|
|||
dpf.correction_word(level_index-1, 0),
|
||||
dpf.correction_word(level_index-1, 1)
|
||||
};
|
||||
const bool is_last = dpf_type::tree::is_last_level(level_index - 1,
|
||||
dpf_type::depth);
|
||||
|
||||
auto prevbuf = memoizer[level_index-1];
|
||||
auto currbuf = memoizer[level_index];
|
||||
|
|
@ -334,12 +348,12 @@ inline auto eval_sequence_interior(const DpfKey & dpf, const sequence_recipe & r
|
|||
if (memoizer.traverse_first(recipe_index) == true)
|
||||
{
|
||||
bool dir = memoizer.get_direction(0);
|
||||
currbuf[output_index++] = dpf_type::traverse_interior(prevbuf[input_index], cw[dir], dir);
|
||||
currbuf[output_index++] = dpf_type::traverse_interior(prevbuf[input_index], cw[dir], dir, is_last);
|
||||
}
|
||||
if (memoizer.traverse_second(recipe_index) == true)
|
||||
{
|
||||
bool dir = memoizer.get_direction(1);
|
||||
currbuf[output_index++] = dpf_type::traverse_interior(prevbuf[input_index], cw[dir], dir);
|
||||
currbuf[output_index++] = dpf_type::traverse_interior(prevbuf[input_index], cw[dir], dir, is_last);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -362,6 +376,7 @@ inline auto eval_sequence_exterior_entire_node(const DpfKey & dpf, const sequenc
|
|||
HEDLEY_PRAGMA(GCC diagnostic push)
|
||||
HEDLEY_PRAGMA(GCC diagnostic ignored "-Wignored-attributes")
|
||||
auto buf = memoizer[dpf.depth];
|
||||
HEDLEY_PRAGMA(GCC diagnostic pop)
|
||||
DPF_UNROLL_LOOP
|
||||
for (std::size_t j = 0; j < nodes_in_interval; ++j)
|
||||
{
|
||||
|
|
@ -375,7 +390,6 @@ HEDLEY_PRAGMA(GCC diagnostic ignored "-Wignored-attributes")
|
|||
std::memcpy(&outbuf[j*dpf_type::outputs_per_leaf], &leaf, sizeof(output_type)*dpf_type::outputs_per_leaf);
|
||||
}
|
||||
}
|
||||
HEDLEY_PRAGMA(GCC diagnostic pop)
|
||||
}
|
||||
|
||||
template <std::size_t I,
|
||||
|
|
@ -393,6 +407,7 @@ inline auto eval_sequence_exterior_output_only(const DpfKey & dpf, const sequenc
|
|||
HEDLEY_PRAGMA(GCC diagnostic push)
|
||||
HEDLEY_PRAGMA(GCC diagnostic ignored "-Wignored-attributes")
|
||||
auto cw = dpf.template leaf<I>();
|
||||
HEDLEY_PRAGMA(GCC diagnostic pop)
|
||||
using node_type = typename DpfKey::exterior_node;
|
||||
using leaf_node_type = std::tuple_element_t<I, typename DpfKey::leaf_tuple>;
|
||||
auto buf = memoizer[dpf.depth];
|
||||
|
|
@ -417,7 +432,6 @@ HEDLEY_PRAGMA(GCC diagnostic ignored "-Wignored-attributes")
|
|||
else
|
||||
outbuf[i] = v;
|
||||
}
|
||||
HEDLEY_PRAGMA(GCC diagnostic pop)
|
||||
}
|
||||
|
||||
template <std::size_t ...Is,
|
||||
|
|
@ -454,9 +468,21 @@ auto eval_sequence(const DpfKey & dpf, const sequence_recipe & recipe,
|
|||
|
||||
} // namespace internal
|
||||
|
||||
/// Evaluate `recipe` into a named buffer, reusing `memoizer`.
|
||||
/// @brief Evaluate `recipe` into a named buffer, reusing `memoizer`.
|
||||
/// @tparam I output index
|
||||
/// @tparam Is is
|
||||
/// @tparam DpfKey DPF key type
|
||||
/// @tparam OutputBuffers tuple of output buffers
|
||||
/// @tparam SequenceMemoizer sequence memoizer
|
||||
/// @tparam ReturnType return type
|
||||
/// @tparam SequenceMemoizer sequence memoizer
|
||||
/// @tparam ReturnType return type
|
||||
/// @param recipe The same object `memoizer` was constructed from.
|
||||
/// @param outbufs Named buffer. The returned iterable refers into it.
|
||||
/// @param dpf the DPF key
|
||||
/// @param memoizer the memoizer built for this key
|
||||
/// @param return_type `return_entire_node_tag_{}` or `return_output_only_tag_{}`
|
||||
/// @return the evaluation result
|
||||
template <std::size_t I = 0,
|
||||
std::size_t ...Is,
|
||||
typename DpfKey,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue