Skip to content

Commit

Permalink
Add move semantics to ViewCtorProp and ViewCtorProp<void,std::string>…
Browse files Browse the repository at this point in the history
… for label
  • Loading branch information
maartenarnst committed Oct 4, 2024
1 parent 22fea83 commit d168c33
Show file tree
Hide file tree
Showing 3 changed files with 111 additions and 11 deletions.
26 changes: 15 additions & 11 deletions core/src/View/Kokkos_ViewCtor.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ struct ViewCtorProp<std::enable_if_t<is_view_label<Label>::value>, Label> {
using type = std::string;

ViewCtorProp(const type &arg) : value(arg) {}
ViewCtorProp(type &&arg) : value(arg) {}
ViewCtorProp(type &&arg) : value(std::move(arg)) {}

type value;
};
Expand Down Expand Up @@ -213,11 +213,16 @@ struct ViewCtorProp : public ViewCtorProp<void, P>... {
using execution_space = typename var_execution_space::type;
using pointer_type = typename var_pointer::type;

/* Copy from a matching argument list.
* Requires std::is_same< P , ViewCtorProp< void , Args >::value ...
*/
template <typename... Args>
inline ViewCtorProp(Args const &...args) : ViewCtorProp<void, P>(args)... {}
// Construct from a matching argument list.
//
// Note that if P is empty, this constructor is the default constructor.
// On the other hand, if P is not empty, the constraint implies that
// there is no default constructor.
template <typename... Args,
typename = std::enable_if_t<std::conjunction_v<
std::is_constructible<view_ctor_prop_base<P>, Args &&>...>>>
ViewCtorProp(Args &&...args)
: ViewCtorProp<void, P>(std::forward<Args>(args))... {}

template <typename... Args>
KOKKOS_FUNCTION ViewCtorProp(pointer_type arg0, Args const &...args)
Expand Down Expand Up @@ -454,15 +459,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) {
using return_type =
Impl::ViewCtorProp<typename Impl::ViewCtorProp<void, Args>::type...>;
auto view_alloc(Args &&...args) {
using return_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
1 change: 1 addition & 0 deletions core/unit_test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,7 @@ foreach(Tag Threads;Serial;OpenMP;Cuda;HPX;OpenMPTarget;OpenACC;HIP;SYCL)
ViewCopy_b
ViewCopy_c
ViewCtorDimMatch
ViewCtorProp
ViewEmptyRuntimeUnmanaged
ViewHooks
ViewLayoutStrideAssignment
Expand Down
95 changes: 95 additions & 0 deletions core/unit_test/TestViewCtorProp.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
//@HEADER
// ************************************************************************
//
// Kokkos v. 4.0
// Copyright (2022) National Technology & Engineering
// Solutions of Sandia, LLC (NTESS).
//
// Under the terms of Contract DE-NA0003525 with NTESS,
// the U.S. Government retains certain rights in this software.
//
// Part of Kokkos, under the Apache License v2.0 with LLVM Exceptions.
// See https://kokkos.org/LICENSE for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//@HEADER

#include <gtest/gtest.h>

#include <Kokkos_Core.hpp>

namespace {

using vcp_empty_t = Kokkos::Impl::ViewCtorProp<>;
using vcp_label_base_t = Kokkos::Impl::ViewCtorProp<void, std::string>;
using vcp_label_t = Kokkos::Impl::ViewCtorProp<std::string>;

// Check traits of Kokkos::Impl::ViewCtorProp<>.
TEST(TEST_CATEGORY, vcp_empty_traits) {
// Check that the empty view constructor properties class is default
// constructible. This is needed for calls of Kokkos::view_alloc().
static_assert(std::is_default_constructible_v<vcp_empty_t>);
static_assert(std::is_same_v<decltype(Kokkos::view_alloc()), vcp_empty_t>);
}

// Check Kokkos::Impl::is_view_label.
TEST(TEST_CATEGORY, is_view_label) {
static_assert(Kokkos::Impl::is_view_label<std::string>::value);

static_assert(Kokkos::Impl::is_view_label<const char[3]>::value);
static_assert(Kokkos::Impl::is_view_label<char[3]>::value);

// A char* is not a label. Thus, a label is distinguished from a pointer type.
static_assert(!Kokkos::Impl::is_view_label<char*>::value);
}

// Check traits of base class Kokkos::Impl::ViewCtorProp<void, std::string>.
TEST(TEST_CATEGORY, vcp_label_base_traits) {
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 derived classes, 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>);
}

// Check traits of derived class Kokkos::Impl::ViewCtorProp<std::string>.
TEST(TEST_CATEGORY, vcp_label_traits) {
static_assert(std::is_base_of_v<vcp_label_base_t, vcp_label_t>);

static_assert(vcp_label_t::has_label);

// 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>);
}

// Check that Kokkos::view_alloc perfect forwards a label passed by
// rvalue reference, and check that the constructor
// of Kokkos::Impl::ViewCtorProp<std::string> moves this label.
TEST(TEST_CATEGORY, view_alloc_can_perfect_forward_label) {
std::string label("our label");

auto prop = Kokkos::view_alloc(std::move(label));

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

// Check the copy constructor of Kokkos::Impl::ViewCtorProp<std::string>.
TEST(TEST_CATEGORY, vcp_label_copy_constructor) {
// Copy construction from a view constructor properties object with a label.
static_assert(std::is_copy_constructible_v<vcp_label_t>);

vcp_label_t prop = Kokkos::view_alloc("our label");
vcp_label_t prop_copy(prop);

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

} // namespace

0 comments on commit d168c33

Please sign in to comment.