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
148 info() : info_base<memfunT>() {}
149
150 /// \todo Constructor that [brief description needed].
151
152 /// \todo Descriptions needed.
153 /// \param[in] arg Description needed.
154 info(const AmArg& arg) :
155 info_base<memfunT>()
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.
169 const refT& ref, const TaskAttributes& attr=TaskAttributes())
170 : info_base<memfunT>(id, requestor, memfun, attr), ref(ref)
171 {}
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.
238 static wrapperT make_task_fn(objT* obj, memfnT memfn) {
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.
249 static wrapperT make_task_fn(const WorldObject<objT>* obj, memfnT memfn) {
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.
259 static wrapperT make_task_fn(WorldObject<objT>* obj, memfnT memfn) {
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>
276 struct WorldObjectTaskHelper<objT, 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.
308 static wrapperT make_task_fn(objT* obj, memfnT memfn) {
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.
319 static wrapperT make_task_fn(const WorldObject<objT>* obj, memfnT memfn) {
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.
330 static wrapperT make_task_fn(WorldObject<objT>* obj, memfnT memfn) {
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 };
343
344 /// Implements most parts of a globally addressable object (via unique ID).
345
346 /// This class is deliberately not default constructible and does
347 /// not support assignment or copying. This ensures that each instance
348 /// is unique. Have a look at \c madness::WorldContainer for an example
349 /// of wrapping this using the PIMPL idiom and a shared pointer.
350 ///
351 /// When deriving classes:
352 /// -# Derived class has `WorldObject<Derived>` as a public base class.
353 /// -# Derived constructor:
354 /// -# invokes `WorldObject<Derived>(world)` constructor.
355 /// -# invokes `process_pending()`.
356 /// -# Derived destructor must either be deferred or preceeded by `gop.fence()`.
357 /// -# Derived class must have at least one virtual function for serialization
358 /// of derived class pointers to be cast to the appropriate type.
359 ///
360 /// Note that \c world is exposed for convenience as a public data member.
361 /// \tparam Derived The derived class. \c WorldObject is a curiously
362 /// recurring template pattern.
363 template <class Derived>
365 public:
366 /// \todo Description needed.
368
369 // copy ctor must be enabled to permit RVO; in C++17 will not need this
370 WorldObject(const WorldObject& other) : world(other.world) { abort(); }
371 // no copy
373
374 private:
375 /// \todo Description needed.
376 typedef std::list<detail::PendingMsg> pendingT;
377
378 /// \todo Description needed.
380
381 World& world; ///< The \c World this object belongs to. (Think globally, act locally).
382
383 // The order here matters in a multi-threaded world
384 volatile bool ready; ///< True if ready to rock 'n roll.
385 ProcessID me; ///< Rank of self.
386 uniqueidT objid; ///< Sense of self.
387
388
389 inline static Spinlock pending_mutex; ///< \todo Description needed.
390 inline static volatile pendingT pending; ///< Buffer for pending messages.
391
392
393 /// \todo Complete: Determine if [unknown] is ready (for ...).
394
395 /// The slightly convoluted logic is to ensure ordering when
396 /// processing pending messages. If a new message arrives
397 /// while processing incoming messages it must be queued.
398 ///
399 /// - If the object does not exist ---> not ready.
400 /// - If the object exists and is ready ---> ready.
401 /// - If the object exists and is not ready then
402 /// - if we are doing a queued/pending message --> ready.
403 /// - else this is a new message --> not ready.
404 ///
405 /// \param[in] id Description needed.
406 /// \param[in,out] obj Description needed.
407 /// \param[in] arg Description needed.
408 /// \param[in,out] ptr Description needed.
409 /// \return Description needed.
410 /// \todo Parameter/return descriptions needed.
411 static bool is_ready(const uniqueidT& id, objT*& obj, const AmArg& arg, am_handlerT ptr) {
412 std::optional<Derived *> opt_obj =
413 arg.get_world()->template ptr_from_id<Derived>(id);
414 if (opt_obj) {
415 // if opt_obj == nullptr, then this ID has already been deregistered
416 MADNESS_ASSERT(*opt_obj != nullptr);
417 obj = static_cast<objT *>(*opt_obj);
418 } else
419 obj = nullptr;
420
421 if (obj) {
422 if (obj->ready || arg.is_pending())
423 return true;
424 }
425
426 MADNESS_PRAGMA_CLANG(diagnostic push)
427 MADNESS_PRAGMA_CLANG(diagnostic ignored "-Wundefined-var-template")
428
429 ScopedMutex<Spinlock> lock(pending_mutex); // BEGIN CRITICAL SECTION
430
431 if (!obj) {
432 std::optional<Derived *> opt_obj =
433 arg.get_world()->template ptr_from_id<Derived>(id);
434 if (opt_obj) {
435 // if opt_obj == nullptr, then this ID has already been deregistered
436 MADNESS_ASSERT(*opt_obj != nullptr);
437 obj = static_cast<objT *>(*opt_obj);
438 } else
439 obj = nullptr;
440 }
441
442 if (obj) {
443 if (obj->ready || arg.is_pending())
444 return true; // END CRITICAL SECTION
445 }
446 const_cast<AmArg &>(arg).set_pending();
447 const_cast<pendingT &>(pending).push_back(
448 detail::PendingMsg(id, ptr, arg));
449
450 MADNESS_PRAGMA_CLANG(diagnostic pop)
451
452 return false; // END CRITICAL SECTION
453 }
454
455 /// Handler for an incoming AM.
456
457 /// \todo Descriptions needed.
458 /// \tparam memfnT Verify: Signature of the member function in the derived class to be invoked for the task.
459 /// \tparam arg1T Type of argument 1.
460 /// \tparam arg2T Type of argument 2.
461 /// \tparam arg3T Type of argument 3.
462 /// \tparam arg4T Type of argument 4.
463 /// \tparam arg5T Type of argument 5.
464 /// \tparam arg6T Type of argument 6.
465 /// \tparam arg7T Type of argument 7.
466 /// \tparam arg8T Type of argument 8.
467 /// \tparam arg9T Type of argument 9.
468 /// \param[in] arg Description needed.
469 template <typename memfnT, typename arg1T, typename arg2T, typename arg3T, typename arg4T,
470 typename arg5T, typename arg6T, typename arg7T, typename arg8T, typename arg9T>
471 static void handler(const AmArg& arg) {
473
474 const uniqueidT& id = detail::peek(arg);
475 am_handlerT ptr = handler<memfnT,arg1T,arg2T,arg3T,arg4T,arg5T,arg6T,arg7T,arg8T,arg9T>;
476 objT* obj;
477 if (is_ready(id,obj,arg,ptr)) {
479 typename detail::task_arg<arg1T>::type arg1;
480 typename detail::task_arg<arg2T>::type arg2;
481 typename detail::task_arg<arg3T>::type arg3;
482 typename detail::task_arg<arg4T>::type arg4;
483 typename detail::task_arg<arg5T>::type arg5;
484 typename detail::task_arg<arg6T>::type arg6;
485 typename detail::task_arg<arg7T>::type arg7;
486 typename detail::task_arg<arg8T>::type arg8;
487 typename detail::task_arg<arg9T>::type arg9;
488 MADNESS_PRAGMA_CLANG(diagnostic push)
489 MADNESS_PRAGMA_CLANG(diagnostic ignored "-Wuninitialized-const-reference")
490 arg & info & arg1 & arg2 & arg3 & arg4 & arg5 & arg6 & arg7 & arg8 & arg9;
491 MADNESS_PRAGMA_CLANG(diagnostic pop)
492 typename detail::info<memfnT>::futureT result(info.ref);
493 detail::run_function(result, task_helper::make_task_fn(obj, info.memfun()),
494 arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9);
495 }
496 }
497
498
499 /// Handler for remote arguments.
500
501 /// \todo Descriptions needed.
502 /// \tparam taskT Description needed.
503 /// \param[in] arg Description needed.
504 template <typename taskT>
505 static void spawn_remote_task_handler(const AmArg& arg) {
506 typedef detail::WorldObjectTaskHelper<Derived,
507 typename taskT::functionT::memfn_type> task_helper;
508
509 MADNESS_ASSERT(taskT::arity <= 9u);
510
511 const uniqueidT& id = detail::peek(arg);
512 am_handlerT ptr = & objT::template spawn_remote_task_handler<taskT>;
513 objT* obj;
514 if (is_ready(id,obj,arg,ptr)) {
516
517 archive::BufferInputArchive input_arch = arg & info;
518
519 // Construct task
520 taskT* task = new taskT(typename taskT::futureT(info.ref),
521 task_helper::make_task_fn(obj, info.memfun()), info.attr, input_arch);
522
523 // Add task to queue
524 arg.get_world()->taskq.add(task);
525 }
526 }
527
528
529 /// \todo Brief description needed.
530
531 /// \todo Descriptions needed.
532 /// \tparam T Description needed.
533 /// \param[in] f Description needed.
534 /// \return Description needed.
535 template <typename T>
536 static inline const T& am_arg(const Future<T>& f) {
537 MADNESS_ASSERT(f.probe()); // Cannot serialize unassigned futures
538 return f.get();
539 }
540
541
542 /// \todo Brief description needed.
543
544 /// \todo Descriptions needed.
545 /// \tparam T Description needed.
546 /// \param[in] t Description needed.
547 /// \return Description needed.
548 template <typename T>
549 static inline const T& am_arg(const T& t) {
550 return t;
551 }
552
553
554 /// \todo Brief description needed.
555
556 /// \todo Descriptions needed.
557 /// \tparam memfnT Verify: Signature of the member function in the derived class to be invoked for the task.
558 /// \tparam a1T Type of argument 1.
559 /// \tparam a2T Type of argument 2.
560 /// \tparam a3T Type of argument 3.
561 /// \tparam a4T Type of argument 4.
562 /// \tparam a5T Type of argument 5.
563 /// \tparam a6T Type of argument 6.
564 /// \tparam a7T Type of argument 7.
565 /// \tparam a8T Type of argument 8.
566 /// \tparam a9T Type of argument 9.
567 /// \param dest Description needed.
568 /// \param memfn Verify: The member function to be invoked for the task.
569 /// \param a1 Argument 1.
570 /// \param a2 Argument 2.
571 /// \param a3 Argument 3.
572 /// \param a4 Argument 4.
573 /// \param a5 Argument 5.
574 /// \param a6 Argument 6.
575 /// \param a7 Argument 7.
576 /// \param a8 Argument 8.
577 /// \param a9 Argument 9.
578 /// \return Description needed.
579 template <typename memfnT, typename a1T, typename a2T, typename a3T,
580 typename a4T, typename a5T, typename a6T, typename a7T,
581 typename a8T, typename a9T>
583 send_am(ProcessID dest, memfnT memfn, const a1T& a1, const a2T& a2,
584 const a3T& a3, const a4T& a4, const a5T& a5, const a6T& a6,
585 const a7T& a7, const a8T& a8, const a9T& a9) const
586 {
589 if (dest == me)
590 detail::run_function(result, task_helper::make_task_fn(this, memfn),
591 a1, a2, a3, a4, a5, a6, a7, a8, a9);
592 else {
593 detail::info<memfnT> info(objid, me, memfn, result.remote_ref(world));
594 world.am.send(dest, & objT::template handler<memfnT, a1T, a2T, a3T, a4T, a5T, a6T, a7T, a8T, a9T>,
595 new_am_arg(info, a1, a2, a3, a4, a5, a6, a7, a8, a9));
596 }
597
598 return result;
599 }
600
601
602 /// \todo Brief description needed.
603
604 /// \todo Descriptions needed.
605 /// \tparam taskT Description needed.
606 /// \tparam memfnT Verify: Signature of the member function in the derived class to be invoked for the task.
607 /// \tparam a1T Type of argument 1.
608 /// \tparam a2T Type of argument 2.
609 /// \tparam a3T Type of argument 3.
610 /// \tparam a4T Type of argument 4.
611 /// \tparam a5T Type of argument 5.
612 /// \tparam a6T Type of argument 6.
613 /// \tparam a7T Type of argument 7.
614 /// \tparam a8T Type of argument 8.
615 /// \tparam a9T Type of argument 9.
616 /// \param dest Description needed.
617 /// \param memfn Verify: The member function to be invoked for the task.
618 /// \param a1 Argument 1.
619 /// \param a2 Argument 2.
620 /// \param a3 Argument 3.
621 /// \param a4 Argument 4.
622 /// \param a5 Argument 5.
623 /// \param a6 Argument 6.
624 /// \param a7 Argument 7.
625 /// \param a8 Argument 8.
626 /// \param a9 Argument 9.
627 /// \param attr Description needed.
628 /// \return Description needed.
629 template <typename taskT, typename memfnT, typename a1T, typename a2T, typename a3T,
630 typename a4T, typename a5T, typename a6T, typename a7T,
631 typename a8T, typename a9T>
632 typename taskT::futureT
633 send_task(ProcessID dest, memfnT memfn, const a1T& a1,
634 const a2T& a2, const a3T& a3, const a4T& a4, const a5T& a5,
635 const a6T& a6, const a7T& a7, const a8T& a8, const a9T& a9,
636 const TaskAttributes& attr) const
637 {
638 typename taskT::futureT result;
639 detail::info<memfnT> info(objid, me, memfn, result.remote_ref(world), attr);
640 world.am.send(dest, & objT::template spawn_remote_task_handler<taskT>,
641 new_am_arg(info, a1, a2, a3, a4, a5, a6, a7, a8, a9), RMI::ATTR_UNORDERED);
642
643 return result;
644 }
645
646 protected:
647
648 /// To be called from \em derived constructor to process pending messages.
649
650 /// Cannot call this from the \c WorldObject constructor since the
651 /// derived class would not yet be fully constructed.
652 ///
653 /// \attention No incoming messages are processed until this routine is
654 /// invoked; the derived class may rely upon a well defined state
655 /// until this routine is invoked.
657 // Messages may be arriving while we are processing the
658 // pending queue. To maximize concurrency copy messages
659 // out of queue before processing outside critical section.
660 //int ndone = 0;
661 while (!ready) {
662 pendingT tmp;
663
664 MADNESS_PRAGMA_CLANG(diagnostic push)
665 MADNESS_PRAGMA_CLANG(diagnostic ignored "-Wundefined-var-template")
666
667 pending_mutex.lock(); // BEGIN CRITICAL SECTION
668 pendingT& nv = const_cast<pendingT&>(pending);
669 for (pendingT::iterator it=nv.begin(); it!=nv.end();) {
670 detail::PendingMsg& p = *it;
671 if (p.id == objid) {
672 tmp.push_back(p);
673 it = nv.erase(it);
674 }
675 else {
676 ++it;
677 }
678 }
679 if (tmp.size() == 0) ready=true;
680 pending_mutex.unlock(); // END CRITICAL SECTION
681
682 MADNESS_PRAGMA_CLANG(diagnostic pop)
683
684 while (tmp.size()) {
685 tmp.front().invokehandler();
686 tmp.pop_front();
687 //++ndone;
688 }
689 }
690 //if (ndone) std::cout << world.rank() << ":pending:" << ndone << std::endl;
691 }
692
693
694 public:
695 /// \brief Constructor that associates an object (via the derived class)
696 /// with a globally unique ID.
697
698 /// \attention The derived class MUST call \c process_pending from
699 /// its constructor to both
700 /// -# process any messages that arrived prior to construction.
701 /// -# to enable processing of future messages.
702 /// \param[in,out] world The \c World encapsulating the \"global\" domain.
704 : world(world)
705 , ready(false)
706 , me(world.rank())
707 , objid(world.register_ptr(static_cast<Derived*>(this))) {};
708
709
710 /// Returns the globally unique object ID.
711 const uniqueidT& id() const {
712 return objid;
713 }
714
715
716 /// Returns a reference to the \c world.
717 World& get_world() const {
718 return const_cast<WorldObject<Derived>*>(this)->world;
719 }
720
721
722 /// \todo Brief description needed.
723
724 /// \todo Descriptions needed.
725 /// \tparam memfnT Verify: Signature of the member function in the derived class to be invoked for the task.
726 /// \param dest Description needed.
727 /// \param memfn Verify: The member function to be invoked for the task.
728 /// \return Description needed.
729 template <typename memfnT>
731 send(ProcessID dest, memfnT memfn) const {
732 return send_am(dest, memfn, voidT::value, voidT::value, voidT::value,
735 }
736
737
738 /// \todo Brief description needed.
739
740 /// \todo Descriptions needed.
741 /// \tparam memfnT Verify: Signature of the member function in the derived class to be invoked for the task.
742 /// \tparam a1T Type of argument 1.
743 /// \param dest Description needed.
744 /// \param memfn Verify: The member function to be invoked for the task.
745 /// \param a1 Argument 1.
746 /// \return Description needed.
747 template <typename memfnT, typename a1T>
749 send(ProcessID dest, memfnT memfn, const a1T& a1) const {
750 return send_am(dest, memfn, am_arg(a1), voidT::value, voidT::value,
753 }
754
755
756 /// \todo Brief description needed.
757
758 /// \todo Descriptions needed.
759 /// \tparam memfnT Verify: Signature of the member function in the derived class to be invoked for the task.
760 /// \tparam a1T Type of argument 1.
761 /// \tparam a2T Type of argument 2.
762 /// \param dest Description needed.
763 /// \param memfn Verify: The member function to be invoked for the task.
764 /// \param a1 Argument 1.
765 /// \param a2 Argument 2.
766 /// \return Description needed.
767 template <typename memfnT, typename a1T, typename a2T>
769 send(ProcessID dest, memfnT memfn, const a1T& a1, const a2T& a2) const {
770 return send_am(dest, memfn, am_arg(a1), am_arg(a2), voidT::value,
773 }
774
775
776 /// \todo Brief description needed.
777
778 /// \todo Descriptions needed.
779 /// \tparam memfnT Verify: Signature of the member function in the derived class to be invoked for the task.
780 /// \tparam a1T Type of argument 1.
781 /// \tparam a2T Type of argument 2.
782 /// \tparam a3T Type of argument 3.
783 /// \param dest Description needed.
784 /// \param memfn Verify: The member function to be invoked for the task.
785 /// \param a1 Argument 1.
786 /// \param a2 Argument 2.
787 /// \param a3 Argument 3.
788 /// \return Description needed.
789 template <typename memfnT, typename a1T, typename a2T, typename a3T>
791 send(ProcessID dest, memfnT memfn, const a1T& a1, const a2T& a2,
792 const a3T& a3) const
793 {
794 return send_am(dest, memfn, am_arg(a1), am_arg(a2), am_arg(a3),
797 }
798
799
800 /// \todo Brief description needed.
801
802 /// \todo Descriptions needed.
803 /// \tparam memfnT Verify: Signature of the member function in the derived class to be invoked for the task.
804 /// \tparam a1T Type of argument 1.
805 /// \tparam a2T Type of argument 2.
806 /// \tparam a3T Type of argument 3.
807 /// \tparam a4T Type of argument 4.
808 /// \param dest Description needed.
809 /// \param memfn Verify: The member function to be invoked for the task.
810 /// \param a1 Argument 1.
811 /// \param a2 Argument 2.
812 /// \param a3 Argument 3.
813 /// \param a4 Argument 4.
814 /// \return Description needed.
815 template <typename memfnT, typename a1T, typename a2T, typename a3T,
816 typename a4T>
818 send(ProcessID dest, memfnT memfn, const a1T& a1, const a2T& a2,
819 const a3T& a3, const a4T& a4) const
820 {
821 return send_am(dest, memfn, am_arg(a1), am_arg(a2), am_arg(a3),
824 }
825
826
827 /// \todo Brief description needed.
828
829 /// \todo Descriptions needed.
830 /// \tparam memfnT Verify: Signature of the member function in the derived class to be invoked for the task.
831 /// \tparam a1T Type of argument 1.
832 /// \tparam a2T Type of argument 2.
833 /// \tparam a3T Type of argument 3.
834 /// \tparam a4T Type of argument 4.
835 /// \tparam a5T Type of argument 5.
836 /// \param dest Description needed.
837 /// \param memfn Verify: The member function to be invoked for the task.
838 /// \param a1 Argument 1.
839 /// \param a2 Argument 2.
840 /// \param a3 Argument 3.
841 /// \param a4 Argument 4.
842 /// \param a5 Argument 5.
843 /// \return Description needed.
844 template <typename memfnT, typename a1T, typename a2T, typename a3T,
845 typename a4T, typename a5T>
847 send(ProcessID dest, memfnT memfn, const a1T& a1, const a2T& a2,
848 const a3T& a3, const a4T& a4, const a5T& a5) const
849 {
850 return send_am(dest, memfn, am_arg(a1), am_arg(a2), am_arg(a3),
853 }
854
855
856 /// \todo Brief description needed.
857
858 /// \todo Descriptions needed.
859 /// \tparam memfnT Verify: Signature of the member function in the derived class to be invoked for the task.
860 /// \tparam a1T Type of argument 1.
861 /// \tparam a2T Type of argument 2.
862 /// \tparam a3T Type of argument 3.
863 /// \tparam a4T Type of argument 4.
864 /// \tparam a5T Type of argument 5.
865 /// \tparam a6T Type of argument 6.
866 /// \param dest Description needed.
867 /// \param memfn Verify: The member function to be invoked for the task.
868 /// \param a1 Argument 1.
869 /// \param a2 Argument 2.
870 /// \param a3 Argument 3.
871 /// \param a4 Argument 4.
872 /// \param a5 Argument 5.
873 /// \param a6 Argument 6.
874 /// \return Description needed.
875 template <typename memfnT, typename a1T, typename a2T, typename a3T,
876 typename a4T, typename a5T, typename a6T>
878 send(ProcessID dest, memfnT memfn, const a1T& a1, const a2T& a2,
879 const a3T& a3, const a4T& a4, const a5T& a5, const a6T& a6) const
880 {
881 return send_am(dest, memfn, am_arg(a1), am_arg(a2), am_arg(a3),
884 }
885
886
887 /// \todo Brief description needed.
888
889 /// \todo Descriptions needed.
890 /// \tparam memfnT Verify: Signature of the member function in the derived class to be invoked for the task.
891 /// \tparam a1T Type of argument 1.
892 /// \tparam a2T Type of argument 2.
893 /// \tparam a3T Type of argument 3.
894 /// \tparam a4T Type of argument 4.
895 /// \tparam a5T Type of argument 5.
896 /// \tparam a6T Type of argument 6.
897 /// \tparam a7T Type of argument 7.
898 /// \param dest Description needed.
899 /// \param memfn Verify: The member function to be invoked for the task.
900 /// \param a1 Argument 1.
901 /// \param a2 Argument 2.
902 /// \param a3 Argument 3.
903 /// \param a4 Argument 4.
904 /// \param a5 Argument 5.
905 /// \param a6 Argument 6.
906 /// \param a7 Argument 7.
907 /// \return Description needed.
908 template <typename memfnT, typename a1T, typename a2T, typename a3T,
909 typename a4T, typename a5T, typename a6T, typename a7T>
911 send(ProcessID dest, memfnT memfn, const a1T& a1, const a2T& a2,
912 const a3T& a3, const a4T& a4, const a5T& a5, const a6T& a6,
913 const a7T& a7) const
914 {
915 return send_am(dest, memfn, am_arg(a1), am_arg(a2), am_arg(a3),
916 am_arg(a4), am_arg(a5), am_arg(a6), am_arg(a7), voidT::value,
918 }
919
920
921 /// \todo Brief description needed.
922
923 /// \todo Descriptions needed.
924 /// \tparam memfnT Verify: Signature of the member function in the derived class to be invoked for the task.
925 /// \tparam a1T Type of argument 1.
926 /// \tparam a2T Type of argument 2.
927 /// \tparam a3T Type of argument 3.
928 /// \tparam a4T Type of argument 4.
929 /// \tparam a5T Type of argument 5.
930 /// \tparam a6T Type of argument 6.
931 /// \tparam a7T Type of argument 7.
932 /// \tparam a8T Type of argument 8.
933 /// \param dest Description needed.
934 /// \param memfn Verify: The member function to be invoked for the task.
935 /// \param a1 Argument 1.
936 /// \param a2 Argument 2.
937 /// \param a3 Argument 3.
938 /// \param a4 Argument 4.
939 /// \param a5 Argument 5.
940 /// \param a6 Argument 6.
941 /// \param a7 Argument 7.
942 /// \param a8 Argument 8.
943 /// \return Description needed.
944 template <typename memfnT, typename a1T, typename a2T, typename a3T,
945 typename a4T, typename a5T, typename a6T, typename a7T, typename a8T>
947 send(ProcessID dest, memfnT memfn, const a1T& a1, const a2T& a2,
948 const a3T& a3, const a4T& a4, const a5T& a5, const a6T& a6,
949 const a7T& a7, const a8T& a8) const
950 {
951 return send_am(dest, memfn, am_arg(a1), am_arg(a2), am_arg(a3),
952 am_arg(a4), am_arg(a5), am_arg(a6), am_arg(a7), am_arg(a8),
954 }
955
956
957 /// \todo Brief description needed.
958
959 /// \todo Descriptions needed.
960 /// \tparam memfnT Verify: Signature of the member function in the derived class to be invoked for the task.
961 /// \tparam a1T Type of argument 1.
962 /// \tparam a2T Type of argument 2.
963 /// \tparam a3T Type of argument 3.
964 /// \tparam a4T Type of argument 4.
965 /// \tparam a5T Type of argument 5.
966 /// \tparam a6T Type of argument 6.
967 /// \tparam a7T Type of argument 7.
968 /// \tparam a8T Type of argument 8.
969 /// \tparam a9T Type of argument 9.
970 /// \param dest Description needed.
971 /// \param memfn Verify: The member function to be invoked for the task.
972 /// \param a1 Argument 1.
973 /// \param a2 Argument 2.
974 /// \param a3 Argument 3.
975 /// \param a4 Argument 4.
976 /// \param a5 Argument 5.
977 /// \param a6 Argument 6.
978 /// \param a7 Argument 7.
979 /// \param a8 Argument 8.
980 /// \param a9 Argument 9.
981 /// \return Description needed.
982 template <typename memfnT, typename a1T, typename a2T, typename a3T,
983 typename a4T, typename a5T, typename a6T, typename a7T, typename a8T,
984 typename a9T>
986 send(ProcessID dest, memfnT memfn, const a1T& a1, const a2T& a2,
987 const a3T& a3, const a4T& a4, const a5T& a5, const a6T& a6,
988 const a7T& a7, const a8T& a8, const a9T& a9) const
989 {
990 return send_am(dest, memfn, am_arg(a1), am_arg(a2), am_arg(a3),
991 am_arg(a4), am_arg(a5), am_arg(a6), am_arg(a7), am_arg(a8),
992 am_arg(a9));
993 }
994
995 /// Sends task to derived class method `returnT (this->*memfn)()`.
996
997 /// \todo Descriptions needed.
998 /// \tparam memfnT Verify: Signature of the member function in the derived class to be invoked for the task.
999 /// \param dest Description needed.
1000 /// \param memfn Verify: The member function to be invoked for the task.
1001 /// \param attr Description needed.
1002 /// \return Description needed.
1003 template <typename memfnT>
1005 task(ProcessID dest, memfnT memfn, const TaskAttributes& attr = TaskAttributes()) const {
1008 if (dest == me)
1009 return world.taskq.add(task_helper::make_task_fn(this, memfn), attr);
1010 else
1011 return send_task<taskT>(dest, memfn, voidT::value, voidT::value,
1014 }
1015
1016 /// Sends task to derived class method `returnT (this->*memfn)(a1)`.
1017
1018 /// \todo Descriptions needed.
1019 /// \tparam memfnT Verify: Signature of the member function in the derived class to be invoked for the task.
1020 /// \tparam a1T Type of argument 1.
1021 /// \param dest Description needed.
1022 /// \param memfn Verify: The member function to be invoked for the task.
1023 /// \param a1 Argument 1.
1024 /// \param attr Description needed.
1025 /// \return Description needed.
1026 template <typename memfnT, typename a1T>
1028 task(ProcessID dest, memfnT memfn, const a1T& a1,
1029 const TaskAttributes& attr = TaskAttributes()) const
1030 {
1032 typedef TaskFn<typename task_helper::wrapperT,
1033 typename detail::task_arg<a1T>::type> taskT;
1034 if (dest == me)
1035 return world.taskq.add(task_helper::make_task_fn(this, memfn),
1036 a1, attr);
1037 else
1038 return send_task<taskT>(dest, memfn, am_arg(a1), voidT::value,
1041 }
1042
1043 /// Sends task to derived class method `returnT (this->*memfn)(a1,a2)`.
1044
1045 /// \todo Descriptions needed.
1046 /// \tparam memfnT Verify: Signature of the member function in the derived class to be invoked for the task.
1047 /// \tparam a1T Type of argument 1.
1048 /// \tparam a2T Type of argument 2.
1049 /// \param dest Description needed.
1050 /// \param memfn Verify: The member function to be invoked for the task.
1051 /// \param a1 Argument 1.
1052 /// \param a2 Argument 2.
1053 /// \param attr Description needed.
1054 /// \return Description needed.
1055 template <typename memfnT, typename a1T, typename a2T>
1057 task(ProcessID dest, memfnT memfn, const a1T& a1, const a2T& a2,
1058 const TaskAttributes& attr = TaskAttributes()) const
1059 {
1061 typedef TaskFn<typename task_helper::wrapperT,
1063 typename detail::task_arg<a2T>::type> taskT;
1064 if (dest == me)
1065 return world.taskq.add(task_helper::make_task_fn(this, memfn),
1066 a1, a2, attr);
1067 else
1068 return send_task<taskT>(dest, memfn, am_arg(a1), am_arg(a2),
1071 }
1072
1073 /// Sends task to derived class method `returnT (this->*memfn)(a1,a2,a3)`.
1074
1075 /// \todo Descriptions needed.
1076 /// \tparam memfnT Verify: Signature of the member function in the derived class to be invoked for the task.
1077 /// \tparam a1T Type of argument 1.
1078 /// \tparam a2T Type of argument 2.
1079 /// \tparam a3T Type of argument 3.
1080 /// \param dest Description needed.
1081 /// \param memfn Verify: The member function to be invoked for the task.
1082 /// \param a1 Argument 1.
1083 /// \param a2 Argument 2.
1084 /// \param a3 Argument 3.
1085 /// \param attr Description needed.
1086 /// \return Description needed.
1087 template <typename memfnT, typename a1T, typename a2T, typename a3T>
1089 task(ProcessID dest, memfnT memfn, const a1T& a1, const a2T& a2,
1090 const a3T& a3, const TaskAttributes& attr = TaskAttributes()) const
1091 {
1093 typedef TaskFn<typename task_helper::wrapperT,
1096 typename detail::task_arg<a3T>::type> taskT;
1097 if (dest == me)
1098 return world.taskq.add(task_helper::make_task_fn(this, memfn),
1099 a1, a2, a3, attr);
1100 else
1101 return send_task<taskT>(dest, memfn, am_arg(a1), am_arg(a2),
1104 }
1105
1106 /// Sends task to derived class method `returnT (this->*memfn)(a1,a2,a3,a4)`.
1107
1108 /// \todo Descriptions needed.
1109 /// \tparam memfnT Verify: Signature of the member function in the derived class to be invoked for the task.
1110 /// \tparam a1T Type of argument 1.
1111 /// \tparam a2T Type of argument 2.
1112 /// \tparam a3T Type of argument 3.
1113 /// \tparam a4T Type of argument 4.
1114 /// \param dest Description needed.
1115 /// \param memfn Verify: The member function to be invoked for the task.
1116 /// \param a1 Argument 1.
1117 /// \param a2 Argument 2.
1118 /// \param a3 Argument 3.
1119 /// \param a4 Argument 4.
1120 /// \param attr Description needed.
1121 /// \return Description needed.
1122 template <typename memfnT, typename a1T, typename a2T, typename a3T,
1123 typename a4T>
1125 task(ProcessID dest, memfnT memfn, const a1T& a1, const a2T& a2,
1126 const a3T& a3, const a4T& a4, const TaskAttributes& attr = TaskAttributes()) const
1127 {
1129 typedef TaskFn<typename task_helper::wrapperT,
1133 typename detail::task_arg<a4T>::type> taskT;
1134 if (dest == me)
1135 return world.taskq.add(task_helper::make_task_fn(this, memfn),
1136 a1, a2, a3, a4, attr);
1137 else
1138 return send_task<taskT>(dest, memfn, am_arg(a1), am_arg(a2),
1141 }
1142
1143 /// Sends task to derived class method `returnT (this->*memfn)(a1,a2,a3,a4,a5)`.
1144
1145 /// \todo Descriptions needed.
1146 /// \tparam memfnT Verify: Signature of the member function in the derived class to be invoked for the task.
1147 /// \tparam a1T Type of argument 1.
1148 /// \tparam a2T Type of argument 2.
1149 /// \tparam a3T Type of argument 3.
1150 /// \tparam a4T Type of argument 4.
1151 /// \tparam a5T Type of argument 5.
1152 /// \param dest Description needed.
1153 /// \param memfn Verify: The member function to be invoked for the task.
1154 /// \param a1 Argument 1.
1155 /// \param a2 Argument 2.
1156 /// \param a3 Argument 3.
1157 /// \param a4 Argument 4.
1158 /// \param a5 Argument 5.
1159 /// \param attr Description needed.
1160 /// \return Description needed.
1161 template <typename memfnT, typename a1T, typename a2T, typename a3T,
1162 typename a4T, typename a5T>
1164 task(ProcessID dest, memfnT memfn, const a1T& a1, const a2T& a2,
1165 const a3T& a3, const a4T& a4, const a5T& a5,
1166 const TaskAttributes& attr = TaskAttributes()) const
1167 {
1169 typedef TaskFn<typename task_helper::wrapperT,
1174 typename detail::task_arg<a5T>::type> taskT;
1175 if (dest == me)
1176 return world.taskq.add(task_helper::make_task_fn(this, memfn),
1177 a1, a2, a3, a4, a5, attr);
1178 else
1179 return send_task<taskT>(dest, memfn, am_arg(a1), am_arg(a2),
1180 am_arg(a3), am_arg(a4), am_arg(a5), voidT::value,
1182 }
1183
1184 /// Sends task to derived class method `returnT (this->*memfn)(a1,a2,a3,a4,a5,a6)`.
1185
1186 /// \todo Descriptions needed.
1187 /// \tparam memfnT Verify: Signature of the member function in the derived class to be invoked for the task.
1188 /// \tparam a1T Type of argument 1.
1189 /// \tparam a2T Type of argument 2.
1190 /// \tparam a3T Type of argument 3.
1191 /// \tparam a4T Type of argument 4.
1192 /// \tparam a5T Type of argument 5.
1193 /// \tparam a6T Type of argument 6.
1194 /// \param dest Description needed.
1195 /// \param memfn Verify: The member function to be invoked for the task.
1196 /// \param a1 Argument 1.
1197 /// \param a2 Argument 2.
1198 /// \param a3 Argument 3.
1199 /// \param a4 Argument 4.
1200 /// \param a5 Argument 5.
1201 /// \param a6 Argument 6.
1202 /// \param attr Description needed.
1203 /// \return Description needed.
1204 template <typename memfnT, typename a1T, typename a2T, typename a3T,
1205 typename a4T, typename a5T, typename a6T>
1207 task(ProcessID dest, memfnT memfn, const a1T& a1, const a2T& a2,
1208 const a3T& a3, const a4T& a4, const a5T& a5, const a6T& a6,
1209 const TaskAttributes& attr = TaskAttributes()) const
1210 {
1212 typedef TaskFn<typename task_helper::wrapperT,
1218 typename detail::task_arg<a6T>::type> taskT;
1219 if (dest == me)
1220 return world.taskq.add(task_helper::make_task_fn(this, memfn),
1221 a1, a2, a3, a4, a5, a6, attr);
1222 else {
1223 return send_task<taskT>(dest, memfn, am_arg(a1), am_arg(a2),
1224 am_arg(a3), am_arg(a4), am_arg(a5), am_arg(a6),
1226 }
1227 }
1228
1229 /// Sends task to derived class method `returnT (this->*memfn)(a1,a2,a3,a4,a5,a6,a7)`.
1230
1231 /// \todo Descriptions needed.
1232 /// \tparam memfnT Verify: Signature of the member function in the derived class to be invoked for the task.
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 /// \param dest Description needed.
1241 /// \param memfn Verify: The member function to be invoked for the task.
1242 /// \param a1 Argument 1.
1243 /// \param a2 Argument 2.
1244 /// \param a3 Argument 3.
1245 /// \param a4 Argument 4.
1246 /// \param a5 Argument 5.
1247 /// \param a6 Argument 6.
1248 /// \param a7 Argument 7.
1249 /// \param attr Description needed.
1250 /// \return Description needed.
1251 template <typename memfnT, typename a1T, typename a2T, typename a3T,
1252 typename a4T, typename a5T, typename a6T, typename a7T>
1254 task(ProcessID dest, memfnT memfn, const a1T& a1, const a2T& a2,
1255 const a3T& a3, const a4T& a4, const a5T& a5, const a6T& a6,
1256 const a7T& a7, const TaskAttributes& attr = TaskAttributes()) const
1257 {
1259 typedef TaskFn<typename task_helper::wrapperT,
1266 typename detail::task_arg<a7T>::type> taskT;
1267 if (dest == me)
1268 return world.taskq.add(task_helper::make_task_fn(this, memfn),
1269 a1, a2, a3, a4, a5, a6, a7, attr);
1270 else
1271 return send_task<taskT>(dest, memfn, am_arg(a1), am_arg(a2),
1272 am_arg(a3), am_arg(a4), am_arg(a5), am_arg(a6),
1273 am_arg(a7), voidT::value, voidT::value, attr);
1274 }
1275
1276 /// Sends task to derived class method `returnT (this->*memfn)(a1,a2,a3,a4,a5,a6,a7,a8)`.
1277
1278 /// \todo Descriptions needed.
1279 /// \tparam memfnT Verify: Signature of the member function in the derived class to be invoked for the task.
1280 /// \tparam a1T Type of argument 1.
1281 /// \tparam a2T Type of argument 2.
1282 /// \tparam a3T Type of argument 3.
1283 /// \tparam a4T Type of argument 4.
1284 /// \tparam a5T Type of argument 5.
1285 /// \tparam a6T Type of argument 6.
1286 /// \tparam a7T Type of argument 7.
1287 /// \tparam a8T Type of argument 8.
1288 /// \param dest Description needed.
1289 /// \param memfn Verify: The member function to be invoked for the task.
1290 /// \param a1 Argument 1.
1291 /// \param a2 Argument 2.
1292 /// \param a3 Argument 3.
1293 /// \param a4 Argument 4.
1294 /// \param a5 Argument 5.
1295 /// \param a6 Argument 6.
1296 /// \param a7 Argument 7.
1297 /// \param a8 Argument 8.
1298 /// \param attr Description needed.
1299 /// \return Description needed.
1300 template <typename memfnT, typename a1T, typename a2T, typename a3T,
1301 typename a4T, typename a5T, typename a6T, typename a7T, typename a8T>
1303 task(ProcessID dest, memfnT memfn, const a1T& a1, const a2T& a2,
1304 const a3T& a3, const a4T& a4, const a5T& a5, const a6T& a6,
1305 const a7T& a7, const a8T& a8,
1306 const TaskAttributes& attr = TaskAttributes()) const
1307 {
1309 typedef TaskFn<typename task_helper::wrapperT,
1317 typename detail::task_arg<a8T>::type> taskT;
1318 if (dest == me)
1319 return world.taskq.add(task_helper::make_task_fn(this, memfn),
1320 a1, a2, a3, a4, a5, a6, a7, a8, attr);
1321 else {
1322 return send_task<taskT>(dest, memfn, am_arg(a1), am_arg(a2),
1323 am_arg(a3), am_arg(a4), am_arg(a5), am_arg(a6),
1324 am_arg(a7), am_arg(a8), voidT::value, attr);
1325 }
1326 }
1327
1328 /// Sends task to derived class method `returnT (this->*memfn)(a1,a2,a3,a4,a5,a6,a7,a8,a9)`.
1329
1330 /// \todo Descriptions needed.
1331 /// \tparam memfnT Verify: Signature of the member function in the derived class to be invoked for the task.
1332 /// \tparam a1T Type of argument 1.
1333 /// \tparam a2T Type of argument 2.
1334 /// \tparam a3T Type of argument 3.
1335 /// \tparam a4T Type of argument 4.
1336 /// \tparam a5T Type of argument 5.
1337 /// \tparam a6T Type of argument 6.
1338 /// \tparam a7T Type of argument 7.
1339 /// \tparam a8T Type of argument 8.
1340 /// \tparam a9T Type of argument 9.
1341 /// \param dest Description needed.
1342 /// \param memfn Verify: The member function to be invoked for the task.
1343 /// \param a1 Argument 1.
1344 /// \param a2 Argument 2.
1345 /// \param a3 Argument 3.
1346 /// \param a4 Argument 4.
1347 /// \param a5 Argument 5.
1348 /// \param a6 Argument 6.
1349 /// \param a7 Argument 7.
1350 /// \param a8 Argument 8.
1351 /// \param a9 Argument 9.
1352 /// \param attr Description needed.
1353 /// \return Description needed.
1354 ///
1355 /// \todo Could we use variadic templates to eliminate a lot of this code duplication?
1356 template <typename memfnT, typename a1T, typename a2T, typename a3T,
1357 typename a4T, typename a5T, typename a6T, typename a7T, typename a8T,
1358 typename a9T>
1360 task(ProcessID dest, memfnT memfn, const a1T& a1, const a2T& a2,
1361 const a3T& a3, const a4T& a4, const a5T& a5, const a6T& a6,
1362 const a7T& a7, const a8T& a8, const a9T& a9,
1363 const TaskAttributes& attr = TaskAttributes()) const
1364 {
1366 typedef TaskFn<typename task_helper::wrapperT,
1375 typename detail::task_arg<a9T>::type> taskT;
1376 if (dest == me)
1377 return world.taskq.add(task_helper::make_task_fn(this, memfn),
1378 a1, a2, a3, a4, a5, a6, a7, a8, a9, attr);
1379 else
1380 return send_task<taskT>(dest, memfn, am_arg(a1), am_arg(a2),
1381 am_arg(a3), am_arg(a4), am_arg(a5), am_arg(a6),
1382 am_arg(a7), am_arg(a8), am_arg(a9), attr);
1383 }
1384
1385 virtual ~WorldObject() {
1386 if(initialized()) {
1387 MADNESS_ASSERT_NOEXCEPT(World::exists(&world) && world.ptr_from_id<Derived>(id()) && *world.ptr_from_id<Derived>(id()) == this);
1388 world.unregister_ptr(this->id());
1389 }
1390 }
1391
1392#ifdef MADNESS_WORLDOBJECT_FUTURE_TRACE
1393 /// "traces" future evaluation by counting their assignments in a static table
1394
1395 /// Counts future assignments in a a statically-sized table to make this as lightweight/lock-free as possible
1396 /// with minimal effort. Can only trace objects of a single World.
1397 /// \param[in,out] f the future to be traced; if ready, will be unchanged (but contribute to the trace
1398 /// statistics of this object), or have a callback registered that will update the tracing statistics on
1399 /// assignment
1400 /// \warning this function will trace futures for WorldObjects associated with default world (id=0) only;
1401 /// use CMake variable `MADNESS_WORLDOBJECT_FUTURE_TRACE_WORLD_ID` to adjust the target World ID.
1402 /// \warning this function will trace futures for WorldObjects with IDs < 1000000 only;
1403 /// use CMake variable `MADNESS_WORLDOBJECT_FUTURE_TRACE_MAX_NOBJECTS` to adjust the limit.
1404 template <typename T>
1405 std::enable_if_t<!std::is_same_v<T,void>,void> trace(Future<T>& f) const;
1406
1407 /// \param[in] id a WorldObject ID
1408 /// \return true if futures associated with \p id are traced
1409 static bool trace_futures(const uniqueidT &id);
1410
1411 /// \return true if futures associated with this object are traced
1412 bool trace_futures() const {
1413 return trace_futures(this->id());
1414 }
1415
1416 /// \param[in] id report tracing stats for this WorldObject
1417 /// \return number of futures given to trace() of the WorldObject with ID \p id
1418 static std::size_t trace_status_nfuture_registered(const uniqueidT& id);
1419
1420 /// \return number of futures given to trace() of this object
1421 std::size_t trace_status_nfuture_registered() const {
1422 return trace_status_nfuture_registered(this->id());
1423 }
1424
1425 /// \param[in] id report tracing stats for this WorldObject
1426 /// \return number of assigned futures given to trace() of the WorldObject with ID \p id
1427 static std::size_t trace_status_nfuture_assigned(const uniqueidT& id);
1428
1429 /// \return number of assigned futures registered via `this->trace()`
1430 std::size_t trace_status_nfuture_assigned() const {
1431 return trace_status_nfuture_assigned(this->id());
1432 }
1433#endif
1434 };
1435
1436#ifdef MADNESS_WORLDOBJECT_FUTURE_TRACE
1437 namespace detail {
1438 template <typename Derived> struct WorldObjectFutureTracer {
1439 // this value is the world ID to trace
1440 constexpr static std::size_t world_id =
1441#ifndef MADNESS_WORLDOBJECT_FUTURE_TRACE_WORLD_ID
1442 0
1443#else
1444 MADNESS_WORLDOBJECT_FUTURE_TRACE_WORLD_ID
1445#endif
1446 ;
1447 // this value is 1 greater than is the highest ID of WorldObjects to trace
1448 constexpr static std::size_t max_object_id =
1449#ifndef MADNESS_WORLDOBJECT_FUTURE_TRACE_MAX_NOBJECTS
1450 1000000
1451#else
1452 MADNESS_WORLDOBJECT_FUTURE_TRACE_MAX_NOBJECTS
1453#endif
1454 ;
1455
1456 static constexpr bool do_trace(const uniqueidT& id) {
1457 return id.get_world_id() == world_id &&
1458 id.get_obj_id() < max_object_id;
1459 }
1460
1461 static std::array<std::atomic<std::size_t>, max_object_id>
1462 nfuture_registered;
1463 static std::array<std::atomic<std::size_t>, max_object_id>
1464 nfuture_assigned;
1465
1466 struct Initializer {
1467 Initializer() {
1468 for (auto &&v : nfuture_registered) {
1469 v.store(0);
1470 }
1471 for (auto &&v : nfuture_assigned) {
1472 v.store(0);
1473 }
1474 }
1475 };
1476 static Initializer initializer;
1477
1478 struct FutureTracer : public CallbackInterface {
1479 FutureTracer(const uniqueidT &id) : id_(id) {
1480 if (do_trace(id_)) {
1481 nfuture_registered[id_.get_obj_id()]++;
1482 }
1483 }
1484
1485 // Not allowed
1486 FutureTracer(const FutureTracer &) = delete;
1487 FutureTracer &operator=(const FutureTracer &) = delete;
1488
1489 virtual ~FutureTracer() {}
1490
1491 /// Notify this object that the future has been set.
1492
1493 /// This will set the value of the future on the remote node and delete
1494 /// this callback object.
1495 void notify() override {
1496 if (do_trace(id_)) {
1497 nfuture_assigned[id_.get_obj_id()]++;
1498 }
1499 delete this;
1500 }
1501
1502 private:
1503 uniqueidT id_;
1504 }; // struct FutureTracer
1505
1506 }; // struct WorldObjectFutureTracer
1507 template <typename Derived>
1508 typename WorldObjectFutureTracer<Derived>::Initializer
1509 WorldObjectFutureTracer<Derived>::initializer;
1510 template <typename Derived>
1511 std::array<std::atomic<std::size_t>, WorldObjectFutureTracer<Derived>::max_object_id>
1512 WorldObjectFutureTracer<Derived>::nfuture_registered;
1513 template <typename Derived>
1514 std::array<std::atomic<std::size_t>, WorldObjectFutureTracer<Derived>::max_object_id>
1515 WorldObjectFutureTracer<Derived>::nfuture_assigned;
1516 } // namespace detail
1517
1518 template <typename Derived>
1519 template <typename T>
1520 std::enable_if_t<!std::is_same_v<T,void>,void> WorldObject<Derived>::trace(Future<T>& f) const {
1521 f.register_callback(
1522 new typename detail::WorldObjectFutureTracer<Derived>::FutureTracer(
1523 this->id()));
1524 }
1525
1526 template <typename Derived>
1527 bool WorldObject<Derived>::trace_futures(const uniqueidT& id) {
1528 return detail::WorldObjectFutureTracer<Derived>::do_trace(id);
1529 }
1530
1531 template <typename Derived>
1532 std::size_t WorldObject<Derived>::trace_status_nfuture_registered(const uniqueidT& id) {
1533 if (detail::WorldObjectFutureTracer<
1534 Derived>::do_trace(id)) {
1535 return detail::WorldObjectFutureTracer<
1536 Derived>::nfuture_registered[id.get_obj_id()];
1537 }
1538 else return 0;
1539 }
1540
1541 template <typename Derived>
1542 std::size_t WorldObject<Derived>::trace_status_nfuture_assigned(const uniqueidT& id) {
1543 if (detail::WorldObjectFutureTracer<
1544 Derived>::do_trace(id)) {
1545 return detail::WorldObjectFutureTracer<
1546 Derived>::nfuture_assigned[id.get_obj_id()];
1547 }
1548 else return 0;
1549 }
1550
1551#endif // MADNESS_WORLDOBJECT_FUTURE_TRACE
1552
1553 namespace archive {
1554
1555 /// Specialization of \c ArchiveLoadImpl for globally-addressable objects.
1556
1557 /// \tparam Derived The derived class of \c WorldObject in a curiously
1558 /// repeating template pattern.
1559 template <class Derived>
1561
1562 /// Read a globally-addressable object from a \c BufferInputArchive.
1563
1564 /// \param[in,out] ar The archive.
1565 /// \param[out] ptr The read object.
1566 static inline void load(const BufferInputArchive& ar, WorldObject<Derived>*& ptr) {
1567 uniqueidT id;
1568 ar & id;
1569 World* world = World::world_from_id(id.get_world_id());
1570 MADNESS_ASSERT(world);
1571 auto ptr_opt = world->ptr_from_id< WorldObject<Derived> >(id);
1572 if (!ptr_opt) MADNESS_EXCEPTION("WorldObj: remote operation attempting to use a locally uninitialized object",0);
1573 ptr = *ptr_opt;
1574 if (!ptr) MADNESS_EXCEPTION("WorldObj: remote operation attempting to use a locally deregistered object",0);
1575 }
1576 };
1577
1578 /// Specialization of \c ArchiveStoreImpl for globally-addressable objects.
1579
1580 /// \tparam Derived The derived class of \c WorldObject in a curiously
1581 /// repeating template pattern.
1582 template <class Derived>
1584
1585 /// Write a globally-addressable object to a \c BufferOutputArchive.
1586
1587 /// \param[in,out] ar The archive.
1588 /// \param[in] ptr The object to store.
1589 static inline void store(const BufferOutputArchive& ar, WorldObject<Derived>* const& ptr) {
1590 ar & ptr->id();
1591 }
1592 };
1593
1594 /// Specialization of \c ArchiveLoadImpl for constant, globally-addressable objects.
1595
1596 /// \tparam Derived The derived class of \c WorldObject in a curiously
1597 /// repeating template pattern.
1598 template <class Derived>
1600
1601 /// Read a globally-addressable object from a \c BufferInputArchive.
1602
1603 /// \param[in,out] ar The archive.
1604 /// \param[out] ptr The read object.
1605 static inline void load(const BufferInputArchive& ar, const WorldObject<Derived>*& ptr) {
1606 uniqueidT id;
1607 ar & id;
1608 World* world = World::world_from_id(id.get_world_id());
1609 MADNESS_ASSERT(world);
1610 auto ptr_opt = world->ptr_from_id< WorldObject<Derived> >(id);
1611 if (!ptr_opt) MADNESS_EXCEPTION("WorldObj: remote operation attempting to use a locally uninitialized object",0);
1612 ptr = *ptr_opt;
1613 if (!ptr) MADNESS_EXCEPTION("WorldObj: remote operation attempting to use a locally deregistered object",0);
1614 }
1615 };
1616
1617 /// Specialization of \c ArchiveStoreImpl for constant, globally-addressable objects.
1618
1619 /// \tparam Derived The derived class of \c WorldObject in a curiously
1620 /// repeating template pattern.
1621 template <class Derived>
1623
1624 /// Write a globally-addressable object to a \c BufferOutputArchive.
1625
1626 /// \param[in,out] ar The archive.
1627 /// \param[in] ptr The object to store.
1628 static inline void store(const BufferOutputArchive& ar, const WorldObject<Derived>* const& ptr) {
1629 ar & ptr->id();
1630 }
1631 };
1632 } // namespace archive
1633} // namespace madness
1634
1635#endif // MADNESS_WORLD_WORLD_OBJECT_H__INCLUDED
1636
1637/// @}
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:736
static const Future< void > value
Definition future.h:742
A future is a possibly yet unevaluated value.
Definition future.h:373
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:323
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:364
World & get_world() const
Returns a reference to the world.
Definition world_object.h:717
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:1207
WorldObject(World &world)
Constructor that associates an object (via the derived class) with a globally unique ID.
Definition world_object.h:703
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:947
static const T & am_arg(const T &t)
Definition world_object.h:549
static bool is_ready(const uniqueidT &id, objT *&obj, const AmArg &arg, am_handlerT ptr)
Definition world_object.h:411
static Spinlock pending_mutex
Definition world_object.h:389
detail::task_result_type< memfnT >::futureT send(ProcessID dest, memfnT memfn, const a1T &a1) const
Definition world_object.h:749
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:986
WorldObject< Derived > objT
Definition world_object.h:367
WorldObject(const WorldObject &other)
Definition world_object.h:370
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:1164
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:1057
World & world
The World this object belongs to. (Think globally, act locally).
Definition world_object.h:381
std::list< detail::PendingMsg > pendingT
Definition world_object.h:376
const uniqueidT & id() const
Returns the globally unique object ID.
Definition world_object.h:711
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:1125
detail::task_result_type< memfnT >::futureT send(ProcessID dest, memfnT memfn, const a1T &a1, const a2T &a2) const
Definition world_object.h:769
void process_pending()
To be called from derived constructor to process pending messages.
Definition world_object.h:656
WorldObject & operator=(const WorldObject &)=delete
static void spawn_remote_task_handler(const AmArg &arg)
Handler for remote arguments.
Definition world_object.h:505
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:791
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:911
ProcessID me
Rank of self.
Definition world_object.h:385
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:1303
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:1254
detail::task_result_type< memfnT >::futureT send(ProcessID dest, memfnT memfn) const
Definition world_object.h:731
volatile bool ready
True if ready to rock 'n roll.
Definition world_object.h:384
virtual ~WorldObject()
Definition world_object.h:1385
detail::voidT voidT
Definition world_object.h:379
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:633
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:1028
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:1089
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:818
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:583
uniqueidT objid
Sense of self.
Definition world_object.h:386
static const T & am_arg(const Future< T > &f)
Definition world_object.h:536
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:878
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:847
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:1360
static volatile pendingT pending
Buffer for pending messages.
Definition world_object.h:390
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:1005
static void handler(const AmArg &arg)
Handler for an incoming AM.
Definition world_object.h:471
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:474
WorldTaskQueue & taskq
Task queue.
Definition world.h:204
void unregister_ptr(const uniqueidT id)
Unregister a global object via its the unique ID.
Definition world.h:387
static bool exists(World *world)
Check if the World exists in the registry.
Definition world.h:247
std::optional< T * > ptr_from_id(uniqueidT id) const
Look up a local pointer from a world-wide unique ID.
Definition world.h:414
WorldAmInterface & am
AM interface.
Definition world.h:203
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:34
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:925
auto to_rel_memfn_ptr(const T &fn)
converts nonstatic member function pointer to the relative equivalent
Definition archive.h:259
Tensor< typename Tensor< T >::scalar_type > arg(const Tensor< T > &t)
Return a new tensor holding the argument of each element of t (complex types only)
Definition tensor.h:2502
static 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
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:113
void free_am_arg(AmArg *arg)
Frees an AmArg allocated with alloc_am_arg.
Definition worldam.h:177
NDIM & f
Definition mra.h:2416
void(* am_handlerT)(const AmArg &)
Type of AM handler functions.
Definition worldam.h:77
std::string type(const PairType &n)
Definition PNOParameters.h:18
Definition mraimpl.h:50
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
static void load(const BufferInputArchive &ar, WorldObject< Derived > *&ptr)
Read a globally-addressable object from a BufferInputArchive.
Definition world_object.h:1566
static void load(const BufferInputArchive &ar, const WorldObject< Derived > *&ptr)
Read a globally-addressable object from a BufferInputArchive.
Definition world_object.h:1605
Default load of an object via serialize(ar, t).
Definition archive.h:666
static void store(const BufferOutputArchive &ar, WorldObject< Derived > *const &ptr)
Write a globally-addressable object to a BufferOutputArchive.
Definition world_object.h:1589
static void store(const BufferOutputArchive &ar, const WorldObject< Derived > *const &ptr)
Write a globally-addressable object to a BufferOutputArchive.
Definition world_object.h:1628
Default store of an object via serialize(ar, t).
Definition archive.h:611
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
Future< resultT > futureT
Definition taskfn.h:244
Implements Dqueue, Thread, ThreadBase and ThreadPool.
#define REMFUTURE(T)
Macro to determine type of future (by removing wrapping Future template).
Definition type_traits.h:162
#define MEMFUN_RETURNT(MEMFUN)
Macro to make member function type traits easier to use.
Definition type_traits.h:704
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