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