source: ThirdParty/mpqc_open/src/lib/util/group/messimpl.cc@ 398fcd

Action_Thermostats Add_AtomRandomPerturbation Add_RotateAroundBondAction Add_SelectAtomByNameAction Adding_Graph_to_ChangeBondActions Adding_MD_integration_tests Adding_StructOpt_integration_tests AutomationFragmentation_failures Candidate_v1.6.0 Candidate_v1.6.1 ChangeBugEmailaddress ChangingTestPorts ChemicalSpaceEvaluator Combining_Subpackages Debian_Package_split Debian_package_split_molecuildergui_only Disabling_MemDebug Docu_Python_wait EmpiricalPotential_contain_HomologyGraph_documentation Enable_parallel_make_install Enhance_userguide Enhanced_StructuralOptimization Enhanced_StructuralOptimization_continued Example_ManyWaysToTranslateAtom Exclude_Hydrogens_annealWithBondGraph FitPartialCharges_GlobalError Fix_ChronosMutex Fix_StatusMsg Fix_StepWorldTime_single_argument Fix_Verbose_Codepatterns ForceAnnealing_goodresults ForceAnnealing_oldresults ForceAnnealing_tocheck ForceAnnealing_with_BondGraph ForceAnnealing_with_BondGraph_continued ForceAnnealing_with_BondGraph_continued_betteresults ForceAnnealing_with_BondGraph_contraction-expansion GeometryObjects Gui_displays_atomic_force_velocity IndependentFragmentGrids_IntegrationTest JobMarket_RobustOnKillsSegFaults JobMarket_StableWorkerPool JobMarket_unresolvable_hostname_fix ODR_violation_mpqc_open PartialCharges_OrthogonalSummation PythonUI_with_named_parameters QtGui_reactivate_TimeChanged_changes Recreated_GuiChecks RotateToPrincipalAxisSystem_UndoRedo StoppableMakroAction Subpackage_levmar Subpackage_vmg ThirdParty_MPQC_rebuilt_buildsystem TremoloParser_IncreasedPrecision TremoloParser_MultipleTimesteps Ubuntu_1604_changes stable
Last change on this file since 398fcd was 860145, checked in by Frederik Heber <heber@…>, 8 years ago

Merge commit '0b990dfaa8c6007a996d030163a25f7f5fc8a7e7' as 'ThirdParty/mpqc_open'

  • Property mode set to 100644
File size: 16.2 KB
Line 
1//
2// messimpl.cc
3//
4// Copyright (C) 1996 Limit Point Systems, Inc.
5//
6// Author: Curtis Janssen <cljanss@limitpt.com>
7// Maintainer: LPS
8//
9// This file is part of the SC Toolkit.
10//
11// The SC Toolkit is free software; you can redistribute it and/or modify
12// it under the terms of the GNU Library General Public License as published by
13// the Free Software Foundation; either version 2, or (at your option)
14// any later version.
15//
16// The SC Toolkit is distributed in the hope that it will be useful,
17// but WITHOUT ANY WARRANTY; without even the implied warranty of
18// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19// GNU Library General Public License for more details.
20//
21// You should have received a copy of the GNU Library General Public License
22// along with the SC Toolkit; see the file COPYING.LIB. If not, write to
23// the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
24//
25// The U.S. Government is granted a limited license as per AL 91-7.
26//
27
28#include <string.h>
29
30#include <util/misc/formio.h>
31#include <util/misc/exenv.h>
32
33#include <util/group/message.h>
34
35#include <util/group/topology.h>
36#include <util/group/hcube.h>
37#ifdef HAVE_NX
38# include <util/group/messpgon.h>
39#endif
40#ifdef HAVE_MPI
41# define MPICH_SKIP_MPICXX
42# include <mpi.h>
43# include <util/group/messmpi.h>
44#endif
45
46#define DEFAULT_GOP_MAX 320000
47
48using namespace std;
49using namespace sc;
50
51static ClassDesc MessageGrp_cd(
52 typeid(MessageGrp),"MessageGrp",1,"public DescribedClass",
53 0, 0, 0);
54
55MessageGrp::MessageGrp(const Ref<KeyVal>& keyval):
56 me_(-1),
57 n_(-1),
58 index_to_classdesc_(0)
59{
60 gop_max_ = keyval->intvalue("gop_max");
61 if (keyval->error() != KeyVal::OK) gop_max_ = DEFAULT_GOP_MAX;
62 debug_ = keyval->booleanvalue("debug");
63}
64
65MessageGrp::MessageGrp():
66 me_(-1),
67 n_(-1),
68 index_to_classdesc_(0)
69{
70 gop_max_ = DEFAULT_GOP_MAX;
71 debug_ = 0;
72}
73
74MessageGrp::~MessageGrp()
75{
76 if (index_to_classdesc_) delete[] index_to_classdesc_;
77}
78
79static Ref<MessageGrp> default_messagegrp;
80
81void
82MessageGrp::set_default_messagegrp(const Ref<MessageGrp>& grp)
83{
84 default_messagegrp = grp;
85}
86
87MessageGrp*
88MessageGrp::get_default_messagegrp()
89{
90 if (default_messagegrp.null()) {
91#if defined(HAVE_MPI) && defined(DEFAULT_MPI)
92 default_messagegrp = new MPIMessageGrp;
93#else
94 default_messagegrp = new ProcMessageGrp;
95#endif
96 }
97 return default_messagegrp.pointer();
98}
99
100MessageGrp *
101MessageGrp::initial_messagegrp(int &argc, char** &argv)
102{
103 MessageGrp *grp = 0;
104
105 char *keyval_string = 0;
106
107 // see if a message group is given on the command line
108 if (argc && argv) {
109 for (int i=0; i<argc; i++) {
110 if (argv[i] && !strcmp(argv[i], "-messagegrp")) {
111 char *messagegrp_string = argv[i];
112 i++;
113 if (i >= argc) {
114 ExEnv::errn() << "-messagegrp must be following by an argument"
115 << endl;
116 abort();
117 }
118 keyval_string = argv[i];
119 // move the messagegrp arguments to the end of argv
120 int j;
121 for (j=i+1; j<argc; j++) {
122 argv[j-2] = argv[j];
123 }
124 argv[j++] = messagegrp_string;
125 argv[j++] = keyval_string;
126 // decrement argc to hide the last two arguments
127 argc -= 2;
128 break;
129 }
130 }
131 }
132
133 if (!keyval_string) {
134 // find out if the environment gives the containing message group
135 keyval_string = getenv("MESSAGEGRP");
136 if (keyval_string) {
137 if (!strncmp("MESSAGEGRP=", keyval_string, 11)) {
138 keyval_string = strchr(keyval_string, '=');
139 }
140 if (*keyval_string == '=') keyval_string++;
141 }
142 }
143
144 // if keyval input for a message group was found, then
145 // create it.
146 if (keyval_string) {
147 if (keyval_string[0] == '\0') return 0;
148 //ExEnv::outn() << "Creating MessageGrp from \"" << keyval_string << "\"" << endl;
149 Ref<ParsedKeyVal> strkv = new ParsedKeyVal();
150 strkv->parse_string(keyval_string);
151 Ref<DescribedClass> dc = strkv->describedclassvalue();
152 grp = dynamic_cast<MessageGrp*>(dc.pointer());
153 if (dc.null()) {
154 ExEnv::errn() << "initial_messagegrp: couldn't find a MessageGrp in "
155 << keyval_string << endl;
156 abort();
157 }
158 else if (!grp) {
159 ExEnv::errn() << "initial_messagegrp: wanted MessageGrp but got "
160 << dc->class_name() << endl;
161 abort();
162 }
163 // prevent an accidental delete
164 grp->reference();
165 strkv = 0;
166 dc = 0;
167 // accidental delete not a problem anymore since all smart pointers
168 // to grp are dead
169 grp->dereference();
170 return grp;
171 }
172
173#if defined(HAVE_MPI)
174 int mpiinited;
175#ifdef ALWAYS_USE_MPI
176 bool always_use_mpi = true;
177#else
178 bool always_use_mpi = false;
179#endif
180 MPI_Initialized(&mpiinited);
181 if (mpiinited || always_use_mpi) {
182 grp = new MPIMessageGrp(&argc,&argv);
183 return grp;
184 }
185#endif
186
187 return 0;
188}
189
190void
191MessageGrp::initialize(int me, int n)
192{
193 // This member is called by a CTOR and, ultimately, causes
194 // 'this' to be converted into a temporary Ref which causes
195 // this to be deleted (very bad), so reference 'this'
196 // (and dereference this down below).
197 this->reference();
198
199 if (topology_.null()) {
200 topology_ = new HypercubeTopology();
201 }
202
203 int i;
204 std::map<std::string,ClassDescP>::iterator J;
205
206 me_ = me;
207 n_ = n;
208
209 // get all of the classes known on this node
210 std::map<std::string,ClassDescP>& classes = ClassDesc::all();
211
212 // Keeps count of how many classes are known.
213 int iclass = 0;
214
215 for (i=0; i<n; i++) {
216 if (i==me) {
217 // Find out how many of my classes are not yet in the
218 // classdesc to index map.
219 int n_new_class = 0;
220 int buffer_size = 0;
221 for (J=classes.begin(); J!=classes.end(); J++) {
222 if (classdesc_to_index_.find(J->second) == classdesc_to_index_.end()) {
223 n_new_class++;
224 buffer_size += strlen(J->second->name()) + 1;
225 }
226 }
227 char* buffer = new char[buffer_size];
228 char* currentbuffer = buffer;
229 for (J=classes.begin(); J!=classes.end(); J++) {
230 if (classdesc_to_index_.find(J->second) == classdesc_to_index_.end()) {
231 classdesc_to_index_[J->second] = iclass;
232 iclass++;
233#ifdef DEBUG
234 ExEnv::outn() << scprintf("node %d adding class %d = \"%s\"\n",
235 me, iclass, J->second->name());
236#endif
237 strcpy(currentbuffer,J->second->name());
238 currentbuffer += strlen(J->second->name()) + 1;
239 }
240 }
241#ifdef DEBUG
242 ExEnv::outn() << scprintf("node %d bcast n_new_class = %d\n",me,n_new_class);
243#endif
244 bcast(&n_new_class,1,i);
245#ifdef DEBUG
246 ExEnv::outn() << scprintf("node %d finished bcast\n",me);
247#endif
248 if (n_new_class) {
249 bcast(&buffer_size,1,i);
250 bcast(buffer,buffer_size,i);
251 }
252 delete[] buffer;
253 }
254 else {
255 int j;
256 // Get new classnames and indices from node i.
257 int n_new_class;
258#ifdef DEBUG
259 ExEnv::outn() << scprintf("node %d begin recv bcast\n",me);
260#endif
261 bcast(&n_new_class,1,i);
262#ifdef DEBUG
263 ExEnv::outn() << scprintf("node %d recv bcast n_new_class = %d\n",
264 me,n_new_class);
265#endif
266 if (n_new_class) {
267 int buffer_size;
268 bcast(&buffer_size,1,i);
269 char* buffer = new char[buffer_size];
270 char* currentbuffer = buffer;
271 bcast(buffer,buffer_size,i);
272 for (j=0; j<n_new_class; j++) {
273 ClassDescP cd = ClassDesc::name_to_class_desc(currentbuffer);
274 if (cd) {
275#ifdef DEBUG
276 ExEnv::outn() << scprintf("node %d adding \"%s\"\n",
277 me, currentbuffer);
278#endif
279 classdesc_to_index_[cd] = iclass;
280 }
281#ifdef DEBUG
282 else {
283 ExEnv::outn() << scprintf("node %d failed to add \"%s\"\n",
284 me, currentbuffer);
285 }
286#endif
287 iclass++;
288 // advance the currentbuffer to the next classname
289 while(*currentbuffer != '\0') currentbuffer++;
290 currentbuffer++;
291 }
292 delete[] buffer;
293 }
294 }
295 }
296 nclass_ = iclass;
297
298 // Construct the mapping of index to classdesc.
299 index_to_classdesc_ = new ClassDescP[iclass];
300 for (i=0; i<nclass_; i++) {
301 index_to_classdesc_[i] = 0;
302 }
303 for (J=classes.begin(); J!=classes.end(); J++) {
304 if (classdesc_to_index_.find(J->second) != classdesc_to_index_.end()) {
305 index_to_classdesc_[classdesc_to_index_[J->second]] = J->second;
306 }
307 }
308
309 this->dereference();
310}
311
312// Sequential send routines
313
314void
315MessageGrp::send(int target, const double* data, int ndata)
316{
317 raw_send(target, data, ndata*sizeof(double));
318}
319void
320MessageGrp::send(int target, const short* data, int ndata)
321{
322 raw_send(target, data, ndata*sizeof(short));
323}
324void
325MessageGrp::send(int target, const long* data, int ndata)
326{
327 raw_send(target, data, ndata*sizeof(long));
328}
329void
330MessageGrp::send(int target, const float* data, int ndata)
331{
332 raw_send(target, data, ndata*sizeof(float));
333}
334void
335MessageGrp::send(int target, const unsigned int* data, int ndata)
336{
337 raw_send(target, data, ndata*sizeof(int));
338}
339void
340MessageGrp::send(int target, const int* data, int ndata)
341{
342 raw_send(target, data, ndata*sizeof(int));
343}
344void
345MessageGrp::send(int target, const char* data, int ndata)
346{
347 raw_send(target, data, ndata);
348}
349void
350MessageGrp::send(int target, const unsigned char* data, int ndata)
351{
352 raw_send(target, data, ndata);
353}
354void
355MessageGrp::send(int target, const signed char* data, int ndata)
356{
357 raw_send(target, data, ndata);
358}
359
360// Sequential receive routines
361
362void
363MessageGrp::recv(int sender, double* data, int ndata)
364{
365 raw_recv(sender, data, ndata*sizeof(double));
366}
367void
368MessageGrp::recv(int sender, short* data, int ndata)
369{
370 raw_recv(sender, data, ndata*sizeof(short));
371}
372void
373MessageGrp::recv(int sender, long* data, int ndata)
374{
375 raw_recv(sender, data, ndata*sizeof(long));
376}
377void
378MessageGrp::recv(int sender, float* data, int ndata)
379{
380 raw_recv(sender, data, ndata*sizeof(float));
381}
382void
383MessageGrp::recv(int sender, unsigned int* data, int ndata)
384{
385 raw_recv(sender, data, ndata*sizeof(int));
386}
387void
388MessageGrp::recv(int sender, int* data, int ndata)
389{
390 raw_recv(sender, data, ndata*sizeof(int));
391}
392void
393MessageGrp::recv(int sender, char* data, int ndata)
394{
395 raw_recv(sender, data, ndata);
396}
397void
398MessageGrp::recv(int sender, unsigned char* data, int ndata)
399{
400 raw_recv(sender, data, ndata);
401}
402void
403MessageGrp::recv(int sender, signed char* data, int ndata)
404{
405 raw_recv(sender, data, ndata);
406}
407
408// Typed send routines
409
410void
411MessageGrp::sendt(int target, int type, const double* data, int ndata)
412{
413 raw_sendt(target, type, data, ndata*sizeof(double));
414}
415void
416MessageGrp::sendt(int target, int type, const short* data, int ndata)
417{
418 raw_sendt(target, type, data, ndata*sizeof(short));
419}
420void
421MessageGrp::sendt(int target, int type, const long* data, int ndata)
422{
423 raw_sendt(target, type, data, ndata*sizeof(long));
424}
425void
426MessageGrp::sendt(int target, int type, const float* data, int ndata)
427{
428 raw_sendt(target, type, data, ndata*sizeof(float));
429}
430void
431MessageGrp::sendt(int target, int type, const unsigned int* data, int ndata)
432{
433 raw_sendt(target, type, data, ndata*sizeof(int));
434}
435void
436MessageGrp::sendt(int target, int type, const int* data, int ndata)
437{
438 raw_sendt(target, type, data, ndata*sizeof(int));
439}
440void
441MessageGrp::sendt(int target, int type, const char* data, int ndata)
442{
443 raw_sendt(target, type, data, ndata);
444}
445void
446MessageGrp::sendt(int target, int type, const unsigned char* data, int ndata)
447{
448 raw_sendt(target, type, data, ndata);
449}
450void
451MessageGrp::sendt(int target, int type, const signed char* data, int ndata)
452{
453 raw_sendt(target, type, data, ndata);
454}
455
456// Typed receive routines
457
458void
459MessageGrp::recvt(int type, double* data, int ndata)
460{
461 raw_recvt(type, data, ndata*sizeof(double));
462}
463void
464MessageGrp::recvt(int type, short* data, int ndata)
465{
466 raw_recvt(type, data, ndata*sizeof(short));
467}
468void
469MessageGrp::recvt(int type, long* data, int ndata)
470{
471 raw_recvt(type, data, ndata*sizeof(long));
472}
473void
474MessageGrp::recvt(int type, float* data, int ndata)
475{
476 raw_recvt(type, data, ndata*sizeof(float));
477}
478void
479MessageGrp::recvt(int type, unsigned int* data, int ndata)
480{
481 raw_recvt(type, data, ndata*sizeof(int));
482}
483void
484MessageGrp::recvt(int type, int* data, int ndata)
485{
486 raw_recvt(type, data, ndata*sizeof(int));
487}
488void
489MessageGrp::recvt(int type, char* data, int ndata)
490{
491 raw_recvt(type, data, ndata);
492}
493void
494MessageGrp::recvt(int type, unsigned char* data, int ndata)
495{
496 raw_recvt(type, data, ndata);
497}
498void
499MessageGrp::recvt(int type, signed char* data, int ndata)
500{
501 raw_recvt(type, data, ndata);
502}
503
504// Broadcast operations
505
506void
507MessageGrp::bcast(double*data, int ndata, int from)
508{
509 raw_bcast(data, ndata*sizeof(double), from);
510}
511void
512MessageGrp::bcast(short*data, int ndata, int from)
513{
514 raw_bcast(data, ndata*sizeof(short), from);
515}
516void
517MessageGrp::bcast(long*data, int ndata, int from)
518{
519 raw_bcast(data, ndata*sizeof(long), from);
520}
521void
522MessageGrp::bcast(float*data, int ndata, int from)
523{
524 raw_bcast(data, ndata*sizeof(float), from);
525}
526void
527MessageGrp::bcast(unsigned int*data, int ndata, int from)
528{
529 raw_bcast(data, ndata*sizeof(int), from);
530}
531void
532MessageGrp::bcast(int*data, int ndata, int from)
533{
534 raw_bcast(data, ndata*sizeof(int), from);
535}
536void
537MessageGrp::bcast(char*data, int ndata, int from)
538{
539 raw_bcast(data, ndata, from);
540}
541void
542MessageGrp::bcast(unsigned char*data, int ndata, int from)
543{
544 raw_bcast(data, ndata, from);
545}
546void
547MessageGrp::bcast(signed char*data, int ndata, int from)
548{
549 raw_bcast(data, ndata, from);
550}
551
552// Global classdesc indices
553
554int
555MessageGrp::classdesc_to_index(const ClassDesc* cdptr)
556{
557 if (classdesc_to_index_.find((ClassDesc*)cdptr) != classdesc_to_index_.end()) {
558 return classdesc_to_index_[(ClassDesc*)cdptr];
559 }
560 else {
561 return -1;
562 }
563}
564
565const ClassDesc*
566MessageGrp::index_to_classdesc(int index)
567{
568 if (index < 0 || index >= nclass_) {
569 return 0;
570 }
571 else {
572 return index_to_classdesc_[index];
573 }
574}
575
576void
577MessageGrp::raw_bcast(void* data, int nbyte, int from)
578{
579 int nbyte_actual = nbyte;
580 int tgop_max = nbyte;
581 if (gop_max_ != 0) {
582 tgop_max = gop_max_;
583 gop_max_ = 0;
584 bcast(nbyte_actual,from);
585 gop_max_ = tgop_max;
586 }
587 for (int idat=0; idat<nbyte_actual; idat+=tgop_max) {
588 int ndat = (idat+tgop_max>nbyte_actual)?(nbyte_actual-idat):tgop_max;
589 Ref<GlobalMsgIter> i(topology_->global_msg_iter(this, from));
590 for (i->forwards(); !i->done(); i->next()) {
591 if (i->send()) {
592 raw_send(i->sendto(), &((char*)data)[idat], ndat);
593 }
594 if (i->recv()) {
595 raw_recv(i->recvfrom(), &((char*)data)[idat], ndat);
596 }
597 }
598 }
599}
600
601void
602MessageGrp::sync()
603{
604 Ref<GlobalMsgIter> i(topology_->global_msg_iter(this, 0));
605
606 for (i->backwards(); !i->done(); i->next()) {
607 if (i->send()) {
608 raw_send(i->sendto(), 0, 0);
609 }
610 if (i->recv()) {
611 raw_recv(i->recvfrom(), 0, 0);
612 }
613 }
614
615 for (i->forwards(); !i->done(); i->next()) {
616 if (i->send()) {
617 raw_send(i->sendto(), 0, 0);
618 }
619 if (i->recv()) {
620 raw_recv(i->recvfrom(), 0, 0);
621 }
622 }
623}
624
625void
626MessageGrp::collect(const double *part, const int *lengths, double *whole)
627{
628 raw_collect(part,lengths,whole,sizeof(double));
629}
630
631void
632MessageGrp::raw_collect(const void *part, const int *lengths, void *whole,
633 int bytes_per_datum)
634{
635 int offset = 0;
636 for (int i=0; i<n_; i++) {
637 int nbytes = lengths[i];
638 if (i==me_) memcpy(&((char*)whole)[offset], part, nbytes);
639 raw_bcast(&((char*)whole)[offset], nbytes, i);
640 offset += nbytes;
641 }
642}
643
644/////////////////////////////////////////////////////////////////////////////
645
646// Local Variables:
647// mode: c++
648// c-file-style: "CLJ"
649// End:
Note: See TracBrowser for help on using the repository browser.