void cpuoptical_(int *gpusize) { // command line arguments float xdetector, ydetector, radius, height, n_C, n_IC, top_absfrac, bulk_abscoeff, beta, d_min, lbound_x, lbound_y, ubound_x, ubound_y, d_max, yield, sensorRefl; int pixelsize, num_primary, min_optphotons, max_optphotons, num_bins; float dcos[3]={0}; // directional cosines float normal[3]={0}; // normal to surface in case of TIR float pos[3] = {0}; // intersecting point coordinates float old_pos[3] = {0}; // source coordinates int nbytes = (optical_.myctropt - (*gpusize))*sizeof(struct start_info); struct start_info *structa; structa = (struct start_info*) malloc(nbytes); if( structa == NULL ) printf("\n Struct start_info array CANNOT BE ALLOCATED - %d !!", (optical_.myctropt-(*gpusize))); // get cpu time clock_t start, end; float num_sec; // get current time stamp to initialize seed input for RNG time_t seconds; seconds = time (NULL); struct timeval tv; gettimeofday(&tv,NULL); float rr=0.0f, theta=0.0f; float r=0.0f; // random number float norm=0.0f; int jj=0; int my_index=0; int penindex = 0; // equal to *gpusize int result_algo = 0; unsigned long long int *num_rebound; // initialize random number generator (RANECU) int seed_input = 271828182 ; // ranecu seed input int seed[2]; // GNU scientific library (gsl) variables const gsl_rng_type * Tgsl; gsl_rng * rgsl; double mu_gsl; // output image variables int xdim = 0; int ydim = 0; int indexi=0, indexj=0; // copy to local variables from PENELOPE buffers xdetector = inputargs_.detx; // x dimension of detector (in um). x in (0,xdetector) ydetector = inputargs_.dety; // y dimension of detector (in um). y in (0,ydetector) height = inputargs_.detheight; // height of column and thickness of detector (in um). z in range (-H/2, H/2) radius = inputargs_.detradius; // radius of column (in um). n_C = inputargs_.detnC; // refractive index of columns n_IC = inputargs_.detnIC; // refractive index of intercolumnar material top_absfrac = inputargs_.dettop; // column's top surface absorption fraction (0.0, 0.5, 0.98) bulk_abscoeff = inputargs_.detbulk; // column's bulk absorption coefficient (in um^-1) (0.001, 0.1 cm^-1) beta = inputargs_.detbeta; // roughness coefficient of column walls d_min = inputargs_.detdmin; // minimum distance a photon can travel when transmitted from a column d_max = inputargs_.detdmax; lbound_x = inputargs_.detlboundx; // x lower bound of region of interest of output image (in um) lbound_y = inputargs_.detlboundy; // y lower bound (in um) ubound_x = inputargs_.detuboundx; // x upper bound (in um) ubound_y = inputargs_.detuboundy; // y upper bound (in um) yield = inputargs_.detyield; // yield (/eV) pixelsize = inputargs_.detpixel; // 1 pixel = pixelsize microns (in um) sensorRefl = inputargs_.detsensorRefl; // Non-Ideal sensor reflectivity (%) num_primary = inputargs_.mynumhist; // total number of primaries to be simulated min_optphotons = inputargs_.minphotons; // minimum number of optical photons detected to be included in PHS max_optphotons = inputargs_.maxphotons; // maximum number of optical photons detected to be included in PHS num_bins = inputargs_.mynumbins; // number of bins for genrating PHS // create a generator chosen by the environment variable GSL_RNG_TYPE gsl_rng_env_setup(); Tgsl = gsl_rng_default; rgsl = gsl_rng_alloc (Tgsl); // dimensions of PRF image xdim = ceil((ubound_x - lbound_x)/pixelsize); ydim = ceil((ubound_y - lbound_y)/pixelsize); unsigned long long int myimage[xdim][ydim]; //initialize the output image 2D array for(indexi = 0; indexi < xdim; indexi++) { for(indexj = 0; indexj < ydim; indexj++) { myimage[indexi][indexj] = 0; } } // memory for storing histogram of # photons detected/primary int *h_num_detected_prim = 0; h_num_detected_prim = (int*)malloc(sizeof(int)*num_primary); for(indexj=0; indexj < num_primary; indexj++) h_num_detected_prim[indexj] = 0; // memory for storing histogram of # photons detected/primary int *h_histogram = 0; h_histogram = (int*)malloc(sizeof(int)*num_bins); for(indexj=0; indexj < num_bins; indexj++) h_histogram[indexj] = 0; penindex = *gpusize; for(my_index = 0; my_index < (optical_.myctropt-(*gpusize)); my_index++) // iterate over x-rays { // reset the global counters num_generated = 0; num_detect=0; num_abs_top=0; num_abs_bulk=0; num_lost=0; num_outofcol=0; num_theta1=0; photon_distance=0.0f; //re-initialize the output image 2D array for(indexi = 0; indexi < xdim; indexi++) for(indexj = 0; indexj < ydim; indexj++) myimage[indexi][indexj] = 0; // copying PENELOPE buffer into *structa // units in the penelope output file are in cm. Convert them to microns. structa[my_index].str_x = optical_.xbufopt[penindex+my_index] * 10000.0f; // x-coordinate of interaction event structa[my_index].str_y = optical_.ybufopt[penindex+my_index] * 10000.0f; // y-coordinate structa[my_index].str_z = optical_.zbufopt[penindex+my_index] * 10000.0f; // z-coordinate structa[my_index].str_E = optical_.debufopt[penindex+my_index]; // energy deposited structa[my_index].str_histnum = optical_.nbufopt[penindex+my_index]; // x-ray history // sample # optical photons based on light yield and energy deposited for this interaction event (using Poisson distribution) mu_gsl = (double)structa[my_index].str_E * yield; structa[my_index].str_N = gsl_ran_poisson(rgsl,mu_gsl); if(structa[my_index].str_N > max_photon_per_EDE) { printf("\n\n str_n exceeds max photons. program is exiting - %d !! \n\n",structa[my_index].str_N); exit(0); } num_rebound = (unsigned long long int*) malloc(structa[my_index].str_N*sizeof(unsigned long long int)); if(num_rebound == NULL) printf("\n Error allocating num_rebound memory !\n"); // start the clock start = clock(); // initialize the RANECU generator in a position far away from the previous history: seed_input = (int)(seconds/3600+tv.tv_usec); // seed input=seconds passed since 1970+current time in micro secs init_PRNG(my_index, 50000, seed_input, seed); // intialize RNG for(jj=0; jj<structa[my_index].str_N; jj++) num_rebound[jj] = 0; // reset the directional cosine and normal vectors dcos[0]=0.0f; dcos[1]=0.0f; dcos[2]=0.0f; normal[0]=0.0f; normal[1]=0.0f; normal[2]=0.0f; // re-initialize myimage for(indexi = 0; indexi < xdim; indexi++) for(indexj = 0; indexj < ydim; indexj++) myimage[indexi][indexj] = 0; // set starting location of photon pos[0] = structa[my_index].str_x; pos[1] = structa[my_index].str_y; pos[2] = structa[my_index].str_z; old_pos[0] = structa[my_index].str_x; old_pos[1] = structa[my_index].str_y; old_pos[2] = structa[my_index].str_z; // initializing the direction cosines for the first particle in each core r = (ranecu(seed) * 2.0f) - 1.0f; // random number between (-1,1) while(fabs(r) <= 0.01f) { r = (ranecu(seed) * 2.0f) - 1.0f; } dcos[2] = r; // random number between (-1,1) rr = sqrt(1.0f-r*r); theta=ranecu(seed)*twopipen; dcos[0]=rr*cos(theta); dcos[1]=rr*sin(theta); norm = sqrt(dcos[0]*dcos[0] + dcos[1]*dcos[1] + dcos[2]*dcos[2]); if ((norm < (1.0f - epsilon)) || (norm > (1.0f + epsilon))) // normalize { dcos[0] = dcos[0]/norm; dcos[1] = dcos[1]/norm; dcos[2] = dcos[2]/norm; } local_counter=0; // total number of photons terminated (either detected at sensor, absorbed at the top or in the bulk) [global variable] while(local_counter < structa[my_index].str_N) // until all the optical photons are not transported { absorbed = 0; detect = 0; bulk_abs = 0; // set starting location of photon pos[0] = structa[my_index].str_x; pos[1] = structa[my_index].str_y; pos[2] = structa[my_index].str_z; old_pos[0] = structa[my_index].str_x; old_pos[1] = structa[my_index].str_y; old_pos[2] = structa[my_index].str_z; num_generated++; result_algo = 0; while(result_algo == 0) { result_algo = algo(normal, old_pos, pos, dcos, num_rebound, seed, structa[my_index], &myimage[0][0], xdetector, ydetector, radius, height, n_C, n_IC, top_absfrac, bulk_abscoeff, beta, d_min, pixelsize, lbound_x, lbound_y, ubound_x, ubound_y, sensorRefl, d_max, ydim, h_num_detected_prim); } } // end the clock end = clock(); num_sec = (((float)end - start)/CLOCKS_PER_SEC); // type cast unsigned long long int to double double cast_num_generated; double cast_num_detect; double cast_num_abs_top; double cast_num_abs_bulk; double cast_num_lost; double cast_num_outofcol; double cast_num_theta1; double cast_gputime; cast_num_generated = (double)num_generated; cast_num_detect = (double)num_detect; cast_num_abs_top = (double)num_abs_top; cast_num_abs_bulk = (double)num_abs_bulk; cast_num_lost = (double)num_lost; cast_num_outofcol = (double)num_outofcol; cast_num_theta1 = (double)num_theta1; cast_gputime = (double)(num_sec*1000.0); // convert in millisecond // save to global counters optstats_.glgen = optstats_.glgen + cast_num_generated; optstats_.gldetect = optstats_.gldetect + cast_num_detect; optstats_.glabstop = optstats_.glabstop + cast_num_abs_top; optstats_.glabsbulk = optstats_.glabsbulk + cast_num_abs_bulk; optstats_.gllost = optstats_.gllost + cast_num_lost; optstats_.gloutofcol = optstats_.gloutofcol + cast_num_outofcol; optstats_.gltheta1 = optstats_.gltheta1 + cast_num_theta1; optstats_.glgputime = optstats_.glgputime + cast_gputime; // release resources free(num_rebound); } // my_index loop ends // make histogram of number of detected photons/primary for num_bins int binsize=0, newbin=0; int bincorr=0; binsize = floor((max_optphotons-min_optphotons)/num_bins); // calculate size of each bin. Assuming equally spaced bins. bincorr = floor(min_optphotons/binsize); // correction in bin number if min_optphotons > 0. for(indexi = 0; indexi < num_primary; indexi++) { newbin = floor(h_num_detected_prim[indexi]/binsize) - bincorr; // find bin # if(h_num_detected_prim[indexi] > 0) // store only non-zero bins { if(h_num_detected_prim[indexi] <= min_optphotons) // # detected < minimum photons given by user, add to the first bin h_histogram[0]++; else if(h_num_detected_prim[indexi] >= max_optphotons) // # detected > maximum photons given by user, then add to the last bin h_histogram[num_bins-1]++; else h_histogram[newbin]++; } } // add num_detected_primary to gldetprimary array in PENELOPE for(indexi = 0; indexi < num_bins; indexi++) outputdetprim_.gldetprimary[indexi] = outputdetprim_.gldetprimary[indexi] + h_histogram[indexi]; // release resources free(structa); free(h_num_detected_prim); free(h_histogram); return; } // C main() ends
/** * Construct a proof. */ void constructProof(Credential *credential, unsigned char *masterSecret) { unsigned char i, j; unsigned int rA_size; unsigned int rA_offset; unsigned long dwPrevHashedBytes; unsigned short wLenMsgRem; unsigned short pRemainder; rA_size = realSize(credential->signature.v, SIZE_V) - 1 - realSize(credential->signature.e, SIZE_E); if (rA_size > SIZE_R_A) { rA_size = SIZE_R_A; } rA_offset = SIZE_R_A - rA_size; init_PRNG(); // HASH - init memset(session.prove.bufferHash, 0, 64); pRemainder = 0; dwPrevHashedBytes = 0; wLenMsgRem = 0; //multosSecureHashIV(SIZE_STATZK, SHA_256, session.prove.challenge, public.prove.apdu.nonce, session.prove.bufferHash, &dwPrevHashedBytes, &wLenMsgRem, &pRemainder); /* C = Z^m * S^r \mod n */ ModExp(SIZE_M, SIZE_N, credential->attribute[0], credential->issuerKey.n, credential->issuerKey.Z, public.prove.buffer.number[0]); ModExp(SIZE_M, SIZE_N, r, credential->issuerKey.n, credential->issuerKey.S, public.prove.buffer.number[1]); ModMul(SIZE_N, public.prove.buffer.number[0], public.prove.buffer.number[1], credential->issuerKey.n); Copy(SIZE_N, session.prove.C, public.prove.buffer.number[0]); multosSecureHashIV(SIZE_N, SHA_256, session.prove.challenge, session.prove.C, session.prove.bufferHash, &dwPrevHashedBytes, &wLenMsgRem, &pRemainder); /* C_tilde = (Z^(m_r))^ \tilde{m_h} * S ^ \tilde{r}/ */ ComputeHat(); ModExp(SIZE_M_, SIZE_N, session.prove.mHatTemp, credential->issuerKey.n, rev_attr_1, public.prove.buffer.number[0]); ComputeHat(); ModExp(SIZE_M_, SIZE_N, session.prove.mHatTemp, credential->issuerKey.n, credential->issuerKey.S, public.prove.buffer.number[1]); ModMul(SIZE_N, public.prove.buffer.number[0], public.prove.buffer.number[1], credential->issuerKey.n); Copy(SIZE_N, session.prove.Ctilde, public.prove.buffer.number[0]); multosSecureHashIV(SIZE_N, SHA_256, session.prove.challenge, session.prove.Ctilde, session.prove.bufferHash, &dwPrevHashedBytes, &wLenMsgRem, &pRemainder); /* \tilde{Co} = Z^{\tilde{m}} * S^{\tilde{r}} \mod n */ ModExp(SIZE_M_, SIZE_N, session.prove.mHatTemp, credential->issuerKey.n, credential->issuerKey.S, public.prove.buffer.number[1]); ComputeHat(); ModExp(SIZE_M_, SIZE_N, session.prove.mHatTemp, credential->issuerKey.n, credential->issuerKey.Z, public.prove.buffer.number[0]); ModMul(SIZE_N, public.prove.buffer.number[0], public.prove.buffer.number[1], credential->issuerKey.n); multosSecureHashIV(SIZE_N, SHA_256, session.prove.challenge, public.prove.buffer.number[0], session.prove.bufferHash, &dwPrevHashedBytes, &wLenMsgRem, &pRemainder); //reset_PRNG(); // XXXX: Move after \tilde{Z} ? // IMPORTANT: Correction to the length of eTilde to prevent overflows RandomBits(public.prove.eHat, LENGTH_E_ - 1); debugValue("eTilde", public.prove.eHat, SIZE_E_); // IMPORTANT: Correction to the length of vTilde to prevent overflows RandomBits(public.prove.vHat, LENGTH_V_ - 1); debugValue("vTilde", public.prove.vHat, SIZE_V_); // IMPORTANT: Correction to the length of rA to prevent negative values RandomBits(public.prove.rA + rA_offset, rA_size * 8 - 1); for (i = 0; i < rA_offset; i++) { public.prove.rA[i] = 0x00; // Set first byte(s) of rA, since it's not set by RandomBits command }