MADNESS 0.10.1
cloud.h
Go to the documentation of this file.
1
2/**
3 \file cloud.h
4 \brief Declares the \c Cloud class for storing data and transfering them between worlds
5 \ingroup world
6
7*/
8
9/**
10 * TODO: - delete container record upon caching if container is replicated
11 */
12
13#ifndef SRC_MADNESS_WORLD_CLOUD_H_
14#define SRC_MADNESS_WORLD_CLOUD_H_
15
16
18#include<any>
19#include<iomanip>
20
21
22/*!
23 \file cloud.h
24 \brief Defines and implements most of madness cloud storage
25
26 TODO: check use of preprocessor directives
27 TODO: clear cache in destructor won't work because no subworld is present -> must be explicitly called, error prone/
28*/
29
30namespace madness {
31
32 /// \brief A utility to get the name of a type as a string from chatGPT
33 template<typename T>
34 struct type_name {
35 static const char* value() { return typeid(T).name();}
36 };
37
38 template<>
39 struct type_name<Function<double,1>> { static const char* value() { return "Function<double,1>"; } };
40 template<>
41 struct type_name<Function<double,2>> { static const char* value() { return "Function<double,2>"; } };
42 template<>
43 struct type_name<Function<double,3>> { static const char* value() { return "Function<double,3>"; } };
44 template<>
45 struct type_name<Function<double,4>> { static const char* value() { return "Function<double,4>"; } };
46 template<>
47 struct type_name<Function<double,5>> { static const char* value() { return "Function<double,5>"; } };
48 template<>
49 struct type_name<Function<double,6>> { static const char* value() { return "Function<double,6>"; } };
50
51 template<>
52 struct type_name<std::vector<Function<double,1>>> { static const char* value() { return "std::vector<Function<double,1>>"; } };
53 template<>
54 struct type_name<std::vector<Function<double,2>>> { static const char* value() { return "std::vector<Function<double,2>>"; } };
55 template<>
56 struct type_name<std::vector<Function<double,3>>> { static const char* value() { return "std::vector<Function<double,3>>"; } };
57 template<>
58 struct type_name<std::vector<Function<double,4>>> { static const char* value() { return "std::vector<Function<double,4>>"; } };
59 template<>
60 struct type_name<std::vector<Function<double,5>>> { static const char* value() { return "std::vector<Function<double,5>>"; } };
61 template<>
62 struct type_name<std::vector<Function<double,6>>> { static const char* value() { return "std::vector<Function<double,6>>"; } };
63
64template<typename keyT>
65struct Recordlist {
66 std::list<keyT> list;
67
68 Recordlist() : list() {};
69
70 explicit Recordlist(const keyT &key) : list{key} {};
71
72 Recordlist(const Recordlist &other) : list(other.list) {};
73
75 for (auto &l2 : list2.list) list.push_back(l2);
76 return *this;
77 }
78
79 Recordlist &operator+=(const keyT &key) {
80 list.push_back(key);
81 return *this;
82 }
83
85 keyT key = list.front();
86 list.pop_front();
87 return key;
88 }
89
90 std::size_t size() const {
91 return list.size();
92 }
93
94 // if type provides id() member function (i.e. WorldObject) use that for hashing, otherwise use hash_value() for
95 // fundamental types (see worldhash.h)
96 template <typename T>
97 using member_id_t = decltype(std::declval<T>().id());
98
99 template <typename T>
101
102 // if type provides a hashing function use that, intrusive hashing, see worldhash.h
103 template <typename T>
104 using member_hash_t = decltype(std::declval<T>().hash());
105
106 template <typename T>
108
109 template<typename T, std::size_t NDIM>
110 static keyT compute_record(const Function<T,NDIM>& arg) {return hash_value(arg.get_impl()->id());}
111
112 template<typename T, std::size_t NDIM>
114
115 template<typename keyQ, typename valueT>
117
118 template<typename keyQ, typename valueT>
119 static keyT compute_record(const std::shared_ptr<WorldContainer<keyQ,valueT>>& arg) {return hash_value(arg->id());}
120
121 template<typename T, std::size_t NDIM>
122 static keyT compute_record(const std::shared_ptr<madness::FunctionImpl<T, NDIM>>& arg) {return hash_value(arg->id());}
123
124 template<typename T>
125 static keyT compute_record(const std::vector<T>& arg) {return hash_range(arg.begin(), arg.end());}
126
127 template<typename T>
128 static keyT compute_record(const Tensor<T>& arg) {return hash_value(arg.normf());}
129
130 template<typename T>
131 static keyT compute_record(const std::shared_ptr<T>& arg) {return compute_record(*arg);}
132
133 template<typename T>
134 static keyT compute_record(const T& arg) {
135 if constexpr (has_member_id<T>::value) {
136 return hash_value(arg.id());
137 } else if constexpr (std::is_pointer_v<T> && has_member_id<std::remove_pointer_t<T>>::value) {
138 return hash_value(arg->id());
139 } else {
140 // compute hash_code for fundamental types
141 std::size_t hashtype = typeid(T).hash_code();
142 hash_combine(hashtype,hash_value(arg));
143 return hashtype;
144 }
145 }
146
147
148 friend std::ostream &operator<<(std::ostream &os, const Recordlist &arg) {
149 using namespace madness::operators;
150 os << arg.list;
151 return os;
152 }
153
154};
155
156/// cloud class
157
158/// store and load data to/from the cloud into arbitrary worlds
159///
160/// Distributed data is always bound to a certain world. If it needs to be
161/// present in another world it can be serialized to the cloud and deserialized
162/// from there again. For an example see test_cloud.cc
163///
164/// Data is stored into a distributed container living in the universe.
165/// During storing a (replicated) list of records is returned that can be used to find the data
166/// in the container. If a combined object (a vector, tuple, etc) is stored a list of records
167/// will be generated. When loading the data from the world the record list will be used to
168/// deserialize all stored objects.
169///
170/// Note that there must be a fence after the destruction of subworld containers, as in:
171///
172/// create subworlds
173/// {
174/// dcT(subworld)
175/// do work
176/// }
177/// subworld.gop.fence();
178class Cloud {
179
180 bool debug = false; ///< prints debug output
181 bool is_replicated=false; ///< if contents of the container are replicated
182 bool dofence = true; ///< fences after load/store
183 bool force_load_from_cache = false; ///< forces load from cache (mainly for debugging)
184
185public:
186 /// These policies determine how the data is stored in the cloud and how it is replicated
187 /// There are six possible combinations of storing and replication policies:
188 /// StoreFunction + Distributed : Functions are stored in the cloud, subworlds need to
189 /// communicate with all universe ranks to access them
190 /// StoreFunction + RankReplicated : Functions are stored in the cloud, but subworlds can
191 /// access them locally -- high memory impact
192 /// StoreFunction + NodeReplicated : Functions are stored in the cloud, but subworlds can
193 /// access them through intra-node communication -- low memory impact
194 /// StoreFunctionPointer + Distributed : Pointers to functions are stored in the cloud,
195 /// subworlds need to communicate with the universe to access function data
196 /// StoreFunctionPointer + RankReplicated : Pointers to functions are stored in the cloud,
197 /// subworlds need to communicate with the universe to access function data
198 /// StoreFunctionPointer + NodeReplicated : Pointers to functions are stored in the cloud,
199 /// subworlds need to communicate with the universe to access function data
200 /// of the last three policies only (StoreFunctionPointer + RankReplicated) is recommended, as the function
201 /// pointers do not have a memory impact.
202 /// on large-memory machines the policy (StoreFunctionPointer + RankReplicated) is recommended, as everything is local
203 /// after the initial replication step
205 StoreFunction, ///< store a madness function in the cloud -- can have a large memory impact
206 ///< equivalent to a deep copy
207 StoreFunctionPointer, ///< store the pointer to the function in the cloud.
208 ///< Return type still is a Function<T,NDIM> with a pointer to the universe function impl.
209 ///< equivalent to a shallow copy
210 };
212 Distributed, ///< no replication of the container, the container is distributed over the universe
213 ///< inter-node communication is required for subworlds to access the data
214 RankReplicated, ///< replicate the container over all universe ranks, such that subworlds can access the data locally
215 ///< will lead to increased memory footprint if there are many subworlds on a node
216 NodeReplicated, ///< replicate the container over all compute nodes, once per node, even if there are several ranks
217 ///< only intra-node communication is required to access the data
218 };
219
220private:
221 StoragePolicy storage_policy = StoreFunctionPointer; ///< current policy for loading/storing/replicating
223
224public:
225
226 typedef std::any cached_objT;
228 using valueT = std::vector<unsigned char>;
229 typedef std::map<keyT, cached_objT> cacheT;
231
232private:
235 recordlistT local_list_of_container_keys; // a world-local list of keys occupied in container
236
237public:
238 template <typename T>
239 using member_cloud_serialize_t = decltype(std::declval<T>().cloud_store(std::declval<World&>(), std::declval<Cloud&>()));
240
241 template <typename T>
243
244public:
245
246 /// @param[in] universe the universe world
247 Cloud(madness::World &universe) : container(universe), reading_time(0l), writing_time(0l),
248 cache_reads(0l), cache_stores(0l) {
249 }
250
251 void set_debug(bool value) {
252 debug = value;
253 }
254
255 void set_fence(bool value) {
256 dofence = value;
257 }
258
259 void set_force_load_from_cache(bool value) {
260 force_load_from_cache = value;
261 }
262
264 replication_policy = value;
265 }
266
270
272 storage_policy = value;
273 }
274
278
279 std::tuple<size_t,double> print_size(World& universe) {
280
281 std::size_t memsize=0;
282 std::size_t max_record_size=0;
283 for (auto& item : container) {
284 memsize+=item.second.size();
285 max_record_size=std::max(max_record_size,item.second.size());
286 }
287 std::size_t global_memsize=memsize;
288 std::size_t max_memsize=memsize;
289 std::size_t min_memsize=memsize;
290 universe.gop.sum(global_memsize);
291 universe.gop.max(max_memsize);
292 universe.gop.max(max_record_size);
293 universe.gop.min(min_memsize);
294
295 auto local_size=container.size();
296 auto global_size=local_size;
297 universe.gop.sum(global_size);
298 double byte2gbyte=1.0/(1024*1024*1024);
299
300 if (universe.rank()==0) {
301 print("Cloud memory:");
302 print(" replicated:",is_replicated);
303 print("size of cloud (total)");
304 print(" number of records: ",global_size);
305 print(" memory in GBytes: ",global_memsize*byte2gbyte);
306 print("size of cloud (average per node)");
307 print(" number of records: ",double(global_size)/universe.size());
308 print(" memory in GBytes: ",global_memsize*byte2gbyte/universe.size());
309 print("min/max of node");
310 print(" memory in GBytes: ",min_memsize*byte2gbyte,max_memsize*byte2gbyte);
311 print(" max record size in GBytes:",max_record_size*byte2gbyte);
312
313 }
314 return std::tie(global_size,global_memsize);
315 }
316
317 void print_timings(World &universe) const {
318 double rtime_max = double(reading_time);
319 double rtime_acc = double(reading_time);
320 double rtime_av = double(reading_time);
321 double wtime = double(writing_time);
322 double ptime = double(replication_time);
323 universe.gop.max(rtime_max);
324 universe.gop.sum(rtime_acc);
325 rtime_av = rtime_acc/universe.size();
326 universe.gop.max(wtime);
327 universe.gop.max(ptime);
328
329 long creads = long(cache_reads);
330 long cstores = long(cache_stores);
331 universe.gop.sum(creads);
332 universe.gop.sum(cstores);
333 if (universe.rank() == 0) {
334 auto precision = std::cout.precision();
335 std::cout << std::fixed << std::setprecision(1);
336 print("cloud storing wall time", wtime * 0.001);
337 print("cloud replication wall time", ptime * 0.001);
338 print("cloud max reading time (all procs)", rtime_max * 0.001, std::defaultfloat);
339 print("cloud average reading cpu time (all procs)", rtime_av * 0.001, std::defaultfloat);
340 print("cloud accumulated reading cpu time (all procs)", rtime_acc * 0.001, std::defaultfloat);
341 std::cout << std::setprecision(precision) << std::scientific;
342 print("cloud cache stores ", long(cstores));
343 print("cloud cache loads ", long(creads));
344 }
345 }
346 void clear_cache(World &subworld) {
347 cached_objects.clear();
348 local_list_of_container_keys.list.clear();
349 subworld.gop.fence();
350 }
351
352 void clear() {
353 container.clear();
354 }
355
357 reading_time=0l;
358 writing_time=0l;
359 writing_time1=0l;
361 cache_stores=0l;
362 cache_reads=0l;
363 }
364
365 /// @param[in] world the subworld the objects are loaded to
366 /// @param[in] recordlist the list of records where the objects are stored
367
368 /// load a single object from the cloud, recordlist is kept unchanged
369 template<typename T>
370 T load(madness::World &world, const recordlistT recordlist) const {
371 recordlistT rlist = recordlist;
372 cloudtimer t(world, reading_time);
373
374 // forward_load will consume the recordlist while loading elements
375 return forward_load<T>(world, rlist);
376 }
377
378 /// similar to load, but will consume the recordlist
379
380 /// @param[in] world the subworld the objects are loaded to
381 /// @param[in] recordlist the list of records where the objects are stored
382 template<typename T>
383 T consuming_load(madness::World &world, recordlistT& recordlist) const {
384 cloudtimer t(world, reading_time);
385
386 // forward_load will consume the recordlist while loading elements
387 return forward_load<T>(world, recordlist);
388 }
389
390 /// load a single object from the cloud, recordlist is consumed while loading elements
391 template<typename T>
392 T forward_load(madness::World &world, recordlistT& recordlist) const {
393 // different objects are stored in different ways
394 // - tuples are split up into their components
395 // - classes with their own cloud serialization are stored using that
396 // - everything else is stored using their usual serialization
397 if constexpr (is_tuple<T>::value) {
398 return load_tuple<T>(world, recordlist);
399 } else if constexpr (has_cloud_serialize<T>::value) {
400 T target = allocator<T>(world);
401 target.cloud_load(world, *this, recordlist);
402 return target;
403 } else {
404 return do_load<T>(world, recordlist);
405 }
406 }
407
408 /// @param[in] world presumably the universe
409 template<typename T>
411 if (is_replicated) {
412 print("Cloud contents are replicated and read-only!");
413 MADNESS_EXCEPTION("cloud error",1);
414 }
415 cloudtimer t(world,writing_time);
416
417 // different objects are stored in different ways
418 // - tuples are split up into their components
419 // - classes with their own cloud serialization are stored using that
420 // - everything else is stored using their usual serialization
421 recordlistT recordlist;
422 if constexpr (is_tuple<T>::value) {
423 recordlist+=store_tuple(world,source);
424 } else if constexpr (has_cloud_serialize<T>::value) {
425 recordlist+=source.cloud_store(world,*this);
426 } else {
427 recordlist+=store_other(world,source);
428 }
429 if (dofence) world.gop.fence();
430 return recordlist;
431 }
432
433 void replicate_per_node(const std::size_t chunk_size=INT_MAX) {
435 MADNESS_EXCEPTION("replication policy is not NodeReplicated",1);
436 }
437 if (debug and (container.size() > 0)) print("replicating container per node");
438 MADNESS_EXCEPTION("Cloud::replicate_per_node not yet implemented",1);
439 }
440
441 void replicate(const std::size_t chunk_size=INT_MAX) {
442
443 double cpu0=cpu_time();
444 World& world=container.get_world();
445 world.gop.fence();
447 container.reset_pmap_to_local();
448 is_replicated=true;
449
450 std::list<keyT> keylist;
451 for (auto it=container.begin(); it!=container.end(); ++it) {
452 keylist.push_back(it->first);
453 }
454
455 for (ProcessID rank=0; rank<world.size(); rank++) {
456 if (rank == world.rank()) {
457 std::size_t keylistsize = keylist.size();
458 world.mpi.Bcast(&keylistsize,sizeof(keylistsize),MPI_BYTE,rank);
459
460 for (auto key : keylist) {
462 bool found=container.find(acc,key);
463 MADNESS_CHECK(found);
464 auto data = acc->second;
465 std::size_t sz=data.size();
466
467 world.mpi.Bcast(&key,sizeof(key),MPI_BYTE,rank);
468 world.mpi.Bcast(&sz,sizeof(sz),MPI_BYTE,rank);
469
470 // if data is too large for MPI_INT break it into pieces to avoid integer overflow
471 for (std::size_t start=0; start<sz; start+=chunk_size) {
472 std::size_t remainder = std::min(sz - start, chunk_size);
473 world.mpi.Bcast(&data[start], remainder, MPI_BYTE, rank);
474 }
475
476 }
477 }
478 else {
479 std::size_t keylistsize;
480 world.mpi.Bcast(&keylistsize,sizeof(keylistsize),MPI_BYTE,rank);
481 for (size_t i=0; i<keylistsize; i++) {
482 keyT key;
483 world.mpi.Bcast(&key,sizeof(key),MPI_BYTE,rank);
484 std::size_t sz;
485 world.mpi.Bcast(&sz,sizeof(sz),MPI_BYTE,rank);
486 valueT data(sz);
487// world.mpi.Bcast(&data[0],sz,MPI_BYTE,rank);
488 for (std::size_t start=0; start<sz; start+=chunk_size) {
489 std::size_t remainder=std::min(sz-start,chunk_size);
490 world.mpi.Bcast(&data[start],remainder,MPI_BYTE,rank);
491 }
492
493 container.replace(key,data);
494 }
495 }
496 }
497 world.gop.fence();
498 double cpu1=cpu_time();
499 if (debug and (world.rank()==0)) print("replication ended after ",cpu1-cpu0," seconds");
500 }
501
502private:
503
504 mutable std::atomic<long> reading_time=0l; // in ms
505 mutable std::atomic<long> writing_time=0l; // in ms
506 mutable std::atomic<long> writing_time1=0l; // in ms
507 mutable std::atomic<long> replication_time=0l; // in ms
508 mutable std::atomic<long> cache_reads=0l;
509 mutable std::atomic<long> cache_stores=0l;
510
511 template<typename> struct is_tuple : std::false_type { };
512 template<typename ...T> struct is_tuple<std::tuple<T...>> : std::true_type { };
513
514 template<typename Q> struct is_vector : std::false_type { };
515 template<typename Q> struct is_vector<std::vector<Q>> : std::true_type { };
516
517 template<typename>
518 struct is_madness_function_vector : std::false_type {
519 };
520 template<typename T, std::size_t NDIM>
521 struct is_madness_function_vector<std::vector<Function<T, NDIM>>> : std::true_type {
522 };
523
524 template<typename T> using is_parallel_serializable_object = std::is_base_of<archive::ParallelSerializableObject,T>;
525
526 template<typename T> using is_world_constructible = std::is_constructible<T, World &>;
527
528 struct cloudtimer {
530 double wall0;
531 std::atomic<long> &rtime;
532
533 cloudtimer(World& world, std::atomic<long> &readtime) : world(world), wall0(wall_time()), rtime(readtime) {}
534
536 long deltatime=long((wall_time() - wall0) * 1000l);
537 rtime += deltatime;
538 }
539 };
540
541 template<typename T>
542 void cache(madness::World &world, const T &obj, const keyT &record) const {
543 const_cast<cacheT &>(cached_objects).insert({record,std::make_any<T>(obj)});
544 }
545
546 /// load an object from the cache, record is unchanged
547 template<typename T>
548 T load_from_cache(madness::World &world, const keyT &record) const {
549 if (world.rank()==0) cache_reads++;
550 if (debug) print("loading", type_name<T>::value(), "from cache record", record, "to world", world.id());
551 if (auto obj = std::any_cast<T>(&cached_objects.find(record)->second)) return *obj;
552 MADNESS_EXCEPTION("failed to load from cloud-cache", 1);
553 T target = allocator<T>(world);
554 return target;
555 }
556
557 bool is_cached(const keyT &key) const {
558 return (cached_objects.count(key) == 1);
559 }
560
561 /// checks if a (universe) container record is used
562
563 /// currently implemented with a local copy of the recordlist, might be
564 /// reimplemented with container.find(), which would include blocking communication.
565 bool is_in_container(const keyT &key) const {
566 auto it = std::find(local_list_of_container_keys.list.begin(),
567 local_list_of_container_keys.list.end(), key);
568 return it!=local_list_of_container_keys.list.end();
569 }
570
571 template<typename T>
572 T allocator(World &world) const {
573 if constexpr (is_world_constructible<T>::value) {
574 return T(world);
575 } else {
576 return T();
577 }
578 }
579
580 template<typename T>
583 bool is_already_present= is_in_container(record);
584 if (debug and world.rank()==0) {
585 if (is_already_present) std::cout << "skipping ";
586 if constexpr (Recordlist<keyT>::has_member_id<T>::value) {
587 std::cout << "storing world object of " << type_name<T>::value() << "id " << source.id()
588 << " to record " << record << std::endl;
589 }
590 std::cout << "storing object of " << type_name<T>::value() << " to record " << record << std::endl;
591 }
592 if constexpr (is_madness_function<T>::value) {
593 if (source.is_compressed() and T::dimT>3) print("WARNING: storing compressed hi-dim `function");
594 }
595
596 // scope is important because of destruction ordering of world objects and fence
597 if (is_already_present) {
598 if (world.rank()==0) cache_stores++;
599 } else {
600 cloudtimer t(world,writing_time1);
604 if constexpr (is_madness_function<T>::value) {
605 // store the pointer to the function, not the function itself
606 par & source.get_impl();
607 } else {
608 // store everything else
609 par & source;
610 }
611 } else {
612 // store everything else
613 par & source;
614 }
616 }
617 if (dofence) world.gop.fence();
618 return recordlistT{record};
619 }
620
621public:
622 /// load a vector from the cloud, pop records from recordlist
623 ///
624 /// @param[inout] world destination world
625 /// @param[inout] recordlist list of records to load from (reduced by the first few elements)
626 template<typename T>
627 typename std::enable_if<is_vector<T>::value, T>::type
628 do_load(World &world, recordlistT &recordlist) const {
629 std::size_t sz = do_load<std::size_t>(world, recordlist);
630 T target(sz);
631 for (std::size_t i = 0; i < sz; ++i) {
632 target[i] = do_load<typename T::value_type>(world, recordlist);
633 }
634 return target;
635 }
636
637 /// load a single object from the cloud, pop record from recordlist
638 ///
639 /// @param[inout] world destination world
640 /// @param[inout] recordlist list of records to load from (reduced by the first element)
641 template<typename T>
642 typename std::enable_if<!is_vector<T>::value, T>::type
643 do_load(World &world, recordlistT &recordlist) const {
644 keyT record = recordlist.pop_front_and_return();
646
647 if (is_cached(record)) return load_from_cache<T>(world, record);
648 if (debug) print("loading", type_name<T>::value(), "from container record", record, "to world", world.id());
649 T target = allocator<T>(world);
652 if constexpr (is_madness_function<T>::value) {
654 // load the pointer to the function, not the function itself
655 // this is important for large functions, as they are not replicated
656 // and only copied to subworlds when needed
657 try {
659 std::shared_ptr<implT> impl;
660 par & impl;
661 target.set_impl(impl); // target now points to a universe function impl
662 } catch (...) {
663 {
664 io_redirect_cout redirect;
665 print("failed to load function pointer from cloud, maybe the target is out of scope?");
666 print("record:", record, "world:", world.id());
667 print("function type:", type_name<T>::value());
668 print("\n");
669 }
670 MADNESS_EXCEPTION("load/store error of pointers in cloud", 1);
671 }
672 } else {
673 // load everything else
674 par & target;
675 }
676 } else {
677 // load everything else
678 par & target;
679 }
680
681 cache(world, target, record);
682 if (is_replicated) container.erase(record);
683
684 return target;
685 }
686
687public:
688
689 // overloaded
690 template<typename T>
691 recordlistT store_other(madness::World& world, const std::vector<T>& source) {
692 if (debug and world.rank()==0)
693 std::cout << "storing vector of " << type_name<T>::value() << " of size " << source.size() << std::endl;
694 recordlistT l = store_other(world, source.size());
695 for (const auto& s : source) l += store_other(world, s);
696 if (dofence) world.gop.fence();
697 if (debug and world.rank()==0) std::cout << "done with vector storing; container size "
698 << container.size() << std::endl;
699 return l;
700 }
701
702 /// store a tuple in multiple records
703 template<typename... Ts>
704 recordlistT store_tuple(World &world, const std::tuple<Ts...> &input) {
706 auto storeaway = [&](const auto &arg) {
707 v += this->store(world, arg);
708 };
709 auto l = [&](Ts const &... arg) {
710 ((storeaway(arg)), ...);
711 };
712 std::apply(l, input);
713 return v;
714 }
715
716 /// load a tuple from the cloud, pop records from recordlist
717 ///
718 /// @param[inout] world destination world
719 /// @param[inout] recordlist list of records to load from (reduced by the first few elements)
720 template<typename T>
721 T load_tuple(madness::World &world, recordlistT &recordlist) const {
722 if (debug) std::cout << "loading tuple of type " << typeid(T).name() << " to world " << world.id() << std::endl;
723 T target;
724 std::apply([&](auto &&... args) {
725 ((args = forward_load<typename std::remove_reference<decltype(args)>::type>(world, recordlist)), ...);
726 }, target);
727 return target;
728 }
729};
730
731} /* namespace madness */
732
733#endif /* SRC_MADNESS_WORLD_CLOUD_H_ */
cloud class
Definition cloud.h:178
bool is_cached(const keyT &key) const
Definition cloud.h:557
void clear()
Definition cloud.h:352
void replicate_per_node(const std::size_t chunk_size=INT_MAX)
Definition cloud.h:433
bool is_in_container(const keyT &key) const
checks if a (universe) container record is used
Definition cloud.h:565
bool force_load_from_cache
forces load from cache (mainly for debugging)
Definition cloud.h:183
bool debug
prints debug output
Definition cloud.h:180
ReplicationPolicy replication_policy
Definition cloud.h:222
std::atomic< long > writing_time1
Definition cloud.h:506
std::enable_if< is_vector< T >::value, T >::type do_load(World &world, recordlistT &recordlist) const
Definition cloud.h:628
recordlistT store_other(madness::World &world, const std::vector< T > &source)
Definition cloud.h:691
std::any cached_objT
Definition cloud.h:226
recordlistT store(madness::World &world, const T &source)
Definition cloud.h:410
T load_tuple(madness::World &world, recordlistT &recordlist) const
Definition cloud.h:721
std::is_base_of< archive::ParallelSerializableObject, T > is_parallel_serializable_object
Definition cloud.h:524
madness::archive::ContainerRecordOutputArchive::keyT keyT
Definition cloud.h:227
std::atomic< long > replication_time
Definition cloud.h:507
Recordlist< keyT > recordlistT
Definition cloud.h:230
StoragePolicy storage_policy
current policy for loading/storing/replicating
Definition cloud.h:221
std::is_constructible< T, World & > is_world_constructible
Definition cloud.h:526
recordlistT store_other(madness::World &world, const T &source)
Definition cloud.h:581
bool is_replicated
if contents of the container are replicated
Definition cloud.h:181
void set_force_load_from_cache(bool value)
Definition cloud.h:259
std::tuple< size_t, double > print_size(World &universe)
Definition cloud.h:279
decltype(std::declval< T >().cloud_store(std::declval< World & >(), std::declval< Cloud & >())) member_cloud_serialize_t
Definition cloud.h:239
void replicate(const std::size_t chunk_size=INT_MAX)
Definition cloud.h:441
recordlistT local_list_of_container_keys
Definition cloud.h:235
std::atomic< long > reading_time
Definition cloud.h:504
void clear_timings()
Definition cloud.h:356
recordlistT store_tuple(World &world, const std::tuple< Ts... > &input)
store a tuple in multiple records
Definition cloud.h:704
void set_debug(bool value)
Definition cloud.h:251
std::enable_if<!is_vector< T >::value, T >::type do_load(World &world, recordlistT &recordlist) const
Definition cloud.h:643
T load(madness::World &world, const recordlistT recordlist) const
load a single object from the cloud, recordlist is kept unchanged
Definition cloud.h:370
void cache(madness::World &world, const T &obj, const keyT &record) const
Definition cloud.h:542
void set_fence(bool value)
Definition cloud.h:255
std::atomic< long > cache_reads
Definition cloud.h:508
ReplicationPolicy get_replication_policy() const
Definition cloud.h:267
Cloud(madness::World &universe)
Definition cloud.h:247
cacheT cached_objects
Definition cloud.h:234
void clear_cache(World &subworld)
Definition cloud.h:346
ReplicationPolicy
Definition cloud.h:211
@ NodeReplicated
Definition cloud.h:216
@ Distributed
Definition cloud.h:212
@ RankReplicated
Definition cloud.h:214
void set_replication_policy(const ReplicationPolicy value)
Definition cloud.h:263
StoragePolicy get_storing_policy() const
Definition cloud.h:275
T load_from_cache(madness::World &world, const keyT &record) const
load an object from the cache, record is unchanged
Definition cloud.h:548
madness::meta::is_detected< member_cloud_serialize_t, T > has_cloud_serialize
Definition cloud.h:242
std::vector< unsigned char > valueT
Definition cloud.h:228
bool dofence
fences after load/store
Definition cloud.h:182
void print_timings(World &universe) const
Definition cloud.h:317
T allocator(World &world) const
Definition cloud.h:572
std::atomic< long > writing_time
Definition cloud.h:505
void set_storing_policy(const StoragePolicy value)
Definition cloud.h:271
madness::WorldContainer< keyT, valueT > container
Definition cloud.h:233
T forward_load(madness::World &world, recordlistT &recordlist) const
load a single object from the cloud, recordlist is consumed while loading elements
Definition cloud.h:392
StoragePolicy
Definition cloud.h:204
@ StoreFunctionPointer
Definition cloud.h:207
@ StoreFunction
Definition cloud.h:205
std::map< keyT, cached_objT > cacheT
Definition cloud.h:229
T consuming_load(madness::World &world, recordlistT &recordlist) const
similar to load, but will consume the recordlist
Definition cloud.h:383
std::atomic< long > cache_stores
Definition cloud.h:509
FunctionImpl holds all Function state to facilitate shallow copy semantics.
Definition funcimpl.h:945
A multiresolution adaptive numerical function.
Definition mra.h:139
A tensor is a multidimensional array.
Definition tensor.h:317
Makes a distributed container with specified attributes.
Definition worlddc.h:866
bool find(accessor &acc, const keyT &key)
Write access to LOCAL value by key. Returns true if found, false otherwise (always false for remote).
Definition worlddc.h:987
void max(T *buf, size_t nelem)
Inplace global max while still processing AM & tasks.
Definition worldgop.h:884
void fence(bool debug=false)
Synchronizes all processes in communicator AND globally ensures no pending AM or tasks.
Definition worldgop.cc:161
void min(T *buf, size_t nelem)
Inplace global min while still processing AM & tasks.
Definition worldgop.h:878
void sum(T *buf, size_t nelem)
Inplace global sum while still processing AM & tasks.
Definition worldgop.h:872
void Bcast(T *buffer, int count, int root) const
MPI broadcast an array of count elements.
Definition worldmpi.h:416
A parallel world class.
Definition world.h:132
ProcessID rank() const
Returns the process rank in this World (same as MPI_Comm_rank()).
Definition world.h:320
WorldMpiInterface & mpi
MPI interface.
Definition world.h:204
ProcessID size() const
Returns the number of processes in this World (same as MPI_Comm_size()).
Definition world.h:330
unsigned long id() const
Definition world.h:315
WorldGopInterface & gop
Global operations.
Definition world.h:207
Definition parallel_dc_archive.h:60
Definition parallel_dc_archive.h:14
long keyT
Definition parallel_dc_archive.h:16
An archive for storing local or parallel data, wrapping a BinaryFstreamInputArchive.
Definition parallel_archive.h:366
An archive for storing local or parallel data wrapping a BinaryFstreamOutputArchive.
Definition parallel_archive.h:321
auto T(World &world, response_space &f) -> response_space
Definition global_functions.cc:28
Tensor< typename Tensor< T >::scalar_type > arg(const Tensor< T > &t)
Return a new tensor holding the argument of each element of t (complex types only)
Definition tensor.h:2503
static const double v
Definition hatom_sf_dirac.cc:20
#define MADNESS_CHECK(condition)
Check a condition — even in a release build the condition is always evaluated so it can have side eff...
Definition madness_exception.h:182
#define MADNESS_EXCEPTION(msg, value)
Macro for throwing a MADNESS exception.
Definition madness_exception.h:119
typename detail::detector< nonesuch, void, Op, Args... >::value_t is_detected
Definition meta.h:169
Definition array_addons.h:50
Namespace for all elements and tools of MADNESS.
Definition DFParameters.h:10
void hash_range(hashT &seed, It first, It last)
Definition worldhash.h:280
static double cpu_time()
Returns the cpu time in seconds relative to an arbitrary origin.
Definition timers.h:127
void hash_combine(hashT &seed, const T &v)
Combine hash values.
Definition worldhash.h:260
static class madness::twoscale_cache_class cache[kmax+1]
void print(const T &t, const Ts &... ts)
Print items to std::cout (items separated by spaces) and terminate with a new line.
Definition print.h:226
double wall_time()
Returns the wall time in seconds relative to an arbitrary origin.
Definition timers.cc:48
std::string type(const PairType &n)
Definition PNOParameters.h:18
std::string name(const FuncType &type, const int ex=-1)
Definition ccpairfunction.h:28
madness::hashT hash_value(const std::array< T, N > &a)
Hash std::array with madness hash.
Definition array_addons.h:78
Definition mraimpl.h:50
Definition test_dc.cc:47
Definition hatom_sf_dirac.cc:91
Definition test_ccpairfunction.cc:22
Definition cloud.h:528
std::atomic< long > & rtime
Definition cloud.h:531
World & world
Definition cloud.h:529
double wall0
Definition cloud.h:530
~cloudtimer()
Definition cloud.h:535
cloudtimer(World &world, std::atomic< long > &readtime)
Definition cloud.h:533
Definition cloud.h:511
Definition cloud.h:514
Definition cloud.h:65
static keyT compute_record(const std::vector< T > &arg)
Definition cloud.h:125
keyT pop_front_and_return()
Definition cloud.h:84
static keyT compute_record(const Function< T, NDIM > &arg)
Definition cloud.h:110
Recordlist(const Recordlist &other)
Definition cloud.h:72
Recordlist(const keyT &key)
Definition cloud.h:70
static keyT compute_record(const std::shared_ptr< T > &arg)
Definition cloud.h:131
static keyT compute_record(const T &arg)
Definition cloud.h:134
std::size_t size() const
Definition cloud.h:90
madness::meta::is_detected< member_id_t, T > has_member_id
Definition cloud.h:100
decltype(std::declval< T >().id()) member_id_t
Definition cloud.h:97
friend std::ostream & operator<<(std::ostream &os, const Recordlist &arg)
Definition cloud.h:148
Recordlist & operator+=(const Recordlist &list2)
Definition cloud.h:74
static keyT compute_record(const WorldContainer< keyQ, valueT > &arg)
Definition cloud.h:116
decltype(std::declval< T >().hash()) member_hash_t
Definition cloud.h:104
static keyT compute_record(const std::shared_ptr< WorldContainer< keyQ, valueT > > &arg)
Definition cloud.h:119
std::list< keyT > list
Definition cloud.h:66
Recordlist & operator+=(const keyT &key)
Definition cloud.h:79
static keyT compute_record(const FunctionImpl< T, NDIM > *arg)
Definition cloud.h:113
static keyT compute_record(const std::shared_ptr< madness::FunctionImpl< T, NDIM > > &arg)
Definition cloud.h:122
static keyT compute_record(const Tensor< T > &arg)
Definition cloud.h:128
madness::meta::is_detected< member_hash_t, T > has_member_hash
Definition cloud.h:107
Recordlist()
Definition cloud.h:68
class to temporarily redirect output to cout
Definition print.h:277
Definition mra.h:2868
static const char * value()
Definition cloud.h:39
static const char * value()
Definition cloud.h:41
static const char * value()
Definition cloud.h:43
static const char * value()
Definition cloud.h:45
static const char * value()
Definition cloud.h:47
static const char * value()
Definition cloud.h:49
static const char * value()
Definition cloud.h:52
static const char * value()
Definition cloud.h:54
static const char * value()
Definition cloud.h:56
static const char * value()
Definition cloud.h:58
static const char * value()
Definition cloud.h:60
static const char * value()
Definition cloud.h:62
A utility to get the name of a type as a string from chatGPT.
Definition cloud.h:34
static const char * value()
Definition cloud.h:35
#define MPI_BYTE
Definition stubmpi.h:77
double source(const coordT &r)
Definition testperiodic.cc:48
int ProcessID
Used to clearly identify process number/rank.
Definition worldtypes.h:43
FLOAT target(const FLOAT &x)
Definition y.cc:295