36 #ifndef MADNESS_WORLD_WORLDGOP_H__INCLUDED
37 #define MADNESS_WORLD_WORLDGOP_H__INCLUDED
58 class WorldAmInterface;
62 class DeferredCleanup;
101 template <
typename T>
108 template <
typename T>
115 template <
typename T>
122 template <
typename T>
129 template <
typename T>
136 template <
typename T>
156 struct PointToPointTag { };
157 struct LazySyncTag { };
158 struct GroupLazySyncTag { };
160 struct GroupBcastTag { };
161 struct ReduceTag { };
162 struct GroupReduceTag { };
163 struct AllReduceTag { };
164 struct GroupAllReduceTag { };
173 template <
typename keyT,
typename valueT>
174 class DelayedSend :
public CallbackInterface {
179 Future<valueT> value_;
182 DelayedSend(
const DelayedSend<keyT, valueT>&);
183 DelayedSend<keyT, valueT>& operator=(
const DelayedSend<keyT, valueT>&);
191 DelayedSend(World& world,
const ProcessID dest,
192 const keyT& key,
const Future<valueT>& value) :
193 world_(world), dest_(dest), key_(key), value_(value)
196 virtual ~DelayedSend() { }
202 virtual void notify() {
203 MADNESS_ASSERT(value_.probe());
204 world_.gop.send_internal(dest_, key_, value_.get());
214 template <
typename valueT,
typename keyT>
215 static Future<valueT> recv_internal(
const keyT& key) {
216 return detail::DistCache<keyT>::template get_cache_value<valueT>(key);
227 template <
typename keyT,
typename valueT>
228 typename disable_if<is_future<valueT> >::type
229 send_internal(
const ProcessID dest,
const keyT& key,
const valueT& value)
const {
230 typedef detail::DistCache<keyT> dist_cache;
232 if(world_.rank() == dest) {
234 dist_cache::set_cache_value(key, value);
237 world_.taskq.add(dest, dist_cache::template set_cache_value<valueT>, key,
251 template <
typename keyT,
typename valueT>
252 void send_internal(
ProcessID dest,
const keyT& key,
const Future<valueT>& value)
const {
253 typedef detail::DistCache<keyT> dist_cache;
255 if(world_.rank() == dest) {
256 dist_cache::set_cache_value(key, value);
261 world_.taskq.add(dest, dist_cache::template set_cache_value<valueT>, key,
266 DelayedSend<keyT, valueT>* delayed_send_callback =
267 new DelayedSend<keyT, valueT>(world_, dest, key, value);
268 const_cast<Future<valueT>&
>(value).register_callback(delayed_send_callback);
281 template <
typename keyT>
282 void lazy_sync_parent(
const ProcessID parent,
const keyT& key,
285 send_internal(parent, key, key.proc());
299 template <
typename keyT,
typename opT>
305 send_internal(child0, key, 1);
307 send_internal(child1, key, 1);
317 template <
typename tagT,
typename keyT,
typename opT>
319 const ProcessID child1,
const keyT& key,
const opT& op)
const {
320 typedef ProcessKey<keyT, tagT> key_type;
324 recv_internal<ProcessID>(key_type(key, child0)) :
327 recv_internal<ProcessID>(key_type(key, child1)) :
330 recv_internal<ProcessID>(key_type(key, parent)) :
334 key_type my_key(key, world_.rank());
336 const key_type&, opT&,
const ProcessID)
const;
337 world_.taskq.add(*
this, lazy_sync_childrenT(& WorldGopInterface::template lazy_sync_children<key_type, opT>),
338 child0_signal, child1_signal, my_key, op, parent_signal,
343 if(child0_signal.
probe() && child1_signal.
probe())
344 send_internal(parent, my_key, world_.rank());
348 world_.taskq.add(*
this, lazy_sync_parentT(& WorldGopInterface::template lazy_sync_parent<key_type>),
349 parent, my_key, child0_signal, child1_signal,
356 template <
typename keyT,
typename valueT,
typename taskfnT>
357 static void bcast_handler(
const AmArg&
arg) {
364 arg & taskfn & key & value &
root;
367 arg.get_world()->taskq.add(arg.get_world()->gop, taskfn, key,
371 template <
typename keyT,
typename valueT,
typename taskfnT>
372 static void group_bcast_handler(
const AmArg& arg) {
377 ProcessID group_root;
380 arg & taskfn & key & value & group_root & group_key;
386 arg.get_world()->taskq.add(arg.get_world()->gop, taskfn, key, value,
395 template <
typename keyT,
typename valueT>
396 void bcast_task(
const keyT& key,
const valueT& value,
const ProcessID root)
const {
401 ProcessID parent = -1, child0 = -1, child1 = -1;
402 world_.mpi.binary_tree_info(root, parent, child0, child1);
409 const bool send0 = (child0 != -1);
410 const bool send1 = (child1 != -1);
416 void (*handler)(
const AmArg&) =
417 & WorldGopInterface::template bcast_handler<keyT, valueT, taskfnT>;
419 & WorldGopInterface::template bcast_task<keyT, valueT>,
432 template <
typename keyT,
typename valueT>
433 void group_bcast_task(
const keyT& key,
const valueT& value,
434 const ProcessID group_root,
const Group& group)
const
440 ProcessID parent = -1, child0 = -1, child1 = -1;
441 group.make_tree(group_root, parent, child0, child1);
446 group.remote_update();
450 const bool send0 = (child0 != -1);
451 const bool send1 = (child1 != -1);
456 void (*handler)(
const AmArg&) =
457 & WorldGopInterface::template group_bcast_handler<keyT, valueT, taskfnT>;
459 & WorldGopInterface::template group_bcast_task<keyT, valueT>,
460 key, value, group_root, group.id());
484 template <
typename tagT,
typename keyT,
typename valueT>
485 void bcast_internal(
const keyT& key, Future<valueT>& value,
const ProcessID root)
const {
486 MADNESS_ASSERT((root >= 0) && (root < world_.size()));
487 MADNESS_ASSERT((world_.rank() ==
root) || (! value.probe()));
490 typedef TaggedKey<keyT, tagT> key_type;
491 const key_type tagged_key(key);
493 if(world_.size() > 1) {
494 if(world_.rank() ==
root) {
501 bcast_task(tagged_key, value.get(),
root);
506 const valueT&,
const ProcessID
root)
const;
507 world_.taskq.add(*
this, bcast_taskT(& WorldGopInterface::template bcast_task<key_type, valueT>),
511 MADNESS_ASSERT(! value.probe());
535 template <
typename tagT,
typename keyT,
typename valueT>
536 void bcast_internal(
const keyT& key, Future<valueT>& value,
537 const ProcessID group_root,
const Group& group)
const
540 typedef TaggedKey<keyT, tagT> key_type;
541 const key_type tagged_key(key);
543 if(group.rank() == group_root) {
546 group_bcast_task(tagged_key, value.get(), group_root, group);
548 typedef void (
WorldGopInterface::*group_bcast_taskT)(
const key_type&,
const valueT&,
550 world_.taskq.add(
this, group_bcast_taskT(& WorldGopInterface::template group_bcast_task<key_type, valueT>),
551 tagged_key, value, group_root, group,
555 MADNESS_ASSERT(! value.probe());
561 group.local_update();
565 template <
typename valueT,
typename opT>
566 static typename detail::result_of<opT>::type
567 reduce_task(
const valueT& value,
const opT& op) {
568 typename detail::result_of<opT>::type result =
op();
573 template <
typename opT>
574 static typename detail::result_of<opT>::type
575 reduce_result_task(
const std::vector<Future<
typename detail::result_of<opT>::type> >& results,
578 MADNESS_ASSERT(results.size() != 0ul);
579 Future<typename detail::result_of<opT>::type> result = results.front();
580 for(std::size_t i = 1ul; i < results.size(); ++i)
581 op(result.get(), results[i].get());
597 template <
typename tagT,
typename keyT,
typename valueT,
typename opT>
598 Future<typename detail::result_of<opT>::type>
599 reduce_internal(
const ProcessID parent,
const ProcessID child0,
600 const ProcessID child1,
const ProcessID root,
const keyT& key,
601 const valueT& value,
const opT& op)
604 typedef ProcessKey<keyT, tagT> key_type;
605 typedef typename detail::result_of<opT>::type result_type;
606 typedef typename remove_future<valueT>::type
value_type;
607 std::vector<Future<result_type> > results;
611 results.push_back(world_.taskq.add(WorldGopInterface::template reduce_task<valueT, opT>,
616 results.push_back(recv_internal<result_type>(key_type(key, child0)));
618 results.push_back(recv_internal<result_type>(key_type(key, child1)));
621 Future<result_type> local_result =
622 world_.taskq.add(WorldGopInterface::template reduce_result_task<opT>,
630 send_internal(parent, key_type(key, world_.rank()), local_result);
640 world_(world), deferred_(new detail::DeferredCleanup()), debug_(false)
651 bool status = debug_;
658 long i = world_.rank();
660 if (i != world_.size()*(world_.size()-1)/2)
error(
"bad value after sum in barrier");
679 void broadcast(
void* buf,
size_t nbyte, ProcessID root,
bool dowork =
true);
685 template <
typename T>
686 inline void broadcast(
T* buf,
size_t nelem, ProcessID root) {
687 broadcast((
void *) buf, nelem*
sizeof(
T), root);
691 template <
typename T>
697 template <
typename T>
706 template <
typename objT>
709 if (world_.rank() ==
root) {
712 BUFLEN = count.
size();
716 unsigned char* buf =
new unsigned char[BUFLEN];
717 if (world_.rank() ==
root) {
722 if (world_.rank() !=
root) {
732 template <
typename T,
class opT>
735 ProcessID parent, child0, child1;
736 world_.mpi.binary_tree_info(0, parent, child0, child1);
737 Tag gsum_tag = world_.mpi.unique_tag();
739 T* buf0 =
new T[nelem];
740 T* buf1 =
new T[nelem];
742 if (child0 != -1) req0 = world_.mpi.Irecv(buf0, nelem*
sizeof(
T),
MPI_BYTE, child0, gsum_tag);
743 if (child1 != -1) req1 = world_.mpi.Irecv(buf1, nelem*
sizeof(
T),
MPI_BYTE, child1, gsum_tag);
747 for (
long i=0; i<(long)nelem; ++i) buf[i] =
op(buf[i],buf0[i]);
751 for (
long i=0; i<(long)nelem; ++i) buf[i] =
op(buf[i],buf1[i]);
758 req0 = world_.mpi.Isend(buf, nelem*
sizeof(
T),
MPI_BYTE, parent, gsum_tag);
766 template <
typename T>
767 inline void sum(
T* buf,
size_t nelem) {
772 template <
typename T>
773 inline void min(
T* buf,
size_t nelem) {
778 template <
typename T>
779 inline void max(
T* buf,
size_t nelem) {
784 template <
typename T>
790 template <
typename T>
796 template <
typename T>
801 template <
typename T>
806 template <
typename T>
811 template <
typename T>
816 template <
typename T>
821 template <
typename T>
827 template <
typename T>
833 template <
typename T>
839 template <
typename T>
845 template <
typename T>
846 std::vector<T>
concat0(
const std::vector<T>& v,
size_t bufsz=1024*1024) {
848 ProcessID parent, child0, child1;
849 world_.mpi.binary_tree_info(0, parent, child0, child1);
850 Tag gsum_tag = world_.mpi.unique_tag();
852 unsigned char* buf0 =
new unsigned char[bufsz];
853 unsigned char* buf1 =
new unsigned char[bufsz];
855 if (child0 != -1) req0 = world_.mpi.Irecv(buf0, bufsz,
MPI_BYTE, child0, gsum_tag);
856 if (child1 != -1) req1 = world_.mpi.Irecv(buf1, bufsz,
MPI_BYTE, child1, gsum_tag);
858 std::vector<T> left, right;
868 for (
unsigned int i=0; i<right.size(); ++i) left.push_back(right[i]);
871 for (
unsigned int i=0; i<v.size(); ++i) left.push_back(v[i]);
876 req0 = world_.mpi.Isend(buf0, ar.
size(),
MPI_BYTE, parent, gsum_tag);
883 if (parent == -1)
return left;
884 else return std::vector<T>();
897 template <
typename valueT,
typename keyT>
912 template <
typename keyT,
typename valueT>
913 void send(
const ProcessID dest,
const keyT& key,
const valueT& value)
const {
944 template <
typename keyT,
typename opT>
946 if(world_.size() > 1) {
949 const ProcessID root = hasher(key) % world_.size();
950 ProcessID parent = -1, child0 = -1, child1 = -1;
951 world_.mpi.binary_tree_info(root, parent, child0, child1);
953 lazy_sync_internal<LazySyncTag>(parent, child0, child1, key,
op);
956 const keyT&, opT&,
const ProcessID)
const;
958 world_.taskq.add(*
this, lazy_sync_childrenT(& WorldGopInterface::template lazy_sync_children<keyT, opT>),
991 template <
typename keyT,
typename opT>
993 MADNESS_ASSERT(! group.
empty());
994 MADNESS_ASSERT(group.
get_world().
id() == world_.id());
996 if(group.
size() > 1) {
999 const ProcessID group_root = hasher(key) % group.
size();
1000 ProcessID parent = -1, child0 = -1, child1 = -1;
1001 group.
make_tree(group_root, parent, child0, child1);
1003 lazy_sync_internal<GroupLazySyncTag>(parent, child0, child1, key,
op);
1006 const keyT&, opT&,
const ProcessID)
const;
1007 world_.taskq.add(*
this, lazy_sync_children(& WorldGopInterface::template lazy_sync_children<keyT, opT>),
1028 template <
typename keyT,
typename valueT>
1030 MADNESS_ASSERT((root >= 0) && (root < world_.size()));
1031 MADNESS_ASSERT((world_.rank() ==
root) || (! value.
probe()));
1033 if(world_.size() > 1)
1034 bcast_internal<BcastTag>(key, value, root);
1060 template <
typename keyT,
typename valueT>
1062 const ProcessID group_root,
const Group& group)
const
1064 MADNESS_ASSERT(! group.
empty());
1065 MADNESS_ASSERT(group.
get_world().
id() == world_.id());
1066 MADNESS_ASSERT((group_root >= 0) && (group_root < group.
size()));
1067 MADNESS_ASSERT((group.
rank() == group_root) || (! value.
probe()));
1069 if(group.
size() > 1)
1070 bcast_internal<GroupBcastTag>(key, value, group_root, group);
1108 template <
typename keyT,
typename valueT,
typename opT>
1110 reduce(
const keyT& key,
const valueT& value,
const opT& op,
const ProcessID root) {
1111 MADNESS_ASSERT((root >= 0) && (root < world_.size()));
1114 ProcessID parent = -1, child0 = -1, child1 = -1;
1115 world_.mpi.binary_tree_info(root, parent, child0, child1);
1117 return reduce_internal<ReduceTag>(parent, child0, child1,
root, key,
1164 template <
typename keyT,
typename valueT,
typename opT>
1166 reduce(
const keyT& key,
const valueT& value,
const opT& op,
1167 const ProcessID group_root,
const Group& group)
1169 MADNESS_ASSERT(! group.
empty());
1170 MADNESS_ASSERT(group.
get_world().
id() == world_.id());
1171 MADNESS_ASSERT((group_root >= 0) && (group_root < group.
size()));
1174 ProcessID parent = -1, child0 = -1, child1 = -1;
1175 group.
make_tree(group_root, parent, child0, child1);
1177 return reduce_internal<ReduceTag>(parent, child0, child1, group_root,
1216 template <
typename keyT,
typename valueT,
typename opT>
1218 all_reduce(
const keyT& key,
const valueT& value,
const opT& op) {
1221 const ProcessID root = hasher(key) % world_.size();
1222 ProcessID parent = -1, child0 = -1, child1 = -1;
1223 world_.mpi.binary_tree_info(root, parent, child0, child1);
1227 reduce_internal<AllReduceTag>(parent, child0, child1,
root,
1230 if(world_.rank() !=
root)
1231 reduce_result =
Future<
typename detail::result_of<opT>::type>();
1234 bcast_internal<AllReduceTag>(key, reduce_result,
root);
1236 return reduce_result;
1280 template <
typename keyT,
typename valueT,
typename opT>
1283 MADNESS_ASSERT(! group.
empty());
1284 MADNESS_ASSERT(group.
get_world().
id() == world_.id());
1288 const ProcessID group_root = hasher(key) % group.
size();
1289 ProcessID parent = -1, child0 = -1, child1 = -1;
1290 group.
make_tree(group_root, parent, child0, child1);
1294 reduce_internal<GroupAllReduceTag>(parent, child0, child1,
1295 group_root, key, value,
op);
1298 if(group.
rank() != group_root)
1299 reduce_result =
Future<
typename detail::result_of<opT>::type>();
1302 bcast_internal<GroupAllReduceTag>(key, reduce_result, 0, group);
1304 return reduce_result;
1310 #endif // MADNESS_WORLD_WORLDGOP_H__INCLUDED
T operator()(const T &a, const T &b) const
Definition: worldgop.h:131
void error(const char *msg)
Definition: world.cc:128
static void await(SafeMPI::Request &request, bool dowork=true)
Wait for MPI request to complete.
Definition: worldfwd.h:650
Future< typename detail::result_of< opT >::type > all_reduce(const keyT &key, const valueT &value, const opT &op)
Distributed all reduce.
Definition: worldgop.h:1218
static TaskAttributes hipri()
Definition: worldthread.h:277
Definition: worldgop.h:109
WorldGopInterface(World &world)
Definition: worldgop.h:639
Future< typename detail::result_of< opT >::type > all_reduce(const keyT &key, const valueT &value, const opT &op, const Group &group)
Distributed, group all reduce.
Definition: worldgop.h:1282
void min(T &a)
Global min of a scalar while still processing AM & tasks.
Definition: worldgop.h:840
AmArg * new_am_arg(const A &a, const B &b, const C &c, const D &d, const E &e, const F &f, const G &g, const H &h, const I &i, const J &j)
Convenience template for serializing arguments into a new AmArg.
Definition: worldam.h:185
bool probe() const
Query the whether this future has been assigned.
Definition: worldfut.h:527
void min(T *buf, size_t nelem)
Inplace global min while still processing AM & tasks.
Definition: worldgop.h:773
Definition: worldgop.h:88
unsigned long id() const
Returns the system-wide unique integer ID of this world.
Definition: worldfwd.h:523
Definition: worldgop.h:116
Implements an archive wrapping a memory buffer.
int Tag
Used to clearly identify message tag/type.
Definition: worldtypes.h:38
void absmin(T *buf, size_t nelem)
Inplace global absmin while still processing AM & tasks.
Definition: worldgop.h:785
Definition: worldgop.h:102
void bit_and(T *buf, size_t nelem)
Definition: worldgop.h:802
Definition: worldgop.h:81
Definition: worldgop.h:67
ProcessID rank() const
Group rank accessor.
Definition: group.h:415
static void get_cache_value(const keyT &key, madness::Future< valueT > &value)
Get the cache value accosted with key.
Definition: dist_cache.h:188
#define MPI_BYTE
Definition: stubmpi.h:66
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:2429
void bit_xor(T *buf, size_t nelem)
Definition: worldgop.h:812
std::size_t size() const
Definition: bufar.h:97
void sum(T &a)
Global sum of a scalar while still processing AM & tasks.
Definition: worldgop.h:828
Definition: worldgop.h:95
void bcast(const keyT &key, Future< valueT > &value, const ProcessID root) const
Broadcast.
Definition: worldgop.h:1029
bool empty() const
Quary empty group.
Definition: group.h:394
Deferred cleanup of shared_ptr's.
Definition: deferred_cleanup.h:57
Key object that included the process information.
Definition: dist_keys.h:71
T operator()(const T &a, const T &b) const
Definition: worldgop.h:110
Wraps an archive around a memory buffer for output.
Definition: bufar.h:58
T operator()(const T &a, const T &b) const
Definition: worldgop.h:96
void bit_or(T *buf, size_t nelem)
Definition: worldgop.h:807
Provides collectives that interoperate with the AM and task interfaces.
Definition: worldgop.h:147
void max(T *buf, size_t nelem)
Inplace global max while still processing AM & tasks.
Definition: worldgop.h:779
void broadcast_serializable(objT &obj, ProcessID root)
Broadcast a serializable object.
Definition: worldgop.h:707
const T1 &f1 return GTEST_2_TUPLE_() T(f0, f1)
T operator()(const T &a, const T &b) const
Definition: worldgop.h:89
Definition: worldgop.h:130
MUP_BASETYPE value_type
The numeric datatype used by the parser.
Definition: muParserDef.h:222
FLOAT a(int j, FLOAT z)
Definition: y1.cc:86
void product(T *buf, size_t nelem)
Inplace global product while still processing AM & tasks.
Definition: worldgop.h:797
void destroy(bool mode)
Set the destruction mode.
Definition: deferred_cleanup.cc:41
T operator()(const T &a, const T &b) const
Definition: worldgop.h:138
static const attrT ATTR_ORDERED
Definition: worldrmi.h:139
Future< typename detail::result_of< opT >::type > reduce(const keyT &key, const valueT &value, const opT &op, const ProcessID root)
Distributed reduce.
Definition: worldgop.h:1110
ProcessID size() const
Group size accessor.
Definition: group.h:432
T operator()(const T &a, const T &b) const
Definition: worldgop.h:68
void broadcast(T *buf, size_t nelem, ProcessID root)
Broadcasts typed contiguous data from process root while still processing AM & tasks.
Definition: worldgop.h:686
World & get_world() const
Parent world accessor.
Definition: group.h:407
void sum(T *buf, size_t nelem)
Inplace global sum while still processing AM & tasks.
Definition: worldgop.h:767
void send(const ProcessID dest, const keyT &key, const valueT &value) const
Send value to dest.
Definition: worldgop.h:913
A parallel world with full functionality wrapping an MPI communicator.
Definition: worldfwd.h:416
void fence()
Synchronizes all processes in communicator AND globally ensures no pending AM or tasks.
Definition: worldgop.cc:52
void make_tree(const ProcessID group_root, ProcessID &parent, ProcessID &child1, ProcessID &child2) const
Compute the binary tree parents and children.
Definition: group.h:452
void lazy_sync(const keyT &key, const opT &op, const Group &group) const
Group lazy sync.
Definition: worldgop.h:992
T operator()(const T &a, const T &b) const
Definition: worldgop.h:117
static const Future< T > default_initializer()
See Gotchas on the documentation mainpage about why this exists and how to use it.
Definition: worldfut.h:439
int ProcessID
Used to clearly identify process number/rank.
Definition: worldtypes.h:37
void barrier()
Synchronizes all processes in communicator ... does NOT fence pending AM or tasks.
Definition: worldgop.h:657
bool set_debug(bool value)
Set debug flag to new value and return old value.
Definition: worldgop.h:650
std::pair< uniqueidT, std::size_t > DistributedID
Distributed ID which is used to identify objects.
Definition: dist_keys.h:44
static Future< valueT > recv(const ProcessID source, const keyT &key)
Receive data from source.
Definition: worldgop.h:898
void do_cleanup()
Deletes/frees any pointers that are in the list.
Definition: deferred_cleanup.cc:62
Definition: safempi.h:243
double abs(double x)
Definition: complexfun.h:48
T operator()(const T &a, const T &b) const
Definition: worldgop.h:82
void reduce(T *buf, size_t nelem, opT op)
Inplace global reduction (like MPI all_reduce) while still processing AM & tasks. ...
Definition: worldgop.h:733
void bcast(const keyT &key, Future< valueT > &value, const ProcessID group_root, const Group &group) const
Group broadcast.
Definition: worldgop.h:1061
std::vector< T > concat0(const std::vector< T > &v, size_t bufsz=1024 *1024)
Concatenate an STL vector of serializable stuff onto node 0.
Definition: worldgop.h:846
static madness::Future< Group > get_group(const DistributedID &did)
Get group from the registry.
Definition: group.cc:89
A collection of processes.
Definition: group.h:52
static void set_cache_value(const keyT &key, const valueT &value)
Set the cache value accosted with key.
Definition: dist_cache.h:149
Defines TaskInterface and implements WorldTaskQueue and associated stuff.
void broadcast(void *buf, size_t nbyte, ProcessID root, bool dowork=true)
Broadcasts bytes from process root while still processing AM & tasks.
Definition: worldgop.cc:145
Definition: worldgop.h:123
A future is a possibly yet unevaluated value.
Definition: ref.h:210
Definition: worldgop.h:137
Tensor< double > op(const Tensor< double > &x)
Definition: kain.cc:508
void logic_and(T *buf, size_t nelem)
Definition: worldgop.h:817
T operator()(const T &a, const T &b) const
Definition: worldgop.h:103
void absmax(T *buf, size_t nelem)
Inplace global absmax while still processing AM & tasks.
Definition: worldgop.h:791
void broadcast(T &t)
Broadcast of a scalar from node 0 to all other nodes.
Definition: worldgop.h:692
void broadcast(T &t, ProcessID root)
Broadcast of a scalar from node root to all other nodes.
Definition: worldgop.h:698
void logic_or(T *buf, size_t nelem)
Definition: worldgop.h:822
T operator()(const T &a, const T &b) const
Definition: worldgop.h:124
Holds machinery to set up Functions/FuncImpls using various Factories and Interfaces.
Definition: chem/atomutil.cc:45
~WorldGopInterface()
Definition: worldgop.h:643
T operator()(const T &a, const T &b) const
Definition: worldgop.h:75
Definition: worldgop.h:74
FLOAT b(int j, FLOAT z)
Definition: y1.cc:79
Hash functor.
Definition: shared_ptr_bits.h:32
const mpreal root(const mpreal &v, unsigned long int k, mp_rnd_t rnd_mode)
Definition: mpreal.h:2180
Future< typename detail::result_of< opT >::type > reduce(const keyT &key, const valueT &value, const opT &op, const ProcessID group_root, const Group &group)
Distributed group reduce.
Definition: worldgop.h:1166
void max(T &a)
Global max of a scalar while still processing AM & tasks.
Definition: worldgop.h:834
void lazy_sync(const keyT &key, const opT &op) const
Lazy sync.
Definition: worldgop.h:945