commit 83fb4650b693397fef1d412d4e1c476864126964
parent 02d5d16b48c41e5d0271054983738b4a6b100989
Author: d.levin256@gmail.com <d.levin256@gmail.com>
Date: Thu, 14 Jul 2022 19:38:11 +0100
Output expressions must use set_elements functions
Diffstat:
6 files changed, 49 insertions(+), 41 deletions(-)
diff --git a/include/kfr/base/basic_expressions.hpp b/include/kfr/base/basic_expressions.hpp
@@ -117,9 +117,8 @@ KFR_INTRINSIC internal::expression_iterator<T, E1> to_iterator(E1&& e1)
template <typename... Ts, typename T = common_type<Ts...>>
inline auto sequence(const Ts&... list)
{
- return lambda<T>([seq = std::array<T, sizeof...(Ts)>{ { static_cast<T>(list)... } }](size_t index) {
- return seq[index % seq.size()];
- });
+ return lambda<T>([seq = std::array<T, sizeof...(Ts)>{ { static_cast<T>(list)... } }](size_t index)
+ { return seq[index % seq.size()]; });
}
template <typename T = int>
@@ -148,8 +147,8 @@ KFR_INTRINSIC auto counter(T1 start)
template <typename T1, typename T2>
KFR_INTRINSIC auto counter(T1 start, T2 step)
{
- return lambda<common_type<T1, T2>>(
- [start, step](cinput_t, size_t index, auto x) { return (enumerate(x) + index) * step + start; });
+ return lambda<common_type<T1, T2>>([start, step](cinput_t, size_t index, auto x)
+ { return (enumerate(x) + index) * step + start; });
}
template <typename Gen>
@@ -534,10 +533,11 @@ struct multioutput : output_expression
{
}
template <typename T, size_t N>
- void operator()(coutput_t coutput, size_t index, const vec<T, N>& x)
+ KFR_INTRINSIC friend void set_elements(multioutput& self, coutput_t coutput, size_t index,
+ const vec<T, N>& x)
{
cfor(csize_t<0>(), csize_t<sizeof...(E)>(),
- [&](auto n) { std::get<val_of(decltype(n)())>(outputs)(coutput, index, x); });
+ [&](auto n) { set_elements(std::get<val_of(decltype(n)())>(self.outputs), coutput, index, x); });
}
std::tuple<E...> outputs;
@@ -577,9 +577,10 @@ struct expression_unpack : private expression_with_arguments<E...>, output_expre
using expression_with_arguments<E...>::size;
template <typename U, size_t N>
- KFR_MEM_INTRINSIC void operator()(coutput_t coutput, size_t index, const vec<vec<U, count>, N>& x)
+ KFR_INTRINSIC friend void set_elements(expression_unpack& self, coutput_t coutput, size_t index,
+ const vec<vec<U, count>, N>& x)
{
- output(coutput, index, x, csizeseq<count>);
+ self.output(coutput, index, x, csizeseq<count>);
}
template <typename Input, KFR_ENABLE_IF(is_input_expression<Input>)>
@@ -594,7 +595,7 @@ private:
void output(coutput_t coutput, size_t index, const vec<vec<U, count>, N>& x, csizes_t<indices...>)
{
const vec<vec<U, N>, count> xx = vec<vec<U, N>, count>::from_flatten(transpose<count>(flatten(x)));
- swallow{ (std::get<indices>(this->args)(coutput, index, xx[indices]), void(), 0)... };
+ swallow{ (set_elements(std::get<indices>(this->args), coutput, index, xx[indices]), void(), 0)... };
}
};
} // namespace internal
diff --git a/include/kfr/base/expression.hpp b/include/kfr/base/expression.hpp
@@ -171,13 +171,15 @@ void test_expression(const E& expr, size_t size, Fn&& fn, const char* expression
if (g > (1 << (maxsize - 1)))
g = 1;
- cswitch(csize<1> << csizeseq<maxsize>, next_size, [&](auto x) {
- constexpr size_t nsize = val_of(decltype(x)());
- ::testo::scope s(as_string("i = ", i, " width = ", nsize));
- test->check(c <= get_elements(expr, cinput, i, vec_shape<T, nsize>()) ==
- internal::get_fn_value<T, nsize>(i, fn),
- expression);
- });
+ cswitch(csize<1> << csizeseq<maxsize>, next_size,
+ [&](auto x)
+ {
+ constexpr size_t nsize = val_of(decltype(x)());
+ ::testo::scope s(as_string("i = ", i, " width = ", nsize));
+ test->check(c <= get_elements(expr, cinput, i, vec_shape<T, nsize>()) ==
+ internal::get_fn_value<T, nsize>(i, fn),
+ expression);
+ });
i += next_size;
}
}
@@ -451,10 +453,10 @@ CMT_INTRINSIC static size_t process(OutputExpr&& out, const InputExpr& in, size_
CMT_LOOP_NOUNROLL
for (; i < start + size / w * w; i += w)
- out(coutput, i, get_elements(in, cinput, i, vec_shape<Tin, w>()));
+ set_elements(out, coutput, i, get_elements(in, cinput, i, vec_shape<Tin, w>()));
CMT_LOOP_NOUNROLL
for (; i < start + size / groupsize * groupsize; i += groupsize)
- out(coutput, i, get_elements(in, cinput, i, vec_shape<Tin, groupsize>()));
+ set_elements(out, coutput, i, get_elements(in, cinput, i, vec_shape<Tin, groupsize>()));
in.end_block(cinput, size);
out.end_block(coutput, size);
@@ -484,10 +486,11 @@ struct output_expression_base : output_expression
virtual void output(size_t index, const T& value) = 0;
template <typename U, size_t N>
- KFR_MEM_INTRINSIC void operator()(coutput_t, size_t index, const vec<U, N>& value)
+ friend KFR_INTRINSIC void set_elements(const output_expression_base& self, coutput_t, size_t index,
+ const vec<U, N>& value)
{
for (size_t i = 0; i < N; i++)
- output(index + i, static_cast<T>(value[i]));
+ self.output(index + i, static_cast<T>(value[i]));
}
};
diff --git a/include/kfr/base/reduce.hpp b/include/kfr/base/reduce.hpp
@@ -79,10 +79,10 @@ struct expression_reduce : output_expression
}
template <size_t N>
- KFR_MEM_INTRINSIC void operator()(coutput_t, size_t, const vec<Tin, N>& x) const
+ KFR_INTRINSIC friend void set_elements(expression_reduce& self, coutput_t, size_t, const vec<Tin, N>& x)
{
- counter += N;
- process(x);
+ self.counter += N;
+ self.process(x);
}
KFR_MEM_INTRINSIC Tout get()
diff --git a/include/kfr/base/univector.hpp b/include/kfr/base/univector.hpp
@@ -99,13 +99,6 @@ struct univector_base<T, Class, true> : input_expression, output_expression
using output_expression::begin_block;
using output_expression::end_block;
- template <typename U, size_t N>
- KFR_MEM_INTRINSIC void operator()(coutput_t, size_t index, const vec<U, N>& value)
- {
- T* data = derived_cast<Class>(this)->data();
- write(ptr_cast<T>(data) + index, vec<T, N>(value));
- }
-
template <typename Input, KFR_ENABLE_IF(is_input_expression<Input>)>
KFR_MEM_INTRINSIC Class& operator=(Input&& input)
{
@@ -604,6 +597,14 @@ KFR_INTRINSIC vec<U, N> get_elements(const univector<T, Tag>& self, cinput_t, si
return static_cast<vec<U, N>>(read<N>(ptr_cast<T>(data) + index));
}
+template <typename T, univector_tag Tag, typename U, size_t N>
+KFR_INTRINSIC void set_elements(univector<T, Tag>& self, coutput_t, size_t index,
+ const vec<U, N>& value)
+{
+ T* data = self.data();
+ write(ptr_cast<T>(data) + index, vec<T, N>(value));
+}
+
/// @brief Converts an expression to univector
template <typename Expr, typename T = value_type_of<Expr>>
KFR_INTRINSIC univector<T> render(Expr&& expr)
diff --git a/include/kfr/dsp/goertzel.hpp b/include/kfr/dsp/goertzel.hpp
@@ -51,15 +51,15 @@ struct expression_goertzel : output_expression
result.imag(q2 * sin(omega));
}
template <typename U, size_t N>
- KFR_MEM_INTRINSIC void operator()(coutput_t, size_t, const vec<U, N>& x)
+ KFR_INTRINSIC friend void set_elements(expression_goertzel& self, coutput_t, size_t, const vec<U, N>& x)
{
vec<T, N> in = x;
CMT_LOOP_UNROLL
for (size_t i = 0; i < N; i++)
{
- q0 = coeff * q1 - q2 + in[i];
- q2 = q1;
- q1 = q0;
+ self.q0 = self.coeff * self.q1 - self.q2 + in[i];
+ self.q2 = self.q1;
+ self.q1 = self.q0;
}
}
complex<T>& result;
@@ -88,15 +88,16 @@ struct expression_parallel_goertzel : output_expression
}
}
template <typename U, size_t N>
- KFR_MEM_INTRINSIC void operator()(coutput_t, size_t, const vec<U, N>& x)
+ KFR_INTRINSIC friend void set_elements(expression_parallel_goertzel& self, coutput_t, size_t,
+ const vec<U, N>& x)
{
const vec<T, N> in = x;
CMT_LOOP_UNROLL
for (size_t i = 0; i < N; i++)
{
- q0 = coeff * q1 - q2 + in[i];
- q2 = q1;
- q1 = q0;
+ self.q0 = self.coeff * self.q1 - self.q2 + in[i];
+ self.q2 = self.q1;
+ self.q1 = self.q0;
}
}
complex<T>* result;
diff --git a/include/kfr/io/tostring.hpp b/include/kfr/io/tostring.hpp
@@ -236,7 +236,8 @@ namespace internal
struct expression_printer : output_expression
{
template <typename T, size_t N>
- void operator()(coutput_t, size_t index, const vec<T, N>& value)
+ KFR_INTRINSIC friend void set_elements(expression_printer& self, coutput_t, size_t index,
+ const vec<T, N>& value)
{
for (size_t i = 0; i < N; i++)
{
@@ -256,7 +257,8 @@ struct expression_printer : output_expression
struct expression_debug_printer : output_expression
{
template <typename T, size_t N>
- void operator()(coutput_t, size_t index, const vec<T, N>& value)
+ KFR_INTRINSIC friend void set_elements(expression_debug_printer& self, coutput_t, size_t index,
+ const vec<T, N>& value)
{
println(fmtwidth<7>(index), ": (", value, ")");
}