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