28 #ifndef _chemistry_qc_mbptr12_contracttbinttensor_h
29 #define _chemistry_qc_mbptr12_contracttbinttensor_h
33 #include <util/misc/regtime.h>
34 #include <util/misc/consumableresources.h>
35 #include <math/mmisc/pairiter.h>
36 #include <chemistry/qc/lcao/utils.h>
37 #include <chemistry/qc/lcao/utils.impl.h>
38 #include <chemistry/qc/mbptr12/r12int_eval.h>
39 #include <util/misc/print.h>
43 template<
typename DataProcess_Bra,
typename DataProcess_Ket,
44 typename DataProcess_BraKet,
bool CorrFactorInBra,
bool CorrFactorInKet,
46 void R12IntEval::contract_tbint_tensor(
50 const Ref<OrbitalSpace>& space1_bra,
51 const Ref<OrbitalSpace>& space2_bra,
52 const Ref<OrbitalSpace>& space1_intb,
53 const Ref<OrbitalSpace>& space2_intb,
54 const Ref<OrbitalSpace>& space1_ket,
55 const Ref<OrbitalSpace>& space2_ket,
56 const Ref<OrbitalSpace>& space1_intk,
57 const Ref<OrbitalSpace>& space2_intk,
58 const Ref<mbptr12::TwoParticleContraction>& tpcontract,
60 const std::vector<std::string>& tformkeys_bra,
61 const std::vector<std::string>& tformkeys_ket) {
63 const bool part1_strong_equiv_part2 = (space1_bra == space2_bra
64 && space1_ket == space2_ket);
66 const bool part1_weak_equiv_part2 = (space1_bra->rank()
67 == space2_bra->rank() && space1_ket->rank() == space2_ket->rank());
69 bool correct_semantics = (
antisymmetrize && (part1_weak_equiv_part2
73 = (correct_semantics && (space1_intb->rank() == space1_intk->rank())
74 && (space2_intb->rank() == space2_intk->rank()));
76 correct_semantics = (correct_semantics && (tpcontract->nrow()
77 == space1_intb->rank()) && (tpcontract->ncol() == space2_intb->rank()));
78 if (!correct_semantics)
79 throw ProgrammingError(
80 "R12IntEval::contract_tbint_tensor_() -- incorrect call semantics",
94 const bool part1_intequiv_part2 = (space1_intb == space2_intb
95 && space1_intk == space2_intk);
99 if (!part1_intequiv_part2 && ! part1_strong_equiv_part2 &&
antisymmetrize)
100 throw ProgrammingError(
"R12IntEval::contract_tbint_tensor_() -- dubious call semantics",
105 const bool alphabeta = !(
antisymmetrize && part1_strong_equiv_part2
106 && part1_intequiv_part2);
113 const bool CorrFactorInBraInt = CorrFactorInBra && CorrFactorInInt;
114 const bool CorrFactorInKetInt = CorrFactorInKet && CorrFactorInInt;
116 const unsigned int nbrasets = (CorrFactorInBra ? corrfactor()->nfunctions()
118 const unsigned int nketsets = (CorrFactorInKet ? corrfactor()->nfunctions()
120 const unsigned int nintsets = (CorrFactorInInt ? corrfactor()->nfunctions()
122 const unsigned int nbraintsets = (CorrFactorInBraInt ? UINT_MAX : nbrasets
124 const unsigned int nketintsets = (CorrFactorInKetInt ? UINT_MAX : nketsets
130 typedef std::vector<Ref<TwoBodyMOIntsTransform> > tformvec;
133 const size_t num_tforms_bra = tformkeys_bra.size();
134 tformvec transforms_bra(num_tforms_bra);
135 for (
unsigned int t = 0; t < num_tforms_bra; ++t) {
136 transforms_bra[t] = moints_runtime4()->get(tformkeys_bra[t]);
140 const size_t num_tforms_ket = tformkeys_ket.size();
141 tformvec transforms_ket(num_tforms_ket);
142 for (
unsigned int t = 0; t < num_tforms_ket; ++t) {
143 transforms_ket[t] = moints_runtime4()->get(tformkeys_ket[t]);
149 Timer tim_gen_tensor_contract(
"Generic tensor contract");
152 std::ostringstream oss_bra;
153 oss_bra <<
"<" << space1_bra->id() <<
" " << space2_bra->id()
155 << space2_intb->id() <<
">";
156 const std::string label_bra = oss_bra.str();
157 std::ostringstream oss_ket;
158 oss_ket <<
"<" << space1_ket->id() <<
" " << space2_ket->id()
160 << space2_intk->id() <<
">";
161 const std::string label_ket = oss_ket.str();
162 std::ostringstream oss;
163 oss <<
"<" << space1_bra->id() <<
" " << space2_bra->id()
165 << space2_ket->id() <<
"> = " << label_bra <<
" . " << label_ket
169 ExEnv::out0() << std::endl << indent <<
"Entered generic contraction (" << label
178 Ref<OrbitalSpace> tspace1_bra = transforms_bra[0]->space1();
179 Ref<OrbitalSpace> tspace2_bra = transforms_bra[0]->space3();
180 Ref<OrbitalSpace> tspace1_intb = transforms_bra[0]->space2();
181 Ref<OrbitalSpace> tspace2_intb = transforms_bra[0]->space4();
182 Ref<OrbitalSpace> tspace1_ket = transforms_ket[0]->space1();
183 Ref<OrbitalSpace> tspace2_ket = transforms_ket[0]->space3();
184 Ref<OrbitalSpace> tspace1_intk = transforms_ket[0]->space2();
185 Ref<OrbitalSpace> tspace2_intk = transforms_ket[0]->space4();
187 std::vector<unsigned int> map1_bra, map2_bra, map1_ket, map2_ket,
188 map1_intb, map2_intb, map1_intk, map2_intk;
190 std::vector<unsigned int> map12_intb;
192 std::vector<unsigned int> map21_intb;
194 std::vector<unsigned int> map12_intk;
196 std::vector<unsigned int> map21_intk;
199 map1_bra = *tspace1_bra << *space1_bra;
200 map2_bra = *tspace2_bra << *space2_bra;
201 map1_intb = *tspace1_intb << *space1_intb;
202 map2_intb = *tspace2_intb << *space2_intb;
205 if (tspace1_intb == tspace2_intb) {
206 map12_intb = map1_intb;
207 map21_intb = map2_intb;
209 map12_intb = *tspace1_intb << *space2_intb;
210 map21_intb = *tspace2_intb << *space1_intb;
215 map1_ket = *tspace1_ket << *space1_ket;
216 map2_ket = *tspace2_ket << *space2_ket;
217 map1_intk = *tspace1_intk << *space1_intk;
218 map2_intk = *tspace2_intk << *space2_intk;
221 if (tspace1_intk == tspace2_intk) {
222 map12_intk = map1_intk;
223 map21_intk = map2_intk;
225 map12_intk = *tspace1_intk << *space2_intk;
226 map21_intk = *tspace2_intk << *space1_intk;
231 const unsigned int bratform_block_ncols = tspace2_intb->rank();
232 const unsigned int kettform_block_ncols = tspace2_intk->rank();
233 const RefDiagSCMatrix evals1_bra = space1_bra->evals();
234 const RefDiagSCMatrix evals2_bra = space2_bra->evals();
235 const RefDiagSCMatrix evals1_ket = space1_ket->evals();
236 const RefDiagSCMatrix evals2_ket = space2_ket->evals();
237 const RefDiagSCMatrix evals1_intb = space1_intb->evals();
238 const RefDiagSCMatrix evals2_intb = space2_intb->evals();
239 const RefDiagSCMatrix evals1_intk = space1_intk->evals();
240 const RefDiagSCMatrix evals2_intk = space2_intk->evals();
244 const SpinCase2 S = (alphabeta ? AlphaBeta : AlphaAlpha);
246 iterbra(space1_bra->rank(), (alphabeta ? space2_bra : space1_bra)->rank(), S);
248 iterket(space1_ket->rank(), (alphabeta ? space2_ket : space1_ket)->rank(), S);
249 SpinMOPairIter iterint(space1_intb->rank(),
250 (alphabeta ? space2_intb : space1_intb)->rank(), S);
252 const unsigned int nbra = iterbra.nij();
254 const unsigned int nket = iterket.nij();
256 const unsigned int nint = iterint.nij();
261 Tcontr = T.kit()->matrix(
new SCDimension(nbra * nbrasets),
262 new SCDimension(nket * nketsets));
268 const unsigned int blksize_int = space1_intb->rank() * space2_intb->rank();
269 double* T_ij =
new double[blksize_int];
270 double* T_kl =
new double[blksize_int];
277 for (
unsigned int fint = 0; fint < nintsets; ++fint) {
279 unsigned int fbraoffset = 0;
280 for (
unsigned int fbra = 0; fbra < nbrasets; ++fbra, fbraoffset += nbra) {
281 const unsigned int fbraint = fbra * nintsets + fint;
282 Ref<TwoBodyMOIntsTransform> tformb = transforms_bra[fbraint];
283 const Ref<TwoBodyIntDescr>& intdescrb = tformb->intdescr();
284 const unsigned int intsetidx_bra = intdescrb->intset(tbint_type_bra);
287 Ref<DistArray4> accumb = tformb->ints_distarray4();
290 unsigned int fketoffset = 0;
291 for (
unsigned int fket = 0; fket < nketsets; ++fket, fketoffset += nket) {
292 const unsigned int fketint = fket * nintsets + fint;
293 Ref<TwoBodyMOIntsTransform> tformk = transforms_ket[fketint];
294 const Ref<TwoBodyIntDescr>& intdescrk = tformk->intdescr();
295 const unsigned int intsetidx_ket = intdescrk->intset(tbint_type_ket);
298 Ref<DistArray4> accumk = tformk->ints_distarray4();
302 ExEnv::out0() << indent <<
"Using transforms " << tformb->name()
303 <<
" and " << tformk->name() << std::endl;
308 std::vector<int> proc_with_ints;
309 const int nproc_with_ints = accumb->tasks_with_access(proc_with_ints);
310 const int me =
r12world()->world()->msg()->me();
311 const bool nket_ge_nevals = (nket >= nproc_with_ints);
313 if (accumb->has_access(me)) {
315 unsigned int ijkl = 0;
316 for (iterbra.start(); iterbra; iterbra.next()) {
317 const int ij = iterbra.ij();
319 bool fetch_ij_block =
false;
320 if (nket_ge_nevals) {
321 fetch_ij_block =
true;
323 const int first_ij_task = ijkl % nproc_with_ints;
324 const int last_ij_task = (ijkl + nket - 1) % nproc_with_ints;
326 if (!(first_ij_task > proc_with_ints[me] && proc_with_ints[me]
328 fetch_ij_block =
true;
333 const unsigned int i = iterbra.i();
334 const unsigned int j = iterbra.j();
335 const unsigned int ii = map1_bra[i];
336 const unsigned int jj = map2_bra[j];
338 Timer tim_intsretrieve(
"MO ints retrieve");
339 const double *ij_buf = accumb->retrieve_pair_block(ii, jj,
341 tim_intsretrieve.exit();
344 <<
": obtained ij blocks" << std::endl;
346 for (iterket.start(); iterket; iterket.next(), ijkl++) {
347 const int kl = iterket.ij();
349 const int ijkl_proc = ijkl % nproc_with_ints;
350 if (ijkl_proc != proc_with_ints[me])
353 const unsigned int k = iterket.i();
354 const unsigned int l = iterket.j();
355 const unsigned int kk = map1_ket[k];
356 const unsigned int ll = map2_ket[l];
360 <<
": working on (i,j | k,l) = (" << i <<
"," << j
361 <<
" | " << k <<
"," << l <<
")" << std::endl;
362 tim_intsretrieve.enter(
"MO ints retrieve");
363 const double *kl_buf =
364 accumk->retrieve_pair_block(kk, ll, intsetidx_ket);
365 tim_intsretrieve.exit();
368 <<
": obtained kl blocks" << std::endl;
371 memset(T_ij, 0, blksize_int *
sizeof(
double));
372 memset(T_kl, 0, blksize_int *
sizeof(
double));
375 ExEnv::out0() << indent <<
"i = " << i <<
" j = " << j
376 <<
" k = " << k <<
" l = " << l << incindent << std::endl;
379 for (iterint.start(); iterint; iterint.next()) {
380 const unsigned int m = iterint.i();
381 const unsigned int n = iterint.j();
382 const int mn = iterint.ij();
385 const unsigned int mm = map1_intb[m];
386 const unsigned int nn = map2_intb[n];
387 MN_bra = mm * bratform_block_ncols + nn;
390 const unsigned int mm = map1_intk[m];
391 const unsigned int nn = map2_intk[n];
392 MN_ket = mm * kettform_block_ncols + nn;
395 const double I_ijmn = ij_buf[MN_bra];
396 const double I_klmn = kl_buf[MN_ket];
399 ExEnv::out0() << indent <<
" m = " << m <<
" n = " << n
406 << std::endl << indent <<
" <kl|mn> = " << I_klmn << std::endl;
408 const double T_ijmn = DataProcess_Bra::I2T(I_ijmn, i, j, m,
413 const double T_klmn = DataProcess_Ket::I2T(I_klmn, k, l, m,
419 ExEnv::out0() << indent <<
" <ij|T|mn> = " << T_ijmn
420 << std::endl << indent <<
" <kl|T|mn> = " << T_klmn
430 const unsigned int mm = map21_intb[m];
431 const unsigned int nn = map12_intb[n];
432 NM_bra = nn * bratform_block_ncols + mm;
435 const unsigned int mm = map21_intk[m];
436 const unsigned int nn = map12_intk[n];
437 NM_ket = nn * kettform_block_ncols + mm;
440 const double I_ijnm = ij_buf[NM_bra];
441 const double I_klnm = kl_buf[NM_ket];
444 ExEnv::out0() <<
" <ij|mn> = " << I_ijmn << std::endl
445 <<
" <ij|nm> = " << I_ijnm << std::endl <<
" <kl|mn> = "
446 << I_klmn << std::endl <<
" <kl|nm> = " << I_klnm << std::endl;
449 const double T_ijmn = DataProcess_Bra::I2T(I_ijmn - I_ijnm,
455 const double T_klmn = DataProcess_Ket::I2T(I_klmn - I_klnm,
462 ExEnv::out0() << indent <<
" <ij|T|mn> = " << T_ijmn
463 << std::endl << indent <<
" <kl|T|mn> = " << T_klmn
473 double T_ijkl = tpcontract->contract(T_ij, T_kl);
475 ExEnv::out0() << decindent << indent <<
" <ij|kl> = "
476 << T_ijkl << std::endl;
478 T_ijkl = DataProcess_BraKet::I2T(T_ijkl, i, j, k, l,
479 evals1_bra, evals1_ket,
480 evals2_bra, evals2_ket);
483 << Tcontr.get_element(ij + fbraoffset, kl + fketoffset)
485 ExEnv::out0() << indent <<
" +<ij|T|kl> = " << T_ijkl << std::endl;
487 Tcontr.accumulate_element(ij + fbraoffset, kl + fketoffset,
491 << Tcontr.get_element(ij + fbraoffset, kl + fketoffset)
495 accumk->release_pair_block(kk, ll, intsetidx_ket);
500 accumb->release_pair_block(ii, jj, intsetidx_bra);
508 if (accumb != accumk && accumk->data_persistent()) accumk->deactivate();
512 if (accumb->data_persistent()) accumb->deactivate();
519 symmetrize<false> (Tcontr, Tcontr, space1_bra, space1_ket);
528 ExEnv::out0() << indent <<
"Exited generic contraction (" << label <<
")"
530 tim_gen_tensor_contract.exit();
533 template<
bool CorrFactorInBra,
bool CorrFactorInKet>
534 void R12IntEval::contract_tbint_tensor(
539 const Ref<OrbitalSpace>& space1_bra,
540 const Ref<OrbitalSpace>& space2_bra,
541 const Ref<OrbitalSpace>& space1_intb,
542 const Ref<OrbitalSpace>& space2_intb,
543 const Ref<OrbitalSpace>& space1_ket,
544 const Ref<OrbitalSpace>& space2_ket,
545 const Ref<OrbitalSpace>& space1_intk,
546 const Ref<OrbitalSpace>& space2_intk,
548 const std::vector<std::string>& tformkeys_bra,
549 const std::vector<std::string>& tformkeys_ket) {
551 MPQC_ASSERT(tformkeys_bra.size() == 1);
552 MPQC_ASSERT(tformkeys_ket.size() == 1);
554 std::vector< Ref<DistArray4> > results;
555 contract_tbint_tensor<CorrFactorInBra, CorrFactorInKet>(
572 RefSCMatrix Tclone = T.clone();
573 Tclone << results[0];
574 T.accumulate(Tclone);
577 template<
bool CorrFactorInBra,
bool CorrFactorInKet>
579 R12IntEval::contract_tbint_tensor(std::vector< Ref<DistArray4> >& results,
583 const Ref<OrbitalSpace>& space1_bra,
584 const Ref<OrbitalSpace>& space2_bra,
585 const Ref<OrbitalSpace>& space1_intb,
586 const Ref<OrbitalSpace>& space2_intb,
587 const Ref<OrbitalSpace>& space1_ket,
588 const Ref<OrbitalSpace>& space2_ket,
589 const Ref<OrbitalSpace>& space1_intk,
590 const Ref<OrbitalSpace>& space2_intk,
592 const std::vector<std::string>& tformkeys_bra,
593 const std::vector<std::string>& tformkeys_ket) {
596 const bool part1_strong_equiv_part2 = (space1_bra == space2_bra
597 && space1_ket == space2_ket);
599 const bool part1_weak_equiv_part2 = (space1_bra->rank()
600 == space2_bra->rank() && space1_ket->rank() == space2_ket->rank());
602 bool correct_semantics = (
antisymmetrize && (part1_weak_equiv_part2
606 = (correct_semantics && (space1_intb->rank() == space1_intk->rank())
607 && (space2_intb->rank() == space2_intk->rank()));
608 if (!correct_semantics)
609 throw ProgrammingError(
610 "R12IntEval::contract_tbint_tensor_() -- incorrect call semantics",
627 const bool part1_intequiv_part2 = (space1_intb == space2_intb
628 && space1_intk == space2_intk);
640 const bool alphabeta = !(
antisymmetrize && part1_strong_equiv_part2
641 && part1_intequiv_part2);
648 const unsigned int nbrasets = (CorrFactorInBra ? corrfactor()->nfunctions()
650 const unsigned int nketsets = (CorrFactorInKet ? corrfactor()->nfunctions()
656 typedef std::vector<Ref<TwoBodyMOIntsTransform> > tformvec;
659 const size_t num_tforms_bra = tformkeys_bra.size();
660 tformvec transforms_bra(num_tforms_bra);
661 for (
unsigned int t = 0; t < num_tforms_bra; ++t) {
662 transforms_bra[t] = moints_runtime4()->get(tformkeys_bra[t]);
666 const size_t num_tforms_ket = tformkeys_ket.size();
667 tformvec transforms_ket(num_tforms_ket);
668 for (
unsigned int t = 0; t < num_tforms_ket; ++t) {
669 transforms_ket[t] = moints_runtime4()->get(tformkeys_ket[t]);
673 bool accumulate =
false;
674 std::vector< Ref<DistArray4> > results_clone;
675 if (results.empty()) {
676 std::vector<std::string> tformkeys_result;
678 transforms_bra[0]->compute();
679 for (
unsigned int tb = 0; tb < num_tforms_bra; ++tb) {
680 const std::string key_bra = tformkeys_bra[tb];
681 const ParsedTwoBodyFourCenterIntKey pkey_bra(key_bra);
682 const std::string parb = pkey_bra.params();
683 std::string params_bra;
685 const std::string::size_type lbpos = parb.find_first_of(
'[');
686 const std::string::size_type rbpos = parb.find_last_of(
']');
687 MPQC_ASSERT(lbpos < rbpos);
688 params_bra = parb.substr(lbpos + 1, (rbpos - lbpos - 1));
691 for (
unsigned int tk = 0; tk < num_tforms_ket; ++tk) {
692 const std::string key_ket = tformkeys_ket[tk];
693 const ParsedTwoBodyFourCenterIntKey pkey_ket(key_ket);
694 const std::string park = pkey_ket.params();
695 std::string params_ket;
697 const std::string::size_type lbpos = park.find_first_of(
'[');
698 const std::string::size_type rbpos = park.find_last_of(
']');
699 MPQC_ASSERT(lbpos < rbpos);
700 params_ket = park.substr(lbpos + 1, (rbpos - lbpos - 1));
703 std::string params_result;
704 if (CorrFactorInBra && CorrFactorInKet)
705 params_result =
'[' + params_bra +
',' + params_ket +
']';
707 if (CorrFactorInBra && !CorrFactorInKet)
708 params_result =
'[' + params_bra +
']';
709 if (!CorrFactorInBra && CorrFactorInKet)
710 params_result =
'[' + params_ket +
']';
713 const std::string descr_key = pkey_bra.oper() +
"@" + pkey_ket.oper() + params_result;
715 const std::string key_result =
716 ParsedTwoBodyFourCenterIntKey::key(space1_bra->id(),
719 space2_ket->id(), descr_key,
720 TwoBodyIntLayout::b1b2_k1k2);
722 tformkeys_result.push_back(key_result);
724 DistArray4Dimensions dims(1, space1_bra->rank(),
725 space2_bra->rank(), space1_ket->rank(),
727 Ref<DistArray4> result = transforms_bra[0]->ints_distarray4()->clone(dims);
728 results.push_back(result);
735 const size_t nresults = results.size();
736 MPQC_ASSERT(nresults == num_tforms_bra*num_tforms_ket);
737 for(
int r=0; r<nresults; ++r) {
738 MPQC_ASSERT(results[r]->num_te_types() == 1);
739 MPQC_ASSERT(results[r]->ni() == space1_bra->rank());
740 MPQC_ASSERT(results[r]->nj() == space2_bra->rank());
741 MPQC_ASSERT(results[r]->nx() == space1_ket->rank());
742 MPQC_ASSERT(results[r]->ny() == space2_ket->rank());
743 MPQC_ASSERT(results[r]->storage() == DistArray4Storage_XY);
746 for(
int r=0; r<nresults; ++r) {
747 results_clone.push_back( results[r]->clone() );
750 std::vector< Ref<DistArray4> >& results_ref = accumulate ? results_clone : results;
755 Timer tim_gen_tensor_contract(
"Generic tensor contract");
758 std::ostringstream oss_bra;
759 oss_bra <<
"<" << space1_bra->id() <<
" " << space2_bra->id()
761 << space2_intb->id() <<
">";
762 const std::string label_bra = oss_bra.str();
763 std::ostringstream oss_ket;
764 oss_ket <<
"<" << space1_ket->id() <<
" " << space2_ket->id()
766 << space2_intk->id() <<
">";
767 const std::string label_ket = oss_ket.str();
768 std::ostringstream oss;
769 oss <<
"<" << space1_bra->id() <<
" " << space2_bra->id()
771 << space2_ket->id() <<
"> = " << label_bra <<
" . " << label_ket
775 ExEnv::out0() << std::endl << indent <<
"Entered generic contraction (" << label
783 Ref<OrbitalSpace> tspace1_bra = transforms_bra[0]->space1();
784 Ref<OrbitalSpace> tspace2_bra = transforms_bra[0]->space3();
785 Ref<OrbitalSpace> tspace1_intb = transforms_bra[0]->space2();
786 Ref<OrbitalSpace> tspace2_intb = transforms_bra[0]->space4();
787 Ref<OrbitalSpace> tspace1_ket = transforms_ket[0]->space1();
788 Ref<OrbitalSpace> tspace2_ket = transforms_ket[0]->space3();
789 Ref<OrbitalSpace> tspace1_intk = transforms_ket[0]->space2();
790 Ref<OrbitalSpace> tspace2_intk = transforms_ket[0]->space4();
791 MPQC_ASSERT(tspace1_bra == space1_bra);
792 MPQC_ASSERT(tspace2_bra == space2_bra);
793 MPQC_ASSERT(tspace1_ket == space1_ket);
794 MPQC_ASSERT(tspace2_ket == space2_ket);
795 MPQC_ASSERT(tspace1_intb == space1_intb);
796 MPQC_ASSERT(tspace2_intb == space2_intb);
797 MPQC_ASSERT(tspace1_intk == space1_intk);
798 MPQC_ASSERT(tspace2_intk == space2_intk);
805 unsigned int fbraoffset = 0;
806 unsigned int fbraket = 0;
807 for (
unsigned int fbra = 0; fbra < nbrasets; ++fbra) {
808 Ref<TwoBodyMOIntsTransform> tformb = transforms_bra[fbra];
809 const Ref<TwoBodyIntDescr>& intdescrb = tformb->intdescr();
810 const unsigned int intsetidx_bra = intdescrb->intset(tbint_type_bra);
813 Ref<DistArray4> accumb = tformb->ints_distarray4();
815 unsigned int fketoffset = 0;
816 for (
unsigned int fket = 0; fket < nketsets; ++fket, ++fbraket) {
817 Ref<TwoBodyMOIntsTransform> tformk = transforms_ket[fket];
818 const Ref<TwoBodyIntDescr>& intdescrk = tformk->intdescr();
819 const unsigned int intsetidx_ket = intdescrk->intset(tbint_type_ket);
822 Ref<DistArray4> accumk = tformk->ints_distarray4();
826 ExEnv::out0() << indent <<
"Using transforms " << tformb->name()
827 <<
" and " << tformk->name() << std::endl;
843 sc::axpy(results_ref[fbraket], 1.0, results[fbraket]);
853 ExEnv::out0() << indent <<
"Exited generic contraction (" << label <<
")"
855 tim_gen_tensor_contract.exit();