~ubuntu-branches/ubuntu/oneiric/mpqc/oneiric

« back to all changes in this revision

Viewing changes to src/lib/chemistry/qc/mbptr12/distsh.cc

  • Committer: Bazaar Package Importer
  • Author(s): Michael Banck
  • Date: 2005-11-27 11:41:49 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20051127114149-zgz9r3gk50w8ww2q
Tags: 2.3.0-1
* New upstream release.
* debian/rules (SONAME): Activate awk snippet for automatic so-name
  detection again, resulting in a bump to `7' and making a `c2a' for
  the C++ allocator change unnecessary; closes: #339232.
* debian/patches/00list (08_gcc-4.0_fixes): Removed, no longer needed.
* debian/rules (test): Remove workarounds, do not abort build if tests
  fail.
* debian/ref: Removed.
* debian/control.in (libsc): Added Conflict against libsc6c2.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
//
2
 
// distsh.cc
3
 
// based on: mbpt/distsh.cc
4
 
//
5
 
// Copyright (C) 1996 Limit Point Systems, Inc.
6
 
//
7
 
// Author: Ida Nielsen <ida@kemi.aau.dk>
8
 
// Maintainer: LPS
9
 
//
10
 
// This file is part of the SC Toolkit.
11
 
//
12
 
// The SC Toolkit is free software; you can redistribute it and/or modify
13
 
// it under the terms of the GNU Library General Public License as published by
14
 
// the Free Software Foundation; either version 2, or (at your option)
15
 
// any later version.
16
 
//
17
 
// The SC Toolkit is distributed in the hope that it will be useful,
18
 
// but WITHOUT ANY WARRANTY; without even the implied warranty of
19
 
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20
 
// GNU Library General Public License for more details.
21
 
//
22
 
// You should have received a copy of the GNU Library General Public License
23
 
// along with the SC Toolkit; see the file COPYING.LIB.  If not, write to
24
 
// the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
25
 
//
26
 
// The U.S. Government is granted a limited license as per AL 91-7.
27
 
//
28
 
 
29
 
#ifdef __GNUC__
30
 
#pragma implementation
31
 
#endif
32
 
 
33
 
#include <util/misc/formio.h>
34
 
#include <chemistry/qc/mbptr12/distsh.h>
35
 
 
36
 
using namespace std;
37
 
using namespace sc;
38
 
 
39
 
/////////////////////////////////////////////////////////////////
40
 
// Function iquicksort performs a quick sort (larger -> smaller) 
41
 
// of the integer data in item by the integer indices in index;
42
 
// data in item remain unchanged
43
 
/////////////////////////////////////////////////////////////////
44
 
static void
45
 
iqs(int *item,int *index,int left,int right)
46
 
{
47
 
  register int i,j;
48
 
  int x,y;
49
 
 
50
 
  i=left; j=right;
51
 
  x=item[index[(left+right)/2]];
52
 
 
53
 
  do {
54
 
    while(item[index[i]]>x && i<right) i++;
55
 
    while(x>item[index[j]] && j>left) j--;
56
 
 
57
 
    if (i<=j) {
58
 
      if (item[index[i]] != item[index[j]]) {
59
 
        y=index[i];
60
 
        index[i]=index[j];
61
 
        index[j]=y;
62
 
        }
63
 
      i++; j--;
64
 
      }
65
 
    } while(i<=j);
66
 
       
67
 
  if (left<j) iqs(item,index,left,j);
68
 
  if (i<right) iqs(item,index,i,right);
69
 
}
70
 
 
71
 
static void
72
 
iquicksort(int *item,int *index,int n)
73
 
{
74
 
  int i;
75
 
  if (n<=0) return;
76
 
  for (i=0; i<n; i++) {
77
 
    index[i] = i;
78
 
    }
79
 
  iqs(item,index,0,n-1);
80
 
  }
81
 
 
82
 
/////////////////////////////////////////////////////////////////
83
 
// DistShellPairR12 class
84
 
 
85
 
DistShellPairR12::DistShellPairR12(const Ref<MessageGrp> & msg,
86
 
                                   int nthread, int mythread,
87
 
                                   const Ref<ThreadLock> & lock,
88
 
                                   const Ref<GaussianBasisSet> & bs1, const Ref<GaussianBasisSet> & bs2):
