1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
// SPDX-FileCopyrightText: Copyright Contributors to the Kokkos project
#include <Kokkos_Macros.hpp>
#ifdef KOKKOS_ENABLE_EXPERIMENTAL_CXX20_MODULES
import kokkos.core;
import kokkos.core_impl;
#else
#include <Kokkos_Core.hpp>
#endif
#include <gtest/gtest.h>
namespace {
using element_t = float;
using memory_space_t = TEST_EXECSPACE::memory_space;
using defacc_t = Kokkos::default_accessor<element_t>;
using const_defacc_t = Kokkos::default_accessor<const element_t>;
using acc_t =
Kokkos::Impl::ReferenceCountedAccessor<element_t, memory_space_t, defacc_t>;
using const_acc_t =
Kokkos::Impl::ReferenceCountedAccessor<const element_t, memory_space_t,
const_defacc_t>;
using data_handle_t = typename acc_t::data_handle_type;
using const_data_handle_t = typename const_acc_t::data_handle_type;
} // namespace
TEST(TEST_CATEGORY, RefCountedAcc_Typedefs) {
static_assert(std::is_same_v<typename acc_t::element_type, element_t>);
static_assert(
std::is_same_v<
typename acc_t::data_handle_type,
Kokkos::Impl::ReferenceCountedDataHandle<element_t, memory_space_t>>);
static_assert(
std::is_same_v<typename acc_t::reference, typename defacc_t::reference>);
static_assert(
std::is_same_v<
typename acc_t::offset_policy,
Kokkos::Impl::ReferenceCountedAccessor<
element_t, memory_space_t, typename defacc_t::offset_policy>>);
}
template <class T>
KOKKOS_FUNCTION void unused_variable_sink(T) {}
void test_refcountedacc_ctors() {
Kokkos::parallel_for(Kokkos::RangePolicy<TEST_EXECSPACE>(0, 1), KOKKOS_LAMBDA(int) {
// default ctor and non-const to const
{
acc_t acc;
const_acc_t c_acc(acc);
static_assert(!std::is_constructible_v<acc_t, const_acc_t>);
unused_variable_sink(c_acc);
}
// from default_accessor
{
defacc_t defacc;
const_defacc_t c_defacc;
acc_t acc(defacc);
const_acc_t c_acc1(defacc);
const_acc_t c_acc2(c_defacc);
static_assert(!std::is_constructible_v<acc_t, const_defacc_t>);
unused_variable_sink(acc);
unused_variable_sink(c_acc1);
unused_variable_sink(c_acc2);
}
});
}
TEST(TEST_CATEGORY, RefCountedAcc_Ctors) { test_refcountedacc_ctors(); }
void test_refcountedacc_conversion_to_default_acc() {
Kokkos::parallel_for(
Kokkos::RangePolicy<TEST_EXECSPACE>(0, 1), KOKKOS_LAMBDA(int) {
// default ctor and non-const to const
acc_t acc;
const_acc_t c_acc;
defacc_t defacc(acc);
const_defacc_t c_defacc1(acc);
const_defacc_t c_defacc2(c_acc);
(void)defacc;
(void)c_defacc1;
(void)c_defacc2;
static_assert(!std::is_constructible_v<defacc_t, const_acc_t>);
});
}
TEST(TEST_CATEGORY, RefCountedAcc_ConversionToDefaultAcc) {
test_refcountedacc_conversion_to_default_acc();
}
void test_refcountedacc_access() {
element_t* ptr = static_cast<element_t*>(
Kokkos::kokkos_malloc<TEST_EXECSPACE::memory_space>(100 *
sizeof(element_t)));
// Gonna use unmanaged data handles here (i.e. not actually referfence
// counted)
data_handle_t dh(ptr);
const_data_handle_t cdh(ptr);
Kokkos::View<int, TEST_EXECSPACE> errors("Errors");
Kokkos::parallel_for(
Kokkos::RangePolicy<TEST_EXECSPACE>(0, 1), KOKKOS_LAMBDA(int) {
acc_t acc;
const_acc_t c_acc;
if (&acc.access(dh, 5) != ptr + 5) errors() += 1;
if (&c_acc.access(cdh, 5) != ptr + 5) errors() += 2;
});
int h_errors = 0;
Kokkos::deep_copy(h_errors, errors);
ASSERT_FALSE(h_errors & 1);
ASSERT_FALSE(h_errors & 2);
Kokkos::kokkos_free<TEST_EXECSPACE>(ptr);
}
TEST(TEST_CATEGORY, RefCountedAcc_Access) { test_refcountedacc_access(); }
void test_refcountedacc_conversion() {
Kokkos::parallel_for(
Kokkos::RangePolicy<TEST_EXECSPACE>(0, 1), KOKKOS_LAMBDA(int) {
using acc_anonym_t = Kokkos::Impl::ReferenceCountedAccessor<
element_t, Kokkos::AnonymousSpace, defacc_t>;
using const_acc_anonym_t = Kokkos::Impl::ReferenceCountedAccessor<
const element_t, Kokkos::AnonymousSpace, const_defacc_t>;
acc_t acc;
const_acc_t c_acc(acc);
acc_anonym_t acc_anonym(acc);
const_acc_anonym_t c_acc_anonym(acc);
acc = acc_anonym;
c_acc = acc_anonym;
static_assert(!std::is_constructible_v<acc_t, const_acc_t>);
static_assert(!std::is_constructible_v<acc_anonym_t, const_acc_t>);
static_assert(
!std::is_constructible_v<acc_anonym_t, const_acc_anonym_t>);
static_assert(
!std::is_constructible_v<Kokkos::Impl::ReferenceCountedAccessor<
double, memory_space_t, defacc_t>,
acc_t>);
unused_variable_sink(c_acc);
unused_variable_sink(c_acc_anonym);
});
}
TEST(TEST_CATEGORY, RefCountedAcc_Conversion) {
test_refcountedacc_conversion();
}
|