3
// based on: mbpt/distsh.cc
5
// Copyright (C) 1996 Limit Point Systems, Inc.
7
// Author: Ida Nielsen <ida@kemi.aau.dk>
10
// This file is part of the SC Toolkit.
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)
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.
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.
26
// The U.S. Government is granted a limited license as per AL 91-7.
30
#pragma implementation
33
#include <util/misc/formio.h>
34
#include <chemistry/qc/mbptr12/distsh.h>
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
/////////////////////////////////////////////////////////////////
45
iqs(int *item,int *index,int left,int right)
51
x=item[index[(left+right)/2]];
54
while(item[index[i]]>x && i<right) i++;
55
while(x>item[index[j]] && j>left) j--;
58
if (item[index[i]] != item[index[j]]) {
67
if (left<j) iqs(item,index,left,j);
68
if (i<right) iqs(item,index,i,right);
72
iquicksort(int *item,int *index,int n)
79
iqs(item,index,0,n-1);
82
/////////////////////////////////////////////////////////////////
83
// DistShellPairR12 class
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):
95
ncpu_ = nthread_*msg->n();
96
ncpu_less_0_ = nthread_*(msg->n()-1);
101
bs1_eq_bs2_ = (bs1_ == bs2_);
105
// Only for static case with different basis sets
107
int nsh2 = bs2_->nshell();
115
DistShellPairR12::~DistShellPairR12()
120
DistShellPairR12::set_dynamic(int d)
123
if (msg_->n() <= 1) {
129
DistShellPairR12::init()
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_;
138
R_ = msg_->me()*nthread_ + mythread_;
146
int absthreadindex = msg_->me()*nthread_ + mythread_;
147
S_ = absthreadindex/nsh2;
148
R_ = absthreadindex%nsh2;
152
print_interval_ = print_percent_*ntask_/100;
153
if (print_interval_==0) print_interval_ = 1;
157
DistShellPairR12::serve_tasks()
159
// initialize work arrays
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];
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();
181
iquicksort(cost, Ivec, nshpairs);
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]],
192
int nreq = nshpairs + ncpu_less_0_;
195
int print_interval = print_percent_*nreq/100;
196
if (print_interval==0) print_interval = 1;
197
int nreq_left = nreq;
200
msg_->recvt(req_type_,&node,1);
202
if (iwork < nshpairs) {
203
SR[0] = Svec[Ivec[iwork]];
204
SR[1] = Rvec[Ivec[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)
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)
223
msg_->sendt(node,ans_type_,SR,2);
228
ExEnv::outn() << "all requests processed" << endl;
238
DistShellPairR12::get_task(int &S, int &R)
240
if (dynamic_) { // dynamic load balancing
243
if (mythread_ == 0) serve_tasks();
250
msg_->sendt(0,req_type_,&me,1);
251
msg_->recvt(ans_type_,SR,2);
256
if (S == -1) return 0;
259
else { // static load balancing
260
int nsh1 = bs1_->nshell();
261
int nsh2 = bs2_->nshell();
262
if (S_ >= nsh1 || R_ >= nsh2) return 0;
265
// advance to the next S_, R_
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_)
293
////////////////////////////////////////////////////////////////////////////
297
// c-file-style: "CLJ-CONDENSED"