Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
scdaq
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Iterations
Requirements
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Locked files
Build
Pipelines
Jobs
Pipeline schedules
Test cases
Artifacts
Deploy
Releases
Package Registry
Container Registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Code review analytics
Issue analytics
Insights
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
scouting-demonstrator
scdaq
Commits
a79885a6
Commit
a79885a6
authored
2 years ago
by
Dinyar Rabady
Committed by
Dinyar Rabady
2 years ago
Browse files
Options
Downloads
Patches
Plain Diff
Perform BX map decoding on the fly
Belongs to
#35
.
parent
a27c3a90
No related branches found
No related tags found
No related merge requests found
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
src/processor.cc
+97
-86
97 additions, 86 deletions
src/processor.cc
src/processor.h
+6
-6
6 additions, 6 deletions
src/processor.h
with
103 additions
and
92 deletions
src/processor.cc
+
97
−
86
View file @
a79885a6
...
...
@@ -31,19 +31,6 @@ BrilHistoQueue<std::array<uint32_t, constants::NBXPerOrbit +
constants
::
NFramesInHistoHeader
>>
StreamProcessor
::
BrilQueue
;
// Loops over each word in the orbit trailer BX map and fills a vector with the
// non-empty BX values
void
bit_check
(
std
::
vector
<
unsigned
int
>
*
bx_vect
,
uint32_t
word
,
uint32_t
offset
)
{
for
(
uint32_t
i
=
0
;
i
<
32
;
i
++
)
{
if
(
word
&
1
)
{
bx_vect
->
push_back
(
i
+
offset
);
}
word
>>=
1
;
}
return
;
}
StreamProcessor
::~
StreamProcessor
()
{}
// checks that the packet size is an integer multiple of the BX block size,
...
...
@@ -92,31 +79,16 @@ bool StreamProcessor::CheckFrameMultBlock(size_t inputSize) {
return
true
;
}
// Looks for orbit trailer then counts the non-empty bunch crossings and fills a
// vector with their values The bool (.second) is used to determine valididy of
// the BX count
std
::
vector
<
unsigned
int
>
StreamProcessor
::
CountBX
(
Slice
&
input
,
char
*
rd_ptr
,
bool
&
trailerError
)
{
bool
StreamProcessor
::
GetTrailer
(
Slice
&
input
,
char
*&
rd_ptr
)
{
rd_ptr
+=
32
;
// +32 to account for orbit header
std
::
vector
<
unsigned
int
>
bx_vect
;
trailerError
=
false
;
while
(
rd_ptr
!=
input
.
end
())
{
blockMuon
*
bl
=
reinterpret_cast
<
blockMuon
*>
(
rd_ptr
);
if
(
bl
->
orbit
[
0
]
==
constants
::
beefdead
)
{
// found orbit trailer
orbit_trailer
*
ot
=
(
orbit_trailer
*
)(
rd_ptr
);
for
(
unsigned
int
k
=
0
;
k
<
(
14
*
8
);
k
++
)
{
// 14*8 = 14 frames, 8 links of orbit trailer containing BX
// hitmap
bit_check
(
&
bx_vect
,
ot
->
bx_map
[
k
],
(
k
*
32
+
1
));
// +1 added to account for BX counting starting at 1
}
return
bx_vect
;
orbit_trailer
*
ot
=
reinterpret_cast
<
orbit_trailer
*>
(
rd_ptr
);
if
(
ot
->
beefdead
[
0
]
==
constants
::
beefdead
)
{
// found orbit trailer
return
true
;
}
rd_ptr
+=
sizeof
(
blockMuon
);
}
trailerError
=
true
;
return
bx_vect
;
return
false
;
}
inline
std
::
pair
<
uint32_t
,
bool
>
StreamProcessor
::
ProcessOrbitHeader
(
...
...
@@ -137,31 +109,58 @@ inline std::pair<uint32_t, bool> StreamProcessor::ProcessOrbitHeader(
// Goes through orbit worth of data and fills the output memory with the calo
// data corresponding to the non-empty bunchcrossings, as marked in bx_vect
StreamProcessor
::
fillOrbitMetadata
StreamProcessor
::
FillOrbitCalo
(
const
std
::
vector
<
unsigned
int
>
&
bx_vect
,
char
*
rd_ptr
,
char
*
wr_ptr
)
{
orbit_trailer
*
trailer
,
char
*
rd_ptr
,
char
*
wr_ptr
)
{
std
::
pair
<
uint32_t
,
bool
>
orbit_header
=
std
::
pair
<
uint32_t
,
bool
>
{
ProcessOrbitHeader
(
rd_ptr
)};
//.second is the warning test enable bit
rd_ptr
+=
32
;
// +32 to account for orbit header
uint32_t
relbx
=
uint32_t
{
0
};
uint32_t
orbit
=
uint32_t
{
orbit_header
.
first
}
-
1
;
// Starting with orbit number one lower than what is in the header
// because the "link orbit" contains a few BXs of the previous orbit
uint32_t
counts
=
uint32_t
{
0
};
uint32_t
orbit
=
uint32_t
{
orbit_header
.
first
};
while
(
relbx
<
bx_vect
.
size
())
{
// total number of non-empty BXs in orbit is
// given by bx_vect.size()
uint32_t
filled_bxs
=
0
;
// We loop over the BX map from the orbit trailer and then match the filled
// BXs to the data we got. The logic below is annoyingly convoluted: The first
// BX we get in the data stream is from BX 3555, however the BX map starts at
// BX 1, we therefore need to start reading the BX map from the 3555th bit.
// 3555//32 = 111, so we start at the 111th word; 3555 mod 32 = 3, however we
// start counting at BX1, so the start bit is 2.
uint32_t
bx
=
3554
;
// We start at 3554 here, because we increment by 1
// immediately after starting the loops.
size_t
word
=
111
;
size_t
bit
=
1
;
// Will be incremented immediately after starting the loop
for
(
size_t
pseudo_bx
=
0
;
pseudo_bx
<
3564
;
++
pseudo_bx
)
{
// Looping over at most an entire orbit here.
if
(
word
==
14
*
8
-
1
&&
bit
==
11
)
{
// Bit 11 in word 111 is the last valid BX (3564), so we
// roll over afterwards. (== 11 because that's the one we
// worked on in the previous loop iteration)
word
=
0
;
bit
=
0
;
bx
=
0
;
// Will be immediately incremented to 1.
++
orbit
;
}
else
if
(
bit
<
31
)
{
++
bit
;
}
else
{
bit
=
0
;
++
word
;
}
++
bx
;
if
((
trailer
->
bx_map
[
word
]
&
(
1
<<
bit
))
==
0
)
{
continue
;
// If the bit is zero that BX was empty and we continue.
}
++
filled_bxs
;
blockCalo
*
bl
=
reinterpret_cast
<
blockCalo
*>
(
rd_ptr
);
if
(
bl
->
calo0
[
0
]
==
constants
::
beefdead
)
{
break
;
}
// orbit trailer has been reached, end of orbit data
uint32_t
bx
=
uint32_t
{
bx_vect
[
relbx
]};
uint32_t
orbit_
=
uint32_t
{
orbit_header
.
first
};
if
(
bx
>
3554
)
{
--
orbit_
;
}
// fix for the fact that bx 3555 - 3564 are from the previous orbit
uint32_t
header
=
uint32_t
{
orbit_header
.
second
};
// header can be added to later
memcpy
(
wr_ptr
,
(
char
*
)
&
header
,
4
);
wr_ptr
+=
4
;
memcpy
(
wr_ptr
,
(
char
*
)
&
bx
,
4
);
wr_ptr
+=
4
;
memcpy
(
wr_ptr
,
(
char
*
)
&
orbit
_
,
4
);
memcpy
(
wr_ptr
,
(
char
*
)
&
orbit
,
4
);
wr_ptr
+=
4
;
for
(
uint32_t
i
=
0
;
i
<
8
;
i
++
)
{
memcpy
(
wr_ptr
,
(
char
*
)
&
i
,
4
);
...
...
@@ -181,13 +180,9 @@ StreamProcessor::fillOrbitMetadata StreamProcessor::FillOrbitCalo(
}
counts
+=
1
;
rd_ptr
+=
sizeof
(
blockCalo
);
relbx
++
;
}
StreamProcessor
::
fillOrbitMetadata
meta
=
{
counts
,
orbit
,
};
StreamProcessor
::
fillOrbitMetadata
meta
=
{
counts
,
orbit
,
filled_bxs
};
return
meta
;
}
...
...
@@ -250,15 +245,47 @@ uint32_t StreamProcessor::FillBril(char *rd_ptr, char *wr_ptr, char *end_ptr) {
// Goes through orbit worth of data and fills the output memory with the muons
// corresponding to the non-empty bunchcrossings, as marked in bx_vect
StreamProcessor
::
fillOrbitMetadata
StreamProcessor
::
FillOrbitMuon
(
const
std
::
vector
<
unsigned
int
>
&
bx_vect
,
char
*
rd_ptr
,
char
*
wr_ptr
)
{
orbit_trailer
*
trailer
,
char
*
rd_ptr
,
char
*
wr_ptr
)
{
std
::
pair
<
uint32_t
,
bool
>
orbit_header
=
std
::
pair
<
uint32_t
,
bool
>
{
ProcessOrbitHeader
(
rd_ptr
)};
//.second is the warning test enable bit
rd_ptr
+=
32
;
// +32 to account for orbit header
uint32_t
orbit
=
uint32_t
{
orbit_header
.
first
};
uint32_t
relbx
=
uint32_t
{
0
};
uint32_t
orbit
=
uint32_t
{
orbit_header
.
first
}
-
1
;
// Starting with orbit number one lower than what is in the header
// because the "link orbit" contains a few BXs of the previous orbit
uint32_t
counts
=
uint32_t
{
0
};
while
(
relbx
<
bx_vect
.
size
())
{
// total number of non-empty BXs in orbit is
// given by bx_vect.size()
uint32_t
filled_bxs
=
0
;
// We loop over the BX map from the orbit trailer and then match the filled
// BXs to the data we got. The logic below is annoyingly convoluted: The first
// BX we get in the data stream is from BX 3555, however the BX map starts at
// BX 1, we therefore need to start reading the BX map from the 3555th bit.
// 3555//32 = 111, so we start at the 111th word; 3555 mod 32 = 3, however we
// start counting at BX1, so the start bit is 2.
uint32_t
bx
=
3554
;
// We start at 3554 here, because we increment by 1
// immediately after starting the loops.
size_t
word
=
111
;
size_t
bit
=
1
;
// Will be incremented immediately after starting the loop
for
(
size_t
pseudo_bx
=
0
;
pseudo_bx
<
3564
;
++
pseudo_bx
)
{
// Looping over at most an entire orbit here.
if
(
word
==
14
*
8
-
1
&&
bit
==
11
)
{
// Bit 11 in word 111 is the last valid BX (3564), so we
// roll over afterwards. (== 11 because that's the one we
// worked on in the previous loop iteration)
word
=
0
;
bit
=
0
;
bx
=
0
;
// Will be immediately incremented to 1.
++
orbit
;
}
else
if
(
bit
<
31
)
{
++
bit
;
}
else
{
bit
=
0
;
++
word
;
}
++
bx
;
if
((
trailer
->
bx_map
[
word
]
&
(
1
<<
bit
))
==
0
)
{
continue
;
// If the bit is zero that BX was empty and we continue.
}
++
filled_bxs
;
blockMuon
*
bl
=
reinterpret_cast
<
blockMuon
*>
(
rd_ptr
);
if
(
bl
->
orbit
[
0
]
==
constants
::
beefdead
)
{
break
;
...
...
@@ -267,19 +294,14 @@ StreamProcessor::fillOrbitMetadata StreamProcessor::FillOrbitMuon(
int
mBcount
=
0
;
bool
AblocksOn
[
8
];
bool
BblocksOn
[
8
];
uint32_t
bx
=
uint32_t
{
bx_vect
[
relbx
]};
if
(
bx
>
3554
)
{
--
orbit
;
}
// fix for the fact that bx 3555 - 3564 are from the previous orbit
for
(
unsigned
int
i
=
0
;
i
<
8
;
i
++
)
{
uint32_t
bxA
=
(
bl
->
bx
[
i
]
>>
shifts
::
bx
)
&
masks
::
bx
;
if
((
bxA
!=
bx
)
&&
(
i
==
0
)
&&
(
bx
<
3555
)
&&
control
.
verbosity
)
{
// only prints warning when BX < 3555 i.e from
// the same orbit
if
((
bxA
!=
bx
)
&&
(
i
==
0
)
&&
control
.
verbosity
)
{
LOG
(
WARNING
)
<<
"BX mismatch, uGMT data word BX = "
<<
std
::
hex
<<
bxA
<<
", BX extracted from trailer = "
<<
bx
<<
", orbitN is "
<<
std
::
dec
<<
orbit
;
}
uint32_t
orbitA
=
bl
->
orbit
[
i
];
uint32_t
pt
=
uint32_t
{(
bl
->
mu1f
[
i
]
>>
shifts
::
pt
)
&
masks
::
pt
};
...
...
@@ -342,15 +364,9 @@ StreamProcessor::fillOrbitMetadata StreamProcessor::FillOrbitMuon(
wr_ptr
+=
4
;
// set bit 0 to 1 for second muon
}
}
rd_ptr
+=
sizeof
(
blockMuon
);
relbx
++
;
}
StreamProcessor
::
fillOrbitMetadata
meta
=
{
counts
,
orbit
,
};
StreamProcessor
::
fillOrbitMetadata
meta
=
{
counts
,
orbit
,
filled_bxs
};
return
meta
;
}
...
...
@@ -372,10 +388,7 @@ void StreamProcessor::process(Slice &input, Slice &out) {
bool
endofpacket
=
false
;
uint32_t
orbit_per_packet_count
=
0
;
bool
firstOrbit
=
true
;
StreamProcessor
::
fillOrbitMetadata
meta
{
0
,
0
,
};
StreamProcessor
::
fillOrbitMetadata
meta
{
0
,
0
,
0
};
if
(
processorType
==
ProcessorType
::
PASS_THROUGH
)
{
memcpy
(
wr_ptr
,
rd_ptr
,
input
.
size
());
out
.
set_end
(
out
.
begin
()
+
input
.
size
());
...
...
@@ -394,9 +407,9 @@ void StreamProcessor::process(Slice &input, Slice &out) {
}
while
(
endofpacket
==
false
)
{
uint32_t
orbitCount
=
0
;
bool
trailer
Error
=
false
;
std
::
vector
<
unsigned
int
>
bx_vect
=
CountBX
(
input
,
rd_ptr
,
trailer
Erro
r
);
if
(
trailer
Error
==
true
)
{
char
*
trailer
_ptr
=
rd_ptr
;
bool
trailerFound
=
GetTrailer
(
input
,
trailer
_pt
r
);
if
(
!
trailer
Found
)
{
stats
.
orbit_trailer_error_count
++
;
LOG
(
WARNING
)
<<
"Orbit trailer error: orbit trailer not found before end of data "
...
...
@@ -404,36 +417,34 @@ void StreamProcessor::process(Slice &input, Slice &out) {
<<
stats
.
orbit_trailer_error_count
;
return
;
}
std
::
sort
(
bx_vect
.
begin
(),
bx_vect
.
end
()
);
orbit_trailer
*
trailer
=
reinterpret_cast
<
orbit_trailer
*>
(
trailer_ptr
);
if
(
processorType
==
ProcessorType
::
GMT
)
{
meta
=
FillOrbitMuon
(
bx_vect
,
rd_ptr
,
wr_ptr
);
meta
=
FillOrbitMuon
(
trailer
,
rd_ptr
,
wr_ptr
);
orbitCount
=
meta
.
counts
;
++
orbit_per_packet_count
;
wr_ptr
+=
orbitC
ount
*
12
+
12
*
bx_vect
.
size
()
;
// 12 bytes for each muon/count then 12
// bytes for each bx header
wr_ptr
+=
meta
.
c
ount
s
*
12
+
12
*
meta
.
filled_bxs
;
// 12 bytes for each muon/count then 12
// bytes for each bx header
}
else
if
(
processorType
==
ProcessorType
::
CALO
)
{
meta
=
FillOrbitCalo
(
bx_vect
,
rd_ptr
,
wr_ptr
);
meta
=
FillOrbitCalo
(
trailer
,
rd_ptr
,
wr_ptr
);
orbitCount
=
meta
.
counts
;
++
orbit_per_packet_count
;
// size of calo packet is 4bytes*(8links*7dataWords + 3headerWords)=236
// bytes Note 7 data words per link because we have the "link number" word
// + 6 words from calo L2
wr_ptr
+=
4
*
((
8
*
7
)
+
3
)
*
bx_vect
.
size
();
wr_ptr
+=
4
*
((
8
*
7
)
+
3
)
*
meta
.
filled_bxs
;
}
else
{
LOG
(
ERROR
)
<<
"UNKNOWN PROCESSOR_TYPE, EXITING"
;
throw
std
::
invalid_argument
(
"ERROR: PROCESSOR_TYPE NOT RECOGNISED"
);
}
rd_ptr
+=
32
+
bx_vect
.
size
()
*
sizeof
(
blockMuon
)
+
rd_ptr
+=
32
+
meta
.
filled_bxs
*
sizeof
(
blockMuon
)
+
constants
::
orbit_trailer_size
;
// 32 for orbit header, + nBXs +
// orbit trailer
counts
+=
orbitCount
;
if
(
firstOrbit
)
{
out
.
set_firstOrbitN
(
meta
.
orbit
);
firstOrbit
=
false
;
};
bx_vect
.
clear
();
}
if
(
rd_ptr
<
input
.
end
())
{
uint32_t
*
dma_trailer_word
=
(
uint32_t
*
)(
rd_ptr
);
...
...
This diff is collapsed.
Click to expand it.
src/processor.h
+
6
−
6
View file @
a79885a6
...
...
@@ -32,16 +32,16 @@ class StreamProcessor : public tbb::filter {
struct
fillOrbitMetadata
{
uint32_t
counts
;
uint32_t
orbit
;
uint32_t
filled_bxs
;
};
void
process
(
Slice
&
input
,
Slice
&
out
);
bool
CheckFrameMultBlock
(
size_t
inputSize
);
std
::
vector
<
unsigned
int
>
CountBX
(
Slice
&
input
,
char
*
rd_ptr
,
bool
&
trailerError
);
bool
GetTrailer
(
Slice
&
input
,
char
*&
rd_ptr
);
inline
std
::
pair
<
uint32_t
,
bool
>
ProcessOrbitHeader
(
char
*
rd_ptr
);
fillOrbitMetadata
FillOrbitMuon
(
std
::
vector
<
unsigned
int
>
&
bx_vect
,
char
*
rd_ptr
,
char
*
wr_ptr
);
fillOrbitMetadata
FillOrbitCalo
(
std
::
vector
<
unsigned
int
>
&
bx_vect
,
char
*
rd_ptr
,
char
*
wr_ptr
);
fillOrbitMetadata
FillOrbitMuon
(
orbit_trailer
*
trailer
,
char
*
rd_ptr
,
char
*
wr_ptr
);
fillOrbitMetadata
FillOrbitCalo
(
orbit_trailer
*
trailer
,
char
*
rd_ptr
,
char
*
wr_ptr
);
uint32_t
FillBril
(
char
*
rd_ptr
,
char
*
wr_ptr
,
char
*
end_ptr
);
size_t
max_size
;
uint64_t
nbPackets
;
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment