source: ThirdParty/mpqc_open/src/lib/chemistry/qc/intv3/storage.cc@ 860145

Action_Thermostats Add_AtomRandomPerturbation Add_RotateAroundBondAction Add_SelectAtomByNameAction Adding_Graph_to_ChangeBondActions Adding_MD_integration_tests Adding_StructOpt_integration_tests Automaking_mpqc_open AutomationFragmentation_failures Candidate_v1.6.0 Candidate_v1.6.1 ChangeBugEmailaddress ChangingTestPorts ChemicalSpaceEvaluator Combining_Subpackages Debian_Package_split Debian_package_split_molecuildergui_only Disabling_MemDebug Docu_Python_wait EmpiricalPotential_contain_HomologyGraph_documentation Enable_parallel_make_install Enhance_userguide Enhanced_StructuralOptimization Enhanced_StructuralOptimization_continued Example_ManyWaysToTranslateAtom Exclude_Hydrogens_annealWithBondGraph FitPartialCharges_GlobalError Fix_ChronosMutex Fix_StatusMsg Fix_StepWorldTime_single_argument Fix_Verbose_Codepatterns ForceAnnealing_goodresults ForceAnnealing_oldresults ForceAnnealing_tocheck ForceAnnealing_with_BondGraph ForceAnnealing_with_BondGraph_continued ForceAnnealing_with_BondGraph_continued_betteresults ForceAnnealing_with_BondGraph_contraction-expansion GeometryObjects Gui_displays_atomic_force_velocity IndependentFragmentGrids_IntegrationTest JobMarket_RobustOnKillsSegFaults JobMarket_StableWorkerPool JobMarket_unresolvable_hostname_fix ODR_violation_mpqc_open PartialCharges_OrthogonalSummation PythonUI_with_named_parameters QtGui_reactivate_TimeChanged_changes Recreated_GuiChecks RotateToPrincipalAxisSystem_UndoRedo StoppableMakroAction Subpackage_levmar Subpackage_mpqc_open Subpackage_vmg ThirdParty_MPQC_rebuilt_buildsystem TremoloParser_IncreasedPrecision TremoloParser_MultipleTimesteps Ubuntu_1604_changes stable
Last change on this file since 860145 was 860145, checked in by Frederik Heber <heber@…>, 8 years ago

Merge commit '0b990dfaa8c6007a996d030163a25f7f5fc8a7e7' as 'ThirdParty/mpqc_open'

  • Property mode set to 100644
