Replace memset with fill to work for non-trivial scalars.

For custom scalars, zero is not necessarily represented by
a zeroed-out memory block (e.g. gnu MPFR). We therefore
cannot rely on `memset` if we want to fill a matrix or tensor
with zeroes. Instead, we should rely on `fill`, which for trivial
types does end up getting converted to a `memset` under-the-hood
(at least with gcc/clang).

Requires adding a `fill(begin, end, v)` to `TensorDevice`.

Replaced all potentially bad instances of memset with fill.

Fixes #2245.
This commit is contained in:
Antonio Sanchez
2021-05-11 09:52:00 -07:00
committed by Rasmus Munk Larsen
parent e9c9a3130b
commit 1e6c6c1576
18 changed files with 229 additions and 61 deletions

View File

@@ -375,8 +375,8 @@ public:
/** Removes all non zeros */
inline void setZero() {
m_data.clear();
memset(m_colStartIndex, 0, (m_outerSize + 1) * sizeof (Index));
memset(m_rowStartIndex, 0, (m_outerSize + 1) * sizeof (Index));
std::fill_n(m_colStartIndex, m_outerSize + 1, Index(0));
std::fill_n(m_rowStartIndex, m_outerSize + 1, Index(0));
}
/** \returns the number of non zero coefficients */
@@ -435,7 +435,7 @@ public:
}
//zeros new data
memset(this->_upperPtr() + start, 0, (bandIncrement - 1) * sizeof (Scalar));
std::fill_n(this->_upperPtr() + start, bandIncrement - 1, Scalar(0));
return m_data.upper(m_colStartIndex[inner]);
} else {
@@ -466,7 +466,7 @@ public:
}
//zeros new data
memset(this->_lowerPtr() + start, 0, (bandIncrement - 1) * sizeof (Scalar));
std::fill_n(this->_lowerPtr() + start, bandIncrement - 1, Scalar(0));
return m_data.lower(m_rowStartIndex[outer]);
} else {
return m_data.lower(m_rowStartIndex[outer] + inner - (outer - m_data.lowerProfile(outer)));
@@ -493,7 +493,7 @@ public:
for (Index innerIdx = inner + 1; innerIdx < outerSize() + 1; innerIdx++) {
m_rowStartIndex[innerIdx] += bandIncrement;
}
memset(this->_upperPtr() + m_rowStartIndex[inner] + previousProfile + 1, 0, (bandIncrement - 1) * sizeof (Scalar));
std::fill_n(this->_upperPtr() + m_rowStartIndex[inner] + previousProfile + 1, bandIncrement - 1, Scalar(0));
return m_data.upper(m_rowStartIndex[inner] + m_data.upperProfile(inner));
} else {
return m_data.upper(m_rowStartIndex[inner] + (outer - inner));
@@ -520,7 +520,7 @@ public:
for (Index innerIdx = outer + 1; innerIdx < outerSize() + 1; innerIdx++) {
m_colStartIndex[innerIdx] += bandIncrement;
}
memset(this->_lowerPtr() + m_colStartIndex[outer] + previousProfile + 1, 0, (bandIncrement - 1) * sizeof (Scalar));
std::fill_n(this->_lowerPtr() + m_colStartIndex[outer] + previousProfile + 1, bandIncrement - 1, Scalar(0));
return m_data.lower(m_colStartIndex[outer] + m_data.lowerProfile(outer));
} else {
return m_data.lower(m_colStartIndex[outer] + (inner - outer));
@@ -619,8 +619,8 @@ public:
m_data.clear();
m_outerSize = diagSize;
memset(m_colStartIndex, 0, (cols + 1) * sizeof (Index));
memset(m_rowStartIndex, 0, (rows + 1) * sizeof (Index));
std::fill_n(m_colStartIndex, cols + 1, Index(0));
std::fill_n(m_rowStartIndex, rows + 1, Index(0));
}
void resizeNonZeros(Index size) {

View File

@@ -187,11 +187,11 @@ public:
}
inline void reset() {
memset(m_diag, 0, m_diagSize * sizeof (Scalar));
memset(m_upper, 0, m_upperSize * sizeof (Scalar));
memset(m_lower, 0, m_lowerSize * sizeof (Scalar));
memset(m_upperProfile, 0, m_diagSize * sizeof (Index));
memset(m_lowerProfile, 0, m_diagSize * sizeof (Index));
std::fill_n(m_diag, m_diagSize, Scalar(0));
std::fill_n(m_upper, m_upperSize, Scalar(0));
std::fill_n(m_lower, m_lowerSize, Scalar(0));
std::fill_n(m_upperProfile, m_diagSize, Index(0));
std::fill_n(m_lowerProfile, m_diagSize, Index(0));
}
void prune(Scalar reference, RealScalar epsilon = dummy_precision<RealScalar>()) {