/* decrease indentation and close for loop */ void mknb_end_loop(void) { mknb_indent_level--; if(mknb_fortran) mknb_code("end do"); else mknb_code("}"); mknb_code(""); }
/* integer constant */ void mknb_declare_const_int(char *name, int value) { char type_name[255]; sprintf(type_name, "%-13s", mknb_fortran ? "integer*4" : "const int"); if(mknb_fortran) { mknb_code("%s %s", type_name ,name); mknb_code(" parameter (%s = %d)",name,value); } else mknb_code("%s %s = %d;", type_name ,name, value); }
void mknb_do_else() { mknb_indent_level--; if(mknb_fortran) mknb_code("else"); else { mknb_code("}"); mknb_code("else"); mknb_code("{"); } mknb_indent_level++; }
void mknb_start_if(char *cond) { mknb_code(""); if(mknb_fortran) mknb_code("if (%s) then",cond); else { mknb_code("if(%s)", cond); mknb_code("{"); } mknb_indent_level++; }
/* Declare a constant fp variable */ void mknb_declare_const_real(char *name, double value) { char type_name[255]; if(mknb_fortran) { sprintf(type_name, "%-13s", mknb_double ? "real*8" : "real*4"); mknb_code("%s %s",type_name,name); mknb_code(" parameter (%s = %f)",name,value); } else { sprintf(type_name, "%-13s", mknb_double ? "const double" : "const float"); mknb_code("%s %s = %.16f;",type_name,name,value); } }
/* Start a for loop and increase indentation.*/ void mknb_start_loop(char *lvar,char *from,char *to) { mknb_code(""); if(mknb_fortran) { mknb_code("do %s=%s,%s",lvar,from,to); } else { mknb_code("for(%s=%s; (%s<%s); %s++)", lvar,from,lvar,to,lvar); mknb_code("{"); } mknb_indent_level++; }
/* Arbitrary declaration */ void mknb_declare_other(char *type_name,char *name) { char tmp[255]; sprintf(tmp,"%-13s", type_name); mknb_code("%s %s%s", tmp, name, mknb_fortran ? "" : ";"); }
/* 4-byte Integer (same size as single precision fp) */ void mknb_declare_int4(char *name) { char type_name[255]; sprintf(type_name, "%-13s", mknb_fortran ? "integer*4" : "int"); mknb_code("%s %s%s", type_name ,name, mknb_fortran ? "" : ";"); }
/* Declare a single-precision floating point var. */ void mknb_declare_real4(char *name) { char type_name[255]; sprintf(type_name, "%-13s", mknb_fortran ? "real*4" : "float"); mknb_code("%s %s%s", type_name ,name, mknb_fortran ? "" : ";"); }
/* Define a new floating-point variable */ void mknb_declare_real(char *name) { char type_name[255]; if(mknb_fortran) sprintf(type_name, "%-13s", mknb_double ? "real*8" : "real*4"); else sprintf(type_name, "%-13s", mknb_double ? "double" : "float"); mknb_code("%s %s%s",type_name,name, mknb_fortran ? "" : ";"); }
void mknb_outerloop(void) { int i,nflops = 0; char tmp[255]; int indent; if(mknb_options.threads) { mknb_comment("Loop over thread workunits"); if(mknb_fortran) { char space[25]; indent = MKNB_FORTRAN_INDENT_STEP*mknb_indent_level; for(i=0 ; i<indent ; i++) space[i]=' '; space[i]=0; fprintf(mknb_output, " 10 %scall f77kernelsync(mtx,count,nri,nthreads,nn0,nn1)\n",space); /* since f77 use call-by-reference we can send the pointer of the * count variable and the mutex to c without fortran knowing about it! */ mknb_indent_level++; mknb_code("if(nn1.gt.nri) nn1=nri"); mknb_comment("Start outer loop over neighborlists"); mknb_start_loop("n", "nn0+1", "nn1"); } else { /* C */ mknb_code(""); mknb_code("do"); mknb_code("{"); mknb_indent_level++; mknb_code("gmx_thread_mutex_lock((gmx_thread_mutex_t *)mtx);"); mknb_assign("nn0","*count"); mknb_comment("Take successively smaller chunks (at least 10 lists)"); mknb_assign("nn1","nn0+(nri-nn0)/(2*nthreads)+10"); /* take sucessively smaller chunks */ mknb_assign("*count","nn1"); mknb_code("gmx_thread_mutex_unlock((gmx_thread_mutex_t *)mtx);"); mknb_code("if(nn1>nri) nn1=nri;"); mknb_comment("Start outer loop over neighborlists"); mknb_start_loop("n", "nn0", "nn1"); } } else { mknb_comment("Start outer loop over neighborlists"); mknb_start_loop("n", (mknb_fortran) ? "1" : "0", "nri"); } /* load shift index and then shift vector for this list */ nflops += mknb_load_shift_vector(); mknb_comment("Load limits for loop over neighbors"); mknb_assign("nj0", "%s%s", mknb_array("jindex","n"), (mknb_fortran) ? "+1" : ""); mknb_assign("nj1", mknb_array("jindex","n+1")); mknb_comment("Get outer coordinate index"); mknb_assign("ii", "%s%s", mknb_array("iinr","n"), (mknb_fortran) ? "+1" : ""); mknb_assign("ii3", "3*ii%s", (mknb_fortran) ? "-2" : ""); nflops += mknb_load_outer_coordinates(); nflops += mknb_load_outer_parameters(); nflops += mknb_zero_outer_potential(); nflops += mknb_zero_outer_forces(); /* do the inner loop ( separate nflops, so no return value) */ mknb_innerloop(); nflops += mknb_update_outer_forces(); nflops += mknb_update_outer_potential(); /* Update innerloop counter (for accounting) if we did threads */ mknb_comment("Increment number of inner iterations"); if(mknb_options.threads) mknb_assign("ninner","ninner + nj1 - nj0"); /* close outer loop */ sprintf(tmp,"Outer loop uses %d flops/iteration",nflops); mknb_comment(tmp); mknb_end_loop(); if(mknb_options.threads) { mknb_comment("Increment number of outer iterations"); mknb_assign("nouter","nouter + nn1 - nn0"); mknb_indent_level--; if(mknb_fortran) mknb_code("if(nn1.lt.nri) goto 10"); else { mknb_code("}"); mknb_code("while (nn1<nri);"); mknb_code(""); } } }