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];
80 for (int i = 0; i < numthreads; i++) {
81 thobjects[i] = new MDWrap(new mdRunner(i, mold.mm, sh_force, sh_force2, mold.nthreads, mold,mold.workload));
84 * boolean waitfordone=true; while(waitfordone) { if (mybarr.done)
85 * waitfordone=false; }
87 long start=System.currentTimeMillis();
88 // for (int i = 0; i < numthreads; i++) {
89 // thobjects[i].md.start(mid[i]);
90 thobjects[0].md.run();
92 long end=System.currentTimeMillis();
93 // System.out.println("Total="+(end-start));
101 int id, i, j, k, lg, mm;
102 double l, rcoff, rcoffs, side, sideh, hsq, hsq2, vel, velt;
103 double a, r, sum, tscale, sc, ekin, ts, sp;
107 double vaver, vaverh, rand;
108 double etot, temp, pres, rp;
109 double u1, u2, s, xx, yy, zz;
110 double xvelocity, yvelocity, zvelocity;
113 double[][][] sh_force2;
115 int ijk, npartm, iseed, tint;
124 public mdRunner(int id, int mm, double[][] sh_force, double[][][] sh_force2, int nthreads,
125 JGFMolDynBench mymd, int workload) {
128 this.sh_force = sh_force;
129 this.sh_force2 = sh_force2;
130 this.nthreads = nthreads;
139 this.workload=workload;
142 public void init(particle[] one, int mdsize) {
144 for (int lg = 0; lg <= 1; lg++) {
145 for (int i = 0; i < mm; i++) {
146 for (int j = 0; j < mm; j++) {
147 for (int k = 0; k < mm; k++) {
149 new particle((i * a + lg * a * 0.5), (j * a + lg * a * 0.5), (k * a), xvelocity,
150 yvelocity, zvelocity, sh_force, sh_force2, id, one);
157 for (int lg = 1; lg <= 2; lg++) {
158 for (int i = 0; i < mm; i++) {
159 for (int j = 0; j < mm; j++) {
160 for (int k = 0; k < mm; k++) {
162 new particle((i * a + (2 - lg) * a * 0.5), (j * a + (lg - 1) * a * 0.5),
163 (k * a + a * 0.5), xvelocity, yvelocity, zvelocity, sh_force, sh_force2, id,
171 /* Initialise velocities */
176 random randnum = new random(iseed, v1, v2);
178 for (int i = 0; i < mdsize; i += 2) {
180 one[i].xvelocity = r * randnum.v1;
181 one[i + 1].xvelocity = r * randnum.v2;
184 for (int i = 0; i < mdsize; i += 2) {
186 one[i].yvelocity = r * randnum.v1;
187 one[i + 1].yvelocity = r * randnum.v2;
190 for (int i = 0; i < mdsize; i += 2) {
192 one[i].zvelocity = r * randnum.v1;
193 one[i + 1].zvelocity = r * randnum.v2;
196 /* velocity scaling */
201 for (int i = 0; i < mdsize; i++) {
202 sp = sp + one[i].xvelocity;
206 for (int i = 0; i < mdsize; i++) {
207 one[i].xvelocity = one[i].xvelocity - sp;
208 ekin = ekin + one[i].xvelocity * one[i].xvelocity;
212 for (int i = 0; i < mdsize; i++) {
213 sp = sp + one[i].yvelocity;
217 for (int i = 0; i < mdsize; i++) {
218 one[i].yvelocity = one[i].yvelocity - sp;
219 ekin = ekin + one[i].yvelocity * one[i].yvelocity;
223 for (int i = 0; i < mdsize; i++) {
224 sp = sp + one[i].zvelocity;
228 for (int i = 0; i < mdsize; i++) {
229 one[i].zvelocity = one[i].zvelocity - sp;
230 ekin = ekin + one[i].zvelocity * one[i].zvelocity;
234 sc = h * Math.sqrt(tref / ts);
236 for (int i = 0; i < mdsize; i++) {
238 one[i].xvelocity = one[i].xvelocity * sc;
239 one[i].yvelocity = one[i].yvelocity * sc;
240 one[i].zvelocity = one[i].zvelocity * sc;
246 public void doinit(int mdsize) {
247 for (int j = 0; j < 3; j++) {
248 double[] sh = sh_force[j];
249 for (int i = 0; i < sh.length; i++) {
255 public void doinit2(int mdsize) {
256 for (int k = 0; k < 3; k++) {
257 double[] sh = sh_force[k];
258 double[][] sha = sh_force2[k];
259 for (int j = 0; j < nthreads; j++) {
260 double[] sha2 = sha[j];
261 for (int i = 0; i < mdsize; i++) {
267 for (int k = 0; k < 3; k++) {
268 double[][] sh1 = sh_force2[k];
269 for (int j = 0; j < nthreads; j++) {
270 double[] sh2 = sh1[j];
271 for (int i = 0; i < mdsize; i++) {
278 for (int j = 1; j < nthreads; j++) {
279 mymd.epot[0] += mymd.epot[j];
280 mymd.vir[0] += mymd.vir[j];
282 for (int j = 1; j < nthreads; j++) {
283 mymd.epot[j] = mymd.epot[0];
284 mymd.vir[j] = mymd.vir[0];
286 for (int j = 0; j < nthreads; j++) {
287 mymd.interactions += mymd.interacts[j];
290 for (int j = 0; j < 3; j++) {
291 double sh[] = sh_force[j];
292 for (int i = 0; i < mdsize; i++) {
293 sh[i] = sh[i] * hsq2;
299 /* Parameter determination */
307 mdsize = mymd.PARTSIZE;
308 one = new particle[mdsize];
311 side = Math.pow((mdsize / tmpden), 0.3333333);
319 rcoffs = rcoff * rcoff;
320 tscale = 16.0 / (1.0 * mdsize - 1.0);
321 vaver = 1.13 * Math.sqrt(tref / 24.0);
324 /* Particle Generation */
332 /* Synchronise threads and start timer before MD simulation */
336 JGFMolDynBench l_mymd=mymd;
338 int numP= (mdsize / workload)+1;
340 double scratchpad[][][];
341 scratchpad=new double[numP][3][mdsize];
345 for (int move = 0; move < movemx; move++) {
346 /* move the particles and update velocities */
347 for (int i = 0; i < one.length; i++) {
348 one[i].domove(side, i);
357 mymd.interacts[id] = 0;
360 int numThread = nthreads;
361 int lworkload = workload;
362 // for (int i=0+id;i<mdsize;i+=numThread) {
369 for (int i = 0 ; i < mdsize; i += lworkload) {
372 int iupper = i + lworkload;
373 if (iupper > mdsize) {
376 int l_size = iupper - ilow;
378 double workingpad[][]=scratchpad[scratch_idx++];
379 long par_start=System.currentTimeMillis();
381 for(int j=0;j<3;j++){
382 for(int l=0;l<mdsize;l++){
386 MDStore store = new MDStore();
387 for(int idx=ilow;idx<iupper;idx++){
388 // one[i].force(side, rcoff, mdsize, i, xx, yy, zz, mymd, worker);
389 one[idx].force(side, rcoff, mdsize, idx, xx, yy, zz, mymd, store,workingpad);
392 long par_end=System.currentTimeMillis();
393 par_time+=(par_end-par_start);
396 for (int k = 0; k < 3; k++) {
397 for (int j = 0; j < mdsize; j++) {
398 // sh_force[k][j] += worker.sh_force2[k][j];
399 sh_force[k][j] += workingpad[k][j];
404 l_interacts+=store.interacts;
409 mymd.epot[0] =l_epot;
410 // System.out.println("SEQ_START");
412 mymd.interactions = l_interacts;
414 for (int k = 0; k < 3; k++) {
415 for (int j = 0; j < sh_force[k].length; j++) {
416 sh_force[k][j] = sh_force[k][j] * hsq2;
420 /* update force arrays */
425 /* scale forces, update velocities */
427 int maxIdx=one.length;
428 for (int i = 0; i < maxIdx; i++) {
429 l_sum = l_sum + one[i].mkekin(hsq2, i);
438 /* average velocity */
440 for (int i = 0; i < mdsize; i++) {
441 velt = one[i].velavg(vaverh, h);
450 /* temperature scale if required */
452 if ((move < istop) && (((move + 1) % irep) == 0)) {
453 sc = Math.sqrt(tref / (tscale * ekin));
454 for (int i = 0; i < mdsize; i++) {
457 ekin = tref / tscale;
460 /* sum to get full potential energy and virial */
462 if (((move + 1) % iprint) == 0) {
463 mymd.ek[id] = 24.0 * ekin;
464 mymd.epot[id] = 4.0 * mymd.epot[id];
465 etot = mymd.ek[id] + mymd.epot[id];
466 temp = tscale * ekin;
467 pres = tmpden * 16.0 * (ekin - mymd.vir[id]) / mdsize;
469 rp = (count / mdsize) * 100.0;
473 // System.out.println("par time="+par_time);
479 public double xcoord, ycoord, zcoord;
480 public double xvelocity, yvelocity, zvelocity;
484 double[][][] sh_force2;
487 public particle(double xcoord, double ycoord, double zcoord, double xvelocity, double yvelocity,
488 double zvelocity, double[][] sh_force, double[][][] sh_force2, int id, particle[] one) {
490 this.xcoord = xcoord;
491 this.ycoord = ycoord;
492 this.zcoord = zcoord;
493 this.xvelocity = xvelocity;
494 this.yvelocity = yvelocity;
495 this.zvelocity = zvelocity;
496 this.sh_force = sh_force;
497 this.sh_force2 = sh_force2;
502 public void domove(double side, int part_id) {
504 xcoord = xcoord + xvelocity + sh_force[0][part_id];
505 ycoord = ycoord + yvelocity + sh_force[1][part_id];
506 zcoord = zcoord + zvelocity + sh_force[2][part_id];
509 xcoord = xcoord + side;
512 xcoord = xcoord - side;
515 ycoord = ycoord + side;
518 ycoord = ycoord - side;
521 zcoord = zcoord + side;
524 zcoord = zcoord - side;
527 xvelocity = xvelocity + sh_force[0][part_id];
528 yvelocity = yvelocity + sh_force[1][part_id];
529 zvelocity = zvelocity + sh_force[2][part_id];
533 // public void force(double side, double rcoff,int mdsize,int x, double xx,
534 // double yy, double zz, JGFMolDynBench mymd) {
535 public void force(double side, double rcoff, int mdsize, int x, double xx, double yy, double zz,
536 JGFMolDynBench mymd, MDStore store,double workingpad[][]) {
541 double fxi, fyi, fzi;
542 double rd, rrd, rrd2, rrd3, rrd4, rrd6, rrd7, r148;
543 double forcex, forcey, forcez;
546 rcoffs = rcoff * rcoff;
552 for (int i = x + 1; i < mdsize; i++) {
553 xx = this.xcoord - one[i].xcoord;
554 yy = this.ycoord - one[i].ycoord;
555 zz = this.zcoord - one[i].zcoord;
576 rd = xx * xx + yy * yy + zz * zz;
585 // mymd.epot[id] += (rrd6 - rrd3);
586 store.epot += (rrd6 - rrd3);
587 r148 = rrd7 - 0.5 * rrd4;
588 // mymd.vir[id] += - rd*r148;
589 store.vir += -rd * r148;
593 // sh_force2[0][id][i] = sh_force2[0][id][i] - forcex;
594 // worker.sh_force2[0][i] = worker.sh_force2[0][i] - forcex;
595 workingpad[0][i] = workingpad[0][i] - forcex;
600 // sh_force2[1][id][i] = sh_force2[1][id][i] - forcey;
601 // worker.sh_force2[1][i] = worker.sh_force2[1][i] - forcey;
602 workingpad[1][i] = workingpad[1][i] - forcey;
607 // sh_force2[2][id][i] = sh_force2[2][id][i] - forcez;
608 // worker.sh_force2[2][i] = worker.sh_force2[2][i] - forcez;
609 workingpad[2][i] = workingpad[2][i] - forcez;
611 // mymd.interacts[id]++;
617 // sh_force2[0][id][x] = sh_force2[0][id][x] + fxi;
618 // sh_force2[1][id][x] = sh_force2[1][id][x] + fyi;
619 // sh_force2[2][id][x] = sh_force2[2][id][x] + fzi;
621 // worker.sh_force2[0][x] = worker.sh_force2[0][x] + fxi;
622 // worker.sh_force2[1][x] = worker.sh_force2[1][x] + fyi;
623 // worker.sh_force2[2][x] = worker.sh_force2[2][x] + fzi;
625 workingpad[0][x] = workingpad[0][x] + fxi;
626 workingpad[1][x] = workingpad[1][x] + fyi;
627 workingpad[2][x] = workingpad[2][x] + fzi;
631 public double mkekin(double hsq2, int part_id) {
635 xvelocity = xvelocity + sh_force[0][part_id];
636 yvelocity = yvelocity + sh_force[1][part_id];
637 zvelocity = zvelocity + sh_force[2][part_id];
639 sumt = (xvelocity * xvelocity) + (yvelocity * yvelocity) + (zvelocity * zvelocity);
643 public double velavg(double vaverh, double h) {
648 sq = Math.sqrt(xvelocity * xvelocity + yvelocity * yvelocity + zvelocity * zvelocity);
654 public void dscal(double sc, int incx) {
655 xvelocity = xvelocity * sc;
656 yvelocity = yvelocity * sc;
657 zvelocity = zvelocity * sc;
664 public double v1, v2;
666 public random(int iseed, double v1, double v2) {
672 public double update() {
675 double scale = 4.656612875e-10;
679 int imod = 2147483647;
686 is1 = (iseed - is2) / 32768;
689 is1 = (is1 * imult + (iss2 - is2) / 32768) % (65536);
691 iseed = (is1 * 32768 + is2) % imod;
693 rand = scale * iseed;
699 public double seed() {
709 s = v1 * v1 + v2 * v2;
713 r = Math.sqrt(-2.0 * Math.log(s) / s);