1 /**************************************************************************
2 * * Java Grande Forum Benchmark Suite - Thread Version 1.0 * * produced by * *
3 * Java Grande Benchmarking Project * * at * * Edinburgh Parallel Computing
4 * Centre * * email: epcc-javagrande@epcc.ed.ac.uk * * * This version copyright
5 * (c) The University of Edinburgh, 2001. * All rights reserved. * *
6 **************************************************************************/
7 public class JGFMolDynBench {
25 public int interactions;
26 public int[] interacts;
31 public JGFMolDynBench(int nthreads,int workload) {
32 this.nthreads = nthreads;
33 this.workload=workload;
36 public void JGFsetsize(int size) {
40 public void JGFinitialise() {
42 datasizes = new int[3];
48 PARTSIZE = mm * mm * mm * 4;
58 public static void JGFapplication(JGFMolDynBench mold) {
60 double sh_force2[][][];
61 int partsize, numthreads;
62 partsize = mold.PARTSIZE;
63 numthreads = mold.nthreads;
65 sh_force = new double[3][partsize];
66 sh_force2 = new double[3][numthreads][partsize];
67 mold.epot = new double[numthreads];
68 mold.vir = new double[numthreads];
69 mold.ek = new double[numthreads];
70 mold.interacts = new int[numthreads];
71 // for(int i=0;i<numthreads;i++) {
72 // mold.epot[i]=new double();
73 // mold.vir[i]=new double();
74 // mold.ek[i]=new double();
75 // mold.interacts[i]=new IntWrapper();
79 MDWrap[] thobjects = new MDWrap[numthreads];
81 for (int i = 0; i < numthreads; i++) {
82 thobjects[i] = new MDWrap(new mdRunner(i, mold.mm, sh_force, sh_force2, mold.nthreads, mold,mold.workload));
86 * boolean waitfordone=true; while(waitfordone) { if (mybarr.done)
87 * waitfordone=false; }
90 for (int i = 0; i < numthreads; i++) {
91 // thobjects[i].md.start(mid[i]);
92 thobjects[i].md.run();
96 public void JGFvalidate() {
97 double[] refval = new double[2];
98 refval[0] = 1731.4306625334357;
99 refval[1] = 7397.392307839352;
100 double dev = Math.fabs(ek[0] - refval[size]);
102 // System.printString("Validation failed\n");
103 // System.printString("Kinetic Energy = " + (long)ek[0] + " " + (long)dev
104 // + " " + size + "\n");
112 int id, i, j, k, lg, mm;
113 double l, rcoff, rcoffs, side, sideh, hsq, hsq2, vel, velt;
114 double a, r, sum, tscale, sc, ekin, ts, sp;
118 double vaver, vaverh, rand;
119 double etot, temp, pres, rp;
120 double u1, u2, s, xx, yy, zz;
121 double xvelocity, yvelocity, zvelocity;
124 double[][][] sh_force2;
126 int ijk, npartm, iseed, tint;
135 public mdRunner(int id, int mm, double[][] sh_force, double[][][] sh_force2, int nthreads,
136 JGFMolDynBench mymd, int workload) {
139 this.sh_force = sh_force;
140 this.sh_force2 = sh_force2;
141 this.nthreads = nthreads;
150 this.workload=workload;
153 public void init(particle[] one, int mdsize) {
155 for (int lg = 0; lg <= 1; lg++) {
156 for (int i = 0; i < mm; i++) {
157 for (int j = 0; j < mm; j++) {
158 for (int k = 0; k < mm; k++) {
160 new particle((i * a + lg * a * 0.5), (j * a + lg * a * 0.5), (k * a), xvelocity,
161 yvelocity, zvelocity, sh_force, sh_force2, id, one);
168 for (int lg = 1; lg <= 2; lg++) {
169 for (int i = 0; i < mm; i++) {
170 for (int j = 0; j < mm; j++) {
171 for (int k = 0; k < mm; k++) {
173 new particle((i * a + (2 - lg) * a * 0.5), (j * a + (lg - 1) * a * 0.5),
174 (k * a + a * 0.5), xvelocity, yvelocity, zvelocity, sh_force, sh_force2, id,
182 /* Initialise velocities */
187 random randnum = new random(iseed, v1, v2);
189 for (int i = 0; i < mdsize; i += 2) {
191 one[i].xvelocity = r * randnum.v1;
192 one[i + 1].xvelocity = r * randnum.v2;
195 for (int i = 0; i < mdsize; i += 2) {
197 one[i].yvelocity = r * randnum.v1;
198 one[i + 1].yvelocity = r * randnum.v2;
201 for (int i = 0; i < mdsize; i += 2) {
203 one[i].zvelocity = r * randnum.v1;
204 one[i + 1].zvelocity = r * randnum.v2;
207 /* velocity scaling */
212 for (int i = 0; i < mdsize; i++) {
213 sp = sp + one[i].xvelocity;
217 for (int i = 0; i < mdsize; i++) {
218 one[i].xvelocity = one[i].xvelocity - sp;
219 ekin = ekin + one[i].xvelocity * one[i].xvelocity;
223 for (int i = 0; i < mdsize; i++) {
224 sp = sp + one[i].yvelocity;
228 for (int i = 0; i < mdsize; i++) {
229 one[i].yvelocity = one[i].yvelocity - sp;
230 ekin = ekin + one[i].yvelocity * one[i].yvelocity;
234 for (int i = 0; i < mdsize; i++) {
235 sp = sp + one[i].zvelocity;
239 for (int i = 0; i < mdsize; i++) {
240 one[i].zvelocity = one[i].zvelocity - sp;
241 ekin = ekin + one[i].zvelocity * one[i].zvelocity;
245 sc = h * Math.sqrt(tref / ts);
247 for (int i = 0; i < mdsize; i++) {
249 one[i].xvelocity = one[i].xvelocity * sc;
250 one[i].yvelocity = one[i].yvelocity * sc;
251 one[i].zvelocity = one[i].zvelocity * sc;
257 public void doinit(int mdsize) {
258 for (int j = 0; j < 3; j++) {
259 double[] sh = sh_force[j];
260 for (int i = 0; i < mdsize; i++) {
266 public void doinit2(int mdsize) {
267 for (int k = 0; k < 3; k++) {
268 double[] sh = sh_force[k];
269 double[][] sha = sh_force2[k];
270 for (int j = 0; j < nthreads; j++) {
271 double[] sha2 = sha[j];
272 for (int i = 0; i < mdsize; i++) {
278 for (int k = 0; k < 3; k++) {
279 double[][] sh1 = sh_force2[k];
280 for (int j = 0; j < nthreads; j++) {
281 double[] sh2 = sh1[j];
282 for (int i = 0; i < mdsize; i++) {
289 for (int j = 1; j < nthreads; j++) {
290 mymd.epot[0] += mymd.epot[j];
291 mymd.vir[0] += mymd.vir[j];
293 for (int j = 1; j < nthreads; j++) {
294 mymd.epot[j] = mymd.epot[0];
295 mymd.vir[j] = mymd.vir[0];
297 for (int j = 0; j < nthreads; j++) {
298 mymd.interactions += mymd.interacts[j];
301 for (int j = 0; j < 3; j++) {
302 double sh[] = sh_force[j];
303 for (int i = 0; i < mdsize; i++) {
304 sh[i] = sh[i] * hsq2;
310 /* Parameter determination */
318 mdsize = mymd.PARTSIZE;
319 one = new particle[mdsize];
322 side = Math.pow((mdsize / tmpden), 0.3333333);
330 rcoffs = rcoff * rcoff;
331 tscale = 16.0 / (1.0 * mdsize - 1.0);
332 vaver = 1.13 * Math.sqrt(tref / 24.0);
335 /* Particle Generation */
343 /* Synchronise threads and start timer before MD simulation */
347 int numP= (mdsize / workload)+1;
349 double scratchpad[][][];
350 scratchpad=new double[numP][3][mdsize];
352 for (int move = 0; move < movemx; move++) {
353 /* move the particles and update velocities */
354 for (int i = 0; i < mdsize; i++) {
355 one[i].domove(side, i);
364 mymd.interacts[id] = 0;
367 int numThread = nthreads;
368 int lworkload = workload;
369 // for (int i=0+id;i<mdsize;i+=numThread) {
371 for (int i = 0 ; i < mdsize; i += lworkload) {
374 int iupper = i + lworkload;
375 if (iupper > mdsize) {
378 int l_size = iupper - ilow;
380 double workingpad[][]=scratchpad[scratch_idx++];
382 for(int j=0;j<3;j++){
383 for(int l=0;l<mdsize;l++){
387 MDStore store = new MDStore();
388 for(int idx=ilow;idx<iupper;idx++){
389 // one[i].force(side, rcoff, mdsize, i, xx, yy, zz, mymd, worker);
390 one[idx].force(side, rcoff, mdsize, idx, xx, yy, zz, mymd, store,workingpad);
395 for (int k = 0; k < 3; k++) {
396 for (int j = 0; j < mdsize; j++) {
397 // sh_force[k][j] += worker.sh_force2[k][j];
398 sh_force[k][j] += workingpad[k][j];
401 mymd.epot[0] += store.epot;
402 mymd.vir[0] += store.vir;
403 mymd.interactions += store.interacts;
408 for (int k = 0; k < 3; k++) {
409 for (int j = 0; j < mdsize; j++) {
410 sh_force[k][j] = sh_force[k][j] * hsq2;
414 /* update force arrays */
419 /* scale forces, update velocities */
421 for (int i = 0; i < mdsize; i++) {
422 sum = sum + one[i].mkekin(hsq2, i);
430 /* average velocity */
432 for (int i = 0; i < mdsize; i++) {
433 velt = one[i].velavg(vaverh, h);
442 /* temperature scale if required */
444 if ((move < istop) && (((move + 1) % irep) == 0)) {
445 sc = Math.sqrt(tref / (tscale * ekin));
446 for (int i = 0; i < mdsize; i++) {
449 ekin = tref / tscale;
452 /* sum to get full potential energy and virial */
454 if (((move + 1) % iprint) == 0) {
455 mymd.ek[id] = 24.0 * ekin;
456 mymd.epot[id] = 4.0 * mymd.epot[id];
457 etot = mymd.ek[id] + mymd.epot[id];
458 temp = tscale * ekin;
459 pres = tmpden * 16.0 * (ekin - mymd.vir[id]) / mdsize;
461 rp = (count / mdsize) * 100.0;
464 // if (id == 0) JGFInstrumentor.stopTimer("Section3:MolDyn:Run",
472 public double xcoord, ycoord, zcoord;
473 public double xvelocity, yvelocity, zvelocity;
477 double[][][] sh_force2;
480 public particle(double xcoord, double ycoord, double zcoord, double xvelocity, double yvelocity,
481 double zvelocity, double[][] sh_force, double[][][] sh_force2, int id, particle[] one) {
483 this.xcoord = xcoord;
484 this.ycoord = ycoord;
485 this.zcoord = zcoord;
486 this.xvelocity = xvelocity;
487 this.yvelocity = yvelocity;
488 this.zvelocity = zvelocity;
489 this.sh_force = sh_force;
490 this.sh_force2 = sh_force2;
495 public void domove(double side, int part_id) {
497 xcoord = xcoord + xvelocity + sh_force[0][part_id];
498 ycoord = ycoord + yvelocity + sh_force[1][part_id];
499 zcoord = zcoord + zvelocity + sh_force[2][part_id];
502 xcoord = xcoord + side;
505 xcoord = xcoord - side;
508 ycoord = ycoord + side;
511 ycoord = ycoord - side;
514 zcoord = zcoord + side;
517 zcoord = zcoord - side;
520 xvelocity = xvelocity + sh_force[0][part_id];
521 yvelocity = yvelocity + sh_force[1][part_id];
522 zvelocity = zvelocity + sh_force[2][part_id];
526 // public void force(double side, double rcoff,int mdsize,int x, double xx,
527 // double yy, double zz, JGFMolDynBench mymd) {
528 public void force(double side, double rcoff, int mdsize, int x, double xx, double yy, double zz,
529 JGFMolDynBench mymd, MDStore store,double workingpad[][]) {
534 double fxi, fyi, fzi;
535 double rd, rrd, rrd2, rrd3, rrd4, rrd6, rrd7, r148;
536 double forcex, forcey, forcez;
539 rcoffs = rcoff * rcoff;
545 for (int i = x + 1; i < mdsize; i++) {
546 xx = this.xcoord - one[i].xcoord;
547 yy = this.ycoord - one[i].ycoord;
548 zz = this.zcoord - one[i].zcoord;
569 rd = xx * xx + yy * yy + zz * zz;
578 // mymd.epot[id] += (rrd6 - rrd3);
579 store.epot += (rrd6 - rrd3);
580 r148 = rrd7 - 0.5 * rrd4;
581 // mymd.vir[id] += - rd*r148;
582 store.vir += -rd * r148;
586 // sh_force2[0][id][i] = sh_force2[0][id][i] - forcex;
587 // worker.sh_force2[0][i] = worker.sh_force2[0][i] - forcex;
588 workingpad[0][i] = workingpad[0][i] - forcex;
593 // sh_force2[1][id][i] = sh_force2[1][id][i] - forcey;
594 // worker.sh_force2[1][i] = worker.sh_force2[1][i] - forcey;
595 workingpad[1][i] = workingpad[1][i] - forcey;
600 // sh_force2[2][id][i] = sh_force2[2][id][i] - forcez;
601 // worker.sh_force2[2][i] = worker.sh_force2[2][i] - forcez;
602 workingpad[2][i] = workingpad[2][i] - forcez;
604 // mymd.interacts[id]++;
610 // sh_force2[0][id][x] = sh_force2[0][id][x] + fxi;
611 // sh_force2[1][id][x] = sh_force2[1][id][x] + fyi;
612 // sh_force2[2][id][x] = sh_force2[2][id][x] + fzi;
614 // worker.sh_force2[0][x] = worker.sh_force2[0][x] + fxi;
615 // worker.sh_force2[1][x] = worker.sh_force2[1][x] + fyi;
616 // worker.sh_force2[2][x] = worker.sh_force2[2][x] + fzi;
618 workingpad[0][x] = workingpad[0][x] + fxi;
619 workingpad[1][x] = workingpad[1][x] + fyi;
620 workingpad[2][x] = workingpad[2][x] + fzi;
624 public double mkekin(double hsq2, int part_id) {
628 xvelocity = xvelocity + sh_force[0][part_id];
629 yvelocity = yvelocity + sh_force[1][part_id];
630 zvelocity = zvelocity + sh_force[2][part_id];
632 sumt = (xvelocity * xvelocity) + (yvelocity * yvelocity) + (zvelocity * zvelocity);
636 public double velavg(double vaverh, double h) {
641 sq = Math.sqrt(xvelocity * xvelocity + yvelocity * yvelocity + zvelocity * zvelocity);
647 public void dscal(double sc, int incx) {
648 xvelocity = xvelocity * sc;
649 yvelocity = yvelocity * sc;
650 zvelocity = zvelocity * sc;
657 public double v1, v2;
659 public random(int iseed, double v1, double v2) {
665 public double update() {
668 double scale = 4.656612875e-10;
672 int imod = 2147483647;
679 is1 = (iseed - is2) / 32768;
682 is1 = (is1 * imult + (iss2 - is2) / 32768) % (65536);
684 iseed = (is1 * 32768 + is2) % imod;
686 rand = scale * iseed;
692 public double seed() {
702 s = v1 * v1 + v2 * v2;
706 r = Math.sqrt(-2.0 * Math.log(s) / s);