Skip to content

Commit

Permalink
Fix simdize loads
Browse files Browse the repository at this point in the history
ChangeLog:

	* vir/simdize.h: Add load ctor, fix copy_from.
	* vir/test.cpp: Test simdize loads and stores.
  • Loading branch information
mattkretz committed Sep 14, 2023
1 parent fdb939c commit 6ecb156
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 5 deletions.
21 changes: 16 additions & 5 deletions vir/simdize.h
Original file line number Diff line number Diff line change
Expand Up @@ -183,16 +183,27 @@ namespace vir
*
* Precondition: [it, it + N) is a valid range.
*/
template <std::contiguous_iterator It, typename Flags = stdx::element_aligned_tag>
requires std::same_as<std::iter_value_t<It>, T>
constexpr
simd_tuple(It it, Flags = {})
: elements([&]<std::size_t... Is>(std::index_sequence<Is...>) {
return tuple_type {std::tuple_element_t<Is, tuple_type>([&](auto i) {
return struct_get<Is>(it[i]);
})...};
}(tuple_size_idx_seq))
{}

template <std::contiguous_iterator It, typename Flags = stdx::element_aligned_tag>
requires std::same_as<std::iter_value_t<It>, T>
constexpr void
copy_from(std::contiguous_iterator auto it, Flags = {})
copy_from(It it, Flags = {})
{
[&]<std::size_t... Is>(std::index_sequence<Is...>) {
((std::get<Is>(elements) = T([&](auto i) {
return struct_get<Is>(it[i]);
})), ...);
}(std::make_index_sequence<size()>());
((std::get<Is>(elements) = std::tuple_element_t<Is, tuple_type>([&](auto i) {
return struct_get<Is>(it[i]);
})), ...);
}(tuple_size_idx_seq);
}

/**
Expand Down
21 changes: 21 additions & 0 deletions vir/test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -311,6 +311,27 @@ static_assert([]() {

static_assert(vir::simdize<Point>(Point{2.f, 1.f, 0.f})[0] == Point{2.f, 1.f, 0.f});

static_assert([] {
std::array<Point, 5> data = {};
vir::simdize<Point, 4> v(data.begin());
PointTpl<DV<float, 4>> w = v;
if (not all_of(w.x == 0.f and w.y == 0.f and w.z == 0.f))
return false;
v.copy_from(data.begin() + 1);
w = v;
if (not all_of(w.x == 0.f and w.y == 0.f and w.z == 0.f))
return false;
w.x = 1.f;
w.y = DV<float, 4>([](float i) { return i; });
v = w;
v.copy_to(data.begin());
if (data != std::array<Point, 5> {Point{1, 0, 0}, {1, 1, 0}, {1, 2, 0}, {1, 3, 0}, {0, 0, 0}})
return false;
v.copy_from(data.begin() + 1);
v.copy_to(data.begin());
return data == std::array<Point, 5> {Point{1, 1, 0}, {1, 2, 0}, {1, 3, 0}, {0, 0, 0}, {0, 0, 0}};
}());

#endif // VIR_HAVE_SIMDIZE
#endif // VIR_HAVE_STRUCT_REFLECT

Expand Down

0 comments on commit 6ecb156

Please sign in to comment.