Skip to content

Commit

Permalink
view(move): fixing move semantics
Browse files Browse the repository at this point in the history
  • Loading branch information
romintomasetti committed Nov 30, 2023
1 parent 0d34280 commit e3d2d6e
Show file tree
Hide file tree
Showing 4 changed files with 88 additions and 7 deletions.
21 changes: 16 additions & 5 deletions core/src/impl/Kokkos_ViewMapping.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3131,8 +3131,8 @@ class ViewMapping<

using handle_type = typename ViewDataHandle<Traits>::handle_type;

handle_type m_impl_handle;
offset_type m_impl_offset;
handle_type m_impl_handle = nullptr;
offset_type m_impl_offset {};

private:
template <class, class...>
Expand Down Expand Up @@ -3348,14 +3348,25 @@ class ViewMapping<
//----------------------------------------

KOKKOS_DEFAULTED_FUNCTION ~ViewMapping() = default;
KOKKOS_INLINE_FUNCTION ViewMapping() : m_impl_handle(), m_impl_offset() {}
KOKKOS_DEFAULTED_FUNCTION ViewMapping() = default;

KOKKOS_DEFAULTED_FUNCTION ViewMapping(const ViewMapping&) = default;
KOKKOS_DEFAULTED_FUNCTION ViewMapping& operator=(const ViewMapping&) =
default;

KOKKOS_DEFAULTED_FUNCTION ViewMapping(ViewMapping&&) = default;
KOKKOS_DEFAULTED_FUNCTION ViewMapping& operator=(ViewMapping&&) = default;
//! Move constructor. Leaves @p other in an empty state.
KOKKOS_INLINE_FUNCTION
ViewMapping(ViewMapping&& other)
: m_impl_handle(std::exchange(other.m_impl_handle, nullptr)),
m_impl_offset(std::move(other.m_impl_offset)) {}

//! Move assignment. Leaves @p other in an empty state.
KOKKOS_INLINE_FUNCTION
ViewMapping& operator=(ViewMapping&& other) {
m_impl_handle = std::exchange(other.m_impl_handle, nullptr);
m_impl_offset = std::move(other.m_impl_offset);
return *this;
}

//----------------------------------------

Expand Down
14 changes: 12 additions & 2 deletions core/src/impl/Kokkos_ViewTracker.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,10 @@ struct ViewTracker {

track_type m_tracker;

KOKKOS_INLINE_FUNCTION
ViewTracker() : m_tracker() {}
KOKKOS_DEFAULTED_FUNCTION
ViewTracker() = default;

//! Copy constructor.
KOKKOS_INLINE_FUNCTION
ViewTracker(const ViewTracker& vt) noexcept
: m_tracker(vt.m_tracker, view_traits::is_managed) {}
Expand Down Expand Up @@ -73,6 +74,7 @@ struct ViewTracker {
KOKKOS_IF_ON_DEVICE((m_tracker.assign_force_disable(vt.m_track.m_tracker);))
}

//! Copy assignment.
KOKKOS_INLINE_FUNCTION ViewTracker& operator=(
const ViewTracker& rhs) noexcept {
if (this == &rhs) return *this;
Expand All @@ -89,6 +91,14 @@ struct ViewTracker {
KOKKOS_INLINE_FUNCTION
explicit ViewTracker(const track_type& tt) noexcept
: m_tracker(tt, view_traits::is_managed) {}

//! Move constructor.
KOKKOS_DEFAULTED_FUNCTION
ViewTracker(ViewTracker&&) = default;

//! Move assignment.
KOKKOS_DEFAULTED_FUNCTION
ViewTracker& operator=(ViewTracker&& other) = default;
};

} // namespace Impl
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 @@ -240,6 +240,7 @@ foreach(Tag Threads;Serial;OpenMP;Cuda;HPX;OpenMPTarget;OpenACC;HIP;SYCL)
ViewMapping_b
ViewMapping_subview
ViewMemoryAccessViolation
ViewMove
ViewOfClass
ViewResize
WorkGraph
Expand Down
59 changes: 59 additions & 0 deletions core/unit_test/TestViewMove.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
//@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
#ifndef TESTVIEWMOVE_HPP_
#define TESTVIEWMOVE_HPP_

#include <gtest/gtest.h>
#include <Kokkos_Core.hpp>

namespace Test {

template <typename view_t>
struct TestViewMove {
template <typename T, typename = std::enable_if_t<
std::is_same_v<std::decay_t<T>, view_t>>>
TestViewMove(T&& view_) : view(std::forward<T>(view_)) {}

view_t view;
};

/**
* @test Ensure that @ref Kokkos::View and its members have proper move
* semantics.
*/
TEST(TEST_CATEGORY, view_move) {
using execution_space = TEST_EXECSPACE;
using view_t = Kokkos::View<double*, execution_space>;
using tester_t = TestViewMove<view_t>;

view_t view("view move test", 5);

EXPECT_EQ(view.use_count(), 1);
EXPECT_TRUE(view.is_allocated());

tester_t tester{std::move(view)};

//! As the view was moved, it's left in a pristine (a.k.a. *empty*) state.
EXPECT_EQ(view.use_count(), 0);
EXPECT_FALSE(view.is_allocated());

EXPECT_EQ(tester.view.use_count(), 1);
EXPECT_TRUE(tester.view.is_allocated());
}

} // namespace Test

#endif // TESTVIEWMOVE_HPP_

0 comments on commit e3d2d6e

Please sign in to comment.