Skip to content

Commit c2ab71d

Browse files
authored
Merge pull request #260 from sy-c/master
v2.21.0
2 parents 903d280 + ca8d665 commit c2ab71d

File tree

8 files changed

+69
-21
lines changed

8 files changed

+69
-21
lines changed

doc/configurationParameters.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,7 @@ The parameters related to 3rd-party libraries are described here for convenience
130130
| consumer-zmq-* | maxRate | int| 0 | Maximum number of pages to publish per second. The associated memory copy has an impact on cpu load, so this should be limited when one does not use all the data (eg for eventDump). |
131131
| consumer-zmq-* | pagesPerBurst | int | 1 | Number of consecutive pages guaranteed to be part of each publish sequence. The maxRate limit is checked at the end of each burst. |
132132
| consumer-zmq-* | zmqOptions | string | | Additional ZMQ options, as a comma-separated list of key=value pairs. Possible keys: ZMQ_CONFLATE, ZMQ_IO_THREADS, ZMQ_LINGER, ZMQ_SNDBUF, ZMQ_SNDHWM, ZMQ_SNDTIMEO. |
133+
| equipment-* | autoTimeframeId | int | 0 | When set, timeframe IDs are generated incrementally instead of being computed from trigger orbit counters. Useful to replay files with unordered / gap between TF. BC still used to detect boundaries between TFs. |
133134
| equipment-* | blockAlign | bytes | 2M | Alignment of the beginning of the big memory block from which the pool is created. Pool will start at a multiple of this value. Each page will then begin at a multiple of memoryPoolPageSize from the beginning of big block. |
134135
| equipment-* | consoleStatsUpdateTime | double | 0 | If set, number of seconds between printing statistics on console. |
135136
| equipment-* | ctpMode | int | 0 | If set, the detector field (CTP run mask) is checked. Incoming data is discarded until a new bit is set, and discarded again after this bit is unset. Automatically implies rdhCheckDetectorField=1 and rdhCheckDetectorField=1. |
@@ -210,8 +211,10 @@ The parameters related to 3rd-party libraries are described here for convenience
210211
| readout | maxMsgError | int | 0 | If non-zero, maximum number of error messages allowed while running. Readout stops when threshold is reached. |
211212
| readout | maxMsgWarning | int | 0 | If non-zero, maximum number of error messages allowed while running. Readout stops when threshold is reached. |
212213
| readout | memoryPoolStatsEnabled | int | 0 | Global debugging flag to enable statistics on memory pool usage (printed to stdout when pool released). |
214+
| readout | numberOfRuns | int | 1 | In standalone mode, number of runs to execute (ie START/STOP cycles). |
213215
| readout | rate | double | -1 | Data rate limit, per equipment, in Hertz. -1 for unlimited. |
214216
| readout | tfRateLimit | double | 0 | When set, the output is limited to a given timeframe rate. |
217+
| readout | tfRateLimitMode | int | 0 | Defines the source for TF rate limit: 0 = use TF id, 1 = use number of TF. |
215218
| readout | timeframeServerUrl | string | | The address to be used to publish current timeframe, e.g. to be used as reference clock for other readout instances. |
216219
| readout | timeStart | string | | In standalone mode, time at which to execute start. If not set, immediately. |
217220
| readout | timeStop | string | | In standalone mode, time at which to execute stop. If not set, on int/term/quit signal. |

doc/releaseNotes.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -571,5 +571,9 @@ This file describes the main feature changes for each readout.exe released versi
571571
- Added consistency check of orbit vs timestamp when large gas in TF ids detected.
572572
- Updated configuration parameters documentation.
573573

574-
## next version
574+
## v2.21.0 - 03/08/2023
575575
- When running from the command line, the environment variable O2_RUN can be used to set the run number. It is set to 0 by default, i.e. undefined run number.
576+
- Updated configuration parameters:
577+
- added readout.numberOfRuns: in standalone mode, number of START/STOP cycles to execute (used for testing).
578+
- added readout.tfRateLimitMode: can be set to 1 to use number of TF instead of computed TF id for rate throttling. Useful when replaying files with jumps in TF ids. (not needed with autoTimeframeId)
579+
- added equipment.autoTimeframeId: to force incremental timeframe IDs. Useful when replaying files with jumps in TF ids. BC still used to detect boundaries between TFs.

