MADNESS 0.10.1
world_object.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_object.h
34 \brief Defines and implements \c WorldObject.
35 \ingroup world_object
36*/
37
38#ifndef MADNESS_WORLD_WORLD_OBJECT_H__INCLUDED
39#define MADNESS_WORLD_WORLD_OBJECT_H__INCLUDED
40
43
44#include <array>
45#include <atomic>
46#include <cstddef>
47#include <type_traits>
48
49/// \addtogroup world_object
50/// @{
51
52namespace madness {
53
54 template <typename> class WorldObject;
55
56 namespace detail {
57
58 /// Common base class for pending messages to ensure in-order processing.
59
60 /// To eliminate synchronization when a distributed object is first
61 /// constructed, we buffer pending messages for containers that
62 /// don't have their ID yet registered.
76
77 /// \todo Brief description needed.
78
79 /// We cannot use the normal task forwarding stuff here because pending
80 /// messages can creating tasks are must be correctly handled. The
81 /// following code does not easily merge with the send handlers since
82 /// the task layer is more restrictive on the copy capability of
83 /// arguments.
84 ///
85 /// It is also annoying that info needs to be broken into two parts so
86 /// that it \c id and \c ref are properly serialized. We need to have
87 /// \c id correctly aligned via \c opaque_wrap, but \c ref cannot be
88 /// serialized that way. Thus we break the class into two parts.
89 ///
90 /// Info stored for AM method forwarding.
91 /// \tparam memfunT Description needed.
92 /// \todo Verify & complete; what is AM?
93 template <typename memfunT>
94 struct info_base {
95 using memfunT_rel_ptr = decltype(archive::to_rel_memfn_ptr(std::declval<memfunT>()));
96 // id must be at front ... see peek.
97 uniqueidT id; ///< \todo Description needed. Context with the "see peek" comment above?
98 ProcessID requestor; ///< \todo Description needed.
99 memfunT_rel_ptr memfun_rel_ptr; ///< \todo Description needed.
100 TaskAttributes attr; ///< \todo Description needed.
101
102 /// \return the (absolute) member function pointer
103 memfunT memfun() const {
104 return archive::to_abs_memfn_ptr<memfunT>(memfun_rel_ptr);
105 }
106
107 protected:
108
110
111 /// \todo Constructor that [brief description needed].
112
113 /// \todo Descriptions needed.
114 /// \param[in] id Description needed.
115 /// \param[in] requestor Description needed.
116 /// \param memfun Verify: The member function to be invoked for the task.
117 /// \param[in] attr Description needed.
120 : id(id)
122 , memfun_rel_ptr(archive::to_rel_memfn_ptr(memfun))
123 , attr(attr) {}
124
125 /// Serializes a \c info_base for I/O.
126
127 /// \tparam Archive The type of I/O archive.
128 /// \param[in,out] ar The I/O archive.
129 template <typename Archive>
130 void serialize(const Archive& ar) {
131 ar & archive::wrap_opaque(*this); // Must be opaque ... see peek.
132 }
133 }; // struct info_base
134
135 /// \todo Brief description needed.
136
137 /// \todo Descriptions needed.
138 /// \tparam memfunT Verify: Signature of the member function in the derived class to be invoked for the task.
139 template <typename memfunT>
140 struct info : public info_base<memfunT> {
141 /// Future for a return value of the memory function. \todo Verify.
143 /// \todo Description needed.
145
146 refT ref; ///< \todo Description needed.
147
149
150 /// \todo Constructor that [brief description needed].
151
152 /// \todo Descriptions needed.
153 /// \param[in] arg Description needed.
154 info(const AmArg& arg) :
156 {
157 arg & *this;
158 }
159
160 /// \todo Constructor that [brief description needed].
161
162 /// \todo Descriptions needed.
163 /// \param[in] id Description needed.
164 /// \param[in] requestor Description needed.
165 /// \param memfun Verify: The member function to be invoked for the task.
166 /// \param[in] ref Description needed.
167 /// \param[in] attr Description needed.
172
173 /// Serializes a \c info for I/O.
174
175 /// \tparam Archive the type of I/O archive.
176 /// \param[in] ar The I/O archive.
177 template <typename Archive>
178 void serialize(const Archive& ar) {
180 ar & ref;
181 }
182 }; // struct info
183
184 /// Extract the unique object ID from an incoming active message header.
185
186 /// We deserialize the header and all arguments at the same
187 /// time to simplify the code. However, it is common that
188 /// when sending a message to an item in a container to
189 /// include a pointer to the container itself. But this
190 /// breaks if the container is not initialized since the
191 /// deserialization throws if the object is not initialized
192 /// (which seems preferable to a hidden race condition). Hence,
193 /// we use this routine to extract the unique ID from the very
194 /// front of the \c info structure. For efficiency we here rely
195 /// upon the serialization of \c info being opaque and the
196 /// ID being at the front of \c info.
197 ///
198 /// \todo Verify parameter description.
199 /// \param[in] arg The active message header.
200 static inline const uniqueidT& peek(const AmArg& arg) {
201 return *((uniqueidT*)(arg.buf()));
202 }
203
204
205 /// \todo Brief description needed.
206
207 /// \todo Descriptions needed.
208 /// \tparam objT Description needed.
209 /// \tparam memfnT Verify: Signature of the member function in the derived class to be invoked for the task.
210 /// \tparam Enabler Description needed.
211 template <typename objT, typename memfnT, typename Enabler = void>
213 /// \todo Description needed.
214 typedef typename std::conditional<memfunc_traits<memfnT>::constness,
215 const objT*, objT*>::type ptrT;
216
217 /// \todo Description needed.
219
220
221 /// \todo Brief description needed.
222
223 /// \todo Descriptions needed.
224 /// \param[in] obj Description needed.
225 /// \param memfn Verify: The member function to be invoked for the task.
226 /// \return Description needed.
227 static wrapperT make_task_fn(const objT* obj, memfnT memfn) {
228 return wrapperT(const_cast<ptrT>(obj), memfn);
229 }
230
231
232 /// \todo Brief description needed.
233
234 /// \todo Descriptions needed.
235 /// \param[in] obj Description needed.
236 /// \param memfn Verify: The member function to be invoked for the task.
237 /// \return Description needed.
239 return wrapperT(const_cast<ptrT>(obj), memfn);
240 }
241
242
243 /// \todo Brief description needed.
244
245 /// \todo Descriptions needed.
246 /// \param[in] obj Description needed.
247 /// \param memfn Verify: The member function to be invoked for the task.
248 /// \return Description needed.
250 return make_task_fn(static_cast<const objT*>(obj), memfn);
251 }
252
253 /// \todo Brief description needed.
254
255 /// \todo Descriptions needed.
256 /// \param[in] obj Description needed.
257 /// \param memfn Verify: The member function to be invoked for the task.
258 /// \return Description needed.
260 return make_task_fn(static_cast<objT*>(obj), memfn);
261 }
262 }; // struct WorldObjectTaskHelper
263
264
265#ifndef MADNESS_DISABLE_SHARED_FROM_THIS
266 // Disable the use of std::enable_shared_from_this if we are using MADNESS's
267 // implementation since weak_ptr is not fully implemented.
268
269
270 /// \todo Brief description needed.
271
272 /// \todo Descriptions needed.
273 /// \tparam objT Description needed.
274 /// \tparam memfnT Verify: Signature of the member function in the derived class to be invoked for the task.
275 template <typename objT, typename memfnT>
277 typename std::enable_if< std::is_base_of<std::enable_shared_from_this<objT>, objT>::value >::type>
278 {
279 /// \todo Description needed.
280 typedef typename std::conditional<memfunc_traits<memfnT>::constness,
281 const objT*, objT*>::type ptrT;
282
283 /// \todo Description needed.
284 typedef typename std::conditional<memfunc_traits<memfnT>::constness,
285 std::shared_ptr<const objT>, std::shared_ptr<objT> >::type shared_ptrT;
286
287 /// \todo Description needed.
289
290
291 /// \todo Brief description needed.
292
293 /// \todo Descriptions needed.
294 /// \param[in] obj Description needed.
295 /// \param memfn Verify: The member function to be invoked for the task.
296 /// \return Description needed.
297 static wrapperT make_task_fn(const objT* obj, memfnT memfn) {
298 return wrapperT(const_cast<ptrT>(obj)->shared_from_this(), memfn);
299 }
300
301
302 /// \todo Brief description needed.
303
304 /// \todo Descriptions needed.
305 /// \param[in] obj Description needed.
306 /// \param memfn Verify: The member function to be invoked for the task.
307 /// \return Description needed.
309 return wrapperT(const_cast<ptrT>(obj)->shared_from_this(), memfn);
310 }
311
312
313 /// \todo Brief description needed.
314
315 /// \todo Descriptions needed.
316 /// \param[in] obj Description needed.
317 /// \param memfn Verify: The member function to be invoked for the task.
318 /// \return Description needed.
320 return make_task_fn(static_cast<const objT*>(obj), memfn);
321 }
322
323
324 /// \todo Brief description needed.
325
326 /// \todo Descriptions needed.
327 /// \param[in] obj Description needed.
328 /// \param memfn Verify: The member function to be invoked for the task.
329 /// \return Description needed.
331 return make_task_fn(static_cast<objT*>(obj), memfn);
332 }
333 }; // struct WorldObjectTaskHelper
334
335#endif // MADNESS_DISABLE_SHARED_FROM_THIS
336
337 } // namespace detail
338
339 /// Base class for WorldObject, useful for introspection
341 virtual ~WorldObjectBase() = default;
342 public:
343 virtual World& get_world() const = 0;
344 };
345
346 /// Implements most parts of a globally addressable object (via unique ID).
347
348 /// This class is deliberately not default constructible and does
349 /// not support assignment or copying. This ensures that each instance
350 /// is unique. Have a look at \c madness::WorldContainer for an example
351 /// of wrapping this using the PIMPL idiom and a shared pointer.
352 ///
353 /// When deriving classes:
354 /// -# Derived class has `WorldObject<Derived>` as a public base class.
355 /// -# Derived constructor:
356 /// -# invokes `WorldObject<Derived>(world)` constructor.
357 /// -# invokes `process_pending()`.
358 /// -# Derived destructor must either be deferred or preceeded by `gop.fence()`.
359 /// -# Derived class must have at least one virtual function for serialization
360 /// of derived class pointers to be cast to the appropriate type.
361 ///
362 /// Note that \c world is exposed for convenience as a public data member.
363 /// \tparam Derived The derived class. \c WorldObject is a curiously
364 /// recurring template pattern.
365 template <class Derived>
367 public:
368 /// \todo Description needed.
370
371 // copy ctor must be enabled to permit RVO; in C++17 will not need this
372 WorldObject(const WorldObject& other) : world(other.world) { abort(); }
373 // no copy
375
376 private:
377 /// \todo Description needed.
378 typedef std::list<detail::PendingMsg> pendingT;
379
380 /// \todo Description needed.
382
383 World& world; ///< The \c World this object belongs to. (Think globally, act locally).
384
385 // The order here matters in a multi-threaded world
386 volatile bool ready; ///< True if ready to rock 'n roll.
387 ProcessID me; ///< Rank of self.
388 uniqueidT objid; ///< Sense of self.
389
390
391 inline static Spinlock pending_mutex; ///< \todo Description needed.
392 inline static volatile pendingT pending; ///< Buffer for pending messages.
393
394
395 /// \todo Complete: Determine if [unknown] is ready (for ...).
396
397 /// The slightly convoluted logic is to ensure ordering when
398 /// processing pending messages. If a new message arrives
399 /// while processing incoming messages it must be queued.
400 ///
401 /// - If the object does not exist ---> not ready.
402 /// - If the object exists and is ready ---> ready.
403 /// - If the object exists and is not ready then
404 /// - if we are doing a queued/pending message --> ready.
405 /// - else this is a new message --> not ready.
406 ///
407 /// \param[in] id Description needed.
408 /// \param[in,out] obj Description needed.
409 /// \param[in] arg Description needed.
410 /// \param[in,out] ptr Description needed.
411 /// \return Description needed.
412 /// \todo Parameter/return descriptions needed.
413 static bool is_ready(const uniqueidT& id, objT*& obj, const AmArg& arg, am_handlerT ptr) {
414 std::optional<Derived *> opt_obj =
415 arg.get_world()->template ptr_from_id<Derived>(id);
416 if (opt_obj) {
417 // if opt_obj == nullptr, then this ID has already been deregistered
418 MADNESS_ASSERT(*opt_obj != nullptr);
419 obj = static_cast<objT *>(*opt_obj);
420 } else
421 obj = nullptr;
422
423 if (obj) {
424 if (obj->ready || arg.is_pending())
425 return true;
426 }
427
429 MADNESS_PRAGMA_CLANG(diagnostic ignored "-Wundefined-var-template")
430
431 ScopedMutex<Spinlock> lock(pending_mutex); // BEGIN CRITICAL SECTION
432
433 if (!obj) {
434 std::optional<Derived *> opt_obj =
435 arg.get_world()->template ptr_from_id<Derived>(id);
436 if (opt_obj) {
437 // if opt_obj == nullptr, then this ID has already been deregistered
438 MADNESS_ASSERT(*opt_obj != nullptr);
439 obj = static_cast<objT *>(*opt_obj);
440 } else
441 obj = nullptr;
442 }
443
444 if (obj) {
445 if (obj->ready || arg.is_pending())
446 return true; // END CRITICAL SECTION
447 }
448 const_cast<AmArg &>(arg).set_pending();
449 const_cast<pendingT &>(pending).push_back(
450 detail::PendingMsg(id, ptr, arg));
451
453
454 return false; // END CRITICAL SECTION
455 }
456
457 /// Handler for an incoming AM.
458
459 /// \todo Descriptions needed.
460 /// \tparam memfnT Verify: Signature of the member function in the derived class to be invoked for the task.
461 /// \tparam arg1T Type of argument 1.
462 /// \tparam arg2T Type of argument 2.
463 /// \tparam arg3T Type of argument 3.
464 /// \tparam arg4T Type of argument 4.
465 /// \tparam arg5T Type of argument 5.
466 /// \tparam arg6T Type of argument 6.
467 /// \tparam arg7T Type of argument 7.
468 /// \tparam arg8T Type of argument 8.
469 /// \tparam arg9T Type of argument 9.
470 /// \param[in] arg Description needed.
471 template <typename memfnT, typename arg1T, typename arg2T, typename arg3T, typename arg4T,
472 typename arg5T, typename arg6T, typename arg7T, typename arg8T, typename arg9T>
499
500
501 /// Handler for remote arguments.
502
503 /// \todo Descriptions needed.
504 /// \tparam taskT Description needed.
505 /// \param[in] arg Description needed.
506 template <typename taskT>
507 static void spawn_remote_task_handler(const AmArg& arg) {
509 typename taskT::functionT::memfn_type> task_helper;
510
511 MADNESS_ASSERT(taskT::arity <= 9u);
512
513 const uniqueidT& id = detail::peek(arg);
514 am_handlerT ptr = & objT::template spawn_remote_task_handler<taskT>;
515 objT* obj;
516 if (is_ready(id,obj,arg,ptr)) {
518
520
521 // Construct task
522 taskT* task = new taskT(typename taskT::futureT(info.ref),
523 task_helper::make_task_fn(obj, info.memfun()), info.attr, input_arch);
524
525 // Add task to queue
526 arg.get_world()->taskq.add(task);
527 }
528 }
529
530
531 /// \todo Brief description needed.
532
533 /// \todo Descriptions needed.
534 /// \tparam T Description needed.
535 /// \param[in] f Description needed.
536 /// \return Description needed.
537 template <typename T>
538 static inline const T& am_arg(const Future<T>& f) {
539 MADNESS_ASSERT(f.probe()); // Cannot serialize unassigned futures
540 return f.get();
541 }
542
543
544 /// \todo Brief description needed.
545
546 /// \todo Descriptions needed.
547 /// \tparam T Description needed.
548 /// \param[in] t Description needed.
549 /// \return Description needed.
550 template <typename T>
551 static inline const T& am_arg(const T& t) {
552 return t;
553 }
554
555
556 /// \todo Brief description needed.
557
558 /// \todo Descriptions needed.
559 /// \tparam memfnT Verify: Signature of the member function in the derived class to be invoked for the task.
560 /// \tparam a1T Type of argument 1.
561 /// \tparam a2T Type of argument 2.
562 /// \tparam a3T Type of argument 3.
563 /// \tparam a4T Type of argument 4.
564 /// \tparam a5T Type of argument 5.
565 /// \tparam a6T Type of argument 6.
566 /// \tparam a7T Type of argument 7.
567 /// \tparam a8T Type of argument 8.
568 /// \tparam a9T Type of argument 9.
569 /// \param dest Description needed.
570 /// \param memfn Verify: The member function to be invoked for the task.
571 /// \param a1 Argument 1.
572 /// \param a2 Argument 2.
573 /// \param a3 Argument 3.
574 /// \param a4 Argument 4.
575 /// \param a5 Argument 5.
576 /// \param a6 Argument 6.
577 /// \param a7 Argument 7.
578 /// \param a8 Argument 8.
579 /// \param a9 Argument 9.
580 /// \return Description needed.
581 template <typename memfnT, typename a1T, typename a2T, typename a3T,
582 typename a4T, typename a5T, typename a6T, typename a7T,
583 typename a8T, typename a9T>
585 send_am(ProcessID dest, memfnT memfn, const a1T& a1, const a2T& a2,
586 const a3T& a3, const a4T& a4, const a5T& a5, const a6T& a6,
587 const a7T& a7, const a8T& a8, const a9T& a9) const
588 {
591 if (dest == me)
592 detail::run_function(result, task_helper::make_task_fn(this, memfn),
593 a1, a2, a3, a4, a5, a6, a7, a8, a9);
594 else {
597 new_am_arg(info, a1, a2, a3, a4, a5, a6, a7, a8, a9));
598 }
599
600 return result;
601 }
602
603
604 /// \todo Brief description needed.
605
606 /// \todo Descriptions needed.
607 /// \tparam taskT Description needed.
608 /// \tparam memfnT Verify: Signature of the member function in the derived class to be invoked for the task.
609 /// \tparam a1T Type of argument 1.
610 /// \tparam a2T Type of argument 2.
611 /// \tparam a3T Type of argument 3.
612 /// \tparam a4T Type of argument 4.
613 /// \tparam a5T Type of argument 5.
614 /// \tparam a6T Type of argument 6.
615 /// \tparam a7T Type of argument 7.
616 /// \tparam a8T Type of argument 8.
617 /// \tparam a9T Type of argument 9.
618 /// \param dest Description needed.
619 /// \param memfn Verify: The member function to be invoked for the task.
620 /// \param a1 Argument 1.
621 /// \param a2 Argument 2.
622 /// \param a3 Argument 3.
623 /// \param a4 Argument 4.
624 /// \param a5 Argument 5.
625 /// \param a6 Argument 6.
626 /// \param a7 Argument 7.
627 /// \param a8 Argument 8.
628 /// \param a9 Argument 9.
629 /// \param attr Description needed.
630 /// \return Description needed.
631 template <typename taskT, typename memfnT, typename a1T, typename a2T, typename a3T,
632 typename a4T, typename a5T, typename a6T, typename a7T,
633 typename a8T, typename a9T>
634 typename taskT::futureT
636 const a2T& a2, const a3T& a3, const a4T& a4, const a5T& a5,
637 const a6T& a6, const a7T& a7, const a8T& a8, const a9T& a9,
638 const TaskAttributes& attr) const
639 {
640 typename taskT::futureT result;
641 detail::info<memfnT> info(objid, me, memfn, result.remote_ref(world), attr);
642 world.am.send(dest, & objT::template spawn_remote_task_handler<taskT>,
643 new_am_arg(info, a1, a2, a3, a4, a5, a6, a7, a8, a9), RMI::ATTR_UNORDERED);
644
645 return result;
646 }
647
648 protected:
649
650 /// To be called from \em derived constructor to process pending messages.
651
652 /// Cannot call this from the \c WorldObject constructor since the
653 /// derived class would not yet be fully constructed.
654 ///
655 /// \attention No incoming messages are processed until this routine is
656 /// invoked; the derived class may rely upon a well defined state
657 /// until this routine is invoked.
659 // Messages may be arriving while we are processing the
660 // pending queue. To maximize concurrency copy messages
661 // out of queue before processing outside critical section.
662 //int ndone = 0;
663 while (!ready) {
665
667 MADNESS_PRAGMA_CLANG(diagnostic ignored "-Wundefined-var-template")
668
669 pending_mutex.lock(); // BEGIN CRITICAL SECTION
670 pendingT& nv = const_cast<pendingT&>(pending);
671 for (pendingT::iterator it=nv.begin(); it!=nv.end();) {
672 detail::PendingMsg& p = *it;
673 if (p.id == objid) {
674 tmp.push_back(p);
675 it = nv.erase(it);
676 }
677 else {
678 ++it;
679 }
680 }
681 if (tmp.size() == 0) ready=true;
682 pending_mutex.unlock(); // END CRITICAL SECTION
683
685
686 while (tmp.size()) {
687 tmp.front().invokehandler();
688 tmp.pop_front();
689 //++ndone;
690 }
691 }
692 //if (ndone) std::cout << world.rank() << ":pending:" << ndone << std::endl;
693 }
694
695
696 public:
697 /// \brief Constructor that associates an object (via the derived class)
698 /// with a globally unique ID.
699
700 /// \attention The derived class MUST call \c process_pending from
701 /// its constructor to both
702 /// -# process any messages that arrived prior to construction.
703 /// -# to enable processing of future messages.
704 /// \param[in,out] world The \c World encapsulating the \"global\" domain.
706 : world(world)
707 , ready(false)
708 , me(world.rank())
709 , objid(world.register_ptr(static_cast<Derived*>(this))) {};
710
711
712 /// Returns the globally unique object ID.
713 const uniqueidT& id() const {
714 return objid;
715 }
716
717
718 /// Returns a reference to the \c world.
719 World& get_world() const {
720 return const_cast<WorldObject<Derived>*>(this)->world;
721 }
722
723
724 /// \todo Brief description needed.
725
726 /// \todo Descriptions needed.
727 /// \tparam memfnT Verify: Signature of the member function in the derived class to be invoked for the task.
728 /// \param dest Description needed.
729 /// \param memfn Verify: The member function to be invoked for the task.
730 /// \return Description needed.
731 template <typename memfnT>
738
739
740 /// \todo Brief description needed.
741
742 /// \todo Descriptions needed.
743 /// \tparam memfnT Verify: Signature of the member function in the derived class to be invoked for the task.
744 /// \tparam a1T Type of argument 1.
745 /// \param dest Description needed.
746 /// \param memfn Verify: The member function to be invoked for the task.
747 /// \param a1 Argument 1.
748 /// \return Description needed.
749 template <typename memfnT, typename a1T>
756
757
758 /// \todo Brief description needed.
759
760 /// \todo Descriptions needed.
761 /// \tparam memfnT Verify: Signature of the member function in the derived class to be invoked for the task.
762 /// \tparam a1T Type of argument 1.
763 /// \tparam a2T Type of argument 2.
764 /// \param dest Description needed.
765 /// \param memfn Verify: The member function to be invoked for the task.
766 /// \param a1 Argument 1.
767 /// \param a2 Argument 2.
768 /// \return Description needed.
769 template <typename memfnT, typename a1T, typename a2T>
776
777
778 /// \todo Brief description needed.
779
780 /// \todo Descriptions needed.
781 /// \tparam memfnT Verify: Signature of the member function in the derived class to be invoked for the task.
782 /// \tparam a1T Type of argument 1.
783 /// \tparam a2T Type of argument 2.
784 /// \tparam a3T Type of argument 3.
785 /// \param dest Description needed.
786 /// \param memfn Verify: The member function to be invoked for the task.
787 /// \param a1 Argument 1.
788 /// \param a2 Argument 2.
789 /// \param a3 Argument 3.
790 /// \return Description needed.
791 template <typename memfnT, typename a1T, typename a2T, typename a3T>
793 send(ProcessID dest, memfnT memfn, const a1T& a1, const a2T& a2,
794 const a3T& a3) const
795 {
796 return send_am(dest, memfn, am_arg(a1), am_arg(a2), am_arg(a3),
799 }
800
801
802 /// \todo Brief description needed.
803
804 /// \todo Descriptions needed.
805 /// \tparam memfnT Verify: Signature of the member function in the derived class to be invoked for the task.
806 /// \tparam a1T Type of argument 1.
807 /// \tparam a2T Type of argument 2.
808 /// \tparam a3T Type of argument 3.
809 /// \tparam a4T Type of argument 4.
810 /// \param dest Description needed.
811 /// \param memfn Verify: The member function to be invoked for the task.
812 /// \param a1 Argument 1.
813 /// \param a2 Argument 2.
814 /// \param a3 Argument 3.
815 /// \param a4 Argument 4.
816 /// \return Description needed.
817 template <typename memfnT, typename a1T, typename a2T, typename a3T,
818 typename a4T>
820 send(ProcessID dest, memfnT memfn, const a1T& a1, const a2T& a2,
821 const a3T& a3, const a4T& a4) const
822 {
823 return send_am(dest, memfn, am_arg(a1), am_arg(a2), am_arg(a3),
826 }
827
828
829 /// \todo Brief description needed.
830
831 /// \todo Descriptions needed.
832 /// \tparam memfnT Verify: Signature of the member function in the derived class to be invoked for the task.
833 /// \tparam a1T Type of argument 1.
834 /// \tparam a2T Type of argument 2.
835 /// \tparam a3T Type of argument 3.
836 /// \tparam a4T Type of argument 4.
837 /// \tparam a5T Type of argument 5.
838 /// \param dest Description needed.
839 /// \param memfn Verify: The member function to be invoked for the task.
840 /// \param a1 Argument 1.
841 /// \param a2 Argument 2.
842 /// \param a3 Argument 3.
843 /// \param a4 Argument 4.
844 /// \param a5 Argument 5.
845 /// \return Description needed.
846 template <typename memfnT, typename a1T, typename a2T, typename a3T,
847 typename a4T, typename a5T>
849 send(ProcessID dest, memfnT memfn, const a1T& a1, const a2T& a2,
850 const a3T& a3, const a4T& a4, const a5T& a5) const
851 {
852 return send_am(dest, memfn, am_arg(a1), am_arg(a2), am_arg(a3),
855 }
856
857
858 /// \todo Brief description needed.
859
860 /// \todo Descriptions needed.
861 /// \tparam memfnT Verify: Signature of the member function in the derived class to be invoked for the task.
862 /// \tparam a1T Type of argument 1.
863 /// \tparam a2T Type of argument 2.
864 /// \tparam a3T Type of argument 3.
865 /// \tparam a4T Type of argument 4.
866 /// \tparam a5T Type of argument 5.
867 /// \tparam a6T Type of argument 6.
868 /// \param dest Description needed.
869 /// \param memfn Verify: The member function to be invoked for the task.
870 /// \param a1 Argument 1.
871 /// \param a2 Argument 2.
872 /// \param a3 Argument 3.
873 /// \param a4 Argument 4.
874 /// \param a5 Argument 5.
875 /// \param a6 Argument 6.
876 /// \return Description needed.
877 template <typename memfnT, typename a1T, typename a2T, typename a3T,
878 typename a4T, typename a5T, typename a6T>
880 send(ProcessID dest, memfnT memfn, const a1T& a1, const a2T& a2,
881 const a3T& a3, const a4T& a4, const a5T& a5, const a6T& a6) const
882 {
883 return send_am(dest, memfn, am_arg(a1), am_arg(a2), am_arg(a3),
886 }
887
888
889 /// \todo Brief description needed.
890
891 /// \todo Descriptions needed.
892 /// \tparam memfnT Verify: Signature of the member function in the derived class to be invoked for the task.
893 /// \tparam a1T Type of argument 1.
894 /// \tparam a2T Type of argument 2.
895 /// \tparam a3T Type of argument 3.
896 /// \tparam a4T Type of argument 4.
897 /// \tparam a5T Type of argument 5.
898 /// \tparam a6T Type of argument 6.
899 /// \tparam a7T Type of argument 7.
900 /// \param dest Description needed.
901 /// \param memfn Verify: The member function to be invoked for the task.
902 /// \param a1 Argument 1.
903 /// \param a2 Argument 2.
904 /// \param a3 Argument 3.
905 /// \param a4 Argument 4.
906 /// \param a5 Argument 5.
907 /// \param a6 Argument 6.
908 /// \param a7 Argument 7.
909 /// \return Description needed.
910 template <typename memfnT, typename a1T, typename a2T, typename a3T,
911 typename a4T, typename a5T, typename a6T, typename a7T>
913 send(ProcessID dest, memfnT memfn, const a1T& a1, const a2T& a2,
914 const a3T& a3, const a4T& a4, const a5T& a5, const a6T& a6,
915 const a7T& a7) const
916 {
917 return send_am(dest, memfn, am_arg(a1), am_arg(a2), am_arg(a3),
920 }
921
922
923 /// \todo Brief description needed.
924
925 /// \todo Descriptions needed.
926 /// \tparam memfnT Verify: Signature of the member function in the derived class to be invoked for the task.
927 /// \tparam a1T Type of argument 1.
928 /// \tparam a2T Type of argument 2.
929 /// \tparam a3T Type of argument 3.
930 /// \tparam a4T Type of argument 4.
931 /// \tparam a5T Type of argument 5.
932 /// \tparam a6T Type of argument 6.
933 /// \tparam a7T Type of argument 7.
934 /// \tparam a8T Type of argument 8.
935 /// \param dest Description needed.
936 /// \param memfn Verify: The member function to be invoked for the task.
937 /// \param a1 Argument 1.
938 /// \param a2 Argument 2.
939 /// \param a3 Argument 3.
940 /// \param a4 Argument 4.
941 /// \param a5 Argument 5.
942 /// \param a6 Argument 6.
943 /// \param a7 Argument 7.
944 /// \param a8 Argument 8.
945 /// \return Description needed.
946 template <typename memfnT, typename a1T, typename a2T, typename a3T,
947 typename a4T, typename a5T, typename a6T, typename a7T, typename a8T>
949 send(ProcessID dest, memfnT memfn, const a1T& a1, const a2T& a2,
950 const a3T& a3, const a4T& a4, const a5T& a5, const a6T& a6,
951 const a7T& a7, const a8T& a8) const
952 {
953 return send_am(dest, memfn, am_arg(a1), am_arg(a2), am_arg(a3),
954 am_arg(a4), am_arg(a5), am_arg(a6), am_arg(a7), am_arg(a8),
956 }
957
958
959 /// \todo Brief description needed.
960
961 /// \todo Descriptions needed.
962 /// \tparam memfnT Verify: Signature of the member function in the derived class to be invoked for the task.
963 /// \tparam a1T Type of argument 1.
964 /// \tparam a2T Type of argument 2.
965 /// \tparam a3T Type of argument 3.
966 /// \tparam a4T Type of argument 4.
967 /// \tparam a5T Type of argument 5.
968 /// \tparam a6T Type of argument 6.
969 /// \tparam a7T Type of argument 7.
970 /// \tparam a8T Type of argument 8.
971 /// \tparam a9T Type of argument 9.
972 /// \param dest Description needed.
973 /// \param memfn Verify: The member function to be invoked for the task.
974 /// \param a1 Argument 1.
975 /// \param a2 Argument 2.
976 /// \param a3 Argument 3.
977 /// \param a4 Argument 4.
978 /// \param a5 Argument 5.
979 /// \param a6 Argument 6.
980 /// \param a7 Argument 7.
981 /// \param a8 Argument 8.
982 /// \param a9 Argument 9.
983 /// \return Description needed.
984 template <typename memfnT, typename a1T, typename a2T, typename a3T,
985 typename a4T, typename a5T, typename a6T, typename a7T, typename a8T,
986 typename a9T>
988 send(ProcessID dest, memfnT memfn, const a1T& a1, const a2T& a2,
989 const a3T& a3, const a4T& a4, const a5T& a5, const a6T& a6,
990 const a7T& a7, const a8T& a8, const a9T& a9) const
991 {
992 return send_am(dest, memfn, am_arg(a1), am_arg(a2), am_arg(a3),
993 am_arg(a4), am_arg(a5), am_arg(a6), am_arg(a7), am_arg(a8),
994 am_arg(a9));
995 }
996
997 /// Sends task to derived class method `returnT (this->*memfn)()`.
998
999 /// \todo Descriptions needed.
1000 /// \tparam memfnT Verify: Signature of the member function in the derived class to be invoked for the task.
1001 /// \param dest Description needed.
1002 /// \param memfn Verify: The member function to be invoked for the task.
1003 /// \param attr Description needed.
1004 /// \return Description needed.
1005 template <typename memfnT>
1007 task(ProcessID dest, memfnT memfn, const TaskAttributes& attr = TaskAttributes()) const {
1010 if (dest == me)
1011 return world.taskq.add(task_helper::make_task_fn(this, memfn), attr);
1012 else
1016 }
1017
1018 /// Sends task to derived class method `returnT (this->*memfn)(a1)`.
1019
1020 /// \todo Descriptions needed.
1021 /// \tparam memfnT Verify: Signature of the member function in the derived class to be invoked for the task.
1022 /// \tparam a1T Type of argument 1.
1023 /// \param dest Description needed.
1024 /// \param memfn Verify: The member function to be invoked for the task.
1025 /// \param a1 Argument 1.
1026 /// \param attr Description needed.
1027 /// \return Description needed.
1028 template <typename memfnT, typename a1T>
1031 const TaskAttributes& attr = TaskAttributes()) const
1032 {
1034 typedef TaskFn<typename task_helper::wrapperT,
1036 if (dest == me)
1037 return world.taskq.add(task_helper::make_task_fn(this, memfn),
1038 a1, attr);
1039 else
1043 }
1044
1045 /// Sends task to derived class method `returnT (this->*memfn)(a1,a2)`.
1046
1047 /// \todo Descriptions needed.
1048 /// \tparam memfnT Verify: Signature of the member function in the derived class to be invoked for the task.
1049 /// \tparam a1T Type of argument 1.
1050 /// \tparam a2T Type of argument 2.
1051 /// \param dest Description needed.
1052 /// \param memfn Verify: The member function to be invoked for the task.
1053 /// \param a1 Argument 1.
1054 /// \param a2 Argument 2.
1055 /// \param attr Description needed.
1056 /// \return Description needed.
1057 template <typename memfnT, typename a1T, typename a2T>
1059 task(ProcessID dest, memfnT memfn, const a1T& a1, const a2T& a2,
1060 const TaskAttributes& attr = TaskAttributes()) const
1061 {
1063 typedef TaskFn<typename task_helper::wrapperT,
1066 if (dest == me)
1067 return world.taskq.add(task_helper::make_task_fn(this, memfn),
1068 a1, a2, attr);
1069 else
1070 return send_task<taskT>(dest, memfn, am_arg(a1), am_arg(a2),
1073 }
1074
1075 /// Sends task to derived class method `returnT (this->*memfn)(a1,a2,a3)`.
1076
1077 /// \todo Descriptions needed.
1078 /// \tparam memfnT Verify: Signature of the member function in the derived class to be invoked for the task.
1079 /// \tparam a1T Type of argument 1.
1080 /// \tparam a2T Type of argument 2.
1081 /// \tparam a3T Type of argument 3.
1082 /// \param dest Description needed.
1083 /// \param memfn Verify: The member function to be invoked for the task.
1084 /// \param a1 Argument 1.
1085 /// \param a2 Argument 2.
1086 /// \param a3 Argument 3.
1087 /// \param attr Description needed.
1088 /// \return Description needed.
1089 template <typename memfnT, typename a1T, typename a2T, typename a3T>
1091 task(ProcessID dest, memfnT memfn, const a1T& a1, const a2T& a2,
1092 const a3T& a3, const TaskAttributes& attr = TaskAttributes()) const
1093 {
1095 typedef TaskFn<typename task_helper::wrapperT,
1099 if (dest == me)
1100 return world.taskq.add(task_helper::make_task_fn(this, memfn),
1101 a1, a2, a3, attr);
1102 else
1103 return send_task<taskT>(dest, memfn, am_arg(a1), am_arg(a2),
1106 }
1107
1108 /// Sends task to derived class method `returnT (this->*memfn)(a1,a2,a3,a4)`.
1109
1110 /// \todo Descriptions needed.
1111 /// \tparam memfnT Verify: Signature of the member function in the derived class to be invoked for the task.
1112 /// \tparam a1T Type of argument 1.
1113 /// \tparam a2T Type of argument 2.
1114 /// \tparam a3T Type of argument 3.
1115 /// \tparam a4T Type of argument 4.
1116 /// \param dest Description needed.
1117 /// \param memfn Verify: The member function to be invoked for the task.
1118 /// \param a1 Argument 1.
1119 /// \param a2 Argument 2.
1120 /// \param a3 Argument 3.
1121 /// \param a4 Argument 4.
1122 /// \param attr Description needed.
1123 /// \return Description needed.
1124 template <typename memfnT, typename a1T, typename a2T, typename a3T,
1125 typename a4T>
1127 task(ProcessID dest, memfnT memfn, const a1T& a1, const a2T& a2,
1128 const a3T& a3, const a4T& a4, const TaskAttributes& attr = TaskAttributes()) const
1129 {
1131 typedef TaskFn<typename task_helper::wrapperT,
1136 if (dest == me)
1137 return world.taskq.add(task_helper::make_task_fn(this, memfn),
1138 a1, a2, a3, a4, attr);
1139 else
1140 return send_task<taskT>(dest, memfn, am_arg(a1), am_arg(a2),
1143 }
1144
1145 /// Sends task to derived class method `returnT (this->*memfn)(a1,a2,a3,a4,a5)`.
1146
1147 /// \todo Descriptions needed.
1148 /// \tparam memfnT Verify: Signature of the member function in the derived class to be invoked for the task.
1149 /// \tparam a1T Type of argument 1.
1150 /// \tparam a2T Type of argument 2.
1151 /// \tparam a3T Type of argument 3.
1152 /// \tparam a4T Type of argument 4.
1153 /// \tparam a5T Type of argument 5.
1154 /// \param dest Description needed.
1155 /// \param memfn Verify: The member function to be invoked for the task.
1156 /// \param a1 Argument 1.
1157 /// \param a2 Argument 2.
1158 /// \param a3 Argument 3.
1159 /// \param a4 Argument 4.
1160 /// \param a5 Argument 5.
1161 /// \param attr Description needed.
1162 /// \return Description needed.
1163 template <typename memfnT, typename a1T, typename a2T, typename a3T,
1164 typename a4T, typename a5T>
1166 task(ProcessID dest, memfnT memfn, const a1T& a1, const a2T& a2,
1167 const a3T& a3, const a4T& a4, const a5T& a5,
1168 const TaskAttributes& attr = TaskAttributes()) const
1169 {
1171 typedef TaskFn<typename task_helper::wrapperT,
1177 if (dest == me)
1178 return world.taskq.add(task_helper::make_task_fn(this, memfn),
1179 a1, a2, a3, a4, a5, attr);
1180 else
1181 return send_task<taskT>(dest, memfn, am_arg(a1), am_arg(a2),
1182 am_arg(a3), am_arg(a4), am_arg(a5), voidT::value,
1184 }
1185
1186 /// Sends task to derived class method `returnT (this->*memfn)(a1,a2,a3,a4,a5,a6)`.
1187
1188 /// \todo Descriptions needed.
1189 /// \tparam memfnT Verify: Signature of the member function in the derived class to be invoked for the task.
1190 /// \tparam a1T Type of argument 1.
1191 /// \tparam a2T Type of argument 2.
1192 /// \tparam a3T Type of argument 3.
1193 /// \tparam a4T Type of argument 4.
1194 /// \tparam a5T Type of argument 5.
1195 /// \tparam a6T Type of argument 6.
1196 /// \param dest Description needed.
1197 /// \param memfn Verify: The member function to be invoked for the task.
1198 /// \param a1 Argument 1.
1199 /// \param a2 Argument 2.
1200 /// \param a3 Argument 3.
1201 /// \param a4 Argument 4.
1202 /// \param a5 Argument 5.
1203 /// \param a6 Argument 6.
1204 /// \param attr Description needed.
1205 /// \return Description needed.
1206 template <typename memfnT, typename a1T, typename a2T, typename a3T,
1207 typename a4T, typename a5T, typename a6T>
1209 task(ProcessID dest, memfnT memfn, const a1T& a1, const a2T& a2,
1210 const a3T& a3, const a4T& a4, const a5T& a5, const a6T& a6,
1211 const TaskAttributes& attr = TaskAttributes()) const
1212 {
1214 typedef TaskFn<typename task_helper::wrapperT,
1221 if (dest == me)
1222 return world.taskq.add(task_helper::make_task_fn(this, memfn),
1223 a1, a2, a3, a4, a5, a6, attr);
1224 else {
1225 return send_task<taskT>(dest, memfn, am_arg(a1), am_arg(a2),
1226 am_arg(a3), am_arg(a4), am_arg(a5), am_arg(a6),
1228 }
1229 }
1230
1231 /// Sends task to derived class method `returnT (this->*memfn)(a1,a2,a3,a4,a5,a6,a7)`.
1232
1233 /// \todo Descriptions needed.
1234 /// \tparam memfnT Verify: Signature of the member function in the derived class to be invoked for the task.
1235 /// \tparam a1T Type of argument 1.
1236 /// \tparam a2T Type of argument 2.
1237 /// \tparam a3T Type of argument 3.
1238 /// \tparam a4T Type of argument 4.
1239 /// \tparam a5T Type of argument 5.
1240 /// \tparam a6T Type of argument 6.
1241 /// \tparam a7T Type of argument 7.
1242 /// \param dest Description needed.
1243 /// \param memfn Verify: The member function to be invoked for the task.
1244 /// \param a1 Argument 1.
1245 /// \param a2 Argument 2.
1246 /// \param a3 Argument 3.
1247 /// \param a4 Argument 4.
1248 /// \param a5 Argument 5.
1249 /// \param a6 Argument 6.
1250 /// \param a7 Argument 7.
1251 /// \param attr Description needed.
1252 /// \return Description needed.
1253 template <typename memfnT, typename a1T, typename a2T, typename a3T,
1254 typename a4T, typename a5T, typename a6T, typename a7T>
1256 task(ProcessID dest, memfnT memfn, const a1T& a1, const a2T& a2,
1257 const a3T& a3, const a4T& a4, const a5T& a5, const a6T& a6,
1258 const a7T& a7, const TaskAttributes& attr = TaskAttributes()) const
1259 {
1261 typedef TaskFn<typename task_helper::wrapperT,
1269 if (dest == me)
1270 return world.taskq.add(task_helper::make_task_fn(this, memfn),
1271 a1, a2, a3, a4, a5, a6, a7, attr);
1272 else
1273 return send_task<taskT>(dest, memfn, am_arg(a1), am_arg(a2),
1274 am_arg(a3), am_arg(a4), am_arg(a5), am_arg(a6),
1276 }
1277
1278 /// Sends task to derived class method `returnT (this->*memfn)(a1,a2,a3,a4,a5,a6,a7,a8)`.
1279
1280 /// \todo Descriptions needed.
1281 /// \tparam memfnT Verify: Signature of the member function in the derived class to be invoked for the task.
1282 /// \tparam a1T Type of argument 1.
1283 /// \tparam a2T Type of argument 2.
1284 /// \tparam a3T Type of argument 3.
1285 /// \tparam a4T Type of argument 4.
1286 /// \tparam a5T Type of argument 5.
1287 /// \tparam a6T Type of argument 6.
1288 /// \tparam a7T Type of argument 7.
1289 /// \tparam a8T Type of argument 8.
1290 /// \param dest Description needed.
1291 /// \param memfn Verify: The member function to be invoked for the task.
1292 /// \param a1 Argument 1.
1293 /// \param a2 Argument 2.
1294 /// \param a3 Argument 3.
1295 /// \param a4 Argument 4.
1296 /// \param a5 Argument 5.
1297 /// \param a6 Argument 6.
1298 /// \param a7 Argument 7.
1299 /// \param a8 Argument 8.
1300 /// \param attr Description needed.
1301 /// \return Description needed.
1302 template <typename memfnT, typename a1T, typename a2T, typename a3T,
1303 typename a4T, typename a5T, typename a6T, typename a7T, typename a8T>
1305 task(ProcessID dest, memfnT memfn, const a1T& a1, const a2T& a2,
1306 const a3T& a3, const a4T& a4, const a5T& a5, const a6T& a6,
1307 const a7T& a7, const a8T& a8,
1308 const TaskAttributes& attr = TaskAttributes()) const
1309 {
1311 typedef TaskFn<typename task_helper::wrapperT,
1320 if (dest == me)
1321 return world.taskq.add(task_helper::make_task_fn(this, memfn),
1322 a1, a2, a3, a4, a5, a6, a7, a8, attr);
1323 else {
1324 return send_task<taskT>(dest, memfn, am_arg(a1), am_arg(a2),
1325 am_arg(a3), am_arg(a4), am_arg(a5), am_arg(a6),
1326 am_arg(a7), am_arg(a8), voidT::value, attr);
1327 }
1328 }
1329
1330 /// Sends task to derived class method `returnT (this->*memfn)(a1,a2,a3,a4,a5,a6,a7,a8,a9)`.
1331
1332 /// \todo Descriptions needed.
1333 /// \tparam memfnT Verify: Signature of the member function in the derived class to be invoked for the task.
1334 /// \tparam a1T Type of argument 1.
1335 /// \tparam a2T Type of argument 2.
1336 /// \tparam a3T Type of argument 3.
1337 /// \tparam a4T Type of argument 4.
1338 /// \tparam a5T Type of argument 5.
1339 /// \tparam a6T Type of argument 6.
1340 /// \tparam a7T Type of argument 7.
1341 /// \tparam a8T Type of argument 8.
1342 /// \tparam a9T Type of argument 9.
1343 /// \param dest Description needed.
1344 /// \param memfn Verify: The member function to be invoked for the task.
1345 /// \param a1 Argument 1.
1346 /// \param a2 Argument 2.
1347 /// \param a3 Argument 3.
1348 /// \param a4 Argument 4.
1349 /// \param a5 Argument 5.
1350 /// \param a6 Argument 6.
1351 /// \param a7 Argument 7.
1352 /// \param a8 Argument 8.
1353 /// \param a9 Argument 9.
1354 /// \param attr Description needed.
1355 /// \return Description needed.
1356 ///
1357 /// \todo Could we use variadic templates to eliminate a lot of this code duplication?
1358 template <typename memfnT, typename a1T, typename a2T, typename a3T,
1359 typename a4T, typename a5T, typename a6T, typename a7T, typename a8T,
1360 typename a9T>
1362 task(ProcessID dest, memfnT memfn, const a1T& a1, const a2T& a2,
1363 const a3T& a3, const a4T& a4, const a5T& a5, const a6T& a6,
1364 const a7T& a7, const a8T& a8, const a9T& a9,
1365 const TaskAttributes& attr = TaskAttributes()) const
1366 {
1368 typedef TaskFn<typename task_helper::wrapperT,
1378 if (dest == me)
1379 return world.taskq.add(task_helper::make_task_fn(this, memfn),
1380 a1, a2, a3, a4, a5, a6, a7, a8, a9, attr);
1381 else
1382 return send_task<taskT>(dest, memfn, am_arg(a1), am_arg(a2),
1383 am_arg(a3), am_arg(a4), am_arg(a5), am_arg(a6),
1384 am_arg(a7), am_arg(a8), am_arg(a9), attr);
1385 }
1386
1395
1396#ifdef MADNESS_WORLDOBJECT_FUTURE_TRACE
1397 /// "traces" future evaluation by counting their assignments in a static table
1398
1399 /// Counts future assignments in a a statically-sized table to make this as lightweight/lock-free as possible
1400 /// with minimal effort. Can only trace objects of a single World.
1401 /// \param[in,out] f the future to be traced; if ready, will be unchanged (but contribute to the trace
1402 /// statistics of this object), or have a callback registered that will update the tracing statistics on
1403 /// assignment
1404 /// \warning this function will trace futures for WorldObjects associated with default world (id=0) only;
1405 /// use CMake variable `MADNESS_WORLDOBJECT_FUTURE_TRACE_WORLD_ID` to adjust the target World ID.
1406 /// \warning this function will trace futures for WorldObjects with IDs < 1000000 only;
1407 /// use CMake variable `MADNESS_WORLDOBJECT_FUTURE_TRACE_MAX_NOBJECTS` to adjust the limit.
1408 template <typename T>
1409 std::enable_if_t<!std::is_same_v<T,void>,void> trace(Future<T>& f) const;
1410
1411 /// \param[in] id a WorldObject ID
1412 /// \return true if futures associated with \p id are traced
1413 static bool trace_futures(const uniqueidT &id);
1414
1415 /// \return true if futures associated with this object are traced
1416 bool trace_futures() const {
1417 return trace_futures(this->id());
1418 }
1419
1420 /// \param[in] id report tracing stats for this WorldObject
1421 /// \return number of futures given to trace() of the WorldObject with ID \p id
1422 static std::size_t trace_status_nfuture_registered(const uniqueidT& id);
1423
1424 /// \return number of futures given to trace() of this object
1425 std::size_t trace_status_nfuture_registered() const {
1426 return trace_status_nfuture_registered(this->id());
1427 }
1428
1429 /// \param[in] id report tracing stats for this WorldObject
1430 /// \return number of assigned futures given to trace() of the WorldObject with ID \p id
1431 static std::size_t trace_status_nfuture_assigned(const uniqueidT& id);
1432
1433 /// \return number of assigned futures registered via `this->trace()`
1434 std::size_t trace_status_nfuture_assigned() const {
1435 return trace_status_nfuture_assigned(this->id());
1436 }
1437#endif
1438 };
1439
1440#ifdef MADNESS_WORLDOBJECT_FUTURE_TRACE
1441 namespace detail {
1442 template <typename Derived> struct WorldObjectFutureTracer {
1443 // this value is the world ID to trace
1444 constexpr static std::size_t world_id =
1445#ifndef MADNESS_WORLDOBJECT_FUTURE_TRACE_WORLD_ID
1446 0
1447#else
1448 MADNESS_WORLDOBJECT_FUTURE_TRACE_WORLD_ID
1449#endif
1450 ;
1451 // this value is 1 greater than is the highest ID of WorldObjects to trace
1452 constexpr static std::size_t max_object_id =
1453#ifndef MADNESS_WORLDOBJECT_FUTURE_TRACE_MAX_NOBJECTS
1454 1000000
1455#else
1456 MADNESS_WORLDOBJECT_FUTURE_TRACE_MAX_NOBJECTS
1457#endif
1458 ;
1459
1460 static constexpr bool do_trace(const uniqueidT& id) {
1461 return id.get_world_id() == world_id &&
1462 id.get_obj_id() < max_object_id;
1463 }
1464
1465 static std::array<std::atomic<std::size_t>, max_object_id>
1466 nfuture_registered;
1467 static std::array<std::atomic<std::size_t>, max_object_id>
1468 nfuture_assigned;
1469
1470 struct Initializer {
1471 Initializer() {
1472 for (auto &&v : nfuture_registered) {
1473 v.store(0);
1474 }
1475 for (auto &&v : nfuture_assigned) {
1476 v.store(0);
1477 }
1478 }
1479 };
1480 static Initializer initializer;
1481
1482 struct FutureTracer : public CallbackInterface {
1483 FutureTracer(const uniqueidT &id) : id_(id) {
1484 if (do_trace(id_)) {
1485 nfuture_registered[id_.get_obj_id()]++;
1486 }
1487 }
1488
1489 // Not allowed
1490 FutureTracer(const FutureTracer &) = delete;
1491 FutureTracer &operator=(const FutureTracer &) = delete;
1492
1493 virtual ~FutureTracer() {}
1494
1495 /// Notify this object that the future has been set.
1496
1497 /// This will set the value of the future on the remote node and delete
1498 /// this callback object.
1499 void notify() override {
1500 if (do_trace(id_)) {
1501 nfuture_assigned[id_.get_obj_id()]++;
1502 }
1503 delete this;
1504 }
1505
1506 private:
1507 uniqueidT id_;
1508 }; // struct FutureTracer
1509
1510 }; // struct WorldObjectFutureTracer
1511 template <typename Derived>
1512 typename WorldObjectFutureTracer<Derived>::Initializer
1513 WorldObjectFutureTracer<Derived>::initializer;
1514 template <typename Derived>
1515 std::array<std::atomic<std::size_t>, WorldObjectFutureTracer<Derived>::max_object_id>
1516 WorldObjectFutureTracer<Derived>::nfuture_registered;
1517 template <typename Derived>
1518 std::array<std::atomic<std::size_t>, WorldObjectFutureTracer<Derived>::max_object_id>
1519 WorldObjectFutureTracer<Derived>::nfuture_assigned;
1520 } // namespace detail
1521
1522 template <typename Derived>
1523 template <typename T>
1524 std::enable_if_t<!std::is_same_v<T,void>,void> WorldObject<Derived>::trace(Future<T>& f) const {
1525 f.register_callback(
1526 new typename detail::WorldObjectFutureTracer<Derived>::FutureTracer(
1527 this->id()));
1528 }
1529
1530 template <typename Derived>
1531 bool WorldObject<Derived>::trace_futures(const uniqueidT& id) {
1532 return detail::WorldObjectFutureTracer<Derived>::do_trace(id);
1533 }
1534
1535 template <typename Derived>
1536 std::size_t WorldObject<Derived>::trace_status_nfuture_registered(const uniqueidT& id) {
1537 if (detail::WorldObjectFutureTracer<
1538 Derived>::do_trace(id)) {
1539 return detail::WorldObjectFutureTracer<
1540 Derived>::nfuture_registered[id.get_obj_id()];
1541 }
1542 else return 0;
1543 }
1544
1545 template <typename Derived>
1546 std::size_t WorldObject<Derived>::trace_status_nfuture_assigned(const uniqueidT& id) {
1547 if (detail::WorldObjectFutureTracer<
1548 Derived>::do_trace(id)) {
1549 return detail::WorldObjectFutureTracer<
1550 Derived>::nfuture_assigned[id.get_obj_id()];
1551 }
1552 else return 0;
1553 }
1554
1555#endif // MADNESS_WORLDOBJECT_FUTURE_TRACE
1556
1557 namespace archive {
1558
1559 /// Specialization of \c ArchiveLoadImpl for globally-addressable objects.
1560
1561 /// \tparam Derived The derived class of \c WorldObject in a curiously
1562 /// repeating template pattern.
1563 template <class Derived>
1565
1566 /// Read a globally-addressable object from a \c BufferInputArchive.
1567
1568 /// \param[in,out] ar The archive.
1569 /// \param[out] ptr The read object.
1570 static inline void load(const BufferInputArchive& ar, WorldObject<Derived>*& ptr) {
1571 uniqueidT id;
1572 ar & id;
1573 World* world = World::world_from_id(id.get_world_id());
1574 MADNESS_ASSERT(world);
1575 auto ptr_opt = world->ptr_from_id< WorldObject<Derived> >(id);
1576 if (!ptr_opt) MADNESS_EXCEPTION("WorldObj: remote operation attempting to use a locally uninitialized object",0);
1577 ptr = *ptr_opt;
1578 if (!ptr) MADNESS_EXCEPTION("WorldObj: remote operation attempting to use a locally deregistered object",0);
1579 }
1580 };
1581
1582 /// Specialization of \c ArchiveStoreImpl for globally-addressable objects.
1583
1584 /// \tparam Derived The derived class of \c WorldObject in a curiously
1585 /// repeating template pattern.
1586 template <class Derived>
1588
1589 /// Write a globally-addressable object to a \c BufferOutputArchive.
1590
1591 /// \param[in,out] ar The archive.
1592 /// \param[in] ptr The object to store.
1593 static inline void store(const BufferOutputArchive& ar, WorldObject<Derived>* const& ptr) {
1594 ar & ptr->id();
1595 }
1596 };
1597
1598 /// Specialization of \c ArchiveLoadImpl for constant, globally-addressable objects.
1599
1600 /// \tparam Derived The derived class of \c WorldObject in a curiously
1601 /// repeating template pattern.
1602 template <class Derived>
1604
1605 /// Read a globally-addressable object from a \c BufferInputArchive.
1606
1607 /// \param[in,out] ar The archive.
1608 /// \param[out] ptr The read object.
1609 static inline void load(const BufferInputArchive& ar, const WorldObject<Derived>*& ptr) {
1610 uniqueidT id;
1611 ar & id;
1612 World* world = World::world_from_id(id.get_world_id());
1613 MADNESS_ASSERT(world);
1614 auto ptr_opt = world->ptr_from_id< WorldObject<Derived> >(id);
1615 if (!ptr_opt) MADNESS_EXCEPTION("WorldObj: remote operation attempting to use a locally uninitialized object",0);
1616 ptr = *ptr_opt;
1617 if (!ptr) MADNESS_EXCEPTION("WorldObj: remote operation attempting to use a locally deregistered object",0);
1618 }
1619 };
1620
1621 /// Specialization of \c ArchiveStoreImpl for constant, globally-addressable objects.
1622
1623 /// \tparam Derived The derived class of \c WorldObject in a curiously
1624 /// repeating template pattern.
1625 template <class Derived>
1627
1628 /// Write a globally-addressable object to a \c BufferOutputArchive.
1629
1630 /// \param[in,out] ar The archive.
1631 /// \param[in] ptr The object to store.
1632 static inline void store(const BufferOutputArchive& ar, const WorldObject<Derived>* const& ptr) {
1633 ar & ptr->id();
1634 }
1635 };
1636 } // namespace archive
1637} // namespace madness
1638
1639#endif // MADNESS_WORLD_WORLD_OBJECT_H__INCLUDED
1640
1641/// @}
World active message that extends an RMI message.
Definition worldam.h:80
Implements the functionality of futures.
Definition future.h:74
Specialization of Future<void> for internal convenience. This does nothing useful!
Definition future.h:732
static const Future< void > value
Definition future.h:738
A future is a possibly yet unevaluated value.
Definition future.h:369
remote_refT remote_ref(World &world) const
Returns a structure used to pass references to another process.
Definition future.h:671
static const attrT ATTR_UNORDERED
Definition worldrmi.h:180
Simple structure used to manage references/pointers to remote instances.
Definition worldref.h:395
Mutex that is applied/released at start/end of a scope.
Definition worldmutex.h:239
Spinlock using pthread spinlock operations.
Definition worldmutex.h:253
void lock() const
Acquire the spinlock waiting if necessary.
Definition worldmutex.h:277
void unlock() const
Free a spinlock owned by this thread.
Definition worldmutex.h:287
Contains attributes of a task.
Definition thread.h:329
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
Implements most parts of a globally addressable object (via unique ID).
Definition world_object.h:366
World & get_world() const
Returns a reference to the world.
Definition world_object.h:719
detail::task_result_type< memfnT >::futureT task(ProcessID dest, memfnT memfn, const a1T &a1, const a2T &a2, const a3T &a3, const a4T &a4, const a5T &a5, const a6T &a6, const TaskAttributes &attr=TaskAttributes()) const
Sends task to derived class method returnT (this->*memfn)(a1,a2,a3,a4,a5,a6).
Definition world_object.h:1209
WorldObject(World &world)
Constructor that associates an object (via the derived class) with a globally unique ID.
Definition world_object.h:705
detail::task_result_type< memfnT >::futureT send(ProcessID dest, memfnT memfn, 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
Definition world_object.h:949
static const T & am_arg(const T &t)
Definition world_object.h:551
static bool is_ready(const uniqueidT &id, objT *&obj, const AmArg &arg, am_handlerT ptr)
Definition world_object.h:413
static Spinlock pending_mutex
Definition world_object.h:391
detail::task_result_type< memfnT >::futureT send(ProcessID dest, memfnT memfn, const a1T &a1) const
Definition world_object.h:751
detail::task_result_type< memfnT >::futureT send(ProcessID dest, memfnT memfn, 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
Definition world_object.h:988
WorldObject< Derived > objT
Definition world_object.h:369
WorldObject(const WorldObject &other)
Definition world_object.h:372
detail::task_result_type< memfnT >::futureT task(ProcessID dest, memfnT memfn, const a1T &a1, const a2T &a2, const a3T &a3, const a4T &a4, const a5T &a5, const TaskAttributes &attr=TaskAttributes()) const
Sends task to derived class method returnT (this->*memfn)(a1,a2,a3,a4,a5).
Definition world_object.h:1166
detail::task_result_type< memfnT >::futureT task(ProcessID dest, memfnT memfn, const a1T &a1, const a2T &a2, const TaskAttributes &attr=TaskAttributes()) const
Sends task to derived class method returnT (this->*memfn)(a1,a2).
Definition world_object.h:1059
World & world
The World this object belongs to. (Think globally, act locally).
Definition world_object.h:383
std::list< detail::PendingMsg > pendingT
Definition world_object.h:378
const uniqueidT & id() const
Returns the globally unique object ID.
Definition world_object.h:713
detail::task_result_type< memfnT >::futureT task(ProcessID dest, memfnT memfn, const a1T &a1, const a2T &a2, const a3T &a3, const a4T &a4, const TaskAttributes &attr=TaskAttributes()) const
Sends task to derived class method returnT (this->*memfn)(a1,a2,a3,a4).
Definition world_object.h:1127
detail::task_result_type< memfnT >::futureT send(ProcessID dest, memfnT memfn, const a1T &a1, const a2T &a2) const
Definition world_object.h:771
void process_pending()
To be called from derived constructor to process pending messages.
Definition world_object.h:658
WorldObject & operator=(const WorldObject &)=delete
static void spawn_remote_task_handler(const AmArg &arg)
Handler for remote arguments.
Definition world_object.h:507
detail::task_result_type< memfnT >::futureT send(ProcessID dest, memfnT memfn, const a1T &a1, const a2T &a2, const a3T &a3) const
Definition world_object.h:793
detail::task_result_type< memfnT >::futureT send(ProcessID dest, memfnT memfn, const a1T &a1, const a2T &a2, const a3T &a3, const a4T &a4, const a5T &a5, const a6T &a6, const a7T &a7) const
Definition world_object.h:913
ProcessID me
Rank of self.
Definition world_object.h:387
detail::task_result_type< memfnT >::futureT task(ProcessID dest, memfnT memfn, 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()) const
Sends task to derived class method returnT (this->*memfn)(a1,a2,a3,a4,a5,a6,a7,a8).
Definition world_object.h:1305
detail::task_result_type< memfnT >::futureT task(ProcessID dest, memfnT memfn, 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()) const
Sends task to derived class method returnT (this->*memfn)(a1,a2,a3,a4,a5,a6,a7).
Definition world_object.h:1256
detail::task_result_type< memfnT >::futureT send(ProcessID dest, memfnT memfn) const
Definition world_object.h:733
volatile bool ready
True if ready to rock 'n roll.
Definition world_object.h:386
virtual ~WorldObject()
Definition world_object.h:1387
detail::voidT voidT
Definition world_object.h:381
taskT::futureT send_task(ProcessID dest, memfnT memfn, 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) const
Definition world_object.h:635
detail::task_result_type< memfnT >::futureT task(ProcessID dest, memfnT memfn, const a1T &a1, const TaskAttributes &attr=TaskAttributes()) const
Sends task to derived class method returnT (this->*memfn)(a1).
Definition world_object.h:1030
detail::task_result_type< memfnT >::futureT task(ProcessID dest, memfnT memfn, const a1T &a1, const a2T &a2, const a3T &a3, const TaskAttributes &attr=TaskAttributes()) const
Sends task to derived class method returnT (this->*memfn)(a1,a2,a3).
Definition world_object.h:1091
detail::task_result_type< memfnT >::futureT send(ProcessID dest, memfnT memfn, const a1T &a1, const a2T &a2, const a3T &a3, const a4T &a4) const
Definition world_object.h:820
detail::task_result_type< memfnT >::futureT send_am(ProcessID dest, memfnT memfn, 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
Definition world_object.h:585
uniqueidT objid
Sense of self.
Definition world_object.h:388
static const T & am_arg(const Future< T > &f)
Definition world_object.h:538
detail::task_result_type< memfnT >::futureT send(ProcessID dest, memfnT memfn, const a1T &a1, const a2T &a2, const a3T &a3, const a4T &a4, const a5T &a5, const a6T &a6) const
Definition world_object.h:880
detail::task_result_type< memfnT >::futureT send(ProcessID dest, memfnT memfn, const a1T &a1, const a2T &a2, const a3T &a3, const a4T &a4, const a5T &a5) const
Definition world_object.h:849
detail::task_result_type< memfnT >::futureT task(ProcessID dest, memfnT memfn, 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()) const
Sends task to derived class method returnT (this->*memfn)(a1,a2,a3,a4,a5,a6,a7,a8,...
Definition world_object.h:1362
static volatile pendingT pending
Buffer for pending messages.
Definition world_object.h:392
detail::task_result_type< memfnT >::futureT task(ProcessID dest, memfnT memfn, const TaskAttributes &attr=TaskAttributes()) const
Sends task to derived class method returnT (this->*memfn)().
Definition world_object.h:1007
static void handler(const AmArg &arg)
Handler for an incoming AM.
Definition world_object.h:473
void add(TaskInterface *t)
Add a new local task, taking ownership of the pointer.
Definition world_task_queue.h:466
A parallel world class.
Definition world.h:132
static World * world_from_id(std::uint64_t id)
Convert a World ID to a World pointer.
Definition world.h:492
WorldTaskQueue & taskq
Task queue.
Definition world.h:206
void unregister_ptr(const uniqueidT id)
Unregister a global object via its the unique ID.
Definition world.h:389
static bool exists(World *world)
Check if the World exists in the registry.
Definition world.h:249
std::optional< T * > ptr_from_id(uniqueidT id) const
Look up a local pointer from a world-wide unique ID.
Definition world.h:416
WorldAmInterface & am
AM interface.
Definition world.h:205
Wraps an archive around a memory buffer for input.
Definition buffer_archive.h:134
Wraps an archive around a memory buffer for output.
Definition buffer_archive.h:59
Functor wrapper for object and member function pointers.
Definition mem_func_wrapper.h:89
Class for unique global IDs.
Definition uniqueid.h:53
char * p(char *buf, const char *name, int k, int initial_level, double thresh, int order)
Definition derivatives.cc:72
auto T(World &world, response_space &f) -> response_space
Definition global_functions.cc:28
archive_array< unsigned char > wrap_opaque(const T *, unsigned int)
Factory function to wrap a pointer to contiguous data as an opaque (uchar) archive_array.
Definition archive.h:926
auto to_rel_memfn_ptr(const T &fn)
converts nonstatic member function pointer to the relative equivalent
Definition archive.h:260
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:2503
static const double v
Definition hatom_sf_dirac.cc:20
#define MADNESS_PRAGMA_CLANG(x)
Definition madness_config.h:200
#define MADNESS_EXCEPTION(msg, value)
Macro for throwing a MADNESS exception.
Definition madness_exception.h:119
#define MADNESS_ASSERT(condition)
Assert a condition that should be free of side-effects since in release builds this might be a no-op.
Definition madness_exception.h:134
#define MADNESS_ASSERT_NOEXCEPT(condition)
Same as MADNESS_ASSERT , but never throws.
Definition madness_exception.h:141
Definition potentialmanager.cc:41
static const uniqueidT & peek(const AmArg &arg)
Extract the unique object ID from an incoming active message header.
Definition world_object.h:200
std::enable_if< std::is_void< typenamedetail::result_of< fnT >::type >::value >::type run_function(Future< void > &result, fnT fn, const voidT &, const voidT &, const voidT &, const voidT &, const voidT &, const voidT &, const voidT &, const voidT &, const voidT &)
Definition taskfn.h:317
Namespace for all elements and tools of MADNESS.
Definition DFParameters.h:10
AmArg * copy_am_arg(const AmArg &arg)
Definition worldam.h:170
AmArg * new_am_arg(const argT &... args)
Convenience template for serializing arguments into a new AmArg.
Definition worldam.h:194
bool initialized()
Check if the MADNESS runtime has been initialized (and not subsequently finalized).
Definition world.cc:74
static double pop(std::vector< double > &v)
Definition SCF.cc:115
void free_am_arg(AmArg *arg)
Frees an AmArg allocated with alloc_am_arg.
Definition worldam.h:177
NDIM & f
Definition mra.h:2528
void(* am_handlerT)(const AmArg &)
Type of AM handler functions.
Definition worldam.h:77
std::string type(const PairType &n)
Definition PNOParameters.h:18
static XNonlinearSolver< std::vector< Function< T, NDIM > >, T, vector_function_allocator< T, NDIM > > nonlinear_vector_solver(World &world, const long nvec)
Definition nonlinsol.h:371
Definition mraimpl.h:51
Wrap a callable object and its arguments into a task function.
Definition taskfn.h:473
Base class for WorldObject, useful for introspection.
Definition world_object.h:340
virtual ~WorldObjectBase()=default
virtual World & get_world() const =0
static void load(const BufferInputArchive &ar, WorldObject< Derived > *&ptr)
Read a globally-addressable object from a BufferInputArchive.
Definition world_object.h:1570
static void load(const BufferInputArchive &ar, const WorldObject< Derived > *&ptr)
Read a globally-addressable object from a BufferInputArchive.
Definition world_object.h:1609
Default load of an object via serialize(ar, t).
Definition archive.h:667
static void store(const BufferOutputArchive &ar, WorldObject< Derived > *const &ptr)
Write a globally-addressable object to a BufferOutputArchive.
Definition world_object.h:1593
static void store(const BufferOutputArchive &ar, const WorldObject< Derived > *const &ptr)
Write a globally-addressable object to a BufferOutputArchive.
Definition world_object.h:1632
Default store of an object via serialize(ar, t).
Definition archive.h:612
Common base class for pending messages to ensure in-order processing.
Definition world_object.h:63
void invokehandler()
Definition world_object.h:71
uniqueidT id
Definition world_object.h:64
AmArg * arg
Definition world_object.h:66
am_handlerT handler
Definition world_object.h:65
PendingMsg(uniqueidT id, am_handlerT handler, const AmArg &arg)
Definition world_object.h:68
std::conditional< memfunc_traits< memfnT >::constness, std::shared_ptr< constobjT >, std::shared_ptr< objT > >::type shared_ptrT
Definition world_object.h:285
std::conditional< memfunc_traits< memfnT >::constness, constobjT *, objT * >::type ptrT
Definition world_object.h:281
Definition world_object.h:212
static wrapperT make_task_fn(const objT *obj, memfnT memfn)
Definition world_object.h:227
static wrapperT make_task_fn(WorldObject< objT > *obj, memfnT memfn)
Definition world_object.h:259
std::conditional< memfunc_traits< memfnT >::constness, constobjT *, objT * >::type ptrT
Definition world_object.h:215
static wrapperT make_task_fn(const WorldObject< objT > *obj, memfnT memfn)
Definition world_object.h:249
static wrapperT make_task_fn(objT *obj, memfnT memfn)
Definition world_object.h:238
MemFuncWrapper< ptrT, memfnT, typename result_of< memfnT >::type > wrapperT
Definition world_object.h:218
Definition world_object.h:94
TaskAttributes attr
Definition world_object.h:100
void serialize(const Archive &ar)
Serializes a info_base for I/O.
Definition world_object.h:130
ProcessID requestor
Definition world_object.h:98
memfunT_rel_ptr memfun_rel_ptr
Definition world_object.h:99
memfunT memfun() const
Definition world_object.h:103
uniqueidT id
Definition world_object.h:97
info_base()
Definition world_object.h:109
info_base(const uniqueidT &id, ProcessID requestor, memfunT memfun, const TaskAttributes &attr=TaskAttributes())
Definition world_object.h:118
decltype(archive::to_rel_memfn_ptr(std::declval< memfunT >())) memfunT_rel_ptr
Definition world_object.h:95
Definition world_object.h:140
Future< REMFUTURE(MEMFUN_RETURNT(memfunT)) > futureT
Future for a return value of the memory function.
Definition world_object.h:142
info()
Definition world_object.h:148
void serialize(const Archive &ar)
Serializes a info for I/O.
Definition world_object.h:178
info(const AmArg &arg)
Definition world_object.h:154
refT ref
Definition world_object.h:146
info(const uniqueidT &id, ProcessID requestor, memfunT memfun, const refT &ref, const TaskAttributes &attr=TaskAttributes())
Definition world_object.h:168
RemoteReference< FutureImpl< REMFUTURE(MEMFUN_RETURNT(memfunT)) > > refT
Definition world_object.h:144
T type
Definition taskfn.h:213
Implements Dqueue, Thread, ThreadBase and ThreadPool.
#define REMFUTURE(T)
Macro to determine type of future (by removing wrapping Future template).
Definition type_traits.h:163
#define MEMFUN_RETURNT(MEMFUN)
Macro to make member function type traits easier to use.
Definition type_traits.h:773
const double a2
Definition vnucso.cc:86
const double a1
Definition vnucso.cc:85
Defines TaskInterface and implements WorldTaskQueue and associated stuff.
int ProcessID
Used to clearly identify process number/rank.
Definition worldtypes.h:43