00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #ifndef _chemistry_qc_scf_fockbuild_h
00030 #define _chemistry_qc_scf_fockbuild_h
00031
00032 #ifdef __GNUC__
00033 #pragma interface
00034 #endif
00035
00036 #include <scconfig.h>
00037 #include <util/misc/regtime.h>
00038 #include <util/group/thread.h>
00039 #include <util/group/message.h>
00040 #include <chemistry/qc/basis/integral.h>
00041
00042 #include <util/group/actmsg.h>
00043 #include <chemistry/qc/scf/fockdist.h>
00044
00045 namespace sc {
00046
00047 class FockBuildMatrix: public RefCount {
00048 private:
00049 void operator = (const FockBuildMatrix&) {}
00050 FockBuildMatrix() {}
00051 protected:
00052 Ref<MessageGrp> msg_;
00053 int nI_, nJ_;
00054 int nproc_;
00055 int me_;
00056
00057 Ref<FockBlocks> blocks1_;
00058 Ref<FockBlocks> blocks2_;
00059 public:
00060 FockBuildMatrix(const FockBuildMatrix&);
00061 FockBuildMatrix(const Ref<MessageGrp> &msg);
00062
00063 const Ref<MessageGrp> &messagegrp() const { return msg_; }
00064
00065 inline int block_offset(int I, int J) const {
00066 if (!symmetric()) {
00067 return I * blocks2_->nblock() + J;
00068 }
00069 else {
00070 if (J > I) {
00071 std::cout << "shell_block_offset: noncanonical indices: "
00072 << I << ", " << J << std::endl;
00073 abort();
00074 }
00075 return (I*(I+1))/2 + J;
00076 }
00077 }
00078 inline int n_block() const {
00079 if (!symmetric()) {
00080 return blocks1_->nblock() * blocks2_->nblock();
00081 }
00082 else {
00083 return (blocks1_->nblock()*(blocks1_->nblock()+1))/2;
00084 }
00085 }
00086 inline int block_owning_proc(int I, int J) const {
00087 return block_offset(I,J)%nproc_;
00088 }
00089 inline bool block_is_owner(int I, int J) const {
00090 return block_owning_proc(I,J) == me_;
00091 }
00092
00093 inline int shell_block_offset(int I, int J) const {
00094 if (!symmetric()) {
00095 return I * nJ_ + J;
00096 }
00097 else {
00098 if (J > I) {
00099 std::cout << "shell_block_offset: noncanonical indices: "
00100 << I << ", " << J << std::endl;
00101 abort();
00102 }
00103 return (I*(I+1))/2 + J;
00104 }
00105 }
00106 inline int n_shell_block() const {
00107 if (!symmetric()) {
00108 return nI_ * nJ_;
00109 }
00110 else {
00111 return (nI_*(nI_+1))/2;
00112 }
00113 }
00114 inline int shell_block_owning_proc(int I, int J) const {
00115 return block_owning_proc(blocks1_->shell_to_block(I),
00116 blocks2_->shell_to_block(J));
00117 }
00118 inline bool shell_block_is_owner(int I, int J) const {
00119 return shell_block_owning_proc(I,J) == me_;
00120 }
00121
00122 virtual bool symmetric() const = 0;
00123
00124
00125 virtual void fix_diagonal_blocks() const = 0;
00126 virtual void clear() = 0;
00127
00128
00129 virtual void scmat_to_data(const RefSymmSCMatrix &m,
00130 const Ref<GaussianBasisSet> &b, bool copy) = 0;
00131 virtual void scmat_to_data(const RefSCMatrix &m,
00132 const Ref<GaussianBasisSet> &b1,
00133 const Ref<GaussianBasisSet> &b2, bool copy) = 0;
00134
00135 virtual void data_to_scmat() const = 0;
00136 virtual void prefetch_block(int I, int J, int ifetch, int nfetch) = 0;
00137 virtual void finish_prefetch_block() = 0;
00138 virtual double *shell_block(int Ish, int Jsh) const = 0;
00139 virtual double *block(int Ish, int Jsh) const = 0;
00140 virtual FockBuildMatrix *copy(int unique_id,
00141 bool copy_data = false) const = 0;
00143 virtual void zero_data() = 0;
00145 virtual void accum(const Ref<FockBuildMatrix> &fbm) = 0;
00147 virtual void accum_remote(const Ref<MessageGrp> &) = 0;
00149 virtual void print() const;
00151 virtual void flush();
00152
00153 virtual void set_fockblocks(const Ref<FockBlocks> &b1,
00154 const Ref<FockBlocks> &b2);
00155
00156 const Ref<FockBlocks> &blocks1() { return blocks1_; }
00157 const Ref<FockBlocks> &blocks2() { return blocks2_; }
00158
00159 };
00160
00161 class ReplFockBuildMatrix: public FockBuildMatrix {
00162 double **blockpointers_;
00165 RefSCMatrix rectmat_;
00166 RefSymmSCMatrix symmmat_;
00167 int ndata_;
00168 Ref<GaussianBasisSet> bs1_;
00169 Ref<GaussianBasisSet> bs2_;
00170 bool owns_data_;
00171
00172 void data_to_symmat() const;
00173 void data_to_rectmat() const;
00174 public:
00175 ReplFockBuildMatrix(const Ref<MessageGrp> &msg);
00176 ReplFockBuildMatrix(const ReplFockBuildMatrix &,
00177 bool copy_data = false);
00178 ~ReplFockBuildMatrix();
00179 bool symmetric() const;
00180 void fix_diagonal_blocks() const;
00181 void clear();
00182 void scmat_to_data(const RefSymmSCMatrix &m,
00183 const Ref<GaussianBasisSet> &b, bool copy);
00184 void scmat_to_data(const RefSCMatrix &m,
00185 const Ref<GaussianBasisSet> &b1,
00186 const Ref<GaussianBasisSet> &b2, bool copy);
00187 void data_to_scmat() const;
00188 void prefetch_block(int I, int J, int ifetch, int nfetch);
00189 void finish_prefetch_block();
00190 double *shell_block(int Ish, int Jsh) const;
00191 double *block(int Ish, int Jsh) const;
00192 FockBuildMatrix *copy(int unique_id, bool copy_data = false) const;
00193 void zero_data();
00194 void accum(const Ref<FockBuildMatrix> &fbm);
00195 void accum_remote(const Ref<MessageGrp> &);
00196 virtual void print() const;
00197 };
00198
00199 class FockContribution;
00200
00201 class FockBuildAMG: public ActiveMessageGrp {
00202 Ref<FockContribution> fc_;
00203 Ref<MessageGrp> return_msg_;
00204 public:
00205 FockBuildAMG(const Ref<MessageGrp>& msg,
00206 const Ref<ThreadGrp>& thr,
00207 const Ref<FockContribution>& fc);
00208 const Ref<FockContribution> &contrib() const {
00209 return fc_;
00210 }
00211 const Ref<MessageGrp> &return_messagegrp() const {
00212 return return_msg_;
00213 }
00214 };
00215
00216 class FockBuildAM: public ActiveMessage {
00217 protected:
00218 int matrix_, I_, J_, nIJ_;
00219 double *data_;
00220 int use_shell_blocks_;
00221 public:
00222 FockBuildAM(int matrix);
00223 ~FockBuildAM();
00224 virtual FockBuildAM* copy() = 0;
00225 FockBuildAM(StateIn &s);
00226 void save_data_state(StateOut &s);
00227 void set_info(int I, int J, int nIJ, double *data,
00228 bool use_shell_blocks) {
00229 I_ = I;
00230 J_ = J;
00231 nIJ_ = nIJ;
00232 data_ = data;
00233 use_shell_blocks_ = use_shell_blocks;
00234 }
00235 };
00236
00237 class FockBuildOp: public RefCount {
00238 private:
00239 int msg_type_;
00240 bool need_read_;
00241 bool need_write_;
00242 bool use_shell_blocks_;
00243 Ref<FockBuildAMG> fbamg_;
00244 Ref<FockBuildAM> fbam_;
00245 Ref<StateSend> statesend_;
00246 public:
00247 FockBuildOp(int unique_id,
00248 bool need_read,
00249 bool need_write,
00250 bool use_shell_blocks,
00251 const Ref<FockBuildAMG> &fbamg,
00252 const Ref<FockBuildAM>& fbam);
00253 void process_write(int node, int I, int J, int nIJ, double *data);
00254 void process_read(int node, int I, int J, int nIJ, double *data);
00255 void begin_prefetch(int node, int I, int J, int nIJ, int ifetch, int nfetch,
00256 double *data, MessageGrp::MessageHandle &mh);
00257 void finish_prefetch(MessageGrp::MessageHandle &mh);
00258 bool need_read() const { return need_read_; }
00259 bool need_write() const { return need_write_; }
00260 FockBuildOp *copy(int unique_id) const;
00261 Ref<MessageGrp> messagegrp() const {
00262 return fbamg_->messagegrp();
00263 }
00264 Ref<MessageGrp> return_messagegrp() const {
00265 return fbamg_->return_messagegrp();
00266 }
00267 };
00268
00269 class DistFockBuildMatrix: public FockBuildMatrix {
00270 double **blockpointers_;
00273 RefSCMatrix rectmat_;
00274 RefSymmSCMatrix symmmat_;
00275 int ndata_;
00276 Ref<GaussianBasisSet> bs1_;
00277 Ref<GaussianBasisSet> bs2_;
00278 bool owns_data_;
00279
00280 bool prefetch_blocks_;
00281
00282 Ref<FockBuildOp> fockbuildop_;
00283
00284 class IJ_t {
00285 uint64_t ij_;
00286 public:
00287 IJ_t(const IJ_t&IJ) { ij_ = IJ.ij_; }
00288 IJ_t(int i, int j) { ij_ = uint64_t(i)<<32|j; }
00289 int i() const { return ij_>>32; }
00290 int j() const { return ij_&0xffffffff; }
00291 bool operator < (const IJ_t&IJ) const { return ij_ < IJ.ij_; }
00292 bool operator > (const IJ_t&IJ) const { return ij_ > IJ.ij_; }
00293 bool operator >= (const IJ_t&IJ) const { return ij_ >= IJ.ij_; }
00294 bool operator <= (const IJ_t&IJ) const { return ij_ <= IJ.ij_; }
00295 bool operator == (const IJ_t&IJ) const { return ij_ == IJ.ij_; }
00296 void operator = (const IJ_t&IJ) { ij_ = IJ.ij_; }
00297 };
00298 typedef std::pair<double*,MessageGrp::MessageHandle> FetchData_t;
00299
00300 mutable std::map<IJ_t,FetchData_t> prefetched_block_cache_;
00301 mutable std::map<IJ_t,double*> block_cache_;
00302 mutable std::map<IJ_t,double*> shell_block_cache_;
00303
00304 std::map<IJ_t,double*> local_blocks_;
00305 std::map<IJ_t,double*> local_shell_blocks_;
00306
00307 void clear_cache();
00308
00309 void data_to_symmat() const;
00310 void data_to_rectmat() const;
00311
00312 double *fetch_block(int I, int J) const;
00313 int block_size(int iblock, int jblock) const;
00314 void insert_shell_block_pointers(int iblock,int jblock,
00315 double *data,
00316 std::map<IJ_t,double*> &) const;
00317 void blockpointers_to_local_blocks();
00318 void local_blocks_to_blockpointers() const;
00319 public:
00320 DistFockBuildMatrix(bool prefetch_blocks,
00321 const Ref<FockBuildOp> &fockbuildop);
00322 DistFockBuildMatrix(const DistFockBuildMatrix &,
00323 int unique_id,
00324 bool copy_data = false);
00325 ~DistFockBuildMatrix();
00326 bool symmetric() const;
00327 void fix_diagonal_blocks() const;
00328 void clear();
00329 void scmat_to_data(const RefSymmSCMatrix &m,
00330 const Ref<GaussianBasisSet> &b, bool copy);
00331 void scmat_to_data(const RefSCMatrix &m,
00332 const Ref<GaussianBasisSet> &b1,
00333 const Ref<GaussianBasisSet> &b2, bool copy);
00334 void data_to_scmat() const;
00335 void prefetch_block(int I, int J, int ifetch, int nfetch);
00336 void finish_prefetch_block();
00337 double *shell_block(int Ish, int Jsh) const;
00338 double *block(int Ish, int Jsh) const;
00339 FockBuildMatrix *copy(int unique_id, bool copy_data = false) const;
00340 void zero_data();
00341 void accum(const Ref<FockBuildMatrix> &fbm);
00342 void accum_remote(const Ref<MessageGrp> &);
00343 void flush();
00344 };
00345
00346 class FockContribution: public RefCount {
00347 protected:
00348 double nint_;
00349 public:
00350 FockContribution();
00351 FockContribution(const FockContribution&);
00352 virtual ~FockContribution();
00358 virtual void contrib_e_J(double factor,
00359 int I, int J, int K, int L,
00360 int nI, int nJ, int nK, int nL,
00361 const double * restrictxx buf) = 0;
00366 virtual void contrib_e_K(double factor,
00367 int I, int J, int K, int L,
00368 int nI, int nJ, int nK, int nL,
00369 const double * restrictxx buf) = 0;
00370 virtual void contrib_p12_p13p24_J(double factor,
00371 int I, int J, int K, int L,
00372 int nI, int nJ, int nK, int nL,
00373 const double * restrictxx buf) = 0;
00374 virtual void contrib_p12_p13p24_K(double factor,
00375 int I, int J, int K, int L,
00376 int nI, int nJ, int nK, int nL,
00377 const double * restrictxx buf) = 0;
00378 virtual void contrib_p34_p13p24_J(double factor,
00379 int I, int J, int K, int L,
00380 int nI, int nJ, int nK, int nL,
00381 const double * restrictxx buf) = 0;
00382 virtual void contrib_p34_p13p24_K(double factor,
00383 int I, int J, int K, int L,
00384 int nI, int nJ, int nK, int nL,
00385 const double * restrictxx buf) = 0;
00386 virtual void contrib_p12_p34_J(double factor,
00387 int I, int J, int K, int L,
00388 int nI, int nJ, int nK, int nL,
00389 const double * restrictxx buf) = 0;
00390 virtual void contrib_p12_p34_K(double factor,
00391 int I, int J, int K, int L,
00392 int nI, int nJ, int nK, int nL,
00393 const double * restrictxx buf) = 0;
00394 virtual void contrib_p34_J(double factor,
00395 int I, int J, int K, int L,
00396 int nI, int nJ, int nK, int nL,
00397 const double * restrictxx buf) = 0;
00398 virtual void contrib_p34_K(double factor,
00399 int I, int J, int K, int L,
00400 int nI, int nJ, int nK, int nL,
00401 const double * restrictxx buf) = 0;
00402 virtual void contrib_p13p24_J(double factor,
00403 int I, int J, int K, int L,
00404 int nI, int nJ, int nK, int nL,
00405 const double * restrictxx buf) = 0;
00406 virtual void contrib_p13p24_K(double factor,
00407 int I, int J, int K, int L,
00408 int nI, int nJ, int nK, int nL,
00409 const double * restrictxx buf) = 0;
00410 virtual void contrib_all_J(double factor,
00411 int I, int J, int K, int L,
00412 int nI, int nJ, int nK, int nL,
00413 const double * restrictxx buf) = 0;
00414 virtual void contrib_all_K(double factor,
00415 int I, int J, int K, int L,
00416 int nI, int nJ, int nK, int nL,
00417 const double * restrictxx buf) = 0;
00418 virtual Ref<FockContribution> clone() = 0;
00419
00420 virtual void set_fmat(int i, const RefSCMatrix &) = 0;
00421 virtual void set_fmat(int i, const RefSymmSCMatrix &) = 0;
00422
00423 virtual void set_jmat(int i, const RefSCMatrix &) = 0;
00424 virtual void set_jmat(int i, const RefSymmSCMatrix &) = 0;
00425
00426 virtual void set_kmat(int i, const RefSCMatrix &) = 0;
00427 virtual void set_kmat(int i, const RefSymmSCMatrix &) = 0;
00428
00429 virtual void set_pmat(int i, const RefSymmSCMatrix &) = 0;
00430
00431 virtual double *jmat_shell_block(int i, int Ish, int Jsh) = 0;
00432 virtual double *kmat_shell_block(int i, int Ish, int Jsh) = 0;
00433 virtual const double *pmat_shell_block(int i, int Ish, int Jsh) = 0;
00434
00435 virtual double *jmat_block(int i, int Ish, int Jsh) = 0;
00436 virtual double *kmat_block(int i, int Ish, int Jsh) = 0;
00437 virtual const double *pmat_block(int i, int Ish, int Jsh) = 0;
00438
00441 virtual signed char *compute_pmax() const = 0;
00442
00444 virtual void copy_matrices(int unique_id) = 0;
00449 virtual void accum(const Ref<FockContribution> &) = 0;
00453 virtual void accum_remote(const Ref<MessageGrp> &) = 0;
00455 virtual void update() = 0;
00456
00457 double nint() const { return nint_; }
00458 double &nint() { return nint_; }
00459
00460 virtual void activate() = 0;
00461 virtual void sync() = 0;
00462 virtual void deactivate() = 0;
00463
00464 virtual void flush() = 0;
00465
00466 virtual void prefetch_blocks(int I, int J, int ifetch, int nfetch) = 0;
00467 virtual void finish_prefetch_blocks() = 0;
00468
00469 virtual void set_fockblocks(const Ref<FockBlocks> &blocks_f1,
00470 const Ref<FockBlocks> &blocks_f2,
00471 const Ref<FockBlocks> &blocks_p) = 0;
00472
00473 virtual Ref<ThreadLock> &get_lock(int i, int I, int J) = 0;
00474 };
00475
00495 class GenericFockContribution: public FockContribution {
00496 protected:
00497 int nfmat_;
00498 std::vector<Ref<FockBuildMatrix> > jmats_;
00499 std::vector<Ref<FockBuildMatrix> > kmats_;
00500 std::vector<bool> k_is_j_;
00501 int npmat_;
00502 std::vector<Ref<FockBuildMatrix> > pmats_;
00503 Ref<GaussianBasisSet> f_b1_, f_b2_, p_b_;
00504 bool f_b1_equiv_f_b2;
00505 int nlocks_;
00506 std::vector<Ref<ThreadLock> > locks_;
00507 std::string fockbuildmatrixtype_;
00508 bool use_shell_blocks_;
00509
00510 Ref<FockBuildAMG> fbamg_;
00511
00512 FockBuildMatrix *fockbuildmatrix(int matrix,
00513 const std::string &type,
00514 const Ref<MessageGrp> &msg,
00515 const Ref<FockBuildAMG> &);
00516
00517 class JLocator {
00518 public:
00519 double *operator()(GenericFockContribution *owner,
00520 int i, int I, int J) {
00521 return owner->jmat_shell_block(i,I,J);
00522 }
00523 };
00524
00525 class KLocator {
00526 public:
00527 double *operator()(GenericFockContribution *owner,
00528 int i, int I, int J) {
00529 return owner->kmat_shell_block(i,I,J);
00530 }
00531 };
00532
00533 template <class Locator>
00534 class JKBlock {
00535 GenericFockContribution *owner_;
00536 double *data_;
00537 int i_, I_, J_, nIJ_;
00538 public:
00539 JKBlock(GenericFockContribution *owner,
00540 int i, int I, int J, int nI, int nJ) {
00541 i_ = i;
00542 I_ = I;
00543 J_ = J;
00544 nIJ_ = nI*nJ;
00545 owner_ = owner;
00546 data_ = owner_->alloc_scratch(nIJ_);
00547 }
00548 ~JKBlock() {
00549 Locator l;
00550 int ilock, jlock;
00551 if (owner_->use_shell_blocks()) {
00552 ilock = I_;
00553 jlock = J_;
00554 }
00555 else {
00556 ilock = owner_->jmat(i_)->blocks1()->shell_to_block(I_);
00557 jlock = owner_->jmat(i_)->blocks2()->shell_to_block(J_);
00558 }
00559 const Ref<ThreadLock> &lock(
00560 owner_->get_lock(i_,ilock,jlock));
00561 lock->lock();
00562 double *real_data = l(owner_,i_,I_,J_);
00563
00564
00565
00566
00567
00568
00569
00570
00571 for (int i=0; i<nIJ_; i++) {
00572
00573
00574
00575 real_data[i] += data_[i];
00576 }
00577
00578
00579
00580
00581
00582 lock->unlock();
00583 owner_->free_scratch(data_);
00584 }
00585 double *data() { return data_; }
00586 };
00587
00588 class PBlock {
00589 GenericFockContribution *owner_;
00590 const double *data_;
00591 public:
00592 PBlock(GenericFockContribution *owner,
00593 int i, int I, int J, int nI, int nJ) {
00594 owner_ = owner;
00595 data_ = owner_->pmat_shell_block(i,I,J);
00596 }
00597 ~PBlock() {}
00598 const double *data() { return data_; }
00599 };
00600
00601 GenericFockContribution(int nfmat, int npmat,
00602 const Ref<GaussianBasisSet> &f_b1,
00603 const Ref<GaussianBasisSet> &f_b2,
00604 const Ref<GaussianBasisSet> &p_b,
00605 const std::string &fockbuildmatrixtype);
00606
00607 void pmax_contrib(const Ref<FockBuildMatrix> &mat,
00608 signed char *pmax) const;
00609
00610 public:
00611 double *jmat_shell_block(int i, int I, int J) {
00612 return jmats_[i]->shell_block(I,J);
00613 }
00614 bool jmat_symmetric(int i) const { return jmats_[i]->symmetric(); }
00615 double *kmat_shell_block(int i, int I, int J) {
00616 return kmats_[i]->shell_block(I,J);
00617 }
00618 bool kmat_symmetric(int i) const { return kmats_[i]->symmetric(); }
00619 const double *pmat_shell_block(int i, int I, int J) {
00620 return pmats_[i]->shell_block(I,J);
00621 }
00622
00623 double *jmat_block(int i, int I, int J) {
00624 return jmats_[i]->block(I,J);
00625 }
00626 double *kmat_block(int i, int I, int J) {
00627 return kmats_[i]->block(I,J);
00628 }
00629 const double *pmat_block(int i, int I, int J) {
00630 return pmats_[i]->block(I,J);
00631 }
00632
00633 Ref<ThreadLock> &get_lock(int i, int Ish, int Jsh) {
00634 int hash = (i+(Ish+1)*(Jsh+1))%nlocks_;
00635 return locks_[hash];
00636 }
00637
00638 double *alloc_scratch(int size) {
00639 double *data = new double[size];
00640 memset(data,0,sizeof(double)*size);
00641 return data;
00642 }
00643
00644 void free_scratch(double *data) {
00645 delete[] data;
00646 }
00647
00648 void set_fmat(int i, const RefSCMatrix &);
00649 void set_fmat(int i, const RefSymmSCMatrix &);
00650
00651 void set_jmat(int i, const RefSCMatrix &);
00652 void set_jmat(int i, const RefSymmSCMatrix &);
00653
00654 void set_kmat(int i, const RefSCMatrix &);
00655 void set_kmat(int i, const RefSymmSCMatrix &);
00656
00657 void set_pmat(int i, const RefSymmSCMatrix &);
00658
00659 void copy_matrices(int unique_id);
00660 void accum(const Ref<FockContribution> &);
00661 void accum_remote(const Ref<MessageGrp> &);
00662 void update();
00663
00664 signed char* compute_pmax() const;
00665
00666 ~GenericFockContribution();
00667
00668 void activate();
00669 void sync();
00670 void deactivate();
00671
00672 void prefetch_blocks(int I, int J, int ifetch, int nfetch);
00673 void finish_prefetch_blocks();
00674
00675 void set_fockblocks(const Ref<FockBlocks> &blocks_f1,
00676 const Ref<FockBlocks> &blocks_f2,
00677 const Ref<FockBlocks> &blocks_p);
00678
00679 void flush();
00680
00681 const Ref<FockBuildMatrix> &jmat(int i) { return jmats_[i]; }
00682 const Ref<FockBuildMatrix> &kmat(int i) { return kmats_[i]; }
00683 const Ref<FockBuildMatrix> &pmat(int i) { return pmats_[i]; }
00684
00685 bool use_shell_blocks() const { return use_shell_blocks_; }
00686 };
00687
00691 class FockBuildThread : public Thread {
00692 protected:
00693 Ref<FockDistribution> fockdist_;
00694 Ref<FockContribution> contrib_;
00695 Ref<ThreadLock> lock_;
00696 Ref<Integral> integral_;
00697 double accuracy_;
00698 Ref<MessageGrp> msg_;
00699 int nthread_;
00700 int threadnum_;
00701 const signed char *pmax_;
00702 Ref<RegionTimer> timer_;
00703 bool prefetch_blocks_;
00704 bool compute_J_;
00705 bool compute_K_;
00706 double coef_K_;
00707
00708 int can_sym_offset(int i, int j) { return (i*(i+1))/2 + j; }
00709 int gen_sym_offset(int i, int j) {
00710 if (i>=j) { return can_sym_offset(i,j); }
00711 else { return can_sym_offset(j,i); }
00712 }
00713 public:
00715 FockBuildThread(const Ref<FockDistribution> &fockdist,
00716 const Ref<MessageGrp> &msg,
00717 int nthread,
00718 int threadnum,
00719 bool prefetch_blocks,
00720 const Ref<ThreadLock> &lock,
00721 const Ref<Integral> &integral,
00722 bool compute_J,
00723 bool compute_K,
00724 double coef_K);
00725 void set_contrib(const Ref<FockContribution>&c) { contrib_ = c; }
00726 void set_accuracy(double acc) { accuracy_ = acc; }
00727 void set_pmax(const signed char *pmax) { pmax_ = pmax; }
00728 const Ref<RegionTimer> get_timer() const { return timer_; }
00729 };
00730
00734 class FockBuildThread_F11_P11 : public FockBuildThread {
00735 Ref<GaussianBasisSet> basis_;
00736 Ref<FockBlocks> blocks_;
00737 Ref<PetiteList> pl_;
00738 Ref<TwoBodyInt> eri_;
00739 void prefetch_blocks(const Ref<FockDist> &dist,
00740 int iblock, int jblock, int kblock, int lblock);
00741 public:
00743 FockBuildThread_F11_P11(const Ref<FockDistribution> &fockdist,
00744 const Ref<MessageGrp> &msg,
00745 int nthread,
00746 int threadnum,
00747 bool prefetch_blocks,
00748 const Ref<ThreadLock> &lock,
00749 const Ref<Integral> &integral,
00750 const Ref<PetiteList> &pl,
00751 const Ref<GaussianBasisSet> &basis1,
00752 const Ref<GaussianBasisSet> &basis2,
00753 const Ref<GaussianBasisSet> &basis3,
00754 const Ref<FockBlocks> &blocks1,
00755 const Ref<FockBlocks> &blocks2,
00756 const Ref<FockBlocks> &blocks3,
00757 bool compute_J,
00758 bool compute_K,
00759 double coef_K);
00760 void run();
00761 };
00762
00766 class FockBuildThread_F12_P33 : public FockBuildThread {
00767 Ref<GaussianBasisSet> basis1_;
00768 Ref<GaussianBasisSet> basis2_;
00769 Ref<GaussianBasisSet> basis3_;
00770 Ref<PetiteList> pl_;
00771
00772 void run_J();
00773 void run_K();
00774
00775 Ref<TwoBodyInt> eri_J_;
00776 Ref<TwoBodyInt> eri_K_;
00777
00778 public:
00780 FockBuildThread_F12_P33(const Ref<FockDistribution> &fockdist,
00781 const Ref<MessageGrp> &msg,
00782 int nthread,
00783 int threadnum,
00784 bool prefetch_blocks,
00785 const Ref<ThreadLock> &lock,
00786 const Ref<Integral> &integral,
00787 const Ref<PetiteList> &pl,
00788 const Ref<GaussianBasisSet> &basis1,
00789 const Ref<GaussianBasisSet> &basis2,
00790 const Ref<GaussianBasisSet> &basis3,
00791 const Ref<FockBlocks> &blocks1,
00792 const Ref<FockBlocks> &blocks2,
00793 const Ref<FockBlocks> &blocks3,
00794 bool compute_J,
00795 bool compute_K,
00796 double coef_K);
00797 void run();
00798 };
00799
00806 class FockBuild: public RefCount {
00807 Ref<FockDistribution> fockdist_;
00808 Ref<FockContribution> contrib_;
00809 Ref<GaussianBasisSet> b_f1_;
00810 Ref<GaussianBasisSet> b_f2_;
00811 Ref<GaussianBasisSet> b_p_;
00812 Ref<MessageGrp> msg_;
00813 Ref<ThreadGrp> thr_;
00814 Ref<Integral> integral_;
00815 double accuracy_;
00816 Ref<PetiteList> pl_;
00817 bool prefetch_blocks_;
00818
00819 Ref<FockBlocks> fb_f1_;
00820 Ref<FockBlocks> fb_f2_;
00821 Ref<FockBlocks> fb_p_;
00822
00823 bool compute_J_;
00824 bool compute_K_;
00825 double coef_K_;
00826
00827 typedef FockBuildThread* (*FBT_CTOR)(const Ref<FockDistribution> &fockdist,
00828 const Ref<MessageGrp> &msg,
00829 int nthread,
00830 int threadnum,
00831 bool prefetch_blocks,
00832 const Ref<ThreadLock> &lock,
00833 const Ref<Integral> &integral,
00834 const Ref<PetiteList> &pl,
00835 const Ref<GaussianBasisSet> &basis1,
00836 const Ref<GaussianBasisSet> &basis2,
00837 const Ref<GaussianBasisSet> &basis3,
00838 const Ref<FockBlocks> &blocks1,
00839 const Ref<FockBlocks> &blocks2,
00840 const Ref<FockBlocks> &blocks3,
00841 bool compute_J,
00842 bool compute_K,
00843 double coef_K);
00844
00845
00846
00847 FockBuildThread **thread_;
00848 void init_threads(FBT_CTOR);
00849 void init_threads();
00850 void done_threads();
00851
00852 public:
00861 FockBuild(const Ref<FockDistribution> &fockdist,
00862 const Ref<FockContribution> &contrib,
00863 bool prefetch_blocks,
00864 const Ref<GaussianBasisSet> &b_f1,
00865 const Ref<GaussianBasisSet> &b_f2 = 0,
00866 const Ref<GaussianBasisSet> &b_p = 0,
00867 const Ref<MessageGrp> &msg=MessageGrp::get_default_messagegrp(),
00868 const Ref<ThreadGrp> &thr=ThreadGrp::get_default_threadgrp(),
00869 const Ref<Integral> &integral=Integral::get_default_integral());
00870 virtual ~FockBuild();
00871
00873 void build();
00874
00875 const Ref<FockContribution> &contrib() const { return contrib_; }
00876 void set_accuracy(double acc) { accuracy_ = acc; }
00877
00878 void set_compute_J(bool compute_J) { compute_J_ = compute_J; }
00879 void set_compute_K(bool compute_K) { compute_K_ = compute_K; }
00880 void set_coef_K(double coef_K) { coef_K_ = coef_K; }
00881 bool compute_J() const { return compute_J_; }
00882 bool compute_K() const { return compute_K_; }
00883 double coef_K() const { return coef_K_; }
00884 };
00885
00886 }
00887
00888 #endif
00889
00890
00891
00892
00893