Skip to content

Commit 84b77fe

Browse files
authored
OMP-ed denominator related lines in spin-adapted MRDSRG (#426)
* openmp denominator related lines * also for t1 * another version
1 parent 5b91649 commit 84b77fe

File tree

6 files changed

+92
-155
lines changed

6 files changed

+92
-155
lines changed

forte/mrdsrg-spin-adapted/sa_dsrgpt.cc

+12-53
Original file line numberDiff line numberDiff line change
@@ -120,26 +120,12 @@ void SA_DSRGPT::compute_t2_full() {
120120
std::vector<std::string> T2blocks(T2_.block_labels());
121121
if (ccvv_source_ == "ZERO") {
122122
T2blocks.erase(std::remove(T2blocks.begin(), T2blocks.end(), "ccvv"), T2blocks.end());
123-
T2_.block("ccvv").iterate([&](const std::vector<size_t>& i, double& value) {
124-
size_t i0 = core_mos_[i[0]];
125-
size_t i1 = core_mos_[i[1]];
126-
size_t i2 = virt_mos_[i[2]];
127-
size_t i3 = virt_mos_[i[3]];
128-
value /= Fdiag_[i0] + Fdiag_[i1] - Fdiag_[i2] - Fdiag_[i3];
129-
});
123+
apply_denominator(T2_, {"ccvv"}, [&](double d) { return 1.0 / d; });
130124
}
131125

132126
// build T2
133-
for (const std::string& block : T2blocks) {
134-
T2_.block(block).iterate([&](const std::vector<size_t>& i, double& value) {
135-
size_t i0 = label_to_spacemo_[block[0]][i[0]];
136-
size_t i1 = label_to_spacemo_[block[1]][i[1]];
137-
size_t i2 = label_to_spacemo_[block[2]][i[2]];
138-
size_t i3 = label_to_spacemo_[block[3]][i[3]];
139-
double denom = Fdiag_[i0] + Fdiag_[i1] - Fdiag_[i2] - Fdiag_[i3];
140-
value *= dsrg_source_->compute_renormalized_denominator(denom);
141-
});
142-
}
127+
apply_denominator(T2_, T2blocks,
128+
[&](double v) { return dsrg_source_->compute_renormalized_denominator(v); });
143129

144130
// transform back to non-canonical basis
145131
if (!semi_canonical_) {
@@ -183,21 +169,12 @@ void SA_DSRGPT::compute_t1() {
183169
std::vector<std::string> T1blocks(T1_.block_labels());
184170
if (ccvv_source_ == "ZERO") {
185171
T1blocks.erase(std::remove(T1blocks.begin(), T1blocks.end(), "cv"), T1blocks.end());
186-
T1_.block("cv").iterate([&](const std::vector<size_t>& i, double& value) {
187-
size_t i0 = core_mos_[i[0]];
188-
size_t i1 = virt_mos_[i[1]];
189-
value /= Fdiag_[i0] - Fdiag_[i1];
190-
});
172+
apply_denominator(T1_, {"cv"}, [](double d) { return 1.0 / d; });
191173
}
192174

193175
// build T1
194-
for (const std::string& block : T1blocks) {
195-
T1_.block(block).iterate([&](const std::vector<size_t>& i, double& value) {
196-
size_t i0 = label_to_spacemo_[block[0]][i[0]];
197-
size_t i1 = label_to_spacemo_[block[1]][i[1]];
198-
value *= dsrg_source_->compute_renormalized_denominator(Fdiag_[i0] - Fdiag_[i1]);
199-
});
200-
}
176+
apply_denominator(T1_, T1blocks,
177+
[&](double d) { return dsrg_source_->compute_renormalized_denominator(d); });
201178

202179
// transform back to non-canonical basis
203180
if (!semi_canonical_) {
@@ -230,27 +207,11 @@ void SA_DSRGPT::renormalize_integrals(bool add) {
230207
}
231208

232209
if (add) {
233-
for (const std::string& block : Vblocks) {
234-
V_.block(block).iterate([&](const std::vector<size_t>& i, double& value) {
235-
size_t i0 = label_to_spacemo_[block[0]][i[0]];
236-
size_t i1 = label_to_spacemo_[block[1]][i[1]];
237-
size_t i2 = label_to_spacemo_[block[2]][i[2]];
238-
size_t i3 = label_to_spacemo_[block[3]][i[3]];
239-
double denom = Fdiag_[i0] + Fdiag_[i1] - Fdiag_[i2] - Fdiag_[i3];
240-
value *= 1.0 + dsrg_source_->compute_renormalized(denom);
241-
});
242-
}
210+
apply_denominator(V_, Vblocks,
211+
[&](double d) { return 1.0 + dsrg_source_->compute_renormalized(d); });
243212
} else {
244-
for (const std::string& block : Vblocks) {
245-
V_.block(block).iterate([&](const std::vector<size_t>& i, double& value) {
246-
size_t i0 = label_to_spacemo_[block[0]][i[0]];
247-
size_t i1 = label_to_spacemo_[block[1]][i[1]];
248-
size_t i2 = label_to_spacemo_[block[2]][i[2]];
249-
size_t i3 = label_to_spacemo_[block[3]][i[3]];
250-
double denom = Fdiag_[i0] + Fdiag_[i1] - Fdiag_[i2] - Fdiag_[i3];
251-
value *= dsrg_source_->compute_renormalized(denom);
252-
});
253-
}
213+
apply_denominator(V_, Vblocks,
214+
[&](double d) { return dsrg_source_->compute_renormalized(d); });
254215
}
255216

256217
// transform back if necessary
@@ -283,10 +244,8 @@ void SA_DSRGPT::renormalize_integrals(bool add) {
283244
}
284245

285246
// scale by exp(-s * D^2)
286-
temp.iterate([&](const std::vector<size_t>& i, const std::vector<SpinType>&, double& value) {
287-
double denom = Fdiag_[i[0]] - Fdiag_[i[1]];
288-
value *= dsrg_source_->compute_renormalized(denom);
289-
});
247+
apply_denominator(temp, temp.block_labels(),
248+
[&](double d) { return dsrg_source_->compute_renormalized(d); });
290249

291250
// transform back if necessary
292251
if (!semi_canonical_) {

forte/mrdsrg-spin-adapted/sa_mrdsrg_amps.cc

+18-80
Original file line numberDiff line numberDiff line change
@@ -95,26 +95,11 @@ void SA_MRDSRG::guess_t2_impl(BlockedTensor& T2) {
9595
std::vector<std::string> T2blocks(T2.block_labels());
9696
if (ccvv_source_ == "ZERO") {
9797
T2blocks.erase(std::remove(T2blocks.begin(), T2blocks.end(), "ccvv"), T2blocks.end());
98-
T2.block("ccvv").iterate([&](const std::vector<size_t>& i, double& value) {
99-
size_t i0 = core_mos_[i[0]];
100-
size_t i1 = core_mos_[i[1]];
101-
size_t i2 = virt_mos_[i[2]];
102-
size_t i3 = virt_mos_[i[3]];
103-
104-
value /= Fdiag_[i0] + Fdiag_[i1] - Fdiag_[i2] - Fdiag_[i3];
105-
});
98+
apply_denominator(T2, {"ccvv"}, [](double d) { return 1.0 / d; });
10699
}
107100

108-
for (const std::string& block : T2blocks) {
109-
T2.block(block).iterate([&](const std::vector<size_t>& i, double& value) {
110-
size_t i0 = label_to_spacemo_[block[0]][i[0]];
111-
size_t i1 = label_to_spacemo_[block[1]][i[1]];
112-
size_t i2 = label_to_spacemo_[block[2]][i[2]];
113-
size_t i3 = label_to_spacemo_[block[3]][i[3]];
114-
double denom = Fdiag_[i0] + Fdiag_[i1] - Fdiag_[i2] - Fdiag_[i3];
115-
value *= dsrg_source_->compute_renormalized_denominator(denom);
116-
});
117-
}
101+
apply_denominator(T2, T2blocks,
102+
[&](double d) { return dsrg_source_->compute_renormalized_denominator(d); });
118103

119104
// transform back to non-canonical basis
120105
if (!semi_canonical_) {
@@ -161,22 +146,12 @@ void SA_MRDSRG::guess_t1(BlockedTensor& F, BlockedTensor& T2, BlockedTensor& T1)
161146
std::vector<std::string> T1blocks(T1.block_labels());
162147
if (ccvv_source_ == "ZERO") {
163148
T1blocks.erase(std::remove(T1blocks.begin(), T1blocks.end(), "cv"), T1blocks.end());
164-
T1.block("cv").iterate([&](const std::vector<size_t>& i, double& value) {
165-
size_t i0 = core_mos_[i[0]];
166-
size_t i1 = virt_mos_[i[1]];
167-
168-
value /= Fdiag_[i0] - Fdiag_[i1];
169-
});
149+
apply_denominator(T1, {"cv"}, [](double d) { return 1.0 / d; });
170150
}
171151

172-
for (const std::string& block : T1blocks) {
173-
T1.block(block).iterate([&](const std::vector<size_t>& i, double& value) {
174-
size_t i0 = label_to_spacemo_[block[0]][i[0]];
175-
size_t i1 = label_to_spacemo_[block[1]][i[1]];
176-
value *=
177-
dsrg_source_->compute_renormalized_denominator(Fdiag_[i0] - Fdiag_[i1]);
178-
});
179-
}
152+
apply_denominator(T1, T1blocks, [&](double d) {
153+
return dsrg_source_->compute_renormalized_denominator(d);
154+
});
180155

181156
// transform back to non-canonical basis
182157
if (!semi_canonical_) {
@@ -230,25 +205,11 @@ void SA_MRDSRG::update_t2() {
230205
timer t2("scale Hbar2 by renormalized denominator");
231206
// scale Hbar2 by renormalized denominator
232207
if (ccvv_source_ == "ZERO") {
233-
DT2_.block("ccvv").iterate([&](const std::vector<size_t>& i, double& value) {
234-
size_t i0 = core_mos_[i[0]];
235-
size_t i1 = core_mos_[i[1]];
236-
size_t i2 = virt_mos_[i[2]];
237-
size_t i3 = virt_mos_[i[3]];
238-
value /= Fdiag_[i0] + Fdiag_[i1] - Fdiag_[i2] - Fdiag_[i3];
239-
});
208+
apply_denominator(DT2_, {"ccvv"}, [](double d) { return 1.0 / d; });
240209
}
241210

242-
for (const std::string& block : T2blocks) {
243-
DT2_.block(block).iterate([&](const std::vector<size_t>& i, double& value) {
244-
size_t i0 = label_to_spacemo_[block[0]][i[0]];
245-
size_t i1 = label_to_spacemo_[block[1]][i[1]];
246-
size_t i2 = label_to_spacemo_[block[2]][i[2]];
247-
size_t i3 = label_to_spacemo_[block[3]][i[3]];
248-
double denom = Fdiag_[i0] + Fdiag_[i1] - Fdiag_[i2] - Fdiag_[i3];
249-
value *= dsrg_source_->compute_renormalized_denominator(denom);
250-
});
251-
}
211+
apply_denominator(DT2_, T2blocks,
212+
[&](double d) { return dsrg_source_->compute_renormalized_denominator(d); });
252213
t2.stop();
253214

254215
// Step 2: work on T2 where Hbar2 is treated as intermediate
@@ -269,16 +230,8 @@ void SA_MRDSRG::update_t2() {
269230

270231
timer t6("scale T2 by delta exponential");
271232
// scale T2 by delta exponential
272-
for (const std::string& block : T2blocks) {
273-
T2_.block(block).iterate([&](const std::vector<size_t>& i, double& value) {
274-
size_t i0 = label_to_spacemo_[block[0]][i[0]];
275-
size_t i1 = label_to_spacemo_[block[1]][i[1]];
276-
size_t i2 = label_to_spacemo_[block[2]][i[2]];
277-
size_t i3 = label_to_spacemo_[block[3]][i[3]];
278-
double denom = Fdiag_[i0] + Fdiag_[i1] - Fdiag_[i2] - Fdiag_[i3];
279-
value *= dsrg_source_->compute_renormalized(denom);
280-
});
281-
}
233+
apply_denominator(T2_, T2blocks,
234+
[&](double d) { return dsrg_source_->compute_renormalized(d); });
282235
if (ccvv_source_ == "ZERO") {
283236
T2_.block("ccvv").zero();
284237
}
@@ -349,21 +302,11 @@ void SA_MRDSRG::update_t1() {
349302

350303
// scale Hbar1 by renormalized denominator
351304
if (ccvv_source_ == "ZERO") {
352-
DT1_.block("cv").iterate([&](const std::vector<size_t>& i, double& value) {
353-
size_t i0 = core_mos_[i[0]];
354-
size_t i1 = virt_mos_[i[1]];
355-
value /= Fdiag_[i0] - Fdiag_[i1];
356-
});
305+
apply_denominator(DT1_, {"cv"}, [](double d) { return 1.0 / d; });
357306
}
358307

359-
for (const std::string& block : T1blocks) {
360-
DT1_.block(block).iterate([&](const std::vector<size_t>& i, double& value) {
361-
size_t i0 = label_to_spacemo_[block[0]][i[0]];
362-
size_t i1 = label_to_spacemo_[block[1]][i[1]];
363-
double denom = Fdiag_[i0] - Fdiag_[i1];
364-
value *= dsrg_source_->compute_renormalized_denominator(denom);
365-
});
366-
}
308+
apply_denominator(DT1_, T1blocks,
309+
[&](double d) { return dsrg_source_->compute_renormalized_denominator(d); });
367310

368311
// Step 2: work on T1 where Hbar1 is treated as intermediate
369312

@@ -379,14 +322,9 @@ void SA_MRDSRG::update_t1() {
379322
}
380323

381324
// scale T1 by delta exponential
382-
for (const std::string& block : T1blocks) {
383-
T1_.block(block).iterate([&](const std::vector<size_t>& i, double& value) {
384-
size_t i0 = label_to_spacemo_[block[0]][i[0]];
385-
size_t i1 = label_to_spacemo_[block[1]][i[1]];
386-
double denom = Fdiag_[i0] - Fdiag_[i1];
387-
value *= dsrg_source_->compute_renormalized(denom);
388-
});
389-
}
325+
apply_denominator(T1_, T1blocks,
326+
[&](double d) { return dsrg_source_->compute_renormalized(d); });
327+
390328
if (ccvv_source_ == "ZERO") {
391329
T1_.block("cv").zero();
392330
}

forte/mrdsrg-spin-adapted/sa_mrpt2.cc

+2-4
Original file line numberDiff line numberDiff line change
@@ -377,10 +377,8 @@ void SA_MRPT2::compute_t2_df_minimal() {
377377
}
378378

379379
// build T2
380-
T2_.iterate([&](const std::vector<size_t>& i, const std::vector<SpinType>&, double& value) {
381-
double denom = Fdiag_[i[0]] + Fdiag_[i[1]] - Fdiag_[i[2]] - Fdiag_[i[3]];
382-
value *= dsrg_source_->compute_renormalized_denominator(denom);
383-
});
380+
apply_denominator(T2_, T2_.block_labels(),
381+
[&](double v) { return dsrg_source_->compute_renormalized_denominator(v); });
384382

385383
// transform back to non-canonical basis
386384
if (!semi_canonical_) {

forte/mrdsrg-spin-adapted/sadsrg.cc

+47
Original file line numberDiff line numberDiff line change
@@ -1210,6 +1210,53 @@ ambit::Tensor SADSRG::read_Bcanonical(const std::string& block,
12101210
return T;
12111211
}
12121212

1213+
void SADSRG::apply_denominator(ambit::BlockedTensor& T, const std::vector<std::string>& Tblocks,
1214+
std::function<double(double)> func) {
1215+
for (const std::string& block : Tblocks) {
1216+
auto _bsize = block.size();
1217+
if (!T.is_block(block) or (_bsize != 2 and _bsize != 4))
1218+
continue;
1219+
1220+
auto size = T.block(block).numel();
1221+
size_t _size = 1;
1222+
for (char i : block) {
1223+
if (label_to_spacemo_.find(i) != label_to_spacemo_.end())
1224+
_size *= label_to_spacemo_[i].size();
1225+
}
1226+
if (size != _size)
1227+
continue;
1228+
1229+
auto& data = T.block(block).data();
1230+
int nthreads = omp_get_max_threads();
1231+
if (size < static_cast<size_t>(nthreads))
1232+
nthreads = size;
1233+
1234+
if (_bsize == 2) {
1235+
auto s1 = label_to_spacemo_[block[1]].size();
1236+
#pragma omp parallel for num_threads(nthreads)
1237+
for (size_t i = 0; i < size; ++i) {
1238+
auto n0 = label_to_spacemo_[block[0]][i / s1];
1239+
auto n1 = label_to_spacemo_[block[1]][i % s1];
1240+
data[i] *= func(Fdiag_[n0] - Fdiag_[n1]);
1241+
}
1242+
} else if (_bsize == 4) {
1243+
auto s3 = label_to_spacemo_[block[3]].size();
1244+
auto s2 = label_to_spacemo_[block[2]].size();
1245+
auto s1 = label_to_spacemo_[block[1]].size();
1246+
auto s23 = s2 * s3;
1247+
auto s123 = s1 * s23;
1248+
#pragma omp parallel for num_threads(nthreads)
1249+
for (size_t i = 0; i < size; ++i) {
1250+
auto n0 = label_to_spacemo_[block[0]][i / s123];
1251+
auto n1 = label_to_spacemo_[block[1]][(i / s23) % s1];
1252+
auto n2 = label_to_spacemo_[block[2]][(i % s23) / s3];
1253+
auto n3 = label_to_spacemo_[block[3]][i % s3];
1254+
data[i] *= func(Fdiag_[n0] + Fdiag_[n1] - Fdiag_[n2] - Fdiag_[n3]);
1255+
}
1256+
}
1257+
}
1258+
}
1259+
12131260
void SADSRG::print_contents(const std::string& str, size_t size) {
12141261
if (str.size() + 4 > size)
12151262
size = str.size() + 4;

forte/mrdsrg-spin-adapted/sadsrg.h

+9-4
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ class SADSRG : public DynamicCorrelationSolver {
7070
void set_Uactv(ambit::Tensor& U);
7171

7272
/// If the amplitudes are converged or not
73-
bool converged() {return converged_; }
73+
bool converged() { return converged_; }
7474

7575
protected:
7676
/// Startup function called in constructor
@@ -380,9 +380,10 @@ class SADSRG : public DynamicCorrelationSolver {
380380
double H2_T1_C0(BlockedTensor& H2, BlockedTensor& T1, const double& alpha, double& C0);
381381
/// Compute zero-body term of commutator [H2, T2], S2[ijab] = 2 * T[ijab] - T[ijba]
382382
std::vector<double> H2_T2_C0(BlockedTensor& H2, BlockedTensor& T2, BlockedTensor& S2,
383-
const double& alpha, double& C0, bool load_mps=false);
383+
const double& alpha, double& C0, bool load_mps = false);
384384
/// Compute zero-body term of commutator [H2, T2], T2 and S2 contain at least two active indices
385-
std::vector<double> H2_T2_C0_T2small(BlockedTensor& H2, BlockedTensor& T2, BlockedTensor& S2, bool load_mps=false);
385+
std::vector<double> H2_T2_C0_T2small(BlockedTensor& H2, BlockedTensor& T2, BlockedTensor& S2,
386+
bool load_mps = false);
386387

387388
/// Compute one-body term of commutator [H1, T1]
388389
void H1_T1_C1(BlockedTensor& H1, BlockedTensor& T1, const double& alpha, BlockedTensor& C1);
@@ -406,7 +407,7 @@ class SADSRG : public DynamicCorrelationSolver {
406407
void V_T1_C0_DF(BlockedTensor& B, BlockedTensor& T1, const double& alpha, double& C0);
407408
/// Compute zero-body term of commutator [V, T2], V is constructed from B (DF/CD)
408409
std::vector<double> V_T2_C0_DF(BlockedTensor& B, BlockedTensor& T1, BlockedTensor& S2,
409-
const double& alpha, double& C0, bool load_mps=false);
410+
const double& alpha, double& C0, bool load_mps = false);
410411

411412
/// Compute one-body term of commutator [V, T1], V is constructed from B (DF/CD)
412413
void V_T1_C1_DF(BlockedTensor& B, BlockedTensor& T1, const double& alpha, BlockedTensor& C1);
@@ -478,6 +479,10 @@ class SADSRG : public DynamicCorrelationSolver {
478479

479480
// ==> common amplitudes analysis and printing <==
480481

482+
/// Apply denominator to BlockedTensor T (only 1- and 2-body)
483+
void apply_denominator(ambit::BlockedTensor& T, const std::vector<std::string>& Tblocks,
484+
std::function<double(double)> func);
485+
481486
/// Prune internal amplitudes for T1
482487
void internal_amps_T1(BlockedTensor& T1);
483488
/// Prune internal amplitudes for T2

0 commit comments

Comments
 (0)