Paramotopy
parallel parameter homotopy through bertini
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
master.cpp
Go to the documentation of this file.
1 
2 #include "master.hpp"
3 
4 
5 
6 
7 
8 
10  runinfo input_p_info,
11  timer & process_timer)
12 
13 {
14  this->paramotopy_settings = input_settings;
15  this->paramotopy_info = input_p_info;
16 
17 
18  //some data members used in this function
19 
21 
23 
25 
27 
29 
30  master_process::SendStart(process_timer);
31 
32  master_process::SendInput(process_timer);
33 
34  master_process::SeedSwitch(process_timer);
35 
36  master_process::LoopSwitch(process_timer);
37 
38  master_process::CleanupSwitch(process_timer);
39 
40 
41 
42 }//re:master
43 
44 
53 
54 
55 
56 
57 
58 
59 
60 
61 
62 
63 
64 
65 
66 
68 {
69 
71  this->numfilesatatime = paramotopy_settings.settings["parallelism"]["numfilesatatime"].intvalue;
72  this->numfilesatatime_orig = paramotopy_settings.settings["parallelism"]["numfilesatatime"].intvalue;
73 
75  this->standardstep2 = paramotopy_settings.settings["mode"]["standardstep2"].intvalue;
76 
77 
79  this->lastoutfilename /= "step2/lastnumsent";
80 
81 }
82 
83 
84 
85 
86 
87 
88 
90 //
91 // some subfunctions
92 //
94 
95 
96 
97 
98 // the master is responsible for generating the data points to work on, and distributing them to the workers.
99 
100 
101 
102 void master_process::NextRandomValue(int pointcounter, // localcounter tells which indices in tempsends
103  double tempsends[]) // holds the created data
104 {
105  MTRand drand;
106 
107  //assign the data
108  for (int ii=0; ii<numparam; ++ii) {
109  double rand_real = drand(), rand_imag = drand();
110 
111  rand_real*=(paramotopy_info.BoundsRight[ii].first
112  - paramotopy_info.BoundsLeft[ii].first);
113  rand_real+=paramotopy_info.BoundsLeft[ii].first;
114 
115  rand_imag*=(paramotopy_info.BoundsRight[ii].second
116  - paramotopy_info.BoundsLeft[ii].second);
117  rand_imag+=paramotopy_info.BoundsLeft[ii].second;
118 
119 
120  tempsends[pointcounter*(2*numparam+1)+2*ii] = rand_real;//for sending to workers, to write into data files.
121  tempsends[pointcounter*(2*numparam+1)+2*ii+1] = rand_imag;
122  }
123  tempsends[pointcounter*(2*numparam+1)+2*numparam] = current_absolute_index;//the line number in mc file
124 
125  return;
126 
127 }
128 
129 
130 // FormNextValues generates parameter points from a mesh-style set
131 void master_process::FormNextValues(int pointcounter,
132  std::vector< std::vector< std::pair<double,double> > > Values,
133  double tempsends[]){
134 
135  int index, I,J;
136  std::vector< int > indexvector;//for forming a subscript from an index, for !userdefined case
137  indexvector.resize(numparam);
138 
139 
140 
141  //get subscripts (zero-based) for the index, current_absolute_index
142  index = current_absolute_index;
143  for (int jj=numparam-1; jj>-1; --jj) {
144  I = (index)%index_conversion_vector[jj];
145  J = (index - I)/index_conversion_vector[jj];
146  indexvector[jj] = J;
147  index = I;
148  }
149 
150  //assign the data
151  for (int jj=0; jj<numparam; ++jj) {
152  tempsends[pointcounter*(2*numparam+1)+2*jj] = Values[jj][ indexvector[jj] ].first;//for sending to workers, to write into data files.
153  tempsends[pointcounter*(2*numparam+1)+2*jj+1] = Values[jj][ indexvector[jj] ].second;
154  }
155  tempsends[pointcounter*(2*numparam+1)+2*numparam] = current_absolute_index;//the line number in mc file
156 
157  return;
158 }
159 
160 
161 
162 
163 
164 //FormNextValues_mc generates points to send, from a user-defined set
165 void master_process::FormNextValues_mc(int pointcounter, //another integer counter
166  double tempsends[]){ //tempsends holds the values to send
167 
168 
169  std::string temp;
170  getline(this->mc_in_stream,temp);
171  std::vector< std::pair<double, double> > CValues;
172  std::stringstream ss;
173  ss << temp;
174 
175  for (int jj = 0; jj < numparam;++jj){
176  ss >> tempsends[pointcounter*(2*numparam+1)+2*jj];
177  ss >> tempsends[pointcounter*(2*numparam+1)+2*jj+1];
178  }
179 
180 
181 
182  tempsends[pointcounter*(2*numparam+1)+2*numparam] = current_absolute_index;//the line number in mc file
183 
184 
185 
186 
187  return;
188 
189 }
190 
191 
192 
193 
194 
195 
196 
197 
198 
199 
200 
201 
202 
203 
204 
205 
206 
207 
208 void master_process::SeedSwitch(timer & process_timer){
209 
210 
211 
212  switch (paramotopy_settings.settings["mode"]["main_mode"].intvalue) {
213  case 0:
214  master_process::SeedBasic(process_timer);
215  break;
216 
217  case 1:
218  master_process::SeedSearch(process_timer);
219  break;
220 
221 
222  default:
223 
224  std::cerr << "invalid main_mode setting" << std::endl;
225  MPI_Abort(MPI_COMM_WORLD, 54);
226  break;
227  }
228 
229 }//re: seed process switch
230 
231 
232 
233 void master_process::SeedBasic(timer & process_timer){
234 
235 
236  this->current_absolute_index = 0;
237 
238  double* tempsends = new double[(numprocs-1)*numfilesatatime*(2*paramotopy_info.numparam+1)];//for sending to workers, to print into datacollected files
239 
240 
242  // make initial data to send to the workers
244 
245 
246 
247  for (int proc_count=1;proc_count<(numprocs);++proc_count){
248  int numtodo = std::min( numfilesatatime, std::max(terminationint-current_absolute_index,0) );
249 
250 
251  if (numtodo>0) {
252 
254 
255  for (int ii = 0; ii <numtodo; ++ii){
256  //determine the parameter values for this file
257 
260  tempsends);
261  }
262  else {//not user defined
265  tempsends);
266 
267  if (paramotopy_settings.settings["files"]["writemeshtomc"].intvalue==1){
268 #ifdef timingstep2
269  process_timer.press_start("write");
270 #endif
271  for (int jj=0; jj<paramotopy_info.numparam; ++jj) {
272  mc_out_stream << tempsends[2*jj]
273  << " " << tempsends[2*jj+1] << " ";
274  }
275  mc_out_stream << std::endl;
276 #ifdef timingstep2
277  process_timer.add_time("write");
278 #endif
279  }// if
280  } // else
281 
282  //increment
283  current_absolute_index++; //for keeping track of folder to write to
284 
285  }//re: for int ii=lastnumsent[proc_count]
286 
287 #ifdef timingstep2
288  process_timer.press_start("send");
289 #endif
290  /* Send the slave a new work unit */
291  MPI_Send(&numtodo, /* message buffer */
292  1, /* how many data items */
293  MPI_INT, /* data item is an integer */
294  proc_count, /* the destination */
295  NUM_PACKETS, /* user chosen message tag */
296  MPI_COMM_WORLD); /* default communicator */
297 #ifdef timingstep2
298  process_timer.add_time("send");
299 #endif
300 
301 
302 
303 #ifdef timingstep2
304  process_timer.press_start("send");
305 #endif
306  /* Send the slave a new work unit */
307  MPI_Send(&tempsends[0], /* message buffer */
308  numtodo*(2*paramotopy_info.numparam+1), /* how many data items */
309  MPI_DOUBLE, /* data item is an integer */
310  proc_count, /* to who we just received from */
311  DATA_DOUBLE, /* user chosen message tag */
312  MPI_COMM_WORLD); /* default communicator */
313 #ifdef timingstep2
314  process_timer.add_time("send");
315 #endif
316 
317 
318  //now send them here
319 
320  active_workers[proc_count] = true;
322 
323  }//re: if numtodo>0
324  else{
325  lastnumsent.push_back(-1);
326  //just send a kill tag
327  master_process::TerminateInactiveWorker(proc_count,process_timer);
328  }
329  }//re: for int proc_count=1:numprocs
330 
331 
332 
333 }
334 
335 
336 void master_process::SeedSearch(timer & process_timer){
337 
338 
339 
340 
341  this->current_absolute_index = 0;
342 
343  double* tempsends = new double[(numprocs-1)*numfilesatatime*(2*paramotopy_info.numparam+1)];//for sending to workers, to print into datacollected files
344 
345 
347  // make initial data to send to the workers
349 
351  std::cerr << "invalid userdefined mode inside search mode" << std::endl;
352  MPI_Abort(MPI_COMM_WORLD,438);
353  }
354 
355 
356  if (paramotopy_settings.settings["mode"]["search_desirednumber"].intvalue <= (numprocs-1)) {
357  numfilesatatime = 1;
358  }
359  else
360  {
361  double fractpart, intpart;
362  fractpart = modf ( double(paramotopy_settings.settings["mode"]["search_desirednumber"].intvalue)/double((numprocs-1)), &intpart);
363 
364 
365  numfilesatatime = int(std::max(int(intpart), numfilesatatime));
366  }
367 
368 
369  for (int proc_count=1;proc_count<(numprocs);++proc_count){
370 
371  int numtodo = std::min( numfilesatatime, std::max(terminationint-current_absolute_index,0) );
372 
373 
374  if (numtodo>0) {
375 
377 
378  for (int ii = 0; ii <numtodo; ++ii){
379 
380 
381  master_process::NextRandomValue(ii, // current index in tempsends
382  tempsends); // data to fill
383 
384  if (paramotopy_settings.settings["files"]["writemeshtomc"].intvalue==1){
385 #ifdef timingstep2
386  process_timer.press_start("write");
387 #endif
388  for (int jj=0; jj<paramotopy_info.numparam; ++jj) {
389  mc_out_stream << tempsends[2*jj+ii*(2*paramotopy_info.numparam+1)]
390  << " " << tempsends[2*jj+1 +ii*(2*paramotopy_info.numparam+1)] << " ";
391  }
392  mc_out_stream << std::endl;
393 #ifdef timingstep2
394  process_timer.add_time("write");
395 #endif
396  }// if
397 
398  //increment
399  current_absolute_index++; //for keeping track of folder to write to
400 
401  }//re: for int ii=lastnumsent[proc_count]
402 
403 #ifdef timingstep2
404  process_timer.press_start("send");
405 #endif
406  /* Send the slave a new work unit */
407  MPI_Send(&numtodo, /* message buffer */
408  1, /* how many data items */
409  MPI_INT, /* data item is an integer */
410  proc_count, /* the destination */
411  NUM_PACKETS, /* user chosen message tag */
412  MPI_COMM_WORLD); /* default communicator */
413 #ifdef timingstep2
414  process_timer.add_time("send");
415 #endif
416 
417 
418 
419 #ifdef timingstep2
420  process_timer.press_start("send");
421 #endif
422  /* Send the slave a new work unit */
423  MPI_Send(&tempsends[0], /* message buffer */
424  numtodo*(2*paramotopy_info.numparam+1), /* how many data items */
425  MPI_DOUBLE, /* data item is an integer */
426  proc_count, /* to who we just received from */
427  DATA_DOUBLE, /* user chosen message tag */
428  MPI_COMM_WORLD); /* default communicator */
429 #ifdef timingstep2
430  process_timer.add_time("send");
431 #endif
432 
433 
434  //now send them here
435 
436  active_workers[proc_count] = true;
438 
439  }//re: if numtodo>0
440  else{
441  lastnumsent.push_back(-1);
442  //just send a kill tag
443  master_process::TerminateInactiveWorker(proc_count,process_timer);
444  }
445  }//re: for int proc_count=1:numprocs
446 
447 
448 
449 
450 
451 
452 }
453 
454 
455 
456 
457 void master_process::LoopSwitch(timer & process_timer){
458 
459 
460  switch (paramotopy_settings.settings["mode"]["main_mode"].intvalue) {
461  case 0:
462  master_process::LoopBasic(process_timer);
463  break;
464 
465  case 1:
466  master_process::LoopSearch(process_timer);
467  break;
468 
469 
470  default:
471  break;
472  }
473 
474 
475 
476 }//re: while loop switch
477 
478 
479 void master_process::LoopBasic(timer & process_timer){
480 
481 
482  MPI_Status status;
483  int numtodo;
484  /* Loop over getting new work requests
485  until there is no more work
486  to be done */
487 
488  double* tempsends = new double[numfilesatatime*(2*paramotopy_info.numparam+1)];
489 
490 
491  int lastlineprocessed = -1;
492 
494 
495 
496  while (current_absolute_index < this->terminationint) {
497 
498 #ifdef timingstep2
499  process_timer.press_start("receive");
500 #endif
501  /* Receive results from a slave */
502  MPI_Recv(&lastlineprocessed, /* message buffer */
503  1, /* one data item */
504  MPI_INT, /* of type int */
505  MPI_ANY_SOURCE, /* receive from any sender */
506  MPI_ANY_TAG, /* any type of message */
507  MPI_COMM_WORLD, /* default communicator */
508  &status); /* info about the received message */
509 
510 
511 #ifdef timingstep2
512  process_timer.add_time("receive");
513 #endif
514 
515 
516  //figure out how many files to do
517  numtodo = numfilesatatime;
518  if (numtodo+current_absolute_index>=terminationint) {
519  numtodo = terminationint - current_absolute_index;
520  }
521 
522 
523 
524  // numtodo guaranteed >0
525 #ifdef timingstep2
526  process_timer.press_start("send");
527 #endif
528  /* Send the slave a new work unit */
529  MPI_Send(&numtodo, /* message buffer */
530  1, /* how many data items */
531  MPI_INT, /* data item is an integer */
532  status.MPI_SOURCE, /* to who we just received from */
533  NUM_PACKETS, /* user chosen message tag */
534  MPI_COMM_WORLD); /* default communicator */
535 #ifdef timingstep2
536  process_timer.add_time("send");
537 #endif
538 
539 
540  int smallestnumsent = current_absolute_index;
541 
542  // make tempsends in the step2 loop
543 
544  memset(tempsends, 0, numtodo*(2*paramotopy_info.numparam+1)*sizeof(double) );
545 
546  for (int ii = 0; ii < numtodo; ++ii){
547 
548  if (paramotopy_info.userdefined==1) {
549 #ifdef timingstep2
550  process_timer.press_start("read");
551 #endif
552  master_process::FormNextValues_mc(ii,tempsends);
553 #ifdef timingstep2
554  process_timer.add_time("read");
555 #endif
556  }
557  else {
560  tempsends);
561 
562 
563  if (paramotopy_settings.settings["files"]["writemeshtomc"].intvalue==1){
564 #ifdef timingstep2
565  process_timer.press_start("write");
566 #endif //write the mc line if not userdefined
567 
568  for (int jj=0; jj<paramotopy_info.numparam; ++jj) {
569  mc_out_stream << tempsends[ii*(2*paramotopy_info.numparam+1)+2*jj] << " "
570  << tempsends[ii*(2*paramotopy_info.numparam+1)+2*jj+1] << " ";
571  }
572  mc_out_stream << std::endl;
573 #ifdef timingstep2
574  process_timer.add_time("write");
575 #endif
576  }
577  }//re: else
578 
579 
580  current_absolute_index++; //increment
581  } //re: make tempsends in the step2 loop
582 
583 
584 #ifdef timingstep2
585  process_timer.press_start("send");
586 #endif
587  /* Send the slave a new work unit */
588  MPI_Send(&tempsends[0], /* message buffer */
589  numtodo*(2*paramotopy_info.numparam+1), /* how many data items */
590  MPI_DOUBLE, /* data item is an integer */
591  status.MPI_SOURCE, /* to who we just received from */
592  DATA_DOUBLE, /* user chosen message tag */
593  MPI_COMM_WORLD); /* default communicator */
594 #ifdef timingstep2
595  process_timer.add_time("send");
596 #endif
597 
598 
599 
600  lastnumsent[status.MPI_SOURCE] = smallestnumsent;
601 
602 
603  std::stringstream tempss;
604  for (int ii=1; ii<numprocs; ++ii) {
605  tempss << lastnumsent[ii] << "\n";
606  }
607 
608 #ifdef timingstep2
609  process_timer.press_start("write");
610 #endif
611  std::ofstream lastout;
612  lastout.open(lastoutfilename.c_str());
613 
614  lastout << tempss.str();
615  lastout.close();
616  lastout.clear();
617 #ifdef timingstep2
618  process_timer.add_time("write");
619 #endif
620 
621 
622 
623  } //re: while loop
624 
625 
626 
627  delete[] tempsends;
628 }// re: loop basic
629 
630 
631 
632 
633 
634 
635 
636 
637 void master_process::LoopSearch(timer & process_timer){
638 
639 
640 
641 
642 
643  MPI_Status status;
644  int numtodo;
645  /* Loop over getting new work requests
646  until there is no more work
647  to be done */
648 
649  double* tempsends = new double[numfilesatatime*(2*paramotopy_info.numparam+1)];
650 
651 
652  int num_solns_this_iteration = -1;
653 
655 
656 
657  int num_found_solns = 0;
658 
659 
660  while ((num_found_solns < paramotopy_settings.settings["mode"]["search_desirednumber"].intvalue) && (current_absolute_index < terminationint) ) {
661 
662 
665  }
666 #ifdef timingstep2
667  process_timer.press_start("receive");
668 #endif
669  /* Receive results from a slave */
670  MPI_Recv(&num_solns_this_iteration, /* message buffer */
671  1, /* one data item */
672  MPI_INT, /* of type int */
673  MPI_ANY_SOURCE, /* receive from any sender */
674  MPI_ANY_TAG, /* any type of message */
675  MPI_COMM_WORLD, /* default communicator */
676  &status); /* info about the received message */
677 #ifdef timingstep2
678  process_timer.add_time("receive");
679 #endif
680 
681  num_found_solns += num_solns_this_iteration;
682  //figure out how many files to do
683  numtodo = numfilesatatime;
684  if (numtodo+current_absolute_index>=terminationint) {
686  }
687 
688  if (num_found_solns>=paramotopy_settings.settings["mode"]["search_desirednumber"].intvalue) {
689  master_process::TerminateActiveWorker(status.MPI_SOURCE, process_timer);
690  break;
691  }
692  else{
693 
694  // numtodo guaranteed >0
695 #ifdef timingstep2
696  process_timer.press_start("send");
697 #endif
698  /* Send the slave a new work unit */
699  MPI_Send(&numtodo, /* message buffer */
700  1, /* how many data items */
701  MPI_INT, /* data item is an integer */
702  status.MPI_SOURCE, /* to who we just received from */
703  NUM_PACKETS, /* user chosen message tag */
704  MPI_COMM_WORLD); /* default communicator */
705 #ifdef timingstep2
706  process_timer.add_time("send");
707 #endif
708  }
709 
710 
711  if (numtodo>0) {
712 
713  int smallestnumsent = current_absolute_index;
714 
715  // make tempsends in the step2 loop
716 
717  memset(tempsends, 0, numtodo*(2*paramotopy_info.numparam+1)*sizeof(double) );
718 
719  for (int ii = 0; ii < numtodo; ++ii){
720 
721  master_process::NextRandomValue(ii, // current index in tempsends
722  tempsends); // data to fill
723 
724  if (paramotopy_settings.settings["files"]["writemeshtomc"].intvalue==1){
725 #ifdef timingstep2
726  process_timer.press_start("write");
727 #endif //write the mc line if not userdefined
728 
729  for (int jj=0; jj<paramotopy_info.numparam; ++jj) {
730  mc_out_stream << tempsends[ii*(2*paramotopy_info.numparam+1)+2*jj] << " "
731  << tempsends[ii*(2*paramotopy_info.numparam+1)+2*jj+1] << " ";
732  }
733  mc_out_stream << std::endl;
734 #ifdef timingstep2
735  process_timer.add_time("write");
736 #endif
737  }
738 
739 
740  current_absolute_index++; //increment
741  } //re: make tempsends in the step2 loop
742 
743 
744 #ifdef timingstep2
745  process_timer.press_start("send");
746 #endif
747  /* Send the slave a new work unit */
748  MPI_Send(&tempsends[0], /* message buffer */
749  numtodo*(2*paramotopy_info.numparam+1), /* how many data items */
750  MPI_DOUBLE, /* data item is an integer */
751  status.MPI_SOURCE, /* to who we just received from */
752  DATA_DOUBLE, /* user chosen message tag */
753  MPI_COMM_WORLD); /* default communicator */
754 #ifdef timingstep2
755  process_timer.add_time("send");
756 #endif
757 
758 
759 
760  lastnumsent[status.MPI_SOURCE] = smallestnumsent;
761 
762 
763  std::stringstream tempss;
764  for (int ii=1; ii<numprocs; ++ii) {
765  tempss << lastnumsent[ii] << "\n";
766  }
767 
768 #ifdef timingstep2
769  process_timer.press_start("write");
770 #endif
771  std::ofstream lastout;
772  lastout.open(lastoutfilename.c_str());
773 
774  lastout << tempss.str();
775  lastout.close();
776  lastout.clear();
777 #ifdef timingstep2
778  process_timer.add_time("write");
779 #endif
780 
781 
782  }//re: if numtodo>0
783 
784 
785  } //re: while loop
786 
787 
788 
789  delete[] tempsends;
790 
791 
792 
793 
794 }//re: LoopSearch()
795 
796 
797 
798 
799 
800 
801 
802 
803 
804 
805 
813 //
814 
815 
816 
817 
818 void master_process::CleanupSwitch(timer & process_timer){
819 
820 
821  switch (paramotopy_settings.settings["mode"]["main_mode"].intvalue) {
822 
823  case 0:
824  master_process::CleanupBasic(process_timer);
825  break;
826 
827  case 1: // also uses the basic cleanup method
828  master_process::CleanupSearch(process_timer);
829  break;
830 
831  default:
832  break;
833  }
834 
835 
836  int arbitraryinteger = 1;
837  MPI_Bcast(&arbitraryinteger, 1, MPI_INT, 0, MPI_COMM_WORLD); // could also be MPI_Barrier()
838 
839  if (paramotopy_settings.settings["files"]["deletetmpfilesatend"].intvalue==1) {
840  boost::filesystem::path temppath(tmpfolder);
841  boost::filesystem::remove_all(tmpfolder);
842  }
843 
844 
845 }//re: cleanup switch
846 
847 
848 
849 void master_process::CleanupBasic(timer & process_timer){
850  /* There's no more work to be done, so receive all the outstanding
851  results from the slaves. */
852 
853 
854 
855  int* receive_buffer = new int[1];
856  MPI_Status status;
857  int killcounter = 0;
858 
859  if (num_active_workers!=int(active_workers.size())) {
860  std::cerr << "discrepancy in number of active workers" << std::endl;
861  MPI_Abort(MPI_COMM_WORLD, 778);
862  }
863  else{
864  std::cout << "number of workers is correct at cleanup" << std::endl;
865  }
866 
867  while (num_active_workers>0) {
868 
869 
870 #ifdef timingstep2
871  process_timer.press_start("receive");
872 #endif
873  MPI_Recv(&receive_buffer[0],
874  1,
875  MPI_INT,
876  MPI_ANY_SOURCE,
877  MPI_ANY_TAG,
878  MPI_COMM_WORLD,
879  &status);
880 #ifdef timingstep2
881  process_timer.add_time("receive");
882 #endif
883 
884  master_process::TerminateActiveWorker(status.MPI_SOURCE, process_timer);
885 
886 
887  std::map< int, bool>::iterator iter;
888  std::stringstream printme;
889  printme << "remaining active workers:\n";
890  for (iter=active_workers.begin(); iter!=active_workers.end(); ++iter) {
891  printme << "worker" << iter->first << "\n";
892  }
893  printme << std::endl;
894 
895  std::cout << printme.str();
896  killcounter++;
897  }
898 
899 
900 #ifdef timingstep2
901  process_timer.press_start("write");
902 #endif
903 
904  if (paramotopy_info.userdefined!=1 && paramotopy_settings.settings["files"]["writemeshtomc"].intvalue==1){
905  mc_out_stream.clear();
906  mc_out_stream.seekp(0, std::ios::beg); // return to the beginning to write the number at the top.
907  // we left plenty of space at the top for this number
909  mc_out_stream.close();
910  }
911 
913  mc_in_stream.close();
914 
915  boost::filesystem::path finishedfile = paramotopy_info.location;
916  finishedfile /= "step2finished";
917 
918  std::ofstream fout;
919  fout.open(finishedfile.c_str());
920  fout << 1;
921  fout.close();
922 
923 #ifdef timingstep2
924  process_timer.add_time("write");
925 #endif
926 
927  delete[] receive_buffer;
928 
929 }//re: cleanup basic
930 
931 
932 
933 void master_process::CleanupSearch(timer & process_timer){
934 
935  master_process::CleanupBasic(process_timer);
936 
937 }
938 
939 
940 
941 
942 
943 
944 
945 
946 
947 
948 
949 
950 void master_process::SendStart(timer & process_timer){
951 
952 
953 
954 
955 #ifdef timingstep2
956  process_timer.press_start("read");
957 #endif
958  // read in the start file
959  std::string start;
961  start, // <-- reads into memory here
962  paramotopy_settings.settings["mode"]["startfilename"].value());
963 #ifdef timingstep2
964  process_timer.add_time("read");
965 #endif
966 
967  int start_length = start.size() + 1; // + 1 to account for null character
968 
969  char *start_send = new char[start_length];
970  for (int ii = 0; ii < int(start.size()); ++ii){
971  start_send[ii] = start[ii];
972  }
973  start_send[start.size()] = '\0';
974 
975 
976 
977 
978 #ifdef timingstep2
979  process_timer.press_start("send");
980 #endif
981 
982  for (int ii = 1; ii < numprocs; ++ii){
983  MPI_Send(&start_length, 1, MPI_INT, ii, NUM_CHARACTERS, MPI_COMM_WORLD);
984  }
985 #ifdef timingstep2
986  process_timer.add_time("send",numprocs-1);
987 #endif
988 
989 
990 
991 
992 
993 #ifdef timingstep2
994  process_timer.press_start("send");
995 #endif
996  for (int ii = 1; ii < numprocs; ++ii){
997  MPI_Send(&start_send[0], start_length, MPI_CHAR, ii, TEXT_FILE, MPI_COMM_WORLD);
998  }
999 #ifdef timingstep2
1000  process_timer.add_time("send",numprocs-1);
1001 #endif
1002 
1003 
1004  delete[] start_send;
1005 
1006 
1007 }
1008 
1009 
1010 
1011 
1012 
1013 void master_process::SendInput(timer & process_timer){
1014 
1015 
1016 
1017 
1018  // for the step 2 memory setup for bertini, we need random values
1019  std::vector<std::pair<double, double> > tmprandomvalues = paramotopy_info.MakeRandomValues(rand());
1020 
1021 
1022 
1023  std::string inputstring;
1024  switch (paramotopy_info.steptwomode) {
1025  case 2:
1026  inputstring = WriteStep2(tmprandomvalues,
1028  paramotopy_info); // found in the step2_funcs.* files
1029 
1030  break;
1031  case 3:
1032  inputstring = WriteFailStep2(tmprandomvalues,
1034  paramotopy_info); // found in the step2_funcs.* files
1035 
1036  break;
1037  default:
1038  std::cerr << "bad steptwomode: " << paramotopy_info.steptwomode << " -- exiting!" << std::endl;
1039  exit(-202);
1040  break;
1041  }
1042 
1043 
1044 
1045 #ifdef verbosestep2
1046  std::cout << "the input file is:\n " << inputstring << std::endl;
1047 #endif
1048 
1049 
1050  int input_length = inputstring.size() + 1; // + 1 to account for null character
1051 #ifdef timingstep2
1052  process_timer.press_start("send");
1053 #endif
1054  for (int ii = 1; ii < numprocs; ++ii){
1055  MPI_Send(&input_length, 1, MPI_INT, ii, NUM_CHARACTERS, MPI_COMM_WORLD);
1056  }
1057 #ifdef timingstep2
1058  process_timer.add_time("send",numprocs-1);
1059 #endif
1060 
1061 
1062  char *input_send = new char[input_length];
1063  for (int ii = 0; ii < int(inputstring.size()); ++ii){
1064  input_send[ii] = inputstring[ii];
1065  }
1066  input_send[inputstring.size()] = '\0';
1067 
1068 #ifdef timingstep2
1069  process_timer.press_start("send");
1070 #endif
1071  for (int ii = 1; ii < numprocs; ++ii){
1072  MPI_Send(&input_send[0], input_length, MPI_CHAR, ii, TEXT_FILE, MPI_COMM_WORLD);
1073  }
1074 #ifdef timingstep2
1075  process_timer.add_time("send",numprocs-1); //one for each worker
1076 #endif
1077 
1078 
1079  delete[] input_send;
1080 }
1081 
1082 
1083 
1084 
1085 
1086 
1087 
1088 
1089 
1090 
1091 
1092 
1093 
1094 
1095 
1096 
1098 
1099 
1100  boost::filesystem::path mcfname = paramotopy_info.location;
1101  mcfname /= "mc";
1103  index_conversion_vector.push_back(1);
1104  for (int ii=1; ii<paramotopy_info.numparam; ++ii) {
1106  }
1107 
1108  if (paramotopy_settings.settings["mode"]["main_mode"].intvalue==0) {
1110  }
1111  else if (paramotopy_settings.settings["mode"]["main_mode"].intvalue==1){
1112  terminationint = paramotopy_settings.settings["mode"]["search_iterations"].intvalue;
1113  }
1114 
1115  }
1116 
1117  else {
1118 
1119  terminationint = GetMcNumLines(paramotopy_info.location,paramotopy_info.numparam); // verified correct for both newline terminated and not newline terminated. dab
1120  }
1121 
1122  return;
1123 
1124 };
1125 
1126 
1127 
1128 
1129 
1130 //opens the mc_in or mc_out file stream
1132 
1133 
1134  boost::filesystem::path mcfname = paramotopy_info.location;
1135  mcfname /= "mc";
1136 
1138  boost::filesystem::remove(mcfname);
1139 
1140  if (paramotopy_settings.settings["files"]["writemeshtomc"].intvalue==1){
1141  //open mc file for writing out to
1142  mc_out_stream.open(mcfname.c_str());
1143 
1144  //end open mc file
1145  if (!mc_out_stream.is_open()){
1146  std::cerr << "failed to open the parameter value out file: " << mcfname << std::endl;
1147  exit(11);
1148 
1149  }
1150  mc_out_stream << " " << std::endl;
1151  // mc_out_stream << terminationint << std::endl;
1152  }
1153  if (paramotopy_settings.settings["files"]["writemeshtomc"].intvalue==1){
1154  mc_out_stream.precision(16);
1155  }
1156  }
1157  else {
1158 
1159  mc_in_stream.open(mcfname.c_str(), std::ios::in);
1160  if (!mc_in_stream.is_open()){
1161  std::cerr << "critical error: failed to open mc file to read parameter values. filename: " << mcfname << std::endl;
1162  exit(10);
1163  }
1164  std::string burnme;
1165  std::getline(mc_in_stream,burnme); // burn the line containing the number of lines in the file
1166  }
1167 
1168  return;
1169 }
1170 
1171 
1172 
1174 
1175 
1176 
1177  std::stringstream templocation;
1178  if (paramotopy_settings.settings["files"]["customtmplocation"].intvalue==1){
1179  templocation << paramotopy_settings.settings["files"]["tempfilelocation"].value();
1180  }
1181  else {
1182  templocation << called_dir;
1183  }
1184  templocation << "/bfiles_" << paramotopy_info.inputfilename << "/tmpstep2";
1185 
1186 
1187  tmpfolder = templocation.str();
1188 
1189 }
1190 
1191 
1192 
1193 
1194 
1195 
1196 
1198 
1199 
1200  boost::filesystem::path DataCollectedbase_dir = paramotopy_info.location;
1201  DataCollectedbase_dir /= "step2/DataCollected";
1202  boost::filesystem::create_directories(DataCollectedbase_dir);
1203 
1204  //make text file with names of folders with data in them
1205  boost::filesystem::path mydirfname = paramotopy_info.location;
1206  mydirfname /= "folders";
1207  std::ofstream fout(mydirfname.c_str());
1208  if (!fout.is_open()){
1209  std::cerr << "failed to open " << mydirfname.string() << " to write folder names!\n";
1210  }
1211  else{
1212  for (int i = 1; i < numprocs;++i){
1213  std::stringstream converter;
1214  converter << i;
1215 
1216  boost::filesystem::path makeme = DataCollectedbase_dir;
1217  makeme /= "c";
1218 
1219  makeme += converter.str();
1220  converter.clear();
1221  converter.str("");
1222 
1223  fout << makeme.string() << "\n";
1224  boost::filesystem::create_directories(makeme);
1225  }
1226  }
1227  fout.close();
1228 
1229 }
1230 
1231 
1232 
1234  timer & process_timer)
1235 {
1236 
1237 
1238 
1239  int arbitraryinteger = 0;
1240 #ifdef timingstep2
1241  process_timer.press_start("send");
1242 #endif
1243  /* Send the slave a new work unit */
1244  MPI_Send(&arbitraryinteger, /* message buffer */
1245  1, /* how many data items */
1246  MPI_INT, /* data item is an integer */
1247  worker_id, /* the destination */
1248  TERMINATE, /* user chosen message tag */
1249  MPI_COMM_WORLD); /* default communicator */
1250 #ifdef timingstep2
1251  process_timer.add_time("send");
1252 #endif
1253 
1254  if (active_workers.find(worker_id)!=active_workers.end()) {
1255  std::cerr << "terminating an active worker as an inactive!\n";
1256  MPI_Abort(MPI_COMM_WORLD,690);
1257  }
1258 
1259 }
1260 
1262  timer & process_timer)
1263 {
1264 
1265 
1266 
1267  int arbitraryinteger = 0;
1268 #ifdef timingstep2
1269  process_timer.press_start("send");
1270 #endif
1271  /* Send the slave a new work unit */
1272  MPI_Send(&arbitraryinteger, /* message buffer */
1273  1, /* how many data items */
1274  MPI_INT, /* data item is an integer */
1275  worker_id, /* the destination */
1276  TERMINATE, /* user chosen message tag */
1277  MPI_COMM_WORLD); /* default communicator */
1278 #ifdef timingstep2
1279  process_timer.add_time("send");
1280 #endif
1281 
1282  if (active_workers.find(worker_id)==active_workers.end()) {
1283  std::cerr << "terminating an INactive worker as active!\n";
1284  MPI_Abort(MPI_COMM_WORLD,691);
1285  }
1286 
1287  active_workers.erase(worker_id);
1289 }
1290 
1291 
1293 {
1294 
1295  bool its_all_good = true;
1296  std::vector< std::string > reported_errors;
1297 
1298 
1299  if (numfilesatatime<0) {
1300  reported_errors.push_back("unset numfilesatatime");
1301  its_all_good = false;
1302  }
1303 
1304 
1305  if (terminationint<0) {
1306  reported_errors.push_back("unset terminationint");
1307  its_all_good = false;
1308  }
1309 
1310  if (tmpfolder.string().size()==0) {
1311  reported_errors.push_back("no tmpfolder");
1312  its_all_good = false;
1313  }
1314 
1315 
1316  if (!its_all_good){
1317  std::cerr << "master " << myid << " reported its not all good, with bad flags:\n";
1318 
1319  for (int ii=0; ii<int(reported_errors.size()); ii++) {
1320  std::cerr << "master flag" << ii << " " << reported_errors[ii] << std::endl;
1321  }
1322  std::cerr << "\n\nABORTING master " << myid << std::endl;
1323  MPI_Abort(MPI_COMM_WORLD, 652);
1324  }
1325 }
1326 
1327 
1328 
1329 
1330 
1331 
void NextRandomValue(int pointcounter, double tempsends[])
Definition: master.cpp:102
void SeedSwitch(timer &process_timer)
Definition: master.cpp:208
std::vector< int > index_conversion_vector
Definition: master.hpp:126
void GetTerminationInt()
Definition: master.cpp:1097
void LoopBasic(timer &process_timer)
Definition: master.cpp:479
int numprocs
number of processors in the communicator
Definition: master.hpp:101
std::map< int, bool > active_workers
map for tracking the active workers.
Definition: master.hpp:129
int steptwomode
Definition: runinfo.hpp:95
void SetTmpFolder()
Definition: master.cpp:1173
void ReadyCheck()
Definition: master.cpp:1292
void LoopSwitch(timer &process_timer)
Definition: master.cpp:457
std::vector< int > NumMeshPoints
Definition: runinfo.hpp:124
void TerminateInactiveWorker(int worker_id, timer &process_timer)
Definition: master.cpp:1233
void FormNextValues_mc(int pointcounter, double tempsends[])
Definition: master.cpp:165
void SendStart(timer &process_timer)
Definition: master.cpp:950
void CleanupBasic(timer &process_timer)
Definition: master.cpp:849
void MasterSetup()
Definition: master.cpp:67
std::ofstream mc_out_stream
parameter point out file
Definition: master.hpp:123
bool userdefined
Definition: runinfo.hpp:119
void CleanupSwitch(timer &process_timer)
Definition: master.cpp:818
runinfo paramotopy_info
the parsed paramotopy input file.
Definition: master.hpp:96
int GetMcNumLines(boost::filesystem::path base_dir, int numparam)
void SetUpFolders()
Definition: master.cpp:1197
boost::filesystem::path lastoutfilename
name of the progress file
Definition: master.hpp:118
int numparam
Definition: runinfo.hpp:64
void CleanupSearch(timer &process_timer)
Definition: master.cpp:933
void TerminateActiveWorker(int worker_id, timer &process_timer)
Definition: master.cpp:1261
void SeedSearch(timer &process_timer)
Definition: master.cpp:336
ProgSettings paramotopy_settings
the ProgSettings for this process
Definition: master.hpp:97
int myid
my MPI id relative to communicator
Definition: master.hpp:103
void OpenMC()
Definition: master.cpp:1131
void LoopSearch(timer &process_timer)
Definition: master.cpp:637
boost::filesystem::path filename
filename for problem
Definition: master.hpp:107
boost::filesystem::path tmpfolder
where the temp files at?
Definition: master.hpp:119
boost::filesystem::path called_dir
where was I when I was instantiated?
Definition: master.hpp:120
int numfilesatatime
current number of files passed out at each distribution
Definition: master.hpp:111
std::ifstream mc_in_stream
parameter point in file
Definition: master.hpp:124
int numparam
number of parameters in problem
Definition: master.hpp:105
void master_main(ProgSettings input_settings, runinfo input_p_info, timer &process_timer)
Definition: master.cpp:9
void SeedBasic(timer &process_timer)
Definition: master.cpp:233
int standardstep2
switch for total degree vs. coeff. homotopy
Definition: master.hpp:109
boost::filesystem::path inputfilename
Definition: runinfo.hpp:90
boost::filesystem::path location
Definition: runinfo.hpp:71
int numfilesatatime_orig
given number of files passed out at each distribution
Definition: master.hpp:112
int num_active_workers
parity checker
Definition: master.hpp:130
int current_absolute_index
the current absolute index.
Definition: master.hpp:115
categorymap settings
void add_time(const std::string timer_name)
Definition: timing.cpp:12
std::vector< std::pair< double, double > > MakeRandomValues(int garbageint)
Definition: runinfo.cpp:788
A class that stores the general program settings of Paramotopy.
std::vector< std::vector< std::pair< double, double > > > Values
Definition: runinfo.hpp:113
A class for the input file parser.
Definition: runinfo.hpp:41
std::string WriteFailStep2(std::vector< std::pair< double, double > > CValues, ProgSettings paramotopy_settings, runinfo paramotopy_info)
Definition: step2_funcs.cpp:40
std::string WriteStep2(std::vector< std::pair< double, double > > CValues, ProgSettings paramotopy_settings, runinfo paramotopy_info)
Definition: step2_funcs.cpp:23
void SendInput(timer &process_timer)
Definition: master.cpp:1013
int terminationint
maximum absolute_current_index value before loop breaks.
Definition: master.hpp:114
std::vector< std::pair< double, double > > BoundsLeft
Definition: runinfo.hpp:115
void press_start(const std::string timer_name)
Definition: timing.cpp:5
Capable of timing arbitrary categories of processes, using a map of timer_data's. ...
Definition: timing.hpp:71
std::vector< int > lastnumsent
progress tracker
Definition: master.hpp:99
std::vector< std::pair< double, double > > BoundsRight
Definition: runinfo.hpp:116
int GetStart(boost::filesystem::path dir, std::string &start, std::string startfilename)
void FormNextValues(int pointcounter, std::vector< std::vector< std::pair< double, double > > > Values, double tempsends[])
Definition: master.cpp:131