Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
232 changes: 189 additions & 43 deletions include/experimental/__p1673_bits/blas2_matrix_rank_1_update.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -114,12 +114,13 @@ struct is_custom_symmetric_matrix_rank_1_update_avail<
: std::true_type
{};

template <class Exec, class x_t, class A_t, class Tr_t, class = void>
struct is_custom_hermitian_matrix_rank_1_update_avail : std::false_type {};
template <class Exec, class ScaleFactorType, class x_t, class A_t, class Tr_t, class = void>
struct is_custom_hermitian_matrix_rank_1_update_avail : std::false_type
{};

template <class Exec, class x_t, class A_t, class Tr_t>
struct is_custom_hermitian_matrix_rank_1_update_avail<
Exec, x_t, A_t, Tr_t,
Exec, void, x_t, A_t, Tr_t,
std::enable_if_t<
std::is_void_v<
decltype(hermitian_matrix_rank_1_update
Expand All @@ -133,7 +134,28 @@ struct is_custom_hermitian_matrix_rank_1_update_avail<
&& !linalg::impl::is_inline_exec_v<Exec>
>
>
: std::true_type{};
: std::true_type
{};

template <class Exec, class ScaleFactorType, class x_t, class A_t, class Tr_t>
struct is_custom_hermitian_matrix_rank_1_update_avail<
Exec, ScaleFactorType, x_t, A_t, Tr_t,
std::enable_if_t<
std::is_void_v<
decltype(hermitian_matrix_rank_1_update
(std::declval<Exec>(),
std::declval<ScaleFactorType>(),
std::declval<x_t>(),
std::declval<A_t>(),
std::declval<Tr_t>()
)
)
>
&& !linalg::impl::is_inline_exec_v<Exec>
>
>
: std::true_type
{};

} // end anonymous namespace

