diff --git a/scripts/runFileTest.sh b/scripts/runFileTest.sh index d6a4b149bb97a6b3033095f071120daf94d46532..e69338450a882a795daf2c262c77280c69543cf2 100755 --- a/scripts/runFileTest.sh +++ b/scripts/runFileTest.sh @@ -8,6 +8,10 @@ function scdaq_test { echo "Starting scdaq test with CALO P5 capture file: check for crash" timeout 10s src/scdaq --config test/config/scdaq-calo.conf | uniq -uc CALORET="${PIPESTATUS[0]}" + echo "#############################################################################" + echo "Starting scdaq test with 2 passthrough P5 capture files: check for crash" + timeout 10s src/scdaq --config test/config/scdaq-passthrough.conf --nstreams 2 | uniq + MULTI_PIPELINE_RET="${PIPESTATUS[0]}" if [[ "$GMTRET" -ne 124 ]]; then # We expect to fail with a timeout because scdaq isn't supposed to return. echo "SCDAQ test for GMT failed with exit code ${GMTRET}!" GMT_FAILED=true @@ -22,6 +26,13 @@ function scdaq_test { echo "SCDAQ test for CALO failed, no output files found!" CALO_FAILED=true fi + if [[ "$MULTI_PIPELINE_RET" -ne 124 ]]; then + echo "SCDAQ test for MULTIPLE PIPELINES failed with exit code ${MULTI_PIPELINE_RET}!" + MULTI_PIPELINE_FAILED=true + elif [[ $(find test/data -name "*scout_PASS1_CALO*" | wc -l) -eq 0 || $(find test/data -name "*scout_PASS2_GMT*" | wc -l) -eq 0 ]]; then + echo "SCDAQ test for MULTIPLE PIPELINES failed, no output files found!" + MULTI_PIPELINE_FAILED=true + fi } echo "building scdaq locally" @@ -34,26 +45,29 @@ tar -xzvf gmt_testfile.tar.gz cd ../../ OUTPUT_EXPECTED=false scdaq_test -echo "Starting second set of test files" echo $GMT_FAILED echo $CALO_FAILED +echo $MULTI_PIPELINE_FAILED +echo "Starting second set of test files" OUTPUT_EXPECTED=true cd test/data rm calo_testfile.dat rm gmt_testfile.dat tar -xzvf calo_testfile_mod.tar.gz tar -xzvf gmt_testfile_mod.tar.gz -rm ../test/data/run000000/in_progress/* +rm -rf run000000/in_progress/* cd ../../ -#next line needed because older GMT files were taken with 5 orbits per packet +#next line needed because older GMT files were taken with 5 orbits per packet sed -i 's/nOrbitsPerPacket:1/nOrbitsPerPacket:5/' test/config/scdaq-gmt.conf scdaq_test echo $GMT_FAILED echo $CALO_FAILED +echo $MULTI_PIPELINE_FAILED + -if [[ $GMT_FAILED = true || $CALO_FAILED = true ]]; then +if [[ $GMT_FAILED = true || $CALO_FAILED = true || $MULTI_PIPELINE_FAILED = true ]]; then exit 1 fi diff --git a/scripts/scdaqrpm.sh b/scripts/scdaqrpm.sh index 65cc978347d39f7d726edb2ea12dde0930a1d9a1..1021a9376e35abee1f377d99c7e6a5cd29251d12 100755 --- a/scripts/scdaqrpm.sh +++ b/scripts/scdaqrpm.sh @@ -133,7 +133,7 @@ cp -R $BASEDIR/src SOURCES/ echo $RPM_SOURCE_DIR cd SOURCES pwd -make +make all %install echo $RPM_SOURCE_DIR diff --git a/src/InputFilter.cc b/src/InputFilter.cc index e7838ed947ef4a838009bfd212fe3eb2ac0b454c..a1788ac4fe205e700361b42a64e3d6ca97175567 100644 --- a/src/InputFilter.cc +++ b/src/InputFilter.cc @@ -8,6 +8,7 @@ #include "log.h" #include "slice.h" +std::atomic<int> filterCounter{0}; InputFilter::InputFilter(size_t packetBufferSize, size_t nbPacketBuffers, ctrl &control) : filter(serial_in_order), control_(control), @@ -20,7 +21,9 @@ InputFilter::InputFilter(size_t packetBufferSize, size_t nbPacketBuffers, ctrl & maxBytesRead_ = 0; previousNbReads_ = 0; - LOG(TRACE) << "Configuration translated into:"; + filterId = filterCounter++; + + LOG(TRACE) << "[" << std::to_string(filterId) << "] Configuration translated into:"; LOG(TRACE) << " MAX_BYTES_PER_INPUT_SLICE: " << packetBufferSize; LOG(TRACE) << " TOTAL_SLICES: " << nbPacketBuffers; LOG(TRACE) << "Created input filter and allocated at " << static_cast<void *>(nextSlice_); @@ -56,7 +59,8 @@ void InputFilter::printStats(std::ostream &out, ssize_t lastBytesRead) { std::ios state(nullptr); state.copyfmt(out); - out << "#" << nbReads_ << ": Reading " << std::fixed << std::setprecision(1) << bwd << " MB/sec, " + out << "[" << std::to_string(filterId) << "] " + << "#" << nbReads_ << ": Reading " << std::fixed << std::setprecision(1) << bwd << " MB/sec, " << nbReadsDiff << " packet(s) min/avg/max " << minBytesRead_ << '/' << avgBytesRead << '/' << maxBytesRead_ << " last " << lastBytesRead; diff --git a/src/InputFilter.h b/src/InputFilter.h index 9b4b9a4b171aff324ed6d418fa96a5ad64ce37cb..4a99895209df1fbb8fb6ede5591ccbe53cff371a 100644 --- a/src/InputFilter.h +++ b/src/InputFilter.h @@ -1,6 +1,7 @@ #ifndef INPUT_FILTER_H #define INPUT_FILTER_H +#include <atomic> #include <cstddef> #include <iostream> @@ -19,6 +20,7 @@ class InputFilter : public tbb::filter { InputFilter(size_t packet_buffer_size, size_t number_of_packet_buffers, ctrl &control); virtual ~InputFilter(); + int filterId = 0; // Return the number of read calls uint64_t nbReads() { return nbReads_; } diff --git a/src/Makefile b/src/Makefile index 849f8ad714741a62a872c532eb000b8eddfbf8e1..57ed2aae389c3e05334db62c3c53cb0b1c380ad1 100644 --- a/src/Makefile +++ b/src/Makefile @@ -12,25 +12,33 @@ TARGET = scdaq # source files -SOURCES = config.cc DmaInputFilter.cc FileDmaInputFilter.cc InputFilter.cc MicronDmaInputFilter.cc OutputByOrbit.cc OutputBySize.cc OutputFileHandler.cc processor.cc scdaq.cc session.cc slice.cc TcpInputFilter.cc tools.cc WZDmaInputFilter.cc +SOURCES = pipeline.cc config.cc DmaInputFilter.cc FileDmaInputFilter.cc InputFilter.cc MicronDmaInputFilter.cc OutputByOrbit.cc OutputBySize.cc OutputFileHandler.cc processor.cc scdaq.cc session.cc slice.cc TcpInputFilter.cc tools.cc WZDmaInputFilter.cc C_SOURCES = wz_dma.c # work out names of object files from sources OBJECTS = $(SOURCES:.cc=.o) OBJECTS += $(C_SOURCES:.c=.o) +TEST_PROGRESS_DIR = test/in_progress + # compiler flags (do not include -c here as it's dealt with by the # appropriate rules; CXXFLAGS gets passed as part of command # invocation for both compilation (where -c is needed) and linking # (where it's not.) -CXXFLAGS = -std=c++11 -Wall -Wextra -Og -g -rdynamic -Wconversion +CXXFLAGS = -std=c++11 -Wall -Wextra -Og -g -rdynamic -Wconversion CFLAGS = $(CXXFLAGS) LDFLAGS = -Llibmicron -ltbb -ltbbmalloc -lboost_thread -lboost_chrono -lcurl -lpthread -lcrypto CPPFLAGS = -I. -Iwzdma + # default target (to build all) -all: ${TARGET} +all: clean_progress ${TARGET} + +clean_progress: + rm -rf ${TEST_PROGRESS_DIR} + +TGT_CLEAN_PROG = cleanprogress # clean target clean: @@ -49,7 +57,7 @@ ${TARGET}: ${OBJECTS} # header dependencies (in more complicated cases, you can # look into generating these automatically.) -scdaq.o: processor.h OutputBySize.h OutputByOrbit.h format.h server.h controls.h config.h session.h log.h +scdaq.o: processor.h OutputBySize.h OutputByOrbit.h format.h server.h controls.h config.h session.h log.h pipeline.h config.o: config.h log.h DmaInputFilter.o: DmaInputFilter.h slice.h FileDmaInputFilter.o: FileDmaInputFilter.h InputFilter.h log.h @@ -65,3 +73,4 @@ TcpInputFilter.o: TcpInputFilter.h InputFilter.h tools.h log.h wz_dma.o: wz_dma.h MicronDmaInputFilter.o: MicronDmaInputFilter.h tools.o: tools.h log.h +pipeline.o: pipeline.h diff --git a/src/config.cc b/src/config.cc index 7e28b37ab19efc32e8fe780354eb83d96e52b131..41d547e6bf6a6d23d6e0ac82ac82dced627146a4 100644 --- a/src/config.cc +++ b/src/config.cc @@ -8,6 +8,11 @@ config::config(std::string filename) { bool valid = true; std::ifstream in(filename.c_str(), std::ios_base::in); + + if (!in.is_open()) { + throw std::invalid_argument("Configuration file could not be opened. Does it exist?"); + } + std::string line; while (!std::getline(in, line).eof()) { // Perform left trim diff --git a/src/pipeline.cc b/src/pipeline.cc new file mode 100644 index 0000000000000000000000000000000000000000..5a9d79c4bae439174b29de44429d767c226a288a --- /dev/null +++ b/src/pipeline.cc @@ -0,0 +1,151 @@ +#include "pipeline.h" + +Pipeline::Pipeline(config &conf, uint maxTokensPerThread) + : fMaxTokensPerThread(maxTokensPerThread), + fConf(conf), + fStreamProcessor(conf.getDmaPacketBufferSize(), conf.getDoZS(), conf.getProcessorType(), + conf.getNOrbitsPerPacket(), conf.getCMSSWHeaders(), + static_cast<uint16_t>(conf.getSourceID()), control) { + tools::log::set_filter_min_severity(fConf.getLogMinSeverity()); + fConf.print(); + const config::InputType &input = fConf.getInput(); + const size_t &nbPacketBuffers = fConf.getNumberOfDmaPacketBuffers(); + const size_t &packetBufferSize = fConf.getDmaPacketBufferSize(); + + if (input == config::InputType::FILEDMA) { + // Create FILE DMA reader + fInputFilter = std::make_shared<FileDmaInputFilter>(fConf.getInputFile(), packetBufferSize, + nbPacketBuffers, control); + + } else if (input == config::InputType::WZDMA) { + // Create WZ DMA reader + fInputFilter = + std::make_shared<WZDmaInputFilter>(packetBufferSize, nbPacketBuffers, control, fConf); + + } else if (input == config::InputType::MICRONDMA) { + // create MicronDmaInputFilter reader + fInputFilter = + std::make_shared<MicronDmaInputFilter>(packetBufferSize, nbPacketBuffers, control, fConf); + + } else if (input == config::InputType::TCPIP) { + // create TcpInputFilter reader + if (fConf.getDev_TCPAutoReconnectOnFailure()) { + fInputFilter = std::make_shared<TcpInputFilter>(fConf.getTcpDestPort(), packetBufferSize, + nbPacketBuffers, fConf.getNOrbitsPerPacket(), + control, fConf); + + } else { + throw std::invalid_argument( + "Configuration error: enable developmentMode to use TCP input filter"); + } + } else { + throw std::invalid_argument("Configuration error: Unknown input type was specified"); + } + + // Add input reader to a pipeline + fPipeline.add_filter(*fInputFilter); + + // Create reformatter and add it to the pipeline + if (fConf.getEnableStreamProcessor()) { + fPipeline.add_filter(fStreamProcessor); + } + + // Create file-writing stage and add it to the pipeline + if (fConf.getNOrbitsPerFile()) { + fOutputStream = std::make_shared<OutputByOrbitStream>(control, fConf); + } else { + fOutputStream = std::make_shared<OutputBySizeStream>( + fConf.getOutputFilenameBase(), fConf.getOutputFilenamePrefix(), Pipeline::control, + fConf.getProcessorType()); + } + fPipeline.add_filter(*fOutputStream); + + // tbb::tick_count mainStartTime = tbb::tick_count::now(); + control.running = false; + control.run_number = 0; + control.max_file_size = fConf.getOutputMaxFileSize(); // in Bytes + control.packets_per_report = static_cast<int>(fConf.getPacketsPerReport()); + control.output_force_write = fConf.getOutputForceWrite(); + control.n_orbits_per_packet = static_cast<int>(fConf.getNOrbitsPerPacket()); + + // Firmware needs at least 1MB buffer for DMA + if (fConf.getDmaPacketBufferSize() < 1024 * 1024) { + LOG(ERROR) << "dma_packet_buffer_size must be at least 1048576 bytes (1MB), but " + << fConf.getDmaPacketBufferSize() + << " bytes was given. Check the configuration file."; + throw std::invalid_argument("Configuration error: DMA packet buffer size too small. "); + } +} + +MultiPipeline::MultiPipeline(std::vector<config> &configs) { + for (auto &config : configs) { + try { + fPipelines.emplace_back(config); + LOG(DEBUG) << "-Configuration loaded"; + LOG(DEBUG) << "-Pipeline set up"; + } catch (std::invalid_argument &e) { + LOG(FATAL) << "-Configuration invalid! Error text is \"" << e.what() << "\" Bailing out."; + throw; + } catch (std::exception &e) { + LOG(ERROR) << "-Error occurred. error text is: \"" << e.what() << "\""; + throw; + } + } + + { // RAII + fServer = std::unique_ptr<server>( + new server(io_service, fPipelines[0].fConf.getPortNumber(), Pipeline::control)); + fServerThread = boost::thread(boost::bind(&boost::asio::io_service::run, &io_service)); + } +} + +int MultiPipeline::Run() { + int retval = 0; + assert(!fPipelines.empty()); + try { + if (!RunPipelines(static_cast<unsigned int>(fPipelines.size()))) { + retval = 1; // Will terminate with error code set + } + } catch (std::exception &e) { + LOG(ERROR) << "Error in pipelines. Error text is: \"" << e.what() << "\""; + retval = 1; // Will terminate with error code set + config &conf = fPipelines.at(0).fConf; // Use info from first file for SCONE reset + LOG(INFO) << "Resetting board at http://" << conf.getSconeHost() << ":" << conf.getSconePort() + << "/" << conf.getSconeBoard() << " before exiting.. "; + int res = tools::reset_board(conf.getSconeHost(), conf.getSconePort(), conf.getSconeBoard()); + if (res != 0) { + LOG(ERROR) << "Reset failed! Error code: " << res; + } else { + LOG(INFO) << "Successfully reset the board."; + } + } + + LOG(DEBUG) << "Terminating the internal TCP server."; + io_service.stop(); + if (!fServerThread.try_join_for(boost::chrono::milliseconds(2000))) { + LOG(ERROR) << "Failed to terminate the internal TCP server, the program " + "may crash on exit."; + } else { + LOG(DEBUG) << "Internal TCP server is terminated."; + } + + return retval; +} + +int MultiPipeline::RunPipelines(uint numStreams) { + tbb::task_group group; + // Run pipelines and measure real time + tbb::tick_count t0 = tbb::tick_count::now(); + for (uint i = 0; i < numStreams; ++i) { + group.run([p = &this->fPipelines.at(i)] { + return p->fPipeline.run(p->fConf.getNumThreads() * p->fMaxTokensPerThread); + }); + } + group.wait(); + tbb::tick_count t1 = tbb::tick_count::now(); + + if (fVerbose) { + LOG(INFO) << "time = " << (t1 - t0).seconds(); + } + return 1; +} \ No newline at end of file diff --git a/src/pipeline.h b/src/pipeline.h new file mode 100644 index 0000000000000000000000000000000000000000..b3818e9b3247f036e5c900423992d609654bf458 --- /dev/null +++ b/src/pipeline.h @@ -0,0 +1,72 @@ +#ifndef PIPELINE_H +#define PIPELINE_H + +#include <sysexits.h> + +#include <boost/asio.hpp> +#include <boost/bind.hpp> +#include <boost/thread.hpp> +#include <cctype> +#include <cstdio> +#include <cstdlib> +#include <cstring> +#include <iostream> +#include <memory> + +#include "DmaInputFilter.h" +#include "FileDmaInputFilter.h" +#include "InputFilter.h" +#include "MicronDmaInputFilter.h" +#include "OutputByOrbit.h" +#include "OutputBySize.h" +#include "TcpInputFilter.h" +#include "WZDmaInputFilter.h" +#include "config.h" +#include "controls.h" +#include "format.h" +#include "processor.h" +#include "server.h" +#include "tbb/concurrent_queue.h" +#include "tbb/pipeline.h" +#include "tbb/task_group.h" +#include "tbb/task_scheduler_init.h" +#include "tbb/tbb_allocator.h" +#include "tbb/tick_count.h" +#include "tools.h" + +class Pipeline { + friend class MultiPipeline; + using OutputFilter = tbb::filter; + + public: + static ctrl control; + // Impacts the maximum number of in-flight TBB tokens + const uint fMaxTokensPerThread; + config fConf; + + std::shared_ptr<InputFilter> fInputFilter; + StreamProcessor fStreamProcessor; + std::shared_ptr<OutputFilter> fOutputStream; + tbb::pipeline fPipeline; + + explicit Pipeline(config &conf, uint maxTokensPerThread = 4); +}; + +class MultiPipeline { + public: + std::deque<Pipeline> fPipelines; + + tbb::task_scheduler_init fSchedulerInit; + boost::asio::io_service io_service; + boost::thread fServerThread; + std::unique_ptr<server> fServer; + bool fVerbose = true; + + explicit MultiPipeline(std::vector<config> &configs); + int Run(); + + private: + int RunPipelines(uint numStreams); +}; + +#endif \ No newline at end of file diff --git a/src/scdaq.cc b/src/scdaq.cc index 1bb5ee8595ab57c03a7aaae4aa9f3890ef0cfb29..1843b92a01024f20efa8fbeae4f3ded081f95d7a 100644 --- a/src/scdaq.cc +++ b/src/scdaq.cc @@ -1,120 +1,39 @@ -#include <sysexits.h> - -#include <boost/asio.hpp> -#include <boost/bind.hpp> -#include <boost/thread.hpp> -#include <cctype> -#include <cstdio> -#include <cstdlib> #include <cstring> #include <iostream> -#include <string> +#include <memory> -#include "DmaInputFilter.h" -#include "FileDmaInputFilter.h" -#include "InputFilter.h" -#include "MicronDmaInputFilter.h" -#include "OutputByOrbit.h" -#include "OutputBySize.h" -#include "TcpInputFilter.h" -#include "WZDmaInputFilter.h" #include "config.h" -#include "controls.h" -#include "format.h" #include "log.h" -#include "processor.h" -#include "server.h" -#include "tbb/concurrent_queue.h" -#include "tbb/pipeline.h" -#include "tbb/task_scheduler_init.h" -#include "tbb/tbb_allocator.h" -#include "tbb/tick_count.h" -#include "tools.h" - -using namespace std; - -int run_pipeline(int nbThreads, ctrl &control, config &conf) { - config::InputType input = conf.getInput(); - size_t packetBufferSize = conf.getDmaPacketBufferSize(); - size_t nbPacketBuffers = conf.getNumberOfDmaPacketBuffers(); - uint32_t tcpDestPort = conf.getTcpDestPort(); - - // Create empty input reader, will assign later when we know what is the data - // source - std::shared_ptr<InputFilter> input_filter; - std::shared_ptr<OutputByOrbitStream> output_stream_by_orbit; - std::shared_ptr<OutputBySizeStream> output_stream_by_size; - // Create the pipeline - tbb::pipeline pipeline; +#include "pipeline.h" - if (input == config::InputType::FILEDMA) { - // Create FILE DMA reader - input_filter = std::make_shared<FileDmaInputFilter>(conf.getInputFile(), packetBufferSize, - nbPacketBuffers, control); +#define MAX_PIPELINES 15 - } else if (input == config::InputType::WZDMA) { - // Create WZ DMA reader - input_filter = - std::make_shared<WZDmaInputFilter>(packetBufferSize, nbPacketBuffers, control, conf); - - } else if (input == config::InputType::MICRONDMA) { - // create MicronDmaInputFilter reader - input_filter = - std::make_shared<MicronDmaInputFilter>(packetBufferSize, nbPacketBuffers, control, conf); - - } else if (input == config::InputType::TCPIP) { - // create TcpInputFilter reader - if (conf.getDev_TCPAutoReconnectOnFailure()) { - input_filter = - std::make_shared<TcpInputFilter>(tcpDestPort, packetBufferSize, nbPacketBuffers, - conf.getNOrbitsPerPacket(), control, conf); +void LoadConfigs(std::string &basename, uint numStreams, std::vector<config> &out_configs) { + if (!numStreams) { + // No number of streams specified, assumes unique config file with provided basename + out_configs.emplace_back(basename); + } else { + // Assumes basename followed by a natural integer between 1..N streams + std::string::size_type dot_position = basename.find_last_of('.'); + std::string base, postfix{}; + if (dot_position == std::string::npos) { + base = basename; } else { - throw std::invalid_argument( - "Configuration error: enable developmentMode to use TCP input filter"); + base = basename.substr(0, dot_position); + postfix = "." + basename.substr(dot_position + 1, std::string::npos); } - } else { - throw std::invalid_argument("Configuration error: Unknown input type was specified"); - } - - // Add input reader to a pipeline - pipeline.add_filter(*input_filter); - - // Create reformatter and add it to the pipeline - // TODO: Created here so we are not subject of scoping, fix later... - StreamProcessor stream_processor(packetBufferSize, conf.getDoZS(), conf.getProcessorType(), - conf.getNOrbitsPerPacket(), conf.getCMSSWHeaders(), - conf.getSourceID(), control); - if (conf.getEnableStreamProcessor()) { - pipeline.add_filter(stream_processor); - } - - // Create file-writing stage and add it to the pipeline - if (conf.getNOrbitsPerFile()) { - output_stream_by_orbit = std::make_shared<OutputByOrbitStream>(control, conf); - pipeline.add_filter(*output_stream_by_orbit); - } else { - output_stream_by_size = std::make_shared<OutputBySizeStream>(conf.getOutputFilenameBase(), - conf.getOutputFilenamePrefix(), - control, conf.getProcessorType()); - pipeline.add_filter(*output_stream_by_size); + for (uint i = 0; i < numStreams; ++i) { + out_configs.emplace_back(base + std::to_string(i + 1) + postfix); + } } - - // Run the pipeline - tbb::tick_count t0 = tbb::tick_count::now(); - // Need more than one token in flight per thread to keep all threads - // busy; 2-4 works - pipeline.run(nbThreads * 4); - tbb::tick_count t1 = tbb::tick_count::now(); - LOG(INFO) << "time = " << (t1 - t0).seconds(); - - return 1; } +ctrl Pipeline::control; + int main(int argc, char *argv[]) { (void)(argc); (void)(argv); - int retval = 0; if (argc < 2) { LOG(DEBUG) << "no arguments provided to scdaq, try --help"; @@ -122,90 +41,54 @@ int main(int argc, char *argv[]) { } if ((std::string(argv[1]) == "-h") || (std::string(argv[1]) == "--help")) { - LOG(DEBUG) << "HELP: expected arguments --config [configfilename]"; + LOG(DEBUG) << "HELP: expected arguments --config [config basename] --nstreams [number of " + "parallel streams]"; return 1; } - if ((argc != 3)) { - LOG(ERROR) << "error occurred, number of arguments != 2, expected --config " - "[configfilename] , try --help"; + if ((argc < 3)) { + LOG(ERROR) << "error occurred, number of arguments is less than 2, expected --config [config " + "basename] (and optionally --nstreams [number of parallel streams]), try --help"; return 1; } + uint num_streams = 0; + std::string config_basename{}; + if (std::string(argv[1]) == "--config") { - LOG(DEBUG) << "scdaq started with conffile: " << std::string(argv[2]); + LOG(DEBUG) << "scdaq started with config files basename: " << std::string(argv[2]); + config_basename.assign(argv[2]); } else { LOG(ERROR) << "invalid argument, expected --config, see --help"; return 1; } - try { - config conf(argv[2]); - conf.print(); - tools::log::set_filter_min_severity(conf.getLogMinSeverity()); - LOG(DEBUG) << "Configuration loaded"; - ctrl control; - // tbb::tick_count mainStartTime = tbb::tick_count::now(); - - control.running = false; - control.run_number = 0; - control.max_file_size = conf.getOutputMaxFileSize(); // in Bytes - control.packets_per_report = conf.getPacketsPerReport(); - control.output_force_write = conf.getOutputForceWrite(); - control.n_orbits_per_packet = conf.getNOrbitsPerPacket(); - - // Firmware needs at least 1MB buffer for DMA - if (conf.getDmaPacketBufferSize() < 1024 * 1024) { - LOG(ERROR) << "dma_packet_buffer_size must be at least 1048576 bytes (1MB), but " - << conf.getDmaPacketBufferSize() - << " bytes was given. Check the configuration file."; - return 1; - } - - boost::asio::io_service io_service; - server s(io_service, conf.getPortNumber(), control); - boost::thread t(boost::bind(&boost::asio::io_service::run, &io_service)); - - int nbThreads = conf.getNumThreads(); - - retval = 0; - try { - tbb::task_scheduler_init init(nbThreads); - if (!run_pipeline(nbThreads, control, conf)) { - retval = 1; - // Will terminate with errorocde set - } - } catch (std::exception &e) { - LOG(ERROR) << "Error in pipelines. Error text is: \"" << e.what() << "\""; - retval = 1; - // Will terminate with errorcode set - LOG(INFO) << "Resetting board at http://" << conf.getSconeHost() << ":" << conf.getSconePort() - << "/" << conf.getSconeBoard() << " before exiting.. "; - int res = tools::reset_board(conf.getSconeHost(), conf.getSconePort(), conf.getSconeBoard()); - if (res != 0) { - LOG(ERROR) << "Reset failed! Error code: " << res; - } else { - LOG(INFO) << "Successfully reset the board."; - } - } + if (argc >= 5 && std::string(argv[3]) == "--nstreams") { + num_streams = static_cast<uint>(std::stoi(argv[4])); + LOG(DEBUG) << "scdaq started with number of parallel streams / config files: " + << std::string(argv[4]); + // Check if `nstreams` exceeds maximum number of pipelines --> recompile with a larger + // MAX_PIPELINES if necessary. + assert(num_streams <= MAX_PIPELINES); + } else { + LOG(WARNING) << "scdaq is implicitly processing a single stream configured at " + << config_basename; + } - LOG(DEBUG) << "Terminating the internal TCP server."; - io_service.stop(); - if (!t.try_join_for(boost::chrono::milliseconds(2000))) { - LOG(ERROR) << "Failed to terminate the internal TCP server, the program " - "may crash on exit."; - } else { - LOG(DEBUG) << "Internal TCP server is terminated."; - } + // Collect loaded config instances from configuration files + std::vector<config> configs{}; + LoadConfigs(config_basename, num_streams, configs); - // utility::report_elapsed_time((tbb::tick_count::now() - - // mainStartTime).seconds()); - return retval; - } catch (std::invalid_argument &e) { - LOG(FATAL) << "Configuration invalid! Error text is \"" << e.what() << "\" Bailing out."; - return EX_CONFIG; + // Instantiate multiple pipelines (up to the directive-defined limit) with the settings from the + // config instances. + MultiPipeline multi_pipeline(configs); + int ret = 0; + try { + // Launch blocking call to run the pipelines in parallel until all streams are severed + ret = multi_pipeline.Run(); } catch (std::exception &e) { - LOG(ERROR) << "Error occurred. error text is: \"" << e.what() << "\""; + LOG(ERROR) << "Error in pipelines. Error text is: \"" << e.what() << "\""; return 1; } + return ret; } diff --git a/src/wz_dma.c b/src/wz_dma.c index c2f18d5cafad42c6e63336eb999413dad3e1c46e..0b12b89895e43bd1588691ba48ed04eddd1ce94f 100644 --- a/src/wz_dma.c +++ b/src/wz_dma.c @@ -2,189 +2,184 @@ * This file defines the API for the DWZ DMA driver. */ -#include <stdio.h> -#include <stdint.h> -#include <unistd.h> +#include "wz_dma.h" + +#include <errno.h> #include <fcntl.h> +#include <stdint.h> +#include <stdio.h> #include <sys/ioctl.h> #include <sys/mman.h> -#include <errno.h> - -#include "wz_dma.h" +#include <unistd.h> // perror may modify errno, we have to save it -#define PERROR(msg) do { int err = errno; perror(msg); errno = err; } while (0) +#define PERROR(msg) \ + do { \ + int err = errno; \ + perror(msg); \ + errno = err; \ + } while (0) /* * Open necessary devices and map DMAable memory. - * Variable usr_regs_size is the size (in power of 2) of the user memory space that should be allocated for I/O communication with the hardware. - * Set to 0 if not necessary. + * Variable usr_regs_size is the size (in power of 2) of the user memory space that should be + * allocated for I/O communication with the hardware. Set to 0 if not necessary. */ -int wz_init(struct wz_private* wz, size_t usr_regs_size) -{ - int res; - - wz->fd_user = -1; - wz->fd_control = -1; - wz->fd_memory = -1; - wz->fd_memory_is_allocated = 0; - wz->usr_regs_size = usr_regs_size; - wz->usr_regs = NULL; - wz->data_buf = NULL; - - - if ( (wz->fd_user = open("/dev/wz-xdma0_user", O_RDWR)) < 0 ) { - wz->fd_user = -1; - PERROR("Can't open /dev/wz-xdma0_user"); - return -1; - }; - - if ( (wz->fd_control = open("/dev/wz-xdma0_control", O_RDWR)) < 0 ) { - wz->fd_control = -1; - PERROR("Can't open /dev/wz-xdma0_control"); - wz_close(wz); - return -1; - }; - - if ( (wz->fd_memory = open("/dev/wz-xdma0_c2h_0", O_RDWR)) < 0 ) { - wz->fd_memory = -1; - PERROR("Can't open /dev/wz-xdma0_c2h_0"); - wz_close(wz); - return -1; - }; - - //Allocate buffers - if ( (res = ioctl(wz->fd_memory, IOCTL_XDMA_WZ_ALLOC_BUFFERS, 0L)) < 0 ) { - PERROR("Can't mmap DMA buffers"); - wz_close(wz); - return -1; - } - wz->fd_memory_is_allocated = 1; - - //Now mmap the user registers - if (wz->usr_regs_size && ((wz->usr_regs = (volatile uint32_t *) mmap(NULL, wz->usr_regs_size, PROT_READ | PROT_WRITE, MAP_SHARED, wz->fd_user, 0)) == MAP_FAILED)) { - wz->usr_regs = NULL; - PERROR("Can't mmap user registers"); - wz_close(wz); - return -1; - } - - if ( (wz->data_buf = (volatile char *) mmap(NULL, TOT_BUF_LEN, PROT_READ|PROT_WRITE, MAP_SHARED, wz->fd_memory, 0)) == MAP_FAILED) { - wz->data_buf = NULL; - PERROR("Can't mmap data buffer"); - wz_close(wz); - return -1; - } - - // Ensure, that all pages are mapped (allocated) - // Assume page size is 4096. If it is larger, it will not hurt, just take long(er) time - int pagesize = 4096; - int64_t i; - for (i = 0; i < TOT_BUF_LEN; i += pagesize) { - // Touch memory so it is really allocated - ((volatile char*) wz->data_buf)[i] = ((volatile char*) wz->data_buf)[i]; - } - - return 0; +int wz_init(struct wz_private* wz, size_t usr_regs_size) { + int res; + + wz->fd_user = -1; + wz->fd_control = -1; + wz->fd_memory = -1; + wz->fd_memory_is_allocated = 0; + wz->usr_regs_size = usr_regs_size; + wz->usr_regs = NULL; + wz->data_buf = NULL; + + if ((wz->fd_user = open("/dev/wz-xdma0_user", O_RDWR)) < 0) { + wz->fd_user = -1; + PERROR("Can't open /dev/wz-xdma0_user"); + return -1; + }; + + if ((wz->fd_control = open("/dev/wz-xdma0_control", O_RDWR)) < 0) { + wz->fd_control = -1; + PERROR("Can't open /dev/wz-xdma0_control"); + wz_close(wz); + return -1; + }; + + if ((wz->fd_memory = open("/dev/wz-xdma0_c2h_0", O_RDWR)) < 0) { + wz->fd_memory = -1; + PERROR("Can't open /dev/wz-xdma0_c2h_0"); + wz_close(wz); + return -1; + }; + + // Allocate buffers + if ((res = ioctl(wz->fd_memory, IOCTL_XDMA_WZ_ALLOC_BUFFERS, 0L)) < 0) { + PERROR("Can't mmap DMA buffers"); + wz_close(wz); + return -1; + } + wz->fd_memory_is_allocated = 1; + + // Now mmap the user registers + if (wz->usr_regs_size && + ((wz->usr_regs = (volatile uint32_t*)mmap(NULL, wz->usr_regs_size, PROT_READ | PROT_WRITE, + MAP_SHARED, wz->fd_user, 0)) == MAP_FAILED)) { + wz->usr_regs = NULL; + PERROR("Can't mmap user registers"); + wz_close(wz); + return -1; + } + + if ((wz->data_buf = (volatile char*)mmap(NULL, TOT_BUF_LEN, PROT_READ | PROT_WRITE, MAP_SHARED, + wz->fd_memory, 0)) == MAP_FAILED) { + wz->data_buf = NULL; + PERROR("Can't mmap data buffer"); + wz_close(wz); + return -1; + } + + // Ensure, that all pages are mapped (allocated) + // Assume page size is 4096. If it is larger, it will not hurt, just take long(er) time + int pagesize = 4096; + int64_t i; + for (i = 0; i < TOT_BUF_LEN; i += pagesize) { + // Touch memory so it is really allocated + ((volatile char*)wz->data_buf)[i] = ((volatile char*)wz->data_buf)[i]; + } + + return 0; } /* The opposite of wz_init */ -int wz_close(struct wz_private* wz) -{ - if (wz->data_buf) { - munmap((void *)wz->data_buf, TOT_BUF_LEN); - } - if (wz->usr_regs) { - munmap((void *)wz->usr_regs, wz->usr_regs_size); - } - if (wz->fd_memory_is_allocated) { - ioctl(wz->fd_memory, IOCTL_XDMA_WZ_FREE_BUFFERS, 0L); - } - if (wz->fd_memory != -1) { - close(wz->fd_memory); - } - if (wz->fd_control != -1) { - close(wz->fd_control); - } - if (wz->fd_user != -1) { - close(wz->fd_user); - } - - wz->fd_user = -1; - wz->fd_control = -1; - wz->fd_memory = -1; - wz->fd_memory_is_allocated = 0; - wz->usr_regs = NULL; - wz->data_buf = NULL; - - return 0; +int wz_close(struct wz_private* wz) { + if (wz->data_buf) { + munmap((void*)wz->data_buf, TOT_BUF_LEN); + } + if (wz->usr_regs) { + munmap((void*)wz->usr_regs, wz->usr_regs_size); + } + if (wz->fd_memory_is_allocated) { + ioctl(wz->fd_memory, IOCTL_XDMA_WZ_FREE_BUFFERS, 0L); + } + if (wz->fd_memory != -1) { + close(wz->fd_memory); + } + if (wz->fd_control != -1) { + close(wz->fd_control); + } + if (wz->fd_user != -1) { + close(wz->fd_user); + } + + wz->fd_user = -1; + wz->fd_control = -1; + wz->fd_memory = -1; + wz->fd_memory_is_allocated = 0; + wz->usr_regs = NULL; + wz->data_buf = NULL; + + return 0; } /* Start the DMA engine */ -inline int wz_start_dma(struct wz_private* wz) -{ - return ioctl(wz->fd_memory, IOCTL_XDMA_WZ_START, 0L); +inline int wz_start_dma(struct wz_private* wz) { + return ioctl(wz->fd_memory, IOCTL_XDMA_WZ_START, 0L); } /* Stop the DMA engine */ -inline int wz_stop_dma(struct wz_private* wz) -{ - return ioctl(wz->fd_memory, IOCTL_XDMA_WZ_STOP, 0L); +inline int wz_stop_dma(struct wz_private* wz) { + return ioctl(wz->fd_memory, IOCTL_XDMA_WZ_STOP, 0L); } - -static inline int wz_get_buf(struct wz_private* wz) -{ - return ioctl(wz->fd_memory, IOCTL_XDMA_WZ_GETBUF, (long) &wz->bdesc); +static inline int wz_get_buf(struct wz_private* wz) { + return ioctl(wz->fd_memory, IOCTL_XDMA_WZ_GETBUF, (long)&wz->bdesc); } -static inline int wz_confirm_buf(struct wz_private* wz) -{ - return ioctl(wz->fd_memory, IOCTL_XDMA_WZ_CONFIRM, (long) &wz->bconf); +static inline int wz_confirm_buf(struct wz_private* wz) { + return ioctl(wz->fd_memory, IOCTL_XDMA_WZ_CONFIRM, (long)&wz->bconf); } - /* Acquire and return buffer */ -inline ssize_t wz_read_start(struct wz_private* wz, char **buffer) -{ - int ret; - if ( (ret = wz_get_buf( wz )) < 0) { - return ret; - } +inline ssize_t wz_read_start(struct wz_private* wz, char** buffer) { + int ret; + if ((ret = wz_get_buf(wz)) < 0) { + return ret; + } - int64_t start_offset = (int64_t)wz->bdesc.first_desc * (int64_t)WZ_DMA_BUFLEN; - int64_t end_offset = (int64_t)wz->bdesc.last_desc * (int64_t)WZ_DMA_BUFLEN + (int64_t) wz->bdesc.last_len; - int64_t bytes_read = end_offset - start_offset; + int64_t start_offset = (int64_t)wz->bdesc.first_desc * (int64_t)WZ_DMA_BUFLEN; + int64_t end_offset = + (int64_t)wz->bdesc.last_desc * (int64_t)WZ_DMA_BUFLEN + (int64_t)wz->bdesc.last_len; + int64_t bytes_read = end_offset - start_offset; - *buffer = (char *)(wz->data_buf + start_offset); + *buffer = (char*)(wz->data_buf + start_offset); - return bytes_read; + return bytes_read; } - /* Mark the buffer to be available for DMA */ -inline int wz_read_complete(struct wz_private* wz) -{ - wz->bconf.first_desc = wz->bdesc.first_desc; - wz->bconf.last_desc = wz->bdesc.last_desc; +inline int wz_read_complete(struct wz_private* wz) { + wz->bconf.first_desc = wz->bdesc.first_desc; + wz->bconf.last_desc = wz->bdesc.last_desc; - return wz_confirm_buf( wz ); + return wz_confirm_buf(wz); } - -/* - * The user logic is driving custom FPGA logic. This is not necessary to use if not implemented in the FPGA. +/* + * The user logic is driving custom FPGA logic. This is not necessary to use if not implemented in + * the FPGA. */ -inline void wz_start_source(struct wz_private* wz) -{ - wz->usr_regs[0x10000/4] = 1; - asm volatile ("" : : : "memory"); +inline void wz_start_source(struct wz_private* wz) { + wz->usr_regs[0x10000 / 4] = 1; + asm volatile("" : : : "memory"); } // User logic -inline void wz_stop_source(struct wz_private* wz) -{ - wz->usr_regs[0x10000/4] = 0; - asm volatile ("" : : : "memory"); +inline void wz_stop_source(struct wz_private* wz) { + wz->usr_regs[0x10000 / 4] = 0; + asm volatile("" : : : "memory"); } diff --git a/test/config/scdaq-calo-cmssw.conf b/test/config/scdaq-calo-cmssw.conf index 271647177e7647c0e4cafb618029305a37a104a4..9a2acba1cd19d643b3886c2ca7b07590747fc8dc 100644 --- a/test/config/scdaq-calo-cmssw.conf +++ b/test/config/scdaq-calo-cmssw.conf @@ -78,6 +78,9 @@ output_force_write:yes ## ################################################################################ +# enable development functionalities (e.g. TCP input filter) +dev_TCPAutoReconnectOnFailure:false + #scdaq port port:8000 diff --git a/test/config/scdaq-passthrough.conf b/test/config/scdaq-passthrough.conf new file mode 100644 index 0000000000000000000000000000000000000000..865f229003ce3da87113078136b798b8be87df76 --- /dev/null +++ b/test/config/scdaq-passthrough.conf @@ -0,0 +1,127 @@ +################################################################################ +## +## Input settings +## +################################################################################ + +# Input settings, allowed values are: +# "wzdma" for DMA driver from Wojciech M. Zabolotny +# "dma" for XILINX DMA driver +# "filedma" for reading from file and simulating DMA +# "micronDMA" for PICO driver +# "tcpip" for TCP/IP input receving + +input:filedma + +## Settings for DMA input + +# DMA device +dma_dev:/dev/xdma0_c2h_0 + +# Max received packet size in bytes (buffer to reserve) +dma_packet_buffer_size:1261568 + +# Number of packet buffers to allocate +dma_number_of_packet_buffers:1000 + +# Print report each N packets, use 0 to disable +packets_per_report:2000 + +# number of orbits per packet, in decimal +nOrbitsPerPacket:4 + +## Extra settings for "filedma" input +input_file:./test/data/calo_testfile.dat + +## Extra settings for "tcpip" input +tcpDestPort:10000 + + +################################################################################ +## +## Stream processor settings +## +################################################################################ + +enable_stream_processor:yes + +# Define processing type (unpacking), allowed values are: +# "PASS_THROUGH" +# "GMT" +# "CALO" +# Note: When changing the processing type, change also "output_filename_prefix" +# in the file output section. +# +processor_type:PASS_THROUGH + +# Enable software zero-supression +doZS:yes + +################################################################################ +## +## File output settings +## +################################################################################ + +output_filename_prefix:scout_PASS0_GMT + +output_filename_base:test/data + +max_file_size:8589934592 + +# Always write data to a file regardless of the run status, useful for debugging +output_force_write:yes + + +################################################################################ +## +## Elastics processor settings (obsolete) +## +################################################################################ + +enable_elastic_processor:no + +port:8000 +elastic_url:http://something.somewhere +pt_cut:7 +quality_cut:12 + + +################################################################################ +## +## SCDAQ Generic Settings +## +################################################################################ + +# enable development functionalities (e.g. TCP input filter) +dev_TCPAutoReconnectOnFailure:false + +## Logging, supported LOG severities: +# TRACE +# DEBUG +# INFO +# WARNING +# ERROR +# FATAL +# +# Log only severities at the same level or more severe than the log_min_severity +# Use TRACE to log everything +# +log_min_severity:ERROR + +# Pipeline settings +threads:8 + +# N orbits to store to each file +# Configured to store fixed number of orbits per file when nOrbitsPerFile > 1 +# Set to 0 to use fixed file size instead +nOrbitsPerFile:0 + +# Headers for cmssw support +cmsswHeaders:no + +## Information necessary to issue a reset request for the board +scone_host:localhost +scone_port:8080 +# Currently can be one of kcu1500_ugmt and kcu1500_demux +scone_board:kcu1500_ugmt diff --git a/test/config/scdaq-passthrough1.conf b/test/config/scdaq-passthrough1.conf new file mode 100644 index 0000000000000000000000000000000000000000..9139d7d0abc89dd8e2ae450fda936d764ab4b5fd --- /dev/null +++ b/test/config/scdaq-passthrough1.conf @@ -0,0 +1,127 @@ +################################################################################ +## +## Input settings +## +################################################################################ + +# Input settings, allowed values are: +# "wzdma" for DMA driver from Wojciech M. Zabolotny +# "filedma" for reading from file and simulating DMA +# "micronDMA" for PICO driver +# "tcpip" for TCP/IP input receving + +input:filedma + +## Settings for DMA input + +# DMA device +dma_dev:/dev/xdma0_c2h_0 + +# Max received packet size in bytes (buffer to reserve) +dma_packet_buffer_size:1261568 + +# Number of packet buffers to allocate +dma_number_of_packet_buffers:1000 + +# Print report each N packets, use 0 to disable +packets_per_report:2000 + +# number of orbits per packet, in decimal +nOrbitsPerPacket:4 + +## Extra settings for "filedma" input +input_file:./test/data/calo_testfile.dat + +## Extra settings for "tcpip" input +tcpDestPort:10000 + + +################################################################################ +## +## Stream processor settings +## +################################################################################ + +enable_stream_processor:yes + +# Define processing type (unpacking), allowed values are: +# "PASS_THROUGH" +# "GMT" +# "CALO" +# "BRIL" +# Note: When changing the processing type, change also "output_filename_prefix" +# in the file output section. +# +processor_type:PASS_THROUGH + +# Enable software zero-supression +doZS:yes + +################################################################################ +## +## File output settings +## +################################################################################ + +output_filename_prefix:scout_PASS1_CALO + +output_filename_base:test/data + +max_file_size:8589934592 + +# Always write data to a file regardless of the run status, useful for debugging +output_force_write:yes + + +################################################################################ +## +## Elastics processor settings (obsolete) +## +################################################################################ + +enable_elastic_processor:no + +port:8000 +elastic_url:http://something.somewhere +pt_cut:7 +quality_cut:12 + + +################################################################################ +## +## SCDAQ Generic Settings +## +################################################################################ + +# enable development functionalities (e.g. TCP input filter) +dev_TCPAutoReconnectOnFailure:false + +## Logging, supported LOG severities: +# TRACE +# DEBUG +# INFO +# WARNING +# ERROR +# FATAL +# +# Log only severities at the same level or more severe than the log_min_severity +# Use TRACE to log everything +# +log_min_severity:ERROR + +# Pipeline settings +threads:8 + +# N orbits to store to each file +# Configured to store fixed number of orbits per file when nOrbitsPerFile > 1 +# Set to 0 to use fixed file size instead +nOrbitsPerFile:0 + +# Headers for cmssw support +cmsswHeaders:no + +## Information necessary to issue a reset request for the board +scone_host:localhost +scone_port:8080 +# Currently can be one of kcu1500_ugmt and kcu1500_demux +scone_board:kcu1500_ugmt diff --git a/test/config/scdaq-passthrough2.conf b/test/config/scdaq-passthrough2.conf new file mode 100644 index 0000000000000000000000000000000000000000..6e4e0e665b60943ce6d93e6363ea1f4239a09ae5 --- /dev/null +++ b/test/config/scdaq-passthrough2.conf @@ -0,0 +1,131 @@ +################################################################################ +## +## Input settings +## +################################################################################ + +# Input settings, allowed values are: +# "wzdma" for DMA driver from Wojciech M. Zabolotny +# "dma" for XILINX DMA driver +# "filedma" for reading from file and simulating DMA +# "micronDMA" for PICO driver +# "tcpip" for TCP/IP input receving + +input:filedma + +## Settings for DMA input + +# DMA device +dma_dev:/dev/xdma0_c2h_0 + +# Max received packet size in bytes (buffer to reserve) +dma_packet_buffer_size:1261568 + +# Number of packet buffers to allocate +dma_number_of_packet_buffers:1000 + +# Print report each N packets, use 0 to disable +packets_per_report:2000 + +# number of orbits per packet, in decimal +nOrbitsPerPacket:4 + +# Extra settings for "filedma" input +input_file:./test/data/gmt_testfile.dat + +## Extra settings for "tcpip" input +tcpDestPort:10001 + + +################################################################################ +## +## Stream processor settings +## +################################################################################ + +enable_stream_processor:yes + +# Define processing type (unpacking), allowed values are: +# "PASS_THROUGH" +# "GMT" +# "CALO" +# "BRIL" +# Note: When changing the processing type, change also "output_filename_prefix" +# in the file output section. + +processor_type:PASS_THROUGH + +# Enable software zero-supression +doZS:yes + +################################################################################ +## +## File output settings +## +################################################################################ + +output_filename_prefix:scout_PASS2_GMT + +output_filename_base:test/data + +max_file_size:8589934592 + +# Always write data to a file regardless of the run status, useful for debugging +output_force_write:yes + + +################################################################################ +## +## Elastics processor settings (obsolete) +## +################################################################################ + +enable_elastic_processor:no + +port:8000 +elastic_url:http://something.somewhere +pt_cut:7 +quality_cut:12 + + +################################################################################ +## +## SCDAQ Generic Settings +## +################################################################################ + +# enable development functionalities (e.g. TCP input filter) +dev_TCPAutoReconnectOnFailure:false + +## Logging, supported LOG severities: +# TRACE +# DEBUG +# INFO +# WARNING +# ERROR +# FATAL +# +# Log only severities at the same level or more severe than the log_min_severity +# Use TRACE to log everything +# +log_min_severity:ERROR + +# Pipeline settings +threads:8 + +# verbosity level, currently supports 0 and 1 +verbosity:0 + +# N orbits to store to each file +# Configured to store fixed number of orbits per file when nOrbitsPerFile > 1 +# Set to 0 to use fixed file size instead +nOrbitsPerFile:0 + +# Headers for cmssw support +cmsswHeaders:no + +## Information necessary to issue a reset request for the board +scone_host:localhost +scone_port:8080 +# Currently can be one of kcu1500_ugmt and kcu1500_demux +scone_board:kcu1500_ugmt diff --git a/test/config/tcp-test.conf b/test/config/tcp-test.conf new file mode 100644 index 0000000000000000000000000000000000000000..23d30532b1be5dd55c41dba91a12d6a067894be6 --- /dev/null +++ b/test/config/tcp-test.conf @@ -0,0 +1,112 @@ +################################################################################ +## +## Input settings +## +################################################################################ + +# Input settings, allowed values are: +# "wzdma" for DMA driver from Wojciech M. Zabolotny +# "filedma" for reading from file and simulating DMA +# "micronDMA" for PICO driver +# "tcpip" for TCP/IP input receving + +input:filedma + +## Settings for DMA input + +# DMA device +dma_dev:/dev/xdma0_c2h_0 + +# Max received packet size in bytes (buffer to reserve) +dma_packet_buffer_size:1261568 + +# Number of packet buffers to allocate +dma_number_of_packet_buffers:1000 + +# Print report each N packets, use 0 to disable +packets_per_report:2000 + +# number of orbits per packet, in decimal +nOrbitsPerPacket:1 + +## Extra settings for "filedma" input +input_file:./test/data/calo_testfile.dat + +## Extra settings for "tcpip" input +tcpDestPort:9000 + + +################################################################################ +## +## Stream processor settings +## +################################################################################ + +enable_stream_processor:yes + +# Define processing type (unpacking), allowed values are: +# "PASS_THROUGH" +# "GMT" +# "CALO" +# "BRIL" +# Note: When changing the processing type, change also "output_filename_prefix" +# in the file output section. +# +processor_type:PASS_THROUGH + +# Enable software zero-supression +doZS:yes + +################################################################################ +## +## File output settings +## +################################################################################ + +output_filename_prefix:tcp-single-scouting_gmt_1 + +output_filename_base:test/in_progress + +max_file_size:8589934592 + +# Always write data to a file regardless of the run status, useful for debugging +output_force_write:no + +################################################################################ +## +## SCDAQ Generic Settings +## +################################################################################ + +# enable development functionalities (e.g. TCP input filter) +dev_TCPAutoReconnectOnFailure:true + +## Logging, supported LOG severities: +# TRACE +# DEBUG +# INFO +# WARNING +# ERROR +# FATAL +# +# Log only severities at the same level or more severe than the log_min_severity +# Use TRACE to log everything +# +log_min_severity:TRACE + +# Pipeline settings +threads:8 + +# N orbits to store to each file +# Configured to store fixed number of orbits per file when nOrbitsPerFile > 1 +# Set to 0 to use fixed file size instead +nOrbitsPerFile:4096 + +# Headers for cmssw support +cmsswHeaders:no + +## Information necessary to issue a reset request for the board +scone_host:localhost +scone_port:8080 +# Currently can be one of kcu1500_ugmt and kcu1500_demux +scone_board:vcu128_bmtf_tcp diff --git a/test/config/tcp-test1.conf b/test/config/tcp-test1.conf new file mode 100644 index 0000000000000000000000000000000000000000..0d2a67ebb29018e5f385af25bbf8c1d33bd9edcc --- /dev/null +++ b/test/config/tcp-test1.conf @@ -0,0 +1,112 @@ +################################################################################ +## +## Input settings +## +################################################################################ + +# Input settings, allowed values are: +# "wzdma" for DMA driver from Wojciech M. Zabolotny +# "filedma" for reading from file and simulating DMA +# "micronDMA" for PICO driver +# "tcpip" for TCP/IP input receving + +input:tcpip + +## Settings for DMA input + +# DMA device +dma_dev:/dev/xdma0_c2h_0 + +# Max received packet size in bytes (buffer to reserve) +dma_packet_buffer_size:1261568 + +# Number of packet buffers to allocate +dma_number_of_packet_buffers:1000 + +# Print report each N packets, use 0 to disable +packets_per_report:2000 + +# number of orbits per packet, in decimal +nOrbitsPerPacket:1 + +## Extra settings for "filedma" input +input_file:./test/data/calo_testfile.dat + +## Extra settings for "tcpip" input +tcpDestPort:10000 + + +################################################################################ +## +## Stream processor settings +## +################################################################################ + +enable_stream_processor:yes + +# Define processing type (unpacking), allowed values are: +# "PASS_THROUGH" +# "GMT" +# "CALO" +# "BRIL" +# Note: When changing the processing type, change also "output_filename_prefix" +# in the file output section. +# +processor_type:PASS_THROUGH + +# Enable software zero-supression +doZS:yes + +################################################################################ +## +## File output settings +## +################################################################################ + +output_filename_prefix:tcp-mp1-scouting_calo_1 + +output_filename_base:test/in_progress + +max_file_size:8589934592 + +# Always write data to a file regardless of the run status, useful for debugging +output_force_write:no + +################################################################################ +## +## SCDAQ Generic Settings +## +################################################################################ + +# enable development functionalities (e.g. TCP input filter) +dev_TCPAutoReconnectOnFailure:true + +## Logging, supported LOG severities: +# TRACE +# DEBUG +# INFO +# WARNING +# ERROR +# FATAL +# +# Log only severities at the same level or more severe than the log_min_severity +# Use TRACE to log everything +# +log_min_severity:TRACE + +# Pipeline settings +threads:8 + +# N orbits to store to each file +# Configured to store fixed number of orbits per file when nOrbitsPerFile > 1 +# Set to 0 to use fixed file size instead +nOrbitsPerFile:4096 + +# Headers for cmssw support +cmsswHeaders:no + +## Information necessary to issue a reset request for the board +scone_host:localhost +scone_port:8080 +# Currently can be one of kcu1500_ugmt and kcu1500_demux +scone_board:vcu128_bmtf_tcp diff --git a/test/config/tcp-test2.conf b/test/config/tcp-test2.conf new file mode 100644 index 0000000000000000000000000000000000000000..5ccc067f9036f5c1bfe46545bc90b7e0263aaab7 --- /dev/null +++ b/test/config/tcp-test2.conf @@ -0,0 +1,112 @@ +################################################################################ +## +## Input settings +## +################################################################################ + +# Input settings, allowed values are: +# "wzdma" for DMA driver from Wojciech M. Zabolotny +# "filedma" for reading from file and simulating DMA +# "micronDMA" for PICO driver +# "tcpip" for TCP/IP input receving + +input:tcpip + +## Settings for DMA input + +# DMA device +dma_dev:/dev/xdma0_c2h_0 + +# Max received packet size in bytes (buffer to reserve) +dma_packet_buffer_size:1261568 + +# Number of packet buffers to allocate +dma_number_of_packet_buffers:1000 + +# Print report each N packets, use 0 to disable +packets_per_report:2000 + +# number of orbits per packet, in decimal +nOrbitsPerPacket:1 + +## Extra settings for "filedma" input +input_file:./test/data/gmt_testfile2.dat + +## Extra settings for "tcpip" input +tcpDestPort:10010 + + +################################################################################ +## +## Stream processor settings +## +################################################################################ + +enable_stream_processor:yes + +# Define processing type (unpacking), allowed values are: +# "PASS_THROUGH" +# "GMT" +# "CALO" +# "BRIL" +# Note: When changing the processing type, change also "output_filename_prefix" +# in the file output section. +# +processor_type:PASS_THROUGH + +# Enable software zero-supression +doZS:yes + +################################################################################ +## +## File output settings +## +################################################################################ + +output_filename_prefix:tcp-mp2-scouting_gmt + +output_filename_base:test/in_progress + +max_file_size:8589934592 + +# Always write data to a file regardless of the run status, useful for debugging +output_force_write:no + +################################################################################ +## +## SCDAQ Generic Settings +## +################################################################################ + +# enable development functionalities (e.g. TCP input filter) +dev_TCPAutoReconnectOnFailure:true + +## Logging, supported LOG severities: +# TRACE +# DEBUG +# INFO +# WARNING +# ERROR +# FATAL +# +# Log only severities at the same level or more severe than the log_min_severity +# Use TRACE to log everything +# +log_min_severity:TRACE + +# Pipeline settings +threads:8 + +# N orbits to store to each file +# Configured to store fixed number of orbits per file when nOrbitsPerFile > 1 +# Set to 0 to use fixed file size instead +nOrbitsPerFile:4096 + +# Headers for cmssw support +cmsswHeaders:no + +## Information necessary to issue a reset request for the board +scone_host:localhost +scone_port:8080 +# Currently can be one of kcu1500_ugmt and kcu1500_demux +scone_board:vcu128_bmtf_tcp