File size: 7.3 KB
Line 
1//
2// storage.cc
3//
4// Copyright (C) 1996 Limit Point Systems, Inc.
5//
6// Author: Curtis Janssen <cljanss@limitpt.com>
7// Maintainer: LPS
8//
9// This file is part of the SC Toolkit.
10//
11// The SC Toolkit is free software; you can redistribute it and/or modify
12// it under the terms of the GNU Library General Public License as published by
13// the Free Software Foundation; either version 2, or (at your option)
14// any later version.
15//
16// The SC Toolkit is distributed in the hope that it will be useful,
17// but WITHOUT ANY WARRANTY; without even the implied warranty of
18// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19// GNU Library General Public License for more details.
20//
21// You should have received a copy of the GNU Library General Public License
22// along with the SC Toolkit; see the file COPYING.LIB. If not, write to
23// the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
24//
25// The U.S. Government is granted a limited license as per AL 91-7.
26//
27
28#ifdef __GNUC__
29#pragma implementation
30#endif
31
32#include <stdlib.h>
33#ifdef HAVE_CONFIG_H
34#include <scconfig.h>
35#endif
36#include <util/misc/formio.h>
37#include <chemistry/qc/intv3/macros.h>
38#include <chemistry/qc/intv3/flags.h>
39#include <chemistry/qc/intv3/types.h>
40
41#include <chemistry/qc/intv3/storage.h>
42
43#define PRINT_STORED 0
44
45#ifdef EXPLICIT_TEMPLATE_INSTANTIATION
46// instantiate the templates needed for integral storage
47template class EAVLMMap<IntegralKey,IntegralLink>;
48template class EAVLMMap<int,IntegralLink>;
49template class EAVLMMapNode<IntegralKey, IntegralLink>;
50template class EAVLMMapNode<int, IntegralLink>;
51#endif
52
53using namespace sc;
54
55/////////////////////////////////////////////////////////////////////////
56// IntegralLink members
57
58IntegralLink::IntegralLink(IntegralKey& key, int cost, int size_):
59 intlist(key),
60 costlist(cost),
61 size(size_)
62{
63}
64
65void*
66IntegralLink::operator new(size_t size, int intsize)
67{
68 return malloc(size + intsize*sizeof(double));
69}
70
71void
72IntegralLink::operator delete(void* ptr,int)
73{
74 free(ptr);
75}
76
77void
78IntegralLink::operator delete(void* ptr)
79{
80 free(ptr);
81}
82
83void
84IntegralLink::print()
85{
86 ExEnv::outn() << scprintf("(%d %d|%d %d)[%d%d%d]",
87 intlist.key.sh0(),
88 intlist.key.sh1(),
89 intlist.key.sh2(),
90 intlist.key.sh3(),
91 intlist.key.p12(),
92 intlist.key.p34(),
93 intlist.key.p13p24());
94}
95
96IntegralLink::~IntegralLink()
97{
98}
99
100//////////////////////////////////////////////////////////////////////////
101// IntegralStorer members
102
103static ClassDesc IntegralStorer_cd(
104 typeid(IntegralStorer),"IntegralStorer",1,"public DescribedClass",
105 create<IntegralStorer>, create<IntegralStorer>, 0);
106
107IntegralStorer::IntegralStorer()
108{
109 table_size_ = 1597;
110 table_ = new EAVLMMap<IntegralKey,IntegralLink>[table_size_];
111 init(0);
112}
113
114IntegralStorer::~IntegralStorer()
115{
116 init(0);
117 delete[] table_;
118}
119
120IntegralStorer::IntegralStorer(const Ref<KeyVal>&keyval)
121{
122 table_size_ = keyval->intvalue("table_size");
123 if (table_size_ <= 0) table_size_ = 1597;
124 table_ = new EAVLMMap<IntegralKey,IntegralLink>[table_size_];
125
126 int n_integral = keyval->intvalue("n_integral");
127 init(n_integral);
128}
129
130void
131IntegralStorer::store(IntegralKey &key, const double *buf,
132 int size, int cost, int actualsize)
133{
134 IntegralLink *link = new(size) IntegralLink(key, cost, size);
135
136 int i;
137 double *buffer = link->buffer();
138 for (i=0; i<link->size; i++) {
139 buffer[i] = buf[i];
140 }
141
142#if PRINT_STORED
143 ExEnv::outn() << scprintf("+++++ %d %d %d %d, %d %d %d size %5d cost %7d at 0x%x slot %5d\n",
144 key.sh0(),key.sh1(),key.sh2(),key.sh3(),
145 key.p12(), key.p34(), key.p13p24(),
146 link->size,link->costlist.key,link,link->hash()%table_size_);
147#endif
148
149 currentsize_ += actualsize;
150 n_integrals_ += size;
151 n_shellquart_++;
152
153 // if the table has grown too big, remove some of the members
154 while (currentsize_ > maxsize_) {
155 IntegralLink *eliminate = costlist.start();
156 currentsize_ -= eliminate->actualsize();
157 costlist.remove(eliminate);
158 table_[eliminate->hash()%table_size_].remove(eliminate);
159 n_shellquart_--;
160 n_integrals_ -= eliminate->size;
161#if PRINT_STORED
162 ExEnv::outn() << scprintf("----- %d %d %d %d, %d %d %d size %5d cost %7d at 0x%x slot %5d\n",
163 eliminate->intlist.key.sh0(),eliminate->intlist.key.sh1(),
164 eliminate->intlist.key.sh2(),eliminate->intlist.key.sh3(),
165 eliminate->intlist.key.p12(), eliminate->intlist.key.p34(),
166 eliminate->intlist.key.p13p24(),
167 eliminate->size, eliminate->costlist.key,
168 eliminate,
169 eliminate->hash()%table_size_);
170#endif
171 delete eliminate;
172 }
173
174 // add the new shell quartet
175 costlist.insert(link);
176 table_[link->hash()%table_size_].insert(link);
177}
178
179int
180IntegralStorer::should_store(int cost, int actualsize)
181{
182 int neededsize = actualsize - (maxsize_ - currentsize_);
183 if (neededsize < 0) neededsize = 0;
184
185 IntegralLink *i;
186 int accumsize = 0;
187 int accumcost = 0;
188 for (i=costlist.start(); i; costlist.next(i)) {
189 if (accumsize >= neededsize || accumcost >= cost) break;
190 accumsize += i->actualsize();
191 accumcost += i->cost();
192 }
193 //printf("should_store: asize = %5d nsize = %5d acost = %7d cost = %7d\n",
194 // accumsize, neededsize, accumcost, cost);
195 if (accumsize >= neededsize) {
196 if (accumcost < cost) return 1;
197 return 0;
198 }
199 return 0;
200}
201
202IntegralLink*
203IntegralStorer::find(IntegralKey& key)
204{
205 int hash = IntegralLink::shells_to_hash(key.sh0(),
206 key.sh1(),
207 key.sh2(),
208 key.sh3());
209 EAVLMMap<IntegralKey,IntegralLink> &list = table_[hash % table_size_];
210 IntegralLink* link = list.find(key);
211 return link;
212}
213
214void
215IntegralStorer::init(int nbytes)
216{
217 costlist.initialize(&IntegralLink::costlist);
218 for (int i=0; i<table_size_; i++) {
219 table_[i].initialize(&IntegralLink::intlist);
220 }
221 done();
222 maxsize_ = nbytes;
223 // estimate a 50% loss due to memory fragmentation
224 maxsize_ /= 2;
225}
226
227void
228IntegralStorer::done()
229{
230 n_shellquart_ = 0;
231 n_integrals_ = 0;
232 currentsize_ = 0;
233 maxsize_ = 0;
234
235 int i;
236 for (i=0; i<table_size_; i++) {
237 table_[i].clear_without_delete();
238 }
239 costlist.clear();
240}
241
242void
243IntegralStorer::print_stats()
244{
245 if (currentsize_ == 0) return;
246 ExEnv::outn() << scprintf("IntegralStorer: n_integrals = %d\n", n_integrals_);
247 ExEnv::outn() << scprintf("IntegralStorer: n_shellquart = %d\n", n_shellquart_);
248 ExEnv::outn() << scprintf("IntegralStorer: currentsize = %d\n", currentsize_);
249 ExEnv::outn() << scprintf("IntegralStorer: maxsize = %d\n", maxsize_);
250#if 0
251 ExEnv::outn() << scprintf("IntegralStorer: hash table distribution:\n");
252 int tlength = 0;
253 int i;
254 for (i=0; i<table_size_; i++) {
255 int length = table_[i].length();
256 tlength += length;
257 ExEnv::outn() << scprintf(" %5d", length);
258 if ((i+1)%13 == 0) ExEnv::outn() << scprintf("\n");
259 }
260 if (i%13 != 0) ExEnv::outn() << scprintf("\n");
261 ExEnv::outn() << scprintf("IntegralStorer: hash table length sum = %d\n", tlength);
262 ExEnv::outn() << scprintf("IntegralStorer: cost list length = %d\n", costlist.length());
263#endif
264}
265
266/////////////////////////////////////////////////////////////////////////////
267
268// Local Variables:
269// mode: c++
270// c-file-style: "CLJ"
271// End:
Note: See TracBrowser for help on using the repository browser.