Expand Down Expand Up @@ -297,7 +319,7 @@ void symmetric_matrix_rank_1_update(
std::experimental::mdspan<ElementType_A, std::experimental::extents<SizeType_A, numRows_A, numCols_A>, Layout_A, Accessor_A> A,
Triangle /* t */)
{
using size_type = ::std::common_type_t<SizeType_x, SizeType_A>;
using size_type = std::common_type_t<SizeType_x, SizeType_A>;

if constexpr (std::is_same_v<Triangle, lower_triangle_t>) {
for (size_type j = 0; j < A.extent(1); ++j) {
Expand Down Expand Up @@ -482,25 +504,139 @@ void symmetric_matrix_rank_1_update(

// Rank-k update of a Hermitian matrix

// Rank-1 update of a Hermitian matrix with scaling factor alpha

MDSPAN_TEMPLATE_REQUIRES(
class ScaleFactorType,
class ElementType_x,
class SizeType_x, ::std::size_t ext_x,
class Layout_x,
class Accessor_x,
class ElementType_A,
class SizeType_A, ::std::size_t numRows_A,
::std::size_t numCols_A,
class Layout_A,
class Accessor_A,
class Triangle,
/* requires */ (
std::is_same_v<Triangle, lower_triangle_t> ||
std::is_same_v<Triangle, upper_triangle_t>
)
)
void hermitian_matrix_rank_1_update(
std::experimental::linalg::impl::inline_exec_t&& /* exec */,
ScaleFactorType alpha,
std::experimental::mdspan<ElementType_x, std::experimental::extents<SizeType_x, ext_x>, Layout_x, Accessor_x> x,
std::experimental::mdspan<ElementType_A, std::experimental::extents<SizeType_A, numRows_A, numCols_A>, Layout_A, Accessor_A> A,
Triangle /* t */)
{
using size_type = std::common_type_t<SizeType_x, SizeType_A>;

if constexpr (std::is_same_v<Triangle, lower_triangle_t>) {
for (size_type j = 0; j < A.extent(1); ++j) {
for (size_type i = j; i < A.extent(0); ++i) {
A(i,j) += alpha * x(i) * impl::conj_if_needed(x(j));
}
}
}
else {
for (size_type j = 0; j < A.extent(1); ++j) {
for (size_type i = 0; i <= j; ++i) {
A(i,j) += alpha * x(i) * impl::conj_if_needed(x(j));
}
}
}
}

MDSPAN_TEMPLATE_REQUIRES(
class ExecutionPolicy,
class ScaleFactorType,
class ElementType_x,
class SizeType_x, ::std::size_t ext_x,
class Layout_x,
class Accessor_x,
class ElementType_A,
class SizeType_A, ::std::size_t numRows_A,
::std::size_t numCols_A,
class Layout_A,
class Accessor_A,
class Triangle,
/* requires */ (
impl::is_linalg_execution_policy_other_than_inline_v<ExecutionPolicy> &&
(std::is_same_v<Triangle, lower_triangle_t> ||
std::is_same_v<Triangle, upper_triangle_t>)
)
)
void hermitian_matrix_rank_1_update(
ExecutionPolicy&& exec,
ScaleFactorType alpha,
std::experimental::mdspan<ElementType_x, std::experimental::extents<SizeType_x, ext_x>, Layout_x, Accessor_x> x,
std::experimental::mdspan<ElementType_A, std::experimental::extents<SizeType_A, numRows_A, numCols_A>, Layout_A, Accessor_A> A,
Triangle t)
{
constexpr bool use_custom = is_custom_hermitian_matrix_rank_1_update_avail<
decltype(execpolicy_mapper(exec)), ScaleFactorType, decltype(x), decltype(A), Triangle
>::value;

if constexpr (use_custom) {
hermitian_matrix_rank_1_update(execpolicy_mapper(exec), alpha, x, A, t);
} else {
hermitian_matrix_rank_1_update(std::experimental::linalg::impl::inline_exec_t(), alpha, x, A, t);
}
}

MDSPAN_TEMPLATE_REQUIRES(
class ScaleFactorType,
class ElementType_x,
class SizeType_x, ::std::size_t ext_x,
class Layout_x,
class Accessor_x,
class ElementType_A,
class SizeType_A, ::std::size_t numRows_A,
::std::size_t numCols_A,
class Layout_A,
class Accessor_A,
class Triangle,
/* requires */ (
(! impl::is_linalg_execution_policy_other_than_inline_v<ScaleFactorType>) &&
(std::is_same_v<Triangle, lower_triangle_t> ||
std::is_same_v<Triangle, upper_triangle_t>)
)
)
void hermitian_matrix_rank_1_update(
ScaleFactorType alpha,
std::experimental::mdspan<ElementType_x, std::experimental::extents<SizeType_x, ext_x>, Layout_x, Accessor_x> x,
std::experimental::mdspan<ElementType_A, std::experimental::extents<SizeType_A, numRows_A, numCols_A>, Layout_A, Accessor_A> A,
Triangle t)
{
hermitian_matrix_rank_1_update(std::experimental::linalg::impl::default_exec_t(), alpha, x, A, t);
}

// Rank-1 update of a Hermitian matrix without scaling factor alpha

template<class ElementType_x,
class SizeType_x, ::std::size_t ext_x,
class Layout_x,
class Accessor_x,
class ElementType_A,
class SizeType_A, ::std::size_t numRows_A,
::std::size_t numCols_A,
class Layout_A,
class Accessor_A,
class Triangle>
MDSPAN_TEMPLATE_REQUIRES(
class ElementType_x,
class SizeType_x, ::std::size_t ext_x,
class Layout_x,
class Accessor_x,
class ElementType_A,
class SizeType_A, ::std::size_t numRows_A,
::std::size_t numCols_A,
class Layout_A,
class Accessor_A,
class Triangle,
/* requires */ (
std::is_same_v<Triangle, lower_triangle_t> ||
std::is_same_v<Triangle, upper_triangle_t>
)
)
void hermitian_matrix_rank_1_update(
std::experimental::linalg::impl::inline_exec_t&& /* exec */,
std::experimental::mdspan<ElementType_x, std::experimental::extents<SizeType_x, ext_x>, Layout_x, Accessor_x> x,
std::experimental::mdspan<ElementType_A, std::experimental::extents<SizeType_A, numRows_A, numCols_A>, Layout_A, Accessor_A> A,
Triangle /* t */)
{
using size_type = ::std::common_type_t<SizeType_x, SizeType_A>;
using size_type = std::common_type_t<SizeType_x, SizeType_A>;

if constexpr (std::is_same_v<Triangle, lower_triangle_t>) {
for (size_type j = 0; j < A.extent(1); ++j) {
Expand All @@ -518,47 +654,57 @@ void hermitian_matrix_rank_1_update(
}
}

template<class ExecutionPolicy,
class ElementType_x,
class SizeType_x, ::std::size_t ext_x,
class Layout_x,
class Accessor_x,
class ElementType_A,
class SizeType_A, ::std::size_t numRows_A,
::std::size_t numCols_A,
class Layout_A,
class Accessor_A,
class Triangle>
MDSPAN_TEMPLATE_REQUIRES(
class ExecutionPolicy,
class ElementType_x,
class SizeType_x, ::std::size_t ext_x,
class Layout_x,
class Accessor_x,
class ElementType_A,
class SizeType_A, ::std::size_t numRows_A,
::std::size_t numCols_A,
class Layout_A,
class Accessor_A,
class Triangle,
/* requires */ (
impl::is_linalg_execution_policy_other_than_inline_v<ExecutionPolicy> &&
(std::is_same_v<Triangle, lower_triangle_t> ||
std::is_same_v<Triangle, upper_triangle_t>)
)
)
void hermitian_matrix_rank_1_update(
ExecutionPolicy&& exec,
std::experimental::mdspan<ElementType_x, std::experimental::extents<SizeType_x, ext_x>, Layout_x, Accessor_x> x,
std::experimental::mdspan<ElementType_A, std::experimental::extents<SizeType_A, numRows_A, numCols_A>, Layout_A, Accessor_A> A,
Triangle t)
{

constexpr bool use_custom = is_custom_hermitian_matrix_rank_1_update_avail<
decltype(execpolicy_mapper(exec)), decltype(x), decltype(A), Triangle
decltype(execpolicy_mapper(exec)), void, decltype(x), decltype(A), Triangle
>::value;

if constexpr(use_custom){
if constexpr (use_custom) {
hermitian_matrix_rank_1_update(execpolicy_mapper(exec), x, A, t);
}
else
{
} else {
hermitian_matrix_rank_1_update(std::experimental::linalg::impl::inline_exec_t(), x, A, t);
}
}

template<class ElementType_x,
class SizeType_x, ::std::size_t ext_x,
class Layout_x,
class Accessor_x,
class ElementType_A,
class SizeType_A, ::std::size_t numRows_A,
::std::size_t numCols_A,
class Layout_A,
class Accessor_A,
class Triangle>
MDSPAN_TEMPLATE_REQUIRES(
class ElementType_x,
class SizeType_x, ::std::size_t ext_x,
class Layout_x,
class Accessor_x,
class ElementType_A,
class SizeType_A, ::std::size_t numRows_A,
::std::size_t numCols_A,
class Layout_A,
class Accessor_A,
class Triangle,
/* requires */ (
std::is_same_v<Triangle, lower_triangle_t> ||
std::is_same_v<Triangle, upper_triangle_t>
)
)
void hermitian_matrix_rank_1_update(
std::experimental::mdspan<ElementType_x, std::experimental::extents<SizeType_x, ext_x>, Layout_x, Accessor_x> x,
std::experimental::mdspan<ElementType_A, std::experimental::extents<SizeType_A, numRows_A, numCols_A>, Layout_A, Accessor_A> A,
Expand Down
1 change: 1 addition & 0 deletions tests/native/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ linalg_add_test(gemv_no_ambig)
linalg_add_test(givens)
linalg_add_test(hemm)
linalg_add_test(herk)
linalg_add_test(her)
linalg_add_test(idx_abs_max)
linalg_add_test(iterator)
linalg_add_test(matrix_inf_norm)
Expand Down
Loading