ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/OpenMD/trunk/src/brains/BlockSnapshotManager.cpp
Revision: 1596
Committed: Mon Jul 25 17:30:53 2011 UTC (13 years, 9 months ago) by gezelter
File size: 9816 byte(s)
Log Message:
Updated the BlockSnapshotManager to use a specified memory footprint
in constructor and not to rely on physmem and residentMem to figure
out free memory. DynamicProps is the only program that uses the
BlockSnapshotManager, so substantial changes were needed there as
well.


File Contents

# User Rev Content
1 tim 318 /*
2     * Copyright (c) 2005 The University of Notre Dame. All Rights Reserved.
3     *
4     * The University of Notre Dame grants you ("Licensee") a
5     * non-exclusive, royalty free, license to use, modify and
6     * redistribute this software in source and binary code form, provided
7     * that the following conditions are met:
8     *
9 gezelter 1390 * 1. Redistributions of source code must retain the above copyright
10 tim 318 * notice, this list of conditions and the following disclaimer.
11     *
12 gezelter 1390 * 2. Redistributions in binary form must reproduce the above copyright
13 tim 318 * notice, this list of conditions and the following disclaimer in the
14     * documentation and/or other materials provided with the
15     * distribution.
16     *
17     * This software is provided "AS IS," without a warranty of any
18     * kind. All express or implied conditions, representations and
19     * warranties, including any implied warranty of merchantability,
20     * fitness for a particular purpose or non-infringement, are hereby
21     * excluded. The University of Notre Dame and its licensors shall not
22     * be liable for any damages suffered by licensee as a result of
23     * using, modifying or distributing the software or its
24     * derivatives. In no event will the University of Notre Dame or its
25     * licensors be liable for any lost revenue, profit or data, or for
26     * direct, indirect, special, consequential, incidental or punitive
27     * damages, however caused and regardless of the theory of liability,
28     * arising out of the use of or inability to use software, even if the
29     * University of Notre Dame has been advised of the possibility of
30     * such damages.
31 gezelter 1390 *
32     * SUPPORT OPEN SCIENCE! If you use OpenMD or its source code in your
33     * research, please cite the appropriate papers when you publish your
34     * work. Good starting points are:
35     *
36     * [1] Meineke, et al., J. Comp. Chem. 26, 252-271 (2005).
37     * [2] Fennell & Gezelter, J. Chem. Phys. 124, 234104 (2006).
38     * [3] Sun, Lin & Gezelter, J. Chem. Phys. 128, 24107 (2008).
39     * [4] Vardeman & Gezelter, in progress (2009).
40 tim 318 */
41     #include <algorithm>
42     #include "brains/BlockSnapshotManager.hpp"
43 gezelter 1596 // #include "utils/residentMem.h"
44     // #include "utils/physmem.h"
45 tim 324 #include "utils/Algorithm.hpp"
46 tim 318 #include "brains/SimInfo.hpp"
47     #include "io/DumpReader.hpp"
48    
49 gezelter 1390 namespace OpenMD {
50 gezelter 1596 BlockSnapshotManager::BlockSnapshotManager(SimInfo* info,
51     const std::string& filename,
52     int storageLayout,
53     long long int memSize,
54     int blockCapacity)
55     : SnapshotManager(storageLayout), info_(info), memSize_(memSize),
56     blockCapacity_(blockCapacity), activeBlocks_(blockCapacity_, -1),
57     activeRefCount_(blockCapacity_, 0) {
58 tim 318
59 gezelter 507 nAtoms_ = info->getNGlobalAtoms();
60     nRigidBodies_ = info->getNGlobalRigidBodies();
61 tim 318
62 gezelter 1596 // eliminate suspect calls to figure out free memory:
63     // RealType physMem = physmem_total();
64     // RealType rssMem = residentMem();
65     // RealType avaliablePhysMem = physMem - rssMem;
66 xsun 1215
67 gezelter 507 int bytesPerStuntDouble = DataStorage::getBytesPerStuntDouble(storageLayout);
68 tim 318
69 gezelter 507 int bytesPerFrame = (nRigidBodies_ + nAtoms_) * bytesPerStuntDouble;
70 tim 318
71 xsun 1215 // total number of frames that can fit in memory
72 gezelter 1596
73     //RealType frameCapacity = avaliablePhysMem / bytesPerFrame;
74     RealType frameCapacity = memSize_ / bytesPerFrame;
75 xsun 1215
76     // number of frames in each block given the need to hold multiple blocks
77     // in memory at the same time:
78     nSnapshotPerBlock_ = int(frameCapacity) / blockCapacity_;
79 gezelter 507 reader_ = new DumpReader(info, filename);
80     nframes_ = reader_->getNFrames();
81     int nblocks = nframes_ / nSnapshotPerBlock_;
82 xsun 1215 if (nframes_ % int(nSnapshotPerBlock_) != 0) {
83 tim 318 ++nblocks;
84 gezelter 507 }
85 tim 318
86 gezelter 507 for (int i = 0; i < nblocks; ++i) {
87 tim 337 blocks_.push_back(SnapshotBlock(i*nSnapshotPerBlock_, (i+1)*nSnapshotPerBlock_));
88 gezelter 507 }
89     //the last block may not have nSnapshotPerBlock frames, we need to consider this special situation
90     blocks_.back().second = nframes_;
91 tim 318
92 gezelter 507 snapshots_.insert(snapshots_.begin(), nframes_, static_cast<Snapshot*>(NULL));
93 tim 358
94 xsun 1215 std::cout << "-----------------------------------------------------"<<std::endl;
95     std::cout << "BlockSnapshotManager memory report:" << std::endl;
96     std::cout << "\n";
97 gezelter 1596 // std::cout << " Physical Memory available:\t" << (unsigned long)physMem << " bytes" <<std::endl;
98     //std::cout << " Resident Memory in use:\t" << (unsigned long)rssMem << " bytes" <<std::endl;
99     //std::cout << "Memory available for OpenMD:\t" << (unsigned long)avaliablePhysMem << " bytes" <<std::endl;
100     std::cout << "Memory requested for OpenMD:\t" << (unsigned long)memSize_ << " bytes" <<std::endl;
101 gezelter 1390 std::cout << " Bytes per StuntDouble:\t" << (unsigned long)bytesPerStuntDouble <<std::endl;
102     std::cout << " Bytes per Frame:\t" << (unsigned long)bytesPerFrame <<std::endl;
103     std::cout << " Frame Capacity:\t" << (unsigned long)frameCapacity <<std::endl;
104     std::cout << " Frames in trajectory:\t" << (unsigned long)nframes_ <<std::endl;
105     std::cout << " Snapshots per Block:\t" << (unsigned long)nSnapshotPerBlock_ <<std::endl;
106     std::cout << " Total number of Blocks:\t" << (unsigned long)nblocks << std::endl;
107 xsun 1215 std::cout << "-----------------------------------------------------"<<std::endl;
108 tim 318
109 gezelter 507 }
110 tim 318
111    
112 gezelter 507 BlockSnapshotManager::~BlockSnapshotManager() {
113 tim 318 currentSnapshot_ = NULL;
114     previousSnapshot_ = NULL;
115    
116     delete reader_;
117 tim 324
118     std::vector<int>::iterator i;
119     for (i = activeBlocks_.begin(); i != activeBlocks_.end(); ++i) {
120 gezelter 507 if (*i != -1) {
121     unloadBlock(*i);
122     }
123 tim 324 }
124 gezelter 507 }
125 tim 318
126 gezelter 1249 Snapshot* BlockSnapshotManager::getSnapshot(int id) {
127     currentSnapshot_ = snapshots_[id];
128     return snapshots_[id];
129     }
130 xsun 1215
131 gezelter 507 int BlockSnapshotManager::getNActiveBlocks() {
132 tim 347 #ifdef __RWSTD
133     int count = 0;
134     std::count_if(activeBlocks_.begin(), activeBlocks_.end(), std::bind2nd(std::not_equal_to<int>(), -1), count);
135     return count;
136     #else
137 tim 324 return std::count_if(activeBlocks_.begin(), activeBlocks_.end(), std::bind2nd(std::not_equal_to<int>(), -1));
138 tim 347 #endif
139 gezelter 507 }
140 tim 318
141    
142 tim 351
143 gezelter 507 bool BlockSnapshotManager::loadBlock(int block) {
144 tim 351 std::vector<int>::iterator i = findActiveBlock(block);
145 tim 318 bool loadSuccess;
146 tim 351 if (i != activeBlocks_.end()) {
147 gezelter 507 //if block is already in memory, just increast the reference count
148     ++activeRefCount_[i - activeBlocks_.begin()];
149     loadSuccess = true;
150 tim 318 } else if (getNActiveBlocks() < blockCapacity_){
151 gezelter 507 //if number of active blocks is less than the block capacity, just load it
152     internalLoad(block);
153     loadSuccess = true;
154 tim 351 } else if (hasZeroRefBlock() > 0) {
155 gezelter 507 //if already reach the block capacity, need to unload a block with 0 reference
156     int zeroRefBlock = getFirstZeroRefBlock();
157     assert(zeroRefBlock != -1);
158     internalUnload(zeroRefBlock);
159     internalLoad(block);
160 tim 351 } else {
161 gezelter 507 //reach the capacity and all blocks in memory are not zero reference
162     loadSuccess = false;
163 tim 318 }
164 tim 351
165 tim 318 return loadSuccess;
166 gezelter 507 }
167 tim 318
168 gezelter 507 bool BlockSnapshotManager::unloadBlock(int block) {
169 tim 318 bool unloadSuccess;
170 tim 351 std::vector<int>::iterator i = findActiveBlock(block);
171    
172     if (i != activeBlocks_.end()){
173 gezelter 507 --activeRefCount_[i - activeBlocks_.begin()];
174     if (activeRefCount_[i - activeBlocks_.begin()] < 0) {
175     //in case, unloadBlock called multiple times
176     activeRefCount_[i - activeBlocks_.begin()] = 0;
177     }
178 tim 351
179 gezelter 507 unloadSuccess = true;
180 tim 351 } else {
181 gezelter 507 unloadSuccess = false;
182 tim 318 }
183 tim 324
184     return unloadSuccess;
185 gezelter 507 }
186 tim 318
187 gezelter 507 void BlockSnapshotManager::internalLoad(int block) {
188 tim 351
189     for (int i = blocks_[block].first; i < blocks_[block].second; ++i) {
190 gezelter 507 snapshots_[i] = loadFrame(i);
191 tim 351 }
192    
193     std::vector<int>::iterator j;
194     j = std::find(activeBlocks_.begin(), activeBlocks_.end(), -1);
195     assert(j != activeBlocks_.end());
196     *j = block;
197     ++activeRefCount_[j - activeBlocks_.begin()];
198 gezelter 507 }
199 tim 351
200 gezelter 507 void BlockSnapshotManager::internalUnload(int block) {
201 tim 351 for (int i = blocks_[block].first; i < blocks_[block].second; ++i) {
202 gezelter 507 delete snapshots_[i];
203     snapshots_[i] = NULL;
204 tim 351 }
205     std::vector<int>::iterator j;
206     j = std::find(activeBlocks_.begin(), activeBlocks_.end(), block);
207     assert(j != activeBlocks_.end());
208     *j = -1;
209 gezelter 507 }
210 tim 351
211 gezelter 507 bool BlockSnapshotManager::hasZeroRefBlock(){
212 tim 352 return std::find(activeRefCount_.begin(), activeRefCount_.end(), 0) != activeRefCount_.end() ? true : false;
213 gezelter 507 }
214 tim 351
215 gezelter 507 int BlockSnapshotManager::getFirstZeroRefBlock(){
216     std::vector<int>::iterator i = std::find(activeRefCount_.begin(), activeRefCount_.end(), 0);
217     return i != activeRefCount_.end() ? activeBlocks_[i - activeRefCount_.begin()] : -1;
218     }
219 tim 351
220 gezelter 507 std::vector<int> BlockSnapshotManager::getActiveBlocks() {
221 tim 318 std::vector<int> result;
222 gezelter 1390 OpenMD::copy_if(activeBlocks_.begin(), activeBlocks_.end(), std::back_inserter(result),
223 gezelter 507 std::bind2nd(std::not_equal_to<int>(), -1));
224 tim 324 return result;
225 gezelter 507 }
226 tim 318
227 gezelter 507 Snapshot* BlockSnapshotManager::loadFrame(int frame){
228 tim 318 Snapshot* snapshot = new Snapshot(nAtoms_, nRigidBodies_, getStorageLayout());
229     snapshot->setID(frame);
230 tim 324
231     /** @todo fixed me */
232     Snapshot* oldSnapshot = currentSnapshot_;
233     currentSnapshot_ = snapshot;
234 tim 318 reader_->readFrame(frame);
235 xsun 1215
236     // What was this for? It doesn't make sense!
237     //currentSnapshot_ = oldSnapshot;
238    
239 tim 318 return snapshot;
240 gezelter 507 }
241 tim 318
242 gezelter 507 int BlockSnapshotManager::getNFrames() {
243 tim 322 return reader_->getNFrames();
244 gezelter 507 }
245 tim 322
246 gezelter 1106 void BlockSnapshotManager::needCOMprops(bool ncp) {
247     reader_->setNeedCOMprops(ncp);
248     }
249    
250 tim 322 }

Properties

Name Value
svn:keywords Author Id Revision Date