src/DataBlockAggregator.cxx

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -292,16 +292,14 @@ int DataBlockSlicer::appendBlock(DataBlockContainerReference const& block, doubl
292292
}
293293
}
294294

295-
// theLog.log(LogDebugTrace, "slicer %p append block eq %d link %d for tf %d",
296-
// this,(int)sourceId.equipmentId,(int)sourceId.linkId,(int)tfId);
295+
// theLog.log(LogDebugTrace, "slicer %p append block eq %d link %d for tf %d", this,(int)sourceId.equipmentId,(int)sourceId.linkId,(int)tfId);
297296
PartialSlice& s = partialSlices[sourceId];
298297

299298
if (s.currentDataSet != nullptr) {
300-
// theLog.log(LogDebugTrace, "slice size = %d chunks",partialSlices[linkId].currentDataSet->size()); if ((partialSlices[linkId].tfId!=tfId)||(partialSlices[linkId].currentDataSet->size()>2))
301-
// {
299+
// theLog.log(LogDebugTrace, "slice size = %d chunks",(int)s.currentDataSet->size());
302300
if ((s.tfId != tfId) || (tfId == undefinedTimeframeId)) {
303301
// the current slice is complete
304-
// theLog.log(LogDebugTrace, "slicer %p TF %d eq %d link %d is complete (%d blocks)",this, (int)s.tfId,(int)sourceId.equipmentId,(int)sourceId.linkId,s.currentDataSet->size());
302+
// theLog.log(LogDebugTrace, "slicer %p TF %d eq %d link %d is complete (%d blocks)",this, (int)s.tfId,(int)sourceId.equipmentId,(int)sourceId.linkId,(int)s.currentDataSet->size());
305303
slices.push(s.currentDataSet);
306304
s.currentDataSet = nullptr;
307305
}
@@ -316,7 +314,7 @@ int DataBlockSlicer::appendBlock(DataBlockContainerReference const& block, doubl
316314
s.currentDataSet->push_back(block);
317315
s.tfId = tfId;
318316
s.lastUpdateTime = timestamp;
319-
// printf(" %d,%d -> %d blocks\n",s.sourceId.equipmentId,s.sourceId.linkId,s.currentDataSet->size());
317+
// printf(" %d,%d -> %d blocks\n",(int)sourceId.equipmentId,(int)sourceId.linkId,(int)s.currentDataSet->size());
320318
return s.currentDataSet->size();
321319
}
322320

@@ -340,6 +338,7 @@ DataSetReference DataBlockSlicer::getSlice(bool includeIncomplete)
340338
bcv = slices.front();
341339
slices.pop();
342340
}
341+
// printf("getSlice -> %p\n", bcv.get());
343342
return bcv;
344343
}
345344

src/ReadoutEquipment.cxx

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,9 @@ ReadoutEquipment::ReadoutEquipment(ConfigFile& cfg, std::string cfgEntryPoint, b
166166
cfg.getOptionalValue<int>(cfgEntryPoint + ".TFperiod", cfgTFperiod);
167167
timeframePeriodOrbits = cfgTFperiod;
168168

169+
// configuration parameter: | equipment-* | autoTimeframeId | int | 0 | When set, timeframe IDs are generated incrementally instead of being computed from trigger orbit counters. Useful to replay files with unordered / gap between TF. BC still used to detect boundaries between TFs. |
170+
cfg.getOptionalValue<int>(cfgEntryPoint + ".autoTimeframeId", cfgAutoTimeframeId, 0);
171+
169172
if (!cfgRdhUseFirstInPageEnabled) {
170173
usingSoftwareClock = true; // if RDH disabled, use internal clock for TF id
171174
}
@@ -174,7 +177,11 @@ ReadoutEquipment::ReadoutEquipment(ConfigFile& cfg, std::string cfgEntryPoint, b
174177
timeframeRate = LHCOrbitRate * 1.0 / timeframePeriodOrbits; // timeframe rate, in Hz
175178
theLog.log(LogInfoDevel_(3002), "Timeframe IDs generated by software, %.2lf Hz", timeframeRate);
176179
} else {
177-
theLog.log(LogInfoDevel_(3002), "Timeframe IDs generated from RDH trigger counters");
180+
if (cfgAutoTimeframeId) {
181+
theLog.log(LogInfoDevel_(3002), "Timeframe IDs generated incrementally with boundaries detected from RDH trigger counters");
182+
} else {
183+
theLog.log(LogInfoDevel_(3002), "Timeframe IDs generated from RDH trigger counters");
184+
}
178185
}
179186
}
180187

