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
  • Loading branch information
maartenarnst committed Sep 20, 2024
1 parent c29bfca commit 1024a71
Show file tree
Hide file tree
Showing 3 changed files with 150 additions and 13 deletions.
26 changes: 13 additions & 13 deletions core/src/View/Kokkos_ViewCtor.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -106,14 +106,12 @@ 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(const ViewCtorProp &) = default;
ViewCtorProp &operator=(const ViewCtorProp &) = default;
ViewCtorProp() = default;

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 +211,12 @@ 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 ...
*/
ViewCtorProp() = default;

//! Construct from a matching argument list.
template <typename... Args>
inline ViewCtorProp(Args const &...args) : ViewCtorProp<void, 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 All @@ -236,11 +235,12 @@ struct ViewCtorProp : public ViewCtorProp<void, P>... {
template <typename... Args>
ViewCtorProp(view_ctor_prop_args<Args...> const &arg)
: view_ctor_prop_base<Args>(
static_cast<view_ctor_prop_base<Args> const &>(arg))... {
// Suppress an unused argument warning that (at least at one point) would
// show up if sizeof...(Args) == 0
(void)arg;
}
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))... {}
};

#if !defined(KOKKOS_COMPILER_MSVC) || !defined(KOKKOS_COMPILER_NVCC)
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 @@ -282,6 +282,7 @@ foreach(Tag Threads;Serial;OpenMP;Cuda;HPX;OpenMPTarget;OpenACC;HIP;SYCL)
ViewCopy_b
ViewCopy_c
ViewCtorDimMatch
ViewCtorProp
ViewEmptyRuntimeUnmanaged
ViewHooks
ViewLayoutStrideAssignment
Expand Down
136 changes: 136 additions & 0 deletions core/unit_test/TestViewCtorProp.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
//@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 Test {

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

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

static_assert(!Kokkos::Impl::is_view_label<char*>::value);
}

// Check traits of Kokkos::Impl::ViewCtorProp<void, std::string>.
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>);

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

// Check traits of Kokkos::Impl::ViewCtorProp<std::string>.
TEST(TEST_CATEGORY, vcp_label_traits) {
using vcp_label_base_t = Kokkos::Impl::ViewCtorProp<void, std::string>;
using vcp_label_t = Kokkos::Impl::ViewCtorProp<std::string>;

static_assert(std::is_base_of_v<vcp_label_base_t, vcp_label_t>);

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

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

// Check functions related to Kokkos::Impl::ViewCtorProp<std::string>.
TEST(TEST_CATEGORY, vcp_label_fcns) {
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();

static_assert(!decltype(prop_empty)::has_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),
"our label");
}

} // namespace Test

0 comments on commit 1024a71

Please sign in to comment.