1 /**************************************************************************
3 * Java Grande Forum Benchmark Suite - Thread Version 1.0 *
7 * Java Grande Benchmarking Project *
11 * Edinburgh Parallel Computing Centre *
13 * email: epcc-javagrande@epcc.ed.ac.uk *
16 * This version copyright (c) The University of Edinburgh, 2001. *
17 * All rights reserved. *
19 **************************************************************************/
20 public class JGFMolDynBench {
31 public global double[] epot;
32 public global double[] vir;
33 public global double[] ek;
38 public int interactions;
39 public int[] interacts;
41 public global int nthreads;
42 public global JGFInstrumentor instr;
44 public JGFMolDynBench(int nthreads, JGFInstrumentor instr) {
45 this.nthreads=nthreads;
49 public void JGFsetsize(int size){
53 public void JGFinitialise(){
55 datasizes = new int[2];
60 PARTSIZE = mm*mm*mm*4;
72 public static void JGFapplication(JGFMolDynBench mold) {
75 mold.epot = global new double [mold.nthreads];
76 mold.vir = global new double [mold.nthreads];
77 mold.ek = global new double [mold.nthreads];
78 mold.interacts = global new int [mold.nthreads];
81 int partsize, numthreads;
83 partsize = mold.PARTSIZE;
84 numthreads = mold.nthreads;
87 double sh_force [][] = new double[3][partsize];
88 double sh_force2 [][][] = new double[3][numthreads][partsize];
91 //Thread thobjects[] = new Thread [nthreads];
95 thobjects = global new mdRunner[numthreads];
96 br= global new TournamentBarrier(numthreads);
99 int mid = (128<<24)|(195<<16)|(175<<8)|73;
102 for(int i=1;i<numthreads;i++) {
104 thobjects[i] = global new mdRunner(i,mold.mm,sh_force,sh_force2,br,mold.instr,mold.nthreads,mold);
111 thobjects[0] = new mdRunner(0,mold.mm,sh_force,sh_force2,br,mold.instr,mold.nthreads,mold);
115 for(int i=1;i<numthreads;i++) {
123 public void JGFvalidate(){
124 double[] refval = new double[2];
125 refval[0] = 1731.4306625334357;
126 refval[1] = 7397.392307839352;
127 double dev = Math.fabs(ek[0] - refval[size]);
129 //System.printString("Validation failed");
130 //System.printString("Kinetic Energy = " + (long)ek[0] + " " + (long)dev + " " + size);
135 class mdRunner extends Thread {
138 int id,i,j,k,lg,mdsize,move,mm;
139 double l,rcoff,rcoffs,side,sideh,hsq,hsq2,vel,velt;
140 double a,r,sum,tscale,sc,ekin,ts,sp;
144 double vaver,vaverh,rand;
145 double etot,temp,pres,rp;
146 double u1,u2,v1,v2,s, xx, yy, zz;
147 double xvelocity, yvelocity, zvelocity;
149 double [][] sh_force;
150 double [][][] sh_force2;
152 int ijk,npartm,iseed,tint;
158 TournamentBarrier br;
160 global JGFInstrumentor instr;
161 global JGFMolDynBench mymd;
166 public mdRunner(int id, int mm, double [][] sh_force, double [][][] sh_force2,TournamentBarrier br,
167 JGFInstrumentor instr, int nthreads, JGFMolDynBench mymd) {
170 this.sh_force=sh_force;
171 this.sh_force2=sh_force2;
174 this.nthreads = nthreads;
188 /* Parameter determination */
191 mdsize = mymd.PARTSIZE;
193 one = new particle [mdsize];
198 side = Math.pow((mdsize/den),0.3333333);
206 rcoffs = rcoff * rcoff;
207 tscale = 16.0 / (1.0 * mdsize - 1.0);
208 vaver = 1.13 * Math.sqrt(tref / 24.0);
211 /* Particle Generation */
219 for (lg=0; lg<=1; lg++) {
220 for (i=0; i<mm; i++) {
221 for (j=0; j<mm; j++) {
222 for (k=0; k<mm; k++) {
223 one[ijk] = new particle((i*a+lg*a*0.5),(j*a+lg*a*0.5),(k*a),
224 xvelocity,yvelocity,zvelocity,sh_force,sh_force2,id,this);
232 for (lg=1; lg<=2; lg++) {
233 for (i=0; i<mm; i++) {
234 for (j=0; j<mm; j++) {
235 for (k=0; k<mm; k++) {
236 one[ijk] = new particle((i*a+(2-lg)*a*0.5),(j*a+(lg-1)*a*0.5),
237 (k*a+a*0.5),xvelocity,yvelocity,zvelocity,sh_force,sh_force2,id,this);
246 /* Initialise velocities */
252 randnum = new random(iseed,v1,v2);
254 for (i=0; i<mdsize; i+=2) {
256 one[i].xvelocity = r*randnum.v1;
257 one[i+1].xvelocity = r*randnum.v2;
260 for (i=0; i<mdsize; i+=2) {
262 one[i].yvelocity = r*randnum.v1;
263 one[i+1].yvelocity = r*randnum.v2;
266 for (i=0; i<mdsize; i+=2) {
268 one[i].zvelocity = r*randnum.v1;
269 one[i+1].zvelocity = r*randnum.v2;
273 /* velocity scaling */
278 for(i=0;i<mdsize;i++) {
279 sp = sp + one[i].xvelocity;
283 for(i=0;i<mdsize;i++) {
284 one[i].xvelocity = one[i].xvelocity - sp;
285 ekin = ekin + one[i].xvelocity*one[i].xvelocity;
289 for(i=0;i<mdsize;i++) {
290 sp = sp + one[i].yvelocity;
294 for(i=0;i<mdsize;i++) {
295 one[i].yvelocity = one[i].yvelocity - sp;
296 ekin = ekin + one[i].yvelocity*one[i].yvelocity;
301 for(i=0;i<mdsize;i++) {
302 sp = sp + one[i].zvelocity;
306 for(i=0;i<mdsize;i++) {
307 one[i].zvelocity = one[i].zvelocity - sp;
308 ekin = ekin + one[i].zvelocity*one[i].zvelocity;
312 sc = h * Math.sqrt(tref/ts);
315 for(i=0;i<mdsize;i++) {
317 one[i].xvelocity = one[i].xvelocity * sc;
318 one[i].yvelocity = one[i].yvelocity * sc;
319 one[i].zvelocity = one[i].zvelocity * sc;
324 /* Synchronise threads and start timer before MD simulation */
329 if (id == 0) JGFInstrumentor.startTimer("Section3:MolDyn:Run", instr.timers);
338 for (move=0;move<movemx;move++) {
340 /* move the particles and update velocities */
342 for (i=0;i<mdsize;i++) {
343 one[i].domove(side,i);
351 for (i=0;i<mdsize;i++) {
352 sh_force[j][i] = 0.0;
359 mymd.interacts[id] = 0;
368 for (i=0+id;i<mdsize;i+=nthreads) {
369 one[i].force(side,rcoff,mdsize,i,xx,yy,zz,mymd);
375 /* update force arrays */
378 for(int k=0;k<3;k++) {
379 for(i=0;i<mdsize;i++) {
380 for(j=0;j<nthreads;j++) {
381 sh_force[k][i] += sh_force2[k][j][i];
388 for(int k=0;k<3;k++) {
389 for(i=0;i<mdsize;i++) {
390 for(j=0;j<nthreads;j++) {
391 sh_force2[k][j][i] = 0.0;
398 for(j=1;j<nthreads;j++) {
399 mymd.epot[0] += mymd.epot[j];
400 mymd.vir[0] += mymd.vir[j];
402 for(j=1;j<nthreads;j++) {
403 mymd.epot[j] = mymd.epot[0];
404 mymd.vir[j] = mymd.vir[0];
406 for(j=0;j<nthreads;j++) {
407 mymd.interactions += mymd.interacts[j];
416 for (i=0;i<mdsize;i++) {
417 sh_force[j][i] = sh_force[j][i] * hsq2;
427 /*scale forces, update velocities */
429 for (i=0;i<mdsize;i++) {
430 sum = sum + one[i].mkekin(hsq2,i);
438 /* average velocity */
440 for (i=0;i<mdsize;i++) {
441 velt = one[i].velavg(vaverh,h);
442 if(velt > vaverh) { count = count + 1.0; }
448 /* temperature scale if required */
450 if((move < istop) && (((move+1) % irep) == 0)) {
451 sc = Math.sqrt(tref / (tscale*ekin));
452 for (i=0;i<mdsize;i++) {
455 ekin = tref / tscale;
458 /* sum to get full potential energy and virial */
460 if(((move+1) % iprint) == 0) {
461 mymd.ek[id] = 24.0*ekin;
462 mymd.epot[id] = 4.0*mymd.epot[id];
463 etot = mymd.ek[id] + mymd.epot[id];
464 temp = tscale * ekin;
465 pres = den * 16.0 * (ekin - mymd.vir[id]) / mdsize;
467 rp = (count / mdsize) * 100.0;
475 if (id == 0) JGFInstrumentor.stopTimer("Section3:MolDyn:Run", instr.timers);
486 public double xcoord, ycoord, zcoord;
487 public double xvelocity,yvelocity,zvelocity;
490 double [][] sh_force;
491 double [][][] sh_force2;
494 public particle(double xcoord, double ycoord, double zcoord, double xvelocity,
495 double yvelocity,double zvelocity,double [][] sh_force,
496 double [][][] sh_force2,int id,mdRunner runner) {
498 this.xcoord = xcoord;
499 this.ycoord = ycoord;
500 this.zcoord = zcoord;
501 this.xvelocity = xvelocity;
502 this.yvelocity = yvelocity;
503 this.zvelocity = zvelocity;
504 this.sh_force = sh_force;
505 this.sh_force2 = sh_force2;
510 public void domove(double side,int part_id) {
512 xcoord = xcoord + xvelocity + sh_force[0][part_id];
513 ycoord = ycoord + yvelocity + sh_force[1][part_id];
514 zcoord = zcoord + zvelocity + sh_force[2][part_id];
516 if(xcoord < 0) { xcoord = xcoord + side; }
517 if(xcoord > side) { xcoord = xcoord - side; }
518 if(ycoord < 0) { ycoord = ycoord + side; }
519 if(ycoord > side) { ycoord = ycoord - side; }
520 if(zcoord < 0) { zcoord = zcoord + side; }
521 if(zcoord > side) { zcoord = zcoord - side; }
523 xvelocity = xvelocity + sh_force[0][part_id];
524 yvelocity = yvelocity + sh_force[1][part_id];
525 zvelocity = zvelocity + sh_force[2][part_id];
529 public void force(double side, double rcoff,int mdsize,int x, double xx, double yy, double zz, JGFMolDynBench mymd) {
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 - runner.one[i].xcoord;
547 yy = this.ycoord - runner.one[i].ycoord;
548 zz = this.zcoord - runner.one[i].zcoord;
550 if(xx < (-sideh)) { xx = xx + side; }
551 if(xx > (sideh)) { xx = xx - side; }
552 if(yy < (-sideh)) { yy = yy + side; }
553 if(yy > (sideh)) { yy = yy - side; }
554 if(zz < (-sideh)) { zz = zz + side; }
555 if(zz > (sideh)) { zz = zz - side; }
558 rd = xx*xx + yy*yy + zz*zz;
567 mymd.epot[id] = mymd.epot[id] + (rrd6 - rrd3);
568 r148 = rrd7 - 0.5*rrd4;
569 mymd.vir[id] = mymd.vir[id] - rd*r148;
573 sh_force2[0][id][i] = sh_force2[0][id][i] - forcex;
578 sh_force2[1][id][i] = sh_force2[1][id][i] - forcey;
583 sh_force2[2][id][i] = sh_force2[2][id][i] - forcez;
585 mymd.interacts[id]++;
590 sh_force2[0][id][x] = sh_force2[0][id][x] + fxi;
591 sh_force2[1][id][x] = sh_force2[1][id][x] + fyi;
592 sh_force2[2][id][x] = sh_force2[2][id][x] + fzi;
596 public double mkekin(double hsq2,int part_id) {
600 xvelocity = xvelocity + sh_force[0][part_id];
601 yvelocity = yvelocity + sh_force[1][part_id];
602 zvelocity = zvelocity + sh_force[2][part_id];
604 sumt = (xvelocity*xvelocity)+(yvelocity*yvelocity)+(zvelocity*zvelocity);
608 public double velavg(double vaverh,double h) {
613 sq = Math.sqrt(xvelocity*xvelocity + yvelocity*yvelocity +
614 zvelocity*zvelocity);
620 public void dscal(double sc,int incx) {
622 xvelocity = xvelocity * sc;
623 yvelocity = yvelocity * sc;
624 zvelocity = zvelocity * sc;
637 public random(int iseed,double v1,double v2) {
643 public double update() {
646 double scale= 4.656612875e-10;
650 int imod = 2147483647;
652 if (iseed<=0) { iseed = 1; }
655 is1 = (iseed-is2)/32768;
658 is1 = (is1*imult+(iss2-is2)/32768) % (65536);
660 iseed = (is1*32768+is2) % imod;
662 rand = scale * iseed;
668 public double seed() {
682 r = Math.sqrt(-2.0*Math.log(s)/s);