@@ -465,6 +472,15 @@ Thread::CallbackResult ReadoutEquipment::threadCallback(void* arg)
465472
if (nextBlock->getData()->header.timeframeId == undefinedTimeframeId) {
466473
nextBlock->getData()->header.timeframeId = ptr->getCurrentTimeframe();
467474
}
475+
476+
if (ptr->cfgAutoTimeframeId) {
477+
uint64_t tfId = nextBlock->getData()->header.timeframeId;
478+
if (tfId != ptr->autoTimeframeIdLatestFromBC) {
479+
ptr->autoTimeframeIdLatestFromBC = tfId;
480+
ptr->autoTimeframeIdCounter++;
481+
}
482+
nextBlock->getData()->header.timeframeId = ptr->autoTimeframeIdCounter;
483+
}
468484
}
469485

470486
// tag data with run number
@@ -614,6 +630,9 @@ void ReadoutEquipment::initCounters()
614630

615631
statsNumberOfTimeframes = 0;
616632

633+
autoTimeframeIdLatestFromBC = undefinedTimeframeId;
634+
autoTimeframeIdCounter = 0;
635+
617636
// reset timeframe clock
618637
currentTimeframe = undefinedTimeframeId;
619638
lastTimeframe = undefinedTimeframeId;

src/ReadoutEquipment.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,9 @@ class ReadoutEquipment
184184
int cfgDisableTimeframes = 0; // When set, all TF features disabled
185185
RateRegulator TFregulator; // clock counter for TF rate checks
186186
DataBlockContainerReference throttlePendingBlock; // in case TF rate limit was reached, a block may be set aside for later (when it belongs to next TF)
187+
int cfgAutoTimeframeId = 0; // when set, TFids are generated incrementally instead of taken from RDH BC.
188+
uint64_t autoTimeframeIdLatestFromBC = undefinedTimeframeId; // latest TFid (computed from BC)
189+
uint64_t autoTimeframeIdCounter = 0; // TFid counter for sequence
187190

188191
bool isRdhEquipment = false; // to be set true for RDH equipments
189192

src/ReadoutVersion.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,5 @@
99
// granted to it by virtue of its status as an Intergovernmental Organization
1010
// or submit itself to any jurisdiction.
1111

12-
#define READOUT_VERSION "2.20.0"
12+
#define READOUT_VERSION "2.21.0"
1313

src/mainReadout.cxx

Lines changed: 29 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -334,6 +334,7 @@ class Readout
334334
bool standaloneMode = false; // flag set when readout running in standalone mode (auto state machines)
335335
int cfgTimeStart = 0; // time at which START should be executed in standalone mode
336336
int cfgTimeStop = 0; // time at which STOP should be executed in standalone mode
337+
int cfgNumberOfRuns = 1; // number of START/STOP loops to execute
337338

338339
private:
339340
int _init(int argc, char* argv[]);
@@ -357,6 +358,7 @@ class Readout
357358
double cfgAggregatorSliceTimeout;
358359
double cfgAggregatorStfTimeout;
359360
double cfgTfRateLimit;
361+
int cfgTfRateLimitMode;
360362
int cfgLogbookEnabled;
361363
std::string cfgLogbookUrl;
362364
std::string cfgLogbookApiToken;
@@ -406,7 +408,8 @@ class Readout
406408
void publishLogbookStats(); // publish current readout counters to logbook
407409
AliceO2::Common::Timer logbookTimer; // timer to handle readout logbook publish interval
408410

