rdf_malloc.cu 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. #include <stdio.h>
  2. #include <iostream>
  3. #include <fstream>
  4. #include <cuda_runtime.h>
  5. #include <cmath>
  6. #include <string>
  7. #include <cstdio>
  8. #include <iomanip>
  9. #include "dcdread.h"
  10. #include<assert.h>
  11. #include <nvtx3/nvToolsExt.h>
  12. using namespace std;
  13. //additional error handling code
  14. static void HandleError(cudaError_t err,
  15. const char *file, int line) {
  16. if (err != cudaSuccess) {
  17. printf( "%s in %s at line %d\n", cudaGetErrorString( err ),
  18. file, line );
  19. exit( EXIT_FAILURE );
  20. }
  21. }
  22. #define HANDLE_ERROR( err ) (HandleError( err, __FILE__, __LINE__ ))
  23. //declaration of GPU function
  24. __global__ void pair_gpu(const double* d_x, const double* d_y, const double* d_z,
  25. unsigned long long int *d_g2, int numatm, int nconf,
  26. double xbox, double ybox, double zbox, int d_bin);
  27. int main(int argc , char* argv[])
  28. {
  29. double xbox,ybox,zbox;
  30. double* h_x,*h_y,*h_z;
  31. double* d_x,*d_y,*d_z;
  32. unsigned long long int *h_g2,*d_g2;
  33. int nbin;
  34. int device;
  35. int numatm,nconf,inconf;
  36. string file;
  37. ///////////////////////////////////////////////////////////////
  38. inconf = 10;
  39. nbin = 2000;
  40. file = "../input/alk.traj.dcd";
  41. device = 0;
  42. HANDLE_ERROR (cudaSetDevice(device));//pick the device to use
  43. ///////////////////////////////////////
  44. std::ifstream infile;
  45. infile.open(file.c_str());
  46. if(!infile){
  47. cout<<"file "<<file.c_str()<<" not found\n";
  48. return 1;
  49. }
  50. assert(infile);
  51. ofstream pairfile,stwo;
  52. pairfile.open("RDF.dat");
  53. stwo.open("Pair_entropy.dat");
  54. /////////////////////////////////////////////////////////
  55. dcdreadhead(&numatm,&nconf,infile);
  56. cout<<"Dcd file has "<< numatm << " atoms and " << nconf << " frames"<<endl;
  57. if (inconf>nconf) cout << "nconf is reset to "<< nconf <<endl;
  58. else {nconf = inconf;}
  59. cout<<"Calculating RDF for " << nconf << " frames"<<endl;
  60. ////////////////////////////////////////////////////////
  61. unsigned long long int sizef= nconf*numatm*sizeof(double);
  62. unsigned long long int sizebin= nbin*sizeof(unsigned long long int);
  63. //Allocate memory on CPU
  64. HANDLE_ERROR(cudaHostAlloc((void **)&h_x, sizef, cudaHostAllocDefault));
  65. HANDLE_ERROR(cudaHostAlloc((void **)&h_y, sizef, cudaHostAllocDefault));
  66. HANDLE_ERROR(cudaHostAlloc((void **)&h_z, sizef, cudaHostAllocDefault));
  67. HANDLE_ERROR(cudaHostAlloc((void **)&h_g2, sizebin, cudaHostAllocDefault));
  68. //Allocate memory on GPU
  69. HANDLE_ERROR(cudaMalloc((void**)&d_x, sizef));
  70. HANDLE_ERROR(cudaMalloc((void**)&d_y, sizef));
  71. HANDLE_ERROR(cudaMalloc((void**)&d_z, sizef));
  72. HANDLE_ERROR(cudaMalloc((void**)&d_g2, sizebin));
  73. HANDLE_ERROR (cudaPeekAtLastError());
  74. memset(h_g2,0,sizebin);
  75. /////////reading cordinates//////////////////////////////////////////////
  76. nvtxRangePush("Read_File");
  77. double ax[numatm],ay[numatm],az[numatm];
  78. for (int i=0;i<nconf;i++) {
  79. dcdreadframe(ax,ay,az,infile,numatm,xbox,ybox,zbox);
  80. for (int j=0;j<numatm;j++){
  81. h_x[i*numatm+j]=ax[j];
  82. h_y[i*numatm+j]=ay[j];
  83. h_z[i*numatm+j]=az[j];
  84. }
  85. }
  86. nvtxRangePop(); //pop for Reading file
  87. nvtxRangePush("Pair_Calculation");
  88. //Copy the data from Host to Device before calculation on GPU
  89. HANDLE_ERROR(cudaMemcpy(d_g2, h_g2, sizebin,cudaMemcpyHostToDevice));
  90. HANDLE_ERROR(cudaMemcpy(d_x, h_x, sizef, cudaMemcpyHostToDevice));
  91. HANDLE_ERROR(cudaMemcpy(d_y, h_y, sizef, cudaMemcpyHostToDevice));
  92. HANDLE_ERROR(cudaMemcpy(d_z, h_z, sizef, cudaMemcpyHostToDevice));
  93. cout<<"Reading of input file and transfer to gpu is completed"<<endl;
  94. //////////////////////////////////////////////////////////////////////////
  95. dim3 nthreads(128, 1, 1);
  96. dim3 nblock;
  97. nblock.x = (numatm + nthreads.x - 1)/nthreads.x;
  98. nblock.y = (numatm + nthreads.y - 1)/nthreads.y;
  99. nblock.z = 1;
  100. pair_gpu<<<nblock, nthreads>>>
  101. (d_x, d_y, d_z, d_g2, numatm, nconf, xbox, ybox, zbox, nbin);
  102. HANDLE_ERROR (cudaPeekAtLastError());
  103. HANDLE_ERROR(cudaDeviceSynchronize());
  104. HANDLE_ERROR(cudaMemcpy(h_g2, d_g2, sizebin, cudaMemcpyDeviceToHost));
  105. nvtxRangePop(); //Pop for Pair Calculation
  106. double pi=acos(-1.0l);
  107. double rho=(numatm)/(xbox*ybox*zbox);
  108. double norm=(4.0l*pi*rho)/3.0l;
  109. double rl,ru,nideal;
  110. double g2[nbin];
  111. double r,gr,lngr,lngrbond,s2=0.0l,s2bond=0.0l;
  112. double box=min(xbox,ybox);
  113. box=min(box,zbox);
  114. double del=box/(2.0l*nbin);
  115. nvtxRangePush("Entropy_Calculation");
  116. for (int i=0;i<nbin;i++) {
  117. rl=(i)*del;
  118. ru=rl+del;
  119. nideal=norm*(ru*ru*ru-rl*rl*rl);
  120. g2[i]=(double)h_g2[i]/((double)nconf*(double)numatm*nideal);
  121. r=(i)*del;
  122. pairfile<<(i+0.5l)*del<<" "<<g2[i]<<endl;
  123. if (r<2.0l) {
  124. gr=0.0l;
  125. }
  126. else {
  127. gr=g2[i];
  128. }
  129. if (gr<1e-5) {
  130. lngr=0.0l;
  131. }
  132. else {
  133. lngr=log(gr);
  134. }
  135. if (g2[i]<1e-6) {
  136. lngrbond=0.0l;
  137. }
  138. else {
  139. lngrbond=log(g2[i]);
  140. }
  141. s2=s2-2.0l*pi*rho*((gr*lngr)-gr+1.0l)*del*r*r;
  142. s2bond=s2bond-2.0l*pi*rho*((g2[i]*lngrbond)-g2[i]+1.0l)*del*r*r;
  143. }
  144. nvtxRangePop(); //Pop for Entropy Calculation
  145. stwo<<"s2 value is "<<s2<<endl;
  146. stwo<<"s2bond value is "<<s2bond<<endl;
  147. cout<<"\n\n\n#Freeing Device memory"<<endl;
  148. HANDLE_ERROR(cudaFree(d_x));
  149. HANDLE_ERROR(cudaFree(d_y));
  150. HANDLE_ERROR(cudaFree(d_z));
  151. HANDLE_ERROR(cudaFree(d_g2));
  152. cout<<"#Freeing Host memory"<<endl;
  153. HANDLE_ERROR(cudaFreeHost(h_x));
  154. HANDLE_ERROR(cudaFreeHost(h_y));
  155. HANDLE_ERROR(cudaFreeHost(h_z));
  156. HANDLE_ERROR(cudaFreeHost(h_g2));
  157. cout<<"#Number of atoms processed: "<<numatm<<endl<<endl;
  158. cout<<"#Number of confs processed: "<<nconf<<endl<<endl;
  159. return 0;
  160. }
  161. __global__ void pair_gpu(const double* d_x, const double* d_y, const double* d_z,
  162. unsigned long long int *d_g2, int numatm, int nconf,
  163. double xbox, double ybox, double zbox, int d_bin)
  164. {
  165. double r, cut, dx, dy, dz;
  166. int ig2;
  167. double box;
  168. box = min(xbox, ybox);
  169. box = min(box, zbox);
  170. double del = box / (2.0 * d_bin);
  171. cut = box * 0.5;
  172. int id1 = blockIdx.y * blockDim.y + threadIdx.y;
  173. int id2 = blockIdx.x * blockDim.x + threadIdx.x;
  174. if (id1 >= numatm || id2 >= numatm) return;
  175. if (id1 > id2) return;
  176. for (int frame = 0; frame < nconf; ++frame) {
  177. dx = d_x[frame * numatm + id1] - d_x[frame * numatm + id2];
  178. dy = d_y[frame * numatm + id1] - d_y[frame * numatm + id2];
  179. dz = d_z[frame * numatm + id1] - d_z[frame * numatm + id2];
  180. dx = dx - xbox * (round(dx / xbox));
  181. dy = dy - ybox * (round(dy / ybox));
  182. dz = dz - zbox * (round(dz / zbox));
  183. r = sqrtf(dx * dx + dy * dy + dz * dz);
  184. if (r < cut) {
  185. ig2 = (int)(r / del);
  186. atomicAdd(&d_g2[ig2], 2);
  187. }
  188. }
  189. }