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
19#include <type_traits>
20#include <future>
21
22// exclude in case ROOT does not have IMT support
23#ifndef R__USE_IMT
24// No need to error out for dictionaries.
25#if !defined(__ROOTCLING__) && !defined(G__DICTIONARY)
26#error "Cannot use ROOT::Experimental::Async without defining R__USE_IMT."
27#endif
28#else
29
30namespace ROOT {
31
32// fwd declaration
33namespace Experimental {
34template <typename T>
35class TFuture;
36}
37
38namespace Detail {
39template <typename T>
41 template <typename V>
43
44protected:
46 std::future<T> fStdFut;
47 std::unique_ptr<TTaskGroup> fTg{nullptr};
48
49 TFutureImpl(std::future<T> &&fut, std::unique_ptr<TTaskGroup> &&tg) : fStdFut(std::move(fut))
50 {
51 fTg = std::move(tg);
52 };
54
55 TFutureImpl(std::future<T> &&fut) : fStdFut(std::move(fut)) {}
56
57 TFutureImpl(TFutureImpl<T> &&other) : fStdFut(std::move(other.fStdFut)), fTg(std::move(other.fTg)) {}
58
59 TFutureImpl &operator=(std::future<T> &&other) { fStdFut = std::move(other); }
60
62
63public:
65
66 TFutureImpl(const TFutureImpl<T> &other) = delete;
67
68 void wait()
69 {
70 if (fTg)
71 fTg->Wait();
72 }
73
74 bool valid() const { return fStdFut.valid(); };
75};
76}
77
78namespace Experimental {
79
80////////////////////////////////////////////////////////////////////////////////
81/// A TFuture class. It can wrap an std::future.
82template <typename T>
83class TFuture final : public ROOT::Detail::TFutureImpl<T> {
84 template <class Function, class... Args>
85 friend TFuture<
86 typename std::result_of<typename std::decay<Function>::type(typename std::decay<Args>::type...)>::type>
87 Async(Function &&f, Args &&... args);
88
89private:
90 TFuture(std::future<T> &&fut, std::unique_ptr<TTaskGroup> &&tg)
91 : ROOT::Detail::TFutureImpl<T>(std::forward<std::future<T>>(fut), std::move(tg)){};
92
93public:
94 TFuture(std::future<T> &&fut) : ROOT::Detail::TFutureImpl<T>(std::forward<std::future<T>>(fut)){};
95
96 T get()
97 {
98 this->wait();
99 return this->fStdFut.get();
100 }
101};
102/// \cond
103// Two specialisations, for void and T& as for std::future
104template <>
105class TFuture<void> final : public ROOT::Detail::TFutureImpl<void> {
106 template <class Function, class... Args>
107 friend TFuture<
108 typename std::result_of<typename std::decay<Function>::type(typename std::decay<Args>::type...)>::type>
109 Async(Function &&f, Args &&... args);
110
111private:
112 TFuture(std::future<void> &&fut, std::unique_ptr<TTaskGroup> &&tg)
113 : ROOT::Detail::TFutureImpl<void>(std::forward<std::future<void>>(fut), std::move(tg)){};
114
115public:
116 TFuture(std::future<void> &&fut) : ROOT::Detail::TFutureImpl<void>(std::forward<std::future<void>>(fut)){};
117
118 void get()
119 {
120 this->wait();
121 fStdFut.get();
122 }
123};
124
125template <typename T>
126class TFuture<T &> final : public ROOT::Detail::TFutureImpl<T &> {
127 template <class Function, class... Args>
128 friend TFuture<
129 typename std::result_of<typename std::decay<Function>::type(typename std::decay<Args>::type...)>::type>
130 Async(Function &&f, Args &&... args);
131
132private:
133 TFuture(std::future<T &> &&fut, std::unique_ptr<TTaskGroup> &&tg)
134 : ROOT::Detail::TFutureImpl<T &>(std::forward<std::future<T &>>(fut), std::move(tg)){};
135
136public:
137 TFuture(std::future<T &> &&fut) : ROOT::Detail::TFutureImpl<T &>(std::forward<std::future<T &>>(fut)){};
138
139 T &get()
140 {
141 this->wait();
142 return this->fStdFut.get();
143 }
144};
145/// \endcond
146
147////////////////////////////////////////////////////////////////////////////////
148/// Runs a function asynchronously potentially in a new thread and returns a
149/// ROOT TFuture that will hold the result.
150template <class Function, class... Args>
151TFuture<typename std::result_of<typename std::decay<Function>::type(typename std::decay<Args>::type...)>::type>
152Async(Function &&f, Args &&... args)
153{
154 // The return type according to the standard implementation of std::future
155 // the long type is due to the fact that we want to be c++11 compatible.
156 // A more elegant version would be:
157 // std::future<std::result_of_t<std::decay_t<Function>(std::decay_t<Args>...)>>
158 using Ret_t = typename std::result_of<typename std::decay<Function>::type(typename std::decay<Args>::type...)>::type;
159
160 auto thisPt = std::make_shared<std::packaged_task<Ret_t()>>(std::bind(f, args...));
161 std::unique_ptr<ROOT::Experimental::TTaskGroup> tg(new ROOT::Experimental::TTaskGroup());
162 tg->Run([thisPt]() { (*thisPt)(); });
163
164 return ROOT::Experimental::TFuture<Ret_t>(thisPt->get_future(), std::move(tg));
165}
166}
167}
168
169#endif
170#endif
typedef void(GLAPIENTRYP _GLUfuncptr)(void)
#define f(i)
Definition RSha256.hxx:104
int type
Definition TGX11.cxx:121
Double_t(* Function)(Double_t)
Definition Functor.C:4
TFutureImpl(std::future< T > &&fut, std::unique_ptr< TTaskGroup > &&tg)
Definition TFuture.hxx:49
friend class Experimental::TFuture
Definition TFuture.hxx:42
TFutureImpl< T > & operator=(TFutureImpl< T > &other)=delete
TFutureImpl & operator=(std::future< T > &&other)
Definition TFuture.hxx:59
TFutureImpl(const TFutureImpl< T > &other)=delete
TFutureImpl< T > & operator=(TFutureImpl< T > &&other)=default
std::future< T > fStdFut
Definition TFuture.hxx:46
TFutureImpl(TFutureImpl< T > &&other)
Definition TFuture.hxx:57
TFutureImpl(std::future< T > &&fut)
Definition TFuture.hxx:55
std::unique_ptr< TTaskGroup > fTg
Definition TFuture.hxx:47
A TFuture class. It can wrap an std::future.
Definition TFuture.hxx:83
TFuture(std::future< T > &&fut)
Definition TFuture.hxx:94
TFuture(std::future< T > &&fut, std::unique_ptr< TTaskGroup > &&tg)
Definition TFuture.hxx:90
friend TFuture< typename std::result_of< typename std::decay< Function >::type(typename std::decay< Args >::type...)>::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:152
A class to manage the asynchronous execution of work items.
TFuture< typename std::result_of< typename std::decay< Function >::type(typename std::decay< Args >::type...)>::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:152
double T(double x)
tbb::task_arena is an alias of tbb::interface7::task_arena, which doesn't allow to forward declare tb...
void forward(const LAYERDATA &prevLayerData, LAYERDATA &currLayerData)
apply the weights (and functions) in forward direction of the DNN