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 
44 #include <madness/madness_config.h>
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>
54 #include <madness/world/timers.h>
55 #include <madness/world/taskfn.h>
57 
58 /// \addtogroup taskq
59 /// @{
60 
61 namespace 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>
93  struct TaskHandlerInfo {
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.
106  : ref(ref), func(func),attr(attr) {}
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...
319  class WorldTaskQueue : public CallbackInterface, private NO_DEFAULTS {
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.
466  void add(TaskInterface* t) {
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>
496  res(t->result());
497  add(static_cast<TaskInterface*>(t));
498  return res;
499  }
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) {
573  detail::ForEachRootTask<rangeT, opT>* for_each_root =
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  {
733  typedef TaskFn<fnT, a1T, a2T, a3T, a4T> taskT;
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.
1361  struct ProbeAllDone {
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.
1368  : tq(tq)
1369  {}
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) :
1420  TaskInterface(0, TaskAttributes::hipri()), range_(range), op_(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
WorldTaskQueue(World &world)
Constructor requiring a communication context (World).
Definition: world_task_queue.cc:54
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::voidT voidT
Definition: world_task_queue.h:394
const ProcessID me
This process.
Definition: world_task_queue.h:323
const T & am_arg(const T &t)
Definition: world_task_queue.h:389
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
size_t size() const
Returns the number of pending tasks.
Definition: world_task_queue.h:451
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
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
void notify()
Definition: world_task_queue.h:327
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
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 >::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
detail::function_enabler< fnT >::type add(ProcessID dest, fnT fn, const TaskAttributes &attr=TaskAttributes())
Create a remote task.
Definition: world_task_queue.h:939
static void remote_task_handler(const AmArg &arg)
Definition: world_task_queue.h:353
World & world
The communication context.
Definition: world_task_queue.h:322
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
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, 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(fnT fn, const TaskAttributes &attr=TaskAttributes())
Create a local task with no arguments.
Definition: world_task_queue.h:636
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)>::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, 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(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
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 TaskAttributes &attr=TaskAttributes())
Invoke resultT (*fn)(a1T,a2T,a3T,a4T) as a task, local or remote.
Definition: world_task_queue.h:1082
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
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
AtomicInt nregistered
Count of pending tasks.
Definition: world_task_queue.h:324
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 TaskAttributes &attr=TaskAttributes())
Invoke resultT (*fn)(a1T) as a task, local or remote.
Definition: world_task_queue.h:971
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 add(TaskInterface *t)
Add a new local task, taking ownership of the pointer.
Definition: world_task_queue.h:466
const T & am_arg(const Future< T > &f)
Definition: world_task_queue.h:377
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
void fence()
Returns after all local tasks have completed.
Definition: world_task_queue.h:1384
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
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
Function< double, 3 > functionT
Definition: mcpfit.cc:50
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
File holds all helper structures necessary for the CC_Operator and CC2 class.
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
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
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
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
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
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
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