Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 10:17:41

0001 
0002 // Copyright 2022, Jefferson Science Associates, LLC.
0003 // Subject to the terms in the LICENSE file found in the top-level directory.
0004 
0005 #include <catch.hpp>
0006 #include <JANA/JApplication.h>
0007 #include <JANA/JEventSource.h>
0008 #include <JANA/JEventProcessorSequential.h>
0009 #include <JANA/JEventProcessorSequentialRoot.h>
0010 
0011 namespace jeventprocessorsequentialtests {
0012 // If you reuse type names in different Catch tests (e.g. DummyFactory),
0013 // the linker will cheerfully not notice and you will get VERY weird errors.
0014 // Hence, we protect each Catch test with its own namespace.
0015 
0016 
0017 struct MyRootProcessor : public JEventProcessorSequentialRoot {
0018     std::vector<std::pair<int, int>> access_log;
0019     std::mutex access_log_mutex;
0020 
0021     void InitWithGlobalRootLock() override {
0022         for (int i = 0; i < 10; ++i) {
0023             std::this_thread::sleep_for(std::chrono::milliseconds(40));
0024             std::lock_guard<std::mutex> lock(access_log_mutex);
0025             access_log.emplace_back(std::make_pair(42, i));
0026         }
0027     }
0028 
0029     void ProcessSequential(const std::shared_ptr<const JEvent> &event) override {
0030         for (int i = 0; i < 10; ++i) {
0031             std::this_thread::sleep_for(std::chrono::milliseconds(40 - i * 10));
0032             std::lock_guard<std::mutex> lock(access_log_mutex);
0033             access_log.emplace_back(std::make_pair(event->GetEventNumber(), i));
0034         }
0035     }
0036 
0037     void FinishWithGlobalRootLock() override {
0038         for (int i = 0; i < 10; ++i) {
0039             std::this_thread::sleep_for(std::chrono::milliseconds(20));
0040             std::lock_guard<std::mutex> lock(access_log_mutex);
0041             access_log.emplace_back(std::make_pair(49, i));
0042         }
0043     }
0044 };
0045 
0046 TEST_CASE("JEventProcessorSequentialRootTests") {
0047 
0048     JApplication app;
0049     app.Add(new JEventSource());
0050     app.SetParameterValue("nthreads", 4);
0051     app.SetParameterValue("jana:nevents", 4);
0052     //app.SetParameterValue("jana:loglevel", "debug");
0053     //app.SetParameterValue("jana:log:show_threadstamp", true);
0054     auto proc = new MyRootProcessor;
0055     app.Add(proc);
0056     app.Run(true);
0057 
0058     auto log = proc->access_log;
0059     // for (auto pair: log) {
0060     //     jout << pair.first << ", " << pair.second << jendl;
0061     // }
0062     // If there are no race conditions, we expect the access log to contain:
0063     // 1. Init
0064     // 2. 4 events with 10 iters apiece
0065     //    - The iterations within each event are in the correct order
0066     //    - Events are NOT INTERLEAVED
0067     //    - Events might NOT be visited in order of event number
0068     //    - All events must be visited
0069     // 3. Finish
0070     REQUIRE(log.size() == 60);
0071     // Check that Init is called correctly
0072     for (int i = 0; i < 10; ++i) {
0073         REQUIRE(log[i].first == 42);
0074         REQUIRE(log[i].second == i);
0075     }
0076     // Check that Finish is called correctly
0077     for (int i = 0; i < 10; ++i) {
0078         REQUIRE(log[50 + i].first == 49);
0079         REQUIRE(log[50 + i].second == i);
0080     }
0081     bool event_processed[4] = {false, false, false, false};
0082 
0083     // Check that each event is processed correctly
0084     for (int event = 0; event < 4; ++event) {
0085         int event_nr = log[10 + event * 10].first;
0086         REQUIRE(event_processed[event_nr] == false);
0087         event_processed[event_nr] = true;
0088         for (int i = 0; i < 10; ++i) {
0089             auto pair = log[10 + event * 10 + i];
0090             REQUIRE(pair.first == event_nr);
0091             REQUIRE(pair.second == i);
0092         }
0093     }
0094 
0095     // All events were processed
0096     for (int event = 0; event < 4; ++event) {
0097         REQUIRE(event_processed[event] == true);
0098     }
0099 }
0100 
0101 struct MySeqProcessor : public JEventProcessorSequential {
0102     std::vector<std::pair<int, int>> access_log;
0103     std::mutex access_log_mutex;
0104 
0105     void Init() override {
0106         for (int i = 0; i < 10; ++i) {
0107             std::this_thread::sleep_for(std::chrono::milliseconds(40));
0108             std::lock_guard<std::mutex> lock(access_log_mutex);
0109             access_log.emplace_back(std::make_pair(42, i));
0110         }
0111     }
0112 
0113     void ProcessSequential(const std::shared_ptr<const JEvent> &event) override {
0114         for (int i = 0; i < 10; ++i) {
0115             std::this_thread::sleep_for(std::chrono::milliseconds(40 - i * 10));
0116             std::lock_guard<std::mutex> lock(access_log_mutex);
0117             access_log.emplace_back(std::make_pair(event->GetEventNumber(), i));
0118         }
0119     }
0120 
0121     void Finish() override {
0122         for (int i = 0; i < 10; ++i) {
0123             std::this_thread::sleep_for(std::chrono::milliseconds(20));
0124             std::lock_guard<std::mutex> lock(access_log_mutex);
0125             access_log.emplace_back(std::make_pair(49, i));
0126         }
0127     }
0128 };
0129 
0130 
0131 TEST_CASE("JEventProcessorSequentialTests") {
0132 
0133     JApplication app;
0134     app.Add(new JEventSource());
0135     app.SetParameterValue("nthreads", 4);
0136     app.SetParameterValue("jana:nevents", 4);
0137     //app.SetParameterValue("jana:loglevel", "debug");
0138     //app.SetParameterValue("jana:log:show_threadstamp", 1);
0139     auto proc = new MySeqProcessor;
0140     app.Add(proc);
0141     app.Run(true);
0142 
0143     auto log = proc->access_log;
0144     // for (auto pair: log) {
0145     //     jout << pair.first << ", " << pair.second << jendl;
0146     // }
0147     // If there are no race conditions, we expect the access log to contain:
0148     // 1. Init
0149     // 2. 4 events with 10 iters apiece
0150     //    - The iterations within each event are in the correct order
0151     //    - Events are NOT INTERLEAVED
0152     //    - Events might NOT be visited in order of event number
0153     //    - All events must be visited
0154     // 3. Finish
0155     REQUIRE(log.size() == 60);
0156     // Check that Init is called correctly
0157     for (int i = 0; i < 10; ++i) {
0158         REQUIRE(log[i].first == 42);
0159         REQUIRE(log[i].second == i);
0160     }
0161     // Check that Finish is called correctly
0162     for (int i = 0; i < 10; ++i) {
0163         REQUIRE(log[50 + i].first == 49);
0164         REQUIRE(log[50 + i].second == i);
0165     }
0166     bool event_processed[4] = {false, false, false, false};
0167 
0168     // Check that each event is processed correctly
0169     for (int event = 0; event < 4; ++event) {
0170         int event_nr = log[10 + event * 10].first;
0171         REQUIRE(event_processed[event_nr] == false);
0172         event_processed[event_nr] = true;
0173         for (int i = 0; i < 10; ++i) {
0174             auto pair = log[10 + event * 10 + i];
0175             REQUIRE(pair.first == event_nr);
0176             REQUIRE(pair.second == i);
0177         }
0178     }
0179 }
0180 
0181 } // namespace