89
 
  msg_(msg),
90
 
  nthread_(nthread),
91
 
  mythread_(mythread),
92
 
  lock_(lock),
93
 
  bs1_(bs1), bs2_(bs2)
94
 
{
95
 
  ncpu_ = nthread_*msg->n();
96
 
  ncpu_less_0_ = nthread_*(msg->n()-1);
97
 
 
98
 
  print_percent_ = 10;
99
 
  debug_ = 0;
100
 
  dynamic_ = 0;
101
 
  bs1_eq_bs2_ = (bs1_ == bs2_);
102
 
  req_type_ = 18101;
103
 
  ans_type_ = 18102;
104
 
 
105
 
  // Only for static case with different basis sets
106
 
  if (!bs1_eq_bs2_) {
107
 
    int nsh2 = bs2_->nshell();
108
 
    incS_ = ncpu_/nsh2;
109
 
    incR_ = ncpu_%nsh2;
110
 
  }
111
 
 
112
 
  init();
113
 
}
114
 
 
115
 
DistShellPairR12::~DistShellPairR12()
116
 
{
117
 
}
118
 
 
119
 
void
120
 
DistShellPairR12::set_dynamic(int d)
121
 
{
122
 
  dynamic_ = d;
123
 
  if (msg_->n() <= 1) {
124
 
    dynamic_ = 0;
125
 
  }
126
 
}
127
 
 
128
 
void
129
 
DistShellPairR12::init()
130
 
{
131
 
  int nsh1 = bs1_->nshell();
132
 
  int nsh2 = bs2_->nshell();
133
 
  int nshpairs = (bs1_eq_bs2_ ? (nsh1*(nsh1+1))/2 : nsh1*nsh2);
134
 
  ntask_ = nshpairs/ncpu_;
135
 
 
136
 
  if (bs1_eq_bs2_) {
137
 
    S_ = 0;
138
 
    R_ = msg_->me()*nthread_ + mythread_;
139
 
    // What the hell?
140
 
    while (R_ > S_) {
141
 
      S_++;
142
 
      R_ = R_ - S_;
143
 
    }
144
 
  }
145
 
  else {
146
 
    int absthreadindex = msg_->me()*nthread_ + mythread_;
147
 
    S_ = absthreadindex/nsh2;
148
 
    R_ = absthreadindex%nsh2;
149
 
  }
150
 
 
151
 
  print_index_ = 0;
152
 
  print_interval_ = print_percent_*ntask_/100;
153
 
  if (print_interval_==0) print_interval_ = 1;
154
 
}
155
 
 
156
 
void
157
 
DistShellPairR12::serve_tasks()
158
 
{
159
 
  // initialize work arrays
160
 
  int S,R,index;
161
 
  int nsh1 = bs1_->nshell();
162
 
  int nsh2 = bs2_->nshell();
163
 
  int nshpairs = (bs1_eq_bs2_ ? (nsh1*(nsh1+1))/2 : nsh1*nsh2);
164
 
  int *cost = new int[nshpairs];
165
 
  int *Svec = new int[nshpairs];
166
 
  int *Rvec = new int[nshpairs];
167
 
  int *Ivec = new int[nshpairs];
168
 
  index = 0;
169
 
  for (S=0; S<nsh1; S++) {
170
 
    int Rmax = (bs1_eq_bs2_ ? S : nsh2-1);
171
 
    for (R=0; R<=Rmax; R++) {
172
 
      cost[index] = bs1_->shell(S).nfunction()*bs2_->shell(R).nfunction();
173
 
      Svec[index] = S;
174
 
      Rvec[index] = R;
175
 
      Ivec[index] = index;
176
 
      index++;
177
 
    }
178
 
  }
179
 
 
180
 
  // sort work
181
 
  iquicksort(cost, Ivec, nshpairs);
182
 
  if (debug_ > 1) {
183
 
    ExEnv::outn() << "costs of shell pairs" << endl;
184
 
    for (index=0; index<nshpairs; index++) {
185
 
      ExEnv::outn() << scprintf(" (%d %d):%d",Svec[Ivec[index]],Rvec[Ivec[index]],
186
 
                               cost[Ivec[index]])
187
 
                   << endl;
188
 
    }
189
 
  }
190
 
 
191
 
  // process requests
192
 
  int nreq = nshpairs + ncpu_less_0_;
193
 
  int iwork = 0;
194
 
  int print_index = 0;
195
 
  int print_interval = print_percent_*nreq/100;
196
 
  if (print_interval==0) print_interval = 1;
197
 
  int nreq_left = nreq;
198
 
  while (nreq_left) {
199
 
    int node;
200
 
    msg_->recvt(req_type_,&node,1);
201
 
    int SR[2];
202
 
    if (iwork < nshpairs) {
203
 
      SR[0] = Svec[Ivec[iwork]];
204
 
      SR[1] = Rvec[Ivec[iwork]];
205
 
      iwork++;
206
 
      if (print_index++%print_interval == 0) {
207
 
        ExEnv::outn() << indent
208
 
                     << scprintf("sending shell pair (%3d %3d) to %3d, %4.1f%% complete",
209
 
                                 SR[0],SR[1],node,(double)(print_index*100)/nreq)
210
 
                     << endl;
211
 
      }
212
 
    }
213
 
    else {
214
 
      SR[0] = -1;
215
 
      SR[1] = -1;
216
 
      if (print_index++%print_interval == 0) {
217
 
        ExEnv::outn() << indent
218
 
                     << scprintf("sending no more tasks message to %3d, %4.1f%% complete",
219
 
                                 node,(double)(print_index*100)/nreq)
220
 
                     << endl;
221
 
      }
222
 
    }
223
 
    msg_->sendt(node,ans_type_,SR,2);
224
 
    nreq_left--;
225
 
  }
226
 
 
227
 
  if (debug_) {
228
 
    ExEnv::outn() << "all requests processed" << endl;
229
 
  }
230
 
 
231
 
  delete[] cost;
232
 
  delete[] Svec;
233
 
  delete[] Rvec;
234
 
  delete[] Ivec;
235
 
}
236
 
 
237
 
int
238
 
DistShellPairR12::get_task(int &S, int &R)
239
 
{
240
 
  if (dynamic_) { // dynamic load balancing
241
 
    int me = msg_->me();
242
 
    if (me == 0) {
243
 
      if (mythread_ == 0) serve_tasks();
244
 
      return 0;
245
 
    }
246
 
    else {
247
 
      int SR[2];
248
 
      
249
 
      lock_->lock();
250
 
      msg_->sendt(0,req_type_,&me,1);
251
 
      msg_->recvt(ans_type_,SR,2);
252
 
      lock_->unlock();
253
 
 
254
 
      S = SR[0];
255
 
      R = SR[1];
256
 
      if (S == -1) return 0;
257
 
    }
258
 
  }
259
 
  else { // static load balancing
260
 
    int nsh1 = bs1_->nshell();
261
 
    int nsh2 = bs2_->nshell();
262
 
    if (S_ >= nsh1 || R_ >= nsh2) return 0;
263
 
    S = S_;
264
 
    R = R_;
265
 
    // advance to the next S_, R_
266
 
    if (bs1_eq_bs2_) {
267
 
      R_ += ncpu_;
268
 
      while (R_ > S_) {
269
 
        S_++;
270
 
        R_ = R_ - S_;
271
 
      }
272
 
    }
273
 
    else {
274
 
      S_ += incS_;
275
 
      R_ += incR_;
276
 
      if (R_ >= nsh2) {
277
 
        S_++;
278
 
        R_ -= nsh2;
279
 
      }
280
 
    }
281
 
    if (print_index_++%print_interval_ == 0) {
282
 
      if (mythread_ == 0 && msg_->me() == 0) {
283
 
        ExEnv::outn() << indent 
284
 
                     << scprintf("  working on shell pair (%3d %3d), %4.1f%% complete",
285
 
                                 S,R,(double)(print_index_*100)/ntask_)
286
 
                     << endl;
287
 
      }
288
 
    }
289
 
  }
290
 
  return 1;
291
 
}
292
 
 
293
 
////////////////////////////////////////////////////////////////////////////
294
 
 
295
 
// Local Variables:
296
 
// mode: c++
297
 
// c-file-style: "CLJ-CONDENSED"
298
 
// End: