postprocessor_object.cpp
Go to the documentation of this file.
52 Chunk get_effective_chunk(const std::size_t total_length, const unsigned int rank, const unsigned int numtasks) 75 Chunk get_my_chunk(const std::size_t dset_length, const ChunkSet& done_chunks, const int rank, const int numtasks) 85 // Whoops, cannot just add lengths, because done_chunks can overlap. Need to add up the actual gaps 88 if(not first_chunk) gap_size -= (prev_chunk_end+1); // e.g. previous chunk finished at '1'; then gap_size is len(2,3,4) = 3 = 5 - 2. Unless no previous chunk, then gap_size is len(0,1,2,3,4) = 5. 89 // std::cout << "Rank "<<rank<<": "<<"examining done_chunk ["<<it->start<<","<<it->end<<"]"<<std::endl; 90 // std::cout << "Rank "<<rank<<": "<<"first? "<<first_chunk<<", prev_chunk_end = "<<prev_chunk_end<<std::endl; 109 if(not first_chunk) last_gap_size -= (prev_chunk_end+1); // e.g. dataset ends at 9 (length 10); previous chunk finished at 6; last_gap_size = len(7,8,9) = 3 = 10 - (6+1) 121 err << "Rank "<<rank<<" chunk calculation encountered nonsense! Computed number of points left to process ("<<left_to_process<<") is greater than the actual dataset length ("<<dset_length<<")! This is a bug in the postprocessor, please report it." <<std::endl; 125 // Get 'effective' start/end positions for this rank; i.e. what the start index would be if the 'done' points were removed. 131 realchunk.eff_length = eff_chunk.length(); // Record real number of points that will be processed from this chunk 141 // Need to add up the size of the gaps between chunks until we exceed the "effective" start/end positions, 143 //std::cout << "Rank "<<rank<<": Getting next done_chunk ["<<it->start<<","<<it->end<<"]"<<std::endl; 145 if(not first_chunk) gap_size -= (prev_chunk_end+1); // e.g. previous chunk finished at '1'; then gap_size is len(2,3,4) = 3 = 5 - 2. Unless no previous chunk, then gap_size is len(0,1,2,3,4) = 5. 146 //std::cout << "Rank "<<rank<<": "<<"examining done_chunk ["<<it->start<<","<<it->end<<"]"<<std::endl; 147 //std::cout << "Rank "<<rank<<": "<<"first? "<<first_chunk<<", prev_chunk_end = "<<prev_chunk_end<<std::endl; 152 //std::cout << "Rank "<<rank<<": count = "<<count<<" (added gap of size "<<gap_size<<"; done_chunk.start="<<it->start<<" - prev_chunk_end="<<prev_chunk_end<<")"<<std::endl; 157 std::size_t overshoot = count - eff_chunk.start; // If count is 3 and our chunk is supposed to start at the first 'not done' point (index 0), we have overshot by 3 - 0 = 3 positions. 161 //std::cout << "Rank "<<rank<<": found start of chunk! realchunk.start = "<<realchunk.start<<", eff_chunk.start = "<<eff_chunk.start<<", overshoot = "<<overshoot<<std::endl; 166 std::size_t overshoot = count - eff_chunk.end; // Suppose our chunk should also end on the first 'not done' point (i.e. we have only one point assigned). Then we have the same calculation as above for the end. 171 //std::cout << "Rank "<<rank<<": found end of chunk! realchunk.end = "<<realchunk.end<<", eff_chunk.end = "<<eff_chunk.end<<", overshoot = "<<overshoot<<std::endl; 193 if(not first_chunk) last_gap_size -= (prev_chunk_end+1); // e.g. dataset ends at 9 (length 10); previous chunk finished at 6; last_gap_size = len(7,8,9) = 3 = 10 - (6+1) 197 err << "Rank "<<rank<<" chunk calculation encountered nonsense! Size of gap between last 'done_chunk' and the end of the dataset was computed as less than zero! ("<<last_gap_size<<" = dset_length("<<dset_length<<") - prev_chunk_end("<<prev_chunk_end<<")). This is a bug in the postprocessor, please report it." <<std::endl; 201 //std::cout << "Rank "<<rank<<": count = "<<count<<" (added LAST gap of size "<<last_gap_size<<"; dset_length="<<dset_length<<" - prev_chunk_end="<<prev_chunk_end<<")"<<std::endl; 204 std::size_t overshoot = count - eff_chunk.start; // ok so from above count=3, say. Suppose eff_chunk.start=0. overshoot=3 223 err << "Rank "<<rank<<" chunk calculation returned nonsense! Assigned start of chunk ("<<realchunk.start<<") exceeds length of dataset ("<<dset_length<<") (end of chunk was "<<realchunk.end<<"). This is a bug in the postprocessor, please report it." <<std::endl; 229 err << "Rank "<<rank<<" chunk calculation returned nonsense! Assigned end of chunk ("<<realchunk.end<<") exceeds length of dataset ("<<dset_length<<") (start of chunk was "<<realchunk.start<<"). This is a bug in the postprocessor, please report it." <<std::endl; 244 err << "Rank "<<rank<<" chunk calculation returned nonsense! The assigned chunk start or end point is already listed as 'done'! This is a bug in the postprocessor, please report it. Debug output:" <<std::endl; 258 // First read collated chunk data from past resumes, and the number of processes used in the last run 292 err << "Tried to read postprocessor resume data from "<<in<<" but encountered a read error of some kind (the file seems to exist but appears to be unreadable"; 299 err << "Tried to read postprocessor resume data from "<<in<<" but the file does not exist or is unreadable. We require this file because according to "<<inprev<<" there were "<<prev_size<<" processes in use during the last run, and we require the resume data from all of them"; 307 err << "Tried to read postprocessor resume data from "<<inprev<<" but encountered a read error of some kind (the file seems to exist but appears to be unreadable"; 311 // Else there is no resume data, assume that this is a new run started without the --restart flag. 343 // Sanity check; Starts and ends of merged chunks should match some start/end in the input chunks 358 err << "Error, merged 'done_chunks' are not consistent with the originally input done_chunks! This indicates a bug in the merge_chunks routine of the postprocessor, please report it. Debug output:" << endl; 371 void record_done_points(const ChunkSet& done_chunks, const Chunk& mydone, const std::string& filebase, unsigned int rank, unsigned int size) 526 std::vector<std::string> keys = getLogLike()->getPrior().getParameters(); // use to use get_keys() in the objective (prior) plugin; 529 if(rank==0) std::cout << "Number of model parameters to be retrieved from previous output: "<< keys.size() <<std::endl; 543 err << "No MPI communicator supplied to postprocessor driver object! This is a bug in the postprocessor scanner plugin, please report it."; 555 err << "Postprocessor tried to access reader object, but found only a NULL pointer! The postprocessor has therefore not been set up correctly, please report this bug."; 566 err << "Postprocessor tried to access printer object, but found only a NULL pointer! The postprocessor has therefore not been set up correctly, please report this bug."; 578 // err << "Postprocessor tried to access LogLike object, but found only a NULL pointer! The postprocessor has therefore not been set up correctly, please report this bug."; 618 new_params = all_params; // Parameters not present in the input file; to be deduced here. Start from everything and cut out those in the input file. 626 err << "Error starting postprocessing run! The 'purpose' name selected for the likelihood to be computed ('"<<logl_purpose_name<<"') collides with an entry in the chosen input data. Please either change the name given in the scanner option 'like', or set 'permit_discard_old_likes' to 'true' to allow the old data to be replaced in the new output."; 633 err << "Error starting postprocessing run! The label name selected for the result of likelihood weighting ('"<<reweighted_loglike_name<<"') collides with an entry in the chosen input data. Please either change the name given in the scanner option 'reweighted_like', or set 'permit_discard_old_likes' to 'true' to allow the old data to be replaced in the new output."; 641 for(std::map<std::string,std::string>::iterator it = renaming_scheme.begin(); it!=renaming_scheme.end(); ++it) 652 err << "Could not find data labelled '"<<in_label<<"' in the input dataset for postprocessing! In your master YAML file you have requested this data to be relabelled to '"<<out_label<<"', however it could not be found under the specified input label."; 662 err << "Cannot rename dataset '"<<in_label<<"' to '"<<out_label<<"'! The requested output label has already been claimed by some other component in the scan. Please choose a different output label for this dataset in the master YAML file, or remove it from the 'rename' options for the postprocessor scanner plugin"; 667 std::set<std::string>::iterator jt = std::find(data_labels.begin(), data_labels.end(), out_label); 676 err << "Cannot rename dataset '"<<in_label<<"' to '"<<out_label<<"'! The requested output label clashes with an item in the input dataset (which isn't getting renamed). Please choose a different output label for this dataset in the master YAML file, remove it from the 'rename' options for the postprocessor scanner plugin, or request for the conflicting input label to be renamed."; 691 err << "Cannot rename dataset '"<<in_label<<"' to '"<<out_label<<"'! The requested output label has already been claimed by some another item in the renaming scheme (you requested '"<<jt->first<<"' to also be renamed to '"<<jt->second<<"'). Please choose a different output label for one of these datasets in the master YAML file, or remove one of them from the 'rename' options for the postprocessor scanner plugin"; 700 err << "Cannot rename dataset '"<<in_label<<"' to '"<<out_label<<"'! The input dataset has a special purpose so renaming it is forbidden. Please remove it from the 'rename' options for the postprocessor scanner plugin in your master YAML file."; 706 for(std::map<std::string,double>::iterator it = cut_less_than.begin(); it!=cut_less_than.end(); ++it) 717 err << "Could not find data labelled '"<<in_label<<"' in the input dataset for postprocessing! In your master YAML file you have requested to only postprocess points satisfying the criteria '"<<in_label<<"' <= "<<cut_value<<", however the requested dataset for cutting could not be found under the specified input label. Please fix the label or remove this entry from the 'cut_less_than' list."; 725 err << "Type of input dataset '"<<in_label<<"' is not 'double'! In your master YAML file you have requested to only postprocess points satisfying the criteria '"<<in_label<<"' <= "<<cut_value<<", however the requested dataset for cutting cannot be retrieved as type 'double'. Currently cuts can only be applied to datasets stored as doubles, sorry! Please remove this entry from the 'cut_less_than' list."; 732 for(std::map<std::string,double>::iterator it = cut_greater_than.begin(); it!=cut_greater_than.end(); ++it) 743 err << "Could not find data labelled '"<<in_label<<"' in the input dataset for postprocessing! In your master YAML file you have requested to only postprocess points satisfying the criteria '"<<in_label<<"' >= "<<cut_value<<", however the requested dataset for cutting could not be found under the specified input label. Please fix the label or remove this entry from the 'cut_greater_than' list."; 751 err << "Type of input dataset '"<<in_label<<"' is not 'double'! In your master YAML file you have requested to only postprocess points satisfying the criteria '"<<in_label<<"' <= "<<cut_value<<", however the requested dataset for cutting cannot be retrieved as type 'double'. Currently cuts can only be applied to datasets stored as doubles, sorry! Please remove this entry from the 'cut_greater_than' list."; 758 if(rank==0) std::cout << "Determining which data is to be copied from input file to new output file, and which will be recomputed..." <<std::endl; 783 ) // if not [input data label] starts with [existing parameter] (plus append seperator character, for extra info like parameter name or index) 785 // Then it is not new. Not allowed to copy this, the likelihood container is already printing it anew. 852 // are going to be replaced in the new output. User must set 'permit_discard_old_likes" to explictly allow this. 859 err << "Error starting postprocessing run! One of the data entries listed in the option 'add_to_like' is scheduled to be recalculated during postprocessing ("<<*it<<"). This is permitted; the old value will be added to 'like' and then discarded and replaced by the new value, however you must explicitly permit this to occur by setting 'permit_discard_old_likes' to 'true'."; 870 err << "Error starting postprocessing run! One of the data entries listed in the option 'subtract_from_like' is scheduled to be recalculated during postprocessing ("<<*it<<"). This is permitted; the old value will be subtracted from 'like' and then discarded and replaced by the new value, however you must explicitly permit this to occur by setting 'permit_discard_old_likes' to 'true'."; 884 if(rank==0) std::cout<<"Computing work assignments (may take a little time for very large datasets)"<<std::endl; 889 getReader().reset(); // Make sure we start from the beginning of the file upon redistributing work 893 if(rank==0) std::cout << "Starting loop over old points ("<<total_length<<" in total)" << std::endl; 894 std::cout << "This task (rank "<<rank<<" of "<<numtasks<<"), will process iterations "<<mychunk.start<<" through to "<<mychunk.end<<", excluding any points that may have already been processed as recorded by resume data. This leaves "<<mychunk.eff_length<<" points for this rank to process."<<std::endl; 898 // Disable auto-incrementing of pointID's in the likelihood container. We will set these manually. 902 bool redistribution_requested = false; // Flag to temporarily stop to redistribute remaining workload amongst MPI processes 908 std::cout << "Postprocessor (rank "<<rank<<") immediately reached end of input file! Skipping execution of main loop, ..."<<std::endl; 912 ChunkSet::iterator current_done_chunk=done_chunks.begin(); // Used to skip past points that are already done 920 err << "The postprocessor has become desynchronised with its assigned reader object! The postprocessor index is "<<loopi<<" but the reader index is "<<getReader().get_current_index()<<"! This indicates a bug in either the postprocessor or the reader, please report it"; 927 std::cout << "Rank "<<rank<<" has reached the end of its batch, stopping iteration." << std::endl; 934 //if(current_done_chunk!=done_chunks.end()) std::cout << "Rank "<<rank<<": loopi="<<loopi<<", current_done_chunk=["<<current_done_chunk->start<<","<<current_done_chunk->end<<"]"<<std::endl; 942 if(loopi<mychunk.start or (current_done_chunk!=done_chunks.end() and current_done_chunk->iContain(loopi))) 951 std::cout << "Rank "<<rank<<" has processed "<<ppi<<" of "<<mychunk.eff_length<<" points ("<<100*ppi/mychunk.eff_length<<"%, with "<<100*n_passed/ppi<<"% passing all cuts)"<<std::endl; 964 //std::cout << "Rank: "<<rank<<", current iteration: "<<loopi<<", current point:" << MPIrank << ", " << pointID << std::endl; 974 // Check if valid model parameters were extracted. If not, something may be wrong with the input file, or we could just be at the end of a buffer (e.g. in HDF5 case). Can't tell the difference, so just skip the point and continue. 990 bool cuts_passed = true; // Will be set to false if any cut is failed, or a required entry is invalid 1048 // We feed the unit hypercube and/or transformed parameter map into the likelihood container. ScannerBit 1049 // interprets the map values as post-transformation and not apply a prior to those, and ensures that the 1050 // length of the cube plus number of transformed parameters adds up to the total number of parameter. 1051 double new_logL = getLogLike()(outputMap); // Here we supply *only* the map; no parameters to transform. 1067 err << "In the input YAML file, you requested to 'add_to_like' the component '"<<old_logl<<"' from your input data file, however this does not match any of the data labels retrieved from the input data file you specified. Please check the spelling, path, etc. and try again."; 1073 err << "In the input YAML file, you requested 'add_to_like' component '"<<old_logl<<"' from your input data file, however this data cannot be retrieved as type 'double', therefore it cannot be used as a likelihood component. Please enter a different data label and try again."; 1084 // Else old likelihood value didn't exist for this point; cannot combine with non-existent likelihood, so don't print the reweighted value. 1095 err << "In the input YAML file, you requested to 'subtract_from_like' the component '"<<old_logl<<"' from your input data file, however this does not match any of the data labels retrieved from the input data file you specified. Please check the spelling, path, etc. and try again."; 1101 err << "In the input YAML file, you requested 'subtract_from_like' component '"<<old_logl<<"' from your input data file, however this data cannot be retrieved as type 'double', therefore it cannot be used as a likelihood component. Please enter a different data label and try again."; 1112 // Else old likelihood value didn't exist for this point; cannot combine with non-existent likelihood, so don't print the reweighted value. 1148 // Use the OutputName set by the reader to preserve the original naming of the modelparameters. 1161 for(std::set<std::string>::iterator it = data_labels_copy.begin(); it!=data_labels_copy.end(); ++it) 1170 //std::cout << "Copying data from "<<in_label<<", to output name "<<out_label<<", for point ("<<MPIrank<<", "<<pointID<<")" <<std::endl; 1176 //std::cout << "Copying data from "<<in_label<<" for point ("<<MPIrank<<", "<<pointID<<")" <<std::endl; 1190 //if(not redistribution_requested) std::cout << "Rank "<<rank<<": Still looping, no redistribution request seen." << std::endl; 1197 //std::cout << "Postprocessor (rank "<<rank<<") received quit signal! Aborting run." << std::endl; 1202 //std::cout << "Postprocessor (rank "<<rank<<") received redistribution request!" << std::endl; 1218 //std::cout << "Postprocessor (rank "<<rank<<") ...but we have less than 10 points left so we will finish them first." << std::endl; 1231 std::cout << "Postprocessor (rank "<<rank<<") reached the end of the input file! (debug: was this the end of our batch? (loopi="<<loopi<<", mychunk.end="<<mychunk.end<<", dset_length = "<<getReader().get_dataset_length()<<")"<<std::endl; 1249 else if(redistribution_requested) // and if we obeyed it; if we ignored it then some other exit code is returned 1273 //std::cout << "ModelParameters marked 'invalid' for model "<<model<<"; point will be skipped." << std::endl; 1288 // Could actually do this in the constructor for the scanner plugin, would be better, but a little more complicated. TODO: do this later. 1298 err << "Error! Reader could not retrieve the required paramater '"<<par<<"' for the model '"<<model<<"' from the supplied data file! Please check that this parameter indeed exists in that file." << std::endl; std::set< std::string > new_params Names of new output to be printed, i.e. output labels not present in the input file. Definition: postprocessor.hpp:118 void print(T const &in, const std::string &label, const int vertexID, const uint rank, const ulong pointID) Definition: basebaseprinter.hpp:139 std::size_t update_interval Number of iterations between progress reports. '0' means no updates. Definition: postprocessor.hpp:155 std::vector< std::string > subtract_from_logl List of likelihoods in old output to be subtracted from the newly computed likelihood. Definition: postprocessor.hpp:139 std::string reweighted_loglike_name The label to assign to the results of add_to_like and subtract_from_like operations. Definition: postprocessor.hpp:164 Printers::BaseBasePrinter * printer The printer for the primary output stream of the scan. Definition: postprocessor.hpp:112 Printers::BaseBaseReader & getReader() Safe accessors for pointer data. Definition: postprocessor_object.cpp:550 unsigned long long int pointID Definition: new_mpi_datatypes.hpp:92 ChunkSet done_chunks Chunks describing the points that can be auto-skipped (because they have been processed previously) ... Definition: postprocessor.hpp:148 unsigned int rank MPI variables (set manually rather than inferred, to allow for "virtual rank" settings. Definition: postprocessor.hpp:171 void record_done_points(const ChunkSet &done_chunks, const Chunk &mydone, const std::string &filebase, unsigned int rank, unsigned int size) Write resume data files These specify which chunks of points have been processed during this run... Definition: postprocessor_object.cpp:371 ChunkSet get_done_points(const std::string &filebase) Read through resume data files and reconstruct which chunks of points have already been processed... Definition: postprocessor_object.cpp:254 std::map< std::string, double > cut_greater_than Definition: postprocessor.hpp:149 void check_settings() Check postprocessor settings for consistency and general validity. Definition: postprocessor_object.cpp:616 Printers::BaseBasePrinter & getPrinter() Definition: postprocessor_object.cpp:561 std::map< std::string, std::string > renaming_scheme Map for renaming old datasets in the new output Keys are "in_label", values are "out_label". Definition: postprocessor.hpp:143 std::string logl_purpose_name Label assigned to the output of the likelihood container. Definition: postprocessor.hpp:161 Chunk get_my_chunk(const std::size_t dset_length, const ChunkSet &done_chunks, const int rank, const int numtasks) Compute start/end indices for a given rank process, given previous "done_chunk" data. Definition: postprocessor_object.cpp:75 virtual void reset()=0 bool discard_old_logl Allow old likelihood components to be overwritten by newly calculated values? Definition: postprocessor.hpp:158 static const int REDIST_REQ Definition: postprocessor.hpp:100 void send_redistribution_request() Definition: postprocessor_object.cpp:594 EXPORT_SYMBOLS bool & auto_increment() Global flag to indicate if auto-incrementing of the PointID by the likelihood container is allowed... Definition: printer_id_tools.cpp:20 virtual ulong get_dataset_length()=0 Definitions of new MPI datatypes needed by printers. "Postprocessing" scanner plugin. std::map< std::string, std::vector< std::string > > req_models Models required by the scan. Definition: postprocessor.hpp:121 virtual PPIDpair get_next_point()=0 Definition: log_tags.hpp:38 int run_main_loop(const ChunkSet &done_chunks) The main run loop. Definition: postprocessor_object.cpp:880 unsigned int numtasks MPI variables (set manually rather than inferred, to allow for "virtual rank" settings. Definition: postprocessor.hpp:170 General small utility functions. EXPORT_SYMBOLS bool startsWith(const std::string &str, const std::string &prefix, bool case_sensitive=true) Checks whether `str' begins with `prefix'. Definition: util_functions.cpp:410 Chunk get_effective_chunk(const std::size_t total_length, const unsigned int rank, const unsigned int numtasks) Get 'effective' start and end positions for a processing batch i.e. Definition: postprocessor_object.cpp:52 bool get_ModelParameters(std::unordered_map< std::string, double > &outputMap) Definition: postprocessor_object.cpp:1261 std::set< std::string > all_params Names of all output that the primary printer knows about at startup (things GAMBIT plans to print fro... Definition: postprocessor.hpp:127 EXPORT_SYMBOLS bool file_exists(const std::string &filename) Check if a file exists. Definition: util_functions.cpp:241 bool early_shutdown_in_progress() const Definition: plugin_loader.hpp:193 ChunkSet merge_chunks(const ChunkSet &) Simplify a ChunkSet by merging chunks which overlap. Definition: postprocessor_object.cpp:316 Printers::BaseBaseReader * reader The reader object in use for the scan. Definition: postprocessor.hpp:109 virtual ulong get_current_index()=0 bool retrieve(T &out, const std::string &label, const uint rank, const ulong pointID) Printer-retrieve dispatch function. Definition: basebaseprinter.hpp:307 std::set< std::string > data_labels_copy Labels of output datasets to be copied. Definition: postprocessor.hpp:133 bool point_done(const ChunkSet done_chunks, size_t index) Helper functions for performing resume related tasks. Definition: postprocessor_object.cpp:34 bool check_for_redistribution_request() Definition: postprocessor_object.cpp:585 std::vector< std::string > add_to_logl List of likelihoods in old output to be added to the newly computed likelihood. Definition: postprocessor.hpp:136 std::string getOutputName() const Definition: model_parameters.cpp:192 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... Definition: util_functions.cpp:93 Options object for PPDriver See matching options in PPDriver class for description. Definition: postprocessor.hpp:62 std::map< std::string, std::map< std::string, std::string > > longname Map to retrieve the "model::parameter" version of the parameter name. Definition: postprocessor.hpp:124 void clear_redistribution_requests() Definition: postprocessor_object.cpp:603 Definition: model_parameters.hpp:53 Class for holding model parameters. bool discard_points_outside_cuts Flag to throw away points that don't pass the cuts (rather than copying them un-processed) ... Definition: postprocessor.hpp:152 std::map< std::string, double > cut_less_than Cut maps, for selecting only points in the input datasets which pass certain criteria. Definition: postprocessor.hpp:148 EXPORT_SYMBOLS const PPIDpair nullpoint Define 'nullpoint' const. Definition: new_mpi_datatypes.cpp:185 EXPORT_SYMBOLS pluginInfo plugin_info Access Functor for plugin info. Definition: plugin_loader.cpp:706 bool retrieve_and_print(const std::string &label, BaseBasePrinter &printer, const uint rank, const ulong pointID) Retrieve and directly print data to new output. Definition: basebaseprinter.hpp:331 pointID / process number pair Used to identify a single parameter space point Definition: new_mpi_datatypes.hpp:90 std::vector< std::string > getKeys() const Get parameter keys (names), probably for external iteration. Definition: model_parameters.cpp:144 virtual std::size_t get_type(const std::string &label)=0 Get type information for a data entry, i.e. Scanner::like_ptr getLogLike() Definition: postprocessor_object.cpp:572 |