MADNESS 0.10.1
taskfn.h
Go to the documentation of this file.
1/*
2 This file is part of MADNESS.
3
4 Copyright (C) 2007,2010 Oak Ridge National Laboratory
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19
20 For more information please contact:
21
22 Robert J. Harrison
23 Oak Ridge National Laboratory
24 One Bethel Valley Road
25 P.O. Box 2008, MS-6367
26
27 email: harrisonrj@ornl.gov
28 tel: 865-241-3937
29 fax: 865-572-0680
30*/
31
32#ifndef MADNESS_WORLD_TASKFN_H__INCLUDED
33#define MADNESS_WORLD_TASKFN_H__INCLUDED
34
35#include <type_traits>
39#include <madness/world/meta.h>
40
41#define MADNESS_TASKQ_VARIADICS 1
42
43namespace madness {
44
45
46 // Forward decls
47 class World;
48 class WorldTaskQueue;
49
50 namespace detail {
51 template <typename, typename, typename> class MemFuncWrapper;
52 template <typename ptrT, typename memfnT, typename resT>
53 memfnT get_mem_func_ptr(const MemFuncWrapper<ptrT, memfnT, resT>&);
54 }
55
56 /// All world tasks must be derived from this public interface
57
58 /// Multiple worlds with independent queues feed tasks into shared task
59 /// pool that is mapped to the H/W.
60 ///
61 /// For simplicity and backward compatibility we maintain two run interfaces
62 /// but new code should adopt the multithreaded interface
63 ///
64 /// \c run(World&) - the user implements this for a single-threaded task
65 ///
66 /// \c run(World&, \c const \c TaskThreadEnv&) - the user implements this for
67 /// a multi-threaded task.
68 ///
70 friend class WorldTaskQueue;
71 private:
72 volatile World* world;
74
75 // Used for submission to underlying queue when all dependencies are satisfied
83
84
85 /// Set task info
86
87 /// \param w The world object that contains the task
88 /// \param c Call this callback on completion
90 world = w;
91 completion = c;
92 }
93
94 /// Adds call back to schedule task when outstanding dependencies are satisfied
96
97 protected:
98 virtual void run(const TaskThreadEnv& env);
99
100 public:
101 static bool debug;
102
103 /// Create a new task with ndepend dependencies (default 0) and given attributes
105 : PoolTaskInterface(attr)
107 , world(0)
108 , completion(0)
109 , submit(this)
110 {}
111
112 /// Create a new task with ndepend dependencies (default 0) and given attributes,
113 /// keep track of \c caller for debugging purposes.
114 TaskInterface(int ndepend, const char* caller, const TaskAttributes attr = TaskAttributes())
115 : PoolTaskInterface(attr)
117 , world(0)
118 , completion(0)
119 , submit(this)
120 {}
121
122 /// Create a new task with zero dependencies and given attributes
123 explicit TaskInterface(const TaskAttributes& attr)
124 : PoolTaskInterface(attr)
126 , world(0)
127 , completion(0)
128 , submit(this)
129 {}
130
131// void serialize(Buffer& ar) {
132// throw "there is no way this is correct";
133// ar & *static_cast<PoolTaskInterface*>(this) & world;
134// }
135
136 /// Runs a single-threaded task ... derived classes must implement this.
137
138 /// This interface may disappear so new code should use the multi-threaded interface.
139 virtual void run(World&) {
140 //print("in virtual run(world) method");
141 MADNESS_EXCEPTION("World TaskInterface: user did not implement one of run(world) or run(world, taskthreadenv)", 0);
142 }
143
144 /// Runs a multi-threaded task
145 virtual void run(World& world, const TaskThreadEnv& env) {
146 //print("in virtual run(world,env) method", env.nthread(), env.id());
147 if (env.nthread() != 1)
148 MADNESS_EXCEPTION("World TaskInterface: user did not implement run(world, taskthreadenv) for multithreaded task", 0);
149 run(world);
150 }
151
152 World* get_world() const { return const_cast<World*>(world); }
153
155
156 }; // class TaskInterface
157
158 namespace detail {
159
160 template <typename T>
162 static const unsigned int value = 1u;
163 };
164
165 template <>
166 struct ArgCountHelper<void> {
167 static const unsigned int value = 0u;
168 };
169
170 // Counts the number of arguments that will be given to a task function
171 template <typename a1T, typename a2T, typename a3T, typename a4T, typename a5T,
172 typename a6T, typename a7T, typename a8T, typename a9T>
173 struct ArgCount : public std::integral_constant<unsigned int, ArgCountHelper<a1T>::value
174 + ArgCountHelper<a2T>::value + ArgCountHelper<a3T>::value
175 + ArgCountHelper<a4T>::value + ArgCountHelper<a5T>::value
176 + ArgCountHelper<a6T>::value + ArgCountHelper<a7T>::value
177 + ArgCountHelper<a8T>::value + ArgCountHelper<a9T>::value> {
178 };
179
180
181 /// A wrapper object for holding task function argument objects
182 template <typename Arg>
183 class ArgHolder : private NO_DEFAULTS{
184 private:
185 Arg arg_;
186 public:
187
188 template <typename Arg_ = Arg,
189 typename = std::enable_if_t<
190 !std::is_same<std::decay_t<Arg_>,
192 >>
193 ArgHolder(Arg_&& arg) : arg_(arg) { }
194
196 arg_()
197 {
198 input_arch & arg_;
199 }
200
201 operator Arg&() & { return arg_; }
202 operator const Arg&() const& { return arg_; }
203 explicit operator Arg&&() && { return std::move(arg_); }
204 }; // class ArgHolder
205
206 template <typename T>
207 struct is_arg_holder : public std::false_type {};
208 template <typename T>
209 struct is_arg_holder<ArgHolder<T>> : public std::true_type {};
210
211 template <typename T>
212 struct task_arg {
213 typedef T type;
215 };
216
217 template <typename T>
218 struct task_arg<Future<T> > {
219 typedef T type;
221 };
222
223 template <typename T>
224 struct task_arg<Future<T>* > {
225 typedef T type;
227 };
228
229 template <>
230 struct task_arg<Future<void> > {
231 typedef const Future<void> type;
232 typedef const Future<void> holderT;
233 };
234
235 template <>
236 struct task_arg<void> {
237 typedef const Future<void> type;
238 typedef const Future<void> holderT;
239 };
240
241 template <typename fnT>
247
248 /// Future<void> is an empty object which is used as a placeholder for
249 /// unused arguments.
251
252 // arg_holder::decay converts an argument holder to the corresponding argument (reference)
253 namespace arg_holder {
254
255 // specialization for ArgHolder<>&
256 template <typename T>
257 T& decay(ArgHolder<T>& arg_holder) {
258 return arg_holder;
259 }
260
261 // specialization for const ArgHolder<>&
262 template <typename T>
263 const T& decay(const ArgHolder<T>& arg_holder) {
264 return arg_holder;
265 }
266
267 // specialization for ArgHolder<>&&
268 template <typename T>
269 T&& decay(ArgHolder<T>&& arg_holder) {
270 return static_cast<T&&>(arg_holder);
271 }
272
273
274 // specialization for Future<>&
275 template <typename T>
276 T& decay(Future<T>& arg_holder) {
277 return arg_holder;
278 }
279
280 // specialization for const Future<>&
281 template <typename T>
282 const T& decay(const Future<T>& arg_holder) {
283 return arg_holder;
284 }
285
286 // specialization for Future<>&&
287 template <typename T>
288 T&& decay(Future<T>&& arg_holder) {
289 return static_cast<T&&>(arg_holder);
290 }
291
292 // specialization for Future<>*
293 template <typename T>
294 T& decay(Future<T>* arg_holder) {
295 return static_cast<T&>(*arg_holder);
296 }
297
298 // specialization for non-Future non-ArgHolder argument
299 template <typename T>
300 auto decay(T&& arg_holder) -> typename std::enable_if<
301 !is_future<T>::value && !is_arg_holder<T>::value, decltype(arg_holder)>::type{
302 return std::forward<T>(arg_holder);
303 }
304
305 } // namespace arg_holder
306
307 using arg_holder::decay;
308
309 // These functions are used to differentiate the task function calls
310 // based on the number of arguments and return type.
311
312 // Note: voidT arguments must be const or the wrong function will be
313 // selected.
314
315 template <typename fnT>
316 inline typename std::enable_if<std::is_void<typename detail::result_of<fnT>::type>::value >::type
317 run_function(Future<void>& result, fnT fn, const voidT&,
318 const voidT&, const voidT&, const voidT&, const voidT&,
319 const voidT&, const voidT&, const voidT&, const voidT&)
320 { fn(); result.set(); }
321
322 template <typename fnT, typename a1T>
323 inline typename std::enable_if<std::is_void<typename detail::result_of<fnT>::type>::value >::type
324 run_function(Future<void>& result, fnT fn, a1T& a1,
325 const voidT&, const voidT&, const voidT&, const voidT&,
326 const voidT&, const voidT&, const voidT&, const voidT&)
327 { fn(decay(a1)); result.set(); }
328
329 template <typename fnT, typename a1T, typename a2T>
330 inline typename std::enable_if<std::is_void<typename detail::result_of<fnT>::type>::value >::type
331 run_function(Future<void>& result, fnT fn, a1T& a1, a2T& a2,
332 const voidT&, const voidT&, const voidT&, const voidT&,
333 const voidT&, const voidT&, const voidT&)
334 { fn(decay(a1), decay(a2)); result.set(); }
335
336 template <typename fnT, typename a1T, typename a2T, typename a3T>
337 inline typename std::enable_if<std::is_void<typename detail::result_of<fnT>::type>::value >::type
338 run_function(Future<void>& result, fnT fn, a1T& a1, a2T& a2,
339 a3T& a3, const voidT&, const voidT&, const voidT&, const voidT&,
340 const voidT&, const voidT&)
341 { fn(decay(a1), decay(a2), decay(a3)); result.set(); }
342
343 template <typename fnT, typename a1T, typename a2T, typename a3T, typename a4T>
344 inline typename std::enable_if<std::is_void<typename detail::result_of<fnT>::type>::value >::type
345 run_function(Future<void>& result, fnT fn, a1T& a1, a2T& a2,
346 a3T& a3, a4T& a4, const voidT&, const voidT&, const voidT&,
347 const voidT&, const voidT&)
348 { fn(decay(a1), decay(a2), decay(a3), decay(a4)); result.set(); }
349
350 template <typename fnT, typename a1T, typename a2T, typename a3T, typename a4T,
351 typename a5T>
352 inline typename std::enable_if<std::is_void<typename detail::result_of<fnT>::type>::value >::type
353 run_function(Future<void>& result, fnT fn, a1T& a1, a2T& a2,
354 a3T& a3, a4T& a4, a5T& a5, const voidT&, const voidT&,
355 const voidT&, const voidT&)
356 { fn(decay(a1), decay(a2), decay(a3), decay(a4), decay(a5)); result.set(); }
357
358 template <typename fnT, typename a1T, typename a2T, typename a3T, typename a4T,
359 typename a5T, typename a6T>
360 inline typename std::enable_if<std::is_void<typename detail::result_of<fnT>::type>::value >::type
361 run_function(Future<void>& result, fnT fn, a1T& a1, a2T& a2,
362 a3T& a3, a4T& a4, a5T& a5, a6T& a6, const voidT&, const voidT&,
363 const voidT&)
364 { fn(decay(a1), decay(a2), decay(a3), decay(a4), decay(a5), decay(a6)); result.set(); }
365
366 template <typename fnT, typename a1T, typename a2T, typename a3T, typename a4T,
367 typename a5T, typename a6T, typename a7T>
368 inline typename std::enable_if<std::is_void<typename detail::result_of<fnT>::type>::value >::type
369 run_function(Future<void>& result, fnT fn, a1T& a1, a2T& a2,
370 a3T& a3, a4T& a4, a5T& a5, a6T& a6, a7T& a7, const voidT&,
371 const voidT&)
372 { fn(decay(a1), decay(a2), decay(a3), decay(a4), decay(a5), decay(a6), decay(a7)); result.set(); }
373
374 template <typename fnT, typename a1T, typename a2T, typename a3T, typename a4T,
375 typename a5T, typename a6T, typename a7T, typename a8T>
376 inline typename std::enable_if<std::is_void<typename detail::result_of<fnT>::type>::value >::type
377 run_function(Future<void>& result, fnT fn, a1T& a1, a2T& a2,
378 a3T& a3, a4T& a4, a5T& a5, a6T& a6, a7T& a7, a8T& a8, const voidT&)
379 { fn(decay(a1), decay(a2), decay(a3), decay(a4), decay(a5), decay(a6), decay(a7), decay(a8)); result.set(); }
380
381 template <typename fnT, typename a1T, typename a2T, typename a3T, typename a4T,
382 typename a5T, typename a6T, typename a7T, typename a8T, typename a9T>
383 inline typename std::enable_if<std::is_void<typename detail::result_of<fnT>::type>::value >::type
384 run_function(Future<void>& result, fnT fn, a1T& a1, a2T& a2,
385 a3T& a3, a4T& a4, a5T& a5, a6T& a6, a7T& a7, a8T& a8, a9T& a9)
386 { fn(decay(a1), decay(a2), decay(a3), decay(a4), decay(a5), decay(a6), decay(a7), decay(a8), decay(a9)); result.set(); }
387
388 template <typename fnT>
389 inline typename std::enable_if<!std::is_void<typename detail::result_of<fnT>::type>::value >::type
391 fnT fn, const voidT&, const voidT&, const voidT&, const voidT&,
392 const voidT&, const voidT&, const voidT&, const voidT&, const voidT&)
393 { result.set(fn()); }
394
395 template <typename fnT, typename a1T>
396 inline typename std::enable_if<!std::is_void<typename detail::result_of<fnT>::type>::value >::type
398 fnT fn, a1T& a1, const voidT&, const voidT&, const voidT&,
399 const voidT&, const voidT&, const voidT&, const voidT&, const voidT&)
400 { result.set(fn(decay(a1))); }
401
402 template <typename fnT, typename a1T, typename a2T>
403 inline typename std::enable_if<!std::is_void<typename detail::result_of<fnT>::type>::value >::type
405 fnT fn, a1T& a1, a2T& a2, const voidT&, const voidT&, const voidT&,
406 const voidT&, const voidT&, const voidT&, const voidT&)
407 { result.set(fn(decay(a1), decay(a2))); }
408
409 template <typename fnT, typename a1T, typename a2T, typename a3T>
410 inline typename std::enable_if<!std::is_void<typename detail::result_of<fnT>::type>::value >::type
412 fnT fn, a1T& a1, a2T& a2, a3T& a3, const voidT&, const voidT&,
413 const voidT&, const voidT&, const voidT&, const voidT&)
414 { result.set(fn(decay(a1), decay(a2), decay(a3))); }
415
416 template <typename fnT, typename a1T, typename a2T, typename a3T, typename a4T>
417 inline typename std::enable_if<!std::is_void<typename detail::result_of<fnT>::type>::value >::type
419 fnT fn, a1T& a1, a2T& a2, a3T& a3, a4T& a4, const voidT&,
420 const voidT&, const voidT&, const voidT&, const voidT&)
421 { result.set(fn(decay(a1), decay(a2), decay(a3), decay(a4))); }
422
423 template <typename fnT, typename a1T, typename a2T, typename a3T, typename a4T,
424 typename a5T>
425 inline typename std::enable_if<!std::is_void<typename detail::result_of<fnT>::type>::value >::type
427 fnT fn, a1T& a1, a2T& a2, a3T& a3, a4T& a4, a5T& a5, const voidT&,
428 const voidT&, const voidT&, const voidT&)
429 { result.set(fn(decay(a1), decay(a2), decay(a3), decay(a4), decay(a5))); }
430
431 template <typename fnT, typename a1T, typename a2T, typename a3T, typename a4T,
432 typename a5T, typename a6T>
433 inline typename std::enable_if<!std::is_void<typename detail::result_of<fnT>::type>::value >::type
435 fnT fn, a1T& a1, a2T& a2, a3T& a3, a4T& a4, a5T& a5, a6T& a6,
436 const voidT&, const voidT&, const voidT&)
437 { result.set(fn(decay(a1), decay(a2), decay(a3), decay(a4), decay(a5), decay(a6))); }
438
439 template <typename fnT, typename a1T, typename a2T, typename a3T, typename a4T,
440 typename a5T, typename a6T, typename a7T>
441 inline typename std::enable_if<!std::is_void<typename detail::result_of<fnT>::type>::value >::type
443 fnT fn, a1T& a1, a2T& a2, a3T& a3, a4T& a4, a5T& a5, a6T& a6,
444 a7T& a7, const voidT&, const voidT&)
445 { result.set(fn(decay(a1), decay(a2), decay(a3), decay(a4), decay(a5), decay(a6), decay(a7))); }
446
447 template <typename fnT, typename a1T, typename a2T, typename a3T, typename a4T,
448 typename a5T, typename a6T, typename a7T, typename a8T>
449 inline typename std::enable_if<!std::is_void<typename detail::result_of<fnT>::type>::value >::type
451 fnT fn, a1T& a1, a2T& a2, a3T& a3, a4T& a4, a5T& a5, a6T& a6,
452 a7T& a7, a8T& a8, const voidT&)
453 { result.set(fn(decay(a1), decay(a2), decay(a3), decay(a4), decay(a5), decay(a6), decay(a7), decay(a8))); }
454
455 template <typename fnT, typename a1T, typename a2T, typename a3T, typename a4T,
456 typename a5T, typename a6T, typename a7T, typename a8T, typename a9T>
457 inline typename std::enable_if<!std::is_void<typename detail::result_of<fnT>::type>::value >::type
459 fnT fn, a1T& a1, a2T& a2, a3T& a3, a4T& a4, a5T& a5, a6T& a6,
460 a7T& a7, a8T& a8, a9T& a9)
461 { result.set(fn(decay(a1), decay(a2), decay(a3), decay(a4), decay(a5), decay(a6), decay(a7), decay(a8), decay(a9))); }
462
463 } // namespace detail
464
465 /// Wrap a callable object and its arguments into a task function
466
467 /// The callable object may have up to 10 arguments
468 /// \note arg*T cannot be a reference type
469 template <typename fnT, typename arg1T = void, typename arg2T = void,
470 typename arg3T = void, typename arg4T = void, typename arg5T = void,
471 typename arg6T = void, typename arg7T = void, typename arg8T = void,
472 typename arg9T = void>
473 struct TaskFn : public TaskInterface {
474
475 static_assert(not (std::is_const<arg1T>::value || std::is_reference<arg1T>::value),
476 "improper instantiation of TaskFn, arg1T cannot be a const or reference type");
477 static_assert(not (std::is_const<arg2T>::value || std::is_reference<arg2T>::value),
478 "improper instantiation of TaskFn, arg2T cannot be a const or reference type");
479 static_assert(not (std::is_const<arg3T>::value || std::is_reference<arg3T>::value),
480 "improper instantiation of TaskFn, arg3T cannot be a const or reference type");
481 static_assert(not (std::is_const<arg4T>::value || std::is_reference<arg4T>::value),
482 "improper instantiation of TaskFn, arg4T cannot be a const or reference type");
483 static_assert(not (std::is_const<arg5T>::value || std::is_reference<arg5T>::value),
484 "improper instantiation of TaskFn, arg5T cannot be a const or reference type");
485 static_assert(not (std::is_const<arg6T>::value || std::is_reference<arg6T>::value),
486 "improper instantiation of TaskFn, arg6T cannot be a const or reference type");
487 static_assert(not (std::is_const<arg7T>::value || std::is_reference<arg7T>::value),
488 "improper instantiation of TaskFn, arg7T cannot be a const or reference type");
489 static_assert(not (std::is_const<arg8T>::value || std::is_reference<arg8T>::value),
490 "improper instantiation of TaskFn, arg8T cannot be a const or reference type");
491 static_assert(not (std::is_const<arg9T>::value || std::is_reference<arg9T>::value),
492 "improper instantiation of TaskFn, arg9T cannot be a const or reference type");
493
494 private:
495 /// This class type
496 typedef TaskFn<fnT, arg1T, arg2T, arg3T, arg4T, arg5T, arg6T, arg7T,
497 arg8T, arg9T> TaskFn_;
498
499 public:
500
501 typedef fnT functionT; ///< The task function type
503 ///< The result type of the function
505
506 // argument value typedefs
507
508 static const unsigned int arity = detail::ArgCount<arg1T, arg2T, arg3T,
509 arg4T, arg5T, arg6T, arg7T, arg8T, arg9T>::value;
510 ///< The number of arguments given for the function
511 ///< \note This may not match the arity of the function
512 ///< if it has default parameter values
513
514 private:
515 futureT result_; ///< The task Future result
516 const functionT func_; ///< The task function
517
518 // If the value of the argument is known at the time the
519 // Note: The type argNT for argN, where N is > arity should be void
520
521 typename detail::task_arg<arg1T>::holderT arg1_;///< Argument 1 that will be given to the function
522 typename detail::task_arg<arg2T>::holderT arg2_;///< Argument 2 that will be given to the function
523 typename detail::task_arg<arg3T>::holderT arg3_;///< Argument 3 that will be given to the function
524 typename detail::task_arg<arg4T>::holderT arg4_;///< Argument 4 that will be given to the function
525 typename detail::task_arg<arg5T>::holderT arg5_;///< Argument 5 that will be given to the function
526 typename detail::task_arg<arg6T>::holderT arg6_;///< Argument 6 that will be given to the function
527 typename detail::task_arg<arg7T>::holderT arg7_;///< Argument 7 that will be given to the function
528 typename detail::task_arg<arg8T>::holderT arg8_;///< Argument 8 that will be given to the function
529 typename detail::task_arg<arg9T>::holderT arg9_;///< Argument 9 that will be given to the function
530
531 template <typename fT>
532 static fT& get_func(fT& f) { return f; }
533
534 template <typename ptrT, typename memfnT, typename resT>
536 return detail::get_mem_func_ptr(wrapper);
537 }
538
539 virtual void get_id(std::pair<void*,unsigned short>& id) const {
540 return make_id(id, get_func(func_));
541 }
542
543
544 /// Register a non-ready future as a dependency
545
546 /// \tparam T The type of the future to check
547 /// \param fut The future to check
548 template <typename T>
549 inline void check_dependency(Future<T>& fut) {
550 if(!fut.probe()) {
552 fut.register_callback(this);
553 }
554 }
555
556 /// Register (pointer to) a non-ready future as a dependency
557
558 /// \tparam T The type of the future to check
559 /// \param fut The future to check
560 template <typename T>
561 inline void check_dependency(Future<T>* fut) {
562 if(!fut->probe()) {
564 fut->register_callback(this);
565 }
566 }
567
568 /// None future arguments are always ready => no op
569 template <typename T>
570 inline void check_dependency(detail::ArgHolder<std::vector<Future<T> > >& arg) {
571 check_dependency(static_cast<std::vector<Future<T> >&>(arg));
572 }
573
574 /// None future arguments are always ready => no op
575 template <typename T>
576 inline void check_dependency(std::vector<Future<T> >& vec) {
577 for(typename std::vector<Future<T> >::iterator it = vec.begin(); it != vec.end(); ++it)
578 check_dependency(*it);
579 }
580
581 /// Future<void> is always ready => no op
582 inline void check_dependency(const std::vector<Future<void> >&) { }
583
584 /// None future arguments are always ready => no op
585 template <typename T>
587
588 /// Future<void> is always ready => no op
589 inline void check_dependency(const Future<void>&) { }
590
591 /// Check dependencies and register callbacks where necessary
603
604 // Copies are not allowed.
607
608 public:
609
610#if MADNESS_TASKQ_VARIADICS
611
612 // what this look like ... but need extra MP functionality
613// template <typename ... argsT>
614// TaskFn(const futureT& result, functionT func, argsT&& ... args) :
615// TaskInterface(attr), result_(result), func_(func), arg1_(), arg2_(),
616// arg3_(), arg4_(), arg5_(), arg6_(), arg7_(), arg8_(), arg9_()
617// {
618// MADNESS_ASSERT(arity == 0u);
619// check_dependencies();
620// }
623 arg3_(), arg4_(), arg5_(), arg6_(), arg7_(), arg8_(), arg9_()
624 {
627 }
628
629 template <typename a1T>
631 const TaskAttributes& attr) :
632 TaskInterface(attr), result_(result), func_(func), arg1_(std::forward<a1T>(a1)), arg2_(),
633 arg3_(), arg4_(), arg5_(), arg6_(), arg7_(), arg8_(), arg9_()
634 {
635 MADNESS_ASSERT(arity == 1u);
637 }
638
639 template <typename a1T, typename a2T>
640 TaskFn(const futureT& result, functionT func, a1T&& a1, a2T&& a2,
641 const TaskAttributes& attr) :
642 TaskInterface(attr), result_(result), func_(func), arg1_(std::forward<a1T>(a1)), arg2_(std::forward<a2T>(a2)),
643 arg3_(), arg4_(), arg5_(), arg6_(), arg7_(), arg8_(), arg9_()
644 {
645 MADNESS_ASSERT(arity == 2u);
647 }
648
649 template <typename a1T, typename a2T, typename a3T>
650 TaskFn(const futureT& result, functionT func, a1T&& a1, a2T&& a2,
651 a3T&& a3, const TaskAttributes& attr) :
652 TaskInterface(attr), result_(result), func_(func), arg1_(std::forward<a1T>(a1)), arg2_(std::forward<a2T>(a2)),
653 arg3_(std::forward<a3T>(a3)), arg4_(), arg5_(), arg6_(), arg7_(), arg8_(), arg9_()
654 {
655 MADNESS_ASSERT(arity == 3u);
657 }
658
659 template <typename a1T, typename a2T, typename a3T, typename a4T>
660 TaskFn(const futureT& result, functionT func, a1T&& a1, a2T&& a2,
661 a3T&& a3, a4T&& a4, const TaskAttributes& attr) :
662 TaskInterface(attr), result_(result), func_(func), arg1_(std::forward<a1T>(a1)), arg2_(std::forward<a2T>(a2)),
663 arg3_(std::forward<a3T>(a3)), arg4_(std::forward<a4T>(a4)), arg5_(), arg6_(), arg7_(), arg8_(), arg9_()
664 {
665 MADNESS_ASSERT(arity == 4u);
667 }
668
669 template <typename a1T, typename a2T, typename a3T, typename a4T, typename a5T>
670 TaskFn(const futureT& result, functionT func, a1T&& a1, a2T&& a2,
671 a3T&& a3, a4T&& a4, a5T&& a5, const TaskAttributes& attr) :
672 TaskInterface(attr), result_(result), func_(func), arg1_(std::forward<a1T>(a1)), arg2_(std::forward<a2T>(a2)),
673 arg3_(std::forward<a3T>(a3)), arg4_(std::forward<a4T>(a4)), arg5_(std::forward<a5T>(a5)), arg6_(), arg7_(), arg8_(), arg9_()
674 {
675 MADNESS_ASSERT(arity == 5u);
677 }
678
679 template <typename a1T, typename a2T, typename a3T, typename a4T, typename a5T,
680 typename a6T>
681 TaskFn(const futureT& result, functionT func, a1T&& a1, a2T&& a2,
682 a3T&& a3, a4T&& a4, a5T&& a5, a6T&& a6,
683 const TaskAttributes& attr) :
684 TaskInterface(attr), result_(result), func_(func), arg1_(std::forward<a1T>(a1)), arg2_(std::forward<a2T>(a2)),
685 arg3_(std::forward<a3T>(a3)), arg4_(std::forward<a4T>(a4)), arg5_(std::forward<a5T>(a5)), arg6_(std::forward<a6T>(a6)), arg7_(), arg8_(), arg9_()
686 {
687 MADNESS_ASSERT(arity == 6u);
689 }
690
691 template <typename a1T, typename a2T, typename a3T, typename a4T, typename a5T,
692 typename a6T, typename a7T>
693 TaskFn(const futureT& result, functionT func, a1T&& a1, a2T&& a2,
694 a3T&& a3, a4T&& a4, a5T&& a5, a6T&& a6,
695 a7T&& a7, const TaskAttributes& attr) :
696 TaskInterface(attr), result_(result), func_(func), arg1_(std::forward<a1T>(a1)), arg2_(std::forward<a2T>(a2)),
697 arg3_(std::forward<a3T>(a3)), arg4_(std::forward<a4T>(a4)), arg5_(std::forward<a5T>(a5)), arg6_(std::forward<a6T>(a6)), arg7_(std::forward<a7T>(a7)), arg8_(), arg9_()
698 {
699 MADNESS_ASSERT(arity == 7u);
701 }
702
703 template <typename a1T, typename a2T, typename a3T, typename a4T, typename a5T,
704 typename a6T, typename a7T, typename a8T>
705 TaskFn(const futureT& result, functionT func, a1T&& a1, a2T&& a2,
706 a3T&& a3, a4T&& a4, a5T&& a5, a6T&& a6, a7T&& a7,
707 a8T&& a8, const TaskAttributes& attr) :
708 TaskInterface(attr), result_(result), func_(func), arg1_(std::forward<a1T>(a1)), arg2_(std::forward<a2T>(a2)),
709 arg3_(std::forward<a3T>(a3)), arg4_(std::forward<a4T>(a4)), arg5_(std::forward<a5T>(a5)), arg6_(std::forward<a6T>(a6)), arg7_(std::forward<a7T>(a7)), arg8_(std::forward<a8T>(a8)), arg9_()
710 {
711 MADNESS_ASSERT(arity == 8u);
713 }
714
715 template <typename a1T, typename a2T, typename a3T, typename a4T, typename a5T,
716 typename a6T, typename a7T, typename a8T, typename a9T>
717 TaskFn(const futureT& result, functionT func, a1T&& a1, a2T&& a2,
718 a3T&& a3, a4T&& a4, a5T&& a5, a6T&& a6,
719 a7T&& a7, a8T&& a8, a9T&& a9, const TaskAttributes& attr) :
720 TaskInterface(attr), result_(result), func_(func), arg1_(std::forward<a1T>(a1)), arg2_(std::forward<a2T>(a2)),
721 arg3_(std::forward<a3T>(a3)), arg4_(std::forward<a4T>(a4)), arg5_(std::forward<a5T>(a5)), arg6_(std::forward<a6T>(a6)), arg7_(std::forward<a7T>(a7)), arg8_(std::forward<a8T>(a8)), arg9_(std::forward<a9T>(a9))
722 {
723 MADNESS_ASSERT(arity == 9u);
725 }
726
728 archive::BufferInputArchive& input_arch) :
729 TaskInterface(attr), result_(result), func_(func), arg1_(input_arch),
730 arg2_(input_arch), arg3_(input_arch), arg4_(input_arch), arg5_(input_arch),
731 arg6_(input_arch), arg7_(input_arch), arg8_(input_arch), arg9_(input_arch)
732 {
733 // No need to check dependencies since the arguments are from an archive
734 }
735#else // MADNESS_TASKQ_VARIADICS
736 TaskFn(const futureT& result, functionT func, const TaskAttributes& attr) :
738 arg3_(), arg4_(), arg5_(), arg6_(), arg7_(), arg8_(), arg9_()
739 {
742 }
743
744 template <typename a1T>
745 TaskFn(const futureT& result, functionT func, const a1T& a1,
746 const TaskAttributes& attr) :
747 TaskInterface(attr), result_(result), func_(func), arg1_(a1), arg2_(),
748 arg3_(), arg4_(), arg5_(), arg6_(), arg7_(), arg8_(), arg9_()
749 {
750 MADNESS_ASSERT(arity == 1u);
752 }
753
754 template <typename a1T, typename a2T>
755 TaskFn(const futureT& result, functionT func, const a1T& a1, const a2T& a2,
756 const TaskAttributes& attr = TaskAttributes()) :
758 arg3_(), arg4_(), arg5_(), arg6_(), arg7_(), arg8_(), arg9_()
759 {
760 MADNESS_ASSERT(arity == 2u);
762 }
763
764 template <typename a1T, typename a2T, typename a3T>
765 TaskFn(const futureT& result, functionT func, const a1T& a1, const a2T& a2,
766 const a3T& a3, const TaskAttributes& attr) :
768 arg3_(a3), arg4_(), arg5_(), arg6_(), arg7_(), arg8_(), arg9_()
769 {
770 MADNESS_ASSERT(arity == 3u);
772 }
773
774 template <typename a1T, typename a2T, typename a3T, typename a4T>
775 TaskFn(const futureT& result, functionT func, const a1T& a1, const a2T& a2,
776 const a3T& a3, const a4T& a4, const TaskAttributes& attr) :
778 arg3_(a3), arg4_(a4), arg5_(), arg6_(), arg7_(), arg8_(), arg9_()
779 {
780 MADNESS_ASSERT(arity == 4u);
782 }
783
784 template <typename a1T, typename a2T, typename a3T, typename a4T, typename a5T>
785 TaskFn(const futureT& result, functionT func, const a1T& a1, const a2T& a2,
786 const a3T& a3, const a4T& a4, const a5T& a5, const TaskAttributes& attr) :
788 arg3_(a3), arg4_(a4), arg5_(a5), arg6_(), arg7_(), arg8_(), arg9_()
789 {
790 MADNESS_ASSERT(arity == 5u);
792 }
793
794 template <typename a1T, typename a2T, typename a3T, typename a4T, typename a5T,
795 typename a6T>
796 TaskFn(const futureT& result, functionT func, const a1T& a1, const a2T& a2,
797 const a3T& a3, const a4T& a4, const a5T& a5, const a6T& a6,
798 const TaskAttributes& attr) :
800 arg3_(a3), arg4_(a4), arg5_(a5), arg6_(a6), arg7_(), arg8_(), arg9_()
801 {
802 MADNESS_ASSERT(arity == 6u);
804 }
805
806 template <typename a1T, typename a2T, typename a3T, typename a4T, typename a5T,
807 typename a6T, typename a7T>
808 TaskFn(const futureT& result, functionT func, const a1T& a1, const a2T& a2,
809 const a3T& a3, const a4T& a4, const a5T& a5, const a6T& a6,
810 const a7T& a7, const TaskAttributes& attr) :
812 arg3_(a3), arg4_(a4), arg5_(a5), arg6_(a6), arg7_(a7), arg8_(), arg9_()
813 {
814 MADNESS_ASSERT(arity == 7u);
816 }
817
818 template <typename a1T, typename a2T, typename a3T, typename a4T, typename a5T,
819 typename a6T, typename a7T, typename a8T>
820 TaskFn(const futureT& result, functionT func, const a1T& a1, const a2T& a2,
821 const a3T& a3, const a4T& a4, const a5T& a5, const a6T& a6, const a7T& a7,
822 const a8T& a8, const TaskAttributes& attr) :
824 arg3_(a3), arg4_(a4), arg5_(a5), arg6_(a6), arg7_(a7), arg8_(a8), arg9_()
825 {
826 MADNESS_ASSERT(arity == 8u);
828 }
829
830 template <typename a1T, typename a2T, typename a3T, typename a4T, typename a5T,
831 typename a6T, typename a7T, typename a8T, typename a9T>
832 TaskFn(const futureT& result, functionT func, const a1T& a1, const a2T& a2,
833 const a3T& a3, const a4T& a4, const a5T& a5, const a6T& a6,
834 const a7T& a7, const a8T& a8, const a9T& a9, const TaskAttributes& attr) :
836 arg3_(a3), arg4_(a4), arg5_(a5), arg6_(a6), arg7_(a7), arg8_(a8), arg9_(a9)
837 {
838 MADNESS_ASSERT(arity == 9u);
840 }
841
842 TaskFn(const futureT& result, functionT func, const TaskAttributes& attr,
843 archive::BufferInputArchive& input_arch) :
844 TaskInterface(attr), result_(result), func_(func), arg1_(input_arch),
845 arg2_(input_arch), arg3_(input_arch), arg4_(input_arch), arg5_(input_arch),
846 arg6_(input_arch), arg7_(input_arch), arg8_(input_arch), arg9_(input_arch)
847 {
848 // No need to check dependencies since the arguments are from an archive
849 }
850#endif // MADNESS_TASKQ_VARIADICS
851
852 virtual ~TaskFn() { }
853
854 const futureT& result() const { return result_; }
855
856 protected:
857 virtual void run(World&, const TaskThreadEnv&) /*override*/{
860 }
861 }; // class TaskFn
862
863} // namespace madness
864
865
866#endif // MADNESS_WORLD_TASKFN_H__INCLUDED
double w(double t, double eps)
Definition DKops.h:22
Disables default copy constructor and assignment operators.
Definition nodefaults.h:49
The class used for callbacks (e.g., dependency tracking).
Definition dependency_interface.h:61
virtual void notify()=0
Invoked by the callback to notify when a dependency is satisfied.
Provides an interface for tracking dependencies.
Definition dependency_interface.h:100
void inc()
Increment the number of dependencies.
Definition dependency_interface.h:251
void register_final_callback(CallbackInterface *callback)
Registers the final callback to be executed when ndepend==0; immediately invoked if ndepend==0.
Definition dependency_interface.h:229
std::atomic< int > ndepend
Counts dependencies. For a valid object ndepend >= 0, after the final callback is executed ndepend is...
Definition dependency_interface.h:105
Specialization of Future<void> for internal convenience. This does nothing useful!
Definition future.h:736
A future is a possibly yet unevaluated value.
Definition future.h:373
void set(const Future< T > &other)
A.set(B), where A and B are futures ensures A has/will have the same value as B.
Definition future.h:508
void register_callback(CallbackInterface *callback)
Registers an object to be called when future is assigned.
Definition future.h:708
bool probe() const
Check whether this future has been assigned.
Definition future.h:631
Lowest level task interface.
Definition thread.h:867
static std::enable_if< detail::function_traits< fnT >::value||detail::memfunc_traits< fnT >::value >::type make_id(std::pair< void *, unsigned short > &id, fnT fn)
Definition thread.h:916
Contains attributes of a task.
Definition thread.h:323
TaskAttributes(unsigned long flags=0)
Sets the attributes to the desired values.
Definition thread.h:337
All world tasks must be derived from this public interface.
Definition taskfn.h:69
virtual void run(const TaskThreadEnv &env)
Override this method to implement a multi-threaded task.
Definition world_task_queue.cc:45
void set_info(World *w, CallbackInterface *c)
Set task info.
Definition taskfn.h:89
virtual void run(World &world, const TaskThreadEnv &env)
Runs a multi-threaded task.
Definition taskfn.h:145
void register_submit_callback()
Adds call back to schedule task when outstanding dependencies are satisfied.
Definition taskfn.h:95
TaskInterface(int ndepend, const char *caller, const TaskAttributes attr=TaskAttributes())
Definition taskfn.h:114
static bool debug
Definition taskfn.h:101
virtual ~TaskInterface()
Definition taskfn.h:154
TaskInterface(const TaskAttributes &attr)
Create a new task with zero dependencies and given attributes.
Definition taskfn.h:123
madness::TaskInterface::Submit submit
CallbackInterface * completion
Definition taskfn.h:73
TaskInterface(int ndepend=0, const TaskAttributes attr=TaskAttributes())
Create a new task with ndepend dependencies (default 0) and given attributes.
Definition taskfn.h:104
virtual void run(World &)
Runs a single-threaded task ... derived classes must implement this.
Definition taskfn.h:139
volatile World * world
Definition taskfn.h:72
World * get_world() const
Definition taskfn.h:152
Used to pass information about the thread environment to a user's task.
Definition thread.h:466
int nthread() const
Get the number of threads collaborating on this task.
Definition thread.h:499
static void add(PoolTaskInterface *task)
Add a new task to the pool.
Definition thread.h:1333
Multi-threaded queue to manage and run tasks.
Definition world_task_queue.h:319
A parallel world class.
Definition world.h:132
Wraps an archive around a memory buffer for input.
Definition buffer_archive.h:134
A wrapper object for holding task function argument objects.
Definition taskfn.h:183
ArgHolder(const archive::BufferInputArchive &input_arch)
Definition taskfn.h:195
Arg arg_
Definition taskfn.h:185
ArgHolder(Arg_ &&arg)
Definition taskfn.h:193
Functor wrapper for object and member function pointers.
Definition mem_func_wrapper.h:89
Defines DependencyInterface and CallbackInterface.
Implements Future and related items.
auto T(World &world, response_space &f) -> response_space
Definition global_functions.cc:34
Tensor< typename Tensor< T >::scalar_type > arg(const Tensor< T > &t)
Return a new tensor holding the argument of each element of t (complex types only)
Definition tensor.h:2502
static double u(double r, double c)
Definition he.cc:20
#define MADNESS_EXCEPTION(msg, value)
Macro for throwing a MADNESS exception.
Definition madness_exception.h:119
#define MADNESS_ASSERT(condition)
Assert a condition that should be free of side-effects since in release builds this might be a no-op.
Definition madness_exception.h:134
T & decay(ArgHolder< T > &arg_holder)
Definition taskfn.h:257
std::enable_if< std::is_void< typenamedetail::result_of< fnT >::type >::value >::type run_function(Future< void > &result, fnT fn, const voidT &, const voidT &, const voidT &, const voidT &, const voidT &, const voidT &, const voidT &, const voidT &, const voidT &)
Definition taskfn.h:317
Future< void > voidT
Definition taskfn.h:250
memfnT get_mem_func_ptr(const MemFuncWrapper< ptrT, memfnT, resT > &wrapper)
Returns the member function pointer from a wrapper.
Definition mem_func_wrapper.h:339
Namespace for all elements and tools of MADNESS.
Definition DFParameters.h:10
std::shared_ptr< FunctionFunctorInterface< double, 3 > > func(new opT(g))
NDIM & f
Definition mra.h:2416
std::string type(const PairType &n)
Definition PNOParameters.h:18
Vector< T, sizeof...(Ts)+1 > vec(T t, Ts... ts)
Factory function for creating a madness::Vector.
Definition vector.h:711
Definition mraimpl.h:50
static const double c
Definition relops.cc:10
Wrap a callable object and its arguments into a task function.
Definition taskfn.h:473
void check_dependencies()
Check dependencies and register callbacks where necessary.
Definition taskfn.h:592
futureT result_
The task Future result.
Definition taskfn.h:515
detail::task_arg< arg4T >::holderT arg4_
Argument 4 that will be given to the function.
Definition taskfn.h:524
detail::task_result_type< fnT >::resultT resultT
The result type of the function.
Definition taskfn.h:502
TaskFn(const futureT &result, functionT func, a1T &&a1, a2T &&a2, a3T &&a3, a4T &&a4, a5T &&a5, a6T &&a6, a7T &&a7, const TaskAttributes &attr)
Definition taskfn.h:693
detail::task_arg< arg7T >::holderT arg7_
Argument 7 that will be given to the function.
Definition taskfn.h:527
void check_dependency(Future< T > *fut)
Register (pointer to) a non-ready future as a dependency.
Definition taskfn.h:561
TaskFn(const futureT &result, functionT func, a1T &&a1, a2T &&a2, a3T &&a3, a4T &&a4, a5T &&a5, const TaskAttributes &attr)
Definition taskfn.h:670
detail::task_arg< arg8T >::holderT arg8_
Argument 8 that will be given to the function.
Definition taskfn.h:528
void check_dependency(const std::vector< Future< void > > &)
Future<void> is always ready => no op.
Definition taskfn.h:582
TaskFn(const futureT &result, functionT func, a1T &&a1, a2T &&a2, a3T &&a3, a4T &&a4, const TaskAttributes &attr)
Definition taskfn.h:660
TaskFn(const futureT &result, functionT func, a1T &&a1, a2T &&a2, const TaskAttributes &attr)
Definition taskfn.h:640
virtual void get_id(std::pair< void *, unsigned short > &id) const
Definition taskfn.h:539
void check_dependency(const Future< void > &)
Future<void> is always ready => no op.
Definition taskfn.h:589
virtual void run(World &, const TaskThreadEnv &)
Runs a multi-threaded task.
Definition taskfn.h:857
detail::task_arg< arg3T >::holderT arg3_
Argument 3 that will be given to the function.
Definition taskfn.h:523
detail::task_result_type< fnT >::futureT futureT
Definition taskfn.h:504
detail::task_arg< arg6T >::holderT arg6_
Argument 6 that will be given to the function.
Definition taskfn.h:526
fnT functionT
The task function type.
Definition taskfn.h:501
detail::task_arg< arg1T >::holderT arg1_
Argument 1 that will be given to the function.
Definition taskfn.h:521
const futureT & result() const
Definition taskfn.h:854
TaskFn(const futureT &result, functionT func, a1T &&a1, a2T &&a2, a3T &&a3, const TaskAttributes &attr)
Definition taskfn.h:650
TaskFn(const futureT &result, functionT func, a1T &&a1, a2T &&a2, a3T &&a3, a4T &&a4, a5T &&a5, a6T &&a6, a7T &&a7, a8T &&a8, a9T &&a9, const TaskAttributes &attr)
Definition taskfn.h:717
TaskFn(const futureT &result, functionT func, const TaskAttributes &attr, archive::BufferInputArchive &input_arch)
Definition taskfn.h:727
void check_dependency(Future< T > &fut)
Register a non-ready future as a dependency.
Definition taskfn.h:549
TaskFn(const futureT &result, functionT func, a1T &&a1, const TaskAttributes &attr)
Definition taskfn.h:630
detail::task_arg< arg2T >::holderT arg2_
Argument 2 that will be given to the function.
Definition taskfn.h:522
detail::task_arg< arg5T >::holderT arg5_
Argument 5 that will be given to the function.
Definition taskfn.h:525
TaskFn(const futureT &result, functionT func, a1T &&a1, a2T &&a2, a3T &&a3, a4T &&a4, a5T &&a5, a6T &&a6, a7T &&a7, a8T &&a8, const TaskAttributes &attr)
Definition taskfn.h:705
detail::task_arg< arg9T >::holderT arg9_
Argument 9 that will be given to the function.
Definition taskfn.h:529
static const unsigned int arity
Definition taskfn.h:508
void check_dependency(std::vector< Future< T > > &vec)
None future arguments are always ready => no op.
Definition taskfn.h:576
TaskFn_ operator=(TaskFn_ &)
TaskFn(const futureT &result, functionT func, const TaskAttributes &attr)
Definition taskfn.h:621
void check_dependency(const detail::ArgHolder< T > &)
None future arguments are always ready => no op.
Definition taskfn.h:586
static memfnT get_func(const detail::MemFuncWrapper< ptrT, memfnT, resT > &wrapper)
Definition taskfn.h:535
void check_dependency(detail::ArgHolder< std::vector< Future< T > > > &arg)
None future arguments are always ready => no op.
Definition taskfn.h:570
TaskFn(const futureT &result, functionT func, a1T &&a1, a2T &&a2, a3T &&a3, a4T &&a4, a5T &&a5, a6T &&a6, const TaskAttributes &attr)
Definition taskfn.h:681
virtual ~TaskFn()
Definition taskfn.h:852
const functionT func_
The task function.
Definition taskfn.h:516
TaskFn< fnT, arg1T, arg2T, arg3T, arg4T, arg5T, arg6T, arg7T, arg8T, arg9T > TaskFn_
This class type.
Definition taskfn.h:497
static fT & get_func(fT &f)
Definition taskfn.h:532
TaskFn(const TaskFn_ &)
Definition taskfn.h:76
PoolTaskInterface * p
Definition taskfn.h:77
Submit(PoolTaskInterface *p)
Definition taskfn.h:78
void notify()
Invoked by the callback to notify when a dependency is satisfied.
Definition taskfn.h:79
Definition taskfn.h:161
static const unsigned int value
Definition taskfn.h:162
Definition taskfn.h:177
Definition taskfn.h:207
Future< T > holderT
Definition taskfn.h:220
Future< T > * holderT
Definition taskfn.h:226
const Future< void > holderT
Definition taskfn.h:232
const Future< void > type
Definition taskfn.h:231
const Future< void > holderT
Definition taskfn.h:238
const Future< void > type
Definition taskfn.h:237
Definition taskfn.h:212
ArgHolder< T > holderT
Definition taskfn.h:214
T type
Definition taskfn.h:213
Definition taskfn.h:242
futureT type
Definition taskfn.h:245
madness::remove_fcvr< typenamemadness::detail::result_of< fnT >::type >::type resultT
Definition taskfn.h:243
Future< resultT > futureT
Definition taskfn.h:244
test if a type is a future.
Definition type_traits.h:79
Definition type_traits.h:197
Implements Dqueue, Thread, ThreadBase and ThreadPool.
const double a2
Definition vnucso.cc:86
const double a1
Definition vnucso.cc:85