Merge pull request #1037 from barfowl/far_stencil_table_ptr

Simplify the private PatchTable::StencilTableHandler class
This commit is contained in:
David G Yu 2019-01-04 16:26:00 -08:00 committed by GitHub
commit bf38091ac3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 145 additions and 118 deletions

View File

@ -66,25 +66,59 @@ PatchTable::PatchTable(PatchTable const & src) :
_varyingPrecisionIsDouble(src._varyingPrecisionIsDouble),
_faceVaryingPrecisionIsDouble(src._faceVaryingPrecisionIsDouble) {
if (src._localPointStencils.IsSet()) {
_localPointStencils = src._localPointStencils.Clone();
if (src._localPointStencils) {
if (src._vertexPrecisionIsDouble) {
_localPointStencils.Set(
new StencilTableReal<double>(*src._localPointStencils.Get<double>()));
} else {
_localPointStencils.Set(
new StencilTableReal<float>(*src._localPointStencils.Get<float>()));
}
}
if (src._localPointVaryingStencils.IsSet()) {
_localPointVaryingStencils = src._localPointVaryingStencils.Clone();
if (src._localPointVaryingStencils) {
if (src._varyingPrecisionIsDouble) {
_localPointVaryingStencils.Set(
new StencilTableReal<double>(*src._localPointVaryingStencils.Get<double>()));
} else {
_localPointVaryingStencils.Set(
new StencilTableReal<float>(*src._localPointVaryingStencils.Get<float>()));
}
}
if (! src._localPointFaceVaryingStencils.empty()) {
_localPointFaceVaryingStencils.resize(src._localPointFaceVaryingStencils.size());
for (int fvc=0; fvc<(int)_localPointFaceVaryingStencils.size(); ++fvc) {
_localPointFaceVaryingStencils[fvc] = src._localPointFaceVaryingStencils[fvc].Clone();
if (src._localPointFaceVaryingStencils[fvc]) {
if (src._faceVaryingPrecisionIsDouble) {
_localPointFaceVaryingStencils[fvc].Set(new StencilTableReal<double>(
*src._localPointFaceVaryingStencils[fvc].Get<double>()));
} else {
_localPointFaceVaryingStencils[fvc].Set(new StencilTableReal<float>(
*src._localPointFaceVaryingStencils[fvc].Get<float>()));
}
}
}
}
}
PatchTable::~PatchTable() {
_localPointStencils.Delete();
_localPointVaryingStencils.Delete();
if (_vertexPrecisionIsDouble) {
delete _localPointStencils.Get<double>();
} else {
delete _localPointStencils.Get<float>();
}
if (_varyingPrecisionIsDouble) {
delete _localPointVaryingStencils.Get<double>();
} else {
delete _localPointVaryingStencils.Get<float>();
}
for (int fvc=0; fvc<(int)_localPointFaceVaryingStencils.size(); ++fvc) {
_localPointFaceVaryingStencils[fvc].Delete();
if (_faceVaryingPrecisionIsDouble) {
delete _localPointFaceVaryingStencils[fvc].Get<double>();
} else {
delete _localPointFaceVaryingStencils[fvc].Get<float>();
}
}
}
@ -365,17 +399,25 @@ PatchTable::GetSingleCreasePatchSharpnessValue(int arrayIndex, int patchIndex) c
int
PatchTable::GetNumLocalPoints() const {
return _localPointStencils.IsSet() ? _localPointStencils.Size() : 0;
if (!_localPointStencils) return 0;
return _vertexPrecisionIsDouble
? _localPointStencils.Get<double>()->GetNumStencils()
: _localPointStencils.Get<float>()->GetNumStencils();
}
int
PatchTable::GetNumLocalPointsVarying() const {
return _localPointVaryingStencils.IsSet() ? _localPointVaryingStencils.Size() : 0;
if (!_localPointVaryingStencils) return 0;
return _varyingPrecisionIsDouble
? _localPointVaryingStencils.Get<double>()->GetNumStencils()
: _localPointVaryingStencils.Get<float>()->GetNumStencils();
}
int
PatchTable::GetNumLocalPointsFaceVarying(int channel) const {
if (channel>=0 && channel<(int)_localPointFaceVaryingStencils.size()) {
return _localPointFaceVaryingStencils[channel].IsSet() ?
_localPointFaceVaryingStencils[channel].Size() : 0;
if (!_localPointFaceVaryingStencils[channel]) return 0;
return _faceVaryingPrecisionIsDouble
? _localPointFaceVaryingStencils[channel].Get<double>()->GetNumStencils()
: _localPointFaceVaryingStencils[channel].Get<float>()->GetNumStencils();
}
return 0;
}

View File

@ -597,54 +597,34 @@ private:
private:
//
// Private class to manage stencil table pointers of varying precision
// Simple private class to hold stencil table pointers of varying precision,
// where the discriminant of the precision is external.
//
// This implementation is still up for debate -- could be improved or
// could be entirely replaced...
// NOTE that this is a simple pointer container and NOT a smart pointer that
// manages the ownership of the object referred to by it.
//
class StencilTableHandler {
class StencilTablePtr {
private:
typedef StencilTableReal<float> float_type;
typedef StencilTableReal<double> double_type;
void init() { _fPtr = 0, _isDouble = false; }
void init(float_type * ptr) { _fPtr = ptr, _isDouble = false; }
void init(double_type * ptr) { _dPtr = ptr, _isDouble = true; }
public:
StencilTableHandler() { init(); }
StencilTableHandler(float_type * ptr) { init(ptr); }
StencilTableHandler(double_type * ptr) { init(ptr); }
// Generic accessor and modifiers:
template <typename REAL> StencilTableReal<REAL> * Get() const;
void Set(float_type * ptr) { init(ptr); }
void Set(double_type * ptr) { init(ptr); }
// Other utilities
bool IsSet() const { return _fPtr != 0; }
bool IsDouble() const { return _isDouble; }
void Clear() { init(); }
int Size() const {
return _isDouble ? _dPtr->GetNumStencils() : _fPtr->GetNumStencils();
}
void Delete() {
if (_isDouble) delete _dPtr;
else delete _fPtr;
}
StencilTableHandler Clone() const {
return _isDouble ? StencilTableHandler(new double_type(*_dPtr))
: StencilTableHandler(new float_type(*_fPtr));
}
private:
union {
float_type * _fPtr;
double_type * _dPtr;
};
bool _isDouble;
public:
StencilTablePtr() { _fPtr = 0; }
StencilTablePtr(float_type * ptr) { _fPtr = ptr; }
StencilTablePtr(double_type * ptr) { _dPtr = ptr; }
operator bool() const { return _fPtr != 0; }
void Set() { _fPtr = 0; }
void Set(float_type * ptr) { _fPtr = ptr; }
void Set(double_type * ptr) { _dPtr = ptr; }
template <typename REAL> StencilTableReal<REAL> * Get() const;
};
private:
@ -671,8 +651,8 @@ private:
QuadOffsetsTable _quadOffsetsTable; // Quad offsets (for Gregory patches)
VertexValenceTable _vertexValenceTable; // Vertex valence table (for Gregory patches)
StencilTableHandler _localPointStencils; // local point conversion stencils
StencilTableHandler _localPointVaryingStencils; // local point varying stencils
StencilTablePtr _localPointStencils; // local point conversion stencils
StencilTablePtr _localPointVaryingStencils; // local point varying stencils
//
// Varying data
@ -686,7 +666,7 @@ private:
//
FVarPatchChannelVector _fvarChannels;
std::vector<StencilTableHandler> _localPointFaceVaryingStencils;
std::vector<StencilTablePtr> _localPointFaceVaryingStencils;
//
// 'single-crease' patch sharpness tables
@ -712,10 +692,10 @@ private:
// Template specializations for float/double -- to be defined before used:
//
template <> inline StencilTableReal<float> *
PatchTable::StencilTableHandler::Get<float>() const { return _fPtr; }
PatchTable::StencilTablePtr::Get<float>() const { return _fPtr; }
template <> inline StencilTableReal<double> *
PatchTable::StencilTableHandler::Get<double>() const { return _dPtr; }
PatchTable::StencilTablePtr::Get<double>() const { return _dPtr; }
template <> inline bool
PatchTable::IsLocalPointStencilPrecision<float>() const {
@ -797,7 +777,7 @@ template <class T>
inline void
PatchTable::ComputeLocalPointValues(T const *src, T *dst) const {
assert(IsLocalPointStencilPrecision<float>());
if (_localPointStencils.IsSet()) {
if (_localPointStencils) {
_localPointStencils.Get<float>()->UpdateValues(src, dst);
}
}
@ -806,7 +786,7 @@ template <class T>
inline void
PatchTable::ComputeLocalPointValuesVarying(T const *src, T *dst) const {
assert(IsLocalPointVaryingStencilPrecision<float>());
if (_localPointVaryingStencils.IsSet()) {
if (_localPointVaryingStencils) {
_localPointVaryingStencils.Get<float>()->UpdateValues(src, dst);
}
}
@ -816,7 +796,7 @@ inline void
PatchTable::ComputeLocalPointValuesFaceVarying(T const *src, T *dst, int channel) const {
assert(IsLocalPointFaceVaryingStencilPrecision<float>());
if (channel >= 0 && channel < (int)_localPointFaceVaryingStencils.size()) {
if (_localPointFaceVaryingStencils[channel].IsSet()) {
if (_localPointFaceVaryingStencils[channel]) {
_localPointFaceVaryingStencils[channel].Get<float>()->UpdateValues(src, dst);
}
}

View File

@ -115,7 +115,7 @@ public:
PatchTable * GetPatchTable() const { return _table; };
private:
typedef PatchTable::StencilTableHandler StencilTableHandler;
typedef PatchTable::StencilTablePtr StencilTablePtr;
// Simple struct to store <face,level> pair for a patch:
struct PatchTuple {
@ -195,12 +195,17 @@ private:
int sourcePointOffset,
Index patchPoints[]);
StencilTableHandler AcquireStencilTable() {
return acquireStencilTable(_stencilTable);
StencilTablePtr AcquireStencilTable() {
return _options.doubleStencilTable
? acquireStencilTable<double>(_stencilTable)
: acquireStencilTable<float>(_stencilTable);
}
private:
// Internal methods:
template <typename REAL>
void initializeStencilTable(int numLocalPointsExpected);
template <typename REAL>
void appendLocalPointStencil(SparseMatrix<REAL> const & conversionMatrix,
int stencilRow,
@ -220,7 +225,8 @@ private:
Index const sourcePoints[],
int sourcePointOffset);
StencilTableHandler acquireStencilTable(StencilTableHandler& stencilTableMember);
template <typename REAL>
StencilTablePtr acquireStencilTable(StencilTablePtr& stencilTableMember);
Index findSharedCornerPoint(int levelIndex, Index valueIndex,
Index newIndex);
@ -239,16 +245,18 @@ private:
std::vector<IndexVector> _sharedCornerPoints;
std::vector<IndexVector> _sharedEdgePoints;
StencilTableHandler _stencilTable;
StencilTablePtr _stencilTable;
// This was hopefully transitional but will persist -- the should be
// no need for Varying local points or stencils associated with them.
public:
StencilTableHandler AcquireStencilTableVarying() {
return acquireStencilTable(_stencilTableVarying);
StencilTablePtr AcquireStencilTableVarying() {
return _options.doubleStencilTable
? acquireStencilTable<double>(_stencilTableVarying)
: acquireStencilTable<float>(_stencilTableVarying);
}
StencilTableHandler _stencilTableVarying;
StencilTablePtr _stencilTableVarying;
};
private:
@ -1417,17 +1425,16 @@ PatchTableBuilder::LocalPointHelper::LocalPointHelper(
if (_options.createStencilTable) {
if (_options.doubleStencilTable) {
_stencilTable.Set(new StencilTableReal<double>(0));
if (_options.createVaryingTable) {
_stencilTableVarying.Set(new StencilTableReal<double>(0));
}
initializeStencilTable<double>(numLocalPointsExpected);
} else {
_stencilTable.Set(new StencilTableReal<float>(0));
if (_options.createVaryingTable) {
_stencilTableVarying.Set(new StencilTableReal<float>(0));
}
initializeStencilTable<float>(numLocalPointsExpected);
}
}
}
template <typename REAL>
void
PatchTableBuilder::LocalPointHelper::initializeStencilTable(int numLocalPointsExpected) {
//
// Reserving space for the local-point stencils has been a source of
@ -1438,65 +1445,63 @@ PatchTableBuilder::LocalPointHelper::LocalPointHelper(
// The average number of entries per stencil has been historically set
// at 16, which seemed high and was reduced on further investigation.
//
if (_stencilTable.IsSet()) {
// Historic note: limits to 100M (=800M bytes) entries for reserved size
size_t const MaxEntriesToReserve = 100 * 1024 * 1024;
size_t const AvgEntriesPerStencil = 9; // originally 16
StencilTableReal<REAL> * stencilTable = new StencilTableReal<REAL>(0);
StencilTableReal<REAL> * varyingTable = _options.createVaryingTable
? new StencilTableReal<REAL>(0) : 0;
size_t numStencilsExpected = numLocalPointsExpected;
size_t numStencilEntriesExpected = numStencilsExpected * AvgEntriesPerStencil;
// Historic note: limits to 100M (=800M bytes) entries for reserved size
size_t const MaxEntriesToReserve = 100 * 1024 * 1024;
size_t const AvgEntriesPerStencil = 9; // originally 16
size_t numEntriesToReserve = std::min(numStencilEntriesExpected,
MaxEntriesToReserve);
if (numEntriesToReserve) {
if (_stencilTable.IsDouble()) {
_stencilTable.Get<double>()->reserve(
(int)numStencilsExpected, (int)numEntriesToReserve);
} else {
_stencilTable.Get<float>()->reserve(
(int)numStencilsExpected, (int)numEntriesToReserve);
}
if (_stencilTableVarying.IsSet()) {
// Varying stencils have only one entry per point
if (_stencilTableVarying.IsDouble()) {
_stencilTableVarying.Get<double>()->reserve(
(int)numStencilsExpected, (int)numStencilsExpected);
} else {
_stencilTableVarying.Get<float>()->reserve(
(int)numStencilsExpected, (int)numStencilsExpected);
}
}
size_t numStencilsExpected = numLocalPointsExpected;
size_t numStencilEntriesExpected = numStencilsExpected * AvgEntriesPerStencil;
size_t numEntriesToReserve = std::min(numStencilEntriesExpected,
MaxEntriesToReserve);
if (numEntriesToReserve) {
stencilTable->reserve(
(int)numStencilsExpected, (int)numEntriesToReserve);
if (varyingTable) {
// Varying stencils have only one entry per point
varyingTable->reserve(
(int)numStencilsExpected, (int)numStencilsExpected);
}
}
_stencilTable.Set(stencilTable);
_stencilTableVarying.Set(varyingTable);
}
PatchTableBuilder::StencilTableHandler
template <typename REAL>
PatchTableBuilder::StencilTablePtr
PatchTableBuilder::LocalPointHelper::acquireStencilTable(
StencilTableHandler& stencilTableMember) {
StencilTablePtr& stencilTableMember) {
StencilTableHandler stencilTable = stencilTableMember;
StencilTableReal<REAL> * stencilTable = stencilTableMember.Get<REAL>();
if (stencilTable.IsSet()) {
if (stencilTable.Size() > 0) {
if (stencilTable.IsDouble()) {
stencilTable.Get<double>()->finalize();
} else {
stencilTable.Get<float>()->finalize();
}
if (stencilTable) {
if (stencilTable->GetNumStencils() > 0) {
stencilTable->finalize();
} else {
stencilTable.Delete();
stencilTable.Clear();
delete stencilTable;
stencilTable = 0;
}
}
stencilTableMember.Clear();
return stencilTable;
stencilTableMember.Set();
return StencilTablePtr(stencilTable);
}
PatchTableBuilder::LocalPointHelper::~LocalPointHelper() {
_stencilTable.Delete();
_stencilTableVarying.Delete();
if (_options.doubleStencilTable) {
delete _stencilTable.Get<double>();
delete _stencilTableVarying.Get<double>();
} else {
delete _stencilTable.Get<float>();
delete _stencilTableVarying.Get<float>();
}
}
Index
@ -1727,11 +1732,11 @@ PatchTableBuilder::LocalPointHelper::AppendLocalPatchPoints(
bool shareLocalPointsForThisPatch = (shareBitsPerPoint != 0);
int const * varyingIndices = 0;
if (_stencilTableVarying.IsSet()) {
if (_stencilTableVarying) {
varyingIndices = GetVaryingIndicesPerType(patchType);
}
bool applyVertexStencils = _stencilTable.IsSet();
bool applyVertexStencils = (_stencilTable.Get<REAL>() != 0);
bool applyVaryingStencils = (varyingIndices != 0);
//