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 **************************************************************************/
23 public class JGFMolDynBench {
41 public int interactions;
42 public int[] interacts;
45 public JGFInstrumentor instr;
47 public JGFMolDynBench(int nthreads, JGFInstrumentor instr) {
48 this.nthreads=nthreads;
52 public void JGFsetsize(int size){
56 public void JGFinitialise(){
58 datasizes = new int[2];
63 PARTSIZE = mm*mm*mm*4;
75 public void JGFapplication() {
77 epot = new double [nthreads];
78 vir = new double [nthreads];
79 ek = new double [nthreads];
81 interacts = new int [nthreads];
83 double sh_force [][] = new double[3][PARTSIZE];
84 double sh_force2 [][][] = new double[3][nthreads][PARTSIZE];
87 Thread thobjects[] = new Thread [nthreads];
88 TournamentBarrier br= new TournamentBarrier(nthreads);
89 //Barrier br = new Barrier(nthreads);
91 for(int i=1;i<nthreads;i++) {
92 thobjects[i] = new mdRunner(i,mm,sh_force,sh_force2,br,instr,nthreads,this);
96 thobjects[0] = new mdRunner(0,mm,sh_force,sh_force2,br,instr,nthreads,this);
99 for(int i=1;i<nthreads;i++) {
103 catch (InterruptedException e) {}
107 public void JGFvalidate(){
108 double[] refval = new double[2];
109 refval[0] = 1731.4306625334357;
110 refval[1] = 7397.392307839352;
111 double dev = Math.abs(ek[0] - refval[size]);
113 System.out.println("Validation failed");
114 System.out.println("Kinetic Energy = " + ek[0] + " " + dev + " " + size);
119 class mdRunner extends Thread {
122 int id,i,j,k,lg,mdsize,move,mm;
123 double l,rcoff,rcoffs,side,sideh,hsq,hsq2,vel,velt;
124 double a,r,sum,tscale,sc,ekin,ts,sp;
128 double vaver,vaverh,rand;
129 double etot,temp,pres,rp;
130 double u1,u2,v1,v2,s, xx, yy, zz;
131 double xvelocity, yvelocity, zvelocity;
133 double [][] sh_force;
134 double [][][] sh_force2;
136 int ijk,npartm,iseed,tint;
142 TournamentBarrier br;
145 JGFInstrumentor instr;
151 public mdRunner(int id, int mm, double [][] sh_force, double [][][] sh_force2,TournamentBarrier br,
152 //public mdRunner(int id, int mm, double [][] sh_force, double [][][] sh_force2,Barrier br,
153 JGFInstrumentor instr, int nthreads, JGFMolDynBench mymd) {
156 this.sh_force=sh_force;
157 this.sh_force2=sh_force2;
160 this.nthreads = nthreads;
174 /* Parameter determination */
176 mdsize = mymd.PARTSIZE;
177 one = new particle [mdsize];
180 side = Math.pow((mdsize/den),0.3333333);
188 rcoffs = rcoff * rcoff;
189 tscale = 16.0 / (1.0 * mdsize - 1.0);
190 vaver = 1.13 * Math.sqrt(tref / 24.0);
193 /* Particle Generation */
200 for (lg=0; lg<=1; lg++) {
201 for (i=0; i<mm; i++) {
202 for (j=0; j<mm; j++) {
203 for (k=0; k<mm; k++) {
204 one[ijk] = new particle((i*a+lg*a*0.5),(j*a+lg*a*0.5),(k*a),
205 xvelocity,yvelocity,zvelocity,sh_force,sh_force2,id,this);
211 for (lg=1; lg<=2; lg++) {
212 for (i=0; i<mm; i++) {
213 for (j=0; j<mm; j++) {
214 for (k=0; k<mm; k++) {
215 one[ijk] = new particle((i*a+(2-lg)*a*0.5),(j*a+(lg-1)*a*0.5),
216 (k*a+a*0.5),xvelocity,yvelocity,zvelocity,sh_force,sh_force2,id,this);
224 /* Initialise velocities */
230 randnum = new random(iseed,v1,v2);
232 for (i=0; i<mdsize; i+=2) {
234 one[i].xvelocity = r*randnum.v1;
235 one[i+1].xvelocity = r*randnum.v2;
238 for (i=0; i<mdsize; i+=2) {
240 one[i].yvelocity = r*randnum.v1;
241 one[i+1].yvelocity = r*randnum.v2;
244 for (i=0; i<mdsize; i+=2) {
246 one[i].zvelocity = r*randnum.v1;
247 one[i+1].zvelocity = r*randnum.v2;
251 /* velocity scaling */
256 for(i=0;i<mdsize;i++) {
257 sp = sp + one[i].xvelocity;
261 for(i=0;i<mdsize;i++) {
262 one[i].xvelocity = one[i].xvelocity - sp;
263 ekin = ekin + one[i].xvelocity*one[i].xvelocity;
267 for(i=0;i<mdsize;i++) {
268 sp = sp + one[i].yvelocity;
272 for(i=0;i<mdsize;i++) {
273 one[i].yvelocity = one[i].yvelocity - sp;
274 ekin = ekin + one[i].yvelocity*one[i].yvelocity;
279 for(i=0;i<mdsize;i++) {
280 sp = sp + one[i].zvelocity;
284 for(i=0;i<mdsize;i++) {
285 one[i].zvelocity = one[i].zvelocity - sp;
286 ekin = ekin + one[i].zvelocity*one[i].zvelocity;
290 sc = h * Math.sqrt(tref/ts);
293 for(i=0;i<mdsize;i++) {
295 one[i].xvelocity = one[i].xvelocity * sc;
296 one[i].yvelocity = one[i].yvelocity * sc;
297 one[i].zvelocity = one[i].zvelocity * sc;
302 /* Synchronise threads and start timer before MD simulation */
305 //Barrier.enterBarrier(br);
306 if (id == 0) JGFInstrumentor.startTimer("Section3:MolDyn:Run", instr.timers);
307 // Barrier.enterBarrier(br);
314 for (move=0;move<movemx;move++) {
316 /* move the particles and update velocities */
318 for (i=0;i<mdsize;i++) {
319 one[i].domove(side,i);
324 //Barrier.enterBarrier(br);
328 for (i=0;i<mdsize;i++) {
329 sh_force[j][i] = 0.0;
336 mymd.interacts[id] = 0;
339 //Barrier.enterBarrier(br);
346 for (i=0+id;i<mdsize;i+=nthreads) {
347 one[i].force(side,rcoff,mdsize,i,xx,yy,zz,mymd);
351 //Barrier.enterBarrier(br);
354 /* update force arrays */
357 for(int k=0;k<3;k++) {
358 for(i=0;i<mdsize;i++) {
359 for(j=0;j<nthreads;j++) {
360 sh_force[k][i] += sh_force2[k][j][i];
367 for(int k=0;k<3;k++) {
368 for(i=0;i<mdsize;i++) {
369 for(j=0;j<nthreads;j++) {
370 sh_force2[k][j][i] = 0.0;
377 for(j=1;j<nthreads;j++) {
378 mymd.epot[0] += mymd.epot[j];
379 mymd.vir[0] += mymd.vir[j];
381 for(j=1;j<nthreads;j++) {
382 mymd.epot[j] = mymd.epot[0];
383 mymd.vir[j] = mymd.vir[0];
385 for(j=0;j<nthreads;j++) {
386 mymd.interactions += mymd.interacts[j];
391 //Barrier.enterBarrier(br);
396 for (i=0;i<mdsize;i++) {
397 sh_force[j][i] = sh_force[j][i] * hsq2;
405 //Barrier.enterBarrier(br);
408 /*scale forces, update velocities */
410 for (i=0;i<mdsize;i++) {
411 sum = sum + one[i].mkekin(hsq2,i);
419 /* average velocity */
421 for (i=0;i<mdsize;i++) {
422 velt = one[i].velavg(vaverh,h);
423 if(velt > vaverh) { count = count + 1.0; }
429 /* temperature scale if required */
431 if((move < istop) && (((move+1) % irep) == 0)) {
432 sc = Math.sqrt(tref / (tscale*ekin));
433 for (i=0;i<mdsize;i++) {
436 ekin = tref / tscale;
439 /* sum to get full potential energy and virial */
441 if(((move+1) % iprint) == 0) {
442 mymd.ek[id] = 24.0*ekin;
443 mymd.epot[id] = 4.0*mymd.epot[id];
444 etot = mymd.ek[id] + mymd.epot[id];
445 temp = tscale * ekin;
446 pres = den * 16.0 * (ekin - mymd.vir[id]) / mdsize;
448 rp = (count / mdsize) * 100.0;
451 //Barrier.enterBarrier(br);
456 //Barrier.enterBarrier(br);
458 if (id == 0) JGFInstrumentor.stopTimer("Section3:MolDyn:Run", instr.timers);
469 public double xcoord, ycoord, zcoord;
470 public double xvelocity,yvelocity,zvelocity;
473 double [][] sh_force;
474 double [][][] sh_force2;
477 public particle(double xcoord, double ycoord, double zcoord, double xvelocity,
478 double yvelocity,double zvelocity,double [][] sh_force,
479 double [][][] sh_force2,int id,mdRunner runner) {
481 this.xcoord = xcoord;
482 this.ycoord = ycoord;
483 this.zcoord = zcoord;
484 this.xvelocity = xvelocity;
485 this.yvelocity = yvelocity;
486 this.zvelocity = zvelocity;
487 this.sh_force = sh_force;
488 this.sh_force2 = sh_force2;
493 public void domove(double side,int part_id) {
495 xcoord = xcoord + xvelocity + sh_force[0][part_id];
496 ycoord = ycoord + yvelocity + sh_force[1][part_id];
497 zcoord = zcoord + zvelocity + sh_force[2][part_id];
499 if(xcoord < 0) { xcoord = xcoord + side; }
500 if(xcoord > side) { xcoord = xcoord - side; }
501 if(ycoord < 0) { ycoord = ycoord + side; }
502 if(ycoord > side) { ycoord = ycoord - side; }
503 if(zcoord < 0) { zcoord = zcoord + side; }
504 if(zcoord > side) { zcoord = zcoord - side; }
506 xvelocity = xvelocity + sh_force[0][part_id];
507 yvelocity = yvelocity + sh_force[1][part_id];
508 zvelocity = zvelocity + sh_force[2][part_id];
512 public void force(double side, double rcoff,int mdsize,int x, double xx, double yy, double zz, JGFMolDynBench mymd) {
518 double rd,rrd,rrd2,rrd3,rrd4,rrd6,rrd7,r148;
519 double forcex,forcey,forcez;
522 rcoffs = rcoff*rcoff;
528 for (int i=x+1;i<mdsize;i++) {
529 xx = this.xcoord - runner.one[i].xcoord;
530 yy = this.ycoord - runner.one[i].ycoord;
531 zz = this.zcoord - runner.one[i].zcoord;
533 if(xx < (-sideh)) { xx = xx + side; }
534 if(xx > (sideh)) { xx = xx - side; }
535 if(yy < (-sideh)) { yy = yy + side; }
536 if(yy > (sideh)) { yy = yy - side; }
537 if(zz < (-sideh)) { zz = zz + side; }
538 if(zz > (sideh)) { zz = zz - side; }
541 rd = xx*xx + yy*yy + zz*zz;
550 mymd.epot[id] = mymd.epot[id] + (rrd6 - rrd3);
551 r148 = rrd7 - 0.5*rrd4;
552 mymd.vir[id] = mymd.vir[id] - rd*r148;
556 sh_force2[0][id][i] = sh_force2[0][id][i] - forcex;
561 sh_force2[1][id][i] = sh_force2[1][id][i] - forcey;
566 sh_force2[2][id][i] = sh_force2[2][id][i] - forcez;
568 mymd.interacts[id]++;
573 sh_force2[0][id][x] = sh_force2[0][id][x] + fxi;
574 sh_force2[1][id][x] = sh_force2[1][id][x] + fyi;
575 sh_force2[2][id][x] = sh_force2[2][id][x] + fzi;
579 public double mkekin(double hsq2,int part_id) {
583 xvelocity = xvelocity + sh_force[0][part_id];
584 yvelocity = yvelocity + sh_force[1][part_id];
585 zvelocity = zvelocity + sh_force[2][part_id];
587 sumt = (xvelocity*xvelocity)+(yvelocity*yvelocity)+(zvelocity*zvelocity);
591 public double velavg(double vaverh,double h) {
596 sq = Math.sqrt(xvelocity*xvelocity + yvelocity*yvelocity +
597 zvelocity*zvelocity);
603 public void dscal(double sc,int incx) {
605 xvelocity = xvelocity * sc;
606 yvelocity = yvelocity * sc;
607 zvelocity = zvelocity * sc;
620 public random(int iseed,double v1,double v2) {
626 public double update() {
629 double scale= 4.656612875e-10;
633 int imod = 2147483647;
635 if (iseed<=0) { iseed = 1; }
638 is1 = (iseed-is2)/32768;
641 is1 = (is1*imult+(iss2-is2)/32768) % (65536);
643 iseed = (is1*32768+is2) % imod;
645 rand = scale * iseed;
651 public double seed() {
665 r = Math.sqrt(-2.0*Math.log(s)/s);