00001 #include "Config.hh"
00002 #include "artdaq/DAQrate/infoFilename.hh"
00003 #include "artdaq-core/Data/Fragment.hh"
00004 #include "fhiclcpp/ParameterSet.h"
00005 #include "fhiclcpp/make_ParameterSet.h"
00006
00007 #include <cstring>
00008 #include <iostream>
00009 #include <fstream>
00010 #include <string>
00011 #include <cstdlib>
00012
00013 #include <sys/types.h>
00014 #include <regex.h>
00015
00016 #include <boost/program_options.hpp>
00017 namespace bpo = boost::program_options;
00018
00019 const char* artdaq::Config::usage = "DetectorsPerNode SinksPerNode Run";
00020
00021
00022
00023
00024
00025
00026 artdaq::Config::Config(int rank, int total_procs, int buffer_count, size_t max_payload_size, int argc, char* argv[]):
00027 rank_(rank)
00028 , total_procs_(total_procs)
00029 , detectors_(getArgDetectors(argc, argv))
00030 , sources_(detectors_)
00031 , sinks_(getArgSinks(argc, argv))
00032 , detector_start_(0)
00033 , source_start_(detectors_)
00034 , sink_start_(detectors_ + sources_)
00035 , event_queue_size_(getArgQueueSize(argc, argv))
00036 , run_(getArgRun(argc, argv))
00037 , buffer_count_(buffer_count)
00038 , max_payload_size_(max_payload_size)
00039 , type_((rank_ < detectors_) ? TaskDetector : ((rank_ < (detectors_ + sources_)) ? TaskSource : TaskSink))
00040 , offset_(rank_ - ((type_ == TaskDetector) ? detector_start_ : (type_ == TaskSource) ? source_start_ : sink_start_))
00041 , node_name_(getProcessorName())
00042 , art_argc_(getArtArgc(argc, argv))
00043 , art_argv_(getArtArgv(argc - art_argc_, argv))
00044 , use_artapp_(getenv("ARTDAQ_DAQRATE_USE_ART") != 0)
00045 {
00046 int total_workers = (detectors_ + sinks_ + sources_);
00047 if (total_procs_ != total_workers)
00048 {
00049 std::cerr << "total_procs " << total_procs_ << " != "
00050 << "total_workers " << total_workers << "\n";
00051 throw "total_procs != total_workers";
00052 }
00053 }
00054
00055 void artdaq::Config::writeInfo() const
00056 {
00057 std::string fname = artdaq::infoFilename("config_", rank_, run_);
00058 std::ofstream ostr(fname.c_str());
00059 printHeader(ostr);
00060 ostr << *this << "\n";
00061 }
00062
00063 int artdaq::Config::destCount() const
00064 {
00065 if (type_ == TaskSink) { throw "No destCount for a sink"; }
00066 return type_ == TaskDetector ? sources_ : sinks_;
00067 }
00068
00069 int artdaq::Config::destStart() const
00070 {
00071 if (type_ == TaskSink) { throw "No destStart for a sink"; }
00072 return type_ == TaskDetector ? source_start_ : sink_start_;
00073 }
00074
00075 int artdaq::Config::srcCount() const
00076 {
00077 if (type_ == TaskDetector) { throw "No srcCount for a detector"; }
00078 return type_ == TaskSink ? sources_ : detectors_;
00079 }
00080
00081 int artdaq::Config::srcStart() const
00082 {
00083 if (type_ == TaskDetector) { throw "No srcStart for a detector"; }
00084 return type_ == TaskSink ? source_start_ : detector_start_;
00085 }
00086
00087 std::string artdaq::Config::typeName() const
00088 {
00089 static const char* names[] = {"Sink", "Source", "Detector"};
00090 return names[type_];
00091 }
00092
00093 int artdaq::Config::getDestFriend() const
00094 {
00095 return offset_ + destStart();
00096 }
00097
00098 int artdaq::Config::getSrcFriend() const
00099 {
00100 return offset_ + srcStart();
00101 }
00102
00103 int artdaq::Config::getArtArgc(int argc, char* argv[]) const
00104 {
00105
00106 int pos = 0;
00107 for (; pos < argc; ++pos)
00108 {
00109 if (strcmp(argv[pos], "--") == 0) { break; }
00110 }
00111 return argc - pos;
00112 }
00113
00114 char** artdaq::Config::getArtArgv(int pos, char** argv) const
00115 {
00116 return argv + pos;
00117 }
00118
00119 void artdaq::Config::printHeader(std::ostream& ost) const
00120 {
00121 ost << "Rank TotalNodes "
00122 << "DetectorsPerNode SourcesPerNode SinksPerNode "
00123 << "BuilderNodes DetectorNodes Sources Sinks Detectors "
00124 << "DetectorStart SourceStart SinkStart "
00125 << "EventQueueSize "
00126 << "Run "
00127 << "Type Offset "
00128 << "Nodename "
00129 << "StartTime\n";
00130 }
00131
00132 void artdaq::Config::print(std::ostream& ost) const
00133 {
00134 ost << rank_ << " "
00135 << sources_ << " "
00136 << sinks_ << " "
00137 << detectors_ << " "
00138 << detector_start_ << " "
00139 << source_start_ << " "
00140 << sink_start_ << " "
00141 << event_queue_size_ << " "
00142 << run_ << " "
00143 << typeName() << " "
00144 << offset_ << " "
00145 << node_name_;
00146 }
00147
00148 fhicl::ParameterSet artdaq::Config::makeParameterSet() const
00149 {
00150 std::stringstream ss;
00151 if (type_ != TaskDetector)
00152 {
00153 ss << "sources: {";
00154 int count = type_ == TaskSource ? detectors_ : sources_;
00155 int start = type_ == TaskSource ? detector_start_ : source_start_;
00156 for (int ii = 0; ii < count; ++ii)
00157 {
00158 ss << "s" << ii + start << ": { transferPluginType: MPI source_rank: " << ii + start << " max_fragment_size_words: " << max_payload_size_ << " buffer_count: " << buffer_count_ << "}";
00159 }
00160
00161 ss << "}";
00162 }
00163 if (type_ != TaskSink)
00164 {
00165 ss << " destinations: {";
00166 int count = type_ == TaskDetector ? sources_ : sinks_;
00167 int start = type_ == TaskDetector ? source_start_ : sink_start_;
00168 for (int ii = 0; ii < count; ++ii)
00169 {
00170 ss << "d" << ii + start << ": { transferPluginType: MPI destination_rank: " << ii + start << " max_fragment_size_words: " << max_payload_size_ << " buffer_count: " << buffer_count_ << "}";
00171 }
00172
00173 ss << "}";
00174 }
00175
00176 fhicl::ParameterSet ps;
00177 fhicl::make_ParameterSet(ss.str(), ps);
00178 return ps;
00179 }
00180
00181 fhicl::ParameterSet artdaq::Config::getArtPset()
00182 {
00183 std::ostringstream descstr;
00184 descstr << "-- <-c <config-file>>";
00185 bpo::options_description desc(descstr.str());
00186 desc.add_options()
00187 ("config,c", bpo::value<std::string>(), "Configuration file.");
00188 bpo::variables_map vm;
00189 try
00190 {
00191 bpo::store(bpo::command_line_parser(art_argc_, art_argv_).
00192 options(desc).allow_unregistered().run(), vm);
00193 bpo::notify(vm);
00194 }
00195 catch (bpo::error const& e)
00196 {
00197 std::cerr << "Exception from command line processing in Config::getArtPset: " << e.what() << "\n";
00198 throw "cmdline parsing error.";
00199 }
00200 if (!vm.count("config"))
00201 {
00202 std::cerr << "Expected \"-- -c <config-file>\" fhicl file specification.\n";
00203 throw "cmdline parsing error.";
00204 }
00205 fhicl::ParameterSet pset;
00206 cet::filepath_lookup lookup_policy("FHICL_FILE_PATH");
00207 fhicl::make_ParameterSet(vm["config"].as<std::string>(), lookup_policy, pset);
00208 auto ps = pset.get<fhicl::ParameterSet>("daq");
00209 buffer_count_ = ps.get<int>("buffer_count", buffer_count_);
00210 max_payload_size_ = ps.get<size_t>("max_fragment_size_words", max_payload_size_);
00211
00212 return ps;
00213 }