Parallel calculation of Array2<f64>
values
#1273
-
Hey, I have tried 2 ways, but I think due to my understanding of
//* Step 2.1: Calculate the overlap matrix S
let S_matr_tmp = Array2::<f64>::zeros((n, n));
let S_matr_mutex = Mutex::new(S_matr_tmp);
(0..n).into_par_iter().for_each(|i| {
(0..=i).into_par_iter().for_each(|j| {
let mut s = S_matr_mutex.lock().unwrap();
if i == j {
s[(i, j)] = 1.0;
// s = 1.0;
} else {
s[(i, j)] = calc_overlap_int_cgto(
&self.mol.wfn_total.basis_set_total.basis_set_cgtos[i],
&self.mol.wfn_total.basis_set_total.basis_set_cgtos[j],
);
s[(j, i)] = s[(i, j)];
}
})
});
self.mol.wfn_total.HF_Matrices.S_matr = S_matr_mutex.into_inner().unwrap();
let D_matr_mutex = Mutex::new(Array2::<f64>::zeros((no_cgtos, no_cgtos)));
//* D^0 matrix */
//* Trying to parallelize it */
Zip::indexed(C_matr_AO_basis.axis_iter(Axis(0))).par_for_each(|mu, row1| {
Zip::indexed(C_matr_AO_basis.outer_iter()).par_for_each(|nu, row2| {
let mut d = D_matr_mutex.lock().unwrap();
let slice1 = row1.slice(s![..no_occ_orb]);
let slice2 = row2.slice(s![..no_occ_orb]);
d[(mu, nu)] = slice1.dot(&slice2);
});
});
let mut D_matr = D_matr_mutex.into_inner().unwrap();
let F_matr_mutex = Mutex::new(F_matr);
(0..no_cgtos).into_par_iter().for_each(|mu| {
(0..no_cgtos).into_par_iter().for_each(|nu| {
(0..no_cgtos).into_par_iter().for_each(|lambda| {
(0..no_cgtos).into_par_iter().for_each(|sigma| {
let mu_nu_lambda_sigma =
calc_ijkl_idx(mu + 1, nu + 1, lambda + 1, sigma + 1);
let mu_lambda_nu_sigma =
calc_ijkl_idx(mu + 1, lambda + 1, nu + 1, sigma + 1);
let mut f = F_matr_mutex.lock().unwrap();
f[(mu, nu)] += D_matr[(lambda, sigma)]
* (2.0
* self.mol.wfn_total.HF_Matrices.ERI_arr1[mu_nu_lambda_sigma]
- self.mol.wfn_total.HF_Matrices.ERI_arr1[mu_lambda_nu_sigma]);
});
});
});
});
let F_matr = F_matr_mutex.into_inner().unwrap(); Any help on how to parallelize the code "correctly" and more information on how to use |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 6 replies
-
Sorry for the very brief answer, but I think your best bet is to use the |
Beta Was this translation helpful? Give feedback.
-
@adamreichold Thank you for your hint. After a lot of trying around and not too much documentation, I found a way to do this, but I am convinced that this solution is "awful". There is definetely a better way of doing this, but this seemed to work: //* New version: par_map_assign_into */
let S_matr_tmp = Array2::<f64>::zeros((n, n));
self.mol.wfn_total.HF_Matrices.S_matr = Array2::<f64>::zeros((n, n));
Zip::indexed(&S_matr_tmp).par_map_assign_into(
&mut self.mol.wfn_total.HF_Matrices.S_matr,
|(i, j), x| {
if i == j {
1.0
} else {
calc_overlap_int_cgto(
&self.mol.wfn_total.basis_set_total.basis_set_cgtos[i],
&self.mol.wfn_total.basis_set_total.basis_set_cgtos[j],
)
}
},
); The main problem is that I need the index to access the Any help would be deeply appreciated. :) |
Beta Was this translation helpful? Give feedback.
@adamreichold Thank you for your hint.
After a lot of trying around and not too much documentation, I found a way to do this, but I am convinced that this solution is "awful". There is definetely a better way of doing this, but this seemed to work: