DDC 0.1.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 <memory_resource>
8#include <string>
9#include <type_traits>
10#include <utility>
11#include <vector>
12
13#include <pdi.h>
14
15#include "ddc/chunk_traits.hpp"
16#include "ddc/discrete_vector.hpp"
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 /// a memory buffer where temporary variables are stored until the class is destroyed
36 std::pmr::monotonic_buffer_resource m_metadata;
37
38public:
39 explicit PdiEvent(std::string const& event_name) : m_event_name(event_name) {}
40
41 PdiEvent(PdiEvent const& rhs) = delete;
42
43 PdiEvent(PdiEvent&& rhs) noexcept = delete;
44
45 ~PdiEvent() noexcept
46 {
47 PDI_event(m_event_name.c_str());
48 for (std::string const& one_name : m_names) {
49 PDI_reclaim(one_name.c_str());
50 }
51 }
52
53 PdiEvent& operator=(PdiEvent const& rhs) = delete;
54
55 PdiEvent& operator=(PdiEvent&& rhs) noexcept = delete;
56
57 /// @{
58 /// API with access argument
59
60 template <
61 PDI_inout_t access,
62 class BorrowedChunk,
63 std::enable_if_t<is_borrowed_chunk_v<BorrowedChunk>, int> = 0>
64 PdiEvent& with(std::string const& name, BorrowedChunk&& data)
65 {
66 static_assert(
67 !(access & PDI_IN) || (chunk_default_access_v<BorrowedChunk> & PDI_IN),
68 "Invalid access for constant data");
69 auto extents = detail::array(data.domain().extents());
70 std::size_t& rank = *std::pmr::polymorphic_allocator<std::size_t>(&m_metadata).allocate(1);
71 rank = extents.size();
72 PDI_share((name + "_rank").c_str(), &rank, PDI_OUT);
73 m_names.push_back(name + "_rank");
74 PDI_share(
75 (name + "_extents").c_str(),
76 std::pmr::vector<std::size_t>(extents.begin(), extents.end(), &m_metadata).data(),
77 PDI_OUT);
78 m_names.push_back(name + "_extents");
79 PDI_share(
80 name.c_str(),
81 const_cast<chunk_value_t<BorrowedChunk>*>(data.data_handle()),
82 access);
83 m_names.push_back(name);
84 return *this;
85 }
86
87 template <
88 PDI_inout_t access,
89 class Arithmetic,
90 std::enable_if_t<std::is_arithmetic_v<std::remove_reference_t<Arithmetic>>, int> = 0>
91 PdiEvent& with(std::string const& name, Arithmetic&& data)
92 {
93 static_assert(
94 !(access & PDI_IN) || (default_access_v<Arithmetic> & PDI_IN),
95 "Invalid access for constant data");
96 using value_type = std::remove_cv_t<std::remove_reference_t<Arithmetic>>;
97 value_type* data_ptr = const_cast<value_type*>(&data);
98 // for read-only data, we share a copy instead of the data itself in case we received a ref on a temporary,
99 if constexpr (!(access & PDI_IN)) {
100 data_ptr = std::pmr::polymorphic_allocator<value_type>(&m_metadata).allocate(1);
101 *data_ptr = data;
102 }
103 PDI_share(name.c_str(), data_ptr, access);
104 m_names.push_back(name);
105 return *this;
106 }
107
108 template <PDI_inout_t access, class T>
109 PdiEvent& and_with(std::string const& name, T&& t)
110 {
111 return with<access>(name, std::forward<T>(t));
112 }
113
114 /// @}
115 /// API with access deduction
116 /// @{
117
118 /// Borrowed chunk overload (Chunk (const)& or ChunkSpan&& or ChunkSpan (const)&)
119 template <class BorrowedChunk, std::enable_if_t<is_borrowed_chunk_v<BorrowedChunk>, int> = 0>
120 PdiEvent& with(std::string const& name, BorrowedChunk&& data)
121 {
122 return with<chunk_default_access_v<BorrowedChunk>>(name, std::forward<BorrowedChunk>(data));
123 }
124
125 /// Arithmetic overload
126 template <
127 class Arithmetic,
128 std::enable_if_t<std::is_arithmetic_v<std::remove_reference_t<Arithmetic>>, int> = 0>
129 PdiEvent& with(std::string const& name, Arithmetic&& data)
130 {
131 return with<default_access_v<Arithmetic>>(name, std::forward<Arithmetic>(data));
132 }
133
134 /// With synonym
135 template <class T>
136 PdiEvent& and_with(std::string const& name, T&& t)
137 {
138 return with(name, std::forward<T>(t));
139 }
140
141 /// @}
142};
143
144template <PDI_inout_t access, class DataType>
145void expose_to_pdi(std::string const& name, DataType&& data)
146{
147 PdiEvent(name).with<access>(name, std::forward<DataType>(data));
148}
149
150template <class DataType>
151void expose_to_pdi(std::string const& name, DataType&& data)
152{
153 PdiEvent(name).with(name, std::forward<DataType>(data));
154}
155
156} // namespace ddc
PdiEvent(PdiEvent const &rhs)=delete
PdiEvent & and_with(std::string const &name, T &&t)
With synonym.
Definition pdi.hpp:136
PdiEvent & and_with(std::string const &name, T &&t)
Definition pdi.hpp:109
PdiEvent & operator=(PdiEvent &&rhs) noexcept=delete
~PdiEvent() noexcept
Definition pdi.hpp:45
PdiEvent & operator=(PdiEvent const &rhs)=delete
PdiEvent(std::string const &event_name)
Definition pdi.hpp:39
PdiEvent & with(std::string const &name, Arithmetic &&data)
Arithmetic overload.
Definition pdi.hpp:129
PdiEvent & with(std::string const &name, BorrowedChunk &&data)
API with access deduction.
Definition pdi.hpp:120
PdiEvent & with(std::string const &name, Arithmetic &&data)
Definition pdi.hpp:91
PdiEvent & with(std::string const &name, BorrowedChunk &&data)
Definition pdi.hpp:64
PdiEvent(PdiEvent &&rhs) noexcept=delete
The top-level namespace of DDC.
void expose_to_pdi(std::string const &name, DataType &&data)
Definition pdi.hpp:145
void expose_to_pdi(std::string const &name, DataType &&data)
Definition pdi.hpp:151