45#include "brains/BlockSnapshotManager.hpp"
57 BlockSnapshotManager::BlockSnapshotManager(
58 SimInfo* info,
const std::string& filename,
int atomStorageLayout,
59 int rigidBodyStorageLayout,
int cutoffGroupStorageLayout,
60 long long int memSize,
int blockCapacity) :
61 SnapshotManager(atomStorageLayout, rigidBodyStorageLayout,
62 cutoffGroupStorageLayout),
63 blockCapacity_(blockCapacity), memSize_(memSize),
64 activeBlocks_(blockCapacity_, -1), activeRefCount_(blockCapacity_, 0) {
65 nAtoms_ = info->getNGlobalAtoms();
66 nRigidBodies_ = info->getNGlobalRigidBodies();
67 nCutoffGroups_ = info->getNCutoffGroups();
68 usePBC_ = info->getSimParams()->getUsePeriodicBoundaryConditions();
75 int bytesPerAtom = DataStorage::getBytesPerStuntDouble(atomStorageLayout);
76 int bytesPerRigidBody =
77 DataStorage::getBytesPerStuntDouble(rigidBodyStorageLayout);
78 int bytesPerCutoffGroup =
79 DataStorage::getBytesPerStuntDouble(DataStorage::dslPosition);
81 int bytesPerFrameData = Snapshot::getFrameDataSize();
83 nRigidBodies_ * bytesPerRigidBody + nAtoms_ * bytesPerAtom +
84 nCutoffGroups_ * bytesPerCutoffGroup + bytesPerFrameData;
88 RealType frameCapacity = (RealType)memSize_ / (RealType)bytesPerFrame;
92 nSnapshotPerBlock_ = int(frameCapacity) / blockCapacity_;
93 if (nSnapshotPerBlock_ <= 0) {
94 std::cerr <<
"not enough memory to hold two configs!\n";
96 reader_ =
new DumpReader(info, filename);
97 nframes_ = reader_->getNFrames();
98 int nblocks = nframes_ / nSnapshotPerBlock_;
99 if (nframes_ %
int(nSnapshotPerBlock_) != 0) { ++nblocks; }
101 for (
int i = 0; i < nblocks; ++i) {
103 SnapshotBlock(i * nSnapshotPerBlock_, (i + 1) * nSnapshotPerBlock_));
107 blocks_.back().second = nframes_;
109 snapshots_.insert(snapshots_.begin(), nframes_,
110 static_cast<Snapshot*
>(NULL));
112 std::cout <<
"-----------------------------------------------------\n";
113 std::cout <<
"BlockSnapshotManager memory report:\n";
122 std::cout <<
"Memory requested for OpenMD:\t" << (
unsigned long)memSize_
123 <<
" bytes" << std::endl;
124 std::cout <<
" Bytes per FrameData:\t"
125 << (
unsigned long)bytesPerFrameData << std::endl;
126 std::cout <<
" Bytes per Atom:\t" << (
unsigned long)bytesPerAtom
128 std::cout <<
" Bytes per RigidBody:\t"
129 << (
unsigned long)bytesPerRigidBody << std::endl;
130 std::cout <<
" Bytes per Cutoff Group:\t"
131 << (
unsigned long)bytesPerCutoffGroup << std::endl;
132 std::cout <<
" Bytes per Frame:\t"
133 << (
unsigned long)bytesPerFrame << std::endl;
134 std::cout <<
" Frame Capacity:\t"
135 << (
unsigned long)frameCapacity << std::endl;
136 std::cout <<
" Frames in trajectory:\t" << (
unsigned long)nframes_
138 std::cout <<
" Snapshots per Block:\t"
139 << (
unsigned long)nSnapshotPerBlock_ << std::endl;
140 std::cout <<
" Total number of Blocks:\t" << (
unsigned long)nblocks
142 std::cout <<
"-----------------------------------------------------"
146 BlockSnapshotManager::~BlockSnapshotManager() {
147 currentSnapshot_ = NULL;
148 previousSnapshot_ = NULL;
152 std::vector<int>::iterator i;
153 for (i = activeBlocks_.begin(); i != activeBlocks_.end(); ++i) {
154 if (*i != -1) { unloadBlock(*i); }
158 Snapshot* BlockSnapshotManager::getSnapshot(
int id) {
159 currentSnapshot_ = snapshots_[id];
160 return snapshots_[id];
163 int BlockSnapshotManager::getNActiveBlocks() {
164 return std::count_if(activeBlocks_.begin(), activeBlocks_.end(),
165 [](
int val) { return val != -1; });
168 bool BlockSnapshotManager::loadBlock(
int block) {
169 std::vector<int>::iterator i = findActiveBlock(block);
170 bool loadSuccess(
false);
171 if (i != activeBlocks_.end()) {
174 ++activeRefCount_[i - activeBlocks_.begin()];
176 }
else if (getNActiveBlocks() < blockCapacity_) {
181 }
else if (hasZeroRefBlock()) {
184 int zeroRefBlock = getFirstZeroRefBlock();
185 assert(zeroRefBlock != -1);
186 internalUnload(zeroRefBlock);
196 bool BlockSnapshotManager::unloadBlock(
int block) {
198 std::vector<int>::iterator i = findActiveBlock(block);
200 if (i != activeBlocks_.end()) {
201 --activeRefCount_[i - activeBlocks_.begin()];
202 if (activeRefCount_[i - activeBlocks_.begin()] < 0) {
204 activeRefCount_[i - activeBlocks_.begin()] = 0;
207 if (activeRefCount_[i - activeBlocks_.begin()] == 0) {
208 internalUnload(block);
211 unloadSuccess =
true;
213 unloadSuccess =
false;
216 return unloadSuccess;
219 void BlockSnapshotManager::internalLoad(
int block) {
220 for (
int i = blocks_[block].first; i < blocks_[block].second; ++i) {
221 snapshots_[i] = loadFrame(i);
224 std::vector<int>::iterator j;
225 j = std::find(activeBlocks_.begin(), activeBlocks_.end(), -1);
226 assert(j != activeBlocks_.end());
228 ++activeRefCount_[j - activeBlocks_.begin()];
231 void BlockSnapshotManager::internalUnload(
int block) {
232 for (
int i = blocks_[block].first; i < blocks_[block].second; ++i) {
233 delete snapshots_[i];
234 snapshots_[i] = NULL;
236 std::vector<int>::iterator j;
237 j = std::find(activeBlocks_.begin(), activeBlocks_.end(), block);
238 assert(j != activeBlocks_.end());
242 bool BlockSnapshotManager::hasZeroRefBlock() {
243 return std::find(activeRefCount_.begin(), activeRefCount_.end(), 0) !=
244 activeRefCount_.end() ?
249 int BlockSnapshotManager::getFirstZeroRefBlock() {
250 std::vector<int>::iterator i =
251 std::find(activeRefCount_.begin(), activeRefCount_.end(), 0);
252 return i != activeRefCount_.end() ?
253 activeBlocks_[i - activeRefCount_.begin()] :
257 std::vector<int> BlockSnapshotManager::getActiveBlocks() {
258 std::vector<int> result;
260 activeBlocks_.begin(), activeBlocks_.end(), std::back_inserter(result),
261 std::bind(std::not_equal_to<int>(), std::placeholders::_1, -1));
265 Snapshot* BlockSnapshotManager::loadFrame(
int frame) {
266 Snapshot* snapshot =
new Snapshot(
267 nAtoms_, nRigidBodies_, nCutoffGroups_, getAtomStorageLayout(),
268 getRigidBodyStorageLayout(), getCutoffGroupStorageLayout(), usePBC_);
269 snapshot->setID(frame);
270 snapshot->clearDerivedProperties();
272 currentSnapshot_ = snapshot;
273 reader_->readFrame(frame);
278 int BlockSnapshotManager::getNFrames() {
return reader_->getNFrames(); }
280 void BlockSnapshotManager::needCOMprops(
bool ncp) {
281 reader_->setNeedCOMprops(ncp);
This basic Periodic Table class was originally taken from the data.cpp file in OpenBabel.