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; }
89 long start=System.currentTimeMillis();
90 for (int i = 0; i < numthreads; i++) {
91 // thobjects[i].md.start(mid[i]);
92 thobjects[i].md.run();
94 long end=System.currentTimeMillis();
95 // System.out.println("Total="+(end-start));
98 public void JGFvalidate() {
99 double[] refval = new double[2];
100 refval[0] = 1731.4306625334357;
101 refval[1] = 7397.392307839352;
102 double dev = Math.fabs(ek[0] - refval[size]);
104 // System.printString("Validation failed\n");
105 // System.printString("Kinetic Energy = " + (long)ek[0] + " " + (long)dev
106 // + " " + size + "\n");
114 int id, i, j, k, lg, mm;
115 double l, rcoff, rcoffs, side, sideh, hsq, hsq2, vel, velt;
116 double a, r, sum, tscale, sc, ekin, ts, sp;
120 double vaver, vaverh, rand;
121 double etot, temp, pres, rp;
122 double u1, u2, s, xx, yy, zz;
123 double xvelocity, yvelocity, zvelocity;
126 double[][][] sh_force2;
128 int ijk, npartm, iseed, tint;
137 public mdRunner(int id, int mm, double[][] sh_force, double[][][] sh_force2, int nthreads,
138 JGFMolDynBench mymd, int workload) {
141 this.sh_force = sh_force;
142 this.sh_force2 = sh_force2;
143 this.nthreads = nthreads;
152 this.workload=workload;
155 public void init(particle[] one, int mdsize) {
157 for (int lg = 0; lg <= 1; 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 + lg * a * 0.5), (j * a + lg * a * 0.5), (k * a), xvelocity,
163 yvelocity, zvelocity, sh_force, sh_force2, id, one);
170 for (int lg = 1; lg <= 2; lg++) {
171 for (int i = 0; i < mm; i++) {
172 for (int j = 0; j < mm; j++) {
173 for (int k = 0; k < mm; k++) {
175 new particle((i * a + (2 - lg) * a * 0.5), (j * a + (lg - 1) * a * 0.5),
176 (k * a + a * 0.5), xvelocity, yvelocity, zvelocity, sh_force, sh_force2, id,
184 /* Initialise velocities */
189 random randnum = new random(iseed, v1, v2);
191 for (int i = 0; i < mdsize; i += 2) {
193 one[i].xvelocity = r * randnum.v1;
194 one[i + 1].xvelocity = r * randnum.v2;
197 for (int i = 0; i < mdsize; i += 2) {
199 one[i].yvelocity = r * randnum.v1;
200 one[i + 1].yvelocity = r * randnum.v2;
203 for (int i = 0; i < mdsize; i += 2) {
205 one[i].zvelocity = r * randnum.v1;
206 one[i + 1].zvelocity = r * randnum.v2;
209 /* velocity scaling */
214 for (int i = 0; i < mdsize; i++) {
215 sp = sp + one[i].xvelocity;
219 for (int i = 0; i < mdsize; i++) {
220 one[i].xvelocity = one[i].xvelocity - sp;
221 ekin = ekin + one[i].xvelocity * one[i].xvelocity;
225 for (int i = 0; i < mdsize; i++) {
226 sp = sp + one[i].yvelocity;
230 for (int i = 0; i < mdsize; i++) {
231 one[i].yvelocity = one[i].yvelocity - sp;
232 ekin = ekin + one[i].yvelocity * one[i].yvelocity;
236 for (int i = 0; i < mdsize; i++) {
237 sp = sp + one[i].zvelocity;
241 for (int i = 0; i < mdsize; i++) {
242 one[i].zvelocity = one[i].zvelocity - sp;
243 ekin = ekin + one[i].zvelocity * one[i].zvelocity;
247 sc = h * Math.sqrt(tref / ts);
249 for (int i = 0; i < mdsize; i++) {
251 one[i].xvelocity = one[i].xvelocity * sc;
252 one[i].yvelocity = one[i].yvelocity * sc;
253 one[i].zvelocity = one[i].zvelocity * sc;
259 public void doinit(int mdsize) {
260 for (int j = 0; j < 3; j++) {
261 double[] sh = sh_force[j];
262 for (int i = 0; i < sh.length; i++) {
268 public void doinit2(int mdsize) {
269 for (int k = 0; k < 3; k++) {
270 double[] sh = sh_force[k];
271 double[][] sha = sh_force2[k];
272 for (int j = 0; j < nthreads; j++) {
273 double[] sha2 = sha[j];
274 for (int i = 0; i < mdsize; i++) {
280 for (int k = 0; k < 3; k++) {
281 double[][] sh1 = sh_force2[k];
282 for (int j = 0; j < nthreads; j++) {
283 double[] sh2 = sh1[j];
284 for (int i = 0; i < mdsize; i++) {
291 for (int j = 1; j < nthreads; j++) {
292 mymd.epot[0] += mymd.epot[j];
293 mymd.vir[0] += mymd.vir[j];
295 for (int j = 1; j < nthreads; j++) {
296 mymd.epot[j] = mymd.epot[0];
297 mymd.vir[j] = mymd.vir[0];
299 for (int j = 0; j < nthreads; j++) {
300 mymd.interactions += mymd.interacts[j];
303 for (int j = 0; j < 3; j++) {
304 double sh[] = sh_force[j];
305 for (int i = 0; i < mdsize; i++) {
306 sh[i] = sh[i] * hsq2;
312 /* Parameter determination */
320 mdsize = mymd.PARTSIZE;
321 one = new particle[mdsize];
324 side = Math.pow((mdsize / tmpden), 0.3333333);
332 rcoffs = rcoff * rcoff;
333 tscale = 16.0 / (1.0 * mdsize - 1.0);
334 vaver = 1.13 * Math.sqrt(tref / 24.0);
337 /* Particle Generation */
345 /* Synchronise threads and start timer before MD simulation */
349 JGFMolDynBench l_mymd=mymd;
351 int numP= (mdsize / workload)+1;
353 double scratchpad[][][];
354 scratchpad=new double[numP][3][mdsize];
358 for (int move = 0; move < movemx; move++) {
359 /* move the particles and update velocities */
360 for (int i = 0; i < one.length; i++) {
361 one[i].domove(side, i);
370 mymd.interacts[id] = 0;
373 int numThread = nthreads;
374 int lworkload = workload;
375 // for (int i=0+id;i<mdsize;i+=numThread) {
382 for (int i = 0 ; i < mdsize; i += lworkload) {
385 int iupper = i + lworkload;
386 if (iupper > mdsize) {
389 int l_size = iupper - ilow;
391 double workingpad[][]=scratchpad[scratch_idx++];
392 long par_start=System.currentTimeMillis();
394 for(int j=0;j<3;j++){
395 for(int l=0;l<mdsize;l++){
399 MDStore store = new MDStore();
400 for(int idx=ilow;idx<iupper;idx++){
401 // one[i].force(side, rcoff, mdsize, i, xx, yy, zz, mymd, worker);
402 one[idx].force(side, rcoff, mdsize, idx, xx, yy, zz, mymd, store,workingpad);
405 long par_end=System.currentTimeMillis();
406 par_time+=(par_end-par_start);
409 for (int k = 0; k < 3; k++) {
410 for (int j = 0; j < mdsize; j++) {
411 // sh_force[k][j] += worker.sh_force2[k][j];
412 sh_force[k][j] += workingpad[k][j];
417 l_interacts+=store.interacts;
418 // mymd.epot[0] += store.epot;
419 // mymd.vir[0] += store.vir;
420 // mymd.interactions += store.interacts;
425 mymd.epot[0] =l_epot;
426 // System.out.println("SEQ_START");
428 mymd.interactions = l_interacts;
430 for (int k = 0; k < 3; k++) {
431 for (int j = 0; j < sh_force[k].length; j++) {
432 sh_force[k][j] = sh_force[k][j] * hsq2;
436 /* update force arrays */
441 /* scale forces, update velocities */
443 int maxIdx=one.length;
444 for (int i = 0; i < maxIdx; i++) {
445 l_sum = l_sum + one[i].mkekin(hsq2, i);
454 /* average velocity */
456 for (int i = 0; i < mdsize; i++) {
457 velt = one[i].velavg(vaverh, h);
466 /* temperature scale if required */
468 if ((move < istop) && (((move + 1) % irep) == 0)) {
469 sc = Math.sqrt(tref / (tscale * ekin));
470 for (int i = 0; i < mdsize; i++) {
473 ekin = tref / tscale;
476 /* sum to get full potential energy and virial */
478 if (((move + 1) % iprint) == 0) {
479 mymd.ek[id] = 24.0 * ekin;
480 mymd.epot[id] = 4.0 * mymd.epot[id];
481 etot = mymd.ek[id] + mymd.epot[id];
482 temp = tscale * ekin;
483 pres = tmpden * 16.0 * (ekin - mymd.vir[id]) / mdsize;
485 rp = (count / mdsize) * 100.0;
488 // if (id == 0) JGFInstrumentor.stopTimer("Section3:MolDyn:Run",
491 // System.out.println("par time="+par_time);
497 public double xcoord, ycoord, zcoord;
498 public double xvelocity, yvelocity, zvelocity;
502 double[][][] sh_force2;
505 public particle(double xcoord, double ycoord, double zcoord, double xvelocity, double yvelocity,
506 double zvelocity, double[][] sh_force, double[][][] sh_force2, int id, particle[] one) {
508 this.xcoord = xcoord;
509 this.ycoord = ycoord;
510 this.zcoord = zcoord;
511 this.xvelocity = xvelocity;
512 this.yvelocity = yvelocity;
513 this.zvelocity = zvelocity;
514 this.sh_force = sh_force;
515 this.sh_force2 = sh_force2;
520 public void domove(double side, int part_id) {
522 xcoord = xcoord + xvelocity + sh_force[0][part_id];
523 ycoord = ycoord + yvelocity + sh_force[1][part_id];
524 zcoord = zcoord + zvelocity + sh_force[2][part_id];
527 xcoord = xcoord + side;
530 xcoord = xcoord - side;
533 ycoord = ycoord + side;
536 ycoord = ycoord - side;
539 zcoord = zcoord + side;
542 zcoord = zcoord - side;
545 xvelocity = xvelocity + sh_force[0][part_id];
546 yvelocity = yvelocity + sh_force[1][part_id];
547 zvelocity = zvelocity + sh_force[2][part_id];
551 // public void force(double side, double rcoff,int mdsize,int x, double xx,
552 // double yy, double zz, JGFMolDynBench mymd) {
553 public void force(double side, double rcoff, int mdsize, int x, double xx, double yy, double zz,
554 JGFMolDynBench mymd, MDStore store,double workingpad[][]) {
559 double fxi, fyi, fzi;
560 double rd, rrd, rrd2, rrd3, rrd4, rrd6, rrd7, r148;
561 double forcex, forcey, forcez;
564 rcoffs = rcoff * rcoff;
570 for (int i = x + 1; i < mdsize; i++) {
571 xx = this.xcoord - one[i].xcoord;
572 yy = this.ycoord - one[i].ycoord;
573 zz = this.zcoord - one[i].zcoord;
594 rd = xx * xx + yy * yy + zz * zz;
603 // mymd.epot[id] += (rrd6 - rrd3);
604 store.epot += (rrd6 - rrd3);
605 r148 = rrd7 - 0.5 * rrd4;
606 // mymd.vir[id] += - rd*r148;
607 store.vir += -rd * r148;
611 // sh_force2[0][id][i] = sh_force2[0][id][i] - forcex;
612 // worker.sh_force2[0][i] = worker.sh_force2[0][i] - forcex;
613 workingpad[0][i] = workingpad[0][i] - forcex;
618 // sh_force2[1][id][i] = sh_force2[1][id][i] - forcey;
619 // worker.sh_force2[1][i] = worker.sh_force2[1][i] - forcey;
620 workingpad[1][i] = workingpad[1][i] - forcey;
625 // sh_force2[2][id][i] = sh_force2[2][id][i] - forcez;
626 // worker.sh_force2[2][i] = worker.sh_force2[2][i] - forcez;
627 workingpad[2][i] = workingpad[2][i] - forcez;
629 // mymd.interacts[id]++;
635 // sh_force2[0][id][x] = sh_force2[0][id][x] + fxi;
636 // sh_force2[1][id][x] = sh_force2[1][id][x] + fyi;
637 // sh_force2[2][id][x] = sh_force2[2][id][x] + fzi;
639 // worker.sh_force2[0][x] = worker.sh_force2[0][x] + fxi;
640 // worker.sh_force2[1][x] = worker.sh_force2[1][x] + fyi;
641 // worker.sh_force2[2][x] = worker.sh_force2[2][x] + fzi;
643 workingpad[0][x] = workingpad[0][x] + fxi;
644 workingpad[1][x] = workingpad[1][x] + fyi;
645 workingpad[2][x] = workingpad[2][x] + fzi;
649 public double mkekin(double hsq2, int part_id) {
653 xvelocity = xvelocity + sh_force[0][part_id];
654 yvelocity = yvelocity + sh_force[1][part_id];
655 zvelocity = zvelocity + sh_force[2][part_id];
657 sumt = (xvelocity * xvelocity) + (yvelocity * yvelocity) + (zvelocity * zvelocity);
661 public double velavg(double vaverh, double h) {
666 sq = Math.sqrt(xvelocity * xvelocity + yvelocity * yvelocity + zvelocity * zvelocity);
672 public void dscal(double sc, int incx) {
673 xvelocity = xvelocity * sc;
674 yvelocity = yvelocity * sc;
675 zvelocity = zvelocity * sc;
682 public double v1, v2;
684 public random(int iseed, double v1, double v2) {
690 public double update() {
693 double scale = 4.656612875e-10;
697 int imod = 2147483647;
704 is1 = (iseed - is2) / 32768;
707 is1 = (is1 * imult + (iss2 - is2) / 32768) % (65536);
709 iseed = (is1 * 32768 + is2) % imod;
711 rand = scale * iseed;
717 public double seed() {
727 s = v1 * v1 + v2 * v2;
731 r = Math.sqrt(-2.0 * Math.log(s) / s);