Skip to content

Commit a653623

Browse files
committed
Process in debuging TI
1 parent 6663360 commit a653623

20 files changed

Lines changed: 2480 additions & 763 deletions

cpp/common/molecular/MMFFsp3_loc.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,7 @@ void clone( MMFFsp3_loc& from, bool bRealloc, bool bREQsDeep=true ){
189189
neighCell[i]=from.neighCell[i];
190190
bkneighs [i]=from.bkneighs [i];
191191
constr [i]=from.constr [i];
192+
constrK [i]=from.constrK [i];
192193
}
193194
for(int i=0; i<nnode; i++){
194195
apars[i]=from.apars[i];

cpp/common/molecular/MolWorld_sp3_multi.h

Lines changed: 302 additions & 91 deletions
Large diffs are not rendered by default.

cpp/common_resources/cl/relax_multi.cl

Lines changed: 134 additions & 132 deletions
Large diffs are not rendered by default.

cpp/libs_OCL/MMFFmulti_lib.cpp

Lines changed: 167 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
#include <thread>
1010
#include <chrono>
11+
#include <vector>
1112

1213
// ============ Global Variables
1314

@@ -20,6 +21,106 @@ MolWorld_sp3_multi W;
2021

2122
extern "C"{
2223

24+
static void assembleMMFFforcesFromRecoil(){
25+
const int nvecTot = W.ocl.nvecs * W.nSystems;
26+
const int nbkTot = W.ocl.nbkng * W.nSystems;
27+
static std::vector<Quat4f> neighForce;
28+
neighForce.resize(nbkTot);
29+
30+
int err=0;
31+
err |= W.ocl.download( W.ocl.ibuff_aforces, W.aforces );
32+
err |= W.ocl.download( W.ocl.ibuff_neighForce, neighForce.data() );
33+
err |= W.ocl.finishRaw();
34+
OCL_checkError(err, "assembleMMFFforcesFromRecoil().download");
35+
36+
for(int i=0; i<nvecTot; i++){
37+
Quat4f fe = W.aforces[i];
38+
const Quat4i ngs = W.bkNeighs[i];
39+
if(ngs.x>=0){ const Quat4f& q = neighForce[ngs.x]; fe.x+=q.x; fe.y+=q.y; fe.z+=q.z; fe.w+=q.w; }
40+
if(ngs.y>=0){ const Quat4f& q = neighForce[ngs.y]; fe.x+=q.x; fe.y+=q.y; fe.z+=q.z; fe.w+=q.w; }
41+
if(ngs.z>=0){ const Quat4f& q = neighForce[ngs.z]; fe.x+=q.x; fe.y+=q.y; fe.z+=q.z; fe.w+=q.w; }
42+
if(ngs.w>=0){ const Quat4f& q = neighForce[ngs.w]; fe.x+=q.x; fe.y+=q.y; fe.z+=q.z; fe.w+=q.w; }
43+
W.aforces[i] = fe;
44+
}
45+
}
46+
47+
static void copySystemGeometryToFF4( int isys ){
48+
const int i0v = isys * W.ocl.nvecs;
49+
for(int i=0; i<W.ff4.nvecs; i++){
50+
W.ff4.apos[i] = W.atoms[i0v+i];
51+
}
52+
53+
Mat3d lvec;
54+
Mat3_from_cl( lvec, W.lvecs[isys] );
55+
W.ff4.setLvec( (Mat3f)lvec );
56+
W.ff4.makeNeighCells( W.bPBC ? W.nPBC : Vec3iZero );
57+
}
58+
59+
static void packMMFFforcesToGPUBuffer( int isys, MMFFf4& ff ){
60+
const int i0v = isys * W.ocl.nvecs;
61+
for(int i=0; i<ff.nvecs; i++){
62+
W.aforces[i0v+i] = ff.fapos[i];
63+
}
64+
}
65+
66+
static void setupTIConstraintsBatch_( int nCVs, Vec3f* initial_positions, Vec3f* final_positions, int nLambda, int batch ){
67+
const Quat4f no_constr = Quat4f{0.0f, 0.0f, 0.0f, -1.0f};
68+
const Quat4f no_constrK = Quat4fZero;
69+
for(int isys=0; isys<W.nSystems; isys++){
70+
const int i0a = isys * W.ocl.nAtoms;
71+
for(int ia=0; ia<W.ocl.nAtoms; ia++){
72+
W.constr [i0a + ia] = no_constr;
73+
W.constrK[i0a + ia] = no_constrK;
74+
}
75+
const int il = isys + batch*W.nSystems;
76+
if(il >= nLambda) continue;
77+
const float lambda = (nLambda > 1) ? ((float)il / (float)(nLambda - 1)) : 0.0f;
78+
79+
int si_count = 0;
80+
for(int ia=0; ia<W.ffls[isys].natoms; ia++){
81+
if(W.ffls[isys].atypes[ia] != W.params.getAtomType("Si")) continue;
82+
if(si_count < nCVs){
83+
Quat4f acon = Quat4f{0.0f,0.0f,0.0f,0.0f};
84+
acon.f.set_sub(final_positions[si_count], initial_positions[si_count]);
85+
acon.f.mul(lambda);
86+
acon.f.add(initial_positions[si_count]);
87+
acon.w = 1e6f * (float)(si_count % 2 + 1);
88+
89+
Quat4f aconK = Quat4f{0.0f,0.0f,0.0f, acon.w};
90+
aconK.f.set_sub(final_positions[si_count], initial_positions[si_count]);
91+
92+
W.constr [isys*W.ocl.nAtoms + ia] = acon;
93+
W.constrK[isys*W.ocl.nAtoms + ia] = aconK;
94+
}
95+
si_count++;
96+
}
97+
}
98+
int err = 0;
99+
err |= W.ocl.upload( W.ocl.ibuff_constr, W.constr );
100+
err |= W.ocl.upload( W.ocl.ibuff_constrK, W.constrK );
101+
err |= W.ocl.finishRaw();
102+
OCL_checkError(err, "setupTIConstraintsBatch_().upload");
103+
}
104+
105+
static void zeroTIAverageForces_(){
106+
for(int isys=0; isys<W.nSystems; isys++) W.averageForces[isys] = Quat4fZero;
107+
int err = 0;
108+
err |= W.ocl.upload( W.ocl.ibuff_averageForces, W.averageForces );
109+
err |= W.ocl.finishRaw();
110+
OCL_checkError(err, "zeroTIAverageForces_().upload");
111+
}
112+
113+
static void downloadTIAverageForces_(){
114+
int err = 0;
115+
err |= W.ocl.download( W.ocl.ibuff_averageForces, W.averageForces );
116+
err |= W.ocl.finishRaw();
117+
OCL_checkError(err, "downloadTIAverageForces_().download");
118+
}
119+
120+
static void resetTIBatchState_(){
121+
W.resetTIBatchState(true);
122+
}
123+
23124
void init_buffers(){
24125
buffers .insert( { "apos", (double*)W.nbmol.apos } );
25126
buffers .insert( { "fapos", (double*)W.nbmol.fapos } );
@@ -48,6 +149,8 @@ void init_buffers(){
48149
fbuffers.insert( { "gpu_aforces", (float*)W.aforces } );
49150
fbuffers.insert( { "gpu_avel", (float*)W.avel } );
50151
fbuffers.insert( { "gpu_constr", (float*)W.constr } );
152+
fbuffers.insert( { "gpu_constrK", (float*)W.constrK } );
153+
fbuffers.insert( { "gpu_averageForces", (float*)W.averageForces } );
51154

52155
fbuffers.insert( { "gpu_REQs", (float*)W.REQs } );
53156
fbuffers.insert( { "gpu_MMpars", (float*)W.MMpars } );
@@ -132,13 +235,65 @@ int run( int nstepMax, double dt, double Fconv, int ialg, double* outE, double*
132235
//return W.run(nstepMax,dt,Fconv,ialg,outE,outF);
133236
}
134237

238+
void eval_getMMFFf4_ocl(){
239+
if( W.task_MMFF == 0 ) W.setup_MMFFf4_ocl();
240+
int err=0;
241+
err |= W.task_cleanF->enque_raw();
242+
err |= W.task_MMFF ->enque_raw();
243+
err |= W.ocl.finishRaw();
244+
OCL_checkError(err, "eval_getMMFFf4_ocl");
245+
assembleMMFFforcesFromRecoil();
246+
}
247+
248+
void eval_getMMFFf4_cpu(){
249+
W.download( false, false );
250+
for(int isys=0; isys<W.nSystems; isys++){
251+
copySystemGeometryToFF4( isys );
252+
W.ff4.eval();
253+
packMMFFforcesToGPUBuffer( isys, W.ff4 );
254+
}
255+
}
256+
135257
void MDloop( int perframe, double Ftol = -1, int iParalel = 3, int perVF = 100 ){
136258
W.iParalel = iParalel;
137259
W.nPerVFs = perVF;
138260
W.iterPerFrame = perframe;
139261
W.MDloop( perframe, Ftol );
140262
}
141263

264+
void setupTIConstraintsBatch( int nCVs, float* initial_positions, float* final_positions, int nLambda, int batch ){
265+
setupTIConstraintsBatch_( nCVs, (Vec3f*)initial_positions, (Vec3f*)final_positions, nLambda, batch );
266+
}
267+
268+
void zeroTIAverageForces(){
269+
zeroTIAverageForces_();
270+
}
271+
272+
void downloadTIAverageForces(){
273+
downloadTIAverageForces_();
274+
}
275+
276+
void resetTIBatchState(){
277+
resetTIBatchState_();
278+
}
279+
280+
void getTIHostEstimator( int isys, int nLambda, int nMDsteps, double* out ){
281+
const int nProdStepsPerLambda = nMDsteps / nLambda;
282+
const double force_scale = 1.0*nLambda / (double)(nMDsteps);
283+
const double force_sum = W.averageForces[isys].z + W.averageForces[isys].w;
284+
const double dE = -force_sum * force_scale;
285+
const double mean_sq = W.averageForces[isys].x * force_scale;
286+
const double var = mean_sq - dE*dE;
287+
const double SD = sqrt(fabs(var));
288+
const double SEM = SD / sqrt((double)nProdStepsPerLambda);
289+
out[0] = force_sum;
290+
out[1] = dE;
291+
out[2] = mean_sq;
292+
out[3] = SEM;
293+
out[4] = force_scale;
294+
out[5] = (double)nProdStepsPerLambda;
295+
}
296+
142297
void set_opt(
143298
double dt_max, double dt_min, double damp_max,
144299
double finc, double fdec, double falpha, int minLastNeg,
@@ -329,8 +484,18 @@ void setSwitches_multi( int CheckInvariants, int PBC, int NonBonded, int MMFF, i
329484
}
330485

331486

332-
double computeFreeEnergy(int nCVs, float* initial_positions, float* final_positions, int nLambda, int nMDsteps, int nEQsteps, double Fconv, int mode, double JEforceconst){
333-
return W.computeFreeEnergy(nCVs, (Vec3f*)initial_positions, (Vec3f*)final_positions, nLambda, nMDsteps, nEQsteps, Fconv, mode, JEforceconst);
487+
void setConstraints( int hardAtoms, int softAtoms, int hardDist, int softDist, int initial ){
488+
#define _setbool(b,i) { if(i>0){b=true;}else if(i<0){b=false;} }
489+
_setbool( W.bHardConstrainedAtoms, hardAtoms );
490+
_setbool( W.bSoftConstrainedAtoms, softAtoms );
491+
_setbool( W.bHardConstrainedDistance, hardDist );
492+
_setbool( W.bSoftConstrainedDistance, softDist );
493+
_setbool( W.initial, initial );
494+
#undef _setbool
495+
}
496+
497+
double computeFreeEnergy(int nCVs, float* initial_positions, float* final_positions, int nLambda, int nMDsteps, int nEQsteps, double Fconv, int mode, double K, int hardAtoms, int softAtoms, int hardDist, int softDist){
498+
return W.computeFreeEnergy(nCVs, (Vec3f*)initial_positions, (Vec3f*)final_positions, nLambda, nMDsteps, nEQsteps, Fconv, mode, K, hardAtoms, softAtoms, hardDist, softDist);
334499
}
335500

336501
} // extern "C"

examples/tFreeEnergy_multi/FREE_ENERGY_TESTING_TUTORIAL.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ python3 run_ES.py \
5555
--nEQsteps 300 \
5656
--Fconv 1e-6 \
5757
--constraints constraints_ES.txt \
58-
--JEforceconst 2.0 \
58+
--K 2.0 \
5959
--dt 0.05 \
6060
-T 300 \
6161
--t_damp 150

examples/tFreeEnergy_multi/collect_ES_summary.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ def mk_hover(r: Dict[str, object], yname: str, yval: float) -> str:
8686
f"set={r.get('param_set','')}<br>"
8787
f"mode={r.get('mode')} N={r.get('N')}<br>"
8888
f"nSys={r.get('nSys')} nLambda={r.get('nLambda')}<br>"
89-
f"nEQ={r.get('nEQsteps')} nMD={r.get('nMDsteps')} JE_K={r.get('JE_K')}<br>"
89+
f"nEQ={r.get('nEQsteps')} nMD={r.get('nMDsteps')} K={r.get('K')}<br>"
9090
f"dt={r.get('dt')} t_damp={r.get('t_damp')}<br>"
9191
f"wall_s={float(r.get('wall_s', float('nan'))):.6g}<br>"
9292
f"{yname}={yval:.6g}<br>"
@@ -271,7 +271,7 @@ def _parse_combo(tag: str) -> Dict[str, object]:
271271
"nLambda": "",
272272
"nEQsteps": "",
273273
"nMDsteps": "",
274-
"JE_K": "",
274+
"K": "",
275275
"dt": "",
276276
"t_damp": "",
277277
"je_target_trajectories": "",
@@ -293,7 +293,7 @@ def _parse_combo(tag: str) -> Dict[str, object]:
293293
out["nMDsteps"] = int(m.group(1))
294294
m = re.search(r"_jek([0-9mp]+)", tag)
295295
if m:
296-
out["JE_K"] = m.group(1).replace("m", "-").replace("p", ".")
296+
out["K"] = m.group(1).replace("m", "-").replace("p", ".")
297297
m = re.search(r"_dt([0-9mp]+)", tag)
298298
if m:
299299
out["dt"] = m.group(1).replace("m", "-").replace("p", ".")
@@ -380,7 +380,7 @@ def main() -> None:
380380
rows.append(row)
381381

382382
fieldnames = [
383-
"status", "N", "mode", "param_set", "nSys", "nLambda", "nEQsteps", "nMDsteps", "JE_K",
383+
"status", "N", "mode", "param_set", "nSys", "nLambda", "nEQsteps", "nMDsteps", "K",
384384
"dt", "t_damp",
385385
"je_target_trajectories", "je_effective_trajectories",
386386
"wall_s", "md_ocl_time_ms_total", "md_ocl_calls", "md_ocl_avg_us_per_step",

examples/tFreeEnergy_multi/plot_F_interactive.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ def get_col(name):
149149

150150
if distances is not None and N_segments is not None:
151151
k_spring = kB * T / (N_segments * b**2)
152-
F_ref = k_spring * distances
152+
F_ref = - k_spring * distances
153153
FE_ref_abs = 0.5 * k_spring * distances**2
154154
FE_ref = FE_ref_abs - FE_ref_abs[0]
155155

@@ -241,7 +241,7 @@ def get_col(name):
241241
dd_dlambda = np.gradient(distances, lambda_vals)
242242
safe_dd = np.copy(dd_dlambda)
243243
safe_dd[np.abs(safe_dd) < 1e-9] = np.nan
244-
force_ti = dE_dlambda / safe_dd
244+
force_ti = -dE_dlambda / safe_dd
245245

246246
hover_text_force_ti = [
247247
f"λ = {lam:.4f}<br>Force (TI) = {f:.4f} eV/Å<br>d = {d:.3f} Å"

0 commit comments

Comments
 (0)