Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improved calculation of CRC32 #46936

Merged
merged 1 commit into from
Dec 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 2 additions & 5 deletions DataFormats/Provenance/src/BranchID.cc
Original file line number Diff line number Diff line change
@@ -1,13 +1,10 @@
#include "DataFormats/Provenance/interface/BranchID.h"
#include "FWCore/Utilities/interface/CRC32Calculator.h"
#include "FWCore/Utilities/interface/calculateCRC32.h"
#include <ostream>

namespace edm {

BranchID::value_type BranchID::toID(std::string const& branchName) {
cms::CRC32Calculator crc32(branchName);
return crc32.checksum();
}
BranchID::value_type BranchID::toID(std::string const& branchName) { return cms::calculateCRC32(branchName); }

std::ostream& operator<<(std::ostream& os, BranchID const& id) {
os << id.id();
Expand Down
16 changes: 8 additions & 8 deletions EventFilter/L1TRawToDigi/src/AMC13Spec.cc
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@

#include "FWCore/Framework/interface/Event.h"
#include "FWCore/MessageLogger/interface/MessageLogger.h"
#include "FWCore/Utilities/interface/CRC32Calculator.h"
#include "FWCore/Utilities/interface/calculateCRC32.h"

#include "EventFilter/L1TRawToDigi/interface/AMC13Spec.h"

#define EDM_ML_DEBUG 1
//#define EDM_ML_DEBUG 1

namespace amc13 {
Header::Header(unsigned int namc, unsigned int orbit) {
Expand Down Expand Up @@ -38,8 +38,8 @@ namespace amc13 {
}

void Trailer::writeCRC(const uint64_t* start, uint64_t* end) {
std::string dstring(reinterpret_cast<const char*>(start), reinterpret_cast<const char*>(end) + 4);
auto crc = cms::CRC32Calculator(dstring).checksum();
std::string_view dstring(reinterpret_cast<const char*>(start), reinterpret_cast<const char*>(end) + 4);
auto crc = cms::calculateCRC32(dstring);

*end = ((*end) & ~(uint64_t(CRC_mask) << CRC_shift)) | (static_cast<uint64_t>(crc & CRC_mask) << CRC_shift);
}
Expand Down Expand Up @@ -128,8 +128,8 @@ namespace amc13 {

int crc = 0;
if (check_crc) {
std::string check(reinterpret_cast<const char*>(start), reinterpret_cast<const char*>(data) - 4);
crc = cms::CRC32Calculator(check).checksum();
std::string_view check(reinterpret_cast<const char*>(start), reinterpret_cast<const char*>(data) - 4);
crc = cms::calculateCRC32(check);

LogDebug("L1T") << "checking data checksum of " << std::hex << crc << std::dec;
}
Expand All @@ -156,8 +156,8 @@ namespace amc13 {
t = Trailer(data++);

if (check_crc) {
std::string check(reinterpret_cast<const char*>(start), reinterpret_cast<const char*>(data) - 4);
crc = cms::CRC32Calculator(check).checksum();
std::string_view check(reinterpret_cast<const char*>(start), reinterpret_cast<const char*>(data) - 4);
crc = cms::calculateCRC32(check);

LogDebug("L1T") << "checking data checksum of " << std::hex << crc << std::dec;
} else {
Expand Down
12 changes: 6 additions & 6 deletions EventFilter/L1TRawToDigi/src/AMCSpec.cc
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
#include <iomanip>

#include "FWCore/MessageLogger/interface/MessageLogger.h"
#include "FWCore/Utilities/interface/CRC32Calculator.h"
#include "FWCore/Utilities/interface/calculateCRC32.h"

#include "EventFilter/L1TRawToDigi/interface/AMCSpec.h"

#define EDM_ML_DEBUG 1
//#define EDM_ML_DEBUG 1

namespace amc {
BlockHeader::BlockHeader(unsigned int amc_no, unsigned int board_id, unsigned int size, unsigned int block) {
Expand Down Expand Up @@ -92,8 +92,8 @@ namespace amc {
}

void Trailer::writeCRC(const uint64_t *start, uint64_t *end) {
std::string dstring(reinterpret_cast<const char *>(start), reinterpret_cast<const char *>(end) + 4);
auto crc = cms::CRC32Calculator(dstring).checksum();
std::string_view dstring(reinterpret_cast<const char *>(start), reinterpret_cast<const char *>(end) + 4);
auto crc = cms::calculateCRC32(dstring);

*end = ((*end) & ~(uint64_t(CRC_mask) << CRC_shift)) | (static_cast<uint64_t>(crc & CRC_mask) << CRC_shift);
}
Expand Down Expand Up @@ -133,8 +133,8 @@ namespace amc {
header_ = Header(payload_.data());
trailer_ = Trailer(&payload_.back());

std::string check(reinterpret_cast<const char *>(payload_.data()), payload_.size() * 8 - 4);
auto crc = cms::CRC32Calculator(check).checksum();
std::string_view check(reinterpret_cast<const char *>(payload_.data()), payload_.size() * 8 - 4);
auto crc = cms::calculateCRC32(check);

trailer_.check(crc, lv1, header_.getSize(), mtf7_mode);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#ifndef FWCore_Utilities_CRC32Calculator_h
#define FWCore_Utilities_CRC32Calculator_h
#ifndef FWCore_Utilities_calculateCRC32_h
#define FWCore_Utilities_calculateCRC32_h

/*
Code to calculate a CRC32 checksum on a string. This code is based
Expand Down Expand Up @@ -55,18 +55,10 @@ from the original code follow below to attribute the source.

#include <cstdint>

#include <string>
#include <string_view>

namespace cms {

class CRC32Calculator {
public:
CRC32Calculator(std::string const& message);

std::uint32_t checksum() { return checksum_; }

private:
std::uint32_t checksum_;
};
std::uint32_t calculateCRC32(std::string_view message);
} // namespace cms
#endif
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@

#include "FWCore/Utilities/interface/CRC32Calculator.h"
#include "FWCore/Utilities/interface/calculateCRC32.h"

namespace cms {

namespace {

const std::uint32_t CRC32_XINIT = 0xFFFFFFFFL;
const std::uint32_t CRC32_XOROT = 0xFFFFFFFFL;
constexpr std::uint32_t CRC32_XINIT = 0xFFFFFFFFL;
constexpr std::uint32_t CRC32_XOROT = 0xFFFFFFFFL;

const std::uint32_t crctable[256] = {
constexpr std::uint32_t crctable[256] = {
0x00000000L, 0x77073096L, 0xEE0E612CL, 0x990951BAL, 0x076DC419L, 0x706AF48FL, 0xE963A535L, 0x9E6495A3L,
0x0EDB8832L, 0x79DCB8A4L, 0xE0D5E91EL, 0x97D2D988L, 0x09B64C2BL, 0x7EB17CBDL, 0xE7B82D07L, 0x90BF1D91L,
0x1DB71064L, 0x6AB020F2L, 0xF3B97148L, 0x84BE41DEL, 0x1ADAD47DL, 0x6DDDE4EBL, 0xF4D4B551L, 0x83D385C7L,
Expand Down Expand Up @@ -43,19 +43,16 @@ namespace cms {
0xB3667A2EL, 0xC4614AB8L, 0x5D681B02L, 0x2A6F2B94L, 0xB40BBE37L, 0xC30C8EA1L, 0x5A05DF1BL, 0x2D02EF8DL};
} // namespace

CRC32Calculator::CRC32Calculator(std::string const& message) {
std::uint32_t calculateCRC32(std::string_view message) {
/* initialize value */
checksum_ = CRC32_XINIT;
uint32_t checksum = CRC32_XINIT;

/* process each byte prior to checksum field */
auto length = message.length();
char const* p = message.data();
for (size_t j = 0; j < length; j++) {
unsigned char uc = *p++;
checksum_ = cms::crctable[(checksum_ ^ uc) & 0xFFL] ^ (checksum_ >> 8);
for (auto uc : message) {
checksum = cms::crctable[(checksum ^ uc) & 0xFFL] ^ (checksum >> 8);
}

/* return XOR out value */
checksum_ = checksum_ ^ CRC32_XOROT;
return checksum ^ CRC32_XOROT;
}
} // namespace cms
16 changes: 0 additions & 16 deletions FWCore/Utilities/test/test_catch2_CRC32Calculator.cc

This file was deleted.

16 changes: 16 additions & 0 deletions FWCore/Utilities/test/test_catch2_calculateCRC32.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#include "catch.hpp"
#include "FWCore/Utilities/interface/calculateCRC32.h"

TEST_CASE("test cms::calculateCRC32", "[calculateCRC32]") {
SECTION("known") {
auto crc32 = cms::calculateCRC32("type_label_instance_process");

// This known result was calculated using python as a cross check
unsigned int knownResult = 1215348599;
REQUIRE(crc32 == knownResult);
}
SECTION("empty") {
auto emptyString_crc32 = cms::calculateCRC32("");
REQUIRE(emptyString_crc32 == 0);
}
}