File indexing completed on 2024-04-06 12:20:57
0001 #include "L1Trigger/L1TMuonEndCap/interface/PhiMemoryImage.h"
0002 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0003
0004 #include <stdexcept>
0005 #include <iostream>
0006 #include <bitset>
0007
0008 #define UINT64_BITS 64
0009
0010 PhiMemoryImage::PhiMemoryImage() { reset(); }
0011
0012 PhiMemoryImage::~PhiMemoryImage() {}
0013
0014 PhiMemoryImage::PhiMemoryImage(const PhiMemoryImage& other) {
0015 std::copy(&(other._buffer[0][0]), &(other._buffer[0][0]) + (_layers * _units), &(_buffer[0][0]));
0016
0017 _straightness = other._straightness;
0018 }
0019
0020 PhiMemoryImage::PhiMemoryImage(PhiMemoryImage&& other) noexcept : PhiMemoryImage() { swap(other); }
0021
0022
0023 PhiMemoryImage& PhiMemoryImage::operator=(PhiMemoryImage other) {
0024 swap(other);
0025 return *this;
0026 }
0027
0028 void PhiMemoryImage::swap(PhiMemoryImage& other) {
0029 std::swap_ranges(&(other._buffer[0][0]), &(other._buffer[0][0]) + (_layers * _units), &(_buffer[0][0]));
0030
0031 std::swap(other._straightness, _straightness);
0032 }
0033
0034 void PhiMemoryImage::reset() {
0035 std::fill(&(_buffer[0][0]), &(_buffer[0][0]) + (_layers * _units), 0);
0036
0037 _straightness = 0;
0038 }
0039
0040 void PhiMemoryImage::set_bit(unsigned int layer, unsigned int bit) {
0041 check_input(layer, bit);
0042 value_type unit = bit / UINT64_BITS;
0043 value_type mask = (1ul << (bit % UINT64_BITS));
0044 _buffer[layer][unit] |= mask;
0045 }
0046
0047 void PhiMemoryImage::clear_bit(unsigned int layer, unsigned int bit) {
0048 check_input(layer, bit);
0049 value_type unit = bit / UINT64_BITS;
0050 value_type mask = (1ul << (bit % UINT64_BITS));
0051 _buffer[layer][unit] &= ~mask;
0052 }
0053
0054 bool PhiMemoryImage::test_bit(unsigned int layer, unsigned int bit) const {
0055 check_input(layer, bit);
0056 value_type unit = bit / UINT64_BITS;
0057 value_type mask = (1ul << (bit % UINT64_BITS));
0058 return _buffer[layer][unit] & mask;
0059 }
0060
0061 void PhiMemoryImage::set_word(unsigned int layer, unsigned int unit, value_type value) {
0062 check_input(layer, unit * UINT64_BITS);
0063 _buffer[layer][unit] = value;
0064 }
0065
0066 PhiMemoryImage::value_type PhiMemoryImage::get_word(unsigned int layer, unsigned int unit) const {
0067 check_input(layer, unit * UINT64_BITS);
0068 return _buffer[layer][unit];
0069 }
0070
0071 void PhiMemoryImage::check_input(unsigned int layer, unsigned int bit) const {
0072 if (layer >= _layers) {
0073 char what[128];
0074 snprintf(what, sizeof(what), "layer (which is %u) >= _layers (which is %u)", layer, _layers);
0075 throw std::out_of_range(what);
0076 }
0077
0078 unsigned int unit = bit / UINT64_BITS;
0079 if (unit >= _units) {
0080 char what[128];
0081 snprintf(what, sizeof(what), "unit (which is %u) >= _units (which is %u)", unit, _units);
0082 throw std::out_of_range(what);
0083 }
0084 }
0085
0086
0087
0088 void PhiMemoryImage::rotl(unsigned int n) {
0089 if (n >= _units * UINT64_BITS)
0090 return;
0091
0092 value_type tmp[_layers][_units];
0093 std::copy(&(_buffer[0][0]), &(_buffer[0][0]) + (_layers * _units), &(tmp[0][0]));
0094
0095 const unsigned int mask = UINT64_BITS - 1;
0096 const unsigned int n1 = n % UINT64_BITS;
0097 const unsigned int n2 = _units - (n / UINT64_BITS);
0098 const unsigned int n3 = (n1 == 0) ? n2 + 1 : n2;
0099
0100 unsigned int i = 0, j = 0, j_curr = 0, j_next = 0;
0101 for (i = 0; i < _layers; ++i) {
0102 for (j = 0; j < _units; ++j) {
0103
0104
0105
0106
0107
0108
0109 j_curr = (n2 + j) % _units;
0110 j_next = (n3 + j + _units - 1) % _units;
0111 _buffer[i][j] = (tmp[i][j_curr] << n1) | (tmp[i][j_next] >> (-n1 & mask));
0112 }
0113 }
0114 }
0115
0116 void PhiMemoryImage::rotr(unsigned int n) {
0117 if (n >= _units * UINT64_BITS)
0118 return;
0119
0120 value_type tmp[_layers][_units];
0121 std::copy(&(_buffer[0][0]), &(_buffer[0][0]) + (_layers * _units), &(tmp[0][0]));
0122
0123 const unsigned int mask = UINT64_BITS - 1;
0124 const unsigned int n1 = n % UINT64_BITS;
0125 const unsigned int n2 = n / UINT64_BITS;
0126 const unsigned int n3 = (n1 == 0) ? n2 + _units - 1 : n2;
0127
0128 unsigned int i = 0, j = 0, j_curr = 0, j_next = 0;
0129 for (i = 0; i < _layers; ++i) {
0130 for (j = 0; j < _units; ++j) {
0131
0132
0133
0134
0135
0136
0137 j_curr = (n2 + j) % _units;
0138 j_next = (n3 + j + 1) % _units;
0139 _buffer[i][j] = (tmp[i][j_curr] >> n1) | (tmp[i][j_next] << (-n1 & mask));
0140 }
0141 }
0142 }
0143
0144 unsigned int PhiMemoryImage::op_and(const PhiMemoryImage& other) const {
0145 static_assert((_layers == 4 && _units == 3), "This function assumes (_layers == 4 && _units == 3)");
0146
0147
0148 bool b_st1 = (_buffer[0][0] & other._buffer[0][0]) || (_buffer[0][1] & other._buffer[0][1]) ||
0149 (_buffer[0][2] & other._buffer[0][2]);
0150 bool b_st2 = (_buffer[1][0] & other._buffer[1][0]) || (_buffer[1][1] & other._buffer[1][1]) ||
0151 (_buffer[1][2] & other._buffer[1][2]);
0152 bool b_st3 = (_buffer[2][0] & other._buffer[2][0]) || (_buffer[2][1] & other._buffer[2][1]) ||
0153 (_buffer[2][2] & other._buffer[2][2]);
0154 bool b_st4 = (_buffer[3][0] & other._buffer[3][0]) || (_buffer[3][1] & other._buffer[3][1]) ||
0155 (_buffer[3][2] & other._buffer[3][2]);
0156
0157
0158
0159
0160 unsigned int ly = (b_st1 << 2) | (b_st2 << 1) | (b_st3 << 0) | (b_st4 << 0);
0161 return ly;
0162 }
0163
0164 void PhiMemoryImage::print(std::ostream& out) const {
0165 constexpr int N = 160;
0166 out << std::bitset<N - 128>(_buffer[3][2]) << std::bitset<128 - 64>(_buffer[3][1]) << std::bitset<64>(_buffer[3][0])
0167 << std::endl;
0168 out << std::bitset<N - 128>(_buffer[2][2]) << std::bitset<128 - 64>(_buffer[2][1]) << std::bitset<64>(_buffer[2][0])
0169 << std::endl;
0170 out << std::bitset<N - 128>(_buffer[1][2]) << std::bitset<128 - 64>(_buffer[1][1]) << std::bitset<64>(_buffer[1][0])
0171 << std::endl;
0172 out << std::bitset<N - 128>(_buffer[0][2]) << std::bitset<128 - 64>(_buffer[0][1]) << std::bitset<64>(_buffer[0][0]);
0173 }
0174
0175
0176
0177 std::ostream& operator<<(std::ostream& o, const PhiMemoryImage& patt) {
0178 patt.print(o);
0179 return o;
0180 }