Skip to content

Commit

Permalink
Update constructor
Browse files Browse the repository at this point in the history
  • Loading branch information
maartenarnst committed Sep 23, 2024
1 parent 05ddd4b commit ab3abc6
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 70 deletions.
30 changes: 14 additions & 16 deletions core/src/View/Kokkos_ViewCtor.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ struct ViewCtorProp<void, CommonViewAllocProp<Specialize, T>> {
KOKKOS_FUNCTION
ViewCtorProp(const type &arg) : value(arg) {}
KOKKOS_FUNCTION
ViewCtorProp(type &&arg) : value(arg) {}
ViewCtorProp(type &&arg) : value(std::move(arg)) {}

type value;
};
Expand All @@ -106,7 +106,9 @@ struct ViewCtorProp<std::enable_if_t<std::is_same_v<P, AllowPadding_t> ||
/* Map input label type to std::string */
template <typename Label>
struct ViewCtorProp<std::enable_if_t<is_view_label<Label>::value>, Label> {
ViewCtorProp() = default;
ViewCtorProp() = default;
ViewCtorProp(const ViewCtorProp &) = default;
ViewCtorProp &operator=(const ViewCtorProp &) = default;

using type = std::string;

Expand Down Expand Up @@ -210,12 +212,12 @@ struct ViewCtorProp : public ViewCtorProp<void, P>... {
using memory_space = typename var_memory_space::type;
using execution_space = typename var_execution_space::type;
using pointer_type = typename var_pointer::type;

ViewCtorProp() = default;


//! Construct from a matching argument list.
template <typename... Args>
ViewCtorProp(Args &&...args)
template <typename... Args,
typename = std::enable_if_t<std::conjunction_v<
std::is_same<P, typename ViewCtorProp<void, Kokkos::Impl::remove_cvref_t<Args>>::type>...>>>
explicit ViewCtorProp(Args&&...args)
: ViewCtorProp<void, P>(std::forward<Args>(args))... {}

template <typename... Args>
Expand All @@ -233,14 +235,11 @@ struct ViewCtorProp : public ViewCtorProp<void, P>... {
// of confused. To work around this, we just use a couple of alias templates
// that amount to the same thing.
template <typename... Args>
ViewCtorProp([[maybe_unused]] view_ctor_prop_args<Args...> const &arg)
ViewCtorProp(view_ctor_prop_args<Args...> const &arg)
: view_ctor_prop_base<Args>(
static_cast<view_ctor_prop_base<Args> const &>(arg))... {}

template <typename... Args>
ViewCtorProp(view_ctor_prop_args<Args...> &&arg)
: view_ctor_prop_base<Args>(
static_cast<view_ctor_prop_base<Args> &&>(arg))... {}
//ViewCtorProp(view_ctor_prop_args<> const &) {}
};

#if !defined(KOKKOS_COMPILER_MSVC) || !defined(KOKKOS_COMPILER_NVCC)
Expand Down Expand Up @@ -454,15 +453,14 @@ inline constexpr Kokkos::Impl::AllowPadding_t AllowPadding{};
* alignment
*/
template <class... Args>
inline Impl::ViewCtorProp<typename Impl::ViewCtorProp<void, Args>::type...>
view_alloc(Args const &...args) {
auto view_alloc(Args&&...args) {
using return_type =
Impl::ViewCtorProp<typename Impl::ViewCtorProp<void, Args>::type...>;
Impl::ViewCtorProp<typename Impl::ViewCtorProp<void, Kokkos::Impl::remove_cvref_t<Args>>::type...>;

static_assert(!return_type::has_pointer,
"Cannot give pointer-to-memory for view allocation");

return return_type(args...);
return return_type(std::forward<Args>(args)...);
}

template <class... Args>
Expand Down
81 changes: 27 additions & 54 deletions core/unit_test/TestViewCtorProp.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,20 +35,22 @@ TEST(TEST_CATEGORY, is_view_label) {
TEST(TEST_CATEGORY, vcp_label_base_traits) {
using vcp_label_base_t = Kokkos::Impl::ViewCtorProp<void, std::string>;

static_assert(std::is_default_constructible_v<vcp_label_base_t>);
static_assert(std::is_copy_constructible_v<vcp_label_base_t>);
static_assert(std::is_copy_assignable_v<vcp_label_base_t>);
static_assert(std::is_move_constructible_v<vcp_label_base_t>);
static_assert(std::is_move_assignable_v<vcp_label_base_t>);

static_assert(std::is_same_v<typename vcp_label_base_t::type, std::string>);

// Check that the base class is default constructible. The default constructor
// may be called by the copy constructor of the derived class, such as when
// copy constructing a view constructor properties object from another view
// constructor properties object that holds fewer properties.
static_assert(std::is_default_constructible_v<vcp_label_base_t>);

static_assert(std::is_constructible_v<vcp_label_base_t, std::string>);
static_assert(std::is_constructible_v<vcp_label_base_t, const std::string&>);
static_assert(std::is_constructible_v<vcp_label_base_t, std::string&&>);

constexpr unsigned N = 3;
static_assert(std::is_constructible_v<vcp_label_base_t, const char[N]>);
static_assert(std::is_constructible_v<vcp_label_base_t, char[N]>);

static_assert(std::is_constructible_v<vcp_label_base_t, char*>);
}

Expand All @@ -61,75 +63,46 @@ TEST(TEST_CATEGORY, vcp_label_traits) {

static_assert(vcp_label_t::has_label);

static_assert(std::is_default_constructible_v<vcp_label_t>);
static_assert(std::is_copy_constructible_v<vcp_label_t>);
static_assert(std::is_copy_assignable_v<vcp_label_t>);
static_assert(std::is_move_constructible_v<vcp_label_t>);
static_assert(std::is_move_assignable_v<vcp_label_t>);
// Check that the derived class is not default constructible. It is a design
// choice to not allow the default constructor to be called.
static_assert(!std::is_default_constructible_v<vcp_label_t>);

static_assert(std::is_constructible_v<vcp_label_t, std::string>);
static_assert(std::is_constructible_v<vcp_label_t, const std::string&>);
static_assert(std::is_constructible_v<vcp_label_t, std::string&&>);

constexpr unsigned N = 3;
static_assert(std::is_constructible_v<vcp_label_t, const char[N]>);
static_assert(std::is_constructible_v<vcp_label_t, char*>);
static_assert(std::is_constructible_v<vcp_label_t, char[N]>);

// Kokkos::Impl::ViewCtorProp<std::string> cannot be constructed from
// a `char*` because `char*` does not satisfy `Kokkos::Impl::is_view_label`,
// hence the constructor cannot access the type alias `type`.
static_assert(!std::is_constructible_v<vcp_label_t, char*>);
}

// Check functions related to Kokkos::Impl::ViewCtorProp<std::string>.
TEST(TEST_CATEGORY, vcp_label_fcns) {
// Check that the constructor of Kokkos::Impl::ViewCtorProp<std::string>
// moves a label passed by rvalue reference.
TEST(TEST_CATEGORY, vcp_label_constructor_can_move) {
using vcp_label_t = Kokkos::Impl::ViewCtorProp<std::string>;

// Check that the user-declared constructor can move.
std::string label("our label");

vcp_label_t prop(std::move(label));

ASSERT_TRUE(label.empty());
ASSERT_EQ(Kokkos::Impl::get_property<Kokkos::Impl::LabelTag>(prop),
"our label");
}

// Check the user-declared copy onstructor.
vcp_label_t prop_copy_constr(prop);
ASSERT_EQ(Kokkos::Impl::get_property<Kokkos::Impl::LabelTag>(prop),
"our label");
ASSERT_EQ(
Kokkos::Impl::get_property<Kokkos::Impl::LabelTag>(prop_copy_constr),
"our label");

// Check the compiler-generated copy assignment operator.
vcp_label_t prop_copy_asgmt;
prop_copy_asgmt = prop;
ASSERT_EQ(Kokkos::Impl::get_property<Kokkos::Impl::LabelTag>(prop),
"our label");
ASSERT_EQ(Kokkos::Impl::get_property<Kokkos::Impl::LabelTag>(prop_copy_asgmt),
"our label");

// Check the user-declared move constructor.
vcp_label_t prop_move_constr(std::move(prop));
ASSERT_TRUE(Kokkos::Impl::get_property<Kokkos::Impl::LabelTag>(prop).empty());
ASSERT_EQ(
Kokkos::Impl::get_property<Kokkos::Impl::LabelTag>(prop_move_constr),
"our label");

// Check the compiler-generated move assignment operator.
vcp_label_t prop_move_asgmt;
prop_move_asgmt = std::move(prop_copy_asgmt);
ASSERT_TRUE(
Kokkos::Impl::get_property<Kokkos::Impl::LabelTag>(prop_copy_asgmt)
.empty());
ASSERT_EQ(Kokkos::Impl::get_property<Kokkos::Impl::LabelTag>(prop_move_asgmt),
"our label");

// Check Kokkos::Impl::with_properties_if_unset.
auto prop_empty = Kokkos::view_alloc();
// Check that Kokkos::view_alloc moves a label passed by rvalue reference.
TEST(TEST_CATEGORY, vcp_label_view_alloc_can_move) {
std::string label("our label");

static_assert(!decltype(prop_empty)::has_label);
auto prop = Kokkos::view_alloc(std::move(label));

const auto prop_with_label = Kokkos::Impl::with_properties_if_unset(
prop_empty, std::string("our label"));
static_assert(decltype(prop_with_label)::has_label);
ASSERT_EQ(Kokkos::Impl::get_property<Kokkos::Impl::LabelTag>(prop_with_label),
ASSERT_TRUE(label.empty());
ASSERT_EQ(Kokkos::Impl::get_property<Kokkos::Impl::LabelTag>(prop),
"our label");
}

Expand Down

0 comments on commit ab3abc6

Please sign in to comment.