Tpetra parallel linear algebra Version of the Day
Loading...
Searching...
No Matches
Tpetra_Details_reallocDualViewIfNeeded.hpp
Go to the documentation of this file.
1// @HEADER
2// *****************************************************************************
3// Tpetra: Templated Linear Algebra Services Package
4//
5// Copyright 2008 NTESS and the Tpetra contributors.
6// SPDX-License-Identifier: BSD-3-Clause
7// *****************************************************************************
8// @HEADER
9
10#ifndef TPETRA_DETAILS_REALLOCDUALVIEWIFNEEDED_HPP
11#define TPETRA_DETAILS_REALLOCDUALVIEWIFNEEDED_HPP
12
19
21#include "Kokkos_DualView.hpp"
22
23namespace Tpetra {
24namespace Details {
25
49template <class ValueType, class DeviceType>
50bool reallocDualViewIfNeeded(Kokkos::DualView<ValueType*, DeviceType>& dv,
51 const size_t newSize,
52 const char newLabel[],
53 const size_t tooBigFactor = 2,
54 const bool needFenceBeforeRealloc = true) {
55 typedef typename DeviceType::execution_space execution_space;
56 typedef Kokkos::DualView<ValueType*, DeviceType> dual_view_type;
57 typedef Kokkos::pair<size_t, size_t> range_type;
58
59 // Profiling this matters, because GPU allocations can be expensive.
61 ProfilingRegion region("Tpetra::Details::reallocDualViewIfNeeded");
62
63 const size_t curSize = static_cast<size_t>(dv.extent(0));
64 if (curSize == newSize) {
65 return false; // did not reallocate
66 } else if (curSize < newSize) { // too small; need to reallocate
68 execution_space().fence(); // keep this fence to respect needFenceBeforeRealloc
69 }
70 dv = dual_view_type(); // free first, in order to save memory
71 // If current size is 0, the DualView's Views likely lack a label.
72 dv = dual_view_type(curSize == 0 ? newLabel : dv.view_device().label(), newSize);
73 return true; // we did reallocate
74 } else {
75 if (newSize == 0) { // special case: realloc to 0 means always do it
77 execution_space().fence(); // keep this fence to respect needFenceBeforeRealloc
78 }
79 // If current size is 0, the DualView's Views likely lack a label.
80 dv = dual_view_type(curSize == 0 ? newLabel : dv.view_device().label(), 0);
81 return true; // we did reallocate
82 }
83 // Instead of writing curSize >= tooBigFactor * newSize, express
84 // via division to avoid overflow (for very large right-hand side).
85 // We've already tested whether newSize == 0, so this is safe.
86 else if (curSize / newSize >= tooBigFactor) {
87 // The allocation is much too big, so free it and reallocate
88 // to the new, smaller size.
90 execution_space().fence(); // keep this fence to respect needFenceBeforeRealloc
91 }
92 dv = dual_view_type(); // free first, in order to save memory
93 // If current size is 0, the DualView's Views likely lack a label.
94 dv = dual_view_type(curSize == 0 ? newLabel : dv.view_device().label(), newSize);
95 return true; // we did reallocate
96 } else {
97 auto d_view = Kokkos::subview(dv.view_device(), range_type(0, newSize));
98 auto h_view = Kokkos::subview(dv.view_host(), range_type(0, newSize));
99 dv = Kokkos::DualView<ValueType*, DeviceType>(d_view, h_view);
100 return false; // we did not reallocate
101 }
102 }
103}
104
106template <class ValueType, class DeviceType>
107bool reallocDualViewIfNeeded(Kokkos::DualView<ValueType*, DeviceType>& exports,
108 const size_t newSize,
109 const std::string& newLabel,
110 const size_t tooBigFactor = 2,
111 const bool needFenceBeforeRealloc = true) {
113 newLabel.c_str(),
116}
117
118} // namespace Details
119} // namespace Tpetra
120
121#endif // TPETRA_DETAILS_REALLOCDUALVIEWIFNEEDED_HPP
Declaration of Tpetra::Details::Profiling, a scope guard for Kokkos Profiling.
Struct that holds views of the contents of a CrsMatrix.
Implementation details of Tpetra.
bool reallocDualViewIfNeeded(Kokkos::DualView< ValueType *, DeviceType > &dv, const size_t newSize, const char newLabel[], const size_t tooBigFactor=2, const bool needFenceBeforeRealloc=true)
Reallocate the DualView in/out argument, if needed.
Namespace Tpetra contains the class and methods constituting the Tpetra library.