Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
TFuture.hxx
Go to the documentation of this file.
1// @(#)root/thread:$Id$
2// Author: Danilo Piparo August 2017
3
4/*************************************************************************
5 * Copyright (C) 1995-2017, Rene Brun and Fons Rademakers. *
6 * All rights reserved. *
7 * *
8 * For the licensing terms see $ROOTSYS/LICENSE. *
9 * For the list of contributors see $ROOTSYS/README/CREDITS. *
10 *************************************************************************/
11
12#ifndef ROOT_TFuture
13#define ROOT_TFuture
14
15#include "RConfigure.h"
16
17#include "ROOT/TTaskGroup.hxx"
18#include "ROOT/TypeTraits.hxx"
19
20#include <type_traits>
21#include <future>
22
23// exclude in case ROOT does not have IMT support
24#ifndef R__USE_IMT
25// No need to error out for dictionaries.
26#if !defined(__ROOTCLING__) && !defined(G__DICTIONARY)
27#error "Cannot use ROOT::Experimental::Async without defining R__USE_IMT."
28#endif
29#else
30
31namespace ROOT {
32
33// fwd declaration
34namespace Experimental {
35template <typename T>
36class TFuture;
37}
38
39namespace Detail {
40template <typename T>
42 template <typename V>
44
45protected:
47 std::future<T> fStdFut;
48 std::unique_ptr<TTaskGroup> fTg{nullptr};
49
50 TFutureImpl(std::future<T> &&fut, std::unique_ptr<TTaskGroup> &&tg) : fStdFut(std::move(fut))
51 {
52 fTg = std::move(tg);
53 };
55
56 TFutureImpl(std::future<T> &&fut) : fStdFut(std::move(fut)) {}
57
58 TFutureImpl(TFutureImpl<T> &&other) : fStdFut(std::move(other.fStdFut)), fTg(std::move(other.fTg)) {}
59
60 TFutureImpl &operator=(std::future<T> &&other) { fStdFut = std::move(other); }
61
63
64public:
66
67 TFutureImpl(const TFutureImpl<T> &other) = delete;
68
69 void wait()
70 {
71 if (fTg)
72 fTg->Wait();
73 }
74
75 bool valid() const { return fStdFut.valid(); };
76};
77}
78
79namespace Experimental {
80
81////////////////////////////////////////////////////////////////////////////////
82/// A TFuture class. It can wrap an std::future.
83template <typename T>
84class TFuture final : public ROOT::Detail::TFutureImpl<T> {
85 template <class Function, class... Args>
86 friend TFuture<
87 ROOT::TypeTraits::InvokeResult_t<typename std::decay<Function>::type, typename std::decay<Args>::type...>>
88 Async(Function &&f, Args &&...args);
89
90private:
91 TFuture(std::future<T> &&fut, std::unique_ptr<TTaskGroup> &&tg)
92 : ROOT::Detail::TFutureImpl<T>(std::forward<std::future<T>>(fut), std::move(tg)){};
93
94public:
95 TFuture(std::future<T> &&fut) : ROOT::Detail::TFutureImpl<T>(std::forward<std::future<T>>(fut)){};
96
97 T get()
98 {
99 this->wait();
100 return this->fStdFut.get();
101 }
102};
103/// \cond
104// Two specialisations, for void and T& as for std::future
105template <>
106class TFuture<void> final : public ROOT::Detail::TFutureImpl<void> {
107 template <class Function, class... Args>
108 friend TFuture<
109 ROOT::TypeTraits::InvokeResult_t<typename std::decay<Function>::type, typename std::decay<Args>::type...>>
110 Async(Function &&f, Args &&...args);
111
112private:
113 TFuture(std::future<void> &&fut, std::unique_ptr<TTaskGroup> &&tg)
114 : ROOT::Detail::TFutureImpl<void>(std::forward<std::future<void>>(fut), std::move(tg)){};
115
116public:
117 TFuture(std::future<void> &&fut) : ROOT::Detail::TFutureImpl<void>(std::forward<std::future<void>>(fut)){};
118
119 void get()
120 {
121 this->wait();
122 fStdFut.get();
123 }
124};
125
126template <typename T>
127class TFuture<T &> final : public ROOT::Detail::TFutureImpl<T &> {
128 template <class Function, class... Args>
129 friend TFuture<
130 ROOT::TypeTraits::InvokeResult_t<typename std::decay<Function>::type, typename std::decay<Args>::type...>>
131 Async(Function &&f, Args &&...args);
132
133private:
134 TFuture(std::future<T &> &&fut, std::unique_ptr<TTaskGroup> &&tg)
135 : ROOT::Detail::TFutureImpl<T &>(std::forward<std::future<T &>>(fut), std::move(tg)){};
136
137public:
138 TFuture(std::future<T &> &&fut) : ROOT::Detail::TFutureImpl<T &>(std::forward<std::future<T &>>(fut)){};
139
140 T &get()
141 {
142 this->wait();
143 return this->fStdFut.get();
144 }
145};
146/// \endcond
147
148////////////////////////////////////////////////////////////////////////////////
149/// Runs a function asynchronously potentially in a new thread and returns a
150/// ROOT TFuture that will hold the result.
151template <class Function, class... Args>
152TFuture<ROOT::TypeTraits::InvokeResult_t<typename std::decay<Function>::type, typename std::decay<Args>::type...>>
153Async(Function &&f, Args &&...args)
154{
155 // The return type according to the standard implementation of std::future
156 using Ret_t = ROOT::TypeTraits::InvokeResult_t<std::decay_t<Function>, std::decay_t<Args>...>;
157
158 auto thisPt = std::make_shared<std::packaged_task<Ret_t()>>(std::bind(f, args...));
159 std::unique_ptr<ROOT::Experimental::TTaskGroup> tg(new ROOT::Experimental::TTaskGroup());
160 tg->Run([thisPt]() { (*thisPt)(); });
161
162 return ROOT::Experimental::TFuture<Ret_t>(thisPt->get_future(), std::move(tg));
163}
164}
165}
166
167#endif
168#endif
#define f(i)
Definition RSha256.hxx:104
Double_t(* Function)(Double_t)
Definition Functor.C:4
TFutureImpl(std::future< T > &&fut, std::unique_ptr< TTaskGroup > &&tg)
Definition TFuture.hxx:50
friend class Experimental::TFuture
Definition TFuture.hxx:43
TFutureImpl< T > & operator=(TFutureImpl< T > &other)=delete
TFutureImpl & operator=(std::future< T > &&other)
Definition TFuture.hxx:60
TFutureImpl(const TFutureImpl< T > &other)=delete
TFutureImpl< T > & operator=(TFutureImpl< T > &&other)=default
std::future< T > fStdFut
Definition TFuture.hxx:47
TFutureImpl(TFutureImpl< T > &&other)
Definition TFuture.hxx:58
TFutureImpl(std::future< T > &&fut)
Definition TFuture.hxx:56
std::unique_ptr< TTaskGroup > fTg
Definition TFuture.hxx:48
A TFuture class. It can wrap an std::future.
Definition TFuture.hxx:84
friend TFuture< ROOT::TypeTraits::InvokeResult_t< typename std::decay< Function >::type, typename std::decay< Args >::type... > > Async(Function &&f, Args &&...args)
Runs a function asynchronously potentially in a new thread and returns a ROOT TFuture that will hold ...
Definition TFuture.hxx:153
TFuture(std::future< T > &&fut)
Definition TFuture.hxx:95
TFuture(std::future< T > &&fut, std::unique_ptr< TTaskGroup > &&tg)
Definition TFuture.hxx:91
A class to manage the asynchronous execution of work items.
TFuture< ROOT::TypeTraits::InvokeResult_t< typename std::decay< Function >::type, typename std::decay< Args >::type... > > Async(Function &&f, Args &&...args)
Runs a function asynchronously potentially in a new thread and returns a ROOT TFuture that will hold ...
Definition TFuture.hxx:153
double T(double x)
This file contains a specialised ROOT message handler to test for diagnostic in unit tests.
void forward(const LAYERDATA &prevLayerData, LAYERDATA &currLayerData)
apply the weights (and functions) in forward direction of the DNN