mirror of
https://github.com/paboyle/Grid.git
synced 2025-04-09 21:50:45 +01:00
Hadrons: DiskVector Eigen specialisation with binary I/O and sha256 correctness check
This commit is contained in:
parent
936eaac8e1
commit
efc0c65056
@ -34,6 +34,12 @@ See the full license in the file "LICENSE" in the top level distribution directo
|
|||||||
#include <ftw.h>
|
#include <ftw.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#ifdef DV_DEBUG
|
||||||
|
#define DV_DEBUG_MSG(dv, stream) LOG(Debug) << "diskvector " << (dv) << ": " << stream << std::endl
|
||||||
|
#else
|
||||||
|
#define DV_DEBUG_MSG(dv, stream)
|
||||||
|
#endif
|
||||||
|
|
||||||
BEGIN_HADRONS_NAMESPACE
|
BEGIN_HADRONS_NAMESPACE
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
@ -56,9 +62,7 @@ public:
|
|||||||
// write to disk and cache
|
// write to disk and cache
|
||||||
T &operator=(const T &obj) const
|
T &operator=(const T &obj) const
|
||||||
{
|
{
|
||||||
#ifdef DV_DEBUG
|
DV_DEBUG_MSG(&master_, "writing to " << i_);
|
||||||
LOG(Debug) << "diskvector " << &master_ << ": writing to " << i_ << std::endl;
|
|
||||||
#endif
|
|
||||||
master_.cacheInsert(i_, obj);
|
master_.cacheInsert(i_, obj);
|
||||||
master_.save(master_.filename(i_), obj);
|
master_.save(master_.filename(i_), obj);
|
||||||
|
|
||||||
@ -82,6 +86,8 @@ public:
|
|||||||
virtual ~DiskVectorBase(void);
|
virtual ~DiskVectorBase(void);
|
||||||
const T & operator[](const unsigned int i) const;
|
const T & operator[](const unsigned int i) const;
|
||||||
RwAccessHelper operator[](const unsigned int i);
|
RwAccessHelper operator[](const unsigned int i);
|
||||||
|
double hitRatio(void) const;
|
||||||
|
void resetStat(void);
|
||||||
private:
|
private:
|
||||||
virtual void load(T &obj, const std::string filename) const = 0;
|
virtual void load(T &obj, const std::string filename) const = 0;
|
||||||
virtual void save(const std::string filename, const T &obj) const = 0;
|
virtual void save(const std::string filename, const T &obj) const = 0;
|
||||||
@ -93,6 +99,7 @@ private:
|
|||||||
private:
|
private:
|
||||||
std::string dirname_;
|
std::string dirname_;
|
||||||
unsigned int size_, cacheSize_;
|
unsigned int size_, cacheSize_;
|
||||||
|
double access_{0.}, hit_{0.};
|
||||||
bool clean_;
|
bool clean_;
|
||||||
// using pointers to allow modifications when class is const
|
// using pointers to allow modifications when class is const
|
||||||
// semantic: const means data unmodified, but cache modification allowed
|
// semantic: const means data unmodified, but cache modification allowed
|
||||||
@ -115,6 +122,7 @@ private:
|
|||||||
|
|
||||||
read(reader, basename(filename), obj);
|
read(reader, basename(filename), obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void save(const std::string filename, const T &obj) const
|
virtual void save(const std::string filename, const T &obj) const
|
||||||
{
|
{
|
||||||
Writer writer(filename);
|
Writer writer(filename);
|
||||||
@ -123,13 +131,70 @@ private:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* Specialisation for Eigen matrices *
|
||||||
|
******************************************************************************/
|
||||||
|
template <typename T>
|
||||||
|
using EigenDiskVectorMat = Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic>;
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
class EigenDiskVector: public DiskVectorBase<EigenDiskVectorMat<T>>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
using DiskVectorBase<EigenDiskVectorMat<T>>::DiskVectorBase;
|
||||||
|
typedef EigenDiskVectorMat<T> Matrix;
|
||||||
|
private:
|
||||||
|
virtual void load(EigenDiskVectorMat<T> &obj, const std::string filename) const
|
||||||
|
{
|
||||||
|
std::ifstream f(filename, std::ios::binary);
|
||||||
|
std::vector<unsigned char> hash(SHA256_DIGEST_LENGTH);
|
||||||
|
Eigen::Index nRow, nCol;
|
||||||
|
size_t matSize;
|
||||||
|
double t;
|
||||||
|
|
||||||
|
f.read(reinterpret_cast<char *>(hash.data()), hash.size()*sizeof(unsigned char));
|
||||||
|
f.read(reinterpret_cast<char *>(&nRow), sizeof(Eigen::Index));
|
||||||
|
f.read(reinterpret_cast<char *>(&nCol), sizeof(Eigen::Index));
|
||||||
|
obj.resize(nRow, nCol);
|
||||||
|
matSize = nRow*nCol*sizeof(T);
|
||||||
|
t = -usecond();
|
||||||
|
f.read(reinterpret_cast<char *>(obj.data()), matSize);
|
||||||
|
t += usecond();
|
||||||
|
DV_DEBUG_MSG(this, "Eigen read " << matSize/t*1.0e6/1024/1024 << " MB/s");
|
||||||
|
auto check = GridChecksum::sha256(obj.data(), matSize);
|
||||||
|
DV_DEBUG_MSG(this, "Eigen sha256 " << GridChecksum::sha256_string(check));
|
||||||
|
if (hash != check)
|
||||||
|
{
|
||||||
|
HADRONS_ERROR(Io, "checksum failed")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void save(const std::string filename, const EigenDiskVectorMat<T> &obj) const
|
||||||
|
{
|
||||||
|
std::ofstream f(filename, std::ios::binary);
|
||||||
|
std::vector<unsigned char> hash(SHA256_DIGEST_LENGTH);
|
||||||
|
Eigen::Index nRow, nCol;
|
||||||
|
size_t matSize;
|
||||||
|
double t;
|
||||||
|
|
||||||
|
nRow = obj.rows();
|
||||||
|
nCol = obj.cols();
|
||||||
|
matSize = nRow*nCol*sizeof(T);
|
||||||
|
hash = GridChecksum::sha256(obj.data(), matSize);
|
||||||
|
DV_DEBUG_MSG(this, "Eigen sha256 " << GridChecksum::sha256_string(hash));
|
||||||
|
f.write(reinterpret_cast<char *>(hash.data()), hash.size()*sizeof(unsigned char));
|
||||||
|
f.write(reinterpret_cast<char *>(&nRow), sizeof(Eigen::Index));
|
||||||
|
f.write(reinterpret_cast<char *>(&nCol), sizeof(Eigen::Index));
|
||||||
|
t = -usecond();
|
||||||
|
f.write(reinterpret_cast<const char *>(obj.data()), matSize);
|
||||||
|
t += usecond();
|
||||||
|
DV_DEBUG_MSG(this, "Eigen write " << matSize/t*1.0e6/1024/1024 << " MB/s");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* DiskVectorBase implementation *
|
* DiskVectorBase implementation *
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
#ifdef DV_DEBUG
|
|
||||||
#define DV_DEBUG_MSG(stream) LOG(Debug) << "diskvector " << this << ": " << stream << std::endl
|
|
||||||
#endif
|
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
DiskVectorBase<T>::DiskVectorBase(const std::string dirname,
|
DiskVectorBase<T>::DiskVectorBase(const std::string dirname,
|
||||||
const unsigned int size,
|
const unsigned int size,
|
||||||
@ -160,28 +225,29 @@ DiskVectorBase<T>::~DiskVectorBase(void)
|
|||||||
template <typename T>
|
template <typename T>
|
||||||
const T & DiskVectorBase<T>::operator[](const unsigned int i) const
|
const T & DiskVectorBase<T>::operator[](const unsigned int i) const
|
||||||
{
|
{
|
||||||
auto &cache = *cachePtr_;
|
auto &cache = *cachePtr_;
|
||||||
auto &loads = *loadsPtr_;
|
auto &loads = *loadsPtr_;
|
||||||
|
|
||||||
DV_DEBUG_MSG("accessing " << i << " (RO)");
|
DV_DEBUG_MSG(this, "accessing " << i << " (RO)");
|
||||||
|
|
||||||
if (i >= size_)
|
if (i >= size_)
|
||||||
{
|
{
|
||||||
HADRONS_ERROR(Size, "index out of range");
|
HADRONS_ERROR(Size, "index out of range");
|
||||||
}
|
}
|
||||||
|
const_cast<double &>(access_)++;
|
||||||
if (cache.find(i) == cache.end())
|
if (cache.find(i) == cache.end())
|
||||||
{
|
{
|
||||||
// cache miss
|
// cache miss
|
||||||
DV_DEBUG_MSG("cache miss");
|
DV_DEBUG_MSG(this, "cache miss");
|
||||||
fetch(i);
|
fetch(i);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
DV_DEBUG_MSG("cache hit");
|
DV_DEBUG_MSG(this, "cache hit");
|
||||||
|
|
||||||
auto pos = std::find(loads.begin(), loads.end(), i);
|
auto pos = std::find(loads.begin(), loads.end(), i);
|
||||||
|
|
||||||
|
const_cast<double &>(hit_)++;
|
||||||
loads.erase(pos);
|
loads.erase(pos);
|
||||||
loads.push_back(i);
|
loads.push_back(i);
|
||||||
}
|
}
|
||||||
@ -193,7 +259,7 @@ const T & DiskVectorBase<T>::operator[](const unsigned int i) const
|
|||||||
{
|
{
|
||||||
msg += std::to_string(p) + " ";
|
msg += std::to_string(p) + " ";
|
||||||
}
|
}
|
||||||
DV_DEBUG_MSG("in cache: " << msg);
|
DV_DEBUG_MSG(this, "in cache: " << msg);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return cache.at(i);
|
return cache.at(i);
|
||||||
@ -202,7 +268,7 @@ const T & DiskVectorBase<T>::operator[](const unsigned int i) const
|
|||||||
template <typename T>
|
template <typename T>
|
||||||
typename DiskVectorBase<T>::RwAccessHelper DiskVectorBase<T>::operator[](const unsigned int i)
|
typename DiskVectorBase<T>::RwAccessHelper DiskVectorBase<T>::operator[](const unsigned int i)
|
||||||
{
|
{
|
||||||
DV_DEBUG_MSG("accessing " << i << " (RW)");
|
DV_DEBUG_MSG(this, "accessing " << i << " (RW)");
|
||||||
|
|
||||||
if (i >= size_)
|
if (i >= size_)
|
||||||
{
|
{
|
||||||
@ -212,6 +278,19 @@ typename DiskVectorBase<T>::RwAccessHelper DiskVectorBase<T>::operator[](const u
|
|||||||
return RwAccessHelper(*this, i);
|
return RwAccessHelper(*this, i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
double DiskVectorBase<T>::hitRatio(void) const
|
||||||
|
{
|
||||||
|
return hit_/access_;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
void DiskVectorBase<T>::resetStat(void)
|
||||||
|
{
|
||||||
|
access_ = 0.;
|
||||||
|
hit_ = 0.;
|
||||||
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
std::string DiskVectorBase<T>::filename(const unsigned int i) const
|
std::string DiskVectorBase<T>::filename(const unsigned int i) const
|
||||||
{
|
{
|
||||||
@ -226,7 +305,7 @@ void DiskVectorBase<T>::evict(void) const
|
|||||||
|
|
||||||
if (cache.size() >= cacheSize_)
|
if (cache.size() >= cacheSize_)
|
||||||
{
|
{
|
||||||
DV_DEBUG_MSG("evicting " << loads.front());
|
DV_DEBUG_MSG(this, "evicting " << loads.front());
|
||||||
cache.erase(loads.front());
|
cache.erase(loads.front());
|
||||||
loads.pop_front();
|
loads.pop_front();
|
||||||
}
|
}
|
||||||
@ -239,7 +318,7 @@ void DiskVectorBase<T>::fetch(const unsigned int i) const
|
|||||||
auto &loads = *loadsPtr_;
|
auto &loads = *loadsPtr_;
|
||||||
struct stat s;
|
struct stat s;
|
||||||
|
|
||||||
DV_DEBUG_MSG("loading " << i << " from disk");
|
DV_DEBUG_MSG(this, "loading " << i << " from disk");
|
||||||
|
|
||||||
evict();
|
evict();
|
||||||
if(stat(filename(i).c_str(), &s) != 0)
|
if(stat(filename(i).c_str(), &s) != 0)
|
||||||
@ -267,7 +346,7 @@ void DiskVectorBase<T>::cacheInsert(const unsigned int i, const T &obj) const
|
|||||||
{
|
{
|
||||||
msg += std::to_string(p) + " ";
|
msg += std::to_string(p) + " ";
|
||||||
}
|
}
|
||||||
DV_DEBUG_MSG("in cache: " << msg);
|
DV_DEBUG_MSG(this, "in cache: " << msg);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -91,6 +91,22 @@ int main(int argc, char *argv[])
|
|||||||
v13r = v[13];
|
v13r = v[13];
|
||||||
LOG(Message) << "v[13] correct? "
|
LOG(Message) << "v[13] correct? "
|
||||||
<< ((v13r == v13w) ? "yes" : "no" ) << std::endl;
|
<< ((v13r == v13w) ? "yes" : "no" ) << std::endl;
|
||||||
|
LOG(Message) << "hit ratio " << v.hitRatio() << std::endl;
|
||||||
|
|
||||||
|
EigenDiskVector<ComplexD> w("eigendiskvector_test", 1000, 4);
|
||||||
|
EigenDiskVector<ComplexD>::Matrix m,n;
|
||||||
|
|
||||||
|
w[2] = EigenDiskVectorMat<ComplexD>::Random(2000, 2000);
|
||||||
|
m = w[2];
|
||||||
|
w[3] = EigenDiskVectorMat<ComplexD>::Random(2000, 2000);
|
||||||
|
w[4] = EigenDiskVectorMat<ComplexD>::Random(2000, 2000);
|
||||||
|
w[5] = EigenDiskVectorMat<ComplexD>::Random(2000, 2000);
|
||||||
|
w[6] = EigenDiskVectorMat<ComplexD>::Random(2000, 2000);
|
||||||
|
w[7] = EigenDiskVectorMat<ComplexD>::Random(2000, 2000);
|
||||||
|
n = w[2];
|
||||||
|
LOG(Message) << "w[2] correct? "
|
||||||
|
<< ((m == n) ? "yes" : "no" ) << std::endl;
|
||||||
|
LOG(Message) << "hit ratio " << w.hitRatio() << std::endl;
|
||||||
|
|
||||||
Grid_finalize();
|
Grid_finalize();
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user