Skip to content

Commit b3c5fa0

Browse files
committed
Separate bar & swt stress tools
1 parent b588308 commit b3c5fa0

File tree

3 files changed

+186
-65
lines changed

3 files changed

+186
-65
lines changed

CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,7 @@ if(PDA_FOUND)
201201
ProgramListCards.cxx
202202
ProgramMetrics.cxx
203203
ProgramStatus.cxx
204+
ProgramSwtStress.cxx
204205
)
205206
list(APPEND EXE_NAMES
206207
roc-bar-stress
@@ -212,6 +213,7 @@ if(PDA_FOUND)
212213
roc-list-cards
213214
roc-metrics
214215
roc-status
216+
roc-swt-stress
215217
)
216218

217219
if(Python2_FOUND)

src/CommandLineUtilities/ProgramBarStress.cxx

Lines changed: 13 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -20,79 +20,49 @@ using namespace AliceO2::roc;
2020
using namespace AliceO2::InfoLogger;
2121
namespace po = boost::program_options;
2222

23+
constexpr uint32_t SWT_WR_WORD_L = 0x0f00040 / 4;
24+
2325
class ProgramBarStress: public Program
2426
{
2527
public:
2628

2729
virtual Description getDescription()
2830
{
2931
return {"Bar Stress", "Stress the Bar Accessor",
30-
"roc-bar-stress --id 42:00.0 --gbt-link 0 --cycles 100000 --print-freq 10000 --errorcheck"};
32+
"roc-bar-stress --id 42:00.0 --cycles 100000 --print-freq 10000"};
3133
}
3234

3335
virtual void addOptions(boost::program_options::options_description& options)
3436
{
3537
options.add_options()
36-
("gbt-link",
37-
po::value<uint32_t>(&mOptions.gbtLink)->default_value(0),
38-
"GBT link over which the bar writes will be performed. CRU is 0-17")
3938
("cycles",
4039
po::value<long long>(&mOptions.cycles)->default_value(100),
41-
"Cycles of SWT writes(/reads) to perform")
40+
"Total bar writes to perform")
4241
("print-freq",
4342
po::value<long long>(&mOptions.printFrequency)->default_value(10),
44-
"Print every #print-freq cycles")
45-
("errorcheck",
46-
po::bool_switch(&mOptions.errorCheck),
47-
"Perform data validation");
43+
"Print every #print-freq cycles");
4844
Options::addOptionCardId(options);
4945
}
5046

