Closed fnrizzi closed 1 year ago
@fnrizzi
I caught up with all_have_traits_and_same_scalar
semantics and it looks all good - no changes required
(for me, it could be simply called all_have_same_scalar
- same like all_have_same_rank
).
@fnrizzi
Considering y = beta * y + alpha * A * x
that triggers Eigen matrix-vector product, scaling, vector summation and vector assignment:
A
and vectors x
and y
is required - Eigen will protest with assertion from Eigen/src/Core/util/XprHelper.h:830-836:
// We require Lhs and Rhs to have "compatible" scalar types.
// It is tempting to always allow mixing different types but remember that this is often impossible in the vectorized paths.
// So allowing mixing different types gives very unexpected errors when enabling vectorization, when the user tries to
// add together a float matrix and a double matrix.
#define EIGEN_CHECK_BINARY_COMPATIBILIY(BINOP,LHS,RHS) \
EIGEN_STATIC_ASSERT((Eigen::internal::has_ReturnType<ScalarBinaryOpTraits<LHS, RHS,BINOP> >::value), \
YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY)
(this assertion is not always triggered properly so eventually a compilation may fail with error: no type named ‘ReturnType’ in ‘struct Eigen::ScalarBinaryOpTraits<double, float, Eigen::internal::scalar_product_op<double, float> >’
)
custom scalar type requirements include that it can be constructed with numeric literal for the calls like Scalar(1)
in Eigen/src/Core/ProductEvaluators.h:343-365 to succeed - for example, consider this code that aims to present scalar
satisfying minimal Eigen requirements (and compiles and runs fine):
struct scalar {
scalar() = default;
scalar(double v) {} // REQUIRED
scalar& operator+=(const scalar &o) { return *this; }
};
scalar operator*(const scalar &a, const scalar &b) { return scalar{}; }
// not actually called at runtime but needed for build
scalar operator+(const scalar &a, const scalar &b) { assert("NOT ALLOWED"); return scalar{}; }
bool operator==(const scalar &a, const scalar &b) { assert("NOT ALLOWED"); return true; }
void test() {
using matrix = Eigen::Matrix<scalar, Eigen::Dynamic, Eigen::Dynamic>;
using vector = Eigen::Matrix<scalar, Eigen::Dynamic, 1>;
const int m = 4, n = 2;
const auto alpha = scalar{};
const auto beta = scalar{};
const matrix A(m, n);
const vector x(n);
vector y(m);
y = beta * y + alpha * A * x;
}
as of v3.4.90, Eigen docs is missing on scalar types support, so it's hard to tell for sure whether that's a fundamental design rule or implementation detail - but I'd bet the former (low chances for support for scalar types without zero/one in near future).
@mzuzek yes for now we should just constraint on same scalar types
@fnrizzi
Kokkos implementation of matrix-vector product can be called like ::KokkosBlas::gemv("N", alpha, A, x, beta, y)
on views with custom scalar types AScalar
, XScalar
, YScalar
under following conditions:
XType
and AType
must be convertible to YScalar
;YType
must have +=
, +
, -
, ==
, !=
and *
operators defined;operator*(const YScalar&, const XScalar&)
needs to be defined;template <class Space> struct Kokkos::Sum<YScalar, Space> {...}
definition is required for internal reductions;Kokkos::Details::ArithTraits<T>::zero()
and Kokkos::Details::ArithTraits<T>::one()
must be defined for T=YScalar
and T=AScalar
;Kokkos::Details::ArithTraits<YScalar>::conj(const YScalar&);
must be defined;Note: these conditions could be altered, but these alterations would be somewhat artificial (e.g. operator+
returning XType
for YType
arguments, instead of natural YType
).
Here's the full code: 446_ops_level2_kokkos_scalar_types.zip
Important: these constraints can be changed in future Kokkos implementations
@fnrizzi It seems that for Teuchos matrix-vector product we have no direct unit tests at all
and indirectly, only ::pressio::transpose
overload (_ops/teuchos/opslevel2.hpp:89-118) is covered by:
functional_small_solvers_nonlinear_gn_qr_exp_data_fit_n5_epetra_np2
functional_small_solvers_nonlinear_gn_qr_exp_data_fit_n5_epetra_np3
functional_small_solvers_nonlinear_gn_qr_exp_data_fit_n11_epetra_np2
functional_small_solvers_nonlinear_gn_qr_exp_data_fit_n11_epetra_np3
Hi @fnrizzi! Would there be anything else to cover under this issue or can we close it ?
no CPP20, just sfinae