48#include "brains/BlockSnapshotManager.hpp"
60 BlockSnapshotManager::BlockSnapshotManager(
61 SimInfo* info,
const std::string& filename,
int atomStorageLayout,
62 int rigidBodyStorageLayout,
int cutoffGroupStorageLayout,
63 long long int memSize,
int blockCapacity) :
65 cutoffGroupStorageLayout),
66 blockCapacity_(blockCapacity), memSize_(memSize),
67 activeBlocks_(blockCapacity_, -1), activeRefCount_(blockCapacity_, 0) {
68 nAtoms_ = info->getNGlobalAtoms();
69 nRigidBodies_ = info->getNGlobalRigidBodies();
70 nCutoffGroups_ = info->getNCutoffGroups();
71 usePBC_ = info->getSimParams()->getUsePeriodicBoundaryConditions();
78 int bytesPerAtom = DataStorage::getBytesPerStuntDouble(atomStorageLayout);
79 int bytesPerRigidBody =
80 DataStorage::getBytesPerStuntDouble(rigidBodyStorageLayout);
81 int bytesPerCutoffGroup =
82 DataStorage::getBytesPerStuntDouble(DataStorage::dslPosition);
84 int bytesPerFrameData = Snapshot::getFrameDataSize();
86 nRigidBodies_ * bytesPerRigidBody + nAtoms_ * bytesPerAtom +
87 nCutoffGroups_ * bytesPerCutoffGroup + bytesPerFrameData;
91 RealType frameCapacity = (RealType)memSize_ / (RealType)bytesPerFrame;
95 nSnapshotPerBlock_ = int(frameCapacity) / blockCapacity_;
96 if (nSnapshotPerBlock_ <= 0) {
97 std::cerr <<
"not enough memory to hold two configs!\n";
99 reader_ =
new DumpReader(info, filename);
100 nframes_ = reader_->getNFrames();
101 int nblocks = nframes_ / nSnapshotPerBlock_;
102 if (nframes_ %
int(nSnapshotPerBlock_) != 0) { ++nblocks; }
104 for (
int i = 0; i < nblocks; ++i) {
106 SnapshotBlock(i * nSnapshotPerBlock_, (i + 1) * nSnapshotPerBlock_));
110 blocks_.back().second = nframes_;
112 snapshots_.insert(snapshots_.begin(), nframes_,
113 static_cast<Snapshot*
>(NULL));
115 std::cout <<
"-----------------------------------------------------\n";
116 std::cout <<
"BlockSnapshotManager memory report:\n";
125 std::cout <<
"Memory requested for OpenMD:\t" << (
unsigned long)memSize_
126 <<
" bytes" << std::endl;
127 std::cout <<
" Bytes per FrameData:\t"
128 << (
unsigned long)bytesPerFrameData << std::endl;
129 std::cout <<
" Bytes per Atom:\t" << (
unsigned long)bytesPerAtom
131 std::cout <<
" Bytes per RigidBody:\t"
132 << (
unsigned long)bytesPerRigidBody << std::endl;
133 std::cout <<
" Bytes per Cutoff Group:\t"
134 << (
unsigned long)bytesPerCutoffGroup << std::endl;
135 std::cout <<
" Bytes per Frame:\t"
136 << (
unsigned long)bytesPerFrame << std::endl;
137 std::cout <<
" Frame Capacity:\t"
138 << (
unsigned long)frameCapacity << std::endl;
139 std::cout <<
" Frames in trajectory:\t" << (
unsigned long)nframes_
141 std::cout <<
" Snapshots per Block:\t"
142 << (
unsigned long)nSnapshotPerBlock_ << std::endl;
143 std::cout <<
" Total number of Blocks:\t" << (
unsigned long)nblocks
145 std::cout <<
"-----------------------------------------------------"
149 BlockSnapshotManager::~BlockSnapshotManager() {
150 currentSnapshot_ = NULL;
151 previousSnapshot_ = NULL;
155 std::vector<int>::iterator i;
156 for (i = activeBlocks_.begin(); i != activeBlocks_.end(); ++i) {
157 if (*i != -1) { unloadBlock(*i); }
161 Snapshot* BlockSnapshotManager::getSnapshot(
int id) {
162 currentSnapshot_ = snapshots_[id];
163 return snapshots_[id];
166 int BlockSnapshotManager::getNActiveBlocks() {
167 return std::count_if(activeBlocks_.begin(), activeBlocks_.end(),
168 [](
int val) { return val != -1; });
171 bool BlockSnapshotManager::loadBlock(
int block) {
172 std::vector<int>::iterator i = findActiveBlock(block);
173 bool loadSuccess(
false);
174 if (i != activeBlocks_.end()) {
177 ++activeRefCount_[i - activeBlocks_.begin()];
179 }
else if (getNActiveBlocks() < blockCapacity_) {
184 }
else if (hasZeroRefBlock()) {
187 int zeroRefBlock = getFirstZeroRefBlock();
188 assert(zeroRefBlock != -1);
189 internalUnload(zeroRefBlock);
199 bool BlockSnapshotManager::unloadBlock(
int block) {
201 std::vector<int>::iterator i = findActiveBlock(block);
203 if (i != activeBlocks_.end()) {
204 --activeRefCount_[i - activeBlocks_.begin()];
205 if (activeRefCount_[i - activeBlocks_.begin()] < 0) {
207 activeRefCount_[i - activeBlocks_.begin()] = 0;
210 if (activeRefCount_[i - activeBlocks_.begin()] == 0) {
211 internalUnload(block);
214 unloadSuccess =
true;
216 unloadSuccess =
false;
219 return unloadSuccess;
222 void BlockSnapshotManager::internalLoad(
int block) {
223 for (
int i = blocks_[block].first; i < blocks_[block].second; ++i) {
224 snapshots_[i] = loadFrame(i);
227 std::vector<int>::iterator j;
228 j = std::find(activeBlocks_.begin(), activeBlocks_.end(), -1);
229 assert(j != activeBlocks_.end());
231 ++activeRefCount_[j - activeBlocks_.begin()];
234 void BlockSnapshotManager::internalUnload(
int block) {
235 for (
int i = blocks_[block].first; i < blocks_[block].second; ++i) {
236 delete snapshots_[i];
237 snapshots_[i] = NULL;
239 std::vector<int>::iterator j;
240 j = std::find(activeBlocks_.begin(), activeBlocks_.end(), block);
241 assert(j != activeBlocks_.end());
245 bool BlockSnapshotManager::hasZeroRefBlock() {
246 return std::find(activeRefCount_.begin(), activeRefCount_.end(), 0) !=
247 activeRefCount_.end() ?
252 int BlockSnapshotManager::getFirstZeroRefBlock() {
253 std::vector<int>::iterator i =
254 std::find(activeRefCount_.begin(), activeRefCount_.end(), 0);
255 return i != activeRefCount_.end() ?
256 activeBlocks_[i - activeRefCount_.begin()] :
260 std::vector<int> BlockSnapshotManager::getActiveBlocks() {
261 std::vector<int> result;
263 activeBlocks_.begin(), activeBlocks_.end(), std::back_inserter(result),
264 std::bind(std::not_equal_to<int>(), std::placeholders::_1, -1));
268 Snapshot* BlockSnapshotManager::loadFrame(
int frame) {
269 Snapshot* snapshot =
new Snapshot(
270 nAtoms_, nRigidBodies_, nCutoffGroups_, getAtomStorageLayout(),
271 getRigidBodyStorageLayout(), getCutoffGroupStorageLayout(), usePBC_);
272 snapshot->setID(frame);
273 snapshot->clearDerivedProperties();
275 currentSnapshot_ = snapshot;
276 reader_->readFrame(frame);
281 int BlockSnapshotManager::getNFrames() {
return reader_->getNFrames(); }
283 void BlockSnapshotManager::needCOMprops(
bool ncp) {
284 reader_->setNeedCOMprops(ncp);
One of the heavy-weight classes of OpenMD, SimInfo maintains objects and variables relating to the cu...
SnapshotManager class is an abstract class which maintains a series of snapshots.
This basic Periodic Table class was originally taken from the data.cpp file in OpenBabel.