forked from cms-sw/cmssw
-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Make GPU-CPU cluster matching deterministic (#294)
Makes the GPU-CPU cluster matching deterministic by intrusively marking CPU clusters with the cluster index. Reuse existing padding space to store the extra transient field, so that the size of SiPixelCluster does not increase. There is still a warning in case of mismatch of the content of the cluster (based on charge comparison), that can eventually be downgraded to a debug message. Properly rewrite the loop in the RawToDigi_kernel . Remove obsolete code (comments and configuration parameters) in SiPixelRawToClusterCUDA and SiPixelRawToClusterGPUKernel.
- Loading branch information
Showing
6 changed files
with
139 additions
and
168 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -8,7 +8,7 @@ | |
//! Class to contain and store all the topological information of pixel clusters: | ||
//! charge, global size, size and the barycenter in x and y | ||
//! local directions. It builds a vector of SiPixel (which is | ||
//! an inner class) and a container of channels. | ||
//! an inner class) and a container of channels. | ||
//! | ||
//! March 2007: Edge methods moved to RectangularPixelTopology class (V.Chiochia) | ||
//! Feb 2008: Modify the Pixel class from float to shorts | ||
|
@@ -21,158 +21,166 @@ | |
#include <vector> | ||
#include <cstdint> | ||
#include <cassert> | ||
#include <limits> | ||
|
||
class PixelDigi; | ||
|
||
class SiPixelCluster { | ||
public: | ||
|
||
class Pixel { | ||
public: | ||
constexpr Pixel() : x(0), y(0), adc(0) {} // for root | ||
constexpr Pixel(int pix_x, int pix_y, int pix_adc) : x(pix_x), y(pix_y), adc(pix_adc) {} | ||
uint16_t x; | ||
constexpr Pixel() : x(0), y(0), adc(0){} // for root | ||
constexpr Pixel(int pix_x, int pix_y, int pix_adc) : | ||
x(pix_x), y(pix_y), adc(pix_adc) {} | ||
uint16_t x; | ||
uint16_t y; | ||
uint16_t adc; | ||
}; | ||
|
||
//--- Integer shift in x and y directions. | ||
class Shift { | ||
public: | ||
constexpr Shift(int dx, int dy) : dx_(dx), dy_(dy) {} | ||
constexpr Shift( int dx, int dy) : dx_(dx), dy_(dy) {} | ||
constexpr Shift() : dx_(0), dy_(0) {} | ||
constexpr int dx() const { return dx_; } | ||
constexpr int dy() const { return dy_; } | ||
|
||
constexpr int dx() const { return dx_;} | ||
constexpr int dy() const { return dy_;} | ||
private: | ||
int dx_; | ||
int dy_; | ||
}; | ||
|
||
//--- Position of a SiPixel | ||
class PixelPos { | ||
public: | ||
constexpr PixelPos() : row_(0), col_(0) {} | ||
constexpr PixelPos(int row, int col) : row_(row), col_(col) {} | ||
constexpr int row() const { return row_; } | ||
constexpr int col() const { return col_; } | ||
constexpr PixelPos operator+(const Shift& shift) const { return PixelPos(row() + shift.dx(), col() + shift.dy()); } | ||
|
||
constexpr PixelPos(int row, int col) : row_(row) , col_(col) {} | ||
constexpr int row() const { return row_;} | ||
constexpr int col() const { return col_;} | ||
constexpr PixelPos operator+( const Shift& shift) const { | ||
return PixelPos( row() + shift.dx(), col() + shift.dy()); | ||
} | ||
private: | ||
int row_; | ||
int col_; | ||
}; | ||
|
||
typedef std::vector<PixelDigi>::const_iterator PixelDigiIter; | ||
typedef std::pair<PixelDigiIter, PixelDigiIter> PixelDigiRange; | ||
|
||
static constexpr unsigned int MAXSPAN = 255; | ||
static constexpr unsigned int MAXPOS = 2047; | ||
|
||
|
||
typedef std::vector<PixelDigi>::const_iterator PixelDigiIter; | ||
typedef std::pair<PixelDigiIter,PixelDigiIter> PixelDigiRange; | ||
|
||
|
||
static constexpr unsigned int MAXSPAN=255; | ||
static constexpr unsigned int MAXPOS=2047; | ||
|
||
/** Construct from a range of digis that form a cluster and from | ||
* a DetID. The range is assumed to be non-empty. | ||
*/ | ||
|
||
SiPixelCluster() {} | ||
|
||
SiPixelCluster(unsigned int isize, | ||
uint16_t const* adcs, | ||
uint16_t const* xpos, | ||
uint16_t const* ypos, | ||
uint16_t const xmin, | ||
uint16_t const ymin) | ||
: thePixelOffset(2 * isize), thePixelADC(adcs, adcs + isize) { | ||
|
||
SiPixelCluster(unsigned int isize, uint16_t const * adcs, | ||
uint16_t const * xpos, uint16_t const * ypos, | ||
uint16_t const xmin, uint16_t const ymin) : | ||
thePixelOffset(2*isize), thePixelADC(adcs,adcs+isize) { | ||
uint16_t maxCol = 0; | ||
uint16_t maxRow = 0; | ||
for (unsigned int i = 0; i != isize; ++i) { | ||
uint16_t xoffset = xpos[i] - xmin; | ||
uint16_t yoffset = ypos[i] - ymin; | ||
thePixelOffset[i * 2] = std::min(uint16_t(MAXSPAN), xoffset); | ||
thePixelOffset[i * 2 + 1] = std::min(uint16_t(MAXSPAN), yoffset); | ||
if (xoffset > maxRow) | ||
maxRow = xoffset; | ||
if (yoffset > maxCol) | ||
maxCol = yoffset; | ||
for (unsigned int i=0; i!=isize; ++i) { | ||
uint16_t xoffset = xpos[i]-xmin; | ||
uint16_t yoffset = ypos[i]-ymin; | ||
thePixelOffset[i*2] = std::min(uint16_t(MAXSPAN),xoffset); | ||
thePixelOffset[i*2+1] = std::min(uint16_t(MAXSPAN),yoffset); | ||
if (xoffset > maxRow) maxRow = xoffset; | ||
if (yoffset > maxCol) maxCol = yoffset; | ||
} | ||
packRow(xmin, maxRow); | ||
packCol(ymin, maxCol); | ||
packRow(xmin,maxRow); | ||
packCol(ymin,maxCol); | ||
} | ||
|
||
|
||
|
||
// obsolete (only for regression tests) | ||
SiPixelCluster(const PixelPos& pix, int adc); | ||
void add(const PixelPos& pix, int adc); | ||
|
||
// Analog linear average position (barycenter) | ||
SiPixelCluster( const PixelPos& pix, int adc); | ||
void add( const PixelPos& pix, int adc); | ||
// Analog linear average position (barycenter) | ||
float x() const { | ||
float qm = 0.0; | ||
int isize = thePixelADC.size(); | ||
for (int i = 0; i < isize; ++i) | ||
qm += float(thePixelADC[i]) * (thePixelOffset[i * 2] + minPixelRow() + 0.5f); | ||
return qm / charge(); | ||
for (int i=0; i<isize; ++i) | ||
qm += float(thePixelADC[i]) * (thePixelOffset[i*2] + minPixelRow() + 0.5f); | ||
return qm/charge(); | ||
} | ||
|
||
float y() const { | ||
float qm = 0.0; | ||
int isize = thePixelADC.size(); | ||
for (int i = 0; i < isize; ++i) | ||
qm += float(thePixelADC[i]) * (thePixelOffset[i * 2 + 1] + minPixelCol() + 0.5f); | ||
return qm / charge(); | ||
for (int i=0; i<isize; ++i) | ||
qm += float(thePixelADC[i]) * (thePixelOffset[i*2+1] + minPixelCol() + 0.5f); | ||
return qm/charge(); | ||
} | ||
|
||
// Return number of pixels. | ||
int size() const { return thePixelADC.size(); } | ||
|
||
int size() const { return thePixelADC.size();} | ||
// Return cluster dimension in the x direction. | ||
int sizeX() const { return rowSpan() + 1; } | ||
|
||
int sizeX() const { return rowSpan() +1;} | ||
// Return cluster dimension in the y direction. | ||
int sizeY() const { return colSpan() + 1; } | ||
|
||
int sizeY() const { return colSpan() +1;} | ||
|
||
|
||
inline int charge() const { | ||
int qm = 0; | ||
int isize = thePixelADC.size(); | ||
for (int i = 0; i < isize; ++i) | ||
for (int i=0; i<isize; ++i) | ||
qm += thePixelADC[i]; | ||
return qm; | ||
} // Return total cluster charge. | ||
|
||
inline int minPixelRow() const { return theMinPixelRow; } // The min x index. | ||
inline int maxPixelRow() const { return minPixelRow() + rowSpan(); } // The max x index. | ||
inline int minPixelCol() const { return theMinPixelCol; } // The min y index. | ||
inline int maxPixelCol() const { return minPixelCol() + colSpan(); } // The max y index. | ||
|
||
const std::vector<uint8_t>& pixelOffset() const { return thePixelOffset; } | ||
const std::vector<uint16_t>& pixelADC() const { return thePixelADC; } | ||
|
||
} // Return total cluster charge. | ||
|
||
inline int minPixelRow() const { return theMinPixelRow;} // The min x index. | ||
inline int maxPixelRow() const { return minPixelRow() + rowSpan();} // The max x index. | ||
inline int minPixelCol() const { return theMinPixelCol;} // The min y index. | ||
inline int maxPixelCol() const { return minPixelCol() + colSpan();} // The max y index. | ||
|
||
|
||
const std::vector<uint8_t> & pixelOffset() const { return thePixelOffset;} | ||
const std::vector<uint16_t> & pixelADC() const { return thePixelADC;} | ||
|
||
// obsolete, use single pixel access below | ||
const std::vector<Pixel> pixels() const { | ||
std::vector<Pixel> oldPixVector; | ||
int isize = thePixelADC.size(); | ||
oldPixVector.reserve(isize); | ||
for (int i = 0; i < isize; ++i) { | ||
oldPixVector.reserve(isize); | ||
for(int i=0; i<isize; ++i) { | ||
oldPixVector.push_back(pixel(i)); | ||
} | ||
return oldPixVector; | ||
} | ||
|
||
// infinite faster than above... | ||
Pixel pixel(int i) const { | ||
return Pixel(minPixelRow() + thePixelOffset[i * 2], minPixelCol() + thePixelOffset[i * 2 + 1], thePixelADC[i]); | ||
return Pixel(minPixelRow() + thePixelOffset[i*2], | ||
minPixelCol() + thePixelOffset[i*2+1], | ||
thePixelADC[i] | ||
); | ||
} | ||
|
||
private: | ||
static int overflow_(uint16_t span) { return span == uint16_t(MAXSPAN); } | ||
|
||
static int overflow_(uint16_t span) { return span==uint16_t(MAXSPAN);} | ||
|
||
public: | ||
int colSpan() const { return thePixelColSpan; } | ||
|
||
|
||
int colSpan() const {return thePixelColSpan; } | ||
|
||
int rowSpan() const { return thePixelRowSpan; } | ||
|
||
|
||
|
||
bool overflowCol() const { return overflow_(thePixelColSpan); } | ||
|
||
bool overflowRow() const { return overflow_(thePixelRowSpan); } | ||
|
||
bool overflow() const { return overflowCol() || overflowRow(); } | ||
|
||
bool overflow() const { return overflowCol() || overflowRow(); } | ||
void packCol(uint16_t ymin, uint16_t yspan) { | ||
theMinPixelCol = ymin; | ||
thePixelColSpan = std::min(yspan, uint16_t(MAXSPAN)); | ||
|
@@ -181,40 +189,51 @@ class SiPixelCluster { | |
theMinPixelRow = xmin; | ||
thePixelRowSpan = std::min(xspan, uint16_t(MAXSPAN)); | ||
} | ||
|
||
// [email protected], 01/05/12 | ||
// [email protected], 01/05/12 | ||
// Getters and setters for the newly added data members (err_x and err_y). See below. | ||
void setSplitClusterErrorX(float errx) { err_x = errx; } | ||
void setSplitClusterErrorY(float erry) { err_y = erry; } | ||
float getSplitClusterErrorX() const { return err_x; } | ||
float getSplitClusterErrorY() const { return err_y; } | ||
void setSplitClusterErrorX( float errx ) { err_x = errx; } | ||
void setSplitClusterErrorY( float erry ) { err_y = erry; } | ||
float getSplitClusterErrorX() const { return err_x; } | ||
float getSplitClusterErrorY() const { return err_y; } | ||
|
||
// the original id (they get sorted) | ||
auto originalId() const { return theOriginalClusterId;} | ||
void setOriginalId(uint16_t id) { theOriginalClusterId=id;} | ||
|
||
private: | ||
std::vector<uint8_t> thePixelOffset; | ||
|
||
std::vector<uint8_t> thePixelOffset; | ||
std::vector<uint16_t> thePixelADC; | ||
|
||
uint16_t theMinPixelRow = MAXPOS; // Minimum pixel index in the x direction (low edge). | ||
uint16_t theMinPixelCol = MAXPOS; // Minimum pixel index in the y direction (left edge). | ||
uint8_t thePixelRowSpan = 0; // Span pixel index in the x direction (low edge). | ||
uint8_t thePixelColSpan = 0; // Span pixel index in the y direction (left edge). | ||
|
||
float err_x = -99999.9f; | ||
float err_y = -99999.9f; | ||
|
||
|
||
uint16_t theMinPixelRow=MAXPOS; // Minimum pixel index in the x direction (low edge). | ||
uint16_t theMinPixelCol=MAXPOS; // Minimum pixel index in the y direction (left edge). | ||
uint8_t thePixelRowSpan=0; // Span pixel index in the x direction (low edge). | ||
uint8_t thePixelColSpan=0; // Span pixel index in the y direction (left edge). | ||
|
||
uint16_t theOriginalClusterId=std::numeric_limits<uint16_t>::max(); | ||
|
||
float err_x=-99999.9f; | ||
float err_y=-99999.9f; | ||
|
||
}; | ||
|
||
|
||
// Comparison operators (needed by DetSetVector) | ||
inline bool operator<(const SiPixelCluster& one, const SiPixelCluster& other) { | ||
if (one.minPixelRow() < other.minPixelRow()) { | ||
inline bool operator<( const SiPixelCluster& one, const SiPixelCluster& other) { | ||
if ( one.minPixelRow() < other.minPixelRow() ) { | ||
return true; | ||
} else if (one.minPixelRow() > other.minPixelRow()) { | ||
} else if ( one.minPixelRow() > other.minPixelRow() ) { | ||
return false; | ||
} else if (one.minPixelCol() < other.minPixelCol()) { | ||
} else if ( one.minPixelCol() < other.minPixelCol() ) { | ||
return true; | ||
} else { | ||
return false; | ||
} | ||
} | ||
|
||
|
||
#include "DataFormats/Common/interface/DetSetVector.h" | ||
#include "DataFormats/Common/interface/DetSetVectorNew.h" | ||
#include "DataFormats/Common/interface/Ref.h" | ||
|
@@ -227,4 +246,4 @@ typedef edm::RefProd<SiPixelClusterCollection> SiPixelClusterRefProd; | |
|
||
typedef edmNew::DetSetVector<SiPixelCluster> SiPixelClusterCollectionNew; | ||
typedef edm::Ref<SiPixelClusterCollectionNew, SiPixelCluster> SiPixelClusterRefNew; | ||
#endif | ||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.