409-
uint64_t maxTimeframeId;
411+
uint64_t currentTimeframeId = undefinedTimeframeId;
412+
uint64_t countTimeframeId;
410413

411414
#ifdef WITH_ZMQ
412415
std::unique_ptr<ZmqServer> tfServer;
@@ -902,6 +905,9 @@ int Readout::_configure(const boost::property_tree::ptree& properties)
902905

903906
// configuration parameter: | readout | timeStop | string | | In standalone mode, time at which to execute stop. If not set, on int/term/quit signal. |
904907
scanTime("readout.timeStop", cfgTimeStop);
908+
909+
// configuration parameter: | readout | numberOfRuns | int | 1 | In standalone mode, number of runs to execute (ie START/STOP cycles). |
910+
cfg.getOptionalValue<int>("readout.numberOfRuns", cfgNumberOfRuns);
905911
}
906912

907913
cfgMaxMsgError = 0;
@@ -934,6 +940,9 @@ int Readout::_configure(const boost::property_tree::ptree& properties)
934940
// configuration parameter: | readout | tfRateLimit | double | 0 | When set, the output is limited to a given timeframe rate. |
935941
cfgTfRateLimit = 0;
936942
cfg.getOptionalValue<double>("readout.tfRateLimit", cfgTfRateLimit);
943+
// configuration parameter: | readout | tfRateLimitMode | int | 0 | Defines the source for TF rate limit: 0 = use TF id, 1 = use number of TF. |
944+
cfgTfRateLimitMode = 0;
945+
cfg.getOptionalValue<int>("readout.tfRateLimitMode", cfgTfRateLimitMode);
937946

938947
// configuration parameter: | readout | disableTimeframes | int | 0 | When set, all timeframe related features are disabled (this may supersede other config parameters). |
939948
cfgDisableTimeframes = 0;
@@ -1386,7 +1395,8 @@ int Readout::_start()
13861395
#endif
13871396
publishLogbookStats();
13881397
logbookTimer.reset(cfgLogbookUpdateInterval * 1000000);
1389-
maxTimeframeId = 0;
1398+
currentTimeframeId = undefinedTimeframeId;
1399+
countTimeframeId = 0;
13901400

13911401
// execute custom command
13921402
executeCustomCommand("preSTART");
@@ -1494,24 +1504,30 @@ void Readout::loopRunning()
14941504
if (bc->size() > 0) {
14951505
if (bc->at(0)->getData() != nullptr) {
14961506
uint64_t newTimeframeId = bc->at(0)->getData()->header.timeframeId;
1497-
// are we complying with maximum TF rate ?
1498-
if (cfgTfRateLimit > 0) {
1499-
if (newTimeframeId > floor(startTimer.getTime() * cfgTfRateLimit) + 1) {
1500-
usleep(1000);
1501-
continue;
1507+
if (newTimeframeId != currentTimeframeId) {
1508+
// beginning of new TF detected: are we complying with maximum TF rate ?
1509+
if (cfgTfRateLimit > 0) {
1510+
uint64_t maxTimeframes = floor(startTimer.getTime() * cfgTfRateLimit) + 1; // number of TF allowed at this point
1511+
// mode 0: compare with TFid
1512+
// mode 1: use number of TF instead of computed TF id. Useful when replaying files with jumps in TF ids.
1513+
if ( ((cfgTfRateLimitMode == 0) && (newTimeframeId > maxTimeframes))
1514+
|| ((cfgTfRateLimitMode == 1) && (countTimeframeId >= maxTimeframes)) ) {
1515+
usleep(1000);
1516+
continue;
1517+
}
15021518
}
1503-
}
1504-
if (newTimeframeId > maxTimeframeId) {
1505-
maxTimeframeId = newTimeframeId;
1519+
countTimeframeId++;
1520+
currentTimeframeId = newTimeframeId;
15061521
#ifdef WITH_ZMQ
15071522
if (tfServer) {
1508-
tfServer->publish(&maxTimeframeId, sizeof(maxTimeframeId));
1523+
tfServer->publish(&currentTimeframeId, sizeof(currentTimeframeId));
15091524
}
15101525
#endif
15111526
gReadoutStats.counters.numberOfSubtimeframes++;
15121527
gReadoutStats.counters.currentOrbit = bc->at(0)->getData()->header.timeframeOrbitFirst;
15131528
gReadoutStats.counters.notify++;
15141529
}
1530+
// printf("Pushing TF #%d = %d\n", (int)countTimeframeId, (int)newTimeframeId);
15151531
}
15161532
for(auto const& b : *bc) {
15171533
updatePageStateFromDataBlockContainerReference(b, MemoryPage::PageState::InConsumer);
@@ -2253,7 +2269,8 @@ int main(int argc, char* argv[])
22532269
return err;
22542270
}
22552271

2256-
int nloop = 3; // number of start/stop loop to execute
2272+
int nloop = theReadout->cfgNumberOfRuns; // number of start/stop loop to execute
2273+
theLog.log("Will execute %d START/STOP cycle", nloop);
22572274

22582275
auto logTimeGuard = [&](const std::string command, int t) {
22592276
if (t) {

src/readoutConfigEditor.tcl

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ set configurationParametersDescriptor {
7676
| consumer-zmq-* | maxRate | int| 0 | Maximum number of pages to publish per second. The associated memory copy has an impact on cpu load, so this should be limited when one does not use all the data (eg for eventDump). |
7777
| consumer-zmq-* | pagesPerBurst | int | 1 | Number of consecutive pages guaranteed to be part of each publish sequence. The maxRate limit is checked at the end of each burst. |
7878
| consumer-zmq-* | zmqOptions | string | | Additional ZMQ options, as a comma-separated list of key=value pairs. Possible keys: ZMQ_CONFLATE, ZMQ_IO_THREADS, ZMQ_LINGER, ZMQ_SNDBUF, ZMQ_SNDHWM, ZMQ_SNDTIMEO. |
79+
| equipment-* | autoTimeframeId | int | 0 | When set, timeframe IDs are generated incrementally instead of being computed from trigger orbit counters. Useful to replay files with unordered / gap between TF. BC still used to detect boundaries between TFs. |
7980
| equipment-* | blockAlign | bytes | 2M | Alignment of the beginning of the big memory block from which the pool is created. Pool will start at a multiple of this value. Each page will then begin at a multiple of memoryPoolPageSize from the beginning of big block. |
8081
| equipment-* | consoleStatsUpdateTime | double | 0 | If set, number of seconds between printing statistics on console. |
8182
| equipment-* | ctpMode | int | 0 | If set, the detector field (CTP run mask) is checked. Incoming data is discarded until a new bit is set, and discarded again after this bit is unset. Automatically implies rdhCheckDetectorField=1 and rdhCheckDetectorField=1. |
@@ -156,8 +157,10 @@ set configurationParametersDescriptor {
156157
| readout | maxMsgError | int | 0 | If non-zero, maximum number of error messages allowed while running. Readout stops when threshold is reached. |
157158
| readout | maxMsgWarning | int | 0 | If non-zero, maximum number of error messages allowed while running. Readout stops when threshold is reached. |
158159
| readout | memoryPoolStatsEnabled | int | 0 | Global debugging flag to enable statistics on memory pool usage (printed to stdout when pool released). |
160+
| readout | numberOfRuns | int | 1 | In standalone mode, number of runs to execute (ie START/STOP cycles). |
159161
| readout | rate | double | -1 | Data rate limit, per equipment, in Hertz. -1 for unlimited. |
160162
| readout | tfRateLimit | double | 0 | When set, the output is limited to a given timeframe rate. |
163+
| readout | tfRateLimitMode | int | 0 | Defines the source for TF rate limit: 0 = use TF id, 1 = use number of TF. |
161164
| readout | timeframeServerUrl | string | | The address to be used to publish current timeframe, e.g. to be used as reference clock for other readout instances. |
162165
| readout | timeStart | string | | In standalone mode, time at which to execute start. If not set, immediately. |
163166
| readout | timeStop | string | | In standalone mode, time at which to execute stop. If not set, on int/term/quit signal. |

0 commit comments

Comments
 (0)