DDC 0.4.1
Loading...
Searching...
No Matches
pdi.hpp
1// Copyright (C) The DDC development team, see COPYRIGHT.md file
2//
3// SPDX-License-Identifier: MIT
4
5#pragma once
6
7#include <any>
8#include <list>
9#include <string>
10#include <type_traits>
11#include <utility>
12#include <vector>
13
14#include <pdi.h>
15
16#include "ddc/chunk_traits.hpp"
17#include "ddc/discrete_vector.hpp"
18
19namespace ddc {
20
21template <class T>
22static constexpr PDI_inout_t default_access_v
23 = (std::is_lvalue_reference_v<T> && !std::is_const_v<std::remove_reference_t<T>>)
24 ? PDI_INOUT
25 : PDI_OUT;
26
27template <class T>
28static constexpr PDI_inout_t chunk_default_access_v = is_writable_chunk_v<T> ? PDI_INOUT : PDI_OUT;
29
30class PdiEvent
31{
32 std::string m_event_name;
33
34 std::vector<std::string> m_names;
35
36 std::list<std::any> m_metadata;
37
38 char const* store_name(std::string&& name)
39 {
40 return m_names.emplace_back(std::move(name)).c_str();
41 }
42
43 char const* store_name(std::string const& name)
44 {
45 return m_names.emplace_back(name).c_str();
46 }
47
48 template <class T>
49 T* store_scalar(T t)
50 {
51 std::any& ref = m_metadata.emplace_back(std::in_place_type<T>, std::move(t));
52 return std::any_cast<T>(&ref);
53 }
54
55 template <class T>
56 T* store_array(std::vector<T> v)
57 {
58 std::any& ref = m_metadata.emplace_back(std::in_place_type<std::vector<T>>, std::move(v));
59 return std::any_cast<std::vector<T>>(&ref)->data();
60 }
61
62public:
63 explicit PdiEvent(std::string const& event_name) : m_event_name(event_name) {}
64
65 PdiEvent(PdiEvent const& rhs) = delete;
66
67 PdiEvent(PdiEvent&& rhs) noexcept = delete;
68
69 ~PdiEvent() noexcept
70 {
71 PDI_event(m_event_name.c_str());
72 for (std::string const& one_name : m_names) {
73 PDI_reclaim(one_name.c_str());
74 }
75 }
76
77 PdiEvent& operator=(PdiEvent const& rhs) = delete;
78
79 PdiEvent& operator=(PdiEvent&& rhs) noexcept = delete;
80
81 /// @{
82 /// API with access argument
83
84 template <
85 PDI_inout_t access,
86 class BorrowedChunk,
87 std::enable_if_t<is_borrowed_chunk_v<BorrowedChunk>, int> = 0>
88 PdiEvent& with(std::string const& name, BorrowedChunk&& data)
89 {
90 static_assert(
91 !(access & PDI_IN) || (chunk_default_access_v<BorrowedChunk> & PDI_IN),
92 "Invalid access for constant data");
93 std::array const extents = detail::array(data.domain().extents());
94 PDI_share(store_name(name + "_rank"), store_scalar(extents.size()), PDI_OUT);
95 PDI_share(
96 store_name(name + "_extents"),
97 store_array(std::vector<std::size_t>(extents.begin(), extents.end())),
98 PDI_OUT);
99 PDI_share(
100 store_name(name),
101 const_cast<chunk_value_t<BorrowedChunk>*>(data.data_handle()),
102 access);
103 return *this;
104 }
105
106 template <
107 PDI_inout_t access,
108 class Arithmetic,
109 std::enable_if_t<std::is_arithmetic_v<std::remove_reference_t<Arithmetic>>, int> = 0>
110 PdiEvent& with(std::string const& name, Arithmetic&& data)
111 {
112 static_assert(
113 !(access & PDI_IN) || (default_access_v<Arithmetic> & PDI_IN),
114 "Invalid access for constant data");
115 using value_type = std::remove_cv_t<std::remove_reference_t<Arithmetic>>;
116 value_type* data_ptr = const_cast<value_type*>(&data);
117 // for read-only data, we share a copy instead of the data itself in case we received a ref on a temporary,
118 if constexpr (!(access & PDI_IN)) {
119 data_ptr = store_scalar(data);
120 }
121 PDI_share(store_name(name), data_ptr, access);
122 return *this;
123 }
124
125#if defined(DDC_BUILD_DEPRECATED_CODE)
126 template <PDI_inout_t access, class T>
127 [[deprecated("Use 'with' instead.")]] PdiEvent& and_with(std::string const& name, T&& t)
128 {
129 return with<access>(name, std::forward<T>(t));
130 }
131#endif
132
133 /// @}
134 /// API with access deduction
135 /// @{
136
137 /// Borrowed chunk overload (Chunk (const)& or ChunkSpan&& or ChunkSpan (const)&)
138 template <class BorrowedChunk, std::enable_if_t<is_borrowed_chunk_v<BorrowedChunk>, int> = 0>
139 PdiEvent& with(std::string const& name, BorrowedChunk&& data)
140 {
141 return with<chunk_default_access_v<BorrowedChunk>>(name, std::forward<BorrowedChunk>(data));
142 }
143
144 /// Arithmetic overload
145 template <
146 class Arithmetic,
147 std::enable_if_t<std::is_arithmetic_v<std::remove_reference_t<Arithmetic>>, int> = 0>
148 PdiEvent& with(std::string const& name, Arithmetic&& data)
149 {
150 return with<default_access_v<Arithmetic>>(name, std::forward<Arithmetic>(data));
151 }
152
153#if defined(DDC_BUILD_DEPRECATED_CODE)
154 /// With synonym
155 template <class T>
156 [[deprecated("Use 'with' instead.")]] PdiEvent& and_with(std::string const& name, T&& t)
157 {
158 return with(name, std::forward<T>(t));
159 }
160#endif
161
162 /// @}
163};
164
165template <PDI_inout_t access, class DataType>
166void expose_to_pdi(std::string const& name, DataType&& data)
167{
168 PdiEvent(name).with<access>(name, std::forward<DataType>(data));
169}
170
171template <class DataType>
172void expose_to_pdi(std::string const& name, DataType&& data)
173{
174 PdiEvent(name).with(name, std::forward<DataType>(data));
175}
176
177} // namespace ddc
PdiEvent(PdiEvent const &rhs)=delete
PdiEvent & operator=(PdiEvent &&rhs) noexcept=delete
~PdiEvent() noexcept
Definition pdi.hpp:69
PdiEvent & operator=(PdiEvent const &rhs)=delete
PdiEvent(std::string const &event_name)
Definition pdi.hpp:63
PdiEvent & with(std::string const &name, Arithmetic &&data)
Arithmetic overload.
Definition pdi.hpp:148
PdiEvent & with(std::string const &name, BorrowedChunk &&data)
API with access deduction.
Definition pdi.hpp:139
PdiEvent & with(std::string const &name, Arithmetic &&data)
Definition pdi.hpp:110
PdiEvent & with(std::string const &name, BorrowedChunk &&data)
Definition pdi.hpp:88
PdiEvent(PdiEvent &&rhs) noexcept=delete
The top-level namespace of DDC.
void expose_to_pdi(std::string const &name, DataType &&data)
Definition pdi.hpp:166
void expose_to_pdi(std::string const &name, DataType &&data)
Definition pdi.hpp:172