main.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404
  1. #ifdef __cplusplus
  2. extern "C" {
  3. #endif
  4. //========================================================================================================================================================================================================200
  5. //======================================================================================================================================================150
  6. //====================================================================================================100
  7. //==================================================50
  8. //========================================================================================================================================================================================================200
  9. // INFORMATION
  10. //========================================================================================================================================================================================================200
  11. //======================================================================================================================================================150
  12. // UPDATE
  13. //======================================================================================================================================================150
  14. // 2009.12 Lukasz G. Szafaryn
  15. // -- entire code written
  16. //======================================================================================================================================================150
  17. // DESCRIPTION
  18. //======================================================================================================================================================150
  19. // Description
  20. //======================================================================================================================================================150
  21. // USE
  22. //======================================================================================================================================================150
  23. // How to run
  24. //========================================================================================================================================================================================================200
  25. // DEFINE/INCLUDE
  26. //========================================================================================================================================================================================================200
  27. //======================================================================================================================================================150
  28. // LIBRARIES
  29. //======================================================================================================================================================150
  30. #include <stdio.h> // (in path known to compiler) needed by printf
  31. #include <stdlib.h> // (in path known to compiler) needed by malloc
  32. #include <stdbool.h> // (in path known to compiler) needed by true/false
  33. //======================================================================================================================================================150
  34. // UTILITIES
  35. //======================================================================================================================================================150
  36. #include "./util/timer/timer.h" // (in path specified here)
  37. #include "./util/num/num.h" // (in path specified here)
  38. //======================================================================================================================================================150
  39. // MAIN FUNCTION HEADER
  40. //======================================================================================================================================================150
  41. #include "./main.h" // (in the current directory)
  42. //======================================================================================================================================================150
  43. // KERNEL
  44. //======================================================================================================================================================150
  45. #include "./kernel/kernel_gpu_opencl_wrapper.h" // (in library path specified here)
  46. // Helper function to print usage
  47. void usage(char *argv0) {
  48. char *help =
  49. "\nUsage: %s [switches] \n\n"
  50. " -b :number of boxes [default=0]\n"
  51. " -p platform_id :OCL platform to use [default=0]\n"
  52. " -d device_id :OCL device to use [default=0]\n"
  53. " -g use_gpu :1 for GPU 0 for CPU [default=0]\n";
  54. fprintf(stderr, help, argv0);
  55. exit(-1);
  56. }
  57. //========================================================================================================================================================================================================200
  58. // MAIN FUNCTION
  59. //========================================================================================================================================================================================================200
  60. int main( int argc,
  61. char *argv [])
  62. {
  63. //======================================================================================================================================================150
  64. // CPU/MCPU VARIABLES
  65. //======================================================================================================================================================150
  66. // timer
  67. long long time0;
  68. time0 = get_time();
  69. // timer
  70. long long time1;
  71. long long time2;
  72. long long time3;
  73. long long time4;
  74. long long time5;
  75. long long time6;
  76. long long time7;
  77. // counters
  78. int i, j, k, l, m, n;
  79. // system memory
  80. par_str par_cpu;
  81. dim_str dim_cpu;
  82. box_str* box_cpu;
  83. FOUR_VECTOR* rv_cpu;
  84. fp* qv_cpu;
  85. FOUR_VECTOR* fv_cpu;
  86. int nh;
  87. printf("WG size of kernel = %d \n", NUMBER_THREADS);
  88. time1 = get_time();
  89. //======================================================================================================================================================150
  90. // CHECK INPUT ARGUMENTS
  91. //======================================================================================================================================================150
  92. // assing default values
  93. dim_cpu.arch_arg = 0;
  94. dim_cpu.cores_arg = 1;
  95. dim_cpu.boxes1d_arg = 1;
  96. /*// go through arguments
  97. if(argc>=3){
  98. for(dim_cpu.cur_arg=1; dim_cpu.cur_arg<argc; dim_cpu.cur_arg++){
  99. // check if -boxes1d
  100. if(strcmp(argv[dim_cpu.cur_arg], "-boxes1d")==0){
  101. // check if value provided
  102. if(argc>=dim_cpu.cur_arg+1){
  103. // check if value is a number
  104. if(isInteger(argv[dim_cpu.cur_arg+1])==1){
  105. dim_cpu.boxes1d_arg = atoi(argv[dim_cpu.cur_arg+1]);
  106. if(dim_cpu.boxes1d_arg<0){
  107. printf("ERROR: Wrong value to -boxes1d argument, cannot be <=0\n");
  108. return 0;
  109. }
  110. dim_cpu.cur_arg = dim_cpu.cur_arg+1;
  111. }
  112. // value is not a number
  113. else{
  114. printf("ERROR: Value to -boxes1d argument in not a number\n");
  115. return 0;
  116. }
  117. }
  118. // value not provided
  119. else{
  120. printf("ERROR: Missing value to -boxes1d argument\n");
  121. return 0;
  122. }
  123. }
  124. // unknown
  125. else{
  126. printf("ERROR: Unknown argument\n");
  127. return 0;
  128. }
  129. }
  130. // Print configuration
  131. printf("Configuration used: arch = %d, cores = %d, boxes1d = %d\n", dim_cpu.arch_arg, dim_cpu.cores_arg, dim_cpu.boxes1d_arg);
  132. }
  133. else{
  134. printf("Provide boxes1d argument, example: -boxes1d 16");
  135. return 0;
  136. }*/
  137. // Arguments parsing for platform, device and type
  138. // Variables to store information on platform and device to use_gpu
  139. int platform_id = 0;
  140. int device_id = 0;
  141. int use_gpu = 0;
  142. /* obtain command line arguments and change appropriate options */
  143. int opt;
  144. extern char *optarg;
  145. while ((opt=getopt(argc,argv,"b:p:d:g:"))!= EOF) {
  146. switch (opt) {
  147. case 'p': platform_id = atoi(optarg);
  148. break;
  149. case 'd': device_id = atoi(optarg);
  150. break;
  151. case 'g': use_gpu = atoi(optarg);
  152. break;
  153. case 'b': dim_cpu.boxes1d_arg = atoi(optarg);
  154. break;
  155. case '?': usage(argv[0]);
  156. break;
  157. default: usage(argv[0]);
  158. break;
  159. }
  160. }
  161. time2 = get_time();
  162. //======================================================================================================================================================150
  163. // INPUTS
  164. //======================================================================================================================================================150
  165. par_cpu.alpha = 0.5;
  166. time3 = get_time();
  167. //======================================================================================================================================================150
  168. // DIMENSIONS
  169. //======================================================================================================================================================150
  170. // total number of boxes
  171. dim_cpu.number_boxes = dim_cpu.boxes1d_arg * dim_cpu.boxes1d_arg * dim_cpu.boxes1d_arg; // 8*8*8=512
  172. // how many particles space has in each direction
  173. dim_cpu.space_elem = dim_cpu.number_boxes * NUMBER_PAR_PER_BOX; //512*100=51,200
  174. dim_cpu.space_mem = dim_cpu.space_elem * sizeof(FOUR_VECTOR);
  175. dim_cpu.space_mem2 = dim_cpu.space_elem * sizeof(fp);
  176. // box array
  177. dim_cpu.box_mem = dim_cpu.number_boxes * sizeof(box_str);
  178. time4 = get_time();
  179. //======================================================================================================================================================150
  180. // SYSTEM MEMORY
  181. //======================================================================================================================================================150
  182. //====================================================================================================100
  183. // BOX
  184. //====================================================================================================100
  185. // allocate boxes
  186. box_cpu = (box_str*)malloc(dim_cpu.box_mem);
  187. // initialize number of home boxes
  188. nh = 0;
  189. // home boxes in z direction
  190. for(i=0; i<dim_cpu.boxes1d_arg; i++){
  191. // home boxes in y direction
  192. for(j=0; j<dim_cpu.boxes1d_arg; j++){
  193. // home boxes in x direction
  194. for(k=0; k<dim_cpu.boxes1d_arg; k++){
  195. // current home box
  196. box_cpu[nh].x = k;
  197. box_cpu[nh].y = j;
  198. box_cpu[nh].z = i;
  199. box_cpu[nh].number = nh;
  200. box_cpu[nh].offset = nh * NUMBER_PAR_PER_BOX;
  201. // initialize number of neighbor boxes
  202. box_cpu[nh].nn = 0;
  203. // neighbor boxes in z direction
  204. for(l=-1; l<2; l++){
  205. // neighbor boxes in y direction
  206. for(m=-1; m<2; m++){
  207. // neighbor boxes in x direction
  208. for(n=-1; n<2; n++){
  209. // check if (this neighbor exists) and (it is not the same as home box)
  210. if( (((i+l)>=0 && (j+m)>=0 && (k+n)>=0)==true && ((i+l)<dim_cpu.boxes1d_arg && (j+m)<dim_cpu.boxes1d_arg && (k+n)<dim_cpu.boxes1d_arg)==true) &&
  211. (l==0 && m==0 && n==0)==false ){
  212. // current neighbor box
  213. box_cpu[nh].nei[box_cpu[nh].nn].x = (k+n);
  214. box_cpu[nh].nei[box_cpu[nh].nn].y = (j+m);
  215. box_cpu[nh].nei[box_cpu[nh].nn].z = (i+l);
  216. box_cpu[nh].nei[box_cpu[nh].nn].number = (box_cpu[nh].nei[box_cpu[nh].nn].z * dim_cpu.boxes1d_arg * dim_cpu.boxes1d_arg) +
  217. (box_cpu[nh].nei[box_cpu[nh].nn].y * dim_cpu.boxes1d_arg) +
  218. box_cpu[nh].nei[box_cpu[nh].nn].x;
  219. box_cpu[nh].nei[box_cpu[nh].nn].offset = box_cpu[nh].nei[box_cpu[nh].nn].number * NUMBER_PAR_PER_BOX;
  220. // increment neighbor box
  221. box_cpu[nh].nn = box_cpu[nh].nn + 1;
  222. }
  223. } // neighbor boxes in x direction
  224. } // neighbor boxes in y direction
  225. } // neighbor boxes in z direction
  226. // increment home box
  227. nh = nh + 1;
  228. } // home boxes in x direction
  229. } // home boxes in y direction
  230. } // home boxes in z direction
  231. //====================================================================================================100
  232. // PARAMETERS, DISTANCE, CHARGE AND FORCE
  233. //====================================================================================================100
  234. // random generator seed set to random value - time in this case
  235. srand(time(NULL));
  236. // input (distances)
  237. rv_cpu = (FOUR_VECTOR*)malloc(dim_cpu.space_mem);
  238. for(i=0; i<dim_cpu.space_elem; i=i+1){
  239. rv_cpu[i].v = (rand()%10 + 1) / 10.0; // get a number in the range 0.1 - 1.0
  240. // rv_cpu[i].v = 0.1; // get a number in the range 0.1 - 1.0
  241. rv_cpu[i].x = (rand()%10 + 1) / 10.0; // get a number in the range 0.1 - 1.0
  242. // rv_cpu[i].x = 0.2; // get a number in the range 0.1 - 1.0
  243. rv_cpu[i].y = (rand()%10 + 1) / 10.0; // get a number in the range 0.1 - 1.0
  244. // rv_cpu[i].y = 0.3; // get a number in the range 0.1 - 1.0
  245. rv_cpu[i].z = (rand()%10 + 1) / 10.0; // get a number in the range 0.1 - 1.0
  246. // rv_cpu[i].z = 0.4; // get a number in the range 0.1 - 1.0
  247. }
  248. // input (charge)
  249. qv_cpu = (fp*)malloc(dim_cpu.space_mem2);
  250. for(i=0; i<dim_cpu.space_elem; i=i+1){
  251. qv_cpu[i] = (rand()%10 + 1) / 10.0; // get a number in the range 0.1 - 1.0
  252. // qv_cpu[i] = 0.5; // get a number in the range 0.1 - 1.0
  253. }
  254. // output (forces)
  255. fv_cpu = (FOUR_VECTOR*)malloc(dim_cpu.space_mem);
  256. for(i=0; i<dim_cpu.space_elem; i=i+1){
  257. fv_cpu[i].v = 0; // set to 0, because kernels keeps adding to initial value
  258. fv_cpu[i].x = 0; // set to 0, because kernels keeps adding to initial value
  259. fv_cpu[i].y = 0; // set to 0, because kernels keeps adding to initial value
  260. fv_cpu[i].z = 0; // set to 0, because kernels keeps adding to initial value
  261. }
  262. time5 = get_time();
  263. //======================================================================================================================================================150
  264. // KERNEL
  265. //======================================================================================================================================================150
  266. //====================================================================================================100
  267. // GPU_OPENCL
  268. //====================================================================================================100
  269. kernel_gpu_opencl_wrapper(par_cpu,
  270. dim_cpu,
  271. box_cpu,
  272. rv_cpu,
  273. qv_cpu,
  274. fv_cpu,
  275. platform_id,
  276. device_id,
  277. use_gpu);
  278. time6 = get_time();
  279. //======================================================================================================================================================150
  280. // SYSTEM MEMORY DEALLOCATION
  281. //======================================================================================================================================================150
  282. // dump results
  283. #ifdef OUTPUT
  284. FILE *fptr;
  285. fptr = fopen("result.txt", "w");
  286. for(i=0; i<dim_cpu.space_elem; i=i+1){
  287. fprintf(fptr, "%f, %f, %f, %f\n", fv_cpu[i].v, fv_cpu[i].x, fv_cpu[i].y, fv_cpu[i].z);
  288. }
  289. fclose(fptr);
  290. #endif
  291. free(rv_cpu);
  292. free(qv_cpu);
  293. free(fv_cpu);
  294. free(box_cpu);
  295. time7 = get_time();
  296. //======================================================================================================================================================150
  297. // DISPLAY TIMING
  298. //======================================================================================================================================================150
  299. // printf("Time spent in different stages of the application:\n");
  300. // printf("%15.12f s, %15.12f % : VARIABLES\n", (float) (time1-time0) / 1000000, (float) (time1-time0) / (float) (time7-time0) * 100);
  301. // printf("%15.12f s, %15.12f % : INPUT ARGUMENTS\n", (float) (time2-time1) / 1000000, (float) (time2-time1) / (float) (time7-time0) * 100);
  302. // printf("%15.12f s, %15.12f % : INPUTS\n", (float) (time3-time2) / 1000000, (float) (time3-time2) / (float) (time7-time0) * 100);
  303. // printf("%15.12f s, %15.12f % : dim_cpu\n", (float) (time4-time3) / 1000000, (float) (time4-time3) / (float) (time7-time0) * 100);
  304. // printf("%15.12f s, %15.12f % : SYS MEM: ALO\n", (float) (time5-time4) / 1000000, (float) (time5-time4) / (float) (time7-time0) * 100);
  305. // printf("%15.12f s, %15.12f % : KERNEL: COMPUTE\n", (float) (time6-time5) / 1000000, (float) (time6-time5) / (float) (time7-time0) * 100);
  306. // printf("%15.12f s, %15.12f % : SYS MEM: FRE\n", (float) (time7-time6) / 1000000, (float) (time7-time6) / (float) (time7-time0) * 100);
  307. // printf("Total time:\n");
  308. // printf("%.12f s\n", (float) (time7-time0) / 1000000);
  309. //======================================================================================================================================================150
  310. // RETURN
  311. //======================================================================================================================================================150
  312. return 0.0; // always returns 0.0
  313. }
  314. //========================================================================================================================================================================================================200
  315. // END
  316. //========================================================================================================================================================================================================200
  317. #ifdef __cplusplus
  318. }
  319. #endif