Skip to content

Commit a49e31a

Browse files
committed
Use own wrapper class DeferredFuture
1 parent 15c3eae commit a49e31a

5 files changed

Lines changed: 104 additions & 21 deletions

File tree

CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -468,6 +468,7 @@ set(CORE_SOURCE
468468
src/WriteIterations.cpp
469469
src/auxiliary/Date.cpp
470470
src/auxiliary/Filesystem.cpp
471+
src/auxiliary/Future.cpp
471472
src/auxiliary/JSON.cpp
472473
src/auxiliary/Mpi.cpp
473474
src/backend/Attributable.cpp

include/openPMD/LoadStoreChunk.hpp

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#pragma once
22

33
#include "openPMD/Dataset.hpp"
4+
#include "openPMD/auxiliary/Future.hpp"
45
#include "openPMD/auxiliary/ShareRawInternal.hpp"
56
#include "openPMD/auxiliary/UniquePtr.hpp"
67

@@ -141,13 +142,15 @@ namespace core
141142
enqueueStore(F &&createBuffer) -> DynamicMemoryView<T>;
142143

143144
template <typename T>
144-
[[nodiscard]] auto enqueueLoad() -> std::future<std::shared_ptr<T>>;
145+
[[nodiscard]] auto
146+
enqueueLoad() -> auxiliary::DeferredFuture<std::shared_ptr<T>>;
145147

146148
template <typename T>
147149
[[nodiscard]] auto load(EnqueuePolicy) -> std::shared_ptr<T>;
148150

149-
[[nodiscard]] auto enqueueLoadVariant()
150-
-> std::future<auxiliary::detail::shared_ptr_dataset_types>;
151+
[[nodiscard]] auto
152+
enqueueLoadVariant() -> auxiliary::DeferredFuture<
153+
auxiliary::detail::shared_ptr_dataset_types>;
151154

152155
[[nodiscard]] auto loadVariant(EnqueuePolicy)
153156
-> auxiliary::detail::shared_ptr_dataset_types;
@@ -164,7 +167,7 @@ namespace core
164167

165168
auto storeChunkConfig() -> internal::LoadStoreConfigWithBuffer;
166169

167-
auto enqueueStore() -> std::future<void>;
170+
auto enqueueStore() -> auxiliary::DeferredFuture<void>;
168171

169172
auto store(EnqueuePolicy) -> void;
170173

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
#pragma once
2+
3+
#include "openPMD/auxiliary/TypeTraits.hpp"
4+
5+
#include <future>
6+
7+
namespace openPMD::auxiliary
8+
{
9+
template <typename T>
10+
class DeferredFuture
11+
{
12+
using task_type = std::packaged_task<T()>;
13+
using future_type = std::future<T>;
14+
future_type m_future;
15+
task_type m_task;
16+
17+
public:
18+
DeferredFuture(task_type);
19+
20+
auto get() -> T;
21+
22+
[[nodiscard]] auto valid() const noexcept -> bool;
23+
24+
auto wait() -> void;
25+
};
26+
} // namespace openPMD::auxiliary

src/LoadStoreChunk.cpp

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -113,15 +113,15 @@ namespace core
113113
}
114114

115115
template <typename T>
116-
auto ConfigureLoadStore::enqueueLoad() -> std::future<std::shared_ptr<T>>
116+
auto ConfigureLoadStore::enqueueLoad()
117+
-> auxiliary::DeferredFuture<std::shared_ptr<T>>
117118
{
118119
auto res = m_rc.loadChunkAllocate_impl<T>(storeChunkConfig());
119-
return std::async(
120-
std::launch::deferred,
120+
return auxiliary::DeferredFuture(std::packaged_task(
121121
[res_lambda = std::move(res), rc = m_rc]() mutable {
122122
rc.seriesFlush();
123123
return res_lambda;
124-
});
124+
}));
125125
}
126126

127127
template <typename T>
@@ -143,21 +143,22 @@ namespace core
143143
{
144144
template <typename T>
145145
static auto call(RecordComponent &rc, internal::LoadStoreConfig cfg)
146-
-> std::future<auxiliary::detail::shared_ptr_dataset_types>
146+
-> auxiliary::DeferredFuture<
147+
auxiliary::detail::shared_ptr_dataset_types>
147148
{
148149
auto res = rc.loadChunkAllocate_impl<T>(std::move(cfg));
149-
return std::async(
150-
std::launch::deferred,
150+
return auxiliary::DeferredFuture(std::packaged_task(
151151
[res_lambda = std::move(res), rc_lambda = rc]() mutable
152152
-> auxiliary::detail::shared_ptr_dataset_types {
153153
rc_lambda.seriesFlush();
154154
return res_lambda;
155-
});
155+
}));
156156
}
157157
};
158158

159159
auto ConfigureLoadStore::enqueueLoadVariant()
160-
-> std::future<auxiliary::detail::shared_ptr_dataset_types>
160+
-> auxiliary::DeferredFuture<
161+
auxiliary::detail::shared_ptr_dataset_types>
161162
{
162163
return m_rc.visit<VisitorEnqueueLoadVariant>(this->storeChunkConfig());
163164
}
@@ -202,16 +203,15 @@ namespace core
202203
}
203204

204205
template <typename Ptr_Type>
205-
auto
206-
ConfigureStoreChunkFromBuffer<Ptr_Type>::enqueueStore() -> std::future<void>
206+
auto ConfigureStoreChunkFromBuffer<Ptr_Type>::enqueueStore()
207+
-> auxiliary::DeferredFuture<void>
207208
{
208209
this->m_rc.storeChunk_impl(
209210
asWriteBuffer(std::move(m_buffer)),
210211
determineDatatype<auxiliary::IsPointer_t<Ptr_Type>>(),
211212
storeChunkConfig());
212-
return std::async(
213-
std::launch::deferred,
214-
[rc_lambda = m_rc]() mutable -> void { rc_lambda.seriesFlush(); });
213+
return auxiliary::DeferredFuture(std::packaged_task(
214+
[rc_lambda = m_rc]() mutable -> void { rc_lambda.seriesFlush(); }));
215215
}
216216

217217
template <typename Ptr_Type>
@@ -300,7 +300,7 @@ template class compose::ConfigureLoadStore<ConfigureLoadStore>;
300300
template auto core::ConfigureLoadStore::enqueueStore() \
301301
-> DynamicMemoryView<dtype>; \
302302
template auto core::ConfigureLoadStore::enqueueLoad() \
303-
-> std::future<std::shared_ptr<dtype>>; \
303+
-> auxiliary::DeferredFuture<std::shared_ptr<dtype>>; \
304304
template auto core::ConfigureLoadStore::load(EnqueuePolicy) \
305305
->std::shared_ptr<dtype>;
306306
// clang-format on
@@ -310,13 +310,15 @@ OPENPMD_FOREACH_DATASET_DATATYPE(INSTANTIATE_METHOD_TEMPLATES)
310310
#undef INSTANTIATE_METHOD_TEMPLATES
311311

312312
/* clang-format would destroy the NOLINT comments */
313-
//// clang-format off
313+
// clang-format off
314314
#define INSTANTIATE_HALF(pointer_type) \
315315
template class ConfigureStoreChunkFromBuffer<pointer_type>; \
316316
template class core::ConfigureStoreChunkFromBuffer<pointer_type>; \
317317
template class compose::ConfigureLoadStore< \
318+
/* NOLINTNEXTLINE(bugprone-macro-parentheses) */ \
318319
ConfigureStoreChunkFromBuffer<pointer_type>>; \
319320
template class compose::ConfigureStoreChunkFromBuffer< \
321+
/* NOLINTNEXTLINE(bugprone-macro-parentheses) */ \
320322
ConfigureStoreChunkFromBuffer<pointer_type>>;
321323
// clang-format on
322324

@@ -325,7 +327,7 @@ OPENPMD_FOREACH_DATASET_DATATYPE(INSTANTIATE_METHOD_TEMPLATES)
325327
#define INSTANTIATE_FULL(pointer_type) \
326328
INSTANTIATE_HALF(pointer_type) \
327329
template class ConfigureLoadStoreFromBuffer<pointer_type>; \
328-
template class core::ConfigureLoadStoreFromBuffer<pointer_type>; \
330+
template class core::ConfigureLoadStoreFromBuffer<pointer_type>; \
329331
template class compose::ConfigureLoadStore< \
330332
/* NOLINTNEXTLINE(bugprone-macro-parentheses) */ \
331333
ConfigureLoadStoreFromBuffer<pointer_type>>; \

src/auxiliary/Future.cpp

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
#include "openPMD/auxiliary/Future.hpp"
2+
#include "openPMD/LoadStoreChunk.hpp"
3+
4+
#include <memory>
5+
6+
// comment
7+
8+
#include "openPMD/DatatypeMacros.hpp"
9+
10+
namespace openPMD::auxiliary
11+
{
12+
13+
template <typename T>
14+
DeferredFuture<T>::DeferredFuture(task_type task)
15+
: m_future(task.get_future()), m_task(std::move(task))
16+
{}
17+
18+
template <typename T>
19+
auto DeferredFuture<T>::get() -> T
20+
{
21+
if (m_future.valid())
22+
{
23+
m_task();
24+
} // else get() was already called, propagate the std::future behavior
25+
return m_future.get();
26+
}
27+
28+
template <typename T>
29+
auto DeferredFuture<T>::valid() const noexcept -> bool
30+
{
31+
return m_future.valid();
32+
}
33+
34+
template <typename T>
35+
auto DeferredFuture<T>::wait() -> void
36+
{
37+
if (!m_task.valid())
38+
{
39+
m_task();
40+
}
41+
}
42+
43+
template class DeferredFuture<void>;
44+
template class DeferredFuture<auxiliary::detail::shared_ptr_dataset_types>;
45+
#define INSTANTIATE_FUTURE(dtype) \
46+
template class DeferredFuture<std::shared_ptr<dtype>>;
47+
OPENPMD_FOREACH_DATASET_DATATYPE(INSTANTIATE_FUTURE)
48+
#undef INSTANTIATE_FUTURE
49+
} // namespace openPMD::auxiliary
50+
51+
#include "openPMD/UndefDatatypeMacros.hpp"

0 commit comments

Comments
 (0)