ALPS MPS Codes
Reference documentation.
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
storage.h
Go to the documentation of this file.
1 /*****************************************************************************
2  *
3  * ALPS MPS DMRG Project
4  *
5  * Copyright (C) 2013 Institute for Theoretical Physics, ETH Zurich
6  * 2011-2011 by Bela Bauer <bauerb@phys.ethz.ch>
7  * 2011-2012 by Michele Dolfi <dolfim@phys.ethz.ch>
8  *
9  * This software is part of the ALPS Applications, published under the ALPS
10  * Application License; you can use, redistribute it and/or modify it under
11  * the terms of the license, either version 1 or (at your option) any later
12  * version.
13  *
14  * You should have received a copy of the ALPS Application License along with
15  * the ALPS Applications; see the file LICENSE.txt. If not, the license is also
16  * available from http://alps.comp-phys.org/.
17  *
18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20  * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
21  * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
22  * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
23  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
24  * DEALINGS IN THE SOFTWARE.
25  *
26  *****************************************************************************/
27 
28 #ifndef STORAGE_H
29 #define STORAGE_H
30 
31 #include <boost/shared_ptr.hpp>
32 #include <boost/thread.hpp>
33 #include <boost/filesystem.hpp>
34 
35 #include <iostream>
36 #include <fstream>
37 
38 #include "utils.hpp"
39 #include "utils/timings.h"
40 
43 
44 #ifdef HAVE_ALPS_HDF5
45 #include "dmrg/utils/archive.h"
46 #include "dmrg/utils/logger.h"
47 namespace storage {
49 }
50 #endif
51 
52 template<class Matrix, class SymmGroup> class Boundary;
53 template<class Matrix, class SymmGroup> class MPSTensor;
54 template<class Matrix, class SymmGroup> class block_matrix;
55 
56 namespace alps { namespace numeric {
57  template <typename T, typename MemoryBlock> class matrix;
58 } }
59 namespace storage {
60  template<class T>
61  struct constrained {
62  typedef T type;
63  };
64  template<typename T>
65  struct constrained<alps::numeric::matrix<T, std::vector<T> > > {
67  };
68 }
69 
70 namespace storage {
71 
72  class nop {
73  public:
74  template<class T> static void prefetch(T& o){}
75  template<class T> static void fetch(T& o){}
76  template<class T> static void evict(T& o){}
77  template<class T> static void drop(T& o){}
78  static void sync(){}
79  };
80 
81  template<class T> class evict_request {};
82  template<class T> class fetch_request {};
83  template<class T> class drop_request {};
84 
85  template<class Matrix, class SymmGroup>
86  class evict_request< Boundary<Matrix, SymmGroup> > {
87  public:
88  evict_request(std::string fp, Boundary<Matrix, SymmGroup>* ptr) : fp(fp), ptr(ptr) { }
89  void operator()(){
90  std::ofstream ofs(fp.c_str(), std::ofstream::binary);
92  size_t loop_max = o.aux_dim();
93  for(size_t b = 0; b < loop_max; ++b){
94  for (std::size_t k = 0; k < o[b].n_blocks(); ++k){
95  Matrix& m = o[b][k];
96  for (std::size_t c = 0; c < num_cols(m); ++c)
97  ofs.write((char*)(&m(0, c)), num_rows(m)*
98  sizeof(typename Matrix::value_type)/sizeof(char));
99  m = Matrix();
100  }
101  }
102  ofs.close();
103  }
104  private:
105  std::string fp;
107  };
108 
109  template<class Matrix, class SymmGroup>
110  class fetch_request< Boundary<Matrix, SymmGroup> > {
111  public:
112  fetch_request(std::string fp, Boundary<Matrix, SymmGroup>* ptr) : fp(fp), ptr(ptr) { }
113  void operator()(){
114  std::ifstream ifs(fp.c_str(), std::ifstream::binary);
115  Boundary<Matrix, SymmGroup>& o = *ptr;
116  size_t loop_max = o.aux_dim();
117  for(size_t b = 0; b < loop_max; ++b){
118  for (std::size_t k = 0; k < o[b].n_blocks(); ++k){
119  o[b][k] = Matrix(o[b].left_basis()[k].second,
120  o[b].right_basis()[k].second);
121  Matrix& m = o[b][k];
122  ifs.read((char*)(&m(0,0)), num_cols(m)*num_rows(m)*
123  sizeof(typename Matrix::value_type)/sizeof(char));
124  }
125  }
126  ifs.close();
127  }
128  private:
129  std::string fp;
131  };
132 
133  template<class Matrix, class SymmGroup>
134  class drop_request< Boundary<Matrix, SymmGroup> > {
135  public:
136  drop_request(std::string fp, Boundary<Matrix, SymmGroup>* ptr) : fp(fp), ptr(ptr) { }
137  void operator()(){
138  Boundary<Matrix, SymmGroup>& o = *ptr;
139  for (std::size_t b = 0; b < o.aux_dim(); ++b)
140  for (std::size_t k = 0; k < o[b].n_blocks(); ++k){
141  o[b][k] = Matrix();
142  }
143  }
144  private:
145  std::string fp;
147  };
148 
149  class disk : public nop {
150  public:
151  class descriptor {
152  public:
153  descriptor() : state(core), dumped(false), sid(disk::index()), worker(NULL) {}
155  this->join();
156  }
157  void thread(boost::thread* t){
158  this->worker = t;
159  disk::track(this);
160  }
161  void join(){
162  if(this->worker){
163  this->worker->join();
164  delete this->worker;
165  this->worker = NULL;
166  disk::untrack(this);
167  }
168  }
170  bool dumped;
171  size_t sid;
172  boost::thread* worker;
173  size_t record;
174  };
175 
176  template<class T> class serializable : public descriptor {
177  public:
179  this->join();
180  descriptor::operator=(rhs);
181  return *this;
182  }
183  void fetch(){
184  if(this->state == core) return;
185  else if(this->state == prefetching) this->join();
186  assert(this->state != storing); // isn't prefetched prior load
187  assert(this->state != uncore); // isn't prefetched prior load
188  this->state = core;
189  }
190  void prefetch(){
191  if(this->state == core) return;
192  else if(this->state == prefetching) return;
193  else if(this->state == storing) this->join();
194 
195  state = prefetching;
196  this->thread(new boost::thread(fetch_request<T>(disk::fp(sid), (T*)this)));
197  }
198  void evict(){
199  if(state == core){
200  if(!dumped){
201  state = storing;
202  dumped = true;
203  this->thread(new boost::thread(evict_request<T>(disk::fp(sid), (T*)this)));
204  }else{
205  state = uncore;
206  drop_request<T>(disk::fp(sid), (T*)this)();
207  }
208  }
209  assert(this->state != prefetching); // evict of prefetched
210  }
211  void drop(){
212  std::remove(disk::fp(sid).c_str());
213  if(state == core) drop_request<T>(disk::fp(sid), (T*)this)();
214  assert(this->state != storing); // drop of already stored data
215  assert(this->state != uncore); // drop of already stored data
216  assert(this->state != prefetching); // drop of prefetched data
217  }
218  };
219 
220  static disk& instance(){
221  static disk singleton;
222  return singleton;
223  }
224  static void init(const std::string& path){
225  maquis::cout << "Temporary storage enabled in " << path << "\n";
226  instance().active = true;
227  instance().path = path;
228  }
229  static bool enabled(){
230  return instance().active;
231  }
232  static std::string fp(size_t sid){
233  return (instance().path + boost::lexical_cast<std::string>(sid));
234  }
235  static size_t index(){
236  return instance().sid++;
237  }
238  static void track(descriptor* d){
239  d->record = instance().queue.size();
240  instance().queue.push_back(d);
241  }
242  static void untrack(descriptor* d){
243  instance().queue[d->record] = NULL;
244  }
245  static void sync(){
246  for(int i = 0; i < instance().queue.size(); ++i)
247  if(instance().queue[i]) instance().queue[i]->join();
248  instance().queue.clear();
249  }
250  template<class T> static void fetch(serializable<T>& t) { if(enabled()) t.fetch(); }
251  template<class T> static void prefetch(serializable<T>& t){ if(enabled()) t.prefetch(); }
252  template<class T> static void evict(serializable<T>& t) { if(enabled()) t.evict(); }
253  template<class T> static void drop(serializable<T>& t) { if(enabled()) t.drop(); }
254  template<class T> static void pin(serializable<T>& t) { }
255 
256  template<class Matrix, class SymmGroup>
258 
259  disk() : active(false), sid(0) {}
260  std::vector<descriptor*> queue;
261  std::string path;
262  bool active;
263  size_t sid;
264  };
265 
266  inline static void setup(BaseParameters& parms){
267  if(!parms["storagedir"].empty()){
268  boost::filesystem::path dp = boost::filesystem::unique_path(parms["storagedir"].as<std::string>() + std::string("/storage_temp_%%%%%%%%%%%%/"));
269  try {
270  boost::filesystem::create_directories(dp);
271  } catch (...) {
272  maquis::cerr << "Error creating dir/file at " << dp << ". Try different 'storagedir'.\n";
273  throw;
274  }
275  storage::disk::init(dp.string());
276  }else{
277  maquis::cout << "Temporary storage is disabled\n";
278  }
279  }
280 }
281 
282 #endif
static void evict(serializable< T > &t)
Definition: storage.h:252
static void pin(serializable< T > &t)
Definition: storage.h:254
static std::string fp(size_t sid)
Definition: storage.h:232
Definition: logger.h:38
static void drop(serializable< T > &t)
Definition: storage.h:253
std::string path
Definition: storage.h:261
static void drop(T &o)
Definition: storage.h:77
static void fetch(serializable< T > &t)
Definition: storage.h:250
static void prefetch(T &o)
Definition: storage.h:74
static void evict(MPSTensor< Matrix, SymmGroup > &t)
Definition: storage.h:257
static bool enabled()
Definition: storage.h:229
static disk & instance()
Definition: storage.h:220
static void track(descriptor *d)
Definition: storage.h:238
alps::numeric::matrix< T, std::vector< T > > type
Definition: storage.h:66
alps::numeric::matrix< double > matrix
Definition: matrices.h:40
std::size_t num_rows(maquis::dmrg::one_matrix< T > const &m)
Definition: one_matrix.hpp:99
evict_request(std::string fp, Boundary< Matrix, SymmGroup > *ptr)
Definition: storage.h:88
boost::thread * worker
Definition: storage.h:172
static void prefetch(serializable< T > &t)
Definition: storage.h:251
static void untrack(descriptor *d)
Definition: storage.h:242
size_t sid
Definition: storage.h:263
static void sync()
Definition: storage.h:78
std::size_t num_cols(maquis::dmrg::one_matrix< T > const &m)
Definition: one_matrix.hpp:102
static void sync()
Definition: storage.h:245
drop_request(std::string fp, Boundary< Matrix, SymmGroup > *ptr)
Definition: storage.h:136
Logger< storage::archive > log
Definition: utils.cpp:40
std::size_t aux_dim() const
Definition: boundary.h:72
fetch_request(std::string fp, Boundary< Matrix, SymmGroup > *ptr)
Definition: storage.h:112
static void init(const std::string &path)
Definition: storage.h:224
static size_t index()
Definition: storage.h:235
static void fetch(T &o)
Definition: storage.h:75
static void evict(T &o)
Definition: storage.h:76
enum storage::disk::descriptor::@0 state
void thread(boost::thread *t)
Definition: storage.h:157
serializable & operator=(const serializable &rhs)
Definition: storage.h:178
bool active
Definition: storage.h:262
std::vector< descriptor * > queue
Definition: storage.h:260