int write_grid(const char* ofile, float gridspacing, float cx, float cy, float cz, long int numplane, long int numcol, long int numpt, const float* eners) { /* Write the current energy grid to a .dx file for later reading */ FILE* dx_out; int i, j, k; int arrpos; int numentries; float starttime, endtime; rt_timerhandle timer; arrpos=0; dx_out = fopen(ofile, "w"); if (dx_out == NULL) { fprintf(stderr, "Error: Couldn't open output dxfile %s. Exiting...", ofile); return 1; } timer = rt_timer_create(); rt_timer_start(timer); /* start the timer */ starttime = rt_timer_timenow(timer); /* Write a dx header */ fprintf(dx_out, "# Data from cionize 1.0\n#\n# Potential (kT/e at 298.15K)\n#\n"); fprintf(dx_out, "object 1 class gridpositions counts %li %li %li\n", numpt, numcol, numplane); fprintf(dx_out, "origin %12.6e %12.6e %12.6e\n", cx, cy, cz); fprintf(dx_out, "delta %12.6e %12.6e %12.6e\n", gridspacing, 0.0, 0.0); fprintf(dx_out, "delta %12.6e %12.6e %12.6e\n", 0.0, gridspacing, 0.0); fprintf(dx_out, "delta %12.6e %12.6e %12.6e\n", 0.0, 0.0, gridspacing); fprintf(dx_out, "object 2 class gridconnections counts %li %li %li\n", numpt, numcol, numplane); fprintf(dx_out, "object 3 class array type double rank 0 items %li data follows\n", numplane * numcol * numpt); /* Write the main data array */ numentries = 0; for (i=0; i<numpt; i++) { for (j=0; j<numcol; j++) { for (k=0; k<numplane; k++) { arrpos = (k*numcol * numpt + j*numpt + i); fprintf(dx_out, "%-13.6e ", POT_CONV * eners[arrpos]); if (numentries % 3 == 2) fprintf(dx_out, "\n"); numentries = numentries + 1; } } } /* Write the opendx footer */ if (arrpos % 3 != 2) fprintf(dx_out, "\n"); fprintf(dx_out, "attribute \"dep\" string \"positions\"\nobject \"regular positions regular connections\" class field\ncomponent \"positions\" value 1\ncomponent \"connections\" value 2\ncomponent \"data\" value 3"); fclose(dx_out); /* check our time */ endtime = rt_timer_timenow(timer); printf("Time for grid output: %.1f\n", endtime - starttime); rt_timer_destroy(timer); return 0; }
/* * Save the rendered image to disk. */ static void renderio(scenedef * scene) { flt iotime; char msgtxt[256]; rt_timerhandle ioth; /* I/O timer handle */ ioth=rt_timer_create(); rt_timer_start(ioth); if (scene->imgbufformat == RT_IMAGE_BUFFER_RGB96F) { if (scene->imgprocess & RT_IMAGE_NORMALIZE) { normalize_rgb96f(scene->hres, scene->vres, (float *) scene->img); rt_ui_message(MSG_0, "Post-processing: normalizing pixel values."); } if (scene->imgprocess & RT_IMAGE_GAMMA) { gamma_rgb96f(scene->hres, scene->vres, (float *) scene->img, scene->imggamma); rt_ui_message(MSG_0, "Post-processing: gamma correcting pixel values."); } } else if (scene->imgbufformat == RT_IMAGE_BUFFER_RGB24) { if (scene->imgprocess & (RT_IMAGE_NORMALIZE | RT_IMAGE_GAMMA)) rt_ui_message(MSG_0, "Can't post-process 24-bit integer image data"); } /* support cropping of output images for SPECMPI benchmarks */ if (scene->imgcrop.cropmode == RT_CROP_DISABLED) { writeimage(scene->outfilename, scene->hres, scene->vres, scene->img, scene->imgbufformat, scene->imgfileformat); } else { /* crop image before writing if necessary */ if (scene->imgbufformat == RT_IMAGE_BUFFER_RGB96F) { float *imgcrop; imgcrop = image_crop_rgb96f(scene->hres, scene->vres, scene->img, scene->imgcrop.xres, scene->imgcrop.yres, scene->imgcrop.xstart, scene->imgcrop.ystart); writeimage(scene->outfilename, scene->imgcrop.xres, scene->imgcrop.yres, imgcrop, scene->imgbufformat, scene->imgfileformat); free(imgcrop); } else if (scene->imgbufformat == RT_IMAGE_BUFFER_RGB24) { unsigned char *imgcrop; imgcrop = image_crop_rgb24(scene->hres, scene->vres, scene->img, scene->imgcrop.xres, scene->imgcrop.yres, scene->imgcrop.xstart, scene->imgcrop.ystart); writeimage(scene->outfilename, scene->imgcrop.xres, scene->imgcrop.yres, imgcrop, scene->imgbufformat, scene->imgfileformat); free(imgcrop); } } rt_timer_stop(ioth); iotime = rt_timer_time(ioth); rt_timer_destroy(ioth); sprintf(msgtxt, " Image I/O Time: %10.4f seconds", iotime); rt_ui_message(MSG_0, msgtxt); }
int calc_grid_energies_excl_mgrid(float* atoms, float* grideners, long int numplane, long int numcol, long int numpt, long int natoms, float gridspacing, unsigned char* excludepos, int maxnumprocs) { // cionize_params* params, cionize_molecule* molecule, cionize_grid* grid) { int i; enthrparms *parms; rt_thread_t * threads; #if defined(THR) int numprocs; int availprocs = rt_thread_numprocessors(); if (params->maxnumprocs <= availprocs) { numprocs = params->maxnumprocs; } else { numprocs = availprocs; } #else int numprocs = 1; #endif printf("calc_grid_energies_excl_mgrid()\n"); /* DH: setup and compute long-range */ MgridParam mg_prm; MgridSystem mg_sys; Mgrid mg; //MgridLattice *lattice; int j, k; int gridfactor; double h, h_1; int nspacings; double *eh; int ndim; int ii, jj, kk; int im, jm, km; int ilo, jlo, klo; double dx_h, dy_h, dz_h; double xphi[4], yphi[4], zphi[4]; double t, en, c; int koff, jkoff, index; rt_timerhandle timer; float totaltime; memset(&mg_prm, 0, sizeof(mg_prm)); memset(&mg_sys, 0, sizeof(mg_sys)); /* * set mgrid parameters * * make sure origin of mgrid's grid is at ionize's grid origin (0,0,0) * * length is (number of grid spacings) * (grid spacing), * where the number of spacings is one less than number of grid points */ mg_prm.length = (numpt-1) * gridspacing; mg_prm.center.x = 0.5 * mg_prm.length; mg_prm.center.y = 0.5 * mg_prm.length; mg_prm.center.z = 0.5 * mg_prm.length; /* make sure domain and grid are both cubic */ if (numpt != numcol || numcol != numplane) { printf("ERROR: grid must be cubic\n"); return -1; } /* * grid used by mgrid needs spacing h >= 2 * * determine grid factor: (2^gridfactor)*h_ionize = h_mgrid */ gridfactor = 0; //nspacings = numpt - 1; nspacings = numpt; /* add one more spacing so that interpolation loop below will work */ h = gridspacing; while (h < 2.0) { h *= 2; nspacings = ((nspacings & 1) ? nspacings/2 + 1 : nspacings/2); gridfactor++; } mg_prm.nspacings = nspacings; /* have to modify mgrid length */ mg_prm.length += h; mg_prm.center.x = 0.5 * mg_prm.length; mg_prm.center.y = 0.5 * mg_prm.length; mg_prm.center.z = 0.5 * mg_prm.length; h_1 = 1.0/h; mg_prm.cutoff = CUTOFF; mg_prm.boundary = MGRID_NONPERIODIC; /* choice of splitting must be consistent with short-range below */ #if defined(CUBIC_TAYLOR2) mg_prm.approx = MGRID_CUBIC; mg_prm.split = MGRID_TAYLOR2; #elif defined(QUINTIC1_TAYLOR3) mg_prm.approx = MGRID_QUINTIC1; mg_prm.split = MGRID_TAYLOR3; #elif defined(HEPTIC1_TAYLOR4) mg_prm.approx = MGRID_HEPTIC1; mg_prm.split = MGRID_TAYLOR4; /* #elif defined(HERMITE_TAYLOR3) mg_prm.approx = MGRID_HERMITE; mg_prm.split = MGRID_TAYLOR3; */ #endif mg_prm.natoms = natoms; printf("natom = %d\n", mg_prm.natoms); printf("mgrid center = %g %g %g\n", mg_prm.center.x, mg_prm.center.y, mg_prm.center.z); printf("mgrid length = %g\n", mg_prm.length); printf("mgrid nspacings = %d\n", mg_prm.nspacings); /* setup mgrid system */ mg_sys.f_elec = (MD_Dvec *) calloc(mg_prm.natoms, sizeof(MD_Dvec)); mg_sys.pos = (MD_Dvec *) calloc(mg_prm.natoms, sizeof(MD_Dvec)); mg_sys.charge = (double *) calloc(mg_prm.natoms, sizeof(double)); for (i = 0; i < mg_prm.natoms; i++) { mg_sys.pos[i].x = atoms[4*i ]; mg_sys.pos[i].y = atoms[4*i + 1]; mg_sys.pos[i].z = atoms[4*i + 2]; mg_sys.charge[i] = atoms[4*i + 3]; } /* setup mgrid solver and compute */ if (mgrid_param_config(&mg_prm)) { printf("ERROR: mgrid_param_config() failed\n"); return -1; } printf("spacing = %g\n", mg_prm.spacing); if (mgrid_init(&mg)) { printf("ERROR: mgrid_init() failed\n"); return -1; } if (mgrid_setup(&mg, &mg_sys, &mg_prm)) { printf("ERROR: mgrid_setup() failed\n"); return -1; } timer = rt_timer_create(); rt_timer_start(timer); if (mgrid_force(&mg, &mg_sys)) { printf("ERROR: mgrid_force() failed\n"); return -1; } /* DH: end setup and compute long-range */ printf(" using %d processors\n", numprocs); /* allocate array of threads */ threads = (rt_thread_t *) calloc(numprocs * sizeof(rt_thread_t), 1); /* allocate and initialize array of thread parameters */ parms = (enthrparms *) malloc(numprocs * sizeof(enthrparms)); for (i=0; i<numprocs; i++) { parms[i].threadid = i; parms[i].threadcount = numprocs; parms[i].atoms = atoms; parms[i].grideners = grideners; parms[i].numplane = numplane; parms[i].numcol = numcol; parms[i].numpt = numpt; parms[i].natoms = natoms; parms[i].gridspacing = gridspacing; parms[i].excludepos = excludepos; } #if defined(THR) /* spawn child threads to do the work */ for (i=0; i<numprocs; i++) { rt_thread_create(&threads[i], energythread, &parms[i]); } /* join the threads after work is done */ for (i=0; i<numprocs; i++) { rt_thread_join(threads[i], NULL); } #else /* single thread does all of the work */ energythread((void *) &parms[0]); #endif /* DH: tabulate and cleanup long-range */ /* interpolate from mgrid potential lattice */ eh = (double *)(mg.egrid[0].data); /* mgrid's long-range potential lattice */ ndim = mg.egrid[0].ni; /* number of points in each dimension of lattice */ for (kk = 0; kk < numplane; kk++) { for (jj = 0; jj < numcol; jj++) { for (ii = 0; ii < numpt; ii++) { /* distance between atom and corner measured in grid points */ dx_h = (ii*gridspacing) * h_1; dy_h = (jj*gridspacing) * h_1; dz_h = (kk*gridspacing) * h_1; /* find closest mgrid lattice point less than or equal to */ im = ii >> gridfactor; jm = jj >> gridfactor; km = kk >> gridfactor; #if defined(CUBIC_TAYLOR2) ilo = im-1; jlo = jm-1; klo = km-1; /* find t for x dimension and compute xphi */ t = dx_h - ilo; xphi[0] = 0.5 * (1 - t) * (2 - t) * (2 - t); t--; xphi[1] = (1 - t) * (1 + t - 1.5 * t * t); t--; xphi[2] = (1 + t) * (1 - t - 1.5 * t * t); t--; xphi[3] = 0.5 * (1 + t) * (2 + t) * (2 + t); /* find t for y dimension and compute yphi */ t = dy_h - jlo; yphi[0] = 0.5 * (1 - t) * (2 - t) * (2 - t); t--; yphi[1] = (1 - t) * (1 + t - 1.5 * t * t); t--; yphi[2] = (1 + t) * (1 - t - 1.5 * t * t); t--; yphi[3] = 0.5 * (1 + t) * (2 + t) * (2 + t); /* find t for z dimension and compute zphi */ t = dz_h - klo; zphi[0] = 0.5 * (1 - t) * (2 - t) * (2 - t); t--; zphi[1] = (1 - t) * (1 + t - 1.5 * t * t); t--; zphi[2] = (1 + t) * (1 - t - 1.5 * t * t); t--; zphi[3] = 0.5 * (1 + t) * (2 + t) * (2 + t); /* determine 64=4*4*4 eh grid stencil contribution to potential */ en = 0; for (k = 0; k < 4; k++) { koff = (k + klo) * ndim; for (j = 0; j < 4; j++) { jkoff = (koff + (j + jlo)) * ndim; c = yphi[j] * zphi[k]; for (i = 0; i < 4; i++) { index = jkoff + (i + ilo); /* ASSERT(&eh[index] == mgrid_lattice_elem(&(mg.egrid[0]), i+ilo, j+jlo, k+klo)); */ if (&eh[index] != mgrid_lattice_elem(&(mg.egrid[0]), i+ilo, j+jlo, k+klo)) { printf("ndim=%d index=%d i+ilo=%d j+jlo=%d k+klo=%d\n" "ia=%d ib=%d ni=%d\n" "ja=%d jb=%d nj=%d\n" "ka=%d kb=%d nk=%d\n", ndim, index, i+ilo, j+jlo, k+klo, mg.egrid[0].ia, mg.egrid[0].ib, mg.egrid[0].ni, mg.egrid[0].ja, mg.egrid[0].jb, mg.egrid[0].nj, mg.egrid[0].ka, mg.egrid[0].kb, mg.egrid[0].nk ); abort(); } en += eh[index] * xphi[i] * c; } } } /* end CUBIC */ #endif //ENERGY(grid->eners[k*numcol*numpt + j*numpt + i]); grideners[kk*numcol*numpt + jj*numpt + ii] += (float)en; // (float) *((double *)mgrid_lattice_elem(lattice, i, j, k)); //ENERGY((float) *((double *)mgrid_lattice_elem(lattice, i, j, k))); //ENERGY(grid->eners[k*numcol*numpt + j*numpt + i]*560.47254); } } } totaltime = rt_timer_timenow(timer); printf("total time for mgrid: %.1f\n", totaltime); rt_timer_destroy(timer); /* cleanup mgrid */ mgrid_done(&mg); free(mg_sys.f_elec); free(mg_sys.pos); free(mg_sys.charge); /* DH: tabulate and cleanup long-range */ /* free thread parms */ free(parms); free(threads); return 0; }
static void * energythread(void *voidparms) { enthrparms *parms = (enthrparms *) voidparms; /* * copy in per-thread parameters */ const float *atoms = parms->atoms; float* grideners = parms->grideners; const long int numplane = parms->numplane; const long int numcol = parms->numcol; const long int numpt = parms->numpt; const long int natoms = parms->natoms; const float gridspacing = parms->gridspacing; const unsigned char* excludepos = parms->excludepos; const int threadid = parms->threadid; const int threadcount = parms->threadcount; /* Calculate the coulombic energy at each grid point from each atom * This is by far the most time consuming part of the process * We iterate over z,y,x, and then atoms * This function is the same as the original calc_grid_energies, except * that it utilizes the exclusion grid */ int i,j,k,n; //Loop counters //float lasttime; float totaltime; // Holds atom x, dy**2+dz**2, and atom q as x/r/q/x/r/q... float * xrq = (float *) malloc(3*natoms * sizeof(float)); int maxn = natoms * 3; rt_timerhandle timer = rt_timer_create(); rt_timer_start(timer); //printf("thread %d started...\n", threadid); // For each point in the cube... for (k=threadid; k<numplane; k+= threadcount) { const float z = gridspacing * (float) k; //lasttime = rt_timer_timenow(timer); for (j=0; j<numcol; j++) { const float y = gridspacing * (float) j; long int voxaddr = numcol*numpt*k + numpt*j; // Prebuild a table of dy and dz values on a per atom basis for (n=0; n<natoms; n++) { int addr3 = n*3; int addr4 = n*4; float dy = y - atoms[addr4 + 1]; float dz = z - atoms[addr4 + 2]; xrq[addr3 ] = atoms[addr4]; xrq[addr3 + 1] = dz*dz + dy*dy; xrq[addr3 + 2] = atoms[addr4 + 3]; } #if defined(__INTEL_COMPILER) // help the vectorizer make reasonable decisions (used prime to keep it honest) #pragma loop count(1009) #endif for (i=0; i<numpt; i++) { // Check if we're on an excluded point, and skip it if we are if (excludepos[voxaddr + i] == 0) { float energy = 0; // Energy of current grid point const float x = gridspacing * (float) i; #if defined(__INTEL_COMPILER) // help the vectorizer make reasonable decisions #pragma vector always #endif // Calculate the interaction with each atom #if 1 for (n=0; n<maxn; n+=3) { float dx = x - xrq[n]; // DH: short-range part: 1/r - g(r) float r2 = dx*dx + xrq[n+1]; if (r2 < CUTOFF*CUTOFF) { float s = r2/(CUTOFF*CUTOFF); #if defined(CUBIC_TAYLOR2) energy += xrq[n + 2]*(1./sqrtf(r2) - (1./CUTOFF)*(1+(s-1)*(-1./2+(s-1)*(3./8)))); #elif defined(QUINTIC1_TAYLOR3) energy += xrq[n + 2]*(1./sqrtf(r2) - (1./CUTOFF)*(1 + (s-1)*(-1./2 + (s-1)*(3./8 + (s-1)*(-5./16))))); #elif defined(HEPTIC1_TAYLOR4) energy += xrq[n + 2]*(1./sqrtf(r2) - (1./CUTOFF)*(1 + (s-1)*(-1./2 + (s-1)*(3./8 + (s-1)*(-5./16 + (s-1)*(35./128)))))); #elif defined(HERMITE_TAYLOR3) energy += xrq[n + 2]*(1./sqrtf(r2) - (1./CUTOFF)*(1 + (s-1)*(-1./2 + (s-1)*(3./8 + (s-1)*(-5./16))))); #endif } } #endif //ENERGY(energy); grideners[voxaddr + i] = energy; } } } #if 0 totaltime = rt_timer_timenow(timer); printf("thread[%d] plane %d/%ld time %.2f, elapsed %.1f, est. total: %.1f\n", threadid, k, numplane, totaltime - lasttime, totaltime, totaltime * numplane / (k+1)); #endif } totaltime = rt_timer_timenow(timer); printf("total time for short-range part: %.1f\n", totaltime); rt_timer_destroy(timer); free(xrq); return NULL; }
int ray(int argc, char **argv) { #else int main(int argc, char **argv) { #endif SceneHandle scene; unsigned int rc; argoptions opt; char * filename; int node, fileindex; rt_timerhandle parsetimer; size_t len; node = rt_initialize(&argc, &argv); rt_set_ui_message(my_ui_message); rt_set_ui_progress(my_ui_progress); if (node == 0) { printf("Tachyon Parallel/Multiprocessor Ray Tracer Version %s \n", TACHYON_VERSION_STRING); printf("Copyright 1994-2010, John E. Stone <*****@*****.**> \n"); printf("------------------------------------------------------------ \n"); } if ((rc = getargs(argc, argv, &opt, node)) != 0) { rt_finalize(); exit(rc); } if (opt.numfiles > 1) { printf("Rendering %d scene files.\n", opt.numfiles); } for (fileindex=0; fileindex<opt.numfiles; fileindex++) { scene = rt_newscene(); /* process command line overrides */ presceneoptions(&opt, scene); filename = opt.filenames[fileindex]; if (opt.numfiles > 1) { printf("\nRendering scene file %d of %d, %s\n", fileindex+1, opt.numfiles, filename); } parsetimer=rt_timer_create(); rt_timer_start(parsetimer); len = strlen(filename); if (len > 4 && (!strcmp(filename+len-4, ".nff") || !strcmp(filename+len-4, ".NFF"))) { rc = ParseNFF(filename, scene); /* must be an NFF file */ } else if (len > 3 && (!strcmp(filename+len-3, ".ac") || !strcmp(filename+len-3, ".AC"))) { rc = ParseAC3D(filename, scene); /* Must be an AC3D file */ } #ifdef USELIBMGF else if (len > 4 && (!strcmp(filename+len-4, ".mgf") || !strcmp(filename+len-4, ".MGF"))) { rc = ParseMGF(filename, scene, 1); /* Must be an MGF file */ } #endif else { rc = readmodel(filename, scene); /* Assume its a Tachyon scene file */ } rt_timer_stop(parsetimer); if (rc == PARSENOERR && node == 0) printf("Scene Parsing Time: %10.4f seconds\n", rt_timer_time(parsetimer)); rt_timer_destroy(parsetimer); if (rc != PARSENOERR && node == 0) { switch(rc) { case PARSEBADFILE: printf("Parser failed due to nonexistent input file: %s\n", filename); break; case PARSEBADSUBFILE: printf("Parser failed due to nonexistent included file.\n"); break; case PARSEBADSYNTAX: printf("Parser failed due to an input file syntax error.\n"); break; case PARSEEOF: printf("Parser unexpectedly hit an end of file.\n"); break; case PARSEALLOCERR: printf("Parser ran out of memory.\n"); break; } if (fileindex+1 < opt.numfiles) printf("Aborting render, continuing with next scene file...\n"); else printf("Aborting render.\n"); rt_deletescene(scene); /* free the scene */ continue; /* process the next scene */ } /* process command line overrides */ postsceneoptions(&opt, scene); /* choose which rendering mode to use */ if (opt.usecamfile == 1) { return animate_scene(opt, scene, node); /* fly using prerecorded data */ } else if (strlen(opt.spaceball) > 0) { return fly_scene(opt, scene, node); /* fly with spaceball etc */ } else { if (opt.numfiles > 1 && opt.nosave != 1) { char multioutfilename[FILENAME_MAX]; sprintf(multioutfilename, opt.outfilename, fileindex); rt_outputfile(scene, multioutfilename); } rt_renderscene(scene); /* Render a single frame */ } rt_deletescene(scene); /* free the scene, get ready for next one */ } rt_finalize(); /* close down the rendering library and MPI */ freeoptions(&opt); /* free parsed command line option data */ return 0; }
/* * main loop for creating animations by playing recorded camera fly-throughs */ static int animate_scene(argoptions opt, SceneHandle scene, int node) { char outfilename[1000]; FILE * camfp; dispHandle * dh = NULL; if (node == 0) dh = tachyon_display_create(scene); /* if we have a camera file, then animate.. */ if ((camfp = fopen(opt.camfilename, "r")) != NULL) { floatvec cv, cu, cc; apivector cmv, cmu, cmc; int frameno = 0; float fps; rt_timerhandle fpstimer; rt_timerhandle animationtimer; rt_set_ui_message(NULL); rt_set_ui_progress(NULL); if (node == 0) printf("Running Camera File: %s\n", opt.camfilename); fpstimer=rt_timer_create(); animationtimer=rt_timer_create(); rt_timer_start(animationtimer); while (!feof(camfp)) { fscanf(camfp, "%f %f %f %f %f %f %f %f %f", &cv.x, &cv.y, &cv.z, &cu.x, &cu.y, &cu.z, &cc.x, &cc.y, &cc.z); cmv.x = cv.x; cmv.y = cv.y; cmv.z = cv.z; cmu.x = cu.x; cmu.y = cu.y; cmu.z = cu.z; cmc.x = cc.x; cmc.y = cc.y; cmc.z = cc.z; if (frameno != 0) { rt_timer_stop(fpstimer); fps = 1.0f / rt_timer_time(fpstimer); } else { fps = 0.0; } rt_timer_start(fpstimer); outfilename[0] = '\0'; if (opt.nosave == 1) { if (node == 0) { printf("\rRendering Frame: %9d %10.4f FPS ", frameno, fps); fflush(stdout); } } else { sprintf(outfilename, opt.outfilename, frameno); if (node == 0) { printf("\rRendering Frame to %s (%10.4f FPS) ", outfilename, fps); fflush(stdout); } } rt_outputfile(scene, outfilename); rt_camera_position(scene, cmc, cmv, cmu); rt_renderscene(scene); if (dh != NULL) tachyon_display_draw(dh); frameno++; } rt_timer_stop(animationtimer); fps = frameno / rt_timer_time(animationtimer); if (node == 0) { printf("\rCompleted animation of %d frames \n", frameno); printf("Animation Time: %10.4f seconds (Averaged %7.4f FPS)\n", rt_timer_time(animationtimer), fps); } rt_timer_destroy(fpstimer); fclose(camfp); } else { if (node == 0) { printf("Couldn't open camera file: %s\n", opt.camfilename); printf("Aborting render.\n"); } rt_deletescene(scene); /* free the scene */ rt_finalize(); /* close down the rendering library and MPI */ return -1; } if (node == 0) { printf("\nFinished Running Camera.\n"); if (dh !=NULL) tachyon_display_delete(dh); } rt_deletescene(scene); /* free the scene */ rt_finalize(); /* close down the rendering library and MPI */ return 0; }
/* * main loop for creating animations by flying using a spaceball * or other 3-D input mechanism. */ static int fly_scene(argoptions opt, SceneHandle scene, int node) { dispHandle * dh = NULL; int done = 0; int frameno = 0; float fps; rt_timerhandle fpstimer; rt_timerhandle animationtimer; char outfilename[1]; #if defined(USESPACEBALL) sbHandle * bh = NULL; #endif if (node == 0) dh = tachyon_display_create(scene); rt_set_ui_message(NULL); rt_set_ui_progress(NULL); if (node == 0) printf("Interactive Camera Flight\n"); outfilename[0] = '\0'; rt_outputfile(scene, outfilename); fpstimer=rt_timer_create(); animationtimer=rt_timer_create(); #if defined(USESPACEBALL) if (node == 0) { #if 1 bh = tachyon_init_spaceball(scene, opt.spaceball); #else if (rt_numnodes() < 2) { bh = tachyon_init_spaceball(scene, opt.spaceball); } else { printf("WARNING: Spaceball mode disabled when running with distributed memory"); } #endif } #endif rt_timer_start(animationtimer); while (!done) { if (frameno != 0) { rt_timer_stop(fpstimer); fps = 1.0f / rt_timer_time(fpstimer); } else { fps = 0.0; } rt_timer_start(fpstimer); if (node == 0) { printf("\rRendering Frame: %9d %10.4f FPS ", frameno, fps); fflush(stdout); } #if defined(USESPACEBALL) if (bh != NULL) done = tachyon_spaceball_update(bh, scene); #endif rt_renderscene(scene); if (dh != NULL) tachyon_display_draw(dh); frameno++; } rt_timer_stop(animationtimer); fps = frameno / rt_timer_time(animationtimer); if (node == 0) { printf("\rCompleted animation of %d frames \n", frameno); printf("Animation Time: %10.4f seconds (Averaged %7.4f FPS)\n", rt_timer_time(animationtimer), fps); } rt_timer_destroy(fpstimer); if (node == 0) { printf("\nFinished Running Camera.\n"); if (dh !=NULL) tachyon_display_delete(dh); } rt_deletescene(scene); /* free the scene */ rt_finalize(); /* close down the rendering library and MPI */ return 0; }
/* * Render the scene */ void renderscene(scenedef * scene) { flt runtime; rt_timerhandle rtth; /* render time timer handle */ /* if certain key aspects of the scene parameters have been changed */ /* since the last frame rendered, or when rendering the scene the */ /* first time, various setup, initialization and memory allocation */ /* routines need to be run in order to prepare for rendering. */ if (scene->scenecheck) rendercheck(scene); if (scene->mynode == 0) rt_ui_progress(0); /* print 0% progress at start of rendering */ /* * Core Ray Tracing Code * * Ideally, as little as possible other than this code should be * executed for rendering a frame. Most if not all memory allocations * should be done outside of the core code, and all setup should be * done outside of here. This will give the best speed when rendering * walk-throughs and similar things. */ rtth=rt_timer_create(); /* create/init rendering timer */ rt_timer_start(rtth); /* start ray tracing timer */ camera_init(scene); /* Initialize all aspects of camera system */ #if defined(MPI) && defined(THR) /* reset the rows counter for this frame */ rt_atomic_int_set(((thr_parms *) scene->threadparms)[0].rowsdone, 0); #endif #ifdef THR /* if using threads, wake up the child threads... */ rt_thread_barrier(((thr_parms *) scene->threadparms)[0].runbar, 1); #endif #ifdef MPI /* if using message passing, start persistent receives */ rt_start_scanlinereceives(scene->parbuf); /* start scanline receives */ #endif /* Actually Ray Trace The Image */ thread_trace(&((thr_parms *) scene->threadparms)[0]); #ifdef MPI rt_waitscanlines(scene->parbuf); /* wait for all scanlines to recv/send */ #endif rt_timer_stop(rtth); /* stop timer for ray tracing runtime */ runtime=rt_timer_time(rtth); rt_timer_destroy(rtth); /* * End of Core Ray Tracing Code * * Anything after here should be UI, tear-down, or reset code * */ if (scene->mynode == 0) { char msgtxt[256]; rt_ui_progress(100); /* print 100% progress when finished rendering */ sprintf(msgtxt, "\n Ray Tracing Time: %10.4f seconds", runtime); rt_ui_message(MSG_0, msgtxt); if (scene->writeimagefile) renderio(scene); } } /* end of renderscene() */
/* * Check the scene to determine whether or not any parameters that affect * the thread pool, the persistent message passing primitives, or other * infrastructure needs to be reconfigured before rendering commences. */ void rendercheck(scenedef * scene) { flt runtime; rt_timerhandle stth; /* setup time timer handle */ if (scene->verbosemode && scene->mynode == 0) { char msgtxt[1024]; int i, totalcpus; flt totalspeed; rt_ui_message(MSG_0, "CPU Information:"); totalspeed = 0.0; totalcpus = 0; for (i=0; i<scene->nodes; i++) { sprintf(msgtxt, " Node %4d: %2d CPUs, CPU Speed %4.2f, Node Speed %6.2f Name: %s", i, scene->cpuinfo[i].numcpus, scene->cpuinfo[i].cpuspeed, scene->cpuinfo[i].nodespeed, scene->cpuinfo[i].machname); rt_ui_message(MSG_0, msgtxt); totalcpus += scene->cpuinfo[i].numcpus; totalspeed += scene->cpuinfo[i].nodespeed; } sprintf(msgtxt, " Total CPUs: %d", totalcpus); rt_ui_message(MSG_0, msgtxt); sprintf(msgtxt, " Total Speed: %f\n", totalspeed); rt_ui_message(MSG_0, msgtxt); } rt_barrier_sync(); /* synchronize all nodes at this point */ stth=rt_timer_create(); rt_timer_start(stth); /* Time the preprocessing of the scene database */ rt_autoshader(scene); /* Adapt to the shading features needed at runtime */ /* Hierarchical grid ray tracing acceleration scheme */ if (scene->boundmode == RT_BOUNDING_ENABLED) engrid_scene(scene, scene->boundthresh); /* if any clipping groups exist, we have to use appropriate */ /* intersection testing logic */ if (scene->cliplist != NULL) { scene->flags |= RT_SHADE_CLIPPING; } /* if there was a preexisting image, free it before continuing */ if (scene->imginternal && (scene->img != NULL)) { free(scene->img); scene->img = NULL; } /* Allocate a new image buffer if necessary */ if (scene->img == NULL) { scene->imginternal = 1; if (scene->verbosemode && scene->mynode == 0) { rt_ui_message(MSG_0, "Allocating Image Buffer."); } /* allocate the image buffer accordinate to pixel format */ if (scene->imgbufformat == RT_IMAGE_BUFFER_RGB24) { scene->img = malloc(scene->hres * scene->vres * 3); } else if (scene->imgbufformat == RT_IMAGE_BUFFER_RGB96F) { scene->img = malloc(sizeof(float) * scene->hres * scene->vres * 3); } else { rt_ui_message(MSG_0, "Illegal image buffer format specifier!"); } if (scene->img == NULL) { scene->imginternal = 0; rt_ui_message(MSG_0, "Warning: Failed To Allocate Image Buffer!"); } } /* if any threads are leftover from a previous scene, and the */ /* scene has changed significantly, we have to collect, and */ /* respawn the worker threads, since lots of things may have */ /* changed which would affect them. */ destroy_render_threads(scene); create_render_threads(scene); /* allocate and initialize persistent scanline receive buffers */ /* which are used by the parallel message passing code. */ scene->parbuf = rt_init_scanlinereceives(scene); /* the scene has been successfully prepared for rendering */ /* unless it gets modified in certain ways, we don't need to */ /* pre-process it ever again. */ scene->scenecheck = 0; rt_timer_stop(stth); /* Preprocessing is finished, stop timing */ runtime=rt_timer_time(stth); rt_timer_destroy(stth); /* Print out relevent timing info */ if (scene->mynode == 0) { char msgtxt[256]; sprintf(msgtxt, "Preprocessing Time: %10.4f seconds",runtime); rt_ui_message(MSG_0, msgtxt); } }
int read_grid(const char* oldgridfile, float* grideners, float gridspacing, long int numplane, long int numcol, long int numpt, float cx, float cy, float cz) { /* Read an energy grid from a .dx file */ int i, j, k; /* int arrpos; */ char dataline[101]; float tmpx, tmpy, tmpz; int count; float tmpspacing; FILE* dx_in; float starttime, endtime; rt_timerhandle timer; dx_in = fopen(oldgridfile, "r"); if (dx_in == NULL) { fprintf(stderr, "Error: Couldn't open input dxfile %s. Exiting...", oldgridfile); return 1; } timer = rt_timer_create(); rt_timer_start(timer); /* start the timer */ starttime = rt_timer_timenow(timer); /* Read the header and check that the values are compatible */ while (fgets(dataline,100,dx_in) && strncmp(dataline,"#",1) == 0); printf( "%s", dataline); sscanf(dataline, "%*s %*i %*s %*s %*s %i %i %i", &i, &j, &k); fgets(dataline, 100, dx_in); printf( "%s", dataline); sscanf(dataline, "%*s %e %e %e", &tmpx, &tmpy, &tmpz); fgets(dataline, 100, dx_in); printf( "%s", dataline); sscanf(dataline, "%*s %e %*e %*e\n", &tmpspacing); if (k != numplane || j != numcol || i != numpt || abs(tmpx - cx) > 0.01 || abs(tmpy - cy) > 0.01 || abs(tmpz - cz) > 0.01 || abs(gridspacing - tmpspacing) > 0.01) { fprintf(stderr, "Comparisons: %i/%li | %i/%li | %i/%li | %f/%f | %f/%f | %f/%f | %f/%f\n", i, numplane, j, numcol, k, numpt, tmpx, cx, tmpy, cy, tmpz, cz, gridspacing, tmpspacing); fprintf(stderr, "Error: Grid dimensions do not match those of the molecule in memory.\n"); return 1; } /* Having passed those tests, skip four lines and start reading data*/ fgets(dataline, 100, dx_in); fgets(dataline, 100, dx_in); fgets(dataline, 100, dx_in); fgets(dataline, 100, dx_in); for (count = 0; count < ((numplane * numcol * numpt)/3); count++) { fgets(dataline, 100, dx_in); sscanf(dataline, "%e %e %e", &grideners[transaddr(3*count, numplane, numcol, numpt)], &grideners[transaddr(3*count + 1, numplane, numcol, numpt)], &grideners[transaddr(3*count + 2, numplane, numcol, numpt)]); } if ((numplane * numcol * numpt) %3 != 0) { fgets(dataline, 100, dx_in); if ((numplane * numcol * numpt) %3 == 1) { sscanf(dataline, "%e", &grideners[transaddr(3*count, numplane, numcol, numpt)]); } else { sscanf(dataline, "%e %e", &grideners[transaddr(3*count, numplane, numcol, numpt)], &grideners[transaddr(3*count + 1, numplane, numcol, numpt)]); } } fclose(dx_in); /* Convert units to the proper internal units for cionize */ for (i=0; i<numpt; i++) { for (j=0; j<numcol; j++) { for (k=0; k<numplane; k++) { float tmpnum; int arrpos; arrpos = (k*numcol * numpt + j*numpt + i); tmpnum = grideners[arrpos]; tmpnum = tmpnum / POT_CONV; grideners[arrpos] = tmpnum; } } } /* check our time */ endtime = rt_timer_timenow(timer); printf("Time for grid input: %.1f\n", endtime - starttime); rt_timer_destroy(timer); return 0; }