51-
int stress(Swt *swt, long long cycles, long long printFrequency, bool errorCheck)
47+
int stress(BarInterface *bar, long long cycles, long long printFrequency)
5248
{
5349

54-
SwtWord swtWordWr = SwtWord(0x0, 0x0, 0x0);
55-
SwtWord swtWordRd = SwtWord(0x0, 0x0, 0x0);
56-
57-
/* swtWordCheck for testing */
58-
// SwtWord swtWordCheck = SwtWord(0x42, 0x42, 0x42);
59-
6050
std::chrono::high_resolution_clock::time_point start = std::chrono::high_resolution_clock::now();
6151
std::chrono::high_resolution_clock::time_point finish = std::chrono::high_resolution_clock::now();
6252

6353
for (long long i=0;; i++){
64-
swtWordWr.setLow((0x1 + i)%0xffffffff);
65-
swtWordWr.setMed((0x2 + i)%0xffffffff);
66-
swtWordWr.setHigh((0x3 + i)%0xffff);
54+
bar->writeRegister(SWT_WR_WORD_L, 0x42);
6755

68-
uint32_t mon = swt->write(swtWordWr);
69-
if (isVerbose())
70-
getLogger() << "WR MON: 0x" << std::setfill('0') << std::hex << mon << InfoLogger::endm;
71-
72-
if (errorCheck){
73-
uint32_t mon = swt->read(swtWordRd);
74-
if (swtWordRd != swtWordWr){
75-
getLogger() << "SWT validation failed" << InfoLogger::endm;
76-
getLogger() << "Read: " << swtWordRd << " | Expected: " << swtWordWr << InfoLogger::endm;
77-
return -1;
78-
}
79-
80-
if (isVerbose()){
81-
getLogger() << "RD MON: 0x" << std::setfill('0') << std::hex << mon << InfoLogger::endm;
82-
getLogger() << "Read swtWord: " << swtWordRd << InfoLogger::endm;
83-
}
84-
}
85-
86-
if (i && (i%printFrequency == 0)){
56+
if (i && ((i%printFrequency == 0) || (i == cycles))){
8757
finish = std::chrono::high_resolution_clock::now();
8858
getLogger() << "loops [" << i-printFrequency+1 << " - " << i << "]: " <<
8959
std::chrono::duration_cast<std::chrono::nanoseconds> (finish - start).count() << "ns" << InfoLogger::endm;
9060

9161
if (i == cycles || isSigInt()){ //sigInt only stops at cycles = printFrequency * X
92-
double throughput = (barOps /(std::chrono::duration_cast<std::chrono::nanoseconds> (finish - start).count() * 1e-9)); //throughput (ops/time) [ops/sec]
62+
double throughput = (printFrequency /(std::chrono::duration_cast<std::chrono::nanoseconds> (finish - start).count() * 1e-9)); //throughput (ops/time) [ops/sec]
9363
getLogger() << "Throughput :" << throughput << " ops/sec" << InfoLogger::endm;
9464

95-
double latency = ((std::chrono::duration_cast<std::chrono::nanoseconds> (finish - start).count() * 1e-9) / barOps); // latency (time/ops) [sec]
65+
double latency = ((std::chrono::duration_cast<std::chrono::nanoseconds> (finish - start).count() * 1e-9) / printFrequency); // latency (time/ops) [sec]
9666
getLogger() << "Operation latency: " << latency << " sec " << InfoLogger::endm;
9767
return i;
9868
}
@@ -108,19 +78,9 @@ class ProgramBarStress: public Program
10878
auto cardId = Options::getOptionCardId(map);
10979

11080
getLogger() << "Card ID: " << cardId << InfoLogger::endm;
111-
getLogger() << "GBT Link: " << mOptions.gbtLink << InfoLogger::endm;
112-
getLogger() << "Cycles of SWT write(/read) operations: " << mOptions.cycles << InfoLogger::endm;
81+
getLogger() << "Total BAR write operations: " << mOptions.cycles << InfoLogger::endm;
11382
getLogger() << "Print frequency: " << mOptions.printFrequency << InfoLogger::endm;
114-
getLogger() << "Error Check enabled: " << mOptions.errorCheck << InfoLogger::endm;
115-
116-
/* bar(Writes | Reads | Ops) every #printFrequency cycles */
117-
barWrites = (SWT_WRITE_BAR_WRITES + SWT_READ_BAR_WRITES*mOptions.errorCheck)*mOptions.printFrequency;
118-
barReads = (SWT_WRITE_BAR_READS + SWT_READ_BAR_READS*mOptions.errorCheck)*mOptions.printFrequency;
119-
barOps = barWrites + barReads;
12083

121-
getLogger() << "Logging time every " << barOps << " bar operations, of which:" << InfoLogger::endm;
122-
getLogger() << "barWrites: " << barWrites << " | barReads: " << barReads << InfoLogger::endm;
123-
12484
std::shared_ptr<BarInterface>
12585
bar0 = ChannelFactory().getBar(cardId, 0);
12686
std::shared_ptr<BarInterface>
@@ -130,38 +90,26 @@ class ProgramBarStress: public Program
13090
getLogger() << "Resetting card..." << InfoLogger::endm;
13191
bar0->writeRegister(Cru::Registers::RESET_CONTROL.index, 0x1);
13292

133-
if(isVerbose())
134-
getLogger() << "Initializing SWT..." << InfoLogger::endm;
135-
auto swt = Swt(*bar2, mOptions.gbtLink);
136-
13793
if(isVerbose())
13894
getLogger() << "Running operations..." << InfoLogger::endm;
13995

14096
auto start = std::chrono::high_resolution_clock::now();
141-
long long cycles_run = stress(&swt, mOptions.cycles, mOptions.printFrequency, mOptions.errorCheck);
97+
long long cycles_run = stress(bar2.get(), mOptions.cycles, mOptions.printFrequency);
14298
auto finish = std::chrono::high_resolution_clock::now();
14399

144100
if (!cycles_run)
145101
getLogger() << "Execution terminated because of error..." << InfoLogger::endm;
146102

147103
getLogger() << "Total duration: " << std::chrono::duration_cast<std::chrono::seconds> (finish-start).count() << "s" << InfoLogger::endm;
148-
getLogger() << "Total bar operations: " << barOps * (cycles_run/mOptions.printFrequency) << InfoLogger::endm;
149-
getLogger() << "Total bar writes " << barWrites * (cycles_run/mOptions.printFrequency) << InfoLogger::endm;
150-
getLogger() << "Total bar reads: " << barReads * (cycles_run/mOptions.printFrequency) << InfoLogger::endm;
104+
getLogger() << "Total bar operations: " << cycles_run << InfoLogger::endm;
151105
}
152106

153107
struct OptionsStruct
154108
{
155-
uint32_t gbtLink = 0;
156109
long long cycles = 100;
157110
long long printFrequency = 10;
158-
bool errorCheck = true;
159111
}mOptions;
160112

161-
long long barOps = 0;
162-
long long barWrites = 0;
163-
long long barReads = 0;
164-
165113
private:
166114
};
167115

Lines changed: 171 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,171 @@
1+
/// \file ProgramSwtStress.cxx
2+
/// \brief Tool that stress the Bar Accessor with SWT transactions
3+
///
4+
/// \author Kostas Alexopoulos ([email protected])
5+
6+
#include <iostream>
7+
#include <iomanip>
8+
#include <cstdint>
9+
#include <chrono>
10+
#include <thread>
11+
#include <cstddef>
12+
#include "Cru/Constants.h"
13+
#include "ReadoutCard/ChannelFactory.h"
14+
#include "Swt/Swt.h"
15+
#include "CommandLineUtilities/Options.h"
16+
#include "CommandLineUtilities/Program.h"
17+
18+
using namespace AliceO2::roc::CommandLineUtilities;
19+
using namespace AliceO2::roc;
20+
using namespace AliceO2::InfoLogger;
21+
namespace po = boost::program_options;
22+
23+
class ProgramSwtStress: public Program
24+
{
25+
public:
26+
27+
virtual Description getDescription()
28+
{
29+
return {"Swt Stress", "Stress the Bar Accessor with SWT transactions",
30+
"roc-swt-stress --id 42:00.0 --gbt-link 0 --cycles 100000 --print-freq 10000 --errorcheck"};
31+
}
32+
33+
virtual void addOptions(boost::program_options::options_description& options)
34+
{
35+
options.add_options()
36+
("gbt-link",
37+
po::value<uint32_t>(&mOptions.gbtLink)->default_value(0),
38+
"GBT link over which the bar writes will be performed. CRU is 0-17")
39+
("cycles",
40+
po::value<long long>(&mOptions.cycles)->default_value(100),
41+
"Cycles of SWT writes(/reads) to perform")
42+
("print-freq",
43+
po::value<long long>(&mOptions.printFrequency)->default_value(10),
44+
"Print every #print-freq cycles")
45+
("errorcheck",
46+
po::bool_switch(&mOptions.errorCheck),
47+
"Perform data validation");
48+
Options::addOptionCardId(options);
49+
}
50+
51+
int stress(Swt *swt, long long cycles, long long printFrequency, bool errorCheck)
52+
{
53+
54+
SwtWord swtWordWr = SwtWord(0x0, 0x0, 0x0);
55+
SwtWord swtWordRd = SwtWord(0x0, 0x0, 0x0);
56+
57+
/* swtWordCheck for testing */
58+
// SwtWord swtWordCheck = SwtWord(0x42, 0x42, 0x42);
59+
60+
std::chrono::high_resolution_clock::time_point start = std::chrono::high_resolution_clock::now();
61+
std::chrono::high_resolution_clock::time_point finish = std::chrono::high_resolution_clock::now();
62+
63+
for (long long i=0;; i++){
64+
swtWordWr.setLow((0x1 + i)%0xffffffff);
65+
swtWordWr.setMed((0x2 + i)%0xffffffff);
66+
swtWordWr.setHigh((0x3 + i)%0xffff);
67+
68+
uint32_t mon = swt->write(swtWordWr);
69+
if (isVerbose())
70+
getLogger() << "WR MON: 0x" << std::setfill('0') << std::hex << mon << InfoLogger::endm;
71+
72+
if (errorCheck){
73+
uint32_t mon = swt->read(swtWordRd);
74+
if (swtWordRd != swtWordWr){
75+
getLogger() << "SWT validation failed" << InfoLogger::endm;
76+
getLogger() << "Read: " << swtWordRd << " | Expected: " << swtWordWr << InfoLogger::endm;
77+
return -1;
78+
}
79+
80+
if (isVerbose()){
81+
getLogger() << "RD MON: 0x" << std::setfill('0') << std::hex << mon << InfoLogger::endm;
82+
getLogger() << "Read swtWord: " << swtWordRd << InfoLogger::endm;
83+
}
84+
}
85+
86+
if (i && ((i%printFrequency == 0) || (i == cycles))){
87+
finish = std::chrono::high_resolution_clock::now();
88+
getLogger() << "loops [" << i-printFrequency+1 << " - " << i << "]: " <<
89+
std::chrono::duration_cast<std::chrono::nanoseconds> (finish - start).count() << "ns" << InfoLogger::endm;
90+
91+
if (i == cycles || isSigInt()){ //sigInt only stops at cycles = printFrequency * X
92+
double throughput = (barOps /(std::chrono::duration_cast<std::chrono::nanoseconds> (finish - start).count() * 1e-9)); //throughput (ops/time) [ops/sec]
93+
getLogger() << "Throughput :" << throughput << " ops/sec" << InfoLogger::endm;
94+
95+
double latency = ((std::chrono::duration_cast<std::chrono::nanoseconds> (finish - start).count() * 1e-9) / barOps); // latency (time/ops) [sec]
96+
getLogger() << "Operation latency: " << latency << " sec " << InfoLogger::endm;
97+
return i;
98+
}
99+
100+
start = std::chrono::high_resolution_clock::now();
101+
}
102+
}
103+
}
104+
105+
virtual void run(const boost::program_options::variables_map& map)
106+
{
107+
108+
auto cardId = Options::getOptionCardId(map);
109+
110+
getLogger() << "Card ID: " << cardId << InfoLogger::endm;
111+
getLogger() << "GBT Link: " << mOptions.gbtLink << InfoLogger::endm;
112+
getLogger() << "Cycles of SWT write(/read) operations: " << mOptions.cycles << InfoLogger::endm;
113+
getLogger() << "Print frequency: " << mOptions.printFrequency << InfoLogger::endm;
114+
getLogger() << "Error Check enabled: " << mOptions.errorCheck << InfoLogger::endm;
115+
116+
/* bar(Writes | Reads | Ops) every #printFrequency cycles */
117+
barWrites = (SWT_WRITE_BAR_WRITES + SWT_READ_BAR_WRITES*mOptions.errorCheck)*mOptions.printFrequency;
118+
barReads = (SWT_WRITE_BAR_READS + SWT_READ_BAR_READS*mOptions.errorCheck)*mOptions.printFrequency;
119+
barOps = barWrites + barReads;
120+
121+
getLogger() << "Logging time every " << barOps << " bar operations, of which:" << InfoLogger::endm;
122+
getLogger() << "barWrites: " << barWrites << " | barReads: " << barReads << InfoLogger::endm;
123+
124+
std::shared_ptr<BarInterface>
125+
bar0 = ChannelFactory().getBar(cardId, 0);
126+
std::shared_ptr<BarInterface>
127+
bar2 = ChannelFactory().getBar(cardId, 2);
128+
129+
if(isVerbose())
130+
getLogger() << "Resetting card..." << InfoLogger::endm;
131+
bar0->writeRegister(Cru::Registers::RESET_CONTROL.index, 0x1);
132+
133+
if(isVerbose())
134+
getLogger() << "Initializing SWT..." << InfoLogger::endm;
135+
auto swt = Swt(*bar2, mOptions.gbtLink);
136+
137+
if(isVerbose())
138+
getLogger() << "Running operations..." << InfoLogger::endm;
139+
140+
auto start = std::chrono::high_resolution_clock::now();
141+
long long cycles_run = stress(&swt, mOptions.cycles, mOptions.printFrequency, mOptions.errorCheck);
142+
auto finish = std::chrono::high_resolution_clock::now();
143+
144+
if (!cycles_run)
145+
getLogger() << "Execution terminated because of error..." << InfoLogger::endm;
146+
147+
getLogger() << "Total duration: " << std::chrono::duration_cast<std::chrono::seconds> (finish-start).count() << "s" << InfoLogger::endm;
148+
getLogger() << "Total bar operations: " << barOps * (cycles_run/mOptions.printFrequency) << InfoLogger::endm;
149+
getLogger() << "Total bar writes " << barWrites * (cycles_run/mOptions.printFrequency) << InfoLogger::endm;
150+
getLogger() << "Total bar reads: " << barReads * (cycles_run/mOptions.printFrequency) << InfoLogger::endm;
151+
}
152+
153+
struct OptionsStruct
154+
{
155+
uint32_t gbtLink = 0;
156+
long long cycles = 100;
157+
long long printFrequency = 10;
158+
bool errorCheck = true;
159+
}mOptions;
160+
161+
long long barOps = 0;
162+
long long barWrites = 0;
163+
long long barReads = 0;
164+
165+
private:
166+
};
167+
168+
int main(int argc, char** argv)
169+
{
170+
return ProgramSwtStress().execute(argc, argv);
171+
}

0 commit comments

Comments
 (0)