Skip to content

Commit

Permalink
Fix nrm2w unification layer, add nrm2w_squared test
Browse files Browse the repository at this point in the history
  • Loading branch information
brian-kelley committed Mar 3, 2022
1 parent 8911130 commit 1f7a45e
Show file tree
Hide file tree
Showing 4 changed files with 261 additions and 24 deletions.
26 changes: 14 additions & 12 deletions src/blas/KokkosBlas1_nrm2w.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,8 @@ nrm2w(const XVector& x, const XVector& w) {
typename XVector::device_type, Kokkos::MemoryTraits<Kokkos::Unmanaged> >
XVector_Internal;

typedef Kokkos::View<mag_type, Kokkos::LayoutLeft, Kokkos::HostSpace,
typedef Kokkos::View<mag_type, typename XVector_Internal::array_layout,
Kokkos::HostSpace,
Kokkos::MemoryTraits<Kokkos::Unmanaged> >
RVector_Internal;

Expand Down Expand Up @@ -134,20 +135,21 @@ void nrm2w(const RV& R, const XMV& X, const XMV& W,
KokkosKernels::Impl::throw_runtime_exception(os.str());
}

using UnifiedXLayout =
typename KokkosKernels::Impl::GetUnifiedLayout<XMV>::array_layout;
using UnifiedRVLayout =
typename KokkosKernels::Impl::GetUnifiedLayoutPreferring<
RV, UnifiedXLayout>::array_layout;

// Create unmanaged versions of the input Views. RV and XMV may be
// rank 1 or rank 2.
typedef Kokkos::View<
typename std::conditional<RV::rank == 0,
typename RV::non_const_value_type,
typename RV::non_const_value_type*>::type,
typename KokkosKernels::Impl::GetUnifiedLayout<RV>::array_layout,
typename RV::device_type, Kokkos::MemoryTraits<Kokkos::Unmanaged> >
typedef Kokkos::View<typename RV::non_const_data_type, UnifiedRVLayout,
typename RV::device_type,
Kokkos::MemoryTraits<Kokkos::Unmanaged> >
RV_Internal;
typedef Kokkos::View<
typename std::conditional<XMV::rank == 1, typename XMV::const_value_type*,
typename XMV::const_value_type**>::type,
typename KokkosKernels::Impl::GetUnifiedLayout<XMV>::array_layout,
typename XMV::device_type, Kokkos::MemoryTraits<Kokkos::Unmanaged> >
typedef Kokkos::View<typename XMV::const_data_type, UnifiedXLayout,
typename XMV::device_type,
Kokkos::MemoryTraits<Kokkos::Unmanaged> >
XMV_Internal;

RV_Internal R_internal = R;
Expand Down
26 changes: 14 additions & 12 deletions src/blas/KokkosBlas1_nrm2w_squared.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,8 @@ nrm2w_squared(const XVector& x, const XVector& w) {
typename XVector::device_type, Kokkos::MemoryTraits<Kokkos::Unmanaged> >
XVector_Internal;

typedef Kokkos::View<mag_type, Kokkos::LayoutLeft, Kokkos::HostSpace,
typedef Kokkos::View<mag_type, typename XVector_Internal::array_layout,
Kokkos::HostSpace,
Kokkos::MemoryTraits<Kokkos::Unmanaged> >
RVector_Internal;

Expand Down Expand Up @@ -135,20 +136,21 @@ void nrm2w_squared(
KokkosKernels::Impl::throw_runtime_exception(os.str());
}

using UnifiedXLayout =
typename KokkosKernels::Impl::GetUnifiedLayout<XMV>::array_layout;
using UnifiedRVLayout =
typename KokkosKernels::Impl::GetUnifiedLayoutPreferring<
RV, UnifiedXLayout>::array_layout;

// Create unmanaged versions of the input Views. RV and XMV may be
// rank 1 or rank 2.
typedef Kokkos::View<
typename std::conditional<RV::rank == 0,
typename RV::non_const_value_type,
typename RV::non_const_value_type*>::type,
typename KokkosKernels::Impl::GetUnifiedLayout<RV>::array_layout,
typename RV::device_type, Kokkos::MemoryTraits<Kokkos::Unmanaged> >
typedef Kokkos::View<typename RV::non_const_data_type, UnifiedRVLayout,
typename RV::device_type,
Kokkos::MemoryTraits<Kokkos::Unmanaged> >
RV_Internal;
typedef Kokkos::View<
typename std::conditional<XMV::rank == 1, typename XMV::const_value_type*,
typename XMV::const_value_type**>::type,
typename KokkosKernels::Impl::GetUnifiedLayout<XMV>::array_layout,
typename XMV::device_type, Kokkos::MemoryTraits<Kokkos::Unmanaged> >
typedef Kokkos::View<typename XMV::const_data_type, UnifiedXLayout,
typename XMV::device_type,
Kokkos::MemoryTraits<Kokkos::Unmanaged> >
XMV_Internal;

RV_Internal R_internal = R;
Expand Down
1 change: 1 addition & 0 deletions unit_test/blas/Test_Blas.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include "Test_Blas1_nrm1.hpp"
#include "Test_Blas1_nrm2_squared.hpp"
#include "Test_Blas1_nrm2.hpp"
#include "Test_Blas1_nrm2w_squared.hpp"
#include "Test_Blas1_nrm2w.hpp"
#include "Test_Blas1_nrminf.hpp"
#include "Test_Blas1_reciprocal.hpp"
Expand Down
232 changes: 232 additions & 0 deletions unit_test/blas/Test_Blas1_nrm2w_squared.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,232 @@
#include <gtest/gtest.h>
#include <Kokkos_Core.hpp>
#include <Kokkos_Random.hpp>
#include <KokkosBlas1_nrm2w_squared.hpp>
#include <KokkosKernels_TestUtils.hpp>

namespace Test {
template <class ViewTypeA, class Device>
void impl_test_nrm2w_squared(int N) {
typedef typename ViewTypeA::value_type ScalarA;
typedef Kokkos::ArithTraits<ScalarA> AT;

ViewTypeA a("A", N);
ViewTypeA w("W", N);

typename ViewTypeA::HostMirror h_a = Kokkos::create_mirror_view(a);
typename ViewTypeA::HostMirror h_w = Kokkos::create_mirror_view(w);

Kokkos::Random_XorShift64_Pool<typename Device::execution_space> rand_pool(
13718);

ScalarA randStart, randEnd;
Test::getRandomBounds(1.0, randStart, randEnd);
Kokkos::fill_random(a, rand_pool, randStart, randEnd);
Kokkos::fill_random(w, rand_pool, randStart, randEnd);

Kokkos::deep_copy(h_a, a);
Kokkos::deep_copy(h_w, w);

double eps = std::is_same<ScalarA, float>::value ? 2 * 1e-5 : 1e-7;

typename AT::mag_type expected_result = 0;
for (int i = 0; i < N; i++) {
typename AT::mag_type term = AT::abs(h_a(i)) / AT::abs(h_w(i));
expected_result += term * term;
}

typename AT::mag_type nonconst_result = KokkosBlas::nrm2w_squared(a, w);
EXPECT_NEAR_KK(nonconst_result, expected_result, eps * expected_result);
}

template <class ViewTypeA, class Device>
void impl_test_nrm2w_squared_mv(int N, int K) {
typedef typename ViewTypeA::value_type ScalarA;
typedef Kokkos::ArithTraits<ScalarA> AT;

typedef multivector_layout_adapter<ViewTypeA> vfA_type;

typename vfA_type::BaseType b_a("A", N, K);
typename vfA_type::BaseType b_w("W", N, K);

ViewTypeA a = vfA_type::view(b_a);
ViewTypeA w = vfA_type::view(b_w);

typedef multivector_layout_adapter<typename ViewTypeA::HostMirror> h_vfA_type;

typename h_vfA_type::BaseType h_b_a = Kokkos::create_mirror_view(b_a);
typename h_vfA_type::BaseType h_b_w = Kokkos::create_mirror_view(b_w);

typename ViewTypeA::HostMirror h_a = h_vfA_type::view(h_b_a);
typename ViewTypeA::HostMirror h_w = h_vfA_type::view(h_b_w);

Kokkos::Random_XorShift64_Pool<typename Device::execution_space> rand_pool(
13718);

ScalarA randStart, randEnd;
Test::getRandomBounds(1.0, randStart, randEnd);
Kokkos::fill_random(b_a, rand_pool, randStart, randEnd);
Kokkos::fill_random(b_w, rand_pool, randStart, randEnd);

Kokkos::deep_copy(h_b_a, b_a);
Kokkos::deep_copy(h_b_w, b_w);

typename AT::mag_type* expected_result = new typename AT::mag_type[K];
for (int j = 0; j < K; j++) {
expected_result[j] = typename AT::mag_type();
for (int i = 0; i < N; i++) {
typename AT::mag_type term = AT::abs(h_a(i, j)) / AT::abs(h_w(i, j));
expected_result[j] += term * term;
}
}

double eps = std::is_same<ScalarA, float>::value ? 2 * 1e-5 : 1e-7;

Kokkos::View<typename AT::mag_type*, Device> r("Dot::Result", K);
KokkosBlas::nrm2w_squared(r, a, w);
auto r_host = Kokkos::create_mirror_view_and_copy(Kokkos::HostSpace(), r);

for (int k = 0; k < K; k++) {
typename AT::mag_type nonconst_result = r_host(k);
EXPECT_NEAR_KK(nonconst_result, expected_result[k],
eps * expected_result[k]);
}

delete[] expected_result;
}
} // namespace Test

template <class ScalarA, class Device>
int test_nrm2w_squared() {
#if defined(KOKKOSKERNELS_INST_LAYOUTLEFT) || \
(!defined(KOKKOSKERNELS_ETI_ONLY) && \
!defined(KOKKOSKERNELS_IMPL_CHECK_ETI_CALLS))
typedef Kokkos::View<ScalarA*, Kokkos::LayoutLeft, Device> view_type_a_ll;
Test::impl_test_nrm2w_squared<view_type_a_ll, Device>(0);
Test::impl_test_nrm2w_squared<view_type_a_ll, Device>(13);
Test::impl_test_nrm2w_squared<view_type_a_ll, Device>(1024);
// Test::impl_test_nrm2<view_type_a_ll, Device>(132231);
#endif

#if defined(KOKKOSKERNELS_INST_LAYOUTRIGHT) || \
(!defined(KOKKOSKERNELS_ETI_ONLY) && \
!defined(KOKKOSKERNELS_IMPL_CHECK_ETI_CALLS))
typedef Kokkos::View<ScalarA*, Kokkos::LayoutRight, Device> view_type_a_lr;
Test::impl_test_nrm2w_squared<view_type_a_lr, Device>(0);
Test::impl_test_nrm2w_squared<view_type_a_lr, Device>(13);
Test::impl_test_nrm2w_squared<view_type_a_lr, Device>(1024);
// Test::impl_test_nrm2<view_type_a_lr, Device>(132231);
#endif

#if defined(KOKKOSKERNELS_INST_LAYOUTSTRIDE) || \
(!defined(KOKKOSKERNELS_ETI_ONLY) && \
!defined(KOKKOSKERNELS_IMPL_CHECK_ETI_CALLS))
typedef Kokkos::View<ScalarA*, Kokkos::LayoutStride, Device> view_type_a_ls;
Test::impl_test_nrm2w_squared<view_type_a_ls, Device>(0);
Test::impl_test_nrm2w_squared<view_type_a_ls, Device>(13);
Test::impl_test_nrm2w_squared<view_type_a_ls, Device>(1024);
// Test::impl_test_nrm2<view_type_a_ls, Device>(132231);
#endif

return 1;
}

template <class ScalarA, class Device>
int test_nrm2w_squared_mv() {
#if defined(KOKKOSKERNELS_INST_LAYOUTLEFT) || \
(!defined(KOKKOSKERNELS_ETI_ONLY) && \
!defined(KOKKOSKERNELS_IMPL_CHECK_ETI_CALLS))
typedef Kokkos::View<ScalarA**, Kokkos::LayoutLeft, Device> view_type_a_ll;
Test::impl_test_nrm2w_squared_mv<view_type_a_ll, Device>(0, 5);
Test::impl_test_nrm2w_squared_mv<view_type_a_ll, Device>(13, 5);
Test::impl_test_nrm2w_squared_mv<view_type_a_ll, Device>(1024, 5);
Test::impl_test_nrm2w_squared_mv<view_type_a_ll, Device>(789, 1);
// Test::impl_test_nrm2w_squared_mv<view_type_a_ll, Device>(132231,5);
#endif

#if defined(KOKKOSKERNELS_INST_LAYOUTRIGHT) || \
(!defined(KOKKOSKERNELS_ETI_ONLY) && \
!defined(KOKKOSKERNELS_IMPL_CHECK_ETI_CALLS))
typedef Kokkos::View<ScalarA**, Kokkos::LayoutRight, Device> view_type_a_lr;
Test::impl_test_nrm2w_squared_mv<view_type_a_lr, Device>(0, 5);
Test::impl_test_nrm2w_squared_mv<view_type_a_lr, Device>(13, 5);
Test::impl_test_nrm2w_squared_mv<view_type_a_lr, Device>(1024, 5);
Test::impl_test_nrm2w_squared_mv<view_type_a_lr, Device>(789, 1);
// Test::impl_test_nrm2w_squared_mv<view_type_a_lr, Device>(132231,5);
#endif

#if defined(KOKKOSKERNELS_INST_LAYOUTSTRIDE) || \
(!defined(KOKKOSKERNELS_ETI_ONLY) && \
!defined(KOKKOSKERNELS_IMPL_CHECK_ETI_CALLS))
typedef Kokkos::View<ScalarA**, Kokkos::LayoutStride, Device> view_type_a_ls;
Test::impl_test_nrm2w_squared_mv<view_type_a_ls, Device>(0, 5);
Test::impl_test_nrm2w_squared_mv<view_type_a_ls, Device>(13, 5);
Test::impl_test_nrm2w_squared_mv<view_type_a_ls, Device>(1024, 5);
Test::impl_test_nrm2w_squared_mv<view_type_a_ls, Device>(789, 1);
// Test::impl_test_nrm2w_squared_mv<view_type_a_ls, Device>(132231,5);
#endif

return 1;
}

#if defined(KOKKOSKERNELS_INST_FLOAT) || \
(!defined(KOKKOSKERNELS_ETI_ONLY) && \
!defined(KOKKOSKERNELS_IMPL_CHECK_ETI_CALLS))
TEST_F(TestCategory, nrm2w_squared_float) {
Kokkos::Profiling::pushRegion("KokkosBlas::Test::nrm2w_squared_float");
test_nrm2w_squared<float, TestExecSpace>();
Kokkos::Profiling::popRegion();
}
TEST_F(TestCategory, nrm2w_squared_mv_float) {
Kokkos::Profiling::pushRegion("KokkosBlas::Test::nrm2w_squared_mv_float");
test_nrm2w_squared_mv<float, TestExecSpace>();
Kokkos::Profiling::popRegion();
}
#endif

#if defined(KOKKOSKERNELS_INST_DOUBLE) || \
(!defined(KOKKOSKERNELS_ETI_ONLY) && \
!defined(KOKKOSKERNELS_IMPL_CHECK_ETI_CALLS))
TEST_F(TestCategory, nrm2w_squared_double) {
Kokkos::Profiling::pushRegion("KokkosBlas::Test::nrm2w_squared_double");
test_nrm2w_squared<double, TestExecSpace>();
Kokkos::Profiling::popRegion();
}
TEST_F(TestCategory, nrm2w_squared_mv_double) {
Kokkos::Profiling::pushRegion("KokkosBlas::Test::nrm2w_squared_mv_double");
test_nrm2w_squared_mv<double, TestExecSpace>();
Kokkos::Profiling::popRegion();
}
#endif

#if defined(KOKKOSKERNELS_INST_COMPLEX_DOUBLE) || \
(!defined(KOKKOSKERNELS_ETI_ONLY) && \
!defined(KOKKOSKERNELS_IMPL_CHECK_ETI_CALLS))
TEST_F(TestCategory, nrm2w_squared_complex_double) {
Kokkos::Profiling::pushRegion(
"KokkosBlas::Test::nrm2w_squared_complex_double");
test_nrm2w_squared<Kokkos::complex<double>, TestExecSpace>();
Kokkos::Profiling::popRegion();
}
TEST_F(TestCategory, nrm2w_squared_mv_complex_double) {
Kokkos::Profiling::pushRegion(
"KokkosBlas::Test::nrm2w_squared_mv_complex_double");
test_nrm2w_squared_mv<Kokkos::complex<double>, TestExecSpace>();
Kokkos::Profiling::popRegion();
}
#endif

#if defined(KOKKOSKERNELS_INST_INT) || \
(!defined(KOKKOSKERNELS_ETI_ONLY) && \
!defined(KOKKOSKERNELS_IMPL_CHECK_ETI_CALLS))
TEST_F(TestCategory, nrm2w_squared_int) {
Kokkos::Profiling::pushRegion("KokkosBlas::Test::nrm2w_squared_int");
test_nrm2w_squared<int, TestExecSpace>();
Kokkos::Profiling::popRegion();
}
TEST_F(TestCategory, nrm2w_squared_mv_int) {
Kokkos::Profiling::pushRegion("KokkosBlas::Test::nrm2w_squared_mv_int");
test_nrm2w_squared_mv<int, TestExecSpace>();
Kokkos::Profiling::popRegion();
}
#endif

0 comments on commit 1f7a45e

Please sign in to comment.