Skip to content

Commit 5d61be5

Browse files
CopilotCstandardlib
andcommitted
fix: dynamically compute mxr in H_Ewald_pw to prevent buffer overflow for small unit cells
Co-authored-by: Cstandardlib <49788094+Cstandardlib@users.noreply.github.com>
1 parent dd4997a commit 5d61be5

1 file changed

Lines changed: 31 additions & 18 deletions

File tree

source/source_hamilt/module_ewald/H_Ewald_pw.cpp

Lines changed: 31 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -50,19 +50,7 @@ double H_Ewald_pw::compute_ewald(const UnitCell& cell,
5050
// buffer variable
5151
// used to optimize alpha
5252

53-
if(PARAM.inp.test_energy)
54-
{
55-
ModuleBase::GlobalFunc::OUT(GlobalV::ofs_running,"mxr",mxr);
56-
}
57-
//r = new ModuleBase::Vector3<double>[mxr];
58-
//r2 = new double[mxr];
59-
//int* irr = new int[mxr];
60-
std::vector<ModuleBase::Vector3<double>> vec_r(mxr);
61-
std::vector<double> vec_r2(mxr);
62-
std::vector<int> vec_irr(mxr);
63-
int* irr = vec_irr.data();
64-
ModuleBase::Vector3<double>* r = vec_r.data();
65-
double* r2 = vec_r2.data();
53+
// (arrays are allocated below, after rmax and mxr are determined)
6654

6755
// (1) calculate total ionic charge
6856
double charge = 0.0;
@@ -158,8 +146,33 @@ double H_Ewald_pw::compute_ewald(const UnitCell& cell,
158146

159147
// R-space sum here (only done for the processor that contains G=0)
160148
ewaldr = 0.0;
161-
#ifdef __MPI
149+
150+
// Compute rmax and dynamically determine mxr (maximum number of r-vectors)
151+
// to avoid buffer overflow for very small unit cells or high cutoff energies.
162152
rmax = 4.0 / sqrt(alpha) / cell.lat0;
153+
{
154+
double bg1[3];
155+
bg1[0] = cell.G.e11; bg1[1] = cell.G.e12; bg1[2] = cell.G.e13;
156+
int nm1 = (int)(dnrm2(3, bg1, 1) * rmax + 2);
157+
bg1[0] = cell.G.e21; bg1[1] = cell.G.e22; bg1[2] = cell.G.e23;
158+
int nm2 = (int)(dnrm2(3, bg1, 1) * rmax + 2);
159+
bg1[0] = cell.G.e31; bg1[1] = cell.G.e32; bg1[2] = cell.G.e33;
160+
int nm3 = (int)(dnrm2(3, bg1, 1) * rmax + 2);
161+
mxr = (2 * nm1 + 1) * (2 * nm2 + 1) * (2 * nm3 + 1);
162+
}
163+
164+
if(PARAM.inp.test_energy)
165+
{
166+
ModuleBase::GlobalFunc::OUT(GlobalV::ofs_running,"mxr",mxr);
167+
}
168+
std::vector<ModuleBase::Vector3<double>> vec_r(mxr);
169+
std::vector<double> vec_r2(mxr);
170+
std::vector<int> vec_irr(mxr);
171+
int* irr = vec_irr.data();
172+
ModuleBase::Vector3<double>* r = vec_r.data();
173+
double* r2 = vec_r2.data();
174+
175+
#ifdef __MPI
163176
if(PARAM.inp.test_energy)
164177
{
165178
ModuleBase::GlobalFunc::OUT(GlobalV::ofs_running,"rmax(unit lat0)",rmax);
@@ -220,8 +233,7 @@ double H_Ewald_pw::compute_ewald(const UnitCell& cell,
220233
#else
221234
if (rho_basis->ig_gge0 >= 0)
222235
{
223-
rmax = 4.0 / sqrt(alpha) / cell.lat0;
224-
if(PARAM.inp.test_energy) ModuleBase::GlobalFunc::OUT(GlobalV::ofs_running,"rmax(unit lat0)",rmax);
236+
if(PARAM.inp.test_energy) ModuleBase::GlobalFunc::OUT(GlobalV::ofs_running,"rmax(unit lat0)",rmax);
225237
// with this choice terms up to ZiZj*erfc(4) are counted (erfc(4)=2x10^-8
226238
int nt1=0;
227239
int nt2=0;
@@ -385,9 +397,10 @@ void H_Ewald_pw::rgen(
385397

386398
if (tt <= rmax * rmax && std::abs(tt) > 1.e-10)
387399
{
388-
if (nrm > mxr)
400+
if (nrm >= mxr)
389401
{
390-
std::cerr << "\n rgen, too many r-vectors," << nrm;
402+
ModuleBase::WARNING_QUIT("rgen", "too many r-vectors (nrm=" + std::to_string(nrm)
403+
+ ", mxr=" + std::to_string(mxr) + "). Please report this issue.");
391404
}
392405
r[nrm] = t;
393406
r2[nrm] = tt;

0 commit comments

Comments
 (0)