gambit is hosted by Hepforge, IPPP Durham
GAMBIT  v1.5.0-2191-ga4742ac
a Global And Modular Bsm Inference Tool
functors.cpp
Go to the documentation of this file.
1 // GAMBIT: Global and Modular BSM Inference Tool
2 // *********************************************
36 
37 #include <chrono>
38 
43 #include "gambit/Models/models.hpp"
44 #include "gambit/Logs/logger.hpp"
45 #include "gambit/Logs/logging.hpp"
46 
47 #include <boost/preprocessor/seq/for_each.hpp>
48 #include <boost/io/ios_state.hpp>
49 
50 namespace Gambit
51 {
52  using namespace LogTags;
53 
54  // Functor class methods
55 
57  functor::functor (str func_name,
58  str func_capability,
59  str result_type,
60  str origin_name,
62  myName (func_name),
63  myCapability (func_capability),
64  myType (Utils::fix_type(result_type)),
65  myOrigin (origin_name),
66  myClaw (&claw),
67  myLabel ("#"+func_capability+" @"+origin_name+"::"+func_name),
68  myTimingLabel ("Runtime(ns) for "+myLabel),
69  myStatus (0),
70  myVertexID (-1), // (Note: myVertexID = -1 is intended to mean that no vertexID has been assigned)
71  myTimingVertexID(-1), // Not actually a graph vertex; ID assigned by "get_main_param_id" function.
72  verbose (false) // For debugging.
73  {}
74 
77 
81  double functor::getRuntimeAverage() { return 0; }
82  double functor::getInvalidationRate() { return 0; }
83  void functor::setFadeRate(double) {}
85  void functor::reset() {}
86  void functor::reset(int) {}
88 
90  void functor::reset_and_calculate() { this->reset(omp_get_thread_num()); this->calculate(); }
91 
94 
96  void functor::setVertexID(int ID) { myVertexID = ID; }
97 
100 
108  void functor::setStatus(int stat)
109  {
110  myStatus = stat;
111  setInUse(myStatus == 2);
112  }
113 
115  str functor::name() const { return myName; }
119  str functor::type() const { return myType; }
121  str functor::origin() const { return myOrigin; }
123  str functor::version() const { return myVersion; }
125  str functor::safe_version()const { utils_error().raise(LOCAL_INFO,"The safe_version method is only defined for backend functors."); return ""; }
134  int functor::status() const { return myStatus; }
136  sspair functor::quantity() const { return std::make_pair(myCapability, myType); }
138  str functor::purpose() const { return myPurpose; }
140  int functor::vertexID() const { return myVertexID; }
144  bool functor::requiresPrinting() const { return false; }
146  bool functor::requiresTimingPrinting() const { return false; }
148  str functor::label() const { return myLabel; }
151 
154  {
155  if (flag)
156  {
157  utils_error().raise(LOCAL_INFO,"The setPrintRequirement method has not been defined in this class.");
158  }
159  }
160 
163  {
164  if (flag)
165  {
166  utils_error().raise(LOCAL_INFO,"The setTimingPrintRequirement method has not been defined in this class.");
167  }
168  }
169 
171  void functor::setNestedList (std::vector<functor*>&)
172  {
173  utils_error().raise(LOCAL_INFO,"The setNestedList method has not been defined in this class.");
174  }
175 
177  void functor::setIteration (long long)
178  {
179  utils_error().raise(LOCAL_INFO,"The setIteration method has not been defined in this class.");
180  }
181 
184  {
185  utils_error().raise(LOCAL_INFO,"The canBeLoopManager method has not been defined in this class.");
186  return false;
187  }
188 
191  {
192  utils_error().raise(LOCAL_INFO,"The loopManagerCapability method has not been defined in this class.");
193  return "none";
194  }
195 
198  {
199  utils_error().raise(LOCAL_INFO,"The loopManagerType method has not been defined in this class.");
200  return "none";
201  }
202 
205  {
206  utils_error().raise(LOCAL_INFO,"The loopManagerName method has not been defined in this class.");
207  return "none";
208  }
209 
212  {
213  utils_error().raise(LOCAL_INFO,"The loopManagerOrigin method has not been defined in this class.");
214  return "none";
215  }
216 
218  std::set<sspair> functor::dependencies()
219  {
220  utils_error().raise(LOCAL_INFO,"The dependencies method has not been defined in this class.");
221  std::set<sspair> empty;
222  return empty;
223  }
225  std::set<str> functor::backendgroups()
226  {
227  utils_error().raise(LOCAL_INFO,"The backendgroups method has not been defined in this class.");
228  std::set<str> empty;
229  return empty;
230  }
232  std::set<sspair> functor::backendreqs()
233  {
234  utils_error().raise(LOCAL_INFO,"The backendreqs method has not been defined in this class.");
235  std::set<sspair> empty;
236  return empty;
237  }
239  std::set<sspair> functor::backendreqs(str)
240  {
241  utils_error().raise(LOCAL_INFO,"The backendreqs method has not been defined in this class.");
242  std::set<sspair> empty;
243  return empty;
244  }
247  {
248  utils_error().raise(LOCAL_INFO,"The backendspermitted method has not been defined in this class.");
249  std::set<sspair> empty;
250  return empty;
251  }
254  {
255  utils_error().raise(LOCAL_INFO,"The backendreq_tags method has not been defined in this class.");
256  std::set<str> empty;
257  return empty;
258  }
261  {
262  utils_error().raise(LOCAL_INFO,"The forcematchingbackend method has not been defined in this class.");
263  std::set<sspair> empty;
264  return empty;
265  }
266 
269  {
270  utils_error().raise(LOCAL_INFO,"The backend_conditional_dependencies method has not been defined in this class.");
271  std::set<sspair> empty;
272  return empty;
273  }
274 
277  {
278  utils_error().raise(LOCAL_INFO,"The breakLoop method has not been defined in this class.");
279  }
280 
283  {
284  return backend_conditional_dependencies(req, type, be, "any");
285  }
286 
288  std::set<sspair> functor::backend_conditional_dependencies (functor* be_functor)
289  {
290  return backend_conditional_dependencies (be_functor->capability(), be_functor->type(),
291  be_functor->origin(), be_functor->version());
292  }
293 
296  {
297  utils_error().raise(LOCAL_INFO,"The model_conditional_dependencies method has not been defined in this class.");
298  std::set<sspair> empty;
299  return empty;
300  }
301 
304  {
305  utils_error().raise(LOCAL_INFO,"The model_conditional_backend_reqs method has not been defined in this class.");
306  std::set<sspair> empty;
307  return empty;
308  }
309 
312  {
313  utils_error().raise(LOCAL_INFO,"The resolveDependency method has not been defined in this class.");
314  }
315 
318  {
319  utils_error().raise(LOCAL_INFO,"The resolveLoopManager method has not been defined in this class.");
320  }
321 
324  {
325  utils_error().raise(LOCAL_INFO,"The resolveBackendReq method has not been defined in this class.");
326  }
327 
330  {
331  utils_error().raise(LOCAL_INFO,"The notifyOfModel method has not been defined in this class.");
332  }
333 
336  {
337  utils_error().raise(LOCAL_INFO,"The notifyOfDependee method has not been defined in this class.");
338  }
339 
341  void functor::notifyOfBackends(std::map<str, std::set<str> >)
342  {
343  utils_error().raise(LOCAL_INFO,"The notifyOfBackends method has not been defined in this class.");
344  }
345 
346  #ifndef NO_PRINTERS
347  void functor::print(Printers::BasePrinter*, const int, int)
349  {
350  str warn_msg = "This is the functor base class print function! This should not\n";
351  warn_msg += "be used; the print function should be redefined in daughter\n"
352  "functor classes. If this is running there is a problem somewhere.\n"
353  "Currently only functors derived from module_functor_common<!=void>\n"
354  "are allowed to try to print themselves; i.e. backend and void\n"
355  "functors may not do this (they inherit this default message).";
356  utils_warning().raise(LOCAL_INFO,warn_msg);
357  }
358 
360  void functor::print(Printers::BasePrinter* printer, const int pointID)
361  {
362  print(printer,pointID,0);
363  }
364  #endif
365 
370  {
371  myOptions = opt;
372  }
373 
376  {
377  return safe_ptr<Options>(&myOptions);
378  }
379 
381  void functor::notifyOfSubCaps(const Options& subcaps)
382  {
383  for (auto entry : subcaps)
384  {
385  str key = entry.first.as<std::string>();
386  if (not mySubCaps.hasKey(key)) mySubCaps.setValue(key, entry.second);
387  else
388  {
389  std::ostringstream ss1, ss2;
390  ss1 << mySubCaps.getValue<YAML::Node>(key);
391  ss2 << entry.second.as<YAML::Node>();
392  if (not (ss1.str() == ss2.str()))
393  {
394  std::ostringstream ss;
395  ss << "Duplicate sub_capability clash. " << endl
396  << "Your ObsLike section of the YAML file contains both " << endl
397  << key << ": " << ss1.str() << endl << "and" << endl << key << ": " << ss2.str() << endl
398  << "GAMBIT does not know which value to choose when trying to determine the sub-capabilities" << endl
399  << "served by " << myOrigin << "::" << myName << ", as both ObsLike entries depend on this function.";
400  utils_error().raise(LOCAL_INFO, ss.str());
401  }
402  }
403  }
404  }
405 
408  {
409  return safe_ptr<Options>(&mySubCaps);
410  }
411 
414  {
416  }
417 
420  {
421  bool allowed = false;
422  if (verbose)
423  {
424  std::cout << "Checking allowedModels set for functor "<<myLabel<<std::endl;
425  for(std::set<str>::iterator it = allowedModels.begin(); it != allowedModels.end(); ++it)
426  {
427  std::cout << " "<< *it << std::endl;
428  }
429  }
430  if (allowedModels.empty() and allowedGroupCombos.empty()) allowed=true;
431  if (allowed_parent_or_friend_exists(model)) allowed=true;
432  if (verbose) std::cout << " Allowed to be used with model "<<model<<"? "<<allowed<<std::endl;
433  return allowed;
434  }
435 
438  {
439  if (allowedModels.find(model) != allowedModels.end()) return true;
440  return false;
441  }
442 
445  {
446  return allowedModels.empty() and allowedGroupCombos.empty();
447  }
448 
450  void functor::setAllowedModel(str model) { allowedModels.insert(model); }
451 
453  bool functor::modelComboAllowed(std::set<str> combo)
454  {
455  // If any model in the combo is always allowed, then give the combo a thumbs up.
456  for(std::set<str>::const_iterator model = combo.begin(); model != combo.end(); model++)
457  {
458  if (modelAllowed(*model)) return true;
459  }
460  // Loop over the allowed combinations, and check if the passed combo matches any of them
461  for(std::set<std::set<str> >::const_iterator group_combo = allowedGroupCombos.begin(); group_combo != allowedGroupCombos.end(); group_combo++)
462  {
463  bool matches = true;
464  //Loop over each group in the allowed group combination, and check if one of the entries in the passed model combination matches it somehow.
465  for(std::set<str>::const_iterator group = group_combo->begin(); group != group_combo->end(); group++)
466  {
467  matches = matches and contains_anything_interpretable_as_member_of(combo, *group);
468  if (not matches) break;
469  }
470  //Return true immediately if all entries in the allowed group combination have been matched.
471  if (matches) return true;
472  }
473  return false;
474  }
475 
477  bool functor::modelComboExplicitlyAllowed(std::set<str> combo)
478  {
479  // If any model in the combo is always explicitly allowed, then give the combo a thumbs up.
480  for(std::set<str>::const_iterator model = combo.begin(); model != combo.end(); model++)
481  {
482  if (modelExplicitlyAllowed(*model)) return true;
483  }
484  // Loop over the allowed combinations, and check if the passed combo matches any of them
485  for(std::set<std::set<str> >::const_iterator group_combo = allowedGroupCombos.begin(); group_combo != allowedGroupCombos.end(); group_combo++)
486  {
487  bool matches = true;
488  //Loop over each group in the allowed group combination, and check if one of the entries in the passed model combination matches it explicitly.
489  for(std::set<str>::const_iterator group = group_combo->begin(); group != group_combo->end(); group++)
490  {
491  matches = matches and has_common_elements(combo, *group);
492  if (not matches) break;
493  }
494  //Return true immediately if all entries in the allowed group combination have been matched.
495  if (matches) return true;
496  }
497  return false;
498  }
499 
502  {
503  //Strip the group contents of its parentheses, then split it, turn it into a set and save it in the map
504  Utils::strip_parentheses(contents);
505  std::vector<str> v = Utils::delimiterSplit(contents, ",");
506  std::set<str> combo(v.begin(), v.end());
507  modelGroups[group] = combo;
508  }
509 
512  {
513  //Strip the group combo of its parentheses and whitespace, then split it and save it in the vector of allowed combos
514  Utils::strip_parentheses(groups);
516  std::vector<str> v = Utils::delimiterSplit(groups, ",");
517  std::set<str> group_combo(v.begin(), v.end());
518  allowedGroupCombos.insert(group_combo);
519  }
520 
523  {
524  str error_msg = "Attempted to use a functor method from a null pointer.";
525  error_msg += "\nProbably you tried to use a conditional dependency that has"
526  "\nnot been activated, or a model parameter that is not defined"
527  "\nin the model for which this function has been invoked."
528  "\nPlease check your module function source code."
529  "\nMethod invoked: " + method + ".";
530  utils_error().raise(LOCAL_INFO,error_msg);
531  }
532 
535  {
536  for (std::set<str>::reverse_iterator it = allowedModels.rbegin() ; it != allowedModels.rend(); ++it)
537  {
538  if (myClaw->model_exists(*it))
539  {
540  if (myClaw->downstream_of(model, *it)) return true;
541  }
542  }
543  return false;
544  }
545 
547  inline bool functor::in_allowed_combo(str model)
548  {
549  // If the model is allowed on its own, just give the thumbs up immediately.
550  if (modelAllowed(model)) return true;
551  // Loop over the allowed combinations, and check if the passed model matches anything in any of them
552  for(std::set<std::set<str> >::const_iterator group_combo = allowedGroupCombos.begin(); group_combo != allowedGroupCombos.end(); group_combo++)
553  {
554  //Loop over each group in the allowed group combination, and check if the model is interpretable as a model in the group.
555  for(std::set<str>::const_iterator group = group_combo->begin(); group != group_combo->end(); group++)
556  {
557  // Work through the members of the model group
558  std::set<str> models = modelGroups.at(*group);
559  for (std::set<str>::reverse_iterator it = models.rbegin() ; it != models.rend(); ++it)
560  {
561  if (myClaw->model_exists(*it))
562  {
563  if (myClaw->downstream_of(model, *it)) return true;
564  }
565  }
566  }
567  }
568  return false;
569  }
570 
573  {
574  // Work through the members of the model group
575  std::set<str> models = modelGroups.at(group);
576  for (std::set<str>::const_iterator it = models.begin() ; it != models.end(); ++it)
577  {
578  if (myClaw->model_exists(*it))
579  {
580  // Work through the members of the combination
581  for (std::set<str>::const_iterator jt = combo.begin() ; jt != combo.end(); ++jt)
582  {
583  if (myClaw->model_exists(*jt))
584  {
585  if (myClaw->downstream_of(*jt, *it)) return true;
586  }
587  }
588  }
589  }
590  return false;
591  }
592 
594  inline bool functor::has_common_elements(std::set<str> combo, str group)
595  {
596  // Work through the members of the model group
597  std::set<str> models = modelGroups.at(group);
598  for (std::set<str>::reverse_iterator it = models.rbegin() ; it != models.rend(); ++it)
599  {
600  if ( std::find(combo.begin(), combo.end(), *it) == combo.end() ) return true;
601  }
602  return false;
603  }
604 
607  str functor::find_friend_or_parent_model_in_map(str model, std::map< str, std::set<sspair> > karta)
608  {
609  std::vector<str> candidates;
610  for (std::map< str, std::set<sspair> >::reverse_iterator it = karta.rbegin() ; it != karta.rend(); ++it)
611  {
612  if (myClaw->model_exists(it->first))
613  {
614  if (myClaw->downstream_of(model, it->first)) candidates.push_back(it->first);
615  }
616  }
617  // If found no candidates, return the empty string.
618  if (candidates.empty()) return "";
619  // If found just one, return it with no further questions.
620  if (candidates.size() == 1) return candidates[0];
621  // If found more than one, choose the one closest to the model passed in.
622  str result = candidates.front();
623  for (std::vector<str>::iterator it = candidates.begin()+1; it != candidates.end(); ++it)
624  {
625  if (myClaw->downstream_of(*it, result)) result = *it;
626  }
627  return result;
628  }
629 
632 
633 
634  // Module_functor_common class methods
635 
638  str func_capability,
639  str result_type,
640  str origin_name,
642  : functor (func_name, func_capability, result_type, origin_name, claw),
643  myTimingPrintFlag (false),
644  start (NULL),
645  end (NULL),
646  point_exception_raised (false),
647  runtime_average (FUNCTORS_RUNTIME_INIT), // default 1 micro second
648  fadeRate (FUNCTORS_FADE_RATE), // can be set individually for each functor
649  pInvalidation (FUNCTORS_BASE_INVALIDATION_RATE),
650  needs_recalculating (NULL),
651  already_printed (NULL),
652  already_printed_timing (NULL),
653  iCanManageLoops (false),
654  iRunNested (false),
655  myLoopManagerCapability ("none"),
656  myLoopManagerType ("none"),
657  myLoopManager (NULL),
658  myCurrentIteration (NULL),
659  globlMaxThreads (omp_get_max_threads()),
660  myLogTag (-1)
661  {
662  if (globlMaxThreads == 0) utils_error().raise(LOCAL_INFO,"Cannot determine number of hardware threads available on this system.");
663  // Determine LogTag number
665  if (not claw.model_exists(origin_name)) check_missing_LogTag();
666  }
667 
670  {
671  if (start != NULL) delete [] start;
672  if (end != NULL) delete [] end;
673  if (needs_recalculating != NULL) delete [] needs_recalculating;
674  if (already_printed != NULL) delete [] already_printed;
675  if (already_printed_timing != NULL) delete [] already_printed_timing;
676  if (myCurrentIteration != NULL) delete [] myCurrentIteration;
677  }
678 
681  {
682  if(myLogTag==-1)
683  {
684  std::ostringstream ss;
685  ss << "Cannot retrieve LogTag number; no match for module name in tag2str map." << endl
686  << "Module: " << myOrigin << endl
687  << "Function: " << myName << endl
688  << "This is probably because there is no log specified for " << myOrigin << " in your yaml file.";
689  utils_warning().raise(LOCAL_INFO,ss.str());
690  }
691  }
692 
695  {
696  return runtime_average;
697  }
698 
701  {
702  myTimingPrintFlag = flag;
703  }
704 
707  {
708  return myTimingPrintFlag;
709  }
710 
713  {
714  init_memory();
715  int n = (iRunNested ? globlMaxThreads : 1);
716  std::fill(needs_recalculating, needs_recalculating+n, true);
717  std::fill(already_printed, already_printed+n, false);
718  std::fill(already_printed_timing, already_printed_timing+n, false);
719  if (iCanManageLoops) resetLoop();
720  point_exception_raised = false;
721  }
722 
724  void module_functor_common::reset(int thread_num)
725  {
726  init_memory();
727  needs_recalculating[thread_num] = true;
728  already_printed[thread_num] = false;
729  already_printed_timing[thread_num] = false;
730  if (iCanManageLoops) resetLoop();
731  }
732 
735  {
738  }
739 
742  {
743  #pragma omp atomic
745  if (f==NULL) f = this;
746  #pragma omp critical (raised_point_exception)
747  {
748  e.set_thrower(f);
750  point_exception_raised = true;
751  }
752  if (omp_get_level()!=0) breakLoop();
753  }
754 
757  {
759  for (auto f = myNestedFunctorList.begin(); f != myNestedFunctorList.end(); ++f)
760  {
761  invalid_point_exception* e = (*f)->retrieve_invalid_point_exception();
762  if (e != NULL) return e;
763  }
764  return NULL;
765  }
766 
769  {
770  return pInvalidation;
771  }
772 
775  {
776  fadeRate = new_rate;
777  }
778 
781  {
782  if (activeModelFlags.find(model) == activeModelFlags.end())
783  {
784  std::ostringstream ss;
785  ss << "Problem with ModelInUse(\"" << model << "\")." << endl
786  << "This model is not known by " << myOrigin << "::" << myName << "." << endl
787  << "Please make sure that it has been mentioned in some context in the" << endl
788  << "rollcall header declaration of this function.";
789  model_error().raise(LOCAL_INFO,ss.str());
790  }
791  return activeModelFlags.at(model);
792  }
793 
796  {
797  chosenReqsFromGroups[group] = "none";
799  }
800 
802  void module_functor_common::iterate(long long iteration)
803  {
804  if (not myNestedFunctorList.empty())
805  {
806  for (std::vector<functor*>::iterator it = myNestedFunctorList.begin();
807  it != myNestedFunctorList.end(); ++it)
808  {
809  (*it)->setIteration(iteration); // Tell the nested functor what iteration this is.
810  try
811  {
812  (*it)->reset_and_calculate(); // Reset the nested functor so that it recalculates, then set it off
813  }
814  catch (invalid_point_exception& e)
815  {
817  if (omp_get_level()==0) throw(e); // If not in an OpenMP parallel block, inform of invalidation and throw onwards
818  }
819  catch (halt_loop_exception& e)
820  {
821  // Skip the rest of the iteration, without trying to evaluate the rest of the loop, and wrap it up.
822  breakLoop();
823  break;
824  }
826  {
827  // Just skip on to the next iteration, without trying to evaluate the rest of the loop.
828  break;
829  }
830  }
831  }
832  }
833 
834  // Initialise the array holding the current iteration(s) of this functor.
836  {
837  if(myCurrentIteration==NULL)
838  {
839  #pragma omp critical(module_functor_init_myCurrentIteration_if_NULL)
840  {
841  if(myCurrentIteration==NULL) // Check again in case two threads managed to get this far in sequence.
842  {
843  // Set the number of slots to the max number of threads allowed iff this functor can run in parallel
844  int nslots = (iRunNested ? globlMaxThreads : 1);
845  // Reserve enough space to hold as many iteration numbers as there are slots (threads) allowed
846  myCurrentIteration = new long long[nslots];
847  // Zero them to start off
848  std::fill(myCurrentIteration, myCurrentIteration+nslots, 0);
849  }
850  }
851  }
852  }
853 
856  {
857  if (myLoopManager == NULL)
858  {
859  str errmsg = "Problem whilst attempting to break out of loop:";
860  errmsg += "\n Loop Manager not properly defined."
861  "\n This is " + this->name() + " in " + this->origin() + ".";
862  utils_error().raise(LOCAL_INFO,errmsg);
863  }
864  else
865  {
867  }
868  }
869 
872  {
873  #pragma omp critical (myLoopIsDone)
874  {
875  myLoopIsDone = true;
876  }
877  }
878 
881  {
882  return safe_ptr<bool>(&myLoopIsDone);
883  }
884 
887  {
888  #pragma omp critical (myLoopIsDone)
889  {
890  myLoopIsDone = false;
891  }
892  }
893 
895  void module_functor_common::setIteration (long long iteration)
896  {
897  init_myCurrentIteration_if_NULL(); // Init memory if this is the first run through.
898  myCurrentIteration[omp_get_thread_num()] = iteration;
899  }
900 
903  {
904  init_myCurrentIteration_if_NULL(); // Init memory if this is the first run through.
906  }
907 
909  void module_functor_common::setCanBeLoopManager (bool canManage) { iCanManageLoops = canManage; }
912 
915  {
916  iRunNested = true;
918  myLoopManagerType = t;
919  }
928 
932  std::set<str> module_functor_common::backendgroups() { return myGroups; }
937  {
938  if (myGroupedBackendReqs.find(group) != myGroupedBackendReqs.end())
939  {
940  return myGroupedBackendReqs[group];
941  }
942  else
943  {
944  std::set<sspair> empty;
945  return empty;
946  }
947  }
950  {
951  if (permitted_map.find(quant) != permitted_map.end())
952  {
953  return permitted_map[quant];
954  }
955  else
956  {
957  std::set<sspair> empty;
958  return empty;
959  }
960  }
963  {
964  if (backendreq_tagmap.find(quant) != backendreq_tagmap.end())
965  {
966  return backendreq_tagmap[quant];
967  }
968  else
969  {
970  std::set<str> empty;
971  return empty;
972  }
973  }
976  {
977  if (myForcedMatches.find(tag) != myForcedMatches.end())
978  {
979  return myForcedMatches[tag];
980  }
981  else
982  {
983  std::set<sspair> empty;
984  return empty;
985  }
986  }
987 
990  {
991  std::set<sspair> generic_deps, specific_deps, total_deps;
992  std::vector<str> quad;
993  quad.push_back(req);
994  quad.push_back(type);
995  quad.push_back(be);
996  quad.push_back(ver);
997  //Check first what conditional dependencies exist for all versions of this backend
998  if (ver != "any")
999  {
1000  generic_deps = backend_conditional_dependencies(req, type, be, "any");
1001  }
1002  //Now see if there are any for this specific version
1004  {
1005  specific_deps = myBackendConditionalDependencies[quad];
1006  }
1007  //Now put them together
1008  total_deps.insert(generic_deps.begin(), generic_deps.end());
1009  total_deps.insert(specific_deps.begin(), specific_deps.end());
1010  return total_deps;
1011  }
1012 
1015  {
1016  return backend_conditional_dependencies(req, type, be, "any");
1017  }
1018 
1021  {
1022  return backend_conditional_dependencies (be_functor->capability(), be_functor->type(),
1023  be_functor->origin(), be_functor->version());
1024  }
1025 
1028  {
1030  if (parent != "") return myModelConditionalDependencies[parent];
1031  std::set<sspair> empty;
1032  return empty;
1033  }
1034 
1037  {
1039  if (parent != "") return myModelConditionalBackendReqs[parent];
1040  std::set<sspair> empty;
1041  return empty;
1042  }
1043 
1046  {
1047  sspair key (dep, Utils::fix_type(dep_type));
1048  myDependencies.insert(key);
1049  dependency_map[key] = resolver;
1050  this->myPurpose = purpose; // only relevant for output nodes
1051  }
1052 
1055  {
1056  myConditionalDependencies[dep] = dep_type;
1057  }
1058 
1061  {
1063  {
1064  str errmsg = "Problem whilst attempting to set conditional dependency:";
1065  errmsg += "\nThe conditional dependency " + dep + " appears not to have"
1066  "\nbeen fully declared; START_CONDITIONAL_DEPENDENCY() is missing."
1067  "\nThis is " + this->name() + " in " + this->origin() + ".";
1068  utils_error().raise(LOCAL_INFO,errmsg);
1069  }
1070  return sspair(dep, myConditionalDependencies.at(dep));
1071  }
1072 
1075  (str req, str be, str ver, str dep, void(*resolver)(functor*, module_functor_common*))
1076  {
1077  // Split the version string and send each version to be registered
1078  std::vector<str> versions = Utils::delimiterSplit(ver, ",");
1079  for (std::vector<str>::iterator it = versions.begin() ; it != versions.end(); ++it)
1080  {
1081  setBackendConditionalDependencySingular(req, be, *it, dep, resolver);
1082  }
1083  }
1084 
1087  (str req, str be, str ver, str dep, void(*resolver)(functor*, module_functor_common*))
1088  {
1090  std::vector<str> quad;
1091  if (backendreq_types.find(req) != backendreq_types.end())
1092  {
1093  quad.push_back(req);
1094  quad.push_back(backendreq_types[req]);
1095  quad.push_back(be);
1096  quad.push_back(ver);
1097  }
1098  else
1099  {
1100  str errmsg = "Problem whilst attempting to set backend-conditional dependency:";
1101  errmsg += "\nThe type of the backend requirement " + req + "on which the"
1102  "\ndependency " + dep + " is conditional has not been set. This"
1103  "\nis " + this->name() + " in " + this->origin() + ".";
1104  utils_error().raise(LOCAL_INFO,errmsg);
1105  }
1107  {
1108  std::set<sspair> newvec;
1109  myBackendConditionalDependencies[quad] = newvec;
1110  }
1111  myBackendConditionalDependencies[quad].insert(key);
1112  dependency_map[key] = resolver;
1113  }
1114 
1117  (str model, str dep, void(*resolver)(functor*, module_functor_common*))
1118  {
1119  // Split the model string and send each model to be registered
1120  std::vector<str> models = Utils::delimiterSplit(model, ",");
1121  for (std::vector<str>::iterator it = models.begin() ; it != models.end(); ++it)
1122  {
1123  setModelConditionalDependencySingular(*it, dep, resolver);
1124  }
1125  }
1126 
1129  (str model, str dep, void(*resolver)(functor*, module_functor_common*))
1130  {
1133  {
1134  std::set<sspair> newvec;
1135  myModelConditionalDependencies[model] = newvec;
1136  }
1137  myModelConditionalDependencies[model].insert(key);
1138  dependency_map[key] = resolver;
1139  }
1140 
1143  void module_functor_common::setBackendReq(str group, str req, str tags, str type, void(*resolver)(functor*))
1144  {
1145  type = Utils::fix_type(type);
1146  sspair key (req, type);
1147  backendreq_types[req] = type;
1148  myBackendReqs.insert(key);
1149  myResolvableBackendReqs.insert(key);
1150  if ( std::find(myGroups.begin(), myGroups.end(), group) == myGroups.end() )
1151  {
1152  myGroups.insert(group);
1153  std::set<sspair> empty;
1154  myGroupedBackendReqs[group] = empty;
1155  }
1156  myGroupedBackendReqs[group].insert(key);
1157  backendreq_map[key] = resolver;
1159  std::vector<str> v = Utils::delimiterSplit(tags, ",");
1160  backendreq_tagmap[key] = std::set<str>(v.begin(), v.end());
1161  backendreq_groups[key] = group;
1162  }
1163 
1166  {
1167  //Strip the tag and model strings of their parentheses
1169  Utils::strip_parentheses(model);
1170 
1171  //Split the tag string and sort it.
1172  std::vector<str> v = Utils::delimiterSplit(tag, ",");
1173  std::set<str> tags(v.begin(), v.end());
1174 
1175  //Find all declared backend requirements that fit one of the tags within the passed tag set.
1176  for (std::set<sspair>::iterator it = myBackendReqs.begin(); it != myBackendReqs.end(); ++it)
1177  {
1178  std::set<str> tagset = backendreq_tagmap[*it];
1179  if (not Utils::is_disjoint(tags, tagset))
1180  {
1181  // Make each of the matching backend requirements conditional on the models passed in.
1182  setModelConditionalBackendReq(model,it->first,it->second);
1183  }
1184  }
1185 
1186  }
1187 
1190  (str model, str req, str type)
1191  {
1192  // Split the model string and send each model to be registered
1193  std::vector<str> models = Utils::delimiterSplit(model, ",");
1194  for (std::vector<str>::iterator it = models.begin() ; it != models.end(); ++it)
1195  {
1196  setModelConditionalBackendReqSingular(*it, req, type);
1197  }
1198  }
1199 
1202  (str model, str req, str type)
1203  {
1204  sspair key (req, Utils::fix_type(type));
1205 
1206  // Remove the entry from the resolvable backend reqs list...
1207  myResolvableBackendReqs.erase(key);
1208 
1209  // Remove the entry from the grouped backend reqs list...
1210  myGroupedBackendReqs.at(backendreq_groups.at(key)).erase(key);
1211 
1212  // Check that the model is not already in the conditional backend reqs list, then add it
1214  {
1215  std::set<sspair> newvec;
1216  myModelConditionalBackendReqs[model] = newvec;
1217  }
1218  myModelConditionalBackendReqs[model].insert(key);
1219  }
1220 
1223  {
1224  //Strip the tag and be-ver strings of their parentheses, then split them
1226  Utils::strip_parentheses(be_and_ver);
1227  std::vector<str> v = Utils::delimiterSplit(tag, ",");
1228  std::set<str> tags(v.begin(), v.end());
1229  std::vector<str> be_plus_versions = Utils::delimiterSplit(be_and_ver, ",");
1230 
1231  //Die if no backend and/or no tags were given.
1232  if (tags.empty() or be_plus_versions.empty())
1233  {
1234  str errmsg = "Error whilst attempting to set permitted backends:";
1235  errmsg += "\nA BACKEND_OPTION must include a backend name and at least one tag."
1236  "\nThis is " + this->name() + " in " + this->origin() + ".";
1237  utils_error().raise(LOCAL_INFO,errmsg);
1238  }
1239 
1240  //Seperate the backend from the versions
1241  str be = be_plus_versions.at(0);
1242  std::vector<str> versions(be_plus_versions.begin()+1,be_plus_versions.end());
1243  if (versions.empty()) versions.push_back("any");
1244 
1245  //Find all declared backend requirements that fit one of the tags within the passed tag set.
1246  for (std::set<sspair>::iterator it = myBackendReqs.begin(); it != myBackendReqs.end(); ++it)
1247  {
1248  std::set<str> tagset = backendreq_tagmap[*it];
1249  if (not Utils::is_disjoint(tags, tagset))
1250  {
1251  // For each of the matching backend requirements, set the chosen backend-version pairs as permitted
1252  for (std::vector<str>::iterator vit = versions.begin() ; vit != versions.end(); ++vit)
1253  {
1254  setPermittedBackend(it->first, be, *vit);
1255  }
1256  }
1257  }
1258 
1259  }
1260 
1263  {
1264  sspair key;
1265  if (backendreq_types.find(req) != backendreq_types.end())
1266  {
1267  key = std::make_pair(req, backendreq_types[req]);
1268  }
1269  else
1270  {
1271  str errmsg = "Error whilst attempting to set permitted backend:";
1272  errmsg += "\nThe return type of the backend requirement " + req + "is not set."
1273  "\nThis probably means the backend requirement has not been declared."
1274  "\nThis is " + this->name() + " in " + this->origin() + ".";
1275  utils_error().raise(LOCAL_INFO,errmsg);
1276  }
1277  sspair vector_entry (be, ver);
1278  if (permitted_map.find(key) == permitted_map.end())
1279  {
1280  std::set<sspair> newvec;
1281  permitted_map[key] = newvec;
1282  }
1283  permitted_map[key].insert(vector_entry);
1284  }
1285 
1288  {
1289  //Strip the tag string of any parentheses, then split it
1291  std::vector<str> tags = Utils::delimiterSplit(tag, ",");
1292 
1293  //Die if no tags were given.
1294  if (tags.empty())
1295  {
1296  str errmsg = "Problem whilst attempting to set backend-matching rule:";
1297  errmsg += "\nA call to FORCE_SAME_BACKEND must include at least one tag!"
1298  "\nThis is " + this->name() + " in " + this->origin() + ".";
1299  utils_error().raise(LOCAL_INFO,errmsg);
1300  }
1301 
1302  //Work with one tag at a time
1303  for (std::vector<str>::iterator tagit = tags.begin(); tagit != tags.end(); ++tagit)
1304  {
1305  std::set<sspair> matches;
1306  //Find all declared backend requirements that fit the current tag
1307  for (std::set<sspair>::iterator it = myBackendReqs.begin(); it != myBackendReqs.end(); ++it)
1308  {
1309  //Test if the current tag is amongst the tags listed for the current backend requirement
1310  std::set<str> its_tags = backendreq_tagmap[*it];
1311  if ( std::find(its_tags.begin(), its_tags.end(), *tagit) != its_tags.end() )
1312  {
1313  //It is; now place the current backend requirement into the set of matches
1314  matches.insert(*it);
1315  }
1316  }
1317  //Save the matched set of backend requirements as needing to be filled using the same backend.
1318  myForcedMatches[*tagit] = matches;
1319  }
1320 
1321  //Note that overlapping sets are explicitly left unmerged, as the common elements
1322  //may or may not be activated in a given scan, making the disjointedness of the
1323  //different sets determinable only at resolution time, not initialisation time.
1324 
1325  }
1326 
1329  {
1330  // Add the rule.
1331  required_classloading_backends[be].insert(ver);
1332  // Add a dependency on the backend's initialisation function.
1333  sspair be_ini_quantity(be + "_" + safe_ver + "_init", "void");
1334  if (std::find(myDependencies.begin(), myDependencies.end(), be_ini_quantity) == myDependencies.end())
1335  {
1336  myDependencies.insert(be_ini_quantity);
1337  }
1338  }
1339 
1341  void module_functor_common::notifyOfBackends(std::map<str, std::set<str> > be_ver_map)
1342  {
1343  missing_backends.clear();
1344  // Loop over all the backends that are needed for this functor to work.
1345  for (auto it = required_classloading_backends.begin(); it != required_classloading_backends.end(); ++it)
1346  {
1347  // Check to make sure some version of the backend in question is connected.
1348  if (be_ver_map.find(it->first) == be_ver_map.end())
1349  {
1350  this->myStatus = -3;
1351  missing_backends.push_back(it->first);
1352  }
1353  else
1354  { // Loop over all the versions of the backend that are needed for this functor to work.
1355  for (auto jt = it->second.begin(); jt != it->second.end(); ++jt)
1356  {
1357  std::set<str> versions = be_ver_map.at(it->first);
1358  // Check that the specific version needed is connected.
1359  if (versions.find(*jt) == versions.end())
1360  {
1361  this->myStatus = -3;
1362  missing_backends.push_back(it->first + ", v" + *jt);
1363  }
1364  }
1365  }
1366  }
1367  }
1368 
1370  void module_functor_common::setNestedList (std::vector<functor*> &newNestedList)
1371  {
1372  if (iCanManageLoops)
1373  {
1374  myNestedFunctorList = newNestedList;
1375  }
1376  else
1377  {
1378  str errmsg = "This module functor is not permitted to manage";
1379  errmsg += "\nloops, so you cannot set its nested functor list."
1380  "\nThis is " + this->name() + " in " + this->origin() + ".";
1381  utils_error().raise(LOCAL_INFO,errmsg);
1382  }
1383  }
1384 
1387  {
1388  sspair key (dep_functor->quantity());
1389  if (std::find(myDependencies.begin(), myDependencies.end(), key) == myDependencies.end())
1390  {
1391  str errmsg = "Cannot resolve dependency:";
1392  errmsg += "\nFunction " + myName + " in " + myOrigin + " does not depend on"
1393  "\ncapability " + key.first + " with type = " + key.second + ".";
1394  utils_error().raise(LOCAL_INFO,errmsg);
1395  }
1396  else
1397  {
1398  // resolve the dependency
1399  if (dependency_map.find(key) != dependency_map.end()) (*dependency_map[key])(dep_functor,this);
1400  // propagate purpose from next to next-to-output nodes
1401  dep_functor->setPurpose(this->myPurpose);
1402  // propagate this functor's dependees and subcaps on to the resolving functor
1403  dep_functor->notifyOfDependee(this);
1404  // save the pointer to the resolving functor to allow this functor to notify it of future dependees
1405  dependency_functor_map[key] = dep_functor;
1406  }
1407  }
1408 
1411  {
1412  // Add the dependent functor's capability-type pair to the list of dependees
1413  myDependees.insert(dependent_functor->quantity());
1414  // Inherit the dependent functor's own dependees
1415  for (const sspair& q : *(dependent_functor->getDependees())) { myDependees.insert(q); }
1416  // Inherit the dependent functor's subcaps
1417  notifyOfSubCaps(*(dependent_functor->getSubCaps()));
1418  // Notify all functors on which this one depends that they also now have a new dependent
1419  for (auto entry : dependency_functor_map) entry.second->notifyOfDependee(dependent_functor);
1420  }
1421 
1424  {
1425  if (dep_functor->capability() != myLoopManagerCapability or not dep_functor->canBeLoopManager())
1426  {
1427  utils_error().raise(LOCAL_INFO, "Cannot set loop manager for nested functor:\n"
1428  "Function " + myName + " in " + myOrigin + " does not need a loop manager with\n"
1429  "capability " + dep_functor->capability() + ".");
1430  }
1431  // Do type checking only if the need for a manger was declared with a specific type
1432  if (myLoopManagerType != "any")
1433  {
1434  if (dep_functor->type() != myLoopManagerType)
1435  {
1436  utils_error().raise(LOCAL_INFO, "Cannot set loop manager for nested functor:\n"
1437  "Function " + myName + " in " + myOrigin + " requires a manager with\n"
1438  "type " + dep_functor->type() + ".");
1439  }
1440  resolveDependency(dep_functor);
1441  }
1442  myLoopManager = dep_functor;
1443  }
1444 
1447  {
1448 
1449  sspair key (be_functor->quantity());
1450 
1451  //First make sure that the proposed backend function fulfills a known requirement of the module function.
1452  if (backendreq_map.find(key) != backendreq_map.end())
1453  {
1454 
1455  sspair proposal (be_functor->origin(), be_functor->version()); //Proposed backend-version pair
1456  sspair generic_proposal (be_functor->origin(), "any"); //Proposed backend, any version
1457 
1458  if ( //Check for a condition under which the proposed backend function is an acceptable fit for this requirement.
1459  //Check whether there are have been any permitted backends stated for this requirement (if not, anything goes).
1460  (permitted_map.find(key) == permitted_map.end()) ||
1461  //Iterate over the vector of backend-version pairs for this requirement to see if all versions of the
1462  //proposed backend have been explicitly permitted.
1463  (std::find(permitted_map[key].begin(), permitted_map[key].end(), generic_proposal) != permitted_map[key].end()) ||
1464  //Iterate over the vector of backend-version pairs again to see if the specific backend version
1465  //proposed had been explicitly permitted.
1466  (std::find(permitted_map[key].begin(), permitted_map[key].end(), proposal) != permitted_map[key].end()) )
1467  {
1468 
1469  //One of the conditions was met, so do the resolution.
1470  (*backendreq_map[key])(be_functor);
1471 
1472  //Set this backend functor's status to active.
1473  be_functor->setStatus(2);
1474 
1475  //If this is also the condition under which any backend-conditional dependencies should be activated, do it.
1476  std::set<sspair> deps_to_activate = backend_conditional_dependencies(be_functor);
1477  for (std::set<sspair>::iterator it = deps_to_activate.begin() ; it != deps_to_activate.end(); ++it)
1478  {
1479  myDependencies.insert(*it);
1480  }
1481 
1482  // Add a dependency on the initialisation function of the backend that this backend function hails from (if not done already).
1483  sspair be_ini_quantity(be_functor->origin() + "_" + be_functor->safe_version() + "_init", "void");
1484  if (std::find(myDependencies.begin(), myDependencies.end(), be_ini_quantity) == myDependencies.end())
1485  {
1486  myDependencies.insert(be_ini_quantity);
1487  }
1488 
1489  //Check if this backend requirement is part of a group.
1490  str group = backendreq_groups[key];
1491  if (group != "none")
1492  {
1493  //If it is part of a group, make sure that group has actually been declared.
1494  if (chosenReqsFromGroups.find(group) != chosenReqsFromGroups.end() )
1495  {
1496  //If it is part of a group, make sure another backend requirement from the same group has not already been activated.
1497  if (chosenReqsFromGroups[group] == "none")
1498  {
1499  //If not, then this this specific backend requirement is now the active one within its group.
1500  chosenReqsFromGroups[group] = key.first;
1501  }
1502  else //This backend requirement is not the first from its group to be resolved.
1503  {
1504  str errmsg = "Cannot resolve backend requirement in group " + group + ":";
1505  errmsg += "\nFunction " + myName + " in " + myOrigin + " has already had backend "
1506  "\nrequirement " + chosenReqsFromGroups[group] + " from the same group filled.";
1507  utils_error().raise(LOCAL_INFO,errmsg);
1508  }
1509  }
1510  else //This backend requirement is part of group that was not declared.
1511  {
1512  str errmsg = "Cannot resolve backend requirement in group " + group + ":";
1513  errmsg += "\nThis group has not been declared. Please add"
1514  "\n BACKEND_GROUP("+group+")"
1515  "\nTo the rollcall declaration of " + myName + " in " + myOrigin + ".";
1516  utils_error().raise(LOCAL_INFO,errmsg);
1517  }
1518  }
1519 
1520  }
1521 
1522  else //The proposed backend function is not an acceptable fit for this requirement.
1523  {
1524  str errmsg = "Cannot resolve backend requirement:";
1525  errmsg += "\nBackend capability " + key.first + " with type " + key.second +
1526  "\nrequired by function " + myName + " in " + myOrigin + " is not permitted"
1527  "\nto use " + proposal.first + ", version " + proposal.second + ".";
1528  utils_error().raise(LOCAL_INFO,errmsg);
1529  }
1530 
1531  }
1532 
1533  else //The proposed backend function does not fulfill any known requirement of the module function.
1534  {
1535  str errmsg = "Cannot resolve backend requirement:";
1536  errmsg += "\nFunction " + myName + " in " + myOrigin + " does not require"
1537  "\nbackend capability " + key.first + " with type " + key.second + ".";
1538  utils_error().raise(LOCAL_INFO,errmsg);
1539  }
1540 
1541  }
1542 
1545  {
1546  // Construct the list of known models only if it doesn't yet exist
1547  if (activeModelFlags.empty())
1548  {
1549  // First get all the explicitly allowed models.
1550  for (auto it = allowedModels.begin(); it != allowedModels.end(); ++it) { activeModelFlags[*it] = false; }
1551  // Next get all the models in groups
1552  for (auto it = modelGroups.begin(); it != modelGroups.end(); ++it)
1553  { for (auto jt = it->second.begin(); jt != it->second.end(); ++jt) { activeModelFlags[*jt] = false; } }
1554  // Next get all the models mentioned in conditional dependencies and backend reqs
1555  for (auto it = myModelConditionalDependencies.begin(); it != myModelConditionalDependencies.end(); ++it) { activeModelFlags[it->first] = false; }
1556  for (auto it = myModelConditionalBackendReqs.begin(); it != myModelConditionalBackendReqs.end(); ++it) { activeModelFlags[it->first] = false; }
1557  }
1558  }
1559 
1562  {
1563  // If activeModels hasn't been populated yet, make sure it is.
1565 
1566  // Now activate the flags for the models that are being used.
1567  for (auto it = activeModelFlags.begin(); it != activeModelFlags.end(); ++it)
1568  {
1569  str activation_candidate = it->first;
1570  if (myClaw->model_exists(activation_candidate))
1571  {
1572  if (myClaw->downstream_of(model, activation_candidate))
1573  {
1574  // Found an activation candidate that the model being scanned can be cast to.
1575  // Assume for now that the candidate will indeed be activated.
1576  it->second = true;
1577  // Compare with models that have already been activated, to avoid activating multiple models of the same lineage.
1578  for (auto jt = activeModelFlags.begin(); jt != activeModelFlags.end(); ++jt)
1579  {
1580  str active_model = jt->first;
1581  if (activation_candidate != active_model and myClaw->model_exists(active_model) and jt->second)
1582  {
1583  // If the already active model can be upcast to the activation candidate, abort the activiation of the candidate.
1584  if (myClaw->downstream_of(active_model, activation_candidate)) it->second = false;
1585  // If the candidate can be upcast to the already active model, activate the candidate instead of the already active model.
1586  if (myClaw->downstream_of(activation_candidate, active_model)) jt->second = false;
1587  if (verbose)
1588  {
1589  cout << "model: " << model << " " << "model to be activated: " << activation_candidate << "(" << it->second << ") active model: " << active_model << "(" << jt->second << ")" << endl;
1590  cout << "active model lives below:" << myClaw->downstream_of(active_model, activation_candidate) << endl;
1591  cout << "activation candidate lives below:" << myClaw->downstream_of(activation_candidate, active_model) << endl;
1592  }
1593  }
1594  }
1595  if (verbose) cout << "Activate candidate " << activation_candidate << "?" << it->second << endl;
1596  }
1597  }
1598  }
1599 
1600  // If this model fits any conditional dependencies (or descended from one that can be interpreted as one that fits any), then activate them.
1601  std::set<sspair> deps_to_activate = model_conditional_dependencies(model);
1602  for (std::set<sspair>::iterator it = deps_to_activate.begin() ; it != deps_to_activate.end(); ++it)
1603  {
1604  myDependencies.insert(*it);
1605  }
1606  // If this model fits any conditional backend requirements (or descended from one that can be interpreted as one that fits any), then activate them.
1607  std::set<sspair> backend_reqs_to_activate = model_conditional_backend_reqs(model);
1608  for (std::set<sspair>::iterator it = backend_reqs_to_activate.begin() ; it != backend_reqs_to_activate.end(); ++it)
1609  {
1610  if (verbose) cout << "req: " << it->first << " " << it->second << endl;
1611  myResolvableBackendReqs.insert(*it);
1612  myGroupedBackendReqs.at(backendreq_groups.at(*it)).insert(*it);
1613  }
1614  }
1615 
1616  // Initialise the memory of this functor.
1618  {
1619  int n = (iRunNested ? globlMaxThreads : 1);
1620  // Reserve enough space to hold as many timing points and recalculation flags as there are slots (threads) allowed
1621  if(start==NULL)
1622  {
1623  #pragma omp critical(module_functor_common_init_memory_start)
1624  {
1625  if(start==NULL) start = new std::chrono::time_point<std::chrono::system_clock>[n];
1626  }
1627  }
1628  if(end==NULL)
1629  {
1630  #pragma omp critical(module_functor_common_init_memory_end)
1631  {
1632  if(end==NULL) end = new std::chrono::time_point<std::chrono::system_clock>[n];
1633  }
1634  }
1635  if(needs_recalculating==NULL)
1636  {
1637  #pragma omp critical(module_functor_common_init_memory_needs_recalculating)
1638  {
1639  if(needs_recalculating==NULL)
1640  {
1641  needs_recalculating = new bool[n];
1642  std::fill(needs_recalculating, needs_recalculating+n, true);
1643  }
1644  }
1645  }
1646  if(already_printed==NULL)
1647  {
1648  #pragma omp critical(module_functor_common_init_memory_already_printed)
1649  {
1650  if(already_printed==NULL)
1651  {
1652  already_printed = new bool[n];
1653  std::fill(already_printed, already_printed+n, false);
1654  }
1655  }
1656  }
1657  if(already_printed_timing==NULL)
1658  {
1659  #pragma omp critical(module_functor_common_init_memory_already_printed_timing)
1660  {
1661  if(already_printed_timing==NULL)
1662  {
1663  already_printed_timing = new bool[n];
1664  std::fill(already_printed_timing, already_printed_timing+n, false);
1665  }
1666  }
1667  }
1668  }
1669 
1672  {
1673  start[thread_num] = std::chrono::system_clock::now();
1674  }
1675 
1678  {
1679  end[thread_num] = std::chrono::system_clock::now();
1680  std::chrono::duration<double> runtime = end[thread_num] - start[thread_num];
1681  #pragma omp critical(module_functor_common_finishTiming)
1682  {
1683  runtime_average = runtime_average*(1-fadeRate) + fadeRate*runtime.count();
1685  }
1686  needs_recalculating[thread_num] = false;
1687  }
1688 
1690 
1692  module_functor<void>::module_functor(void (*inputFunction)(),
1693  str func_name,
1694  str func_capability,
1695  str result_type,
1696  str origin_name,
1698  : module_functor_common(func_name, func_capability, result_type, origin_name, claw),
1699  myFunction (inputFunction) {}
1700 
1707  {
1708  if (myStatus == -3) // Do an explicit status check to hold standalone writers' hands
1709  {
1710  std::ostringstream ss;
1711  ss << "Sorry, the function " << origin() << "::" << name()
1712  << " cannot be used" << endl << "because it requires classes from a backend that you do not have installed."
1713  << endl << "Missing backends: ";
1714  for (auto it = missing_backends.begin(); it != missing_backends.end(); ++it) ss << endl << " " << *it;
1715  backend_error().raise(LOCAL_INFO, ss.str());
1716  }
1717  else if (myStatus == -4)
1718  {
1719  std::ostringstream ss;
1720  ss << "Sorry, the backend initialisation function " << name()
1721  << " cannot be used" << endl << "because it initialises a backend that you do not have installed!";
1722  backend_error().raise(LOCAL_INFO, ss.str());
1723  }
1724  boost::io::ios_flags_saver ifs(cout); // Don't allow module functions to change the output precision of cout
1725  int thread_num = omp_get_thread_num();
1726  fill_activeModelFlags(); // If activeModels hasn't been populated yet, make sure it is.
1727  init_memory(); // Init memory if this is the first run through.
1728  if (needs_recalculating[thread_num])
1729  {
1731 
1733  this->startTiming(thread_num);
1734  try
1735  {
1736  this->myFunction();
1737  }
1738  catch (invalid_point_exception& e)
1739  {
1741  if (omp_get_level()==0) // If not in an OpenMP parallel block, throw onwards
1742  {
1743  this->finishTiming(thread_num);
1745  throw(e);
1746  }
1747  }
1748  this->finishTiming(thread_num);
1749  logger().leaving_module();
1751  }
1752  }
1753 
1755  #ifndef NO_PRINTERS
1756  void module_functor<void>::print(Printers::BasePrinter*, const int, int) {}
1757  void module_functor<void>::print(Printers::BasePrinter*, const int) {}
1758  #endif
1759 
1761 
1764  str func_name,
1765  str func_capability,
1766  str result_type,
1767  str origin_name,
1769  : module_functor<ModelParameters>(inputFunction, func_name, func_capability, result_type, origin_name, claw)
1770  {
1771  init_memory();
1772  }
1773 
1776  {
1777  myValue->_definePar(parname);
1778  }
1779 
1782  {
1783  myValue->setModelName(model_name);
1784  }
1785 
1788  {
1789  for(std::map<std::string,double>::const_iterator it = myValue->begin();
1790  it != myValue->end();
1791  it++)
1792  {
1793  receiver.addParameter(it->first);
1794  }
1796  receiver.setModelName(myValue->getModelName());
1797  }
1798 
1800 
1802 
1805  str func_name,
1806  str func_capability,
1807  str result_type,
1808  str origin_name,
1810  : model_functor(inputFunction, func_name, func_capability, result_type, origin_name, claw) {}
1811 
1817  {
1818  return myValue;
1819  }
1820 
1822 
1823 }
str myVersion
Internal storage of the version of the module or backend to which the function belongs.
Definition: functors.hpp:328
str version() const
Getter for the version of the wrapped function&#39;s origin (module or backend)
Definition: functors.cpp:123
bool iCanManageLoops
Flag indicating whether this function can manage a loop over other functions.
Definition: functors.hpp:624
std::map< std::string, double >::const_iterator end() const
Get a const iterator to the last parameter map entry.
void notifyOfBackends(std::map< str, std::set< str > >)
Indicate to the functor which backends are actually loaded and working.
Definition: functors.cpp:1341
Options myOptions
Internal storage of function options, as a YAML node.
Definition: functors.hpp:355
std::map< sspair, void(*)(functor *)> backendreq_map
Map from (backend requirement-type pairs) to (pointers to templated void functions that set backend r...
Definition: functors.hpp:700
Gambit invalid loop iteration exception class.
Definition: exceptions.hpp:271
str purpose() const
Getter for purpose (relevant for output nodes, aka helper structures for the dep. resolution) ...
Definition: functors.cpp:138
virtual std::set< sspair > backendreqs()
Getter for listing all backend requirements.
Definition: functors.cpp:232
str find_friend_or_parent_model_in_map(str model, std::map< str, std::set< sspair > > karta)
Try to find a parent or friend model in some user-supplied map from models to sspair vectors...
Definition: functors.cpp:607
void setModelConditionalDependencySingular(str, str, void(*)(functor *, module_functor_common *))
Add a model conditional dependency for a single model.
Definition: functors.cpp:1129
void setRequiredClassloader(str, str, str)
Add a rule indicating that classes from a given backend must be available.
Definition: functors.cpp:1328
virtual std::set< sspair > backend_conditional_dependencies(str, str, str, str)
Getter for listing backend-specific conditional dependencies (4-string version)
Definition: functors.cpp:268
sspair retrieve_conditional_dep_type_pair(str)
Retrieve full conditional dependency-type pair from conditional dependency only.
Definition: functors.cpp:1060
virtual void startTiming(int)
Do pre-calculate timing things.
Definition: functors.cpp:1671
bool in_allowed_combo(str model)
Check that a model is actually part of a combination that is allowed to be used with this functor...
Definition: functors.cpp:547
bool contains_anything_interpretable_as_member_of(std::set< str > combo, str group)
Test whether any of the entries in a given model group is a valid interpretation of any members in a ...
Definition: functors.cpp:572
void setDependency(str, str, void(*)(functor *, module_functor_common *), str purpose="")
Add and activate unconditional dependencies.
Definition: functors.cpp:1045
std::map< str, str > backendreq_types
Map from backend requirements to their required types.
Definition: functors.hpp:690
safe_ptr< Options > getSubCaps()
Return a safe pointer to the subcaps that this functor realises it is supposed to facilitate downstre...
Definition: functors.cpp:407
bool point_exception_raised
A flag indicating whether or not this functor has invalidated the current point.
Definition: functors.hpp:600
std::map< str, std::set< str > > required_classloading_backends
Map from required classloading backends to their versions.
Definition: functors.hpp:709
Model helper declarations.
str myCapability
Internal storage of exactly what the function calculates.
Definition: functors.hpp:322
void setVertexID(int)
Setter for vertex ID (used in printer system)
Definition: functors.cpp:96
bool modelComboExplicitlyAllowed(std::set< str > combo)
Test whether the functor has been explictly allowed to be used with a given combination of models...
Definition: functors.cpp:477
void setBackendConditionalDependencySingular(str, str, str, str, void(*)(functor *, module_functor_common *))
Add a backend conditional dependency for a single backend version.
Definition: functors.cpp:1087
void setModelName(const std::string &)
virtual std::set< sspair > backend_conditional_dependencies(str req, str type, str be, str ver)
Getter for listing backend-specific conditional dependencies (4-string version)
Definition: functors.cpp:989
EXPORT_SYMBOLS error & utils_error()
Utility errors.
virtual void init_memory()
Initialise the memory of this functor.
Definition: functors.cpp:1617
virtual str loopManagerOrigin()
Getter for revealing the module of the wrapped function&#39;s assigned loop manager.
Definition: functors.cpp:211
void setAllowedModel(str model)
Add a model to the internal list of models for which this functor is allowed to be used...
Definition: functors.cpp:450
void fill_activeModelFlags()
Construct the list of known models only if it doesn&#39;t yet exist.
Definition: functors.cpp:1544
void setAllowedModelGroupCombo(str groups)
Add a combination of model groups to the internal list of combinations for which this functor is allo...
Definition: functors.cpp:511
primary_model_functor(void(*)(ModelParameters &), str, str, str, str, Models::ModelFunctorClaw &)
Constructor.
Definition: functors.cpp:1804
virtual str loopManagerCapability()
Getter for revealing the required capability of the wrapped function&#39;s loop manager.
Definition: functors.cpp:190
virtual str loopManagerOrigin()
Getter for revealing the module of the wrapped function&#39;s assigned loop manager.
Definition: functors.cpp:927
virtual void setNestedList(std::vector< functor *> &newNestedList)
Set the ordered list of pointers to other functors that should run nested in a loop managed by this o...
Definition: functors.cpp:1370
virtual void reset()
Definition: functors.cpp:85
module_functor_common(str, str, str, str, Models::ModelFunctorClaw &)
Constructor.
Definition: functors.cpp:637
virtual std::set< sspair > backendspermitted(sspair)
Getter for listing permitted backends.
Definition: functors.cpp:246
virtual void resolveDependency(functor *)
Resolve a dependency using a pointer to another functor object.
Definition: functors.cpp:311
const str myTimingLabel
String label, used to label functor timing data for printer system.
Definition: functors.hpp:337
A safe pointer that throws an informative error if you try to dereference it when nullified...
Definition: util_types.hpp:175
str myOrigin
Internal storage of the name of the module or backend to which the function belongs.
Definition: functors.hpp:326
virtual invalid_point_exception * retrieve_invalid_point_exception()
Retrieve the previously saved exception generated when this functor invalidated the current point in ...
Definition: functors.cpp:756
Actual module functor type for all but TYPE=void.
Definition: functors.hpp:745
virtual void resolveBackendReq(functor *)
Resolve a backend requirement using a pointer to another functor object.
Definition: functors.cpp:323
virtual void acknowledgeInvalidation(invalid_point_exception &, functor *f=NULL)
Acknowledge that this functor invalidated the current point in model space.
Definition: functors.cpp:741
virtual str loopManagerCapability()
Getter for revealing the required capability of the wrapped function&#39;s loop manager.
Definition: functors.cpp:921
void setBackendReq(str, str, str, str, void(*)(functor *))
Add an unconditional backend requirement The info gets updated later if this turns out to be contitio...
Definition: functors.cpp:1143
#define FUNCTORS_BASE_INVALIDATION_RATE
Minimum invaldiation rate (should be 0<...<<1)
Definition: functors.hpp:58
void addParameter(str parname)
Function for adding a new parameter to the map inside the ModelParameters object. ...
Definition: functors.cpp:1775
void makeBackendMatchingRule(str tag)
Add one or more rules for forcing backends reqs with the same tags to always be resolved from the sam...
Definition: functors.cpp:1287
bool modelExplicitlyAllowed(str model)
Test whether the functor is explictly always allowed to be used with a given model.
Definition: functors.cpp:437
virtual str safe_version() const
Getter for the &#39;safe&#39; incarnation of the version of the wrapped function&#39;s origin (module or backend)...
Definition: functors.cpp:125
#define LOCAL_INFO
Definition: local_info.hpp:34
virtual str loopManagerName()
Getter for revealing the name of the wrapped function&#39;s assigned loop manager.
Definition: functors.cpp:925
Function wrapper (functor) base class.
Definition: functors.hpp:87
void setStatus(int)
Setter for status: -6 = required external tool absent (pybind11) -5 = required external tool absent (...
Definition: functors.cpp:108
EXPORT_SYMBOLS void strip_parentheses(str &)
Strips leading and/or trailing parentheses from a string.
functor(str, str, str, str, Models::ModelFunctorClaw &)
Constructor.
Definition: functors.cpp:57
void makeBackendOptionRule(str, str)
Add a rule for dictating which backends can be used to fulfill which backend requirements.
Definition: functors.cpp:1222
virtual bool requiresPrinting() const
Getter indicating if the wrapped function&#39;s result should to be printed.
Definition: functors.cpp:144
virtual void setPrintRequirement(bool)
Setter for indicating if the wrapped function&#39;s result should to be printed.
Definition: functors.cpp:153
void makeBackendRuleForModel(str, str)
Add a rule for activating backend requirements according to the model being scanned.
Definition: functors.cpp:1165
void entering_module(int)
Set the internal variables tracking which module and/or backend is currently running.
Definition: logmaster.cpp:620
virtual bool requiresTimingPrinting() const
Getter indicating if the timing data for this function&#39;s execution should be printed.
Definition: functors.cpp:146
model_functor(void(*)(ModelParameters &), str, str, str, str, Models::ModelFunctorClaw &)
Constructor.
Definition: functors.cpp:1763
std::map< str, str > myConditionalDependencies
Map of conditional dependencies to their types.
Definition: functors.hpp:667
Functor template class definitions.
virtual std::set< sspair > backendspermitted(sspair quant)
Getter for listing permitted backends.
Definition: functors.cpp:949
bool myLoopIsDone
Flag indicating whether this function is ready to finish its loop (only relevant if iCanManageLoops =...
Definition: functors.hpp:627
bool verbose
Debug flag.
Definition: functors.hpp:352
int str2tag(const std::string &)
Definition: logging.cpp:152
safe_ptr< Options > getOptions()
Return a safe pointer to the options that this functor is supposed to run with (e.g. from the ini file).
Definition: functors.cpp:375
#define FUNCTORS_FADE_RATE
Decay rate of average runtime estimate [(number of functor evaluations)^-1].
Definition: functors.hpp:56
double getInvalidationRate()
Getter for invalidation rate.
Definition: functors.cpp:768
std::map< str, std::set< sspair > > myForcedMatches
Map from tags to sets of matching (backend requirement-type pairs) that are forced to use the same ba...
Definition: functors.hpp:706
str myPurpose
Purpose of the function (relevant for output and next-to-output functors)
Definition: functors.hpp:330
virtual std::set< sspair > model_conditional_backend_reqs(str)
Getter for listing model-specific conditional backend requirements.
Definition: functors.cpp:303
void notifyOfSubCaps(const Options &)
Notify the functor about an instance of the options class that contains sub-capability information...
Definition: functors.cpp:381
void setConditionalDependency(str, str)
Add conditional dependency-type pairs in advance of later conditions.
Definition: functors.cpp:1054
virtual void setTimingPrintRequirement(bool)
Setter for indicating if the timing data for this function&#39;s execution should be printed.
Definition: functors.cpp:162
Logging access header for GAMBIT.
std::set< sspair > myBackendReqs
Set of all backend requirement-type string pairs.
Definition: functors.hpp:655
virtual void notifyOfModel(str)
Notify the functor that a certain model is being scanned, so that it can activate itself accordingly...
Definition: functors.cpp:329
virtual void calculate()
Virtual calculate(); needs to be redefined in daughters.
Definition: functors.cpp:76
module_functor(void(*)(TYPE &), str, str, str, str, Models::ModelFunctorClaw &)
Constructor.
std::map< sspair, str > backendreq_groups
Map from backend requirements to their designated groups.
Definition: functors.hpp:693
sspair quantity() const
Getter for the overall quantity provided by the wrapped function (capability-type pair) ...
Definition: functors.cpp:136
std::vector< functor * > myNestedFunctorList
Vector of functors that have been set up to run nested within this one.
Definition: functors.hpp:640
virtual void setNestedList(std::vector< functor *> &)
Set the ordered list of pointers to other functors that should run nested in a loop managed by this o...
Definition: functors.cpp:171
str myType
Internal storage of the type of what the function calculates.
Definition: functors.hpp:324
virtual void init_memory()
Initialise the memory of this functor.
double getRuntimeAverage()
Getter for averaged runtime.
Definition: functors.cpp:694
bool allModelsAllowed()
Test whether the functor is allowed to be used with all models.
Definition: functors.cpp:444
str origin() const
Getter for the wrapped function&#39;s origin (module or backend name)
Definition: functors.cpp:121
bool downstream_of(const str &, const str &) const
Check if model 1 exists somewhere downstream of (and can be therefore be interpreted as a) model 2...
Definition: models.cpp:286
std::map< sspair, std::set< str > > backendreq_tagmap
Map from backend requirements to their rule tags.
Definition: functors.hpp:696
virtual void resolveDependency(functor *dep_functor)
Resolve a dependency using a pointer to another functor object.
Definition: functors.cpp:1386
Gambit invalid point exception class.
Definition: exceptions.hpp:229
bool myTimingPrintFlag
Flag to select whether or not the timing data for this function&#39;s execution should be printed;...
Definition: functors.hpp:585
int vertexID() const
Getter for vertex ID.
Definition: functors.cpp:140
std::map< sspair, void(*)(functor *, module_functor_common *)> dependency_map
Map from (dependency-type pairs) to (pointers to templated void functions that set dependency functor...
Definition: functors.hpp:683
virtual str loopManagerType()
Getter for revealing the required type of the wrapped function&#39;s loop manager.
Definition: functors.cpp:923
void setFadeRate(double)
Setter for the fade rate.
Definition: functors.cpp:774
std::set< sspair > myDependees
List of all capability,type pairs of functors downstream of this one in the dependency tree...
Definition: functors.hpp:361
void setTimingPrintRequirement(bool)
Setter for indicating if the timing data for this function&#39;s execution should be printed.
Definition: functors.cpp:700
bool allowed_parent_or_friend_exists(str model)
Test if there is a model in the functor&#39;s allowedModels list as which this model can be interpreted...
Definition: functors.cpp:534
virtual std::set< str > backendgroups()
Getter for listing backend requirement groups.
Definition: functors.cpp:225
virtual void notifyOfDependee(functor *)
Notify the functor that another functor depends on it.
Definition: functors.cpp:1410
std::map< sspair, functor * > dependency_functor_map
Map from (dependency-type pairs) to pointers to functors used to resolve them that set dependency fun...
Definition: functors.hpp:687
std::map< str, std::set< str > > modelGroups
Map from model group names to group contents.
Definition: functors.hpp:370
std::set< sspair > myResolvableBackendReqs
Set of all backend requirement-type string pairs currently available for resolution.
Definition: functors.hpp:658
std::pair< str, str > sspair
Shorthand for a pair of standard strings.
Definition: util_types.hpp:64
void setPurpose(str)
Setter for purpose (relevant only for next-to-output functors)
Definition: functors.cpp:93
bool * needs_recalculating
Needs recalculating or not?
Definition: functors.hpp:615
Functor derived class for module functions.
Definition: functors.hpp:399
bool hasKey(const args &... keys) const
Getters for key/value pairs (which is all the options node should contain)
virtual std::set< sspair > model_conditional_dependencies(str model)
Getter for listing model-specific conditional dependencies.
Definition: functors.cpp:1027
virtual void notifyOfDependee(functor *)
Notify the functor that it is being used to fill a dependency of another functor. ...
Definition: functors.cpp:335
Models object that performs initialisation and checking operations on a primary_model_functor list...
Definition: models.hpp:55
virtual void finishTiming(int)
Do post-calculate timing things.
Definition: functors.cpp:1677
TYPE getValue(const args &... keys) const
A safe pointer designed to point at an array, and return the entry in that array corresponding to the...
Definition: util_types.hpp:230
virtual void setLoopManagerCapType(str cap, str t)
Setter for specifying the capability required of a manager functor, if it is to run this functor nest...
Definition: functors.cpp:914
str name() const
Getter for the wrapped function&#39;s name.
Definition: functors.cpp:115
error & backend_error()
Backend errors.
virtual void resolveLoopManager(functor *)
Set this functor&#39;s loop manager (if it has one)
Definition: functors.cpp:317
virtual double getInvalidationRate()
Definition: functors.cpp:82
std::map< std::string, double >::const_iterator begin() const
Get a const iterator to the first parameter map entry.
bool has_common_elements(std::set< str > combo, str group)
Work out whether a given combination of models and a model group have any elements in common...
Definition: functors.cpp:594
Functor class definitions.
double pInvalidation
Probability that functors invalidates point in model parameter space.
Definition: functors.hpp:612
virtual void reset_and_calculate()
Reset-then-recalculate method.
Definition: functors.cpp:90
static void failBigTime(str method)
Attempt to retrieve a dependency or model parameter that has not been resolved.
Definition: functors.cpp:522
ModelParameters * getcontentsPtr()
Functor contents raw pointer "get" function Returns a raw pointer to myValue, so that the contents ma...
Definition: functors.cpp:1816
std::map< str, bool > activeModelFlags
Map from known models to flags indicating if they are activated or not (known = allowed, in allowed groups or conditions for conditional dependencies)
Definition: functors.hpp:679
virtual std::set< str > backendreq_tags(sspair)
Getter for listing tags associated with backend requirements.
Definition: functors.cpp:253
virtual str loopManagerName()
Getter for revealing the name of the wrapped function&#39;s assigned loop manager.
Definition: functors.cpp:204
virtual void notifyOfInvalidation(const str &)
Definition: functors.cpp:84
str timingLabel() const
Getter for the printer timing label.
Definition: functors.cpp:150
virtual bool canBeLoopManager()
Getter for revealing whether this is permitted to be a manager functor.
Definition: functors.cpp:183
void setModelConditionalDependency(str, str, void(*)(functor *, module_functor_common *))
Add a model conditional dependency for multiple models.
Definition: functors.cpp:1117
virtual void breakLoopFromManagedFunctor()
Tell the manager of the loop in which this functor runs that it is time to break the loop...
Definition: functors.cpp:855
virtual std::set< sspair > forcematchingbackend(str)
Getter for listing backend requirements that must be resolved from the same backend.
Definition: functors.cpp:975
virtual void raise(const std::string &)
Raise the exception, i.e. throw it. Exact override of base method.
Definition: exceptions.cpp:422
virtual std::set< sspair > dependencies()
Getter for listing currently activated dependencies.
Definition: functors.cpp:218
void donateParameters(model_functor &receiver)
Function for handing over parameter identities to another model_functor.
Definition: functors.cpp:1787
virtual void init_myCurrentIteration_if_NULL()
Initialise the array holding the current iteration(s) of this functor.
Definition: functors.cpp:835
virtual void print(Printers::BasePrinter *printer, const int pointID, int index)
Printer function.
EXPORT_SYMBOLS warning & utils_warning()
Utility warnings.
const str myLabel
String label, used to label functor results for printer system.
Definition: functors.hpp:335
bool * already_printed
Has result already been sent to the printer?
Definition: functors.hpp:618
#define FUNCTORS_RUNTIME_INIT
Initial runtime estimate (s)
Definition: functors.hpp:60
EXPORT_SYMBOLS void strip_whitespace_except_after_const(str &)
Strip all whitespace except that following "const", in which case the whitespace is replaced by a sin...
Functors specific to ModelParameters objects.
Definition: functors.hpp:974
virtual void breakLoop()
Tell the functor that the loop it manages should break now.
Definition: functors.cpp:276
const int method
Definition: Axions.cpp:655
safe_ptr< str > getChosenReqFromGroup(str)
Return a safe pointer to a string indicating which backend requirement has been activated for a given...
Definition: functors.cpp:795
std::set< sspair > myDependencies
Vector of dependency-type string pairs.
Definition: functors.hpp:664
virtual std::set< sspair > dependencies()
Getter for listing currently activated dependencies.
Definition: functors.cpp:930
virtual ~module_functor_common()
Destructor.
Definition: functors.cpp:669
virtual invalid_point_exception * retrieve_invalid_point_exception()
Retrieve the previously saved exception generated when this functor invalidated the current point in ...
Definition: functors.cpp:631
void calculate()
Calculate method.
bool requiresTimingPrinting() const
Getter indicating if the timing data for this function&#39;s execution should be printed.
Definition: functors.cpp:706
std::map< sspair, std::set< sspair > > permitted_map
Map from (backend requirement-type pairs) to (set of permitted {backend-version} pairs) ...
Definition: functors.hpp:703
virtual std::set< sspair > model_conditional_backend_reqs(str model)
Getter for listing model-specific conditional backend requirements.
Definition: functors.cpp:1036
const bool verbose
Definition: logging.cpp:52
bool getActiveModelFlag(str)
Indicate whether or not a known model is activated or not.
Definition: functors.cpp:780
long long * myCurrentIteration
Pointer to counters for iterations of nested functor loop.
Definition: functors.hpp:643
safe_ptr< std::set< sspair > > getDependees()
Return a safe pointer to the vector of all capability,type pairs of functors arranged downstream of t...
Definition: functors.cpp:413
void notifyOfInvalidation(const str &)
Tell the functor that it invalidated the current point in model space, pass a message explaining why...
Definition: functors.cpp:734
EXPORT_SYMBOLS Logging::LogMaster & logger()
Function to retrieve a reference to the Gambit global log object.
Definition: logger.cpp:95
Printers::BaseBasePrinter printer
Type of the printer objects.
str type() const
Getter for the wrapped function&#39;s reported return type.
Definition: functors.cpp:119
void setBackendConditionalDependency(str, str, str, str, void(*)(functor *, module_functor_common *))
Add a backend conditional dependency for multiple backend versions.
Definition: functors.cpp:1075
virtual double getRuntimeAverage()
Interfaces for runtime optimization Need to be implemented by daughters.
Definition: functors.cpp:81
bool is_disjoint(const Set1 &set1, const Set2 &set2)
Test if two sets are disjoint (works on any sorted std container I think)
void setTimingVertexID(int)
Set ID for timing &#39;vertex&#39; (used in printer system)
Definition: functors.cpp:99
std::vector< str > missing_backends
Vector of required backends currently missing.
Definition: functors.hpp:712
std::string str
Shorthand for a standard string.
Definition: Analysis.hpp:35
bool model_exists(const str &) const
Indicate whether a model is recognised by GAMBIT or not.
Definition: models.cpp:209
virtual std::set< sspair > model_conditional_dependencies(str)
Getter for listing model-specific conditional dependencies.
Definition: functors.cpp:295
str capability() const
Getter for the wrapped function&#39;s reported capability.
Definition: functors.cpp:117
virtual std::set< str > backendreq_tags(sspair)
Getter for listing tags associated with backend requirements.
Definition: functors.cpp:962
void setModelGroup(str group, str contents)
Add a model group definition to the internal list of model groups.
Definition: functors.cpp:501
Header for logging classes.
std::map< str, std::set< sspair > > myGroupedBackendReqs
Set of backend requirement-type string pairs for specific backend groups.
Definition: functors.hpp:661
double fadeRate
Fade rate for average runtime.
Definition: functors.hpp:609
virtual void resetLoop()
Provide a way to reset the flag indicating that a loop managed by this functor should break...
Definition: functors.cpp:886
virtual void setIteration(long long iteration)
Setter for setting the iteration number in the loop in which this functor runs.
Definition: functors.cpp:895
virtual void notifyOfModel(str model)
Notify the functor that a certain model is being scanned, so that it can activate its dependencies an...
Definition: functors.cpp:1561
str label() const
Getter for string label.
Definition: functors.cpp:148
void setModelName(str model_name)
Function for setting the model name for a ModelParameters object. Mainly for better error messages...
Definition: functors.cpp:1781
virtual void setCanBeLoopManager(bool canManage)
Setter for specifying whether this is permitted to be a manager functor, which runs other functors ne...
Definition: functors.cpp:909
std::map< std::vector< str >, std::set< sspair > > myBackendConditionalDependencies
Map from (vector with 4 strings: backend req, type, backend, version) to (set of {conditional depende...
Definition: functors.hpp:670
functor * myLoopManager
Pointer to the functor that mangages the loop that this function runs inside of.
Definition: functors.hpp:637
virtual omp_safe_ptr< long long > iterationPtr()
Return a safe pointer to the iteration number in the loop in which this functor runs.
Definition: functors.cpp:902
virtual void resolveBackendReq(functor *be_functor)
Resolve a backend requirement using a pointer to another functor object.
Definition: functors.cpp:1446
int timingVertexID() const
Getter for timing vertex ID.
Definition: functors.cpp:142
bool * already_printed_timing
Has timing data already been sent to the printer?
Definition: functors.hpp:621
std::map< str, std::set< sspair > > myModelConditionalBackendReqs
Map from models to (set of {conditional backend requirement-type} pairs)
Definition: functors.hpp:676
std::chrono::time_point< std::chrono::system_clock > * end
Definition: functors.hpp:597
str myLoopManagerCapability
Capability of a function that mangages a loop that this function can run inside of.
Definition: functors.hpp:633
std::set< std::set< str > > allowedGroupCombos
List of allowed model group combinations.
Definition: functors.hpp:367
virtual void notifyOfBackends(std::map< str, std::set< str > >)
Indicate to the functor which backends are actually loaded and working.
Definition: functors.cpp:341
EXPORT_SYMBOLS std::vector< str > delimiterSplit(str s, str delim)
Split a string into a vector of strings, using a delimiter, and removing any whitespace around the de...
std::chrono::time_point< std::chrono::system_clock > * start
Beginning and end timing points.
Definition: functors.hpp:597
Exception objects required for standalone compilation.
virtual void setIteration(long long)
Set the iteration number in a loop in which this functor runs.
Definition: functors.cpp:177
double runtime_average
Averaged runtime in ns.
Definition: functors.hpp:606
virtual void setInUse(bool)
Set the inUse flag (must be overridden in derived class to have any effect).
Definition: functors.hpp:130
void notifyOfIniOptions(const Options &)
Notify the functor about an instance of the options class that contains information from its correspo...
Definition: functors.cpp:369
virtual safe_ptr< bool > loopIsDone()
Return a safe pointer to the flag indicating that a loop managed by this functor should break now...
Definition: functors.cpp:880
void set_thrower(functor *)
Set the pointer to the functor that threw the invalid point exception.
Definition: exceptions.cpp:401
virtual void iterate(long long iteration)
Execute a single iteration in the loop managed by this functor.
Definition: functors.cpp:802
std::string getModelName() const
Getters/setters for model and output names.
void(* myFunction)(TYPE &)
Internal storage of function pointer.
Definition: functors.hpp:783
invalid_point_exception & invalid_point()
Invalid point exceptions.
void _definePar(const std::string &newkey)
Define a parameter with name, value (i.e. add to internal map). Value is initialised to zero...
void check_missing_LogTag()
Check if an appropriate LogTag for this functor is missing from the logging system.
Definition: functors.cpp:680
bool iRunNested
Flag indicating whether this function can run nested in a loop over functions.
Definition: functors.hpp:630
virtual void setFadeRate(double)
Definition: functors.cpp:83
str myLoopManagerType
Capability of a function that mangages a loop that this function can run inside of.
Definition: functors.hpp:635
virtual std::set< str > backendgroups()
Getter for listing backend requirement groups.
Definition: functors.cpp:932
str myName
Internal storage of the function name.
Definition: functors.hpp:320
void setModelConditionalBackendReq(str model, str req, str type)
Add a model conditional backend requirement for multiple models.
Definition: functors.cpp:1190
void setValue(const KEYTYPE &key, const VALTYPE &val)
Basic setter, for adding extra options.
Simple container used for storing info about which types have been defined as equivalent for depencen...
virtual std::set< sspair > backendreqs()
Getter for listing all backend requirements.
Definition: functors.cpp:934
std::set< str > myGroups
Internal list of backend groups that this functor&#39;s requirements fall into.
Definition: functors.hpp:649
virtual str loopManagerType()
Getter for revealing the required type of the wrapped function&#39;s loop manager.
Definition: functors.cpp:197
void setModelConditionalBackendReqSingular(str model, str req, str type)
Add a model conditional backend requirement for a single model.
Definition: functors.cpp:1202
virtual void resolveLoopManager(functor *)
Set this functor&#39;s loop manager (if it has one)
Definition: functors.cpp:1423
std::map< str, str > chosenReqsFromGroups
Map from groups to backend reqs, indicating which backend req has been activated for which backend gr...
Definition: functors.hpp:652
invalid_point_exception raised_point_exception
An exception raised because this functor has invalidated the current point.
Definition: functors.hpp:603
bool modelComboAllowed(std::set< str > combo)
Test whether the functor is allowed (either explicitly or implicitly) to be used with a given combina...
Definition: functors.cpp:453
int myVertexID
Internal storage of the vertex ID number used by the printer system to identify functors.
Definition: functors.hpp:348
Gambit halt loop exception class.
Definition: exceptions.hpp:260
int myStatus
Status: -4 = required backend absent (backend ini functions) -3 = required classes absent -2 = functi...
Definition: functors.hpp:346
virtual bool canBeLoopManager()
Getter for revealing whether this is permitted to be a manager functor.
Definition: functors.cpp:911
const int globlMaxThreads
Maximum number of OpenMP threads this MPI process is permitted to launch in total.
Definition: functors.hpp:646
void setPermittedBackend(str req, str be, str ver)
Add a single permitted backend version.
Definition: functors.cpp:1262
const Models::ModelFunctorClaw * myClaw
Bound model functor claw, for checking relationships between models.
Definition: functors.hpp:332
str fix_type(str)
Clean out whitespace and strip Gambit and default BOSSed class namespaces.
int status() const
Getter for the wrapped function current status: -4 = required backend absent (backend ini functions) ...
Definition: functors.cpp:134
virtual void breakLoop()
Tell the functor that the loop it manages should break now.
Definition: functors.cpp:871
error & model_error()
Model errors.
bool modelAllowed(str model)
Test whether the functor is always allowed (either explicitly or implicitly) to be used with a given ...
Definition: functors.cpp:419
TODO: see if we can use this one:
Definition: Analysis.hpp:33
A small wrapper object for &#39;options&#39; nodes.
int myTimingVertexID
ID assigned by printers to the timing data output stream.
Definition: functors.hpp:350
int myLogTag
Integer LogTag, for tagging log messages.
Definition: functors.hpp:718
std::set< str > allowedModels
List of allowed models.
Definition: functors.hpp:364
ModelParameters * myValue
Internal pointer to storage location of function value.
Definition: functors.hpp:786
std::map< str, std::set< sspair > > myModelConditionalDependencies
Map from models to (set of {conditional dependency-type} pairs)
Definition: functors.hpp:673
virtual void print(Printers::BasePrinter *printer, const int pointID, int thread_num)
Printer function.
Definition: functors.cpp:348
void reset()
Reset functor.
Definition: functors.cpp:712
Options mySubCaps
Internal storage of function sub-capabilities, as a YAML node.
Definition: functors.hpp:358
virtual std::set< sspair > forcematchingbackend(str)
Getter for listing backend requirements that must be resolved from the same backend.
Definition: functors.cpp:260