rdf_unified_memory.cu 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204
  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* d_x,*d_y,*d_z;
  31. unsigned long long int *d_g2;
  32. int nbin;
  33. int device;
  34. int numatm,nconf,inconf;
  35. string file;
  36. ///////////////////////////////////////////////////////////////
  37. inconf = 10;
  38. nbin = 2000;
  39. file = "../input/alk.traj.dcd";
  40. device = 0;
  41. HANDLE_ERROR (cudaSetDevice(device));//pick the device to use
  42. ///////////////////////////////////////
  43. std::ifstream infile;
  44. infile.open(file.c_str());
  45. if(!infile){
  46. cout<<"file "<<file.c_str()<<" not found\n";
  47. return 1;
  48. }
  49. assert(infile);
  50. ofstream pairfile,stwo;
  51. pairfile.open("RDF.dat");
  52. stwo.open("Pair_entropy.dat");
  53. /////////////////////////////////////////////////////////
  54. dcdreadhead(&numatm,&nconf,infile);
  55. cout<<"Dcd file has "<< numatm << " atoms and " << nconf << " frames"<<endl;
  56. if (inconf>nconf) cout << "nconf is reset to "<< nconf <<endl;
  57. else {nconf = inconf;}
  58. cout<<"Calculating RDF for " << nconf << " frames"<<endl;
  59. ////////////////////////////////////////////////////////
  60. unsigned long long int sizef= nconf*numatm*sizeof(double);
  61. unsigned long long int sizebin= nbin*sizeof(unsigned long long int);
  62. // Allocate Unified Memory -- accessible from CPU or GPU
  63. cudaMallocManaged(&d_x, sizef);
  64. cudaMallocManaged(&d_y, sizef);
  65. cudaMallocManaged(&d_z, sizef);
  66. cudaMallocManaged(&d_g2, sizebin);
  67. HANDLE_ERROR (cudaPeekAtLastError());
  68. memset(d_g2,0,sizebin);
  69. /////////reading cordinates//////////////////////////////////////////////
  70. nvtxRangePush("Read_File");
  71. double ax[numatm],ay[numatm],az[numatm];
  72. for (int i=0;i<nconf;i++) {
  73. dcdreadframe(ax,ay,az,infile,numatm,xbox,ybox,zbox);
  74. for (int j=0;j<numatm;j++){
  75. d_x[i*numatm+j]=ax[j];
  76. d_y[i*numatm+j]=ay[j];
  77. d_z[i*numatm+j]=az[j];
  78. }
  79. }
  80. nvtxRangePop(); //pop for Reading file
  81. nvtxRangePush("Pair_Calculation");
  82. cout<<"Reading of input file and transfer to gpu is completed"<<endl;
  83. //////////////////////////////////////////////////////////////////////////
  84. dim3 nthreads(128, 1, 1);
  85. dim3 nblock;
  86. nblock.x = (numatm + nthreads.x - 1)/nthreads.x;
  87. nblock.y = (numatm + nthreads.y - 1)/nthreads.y;
  88. nblock.z = 1;
  89. pair_gpu<<<nblock, nthreads>>>
  90. (d_x, d_y, d_z, d_g2, numatm, nconf, xbox, ybox, zbox, nbin);
  91. HANDLE_ERROR (cudaPeekAtLastError());
  92. HANDLE_ERROR(cudaDeviceSynchronize());
  93. nvtxRangePop(); //Pop for Pair Calculation
  94. double pi=acos(-1.0l);
  95. double rho=(numatm)/(xbox*ybox*zbox);
  96. double norm=(4.0l*pi*rho)/3.0l;
  97. double rl,ru,nideal;
  98. double g2[nbin];
  99. double r,gr,lngr,lngrbond,s2=0.0l,s2bond=0.0l;
  100. double box=min(xbox,ybox);
  101. box=min(box,zbox);
  102. double del=box/(2.0l*nbin);
  103. nvtxRangePush("Entropy_Calculation");
  104. for (int i=0;i<nbin;i++) {
  105. rl=(i)*del;
  106. ru=rl+del;
  107. nideal=norm*(ru*ru*ru-rl*rl*rl);
  108. g2[i]=(double)d_g2[i]/((double)nconf*(double)numatm*nideal);
  109. r=(i)*del;
  110. pairfile<<(i+0.5l)*del<<" "<<g2[i]<<endl;
  111. if (r<2.0l) {
  112. gr=0.0l;
  113. }
  114. else {
  115. gr=g2[i];
  116. }
  117. if (gr<1e-5) {
  118. lngr=0.0l;
  119. }
  120. else {
  121. lngr=log(gr);
  122. }
  123. if (g2[i]<1e-6) {
  124. lngrbond=0.0l;
  125. }
  126. else {
  127. lngrbond=log(g2[i]);
  128. }
  129. s2=s2-2.0l*pi*rho*((gr*lngr)-gr+1.0l)*del*r*r;
  130. s2bond=s2bond-2.0l*pi*rho*((g2[i]*lngrbond)-g2[i]+1.0l)*del*r*r;
  131. }
  132. nvtxRangePop(); //Pop for Entropy Calculation
  133. stwo<<"s2 value is "<<s2<<endl;
  134. stwo<<"s2bond value is "<<s2bond<<endl;
  135. cout<<"#Freeing memory"<<endl;
  136. // Free memory
  137. HANDLE_ERROR(cudaFree(d_x));
  138. HANDLE_ERROR(cudaFree(d_y));
  139. HANDLE_ERROR(cudaFree(d_z));
  140. HANDLE_ERROR(cudaFree(d_g2));
  141. cout<<"#Number of atoms processed: "<<numatm<<endl<<endl;
  142. cout<<"#Number of confs processed: "<<nconf<<endl<<endl;
  143. return 0;
  144. }
  145. __global__ void pair_gpu(const double* d_x, const double* d_y, const double* d_z,
  146. unsigned long long int *d_g2, int numatm, int nconf,
  147. double xbox, double ybox, double zbox, int d_bin)
  148. {
  149. double r, cut, dx, dy, dz;
  150. int ig2;
  151. double box;
  152. box = min(xbox, ybox);
  153. box = min(box, zbox);
  154. double del = box / (2.0 * d_bin);
  155. cut = box * 0.5;
  156. int id1 = blockIdx.y * blockDim.y + threadIdx.y;
  157. int id2 = blockIdx.x * blockDim.x + threadIdx.x;
  158. if (id1 >= numatm || id2 >= numatm) return;
  159. if (id1 > id2) return;
  160. for (int frame = 0; frame < nconf; ++frame) {
  161. dx = d_x[frame * numatm + id1] - d_x[frame * numatm + id2];
  162. dy = d_y[frame * numatm + id1] - d_y[frame * numatm + id2];
  163. dz = d_z[frame * numatm + id1] - d_z[frame * numatm + id2];
  164. dx = dx - xbox * (round(dx / xbox));
  165. dy = dy - ybox * (round(dy / ybox));
  166. dz = dz - zbox * (round(dz / zbox));
  167. r = sqrtf(dx * dx + dy * dy + dz * dz);
  168. if (r < cut) {
  169. ig2 = (int)(r / del);
  170. atomicAdd(&d_g2[ig2], 2);
  171. }
  172. }
  173. }