MADNESS 0.10.1
world_task_queue.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/**
33 \file world_task_queue.h
34 \brief Defines \c TaskInterface and implements \c WorldTaskQueue and associated stuff.
35 \ingroup taskq
36*/
37
38#ifndef MADNESS_WORLD_WORLD_TASK_QUEUE_H__INCLUDED
39#define MADNESS_WORLD_WORLD_TASK_QUEUE_H__INCLUDED
40
41#include <type_traits>
42#include <iostream>
43
45
46// must be included before world/range.h
47#ifdef HAVE_INTEL_TBB
48# include <tbb/parallel_reduce.h>
49#endif
50
51#include <madness/world/meta.h>
53#include <madness/world/range.h>
57
58/// \addtogroup taskq
59/// @{
60
61namespace madness {
62
63 // Forward decls
64 class World;
65 class WorldTaskQueue;
66 template <typename> struct TaskFunction;
67 template <typename> struct TaskMemfun;
68
69 namespace meta {
70 template <typename ... argsT>
71 struct taskattr_is_last_arg : public std::integral_constant<bool, std::is_same<std::decay_t<typename meta::last_type<argsT...>::type>,
72 TaskAttributes>::value> {};
73 template <>
74 struct taskattr_is_last_arg<> : public std::false_type {};
75 }
76
77 namespace detail {
78
79 // a few more forward decls
80 template <typename ptrT, typename memfnT, typename resT>
81 memfnT get_mem_func_ptr(const MemFuncWrapper<ptrT, memfnT, resT>&);
82
83 template <typename, typename>
84 class ForEachRootTask;
85
86 /// Serialization container for sending tasks to remote nodes.
87
88 /// \attention This struct is for internal use only. You should not
89 /// use this class directly.
90 /// \tparam refT The remote reference type for task result future.
91 /// \tparam functionT The task function type.
92 template <typename refT, typename functionT>
94 refT ref; ///< Remote reference for a task result future.
95 functionT func; ///< A task function.
96 TaskAttributes attr; ///< Task attributes.
97
98 TaskHandlerInfo() = default;
99
100 /// Construct task info object.
101
102 /// \param[in] ref Remote reference to the result future.
103 /// \param[in] func The task function.
104 /// \param[in] attr The task attrubutes.
107
108 /// Serialization of an object.
109
110 /// \tparam Archive The serialization archive type.
111 /// \param[in,out] ar The serialization archive.
112 template <typename Archive>
113 void serialize(const Archive& ar) {
114 serialize_internal<functionT>(ar);
115 }
116
117 private:
118
119 /// Serialization for function pointers and member function pointers.
120
121 /// \tparam fnT The function type.
122 /// \tparam Archive The serialization archive type.
123 /// \param[in,out] ar The serialization archive.
124 template <typename fnT, typename Archive>
125 typename std::enable_if<is_any_function_pointer_v<fnT>>::type
126 serialize_internal(const Archive& ar) {
127 ar & ref & func & attr;
128 }
129
130 /// Serialization for non- function pointers and member function pointers.
131
132 /// \tparam fnT The function type.
133 /// \tparam Archive The serialization archive type.
134 /// \param[in,out] ar The serialization archive.
135 template <typename fnT, typename Archive>
136 typename std::enable_if<!is_any_function_pointer_v<fnT>>::type
137 serialize_internal(const Archive& ar) {
138 ar & ref & func & attr;
139 }
140 }; // struct TaskHandlerInfo
141
142 /// Behave like a lazy \c std::enable_if.
143
144 /// Evaluates to \c returnT if \c B is true, otherwise to an invalid type expression
145 /// which causes the template expression in which it is used to not be considered for
146 /// overload resolution. This "lazy" version is used if \c T is only valid when
147 /// B is true. Note: typename T::type is the return type and must be well formed.
148 /// \tparam B The bool value.
149 /// \tparam returnT The type.
150 template <bool B, class returnT>
152 typedef typename returnT::type type;
153 };
154
155 /// Specialization that disables \c type when \c B is false.
156
157 /// \tparam returnT The type.
158 template <class returnT>
159 struct function_enabler_helper<false, returnT> { };
160
161 /// \todo Brief description needed.
162
163 /// \todo Descriptions needed.
164 /// \tparam fnT Description needed.
165 template <typename fnT>
166 struct function_enabler : public
168 function_traits<fnT>::value || is_functor<fnT>::value,
169 task_result_type<fnT> >
170 { };
171
172 /// \todo Brief description needed.
173
174 /// \todo Descriptions needed.
175 /// \tparam fnT Description needed.
176 template <typename callableT, typename Enabler = void>
178 template <typename callableT>
179 struct callable_enabler<callableT,
180 std::enable_if_t<callable_traits<callableT>::value>>
182
183 /// \todo Brief description needed.
184
185 /// \todo Descriptions needed.
186 /// \tparam objT Description needed.
187 /// \tparam memfnT Description needed.
188 /// \tparam enableT Description needed.
189 template <typename objT, typename memfnT, typename enableT = void>
191 { };
192
193 /// \todo Brief description needed.
194
195 /// \todo Descriptions needed
196 /// \tparam objT Description needed.
197 /// \tparam resT Description needed.
198 /// \tparam baseT Description needed.
199 /// \tparam paramT Description needed.
200 template <typename objT, typename resT, typename baseT, typename ... paramT>
201 struct memfunc_enabler_base<objT, resT (baseT::*)(paramT...),
202 typename std::enable_if<std::is_base_of<baseT, objT>::value>::type >
203 {
204 /// \todo Brief description needed.
205 typedef typename add_future<resT>::type type;
206 };
207
208 /// \todo Brief description needed.
209
210 /// \todo Descriptions needed.
211 /// \tparam objT Description needed.
212 /// \tparam resT Description needed.
213 /// \tparam baseT Description needed.
214 /// \tparam paramT Description needed.
215 template <typename objT, typename resT, typename baseT, typename ... paramT>
216 struct memfunc_enabler_base<objT, resT (baseT::*)(paramT...) const,
217 typename std::enable_if<std::is_base_of<baseT, objT>::value>::type >
218 {
219 /// \todo Brief description needed.
220 typedef typename add_future<resT>::type type;
221 };
222
223 /// \todo Brief description needed.
224
225 /// \todo Descriptions needed.
226 /// \tparam objT Description needed.
227 /// \tparam memfnT Description needed.
228 template <typename objT, typename memfnT>
230 public memfunc_enabler_base<typename std::decay<objT>::type, memfnT>
231 { };
232
233 /// \todo Brief description needed.
234
235 /// \todo Descriptions needed.
236 /// \tparam objT Description needed.
237 /// \tparam memfnT Description needed.
238 template <typename objT, typename memfnT>
239 struct memfunc_enabler<objT*, memfnT> :
241 { };
242
243 /// \todo Brief description needed.
244
245 /// \todo Descriptions needed.
246 /// \tparam objT Description needed.
247 /// \tparam memfnT Description needed.
248 template <typename objT, typename memfnT>
249 struct memfunc_enabler<const objT*, memfnT> :
251 { };
252
253 /// \todo Brief description needed.
254
255 /// \todo Descriptions needed.
256 /// \tparam objT Description needed.
257 /// \tparam memfnT Description needed.
258 template <typename objT, typename memfnT>
259 struct memfunc_enabler<objT* const, memfnT> :
261 { };
262
263 /// \todo Brief description needed.
264
265 /// \todo Descriptions needed.
266 /// \tparam objT Description needed.
267 /// \tparam memfnT Description needed.
268 template <typename objT, typename memfnT>
269 struct memfunc_enabler<const objT* const, memfnT> :
271 { };
272
273 /// \todo Brief description needed.
274
275 /// \todo Descriptions needed.
276 /// \tparam objT Description needed.
277 /// \tparam memfnT Description needed.
278 template <typename objT, typename memfnT>
279 struct memfunc_enabler<std::shared_ptr<objT>&, memfnT> :
280 public memfunc_enabler<objT, memfnT>
281 { };
282
283 /// \todo Brief description needed.
284
285 /// \todo Descriptions needed.
286 /// \tparam objT Description needed.
287 /// \tparam memfnT Description needed.
288 template <typename objT, typename memfnT>
289 struct memfunc_enabler<const std::shared_ptr<objT>&, memfnT> :
290 public memfunc_enabler<objT, memfnT>
291 { };
292
293 /// \todo Brief description needed.
294
295 /// \todo Descriptions needed.
296 /// \tparam objT Description needed.
297 /// \tparam memfnT Description needed.
298 template <typename objT, typename memfnT>
299 struct memfunc_enabler<std::shared_ptr<objT>, memfnT> :
300 public memfunc_enabler<objT, memfnT>
301 { };
302
303 /// \todo Brief description needed.
304
305 /// \todo Descriptions needed.
306 /// \tparam objT Description needed.
307 /// \tparam memfnT Description needed.
308 template <typename objT, typename memfnT>
309 struct memfunc_enabler<const std::shared_ptr<objT>, memfnT> :
310 public memfunc_enabler<objT, memfnT>
311 { };
312
313 } // namespace detail
314
315
316 /// Multi-threaded queue to manage and run tasks.
317
318 /// \todo A concise description of the inner workings...
320 friend class TaskInterface;
321 private:
322 World& world; ///< The communication context.
323 const ProcessID me; ///< This process.
324 AtomicInt nregistered; ///< Count of pending tasks.
325
326 /// \todo Brief description needed.
327 void notify() {
328 nregistered--;
329 }
330
331 /// \todo Brief description needed.
332
333 /// This template is used in the reduce kernel.
334 /// \todo Template parameter descriptions need verification.
335 /// \tparam resultT Return type of the operation.
336 /// \tparam opT The operation.
337 /// \param[in] left Description needed.
338 /// \param[in] right Description needed.
339 /// \param[in] op The operation used in the reduce.
340 /// \return Reduce of \c left and \c right using \c op.
341 template <typename resultT, typename opT>
342 static resultT sum(const resultT& left, const resultT& right, const opT& op) {
343 //std::cout << " REDUCE SUM " << left << " " << right << std::endl;
344 return op(left,right);
345 }
346
347 /// \todo Brief description needed.
348
349 /// \todo Descriptions needed.
350 /// \tparam taskT Description needed.
351 /// \param arg Description needed.
352 template <typename taskT>
353 static void remote_task_handler(const AmArg& arg) {
354 MADNESS_ASSERT(taskT::arity <= 9u);
355
356 // Get task info and arguments form active message
357
358 detail::TaskHandlerInfo<typename taskT::futureT::remote_refT,
359 typename taskT::functionT> info;
360
361 archive::BufferInputArchive input_arch = arg & info;
362
363 // Construct task
364 taskT* task = new taskT(typename taskT::futureT(info.ref),
365 info.func, info.attr, input_arch);
366
367 // Add task to queue
368 arg.get_world()->taskq.add(task);
369 }
370
371 /// \todo Brief description needed.
372
373 /// \todo Descriptions needed.
374 /// \tparam T Description needed.
375 /// \param[in] f Description needed.
376 template <typename T>
377 inline const T& am_arg(const Future<T>& f) {
378 MADNESS_ASSERT(f.probe());
379 return f.get();
380 }
381
382 /// \todo Brief description needed.
383
384 /// \todo Descriptions needed.
385 /// \tparam T Description needed.
386 /// \param[in] t Description needed.
387 /// \return Description needed.
388 template <typename T>
389 inline const T& am_arg(const T& t) {
390 return t;
391 }
392
393 /// \todo Brief description needed.
395
396 /// \todo Brief description needed.
397
398 /// \todo Descriptions needed.
399 /// \tparam taskT Description needed.
400 /// \tparam fnT Description needed.
401 /// \tparam a1T Type of argument 1.
402 /// \tparam a2T Type of argument 2.
403 /// \tparam a3T Type of argument 3.
404 /// \tparam a4T Type of argument 4.
405 /// \tparam a5T Type of argument 5.
406 /// \tparam a6T Type of argument 6.
407 /// \tparam a7T Type of argument 7.
408 /// \tparam a8T Type of argument 8.
409 /// \tparam a9T Type of argument 9.
410 /// \param where Description needed.
411 /// \param fn Description needed.
412 /// \param[in] a1 Argument 1.
413 /// \param[in] a2 Argument 2.
414 /// \param[in] a3 Argument 3.
415 /// \param[in] a4 Argument 4.
416 /// \param[in] a5 Argument 5.
417 /// \param[in] a6 Argument 6.
418 /// \param[in] a7 Argument 7.
419 /// \param[in] a8 Argument 8.
420 /// \param[in] a9 Argument 9.
421 /// \param[in] attr Description needed.
422 /// \return Description needed.
423 template <typename taskT, typename fnT, typename a1T, typename a2T, typename a3T,
424 typename a4T, typename a5T, typename a6T, typename a7T,
425 typename a8T, typename a9T>
426 inline typename taskT::futureT
427 send_task(ProcessID where, fnT fn, const a1T& a1,
428 const a2T& a2, const a3T& a3, const a4T& a4, const a5T& a5,
429 const a6T& a6, const a7T& a7, const a8T& a8, const a9T& a9,
430 const TaskAttributes& attr)
431 {
432 typename taskT::futureT result;
434 world.am.send(where, & WorldTaskQueue::template remote_task_handler<taskT>,
435 new_am_arg(infoT(result.remote_ref(world), fn, attr),
436 a1, a2, a3, a4, a5, a6, a7, a8, a9), RMI::ATTR_UNORDERED);
437
438 return result;
439 }
440
441
442 public:
443 /// Constructor requiring a communication context (\c World).
444
445 /// \param[in,out] world The communication context.
447
448 /// Returns the number of pending tasks.
449
450 /// \return The number of pending tasks.
451 size_t size() const {
452 return nregistered;
453 }
454
455
456 /// Add a new local task, taking ownership of the pointer.
457
458 /// The task pointer (\c t) is assumed to have been created with
459 /// \c new and when the task is eventually run the queue
460 /// will call the task's destructor using \c delete.
461 ///
462 /// Once the task is complete it will execute
463 /// \c task_complete_callback to decrement the number of pending
464 /// tasks and be deleted.
465 /// \param[in] t Pointer to the task.
467 nregistered++;
468
469 t->set_info(&world, this); // Stuff info
470
471 // Always use the callback to avoid race condition
473 }
474
475 /// \todo Brief description needed.
476
477 /// \todo Descriptions needed.
478 /// \tparam fnT Description needed.
479 /// \tparam a1T Type of argument 1.
480 /// \tparam a2T Type of argument 2.
481 /// \tparam a3T Type of argument 3.
482 /// \tparam a4T Type of argument 4.
483 /// \tparam a5T Type of argument 5.
484 /// \tparam a6T Type of argument 6.
485 /// \tparam a7T Type of argument 7.
486 /// \tparam a8T Type of argument 8.
487 /// \tparam a9T Type of argument 9.
488 /// \param[in] t Description needed.
489 /// \return Description needed.
490 template <typename fnT, typename a1T, typename a2T, typename a3T,
491 typename a4T, typename a5T, typename a6T, typename a7T, typename a8T,
492 typename a9T>
500
501 /// Reduce `op(item)` for all items in range using `op(sum,op(item))`.
502
503 /// The operation must provide the following interface, of
504 /// which the \c operator() methods are required by \c reduce()
505 /// and the rest by the task interface.
506 /// \code
507 /// struct opT {
508 /// opT();
509 /// opT(const &opT);
510 /// resultT operator()(const rangeT::iterator& it) const;
511 /// resultT operator()(const resultT& left, const resultT& right);
512 /// template <typename Archive> void serialize(const Archive& ar);
513 /// }
514 /// \endcode
515 /// \note The serialize method does not actually have to
516 /// work unless you want to have the task be stealable.
517 ///
518 /// Adjust the chunksize in the range to control granularity.
519 /// \todo Descriptions needed and/or verified.
520 /// \tparam resultT The result type of the operation.
521 /// \tparam rangeT Description needed.
522 /// \tparam opT Function type of the operation.
523 /// \param[in] range The range of items.
524 /// \param[in] op The operation.
525 /// \return Description needed.
526 template <typename resultT, typename rangeT, typename opT>
527 Future<resultT> reduce(const rangeT& range, const opT& op) {
528 if (range.size() <= range.get_chunksize()) {
529 resultT sum = resultT();
530 for (typename rangeT::iterator it=range.begin(); it != range.end(); ++it) sum = op(sum,op(it));
531 return Future<resultT>(sum);
532 } else {
533 rangeT left = range;
534 rangeT right(left,Split());
535
536 Future<resultT> leftsum = add(*this, &WorldTaskQueue::reduce<resultT,rangeT,opT>, left, op);
537 Future<resultT> rightsum = add(*this, &WorldTaskQueue::reduce<resultT,rangeT,opT>, right, op);
538 return add(&WorldTaskQueue::sum<resultT,opT>, leftsum, rightsum, op);
539 }
540 }
541
542 /// Apply `op(item)` on all items in range.
543
544 /// The operation must provide the following interface, of
545 /// which the \c operator() method is required by `for_each()`
546 /// and the rest by the task interface.
547 /// \code
548 /// struct opT {
549 /// opT(const opT&);
550 /// bool operator()(const rangeT::iterator& it) const;
551 /// };
552 /// \endcode
553 /// \note The serialize method does not actually have to
554 /// work unless you want to have the task be stealable.
555 ///
556 /// Adjust the chunksize in the range to control granularity.
557 ///
558 /// Your operation should return true/false for success failure
559 /// and the logical and of all results is returned as the
560 /// future result.
561 ///
562 /// You can ignore the result if you are interested
563 /// in neither synchronization nor result status.
564 /// \todo Descriptions needed and/or verified.
565 /// \tparam rangeT Description needed.
566 /// \tparam opT Funtion type of the operation. This function should
567 /// have a return type of \c bool.
568 /// \param[in] range The range of items.
569 /// \param[in] op The operation.
570 /// \return Future for a bool which is the logical `and` of all `op(item)` calls.
571 template <typename rangeT, typename opT>
572 Future<bool> for_each(const rangeT& range, const opT& op) {
575 Future<bool> result = for_each_root->result();
576 add(for_each_root);
577 return result;
578 }
579
580#if MADNESS_TASKQ_VARIADICS
581
582 ///////////////////////////////////////////////////////////////////////////////
583
584 /// Create a local task with one argument.
585
586 /// Creates a task in this process. An argument that is a future may be
587 /// used to carry dependencies.
588 /// \tparam fnT A function pointer or functor.
589 /// \tparam a1T Type of argument 1.
590 /// \param[in,out] fn The function to be called in the task.
591 /// \param[in] a1 Argument 1.
592 /// \param[in] attr The task attributes.
593 /// \return A future to the result. If the task function return
594 /// type is \c void, a \c Future<void> object is returned that may
595 /// be ignored.
596 /// \note future_to_ref_t is used instead of remove_future_t so that
597 /// argument Future's convert to refs so that X(Y&) can invoked by add(X, Future<T>);
598 /// if remove_future_t were used, X(Y) would be expected instead.
599 /// This is reasonable if we remember the shallow copy semantics of Futures: they act
600 /// as refs.
601 template <typename fnT, typename... argsT,
602 typename = std::enable_if_t<
603 meta::taskattr_is_last_arg<argsT...>::value>>
605 add(fnT&& fn, argsT&&... args) {
606 using taskT = typename meta::drop_last_arg_and_apply<TaskFn,
607 std::decay_t<fnT>,
608 std::remove_cv_t<std::remove_reference_t<argsT>>...>::type;
609 return add(new taskT(typename taskT::futureT(), std::forward<fnT>(fn),
610 std::forward<argsT>(args)...));
611 }
612
613 template <typename fnT, typename... argsT,
614 typename = std::enable_if_t<
615 !meta::taskattr_is_last_arg<argsT...>::value>>
616 typename detail::function_enabler<fnT(future_to_ref_t<argsT>...)>::type add(
617 fnT&& fn, argsT&&... args) {
618 using taskT = TaskFn<std::decay_t<fnT>, std::remove_cv_t<std::remove_reference_t<argsT>>...>;
619 return add(new taskT(typename taskT::futureT(), std::forward<fnT>(fn),
620 std::forward<argsT>(args)..., TaskAttributes()));
621 }
622
623#else
624 /// Create a local task with no arguments.
625
626 /// Creates a task in this process. An argument that is a future may be
627 /// used to carry dependencies.
628 /// \tparam fnT A function pointer or functor.
629 /// \param[in,out] fn The function to be called in the task.
630 /// \param[in] attr The task attributes.
631 /// \return A future to the result. If the task function return
632 /// type is \c void, a \c Future<void> object is returned that may
633 /// be ignored.
634 template <typename fnT>
635 typename detail::function_enabler<fnT()>::type
636 add(fnT fn, const TaskAttributes& attr=TaskAttributes()) {
637 typedef TaskFn<fnT> taskT;
638 return add(new taskT(typename taskT::futureT(),
639 fn, attr));
640 }
641
642 /// Create a local task with one argument.
643
644 /// Creates a task in this process. An argument that is a future may be
645 /// used to carry dependencies.
646 /// \tparam fnT A function pointer or functor.
647 /// \tparam a1T Type of argument 1.
648 /// \param[in,out] fn The function to be called in the task.
649 /// \param[in] a1 Argument 1.
650 /// \param[in] attr The task attributes.
651 /// \return A future to the result. If the task function return
652 /// type is \c void, a \c Future<void> object is returned that may
653 /// be ignored.
654 template <typename fnT, typename a1T>
655 typename detail::function_enabler<fnT(a1T)>::type
656 add(fnT fn, const a1T& a1, const TaskAttributes& attr=TaskAttributes()) {
657 typedef TaskFn<fnT, a1T> taskT;
658 return add(new taskT(typename taskT::futureT(),
659 fn, a1, attr));
660 }
661
662 /// Create a local task with two arguments.
663
664 /// Creates a task in this process. An argument that is a future may be
665 /// used to carry dependencies.
666 /// \tparam fnT A function pointer or functor.
667 /// \tparam a1T Type of argument 1.
668 /// \tparam a2T Type of argument 2.
669 /// \param[in,out] fn The function to be called in the task.
670 /// \param[in] a1 Argument 1.
671 /// \param[in] a2 Argument 2.
672 /// \param[in] attr The task attributes.
673 /// \return A future to the result. If the task function return
674 /// type is \c void, a \c Future<void> object is returned that may
675 /// be ignored.
676 template <typename fnT, typename a1T, typename a2T>
677 typename detail::function_enabler<fnT(a1T, a2T)>::type
678 add(fnT fn, const a1T& a1, const a2T& a2, const TaskAttributes& attr=TaskAttributes()) {
679 typedef TaskFn<fnT, a1T, a2T> taskT;
680 return add(new taskT(typename taskT::futureT(),
681 fn, a1, a2, attr));
682 }
683
684 /// Create a local task with three arguments.
685
686 /// Creates a task in this process. An argument that is a future may be
687 /// used to carry dependencies.
688 /// \tparam fnT A function pointer or functor.
689 /// \tparam a1T Type of argument 1.
690 /// \tparam a2T Type of argument 2.
691 /// \tparam a3T Type of argument 3.
692 /// \param[in,out] fn The function to be called in the task.
693 /// \param[in] a1 Argument 1.
694 /// \param[in] a2 Argument 2.
695 /// \param[in] a3 Argument 3.
696 /// \param[in] attr The task attributes.
697 /// \return A future to the result. If the task function return
698 /// type is \c void, a \c Future<void> object is returned that may
699 /// be ignored.
700 template <typename fnT, typename a1T, typename a2T, typename a3T>
701 typename detail::function_enabler<fnT(a1T, a2T, a3T)>::type
702 add(fnT fn, const a1T& a1, const a2T& a2, const a3T& a3,
703 const TaskAttributes& attr=TaskAttributes())
704 {
705 typedef TaskFn<fnT, a1T, a2T, a3T> taskT;
706 return add(new taskT(typename taskT::futureT(),
707 fn, a1, a2, a3, attr));
708 }
709
710 /// Create a local task with four arguments.
711
712 /// Creates a task in this process. An argument that is a future may be
713 /// used to carry dependencies.
714 /// \tparam fnT A function pointer or functor.
715 /// \tparam a1T Type of argument 1.
716 /// \tparam a2T Type of argument 2.
717 /// \tparam a3T Type of argument 3.
718 /// \tparam a4T Type of argument 4.
719 /// \param[in,out] fn The function to be called in the task.
720 /// \param[in] a1 Argument 1.
721 /// \param[in] a2 Argument 2.
722 /// \param[in] a3 Argument 3.
723 /// \param[in] a4 Argument 4.
724 /// \param[in] attr The task attributes.
725 /// \return A future to the result. If the task function return
726 /// type is \c void, a \c Future<void> object is returned that may
727 /// be ignored.
728 template <typename fnT, typename a1T, typename a2T, typename a3T, typename a4T>
729 typename detail::function_enabler<fnT(a1T, a2T, a3T, a4T)>::type
730 add(fnT fn, const a1T& a1, const a2T& a2, const a3T& a3, const a4T& a4,
731 const TaskAttributes& attr=TaskAttributes())
732 {
734 return add(new taskT(typename taskT::futureT(),
735 fn, a1, a2, a3, a4, attr));
736 }
737
738 /// Create a local task with five arguments.
739
740 /// Creates a task in this process. An argument that is a future may be
741 /// used to carry dependencies.
742 /// \tparam fnT A function pointer or functor.
743 /// \tparam a1T Type of argument 1.
744 /// \tparam a2T Type of argument 2.
745 /// \tparam a3T Type of argument 3.
746 /// \tparam a4T Type of argument 4.
747 /// \tparam a5T Type of argument 5.
748 /// \param[in,out] fn The function to be called in the task.
749 /// \param[in] a1 Argument 1.
750 /// \param[in] a2 Argument 2.
751 /// \param[in] a3 Argument 3.
752 /// \param[in] a4 Argument 4.
753 /// \param[in] a5 Argument 5.
754 /// \param[in] attr The task attributes.
755 /// \return A future to the result. If the task function return
756 /// type is \c void, a \c Future<void> object is returned that may
757 /// be ignored.
758 template <typename fnT, typename a1T, typename a2T, typename a3T, typename a4T,
759 typename a5T>
760 typename detail::function_enabler<fnT(a1T, a2T, a3T, a4T, a5T)>::type
761 add(fnT fn, const a1T& a1, const a2T& a2, const a3T& a3, const a4T& a4,
762 const a5T& a5, const TaskAttributes& attr=TaskAttributes())
763 {
765 return add(new taskT(typename taskT::futureT(),
766 fn, a1, a2, a3, a4, a5, attr));
767 }
768
769 /// Create a local task with six arguments.
770
771 /// Creates a task in this process. An argument that is a future may be
772 /// used to carry dependencies.
773 /// \tparam fnT A function pointer or functor.
774 /// \tparam a1T Type of argument 1.
775 /// \tparam a2T Type of argument 2.
776 /// \tparam a3T Type of argument 3.
777 /// \tparam a4T Type of argument 4.
778 /// \tparam a5T Type of argument 5.
779 /// \tparam a6T Type of argument 6.
780 /// \param[in,out] fn The function to be called in the task.
781 /// \param[in] a1 Argument 1.
782 /// \param[in] a2 Argument 2.
783 /// \param[in] a3 Argument 3.
784 /// \param[in] a4 Argument 4.
785 /// \param[in] a5 Argument 5.
786 /// \param[in] a6 Argument 6.
787 /// \param[in] attr The task attributes.
788 /// \return A future to the result. If the task function return
789 /// type is \c void, a \c Future<void> object is returned that may
790 /// be ignored.
791 template <typename fnT, typename a1T, typename a2T, typename a3T, typename a4T,
792 typename a5T, typename a6T>
793 typename detail::function_enabler<fnT(a1T, a2T, a3T, a4T, a5T, a6T)>::type
794 add(fnT fn, const a1T& a1, const a2T& a2, const a3T& a3, const a4T& a4,
795 const a5T& a5, const a6T& a6, const TaskAttributes& attr=TaskAttributes())
796 {
798 return add(new taskT(typename taskT::futureT(),
799 fn, a1, a2, a3, a4, a5, a6, attr));
800 }
801
802 /// Create a local task with seven arguments.
803
804 /// Creates a task in this process. An argument that is a future may be
805 /// used to carry dependencies.
806 /// \tparam fnT A function pointer or functor.
807 /// \tparam a1T Type of argument 1.
808 /// \tparam a2T Type of argument 2.
809 /// \tparam a3T Type of argument 3.
810 /// \tparam a4T Type of argument 4.
811 /// \tparam a5T Type of argument 5.
812 /// \tparam a6T Type of argument 6.
813 /// \tparam a7T Type of argument 7.
814 /// \param[in,out] fn The function to be called in the task.
815 /// \param[in] a1 Argument 1.
816 /// \param[in] a2 Argument 2.
817 /// \param[in] a3 Argument 3.
818 /// \param[in] a4 Argument 4.
819 /// \param[in] a5 Argument 5.
820 /// \param[in] a6 Argument 6.
821 /// \param[in] a7 Argument 7.
822 /// \param[in] attr The task attributes.
823 /// \return A future to the result. If the task function return
824 /// type is \c void, a \c Future<void> object is returned that may
825 /// be ignored.
826 template <typename fnT, typename a1T, typename a2T, typename a3T, typename a4T,
827 typename a5T, typename a6T, typename a7T>
828 typename detail::function_enabler<fnT(a1T, a2T, a3T, a4T, a5T, a6T, a7T)>::type
829 add(fnT fn, const a1T& a1, const a2T& a2, const a3T& a3, const a4T& a4,
830 const a5T& a5, const a6T& a6, const a7T& a7,
831 const TaskAttributes& attr=TaskAttributes())
832 {
834 return add(new taskT(typename taskT::futureT(),
835 fn, a1, a2, a3, a4, a5, a6, a7, attr));
836 }
837
838 /// Create a local task with eight arguments.
839
840 /// Creates a task in this process. An argument that is a future may be
841 /// used to carry dependencies.
842 /// \tparam fnT A function pointer or functor.
843 /// \tparam a1T Type of argument 1.
844 /// \tparam a2T Type of argument 2.
845 /// \tparam a3T Type of argument 3.
846 /// \tparam a4T Type of argument 4.
847 /// \tparam a5T Type of argument 5.
848 /// \tparam a6T Type of argument 6.
849 /// \tparam a7T Type of argument 7.
850 /// \tparam a8T Type of argument 8.
851 /// \param[in,out] fn The function to be called in the task.
852 /// \param[in] a1 Argument 1.
853 /// \param[in] a2 Argument 2.
854 /// \param[in] a3 Argument 3.
855 /// \param[in] a4 Argument 4.
856 /// \param[in] a5 Argument 5.
857 /// \param[in] a6 Argument 6.
858 /// \param[in] a7 Argument 7.
859 /// \param[in] a8 Argument 8.
860 /// \param[in] attr The task attributes.
861 /// \return A future to the result. If the task function return
862 /// type is \c void, a \c Future<void> object is returned that may
863 /// be ignored.
864 template <typename fnT, typename a1T, typename a2T, typename a3T, typename a4T,
865 typename a5T, typename a6T, typename a7T, typename a8T>
866 typename detail::function_enabler<fnT(a1T, a2T, a3T, a4T, a5T, a6T, a7T, a8T)>::type
867 add(fnT fn, const a1T& a1, const a2T& a2, const a3T& a3, const a4T& a4,
868 const a5T& a5, const a6T& a6, const a7T& a7, const a8T& a8,
869 const TaskAttributes& attr=TaskAttributes())
870 {
872 return add(new taskT(typename taskT::futureT(),
873 fn, a1, a2, a3, a4, a5, a6, a7, a8, attr));
874 }
875
876 /// Create a local task with nine arguments.
877
878 /// Creates a task in this process. An argument that is a future may be
879 /// used to carry dependencies.
880 /// \tparam fnT A function pointer or functor.
881 /// \tparam a1T Type of argument 1.
882 /// \tparam a2T Type of argument 2.
883 /// \tparam a3T Type of argument 3.
884 /// \tparam a4T Type of argument 4.
885 /// \tparam a5T Type of argument 5.
886 /// \tparam a6T Type of argument 6.
887 /// \tparam a7T Type of argument 7.
888 /// \tparam a8T Type of argument 8.
889 /// \tparam a9T Type of argument 9.
890 /// \param[in,out] fn The function to be called in the task.
891 /// \param[in] a1 Argument 1.
892 /// \param[in] a2 Argument 2.
893 /// \param[in] a3 Argument 3.
894 /// \param[in] a4 Argument 4.
895 /// \param[in] a5 Argument 5.
896 /// \param[in] a6 Argument 6.
897 /// \param[in] a7 Argument 7.
898 /// \param[in] a8 Argument 8.
899 /// \param[in] a9 Argument 9.
900 /// \param[in] attr The task attributes.
901 /// \return A future to the result. If the task function return
902 /// type is \c void, a \c Future<void> object is returned that may
903 /// be ignored.
904 template <typename fnT, typename a1T, typename a2T, typename a3T, typename a4T,
905 typename a5T, typename a6T, typename a7T, typename a8T, typename a9T>
906 typename detail::function_enabler<fnT(a1T, a2T, a3T, a4T, a5T, a6T, a7T, a8T, a9T)>::type
907 add(fnT fn, const a1T& a1, const a2T& a2, const a3T& a3, const a4T& a4,
908 const a5T& a5, const a6T& a6, const a7T& a7, const a8T& a8, const a9T& a9,
909 const TaskAttributes& attr=TaskAttributes())
910 {
912 return add(new taskT(typename taskT::futureT(),
913 fn, a1, a2, a3, a4, a5, a6, a7, a8, a9, attr));
914 }
915#endif
916
917 /// Create a remote task.
918
919 /// Creates a task in process \c dest, which may or may not be this
920 /// process. An argument that is a future may be used to carry
921 /// dependencies for local tasks. A future that is not ready cannot be
922 /// used as an argument for remote tasks -- i.e., remote tasks must
923 /// be ready to execute (you can work around this by making a local task
924 /// to submit the remote task once everything is ready).
925 /// \tparam fnT A function pointer or functor type.
926 /// \param[in] dest The process where the task will be created.
927 /// \param[in] fn The function to be called in the task.
928 /// \param[in] attr The task attributes.
929 /// \return A future to the result. If the task function return type
930 /// is \c void, a \c Future<void> object is return that may
931 /// be ignored.
932 /// \note Arguments must be (de)serializable and must of course make
933 /// sense at the remote destination. Fundamental types, simple STL
934 /// containers, and pointers to \c World, \c WorldContainer, and
935 /// user-defined types derived from \c WorldObject<> are automatically
936 /// handled. Anything else is your problem.
937 template <typename fnT>
939 add(ProcessID dest, fnT fn, const TaskAttributes& attr=TaskAttributes())
940 {
941 typedef TaskFn<fnT> taskT;
942 if(dest == me)
943 return add(fn, attr);
944 else
945 return send_task<taskT>(dest, fn, voidT::value, voidT::value,
948 }
949
950 /// Invoke `resultT (*fn)(a1T)` as a task, local or remote.
951
952 /// A future is returned to hold the eventual result of the task.
953 /// \c Future<void> is an empty class that may be ignored.
954 /// \tparam fnT A function pointer or functor type.
955 /// \tparam a1T Type of argument 1.
956 /// \param[in] dest The process where the task will be created.
957 /// \param[in] fn The function to be called in the task.
958 /// \param[in] a1 Argument 1.
959 /// \param[in] attr The task attributes.
960 /// \return A future to the result. If the task function return type
961 /// is \c void, a \c Future<void> object is return that may
962 /// be ignored.
963 /// \note Arguments must be (de)serializable and must of course make
964 /// sense at the remote destination. Fundamental types,
965 /// simple STL containers, and pointers to \c World,
966 /// \c WorldContainer, and user-defined types derived from
967 /// \c WorldObject are automatically handled. Anything else is
968 /// your problem.
969 template <typename fnT, typename a1T>
971 add(ProcessID dest, fnT fn, const a1T& a1, const TaskAttributes& attr=TaskAttributes())
972 {
973 typedef TaskFn<fnT, a1T> taskT;
974 if(dest == me)
975 return add(fn, a1, attr);
976 else
977 return send_task<taskT>(dest, fn, am_arg(a1), voidT::value,
980 }
981
982 /// Invoke `resultT (*fn)(a1T,a2T)` as a task, local or remote.
983
984 /// A future is returned to hold the eventual result of the task.
985 /// \c Future<void> is an empty class that may be ignored.
986 /// \tparam fnT A function pointer or functor type.
987 /// \tparam a1T Type of argument 1.
988 /// \tparam a2T Type of argument 2.
989 /// \param[in] dest The process where the task will be created.
990 /// \param[in] fn The function to be called in the task.
991 /// \param[in] a1 Argument 1.
992 /// \param[in] a2 Argument 2.
993 /// \param[in] attr The task attributes.
994 /// \return A future to the result. If the task function return type
995 /// is \c void, a \c Future<void> object is return that may
996 /// be ignored.
997 /// \note Arguments must be (de)serializable and must of course make
998 /// sense at the remote destination. Fundamental types,
999 /// simple STL containers, and pointers to \c World,
1000 /// \c WorldContainer, and user-defined types derived from
1001 /// \c WorldObject are automatically handled. Anything else is
1002 /// your problem.
1003 template <typename fnT, typename a1T, typename a2T>
1005 add(ProcessID dest, fnT fn, const a1T& a1, const a2T& a2,
1006 const TaskAttributes& attr=TaskAttributes())
1007 {
1008 typedef TaskFn<fnT, a1T, a2T> taskT;
1009 if(dest == me)
1010 return add(fn, a1, a2, attr);
1011 else
1012 return send_task<taskT>(dest, fn, am_arg(a1), am_arg(a2),
1015 }
1016
1017 /// Invoke `resultT (*fn)(a1T,a2T,a3T)` as a task, local or remote.
1018
1019 /// A future is returned to hold the eventual result of the task.
1020 /// \c Future<void> is an empty class that may be ignored.
1021 /// \tparam fnT A function pointer or functor type.
1022 /// \tparam a1T Type of argument 1.
1023 /// \tparam a2T Type of argument 2.
1024 /// \tparam a3T Type of argument 3.
1025 /// \param[in] dest The process where the task will be created.
1026 /// \param[in] fn The function to be called in the task.
1027 /// \param[in] a1 Argument 1.
1028 /// \param[in] a2 Argument 2.
1029 /// \param[in] a3 Argument 3.
1030 /// \param[in] attr The task attributes.
1031 /// \return A future to the result. If the task function return type
1032 /// is \c void, a \c Future<void> object is return that may
1033 /// be ignored.
1034 /// \note Arguments must be (de)serializable and must of course make
1035 /// sense at the remote destination. Fundamental types,
1036 /// simple STL containers, and pointers to \c World,
1037 /// \c WorldContainer, and user-defined types derived from
1038 /// \c WorldObject are automatically handled. Anything else is
1039 /// your problem.
1040 template <typename fnT, typename a1T, typename a2T, typename a3T>
1042 add(ProcessID dest, fnT fn, const a1T& a1, const a2T& a2, const a3T& a3,
1043 const TaskAttributes& attr=TaskAttributes())
1044 {
1045 typedef TaskFn<fnT, a1T, a2T, a3T> taskT;
1046 if(dest == me)
1047 return add(fn, a1, a2, a3, attr);
1048 else
1049 return send_task<taskT>(dest, fn, am_arg(a1), am_arg(a2),
1052 }
1053
1054 /// Invoke `resultT (*fn)(a1T,a2T,a3T,a4T)` as a task, local or remote.
1055
1056 /// A future is returned to hold the eventual result of the task.
1057 /// \c Future<void> is an empty class that may be ignored.
1058 /// \tparam fnT A function pointer or functor type.
1059 /// \tparam a1T Type of argument 1.
1060 /// \tparam a2T Type of argument 2.
1061 /// \tparam a3T Type of argument 3.
1062 /// \tparam a4T Type of argument 4.
1063 /// \param[in] dest The process where the task will be created.
1064 /// \param[in] fn The function to be called in the task.
1065 /// \param[in] a1 Argument 1.
1066 /// \param[in] a2 Argument 2.
1067 /// \param[in] a3 Argument 3.
1068 /// \param[in] a4 Argument 4.
1069 /// \param[in] attr The task attributes.
1070 /// \return A future to the result. If the task function return type
1071 /// is \c void, a \c Future<void> object is return that may
1072 /// be ignored.
1073 /// \note Arguments must be (de)serializable and must of course make
1074 /// sense at the remote destination. Fundamental types,
1075 /// simple STL containers, and pointers to \c World,
1076 /// \c WorldContainer, and user-defined types derived from
1077 /// \c WorldObject are automatically handled. Anything else is
1078 /// your problem.
1079 template <typename fnT, typename a1T, typename a2T, typename a3T,
1080 typename a4T>
1082 add(ProcessID dest, fnT fn, const a1T& a1, const a2T& a2, const a3T& a3,
1083 const a4T& a4, const TaskAttributes& attr=TaskAttributes())
1084 {
1085 typedef TaskFn<fnT, a1T, a2T, a3T, a4T> taskT;
1086 if(dest == me)
1087 return add(fn, a1, a2, a3, a4, attr);
1088 else
1089 return send_task<taskT>(dest, fn, am_arg(a1), am_arg(a2),
1092 }
1093
1094 /// Invoke `resultT (*fn)(a1T,a2T,a3T,a4T,a5T)` as a task, local or remote.
1095
1096 /// A future is returned to hold the eventual result of the task.
1097 /// \c Future<void> is an empty class that may be ignored.
1098 /// \tparam fnT A function pointer or functor type.
1099 /// \tparam a1T Type of argument 1.
1100 /// \tparam a2T Type of argument 2.
1101 /// \tparam a3T Type of argument 3.
1102 /// \tparam a4T Type of argument 4.
1103 /// \tparam a5T Type of argument 5.
1104 /// \param[in] dest The process where the task will be created.
1105 /// \param[in] fn The function to be called in the task.
1106 /// \param[in] a1 Argument 1.
1107 /// \param[in] a2 Argument 2.
1108 /// \param[in] a3 Argument 3.
1109 /// \param[in] a4 Argument 4.
1110 /// \param[in] a5 Argument 5.
1111 /// \param[in] attr The task attributes.
1112 /// \return A future to the result. If the task function return type
1113 /// is \c void, a \c Future<void> object is return that may
1114 /// be ignored.
1115 /// \note Arguments must be (de)serializable and must of course make
1116 /// sense at the remote destination. Fundamental types,
1117 /// simple STL containers, and pointers to \c World,
1118 /// \c WorldContainer, and user-defined types derived from
1119 /// \c WorldObject are automatically handled. Anything else is
1120 /// your problem.
1121 template <typename fnT, typename a1T, typename a2T, typename a3T,
1122 typename a4T, typename a5T>
1124 add(ProcessID dest, fnT fn, const a1T& a1, const a2T& a2, const a3T& a3,
1125 const a4T& a4, const a5T& a5, const TaskAttributes& attr=TaskAttributes())
1126 {
1128 if(dest == me)
1129 return add(fn, a1, a2, a3, a4, a5, attr);
1130 else
1131 return send_task<taskT>(dest, fn, am_arg(a1), am_arg(a2),
1132 am_arg(a3), am_arg(a4), am_arg(a5), voidT::value,
1134 }
1135
1136 /// Invoke `resultT (*fn)(a1T,a2T,a3T,a4T,a5T,a6T)` as a task, local or remote.
1137
1138 /// A future is returned to hold the eventual result of the task.
1139 /// \c Future<void> is an empty class that may be ignored.
1140 /// \tparam fnT A function pointer or functor type.
1141 /// \tparam a1T Type of argument 1.
1142 /// \tparam a2T Type of argument 2.
1143 /// \tparam a3T Type of argument 3.
1144 /// \tparam a4T Type of argument 4.
1145 /// \tparam a5T Type of argument 5.
1146 /// \tparam a6T Type of argument 6.
1147 /// \param[in] dest The process where the task will be created.
1148 /// \param[in] fn The function to be called in the task.
1149 /// \param[in] a1 Argument 1.
1150 /// \param[in] a2 Argument 2.
1151 /// \param[in] a3 Argument 3.
1152 /// \param[in] a4 Argument 4.
1153 /// \param[in] a5 Argument 5.
1154 /// \param[in] a6 Argument 6.
1155 /// \param[in] attr The task attributes.
1156 /// \return A future to the result. If the task function return type
1157 /// is \c void, a \c Future<void> object is return that may
1158 /// be ignored.
1159 /// \note Arguments must be (de)serializable and must of course make
1160 /// sense at the remote destination. Fundamental types,
1161 /// simple STL containers, and pointers to \c World,
1162 /// \c WorldContainer, and user-defined types derived from
1163 /// \c WorldObject are automatically handled. Anything else is
1164 /// your problem.
1165 template <typename fnT, typename a1T, typename a2T, typename a3T,
1166 typename a4T, typename a5T, typename a6T>
1168 add(ProcessID dest, fnT fn, const a1T& a1, const a2T& a2, const a3T& a3,
1169 const a4T& a4, const a5T& a5, const a6T& a6,
1170 const TaskAttributes& attr=TaskAttributes())
1171 {
1173 if(dest == me)
1174 return add(fn, a1, a2, a3, a4, a5, a6, attr);
1175 else
1176 return send_task<taskT>(dest, fn, am_arg(a1), am_arg(a2),
1177 am_arg(a3), am_arg(a4), am_arg(a5), am_arg(a6),
1179 }
1180
1181 /// Invoke `resultT (*fn)(a1T,a2T,a3T,a4T,a5T,a6T,a7T)` as a task, local or remote.
1182
1183 /// A future is returned to hold the eventual result of the task.
1184 /// \c Future<void> is an empty class that may be ignored.
1185 /// \tparam fnT A function pointer or functor type.
1186 /// \tparam a1T Type of argument 1.
1187 /// \tparam a2T Type of argument 2.
1188 /// \tparam a3T Type of argument 3.
1189 /// \tparam a4T Type of argument 4.
1190 /// \tparam a5T Type of argument 5.
1191 /// \tparam a6T Type of argument 6.
1192 /// \tparam a7T Type of argument 7.
1193 /// \param[in] dest The process where the task will be created.
1194 /// \param[in] fn The function to be called in the task.
1195 /// \param[in] a1 Argument 1.
1196 /// \param[in] a2 Argument 2.
1197 /// \param[in] a3 Argument 3.
1198 /// \param[in] a4 Argument 4.
1199 /// \param[in] a5 Argument 5.
1200 /// \param[in] a6 Argument 6.
1201 /// \param[in] a7 Argument 7.
1202 /// \param[in] attr The task attributes.
1203 /// \return A future to the result. If the task function return type
1204 /// is \c void, a \c Future<void> object is return that may
1205 /// be ignored.
1206 /// \note Arguments must be (de)serializable and must of course make
1207 /// sense at the remote destination. Fundamental types,
1208 /// simple STL containers, and pointers to \c World,
1209 /// \c WorldContainer, and user-defined types derived from
1210 /// \c WorldObject are automatically handled. Anything else is
1211 /// your problem.
1212 template <typename fnT, typename a1T, typename a2T, typename a3T,
1213 typename a4T, typename a5T, typename a6T, typename a7T>
1215 add(ProcessID dest, fnT fn, const a1T& a1, const a2T& a2, const a3T& a3,
1216 const a4T& a4, const a5T& a5, const a6T& a6, const a7T& a7,
1217 const TaskAttributes& attr=TaskAttributes())
1218 {
1220 if(dest == me)
1221 return add(fn, a1, a2, a3, a4, a5, a6, a7, attr);
1222 else
1223 return send_task<taskT>(dest, fn, am_arg(a1), am_arg(a2),
1224 am_arg(a3), am_arg(a4), am_arg(a5), am_arg(a6),
1225 am_arg(a7), voidT::value, voidT::value, attr);
1226 }
1227
1228 /// Invoke `resultT (*fn)(a1T,a2T,a3T,a4T,a5T,a6T,a7T,a8T)` as a task, local or remote.
1229
1230 /// A future is returned to hold the eventual result of the task.
1231 /// \c Future<void> is an empty class that may be ignored.
1232 /// \tparam fnT A function pointer or functor type.
1233 /// \tparam a1T Type of argument 1.
1234 /// \tparam a2T Type of argument 2.
1235 /// \tparam a3T Type of argument 3.
1236 /// \tparam a4T Type of argument 4.
1237 /// \tparam a5T Type of argument 5.
1238 /// \tparam a6T Type of argument 6.
1239 /// \tparam a7T Type of argument 7.
1240 /// \tparam a8T Type of argument 8.
1241 /// \param[in] dest The process where the task will be created.
1242 /// \param[in] fn The function to be called in the task.
1243 /// \param[in] a1 Argument 1.
1244 /// \param[in] a2 Argument 2.
1245 /// \param[in] a3 Argument 3.
1246 /// \param[in] a4 Argument 4.
1247 /// \param[in] a5 Argument 5.
1248 /// \param[in] a6 Argument 6.
1249 /// \param[in] a7 Argument 7.
1250 /// \param[in] a8 Argument 8.
1251 /// \param[in] attr The task attributes.
1252 /// \return A future to the result. If the task function return type
1253 /// is \c void, a \c Future<void> object is return that may
1254 /// be ignored.
1255 /// \note Arguments must be (de)serializable and must of course make
1256 /// sense at the remote destination. Fundamental types,
1257 /// simple STL containers, and pointers to \c World,
1258 /// \c WorldContainer, and user-defined types derived from
1259 /// \c WorldObject are automatically handled. Anything else is
1260 /// your problem.
1261 template <typename fnT, typename a1T, typename a2T, typename a3T,
1262 typename a4T, typename a5T, typename a6T, typename a7T,
1263 typename a8T>
1265 add(ProcessID dest, fnT fn, const a1T& a1, const a2T& a2, const a3T& a3,
1266 const a4T& a4, const a5T& a5, const a6T& a6, const a7T& a7,
1267 const a8T& a8, const TaskAttributes& attr=TaskAttributes())
1268 {
1270 if(dest == me)
1271 return add(fn, a1, a2, a3, a4, a5, a6, a7, a8, attr);
1272 else
1273 return send_task<taskT>(dest, fn, am_arg(a1), am_arg(a2),
1274 am_arg(a3), am_arg(a4), am_arg(a5), am_arg(a6),
1275 am_arg(a7), am_arg(a8), voidT::value, attr);
1276 }
1277
1278 /// Invoke `resultT (*fn)(a1T,a2T,a3T,a4T,a5T,a6T,a7T,a8T,a9T)` as a task, local or remote.
1279
1280 /// A future is returned to hold the eventual result of the task.
1281 /// \c Future<void> is an empty class that may be ignored.
1282 /// \tparam fnT A function pointer or functor type.
1283 /// \tparam a1T Type of argument 1.
1284 /// \tparam a2T Type of argument 2.
1285 /// \tparam a3T Type of argument 3.
1286 /// \tparam a4T Type of argument 4.
1287 /// \tparam a5T Type of argument 5.
1288 /// \tparam a6T Type of argument 6.
1289 /// \tparam a7T Type of argument 7.
1290 /// \tparam a8T Type of argument 8.
1291 /// \tparam a9T Type of argument 9.
1292 /// \param[in] dest The process where the task will be created.
1293 /// \param[in] fn The function to be called in the task.
1294 /// \param[in] a1 Argument 1.
1295 /// \param[in] a2 Argument 2.
1296 /// \param[in] a3 Argument 3.
1297 /// \param[in] a4 Argument 4.
1298 /// \param[in] a5 Argument 5.
1299 /// \param[in] a6 Argument 6.
1300 /// \param[in] a7 Argument 7.
1301 /// \param[in] a8 Argument 8.
1302 /// \param[in] a9 Argument 9.
1303 /// \param[in] attr The task attributes.
1304 /// \return A future to the result. If the task function return type
1305 /// is \c void, a \c Future<void> object is return that may
1306 /// be ignored.
1307 /// \note Arguments must be (de)serializable and must of course make
1308 /// sense at the remote destination. Fundamental types,
1309 /// simple STL containers, and pointers to \c World,
1310 /// \c WorldContainer, and user-defined types derived from
1311 /// \c WorldObject are automatically handled. Anything else is
1312 /// your problem.
1313 /// \todo Could we use metaprogramming or variadic templates to reduce all of these instances to one template that generates versions for one more (less) parameter?
1314 template <typename fnT, typename a1T, typename a2T, typename a3T,
1315 typename a4T, typename a5T, typename a6T, typename a7T,
1316 typename a8T, typename a9T>
1318 add(ProcessID dest, fnT fn, const a1T& a1, const a2T& a2, const a3T& a3,
1319 const a4T& a4, const a5T& a5, const a6T& a6, const a7T& a7,
1320 const a8T& a8, const a9T& a9, const TaskAttributes& attr=TaskAttributes())
1321 {
1323 if(dest == me)
1324 return add(fn, a1, a2, a3, a4, a5, a6, a7, a8, a9, attr);
1325 else
1326 return send_task<taskT>(dest, fn, am_arg(a1), am_arg(a2),
1327 am_arg(a3), am_arg(a4), am_arg(a5), am_arg(a6),
1328 am_arg(a7), am_arg(a8), am_arg(a9), attr);
1329 }
1330
1331 /// Invoke `resultT (obj.*memfn)(args...)` as a local task.
1332
1333 /// \todo Verify this documentation.
1334 /// A future is returned to hold the eventual result of the task.
1335 /// \c Future<void> is an empty class that may be ignored.
1336 /// \tparam objT The object type.
1337 /// \tparam memfnT The member function type.
1338 /// \tparam argT Variadic template for arguments.
1339 /// \param[in] obj The associated object for invoking the member function pointer.
1340 /// \param[in] memfn The member function pointer.
1341 /// \param[in] args The argument pack.
1342 /// \return A future to the result. If the task function return type
1343 /// is \c void, a \c Future<void> object is return that may
1344 /// be ignored.
1345 /// \note Arguments must be (de)serializable and must of course make
1346 /// sense at the remote destination. Fundamental types,
1347 /// simple STL containers, and pointers to \c World,
1348 /// \c WorldContainer, and user-defined types derived from
1349 /// \c WorldObject are automatically handled. Anything else is
1350 /// your problem.
1351 template <typename objT, typename memfnT, typename... argT>
1353 add(objT&& obj, memfnT memfn, argT&&... args)
1354 { return add(detail::wrap_mem_fn(std::forward<objT>(obj),memfn), std::forward<argT>(args)...); }
1355
1356
1357
1358 private:
1359
1360 /// \todo Brief description needed.
1362 WorldTaskQueue* tq; ///< The task queue.
1363
1364 /// Construct a \c ProbeAllDone for a given task queue.
1365
1366 /// \param[in] tq Pointer to the task queue.
1370
1371 /// Determine if all tasks in the queue are complete.
1372
1373 /// \return True if all tasks are complete; false otherwise.
1374 bool operator()() const {
1375 return (tq->nregistered == 0);
1376 }
1377 };
1378
1379 public:
1380
1381 /// Returns after all local tasks have completed.
1382
1383 /// While waiting, the calling thread will run tasks.
1384 void fence() {
1385 try {
1386 ThreadPool::await(ProbeAllDone(this), true);
1387 } catch(...) {
1388 fprintf(stderr, "!!MADNESS ERROR: Exception thrown in WorldTaskQueue::fence() with %i pending task(s)\n", int(nregistered));
1389 throw;
1390 }
1391 }
1392 };
1393
1394 namespace detail {
1395
1396#ifdef HAVE_INTEL_TBB
1397
1398 /// Apply an operation to a range of iterators.
1399
1400 /// \tparam rangeT The range of iterators type.
1401 /// \tparam opT The operation type.
1402 /// This task creates `for_each` tasks and collects information on the
1403 /// results of those tasks. Once all tasks have completed it will set
1404 /// the result future.
1405 template <typename rangeT, typename opT>
1407 private:
1408 rangeT range_; ///< The range.
1409 opT op_; ///< The foreach function.
1410 Future<bool> completion_status_; ///< The result of this set of tasks.
1411
1412 public:
1413
1414 /// Constructor.
1415
1416 /// \param[in] world The world where the tasks will run.
1417 /// \param[in] range The range of iterators.
1418 /// \param[in] op The operation that will be applied to the range of iterators.
1419 ForEachRootTask(World&, const rangeT range, const opT& op) :
1421 { }
1422
1423 /// Virtual destructor.
1424 virtual ~ForEachRootTask() = default;
1425
1426 /// Result accessor.
1427
1428 /// \return A const reference to the result future.
1429 const Future<bool>& result() const { return completion_status_; }
1430
1431 /// Task run work.
1432
1433 /// Sets the result future based on the status of all iterations.
1434 virtual void run(World&, const TaskThreadEnv& ) /*override*/ {
1435
1436 // Note: We use parallel_reduce instead of parallel_foreach to
1437 // accumulate result flags. Otherwise, this logically functions
1438 // like parallel_foreach.
1439 const bool result =
1440 tbb::parallel_reduce(range_, true,
1441 [this](const rangeT& r, bool init) -> bool {
1442 for(typename rangeT::iterator it = r.begin(); it != r.end(); ++it)
1443 init = init && op_(it);
1444 return init;
1445 },
1446 [](const bool left, const bool right) -> bool {
1447 return left && right;
1448 }
1449 );
1451 }
1452
1453 private:
1454 /// Get the task ID.
1455
1456 /// \todo Verify that \c id is an output parameter.
1457 /// \param[out] id The ID to set for this task.
1458 virtual void get_id(std::pair<void*,unsigned short>& id) const {
1459 PoolTaskInterface::make_id(id, *this);
1460 }
1461 }; // class ForEachRootTask
1462
1463#else
1464
1465 /// Apply an operation to a range of iterators.
1466
1467 /// This task will progressively split range, creating leaves for each
1468 /// task, until the range of iterators is smaller than the chunk size.
1469 /// \tparam rangeT The range of iterators type.
1470 /// \tparam opT The operation type.
1471 template <typename rangeT, typename opT>
1472 class ForEachTask : public TaskInterface {
1473 private:
1474 rangeT range_; ///< The range of iterators.
1475 opT op_; ///< The operation to apply to range.
1476 ForEachRootTask<rangeT, opT>& root_; ///< The root task that signals completion and status.
1477
1478 // not allowed
1479 ForEachTask(const ForEachTask<rangeT, opT>& fet) = delete;
1480 ForEachTask& operator=(const ForEachTask<rangeT, opT>& fet) = delete;
1481
1482 public:
1483
1484 /// Constructor.
1485
1486 /// \todo Descriptions needed.
1487 /// \param[in] range The range of tasks.
1488 /// \param[in] op The operation to perform.
1489 /// \param root Description needed.
1490 ForEachTask(const rangeT range, const opT& op, ForEachRootTask<rangeT, opT>& root) :
1491 TaskInterface(0, TaskAttributes::hipri()), range_(range), op_(op), root_(root)
1492 {
1493 // Increment the master task dependency counter for this task
1494 root_.inc();
1495 }
1496
1497 /// Virtual destructor.
1498 virtual ~ForEachTask() = default;
1499
1500 /// Run the task.
1501
1502 /// \todo Descriptions needed.
1503 /// \param[in] tte Description needed.
1504 virtual void run(const TaskThreadEnv& tte) {
1505 // Create leaf tasks and split range until it is less than chuncksize
1506 while(range_.size() > range_.get_chunksize()) {
1507 rangeT right(range_,Split());
1508 ForEachTask<rangeT,opT>* leaf = new ForEachTask<rangeT,opT>(right, op_, root_);
1509 root_.world().taskq.add(leaf);
1510 }
1511
1512 // Iterate over the remaining chunck of range and call op_ for each element
1513 int status = 0;
1514 for(typename rangeT::iterator it = range_.begin(); it != range_.end(); ++it)
1515 if(op_(it))
1516 ++status;
1517
1518 // Notify the root task that this task is done give the status
1519 root_.complete(status);
1520 }
1521
1522 private:
1523 /// Get the task ID.
1524
1525 /// \todo Is \c id an input and/or output parameter?
1526 /// \param id The ID to set for this task
1527 virtual void get_id(std::pair<void*,unsigned short>& id) const {
1528 PoolTaskInterface::make_id(id, *this);
1529 }
1530 }; // class ForEachTask
1531
1532
1533 /// Apply an operation to a range of iterators.
1534
1535 /// \tparam rangeT The range of iterators type.
1536 /// \tparam opT The operation type.
1537 /// This task creates `for_each` tasks and collects information on the
1538 /// results of those tasks. Once all tasks have completed it will set
1539 /// the result future.
1540 template <typename rangeT, typename opT>
1541 class ForEachRootTask : public TaskInterface {
1542 private:
1543 World& world_; ///< The world where this task will run.
1544 AtomicInt status_; ///< Accumulates the status of each iteration.
1545 Future<bool> completion_status_; ///< The result of this set of tasks.
1546
1547 public:
1548
1549 /// Constructor.
1550
1551 /// \param[in] world The world where the tasks will run.
1552 /// \param[in] range The range of iterators.
1553 /// \param[in] op The operation that will be applied to the range of iterators.
1554 ForEachRootTask(World& world, const rangeT range, const opT& op) :
1555 TaskInterface(0, TaskAttributes::hipri()), world_(world)
1556 {
1557 status_ = - (range.size());
1558 // Create the first for each task.
1559 world_.taskq.add(new ForEachTask<rangeT,opT>(range, op, *this));
1560 }
1561
1562 /// Virtual destructor.
1563 virtual ~ForEachRootTask() = default;
1564
1565 /// World accessor.
1566
1567 /// \return A reference to the \c World.
1568 World& world() const {
1569 return world_;
1570 }
1571
1572 /// Result accessor.
1573
1574 /// \return A const reference to the result future.
1575 const Future<bool>& result() const {
1576 return completion_status_;
1577 }
1578
1579 /// Called by child tasks when they are complete.
1580
1581 /// \param[in] status The number of iterations that returned true.
1582 void complete(const int status) {
1583 status_ += status;
1585 }
1586
1587 /// Task run work.
1588
1589 /// Sets the result future based on the status of all iterations.
1590 virtual void run(const TaskThreadEnv&) {
1591 completion_status_.set(status_ == 0);
1592 }
1593
1594 private:
1595 /// Get the task ID.
1596
1597 /// \todo Verify that \c id is an output parameter.
1598 /// \param[out] id The ID to set for this task.
1599 virtual void get_id(std::pair<void*,unsigned short>& id) const {
1600 PoolTaskInterface::make_id(id, *this);
1601 }
1602 }; // class ForEachRootTask
1603
1604#endif // HAVE_INTEL_TBB
1605
1606 } // namespace detail
1607
1608} // namespace madness
1609
1610/// @}
1611
1612#endif // MADNESS_WORLD_WORLD_TASK_QUEUE_H__INCLUDED
Disables default copy constructor and assignment operators.
Definition nodefaults.h:49
World active message that extends an RMI message.
Definition worldam.h:80
An integer with atomic set, get, read+increment, read+decrement, and decrement+test operations.
Definition atomicint.h:126
The class used for callbacks (e.g., dependency tracking).
Definition dependency_interface.h:61
void inc()
Increment the number of dependencies.
Definition dependency_interface.h:251
void notify()
Invoked by callbacks to notify of dependencies being satisfied.
Definition dependency_interface.h:183
Specialization of Future<void> for internal convenience. This does nothing useful!
Definition future.h:736
static const Future< void > value
Definition future.h:742
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
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
static const attrT ATTR_UNORDERED
Definition worldrmi.h:180
Contains attributes of a task.
Definition thread.h:323
static TaskAttributes hipri()
Definition thread.h:450
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
void set_info(World *w, CallbackInterface *c)
Set task info.
Definition taskfn.h:89
void register_submit_callback()
Adds call back to schedule task when outstanding dependencies are satisfied.
Definition taskfn.h:95
TaskInterface(int ndepend=0, const TaskAttributes attr=TaskAttributes())
Create a new task with ndepend dependencies (default 0) and given attributes.
Definition taskfn.h:104
volatile World * world
Definition taskfn.h:72
Used to pass information about the thread environment to a user's task.
Definition thread.h:466
static void await(const Probe &probe, bool dowork=true, bool sleep=false)
Gracefully wait for a condition to become true, executing any tasks in the queue.
Definition thread.h:1444
void send(ProcessID dest, am_handlerT op, const AmArg *arg, const int attr=RMI::ATTR_ORDERED)
Sends a managed non-blocking active message.
Definition worldam.h:278
Multi-threaded queue to manage and run tasks.
Definition world_task_queue.h:319
TaskFn< fnT, a1T, a2T, a3T, a4T, a5T, a6T, a7T, a8T, a9T >::futureT add(TaskFn< fnT, a1T, a2T, a3T, a4T, a5T, a6T, a7T, a8T, a9T > *t)
Definition world_task_queue.h:494
detail::voidT voidT
Definition world_task_queue.h:394
const ProcessID me
This process.
Definition world_task_queue.h:323
detail::function_enabler< fnT >::type add(ProcessID dest, fnT fn, const TaskAttributes &attr=TaskAttributes())
Create a remote task.
Definition world_task_queue.h:939
detail::function_enabler< fnT(a1T, a2T, a3T, a4T, a5T, a6T)>::type add(fnT fn, const a1T &a1, const a2T &a2, const a3T &a3, const a4T &a4, const a5T &a5, const a6T &a6, const TaskAttributes &attr=TaskAttributes())
Create a local task with six arguments.
Definition world_task_queue.h:794
detail::function_enabler< fnT >::type add(ProcessID dest, fnT fn, const a1T &a1, const a2T &a2, const a3T &a3, const a4T &a4, const a5T &a5, const a6T &a6, const TaskAttributes &attr=TaskAttributes())
Invoke resultT (*fn)(a1T,a2T,a3T,a4T,a5T,a6T) as a task, local or remote.
Definition world_task_queue.h:1168
detail::function_enabler< fnT >::type add(ProcessID dest, fnT fn, const a1T &a1, const a2T &a2, const a3T &a3, const a4T &a4, const TaskAttributes &attr=TaskAttributes())
Invoke resultT (*fn)(a1T,a2T,a3T,a4T) as a task, local or remote.
Definition world_task_queue.h:1082
size_t size() const
Returns the number of pending tasks.
Definition world_task_queue.h:451
detail::memfunc_enabler< objT, memfnT >::type add(objT &&obj, memfnT memfn, argT &&... args)
Invoke resultT (obj.*memfn)(args...) as a local task.
Definition world_task_queue.h:1353
detail::function_enabler< fnT >::type add(ProcessID dest, fnT fn, const a1T &a1, const a2T &a2, const a3T &a3, const a4T &a4, const a5T &a5, const TaskAttributes &attr=TaskAttributes())
Invoke resultT (*fn)(a1T,a2T,a3T,a4T,a5T) as a task, local or remote.
Definition world_task_queue.h:1124
void notify()
Definition world_task_queue.h:327
detail::function_enabler< fnT()>::type add(fnT fn, const TaskAttributes &attr=TaskAttributes())
Create a local task with no arguments.
Definition world_task_queue.h:636
detail::function_enabler< fnT(a1T, a2T, a3T, a4T, a5T, a6T, a7T)>::type add(fnT fn, const a1T &a1, const a2T &a2, const a3T &a3, const a4T &a4, const a5T &a5, const a6T &a6, const a7T &a7, const TaskAttributes &attr=TaskAttributes())
Create a local task with seven arguments.
Definition world_task_queue.h:829
detail::function_enabler< fnT(a1T)>::type add(fnT fn, const a1T &a1, const TaskAttributes &attr=TaskAttributes())
Create a local task with one argument.
Definition world_task_queue.h:656
Future< bool > for_each(const rangeT &range, const opT &op)
Apply op(item) on all items in range.
Definition world_task_queue.h:572
detail::function_enabler< fnT(a1T, a2T, a3T, a4T)>::type add(fnT fn, const a1T &a1, const a2T &a2, const a3T &a3, const a4T &a4, const TaskAttributes &attr=TaskAttributes())
Create a local task with four arguments.
Definition world_task_queue.h:730
static void remote_task_handler(const AmArg &arg)
Definition world_task_queue.h:353
detail::function_enabler< fnT >::type add(ProcessID dest, fnT fn, const a1T &a1, const a2T &a2, const TaskAttributes &attr=TaskAttributes())
Invoke resultT (*fn)(a1T,a2T) as a task, local or remote.
Definition world_task_queue.h:1005
World & world
The communication context.
Definition world_task_queue.h:322
detail::function_enabler< fnT(a1T, a2T, a3T)>::type add(fnT fn, const a1T &a1, const a2T &a2, const a3T &a3, const TaskAttributes &attr=TaskAttributes())
Create a local task with three arguments.
Definition world_task_queue.h:702
detail::function_enabler< fnT >::type add(ProcessID dest, fnT fn, const a1T &a1, const a2T &a2, const a3T &a3, const a4T &a4, const a5T &a5, const a6T &a6, const a7T &a7, const a8T &a8, const a9T &a9, const TaskAttributes &attr=TaskAttributes())
Invoke resultT (*fn)(a1T,a2T,a3T,a4T,a5T,a6T,a7T,a8T,a9T) as a task, local or remote.
Definition world_task_queue.h:1318
const T & am_arg(const Future< T > &f)
Definition world_task_queue.h:377
detail::function_enabler< fnT(a1T, a2T)>::type add(fnT fn, const a1T &a1, const a2T &a2, const TaskAttributes &attr=TaskAttributes())
Create a local task with two arguments.
Definition world_task_queue.h:678
detail::function_enabler< fnT >::type add(ProcessID dest, fnT fn, const a1T &a1, const a2T &a2, const a3T &a3, const TaskAttributes &attr=TaskAttributes())
Invoke resultT (*fn)(a1T,a2T,a3T) as a task, local or remote.
Definition world_task_queue.h:1042
static resultT sum(const resultT &left, const resultT &right, const opT &op)
Definition world_task_queue.h:342
detail::function_enabler< fnT(a1T, a2T, a3T, a4T, a5T, a6T, a7T, a8T, a9T)>::type add(fnT fn, const a1T &a1, const a2T &a2, const a3T &a3, const a4T &a4, const a5T &a5, const a6T &a6, const a7T &a7, const a8T &a8, const a9T &a9, const TaskAttributes &attr=TaskAttributes())
Create a local task with nine arguments.
Definition world_task_queue.h:907
detail::function_enabler< fnT >::type add(ProcessID dest, fnT fn, const a1T &a1, const TaskAttributes &attr=TaskAttributes())
Invoke resultT (*fn)(a1T) as a task, local or remote.
Definition world_task_queue.h:971
AtomicInt nregistered
Count of pending tasks.
Definition world_task_queue.h:324
detail::function_enabler< fnT(a1T, a2T, a3T, a4T, a5T, a6T, a7T, a8T)>::type add(fnT fn, const a1T &a1, const a2T &a2, const a3T &a3, const a4T &a4, const a5T &a5, const a6T &a6, const a7T &a7, const a8T &a8, const TaskAttributes &attr=TaskAttributes())
Create a local task with eight arguments.
Definition world_task_queue.h:867
detail::function_enabler< fnT >::type add(ProcessID dest, fnT fn, const a1T &a1, const a2T &a2, const a3T &a3, const a4T &a4, const a5T &a5, const a6T &a6, const a7T &a7, const TaskAttributes &attr=TaskAttributes())
Invoke resultT (*fn)(a1T,a2T,a3T,a4T,a5T,a6T,a7T) as a task, local or remote.
Definition world_task_queue.h:1215
void add(TaskInterface *t)
Add a new local task, taking ownership of the pointer.
Definition world_task_queue.h:466
Future< resultT > reduce(const rangeT &range, const opT &op)
Reduce op(item) for all items in range using op(sum,op(item)).
Definition world_task_queue.h:527
detail::function_enabler< fnT(a1T, a2T, a3T, a4T, a5T)>::type add(fnT fn, const a1T &a1, const a2T &a2, const a3T &a3, const a4T &a4, const a5T &a5, const TaskAttributes &attr=TaskAttributes())
Create a local task with five arguments.
Definition world_task_queue.h:761
detail::function_enabler< fnT >::type add(ProcessID dest, fnT fn, const a1T &a1, const a2T &a2, const a3T &a3, const a4T &a4, const a5T &a5, const a6T &a6, const a7T &a7, const a8T &a8, const TaskAttributes &attr=TaskAttributes())
Invoke resultT (*fn)(a1T,a2T,a3T,a4T,a5T,a6T,a7T,a8T) as a task, local or remote.
Definition world_task_queue.h:1265
const T & am_arg(const T &t)
Definition world_task_queue.h:389
void fence()
Returns after all local tasks have completed.
Definition world_task_queue.h:1384
taskT::futureT send_task(ProcessID where, fnT fn, const a1T &a1, const a2T &a2, const a3T &a3, const a4T &a4, const a5T &a5, const a6T &a6, const a7T &a7, const a8T &a8, const a9T &a9, const TaskAttributes &attr)
Definition world_task_queue.h:427
A parallel world class.
Definition world.h:132
WorldAmInterface & am
AM interface.
Definition world.h:203
Wraps an archive around a memory buffer for input.
Definition buffer_archive.h:134
Apply an operation to a range of iterators.
Definition world_task_queue.h:1406
virtual ~ForEachRootTask()=default
Virtual destructor.
virtual void run(World &, const TaskThreadEnv &)
Task run work.
Definition world_task_queue.h:1434
opT op_
The foreach function.
Definition world_task_queue.h:1409
rangeT range_
The range.
Definition world_task_queue.h:1408
Future< bool > completion_status_
The result of this set of tasks.
Definition world_task_queue.h:1410
const Future< bool > & result() const
Result accessor.
Definition world_task_queue.h:1429
virtual void get_id(std::pair< void *, unsigned short > &id) const
Get the task ID.
Definition world_task_queue.h:1458
ForEachRootTask(World &, const rangeT range, const opT &op)
Constructor.
Definition world_task_queue.h:1419
void run(World &world, ansatzT ansatz, const int nuclear_charge, const commandlineparser &parser, const int nstates)
Definition dirac-hatom.cc:1388
auto T(World &world, response_space &f) -> response_space
Definition global_functions.cc:34
tbb::split Split
Dummy class, a la Intel TBB, used to distinguish splitting constructor.
Definition range.h:54
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
Tensor< double > op(const Tensor< double > &x)
Definition kain.cc:508
Macros and tools pertaining to the configuration of MADNESS.
#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
Defines tools for encapsulating a pointer to a member function.
MemFuncWrapper< objT *, memfnT, typename result_of< memfnT >::type > wrap_mem_fn(objT &obj, memfnT memfn)
Create a member function wrapper (MemFuncWrapper) from an object and a member function pointer.
Definition mem_func_wrapper.h:251
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
AmArg * new_am_arg(const argT &... args)
Convenience template for serializing arguments into a new AmArg.
Definition worldam.h:194
NDIM & f
Definition mra.h:2416
std::string type(const PairType &n)
Definition PNOParameters.h:18
Definition mraimpl.h:50
Implements NO_DEFAULTS.
Implement the Range class for parallel iteration.
Wrap a callable object and its arguments into a task function.
Definition taskfn.h:473
detail::task_result_type< fnT >::futureT futureT
Definition taskfn.h:504
const futureT & result() const
Definition taskfn.h:854
Definition world_task_queue.h:66
Definition world_task_queue.h:67
Definition world_task_queue.h:1361
bool operator()() const
Determine if all tasks in the queue are complete.
Definition world_task_queue.h:1374
ProbeAllDone(WorldTaskQueue *tq)
Construct a ProbeAllDone for a given task queue.
Definition world_task_queue.h:1367
WorldTaskQueue * tq
The task queue.
Definition world_task_queue.h:1362
Future< T > type
Type with Future added.
Definition type_traits.h:90
Serialization container for sending tasks to remote nodes.
Definition world_task_queue.h:93
std::enable_if<!is_any_function_pointer_v< fnT > >::type serialize_internal(const Archive &ar)
Serialization for non- function pointers and member function pointers.
Definition world_task_queue.h:137
std::enable_if< is_any_function_pointer_v< fnT > >::type serialize_internal(const Archive &ar)
Serialization for function pointers and member function pointers.
Definition world_task_queue.h:126
functionT func
A task function.
Definition world_task_queue.h:95
TaskHandlerInfo(const refT &ref, functionT func, const TaskAttributes &attr)
Construct task info object.
Definition world_task_queue.h:105
void serialize(const Archive &ar)
Serialization of an object.
Definition world_task_queue.h:113
TaskAttributes attr
Task attributes.
Definition world_task_queue.h:96
refT ref
Remote reference for a task result future.
Definition world_task_queue.h:94
typename callable_traits< callableT >::result_type type
Definition world_task_queue.h:181
Definition world_task_queue.h:177
Function traits in the spirit of boost function traits.
Definition function_traits.h:17
Behave like a lazy std::enable_if.
Definition world_task_queue.h:151
returnT::type type
Definition world_task_queue.h:152
Definition world_task_queue.h:170
Definition world_task_queue.h:191
Definition world_task_queue.h:231
Definition world_task_queue.h:72
AtomicInt sum
Definition test_atomicint.cc:46
int task(int i)
Definition test_runtime.cpp:4
const char * status[2]
Definition testperiodic.cc:43
Wrappers around platform dependent timers and performance info.
const double a2
Definition vnucso.cc:86
const double a1
Definition vnucso.cc:85
int ProcessID
Used to clearly identify process number/rank.
Definition worldtypes.h:43