pi_kernel.cu 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. /*
  2. * StarPU
  3. * Copyright (C) INRIA 2008-2010 (see AUTHORS file)
  4. *
  5. * This program is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU Lesser General Public License as published by
  7. * the Free Software Foundation; either version 2.1 of the License, or (at
  8. * your option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful, but
  11. * WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  13. *
  14. * See the GNU Lesser General Public License in COPYING.LGPL for more details.
  15. */
  16. #include "pi.h"
  17. #define BLOCK_SIZE 256
  18. static __global__ void monte_carlo(TYPE *random_numbers_x, TYPE *random_numbers_y,
  19. unsigned n, unsigned *output_cnt)
  20. {
  21. __shared__ unsigned scnt[BLOCK_SIZE];
  22. const int tid = threadIdx.x + blockIdx.x*blockDim.x;
  23. /* Blank the shared mem buffer */
  24. if (threadIdx.x < 32)
  25. scnt[threadIdx.x] = 0;
  26. __syncthreads();
  27. /* Do we have a successful shot ? */
  28. TYPE x = random_numbers_x[tid];
  29. TYPE y = random_numbers_y[tid];
  30. TYPE dist = (x*x + y*y);
  31. scnt[threadIdx.x] = (dist <= 1.0f);
  32. __syncthreads();
  33. /* XXX that's totally unoptimized : we should do a reduction ! */
  34. if (threadIdx.x == 0)
  35. {
  36. unsigned total_cnt = 0;
  37. unsigned i;
  38. for (i = 0; i < BLOCK_SIZE; i++)
  39. total_cnt += scnt[i];
  40. output_cnt[blockIdx.x] = total_cnt;
  41. }
  42. }
  43. static __global__ void sum_per_block_cnt(unsigned previous_nblocks,
  44. unsigned *output_cnt,
  45. unsigned *cnt)
  46. {
  47. /* XXX that's totally unoptimized yet : we should do a reduction ! */
  48. if (threadIdx.x == 0)
  49. {
  50. unsigned total_cnt = 0;
  51. unsigned i;
  52. for (i = 0; i < previous_nblocks; i++)
  53. total_cnt += output_cnt[i];
  54. *cnt = total_cnt;
  55. }
  56. }
  57. extern "C" void cuda_kernel(void *descr[], void *cl_arg)
  58. {
  59. TYPE *random_numbers_x = (TYPE *)STARPU_GET_VECTOR_PTR(descr[0]);
  60. TYPE *random_numbers_y = (TYPE *)STARPU_GET_VECTOR_PTR(descr[1]);
  61. unsigned nx = STARPU_GET_VECTOR_NX(descr[0]);
  62. unsigned *cnt = (unsigned *)STARPU_GET_VECTOR_PTR(descr[2]);
  63. unsigned *per_block_cnt;
  64. cudaMalloc((void **)&per_block_cnt, (nx/BLOCK_SIZE)*sizeof(unsigned));
  65. monte_carlo<<<nx/BLOCK_SIZE, BLOCK_SIZE>>>(random_numbers_x, random_numbers_y, nx, per_block_cnt);
  66. cudaThreadSynchronize();
  67. sum_per_block_cnt<<<1, 32>>>(nx/BLOCK_SIZE, per_block_cnt, cnt);
  68. cudaThreadSynchronize();
  69. cudaFree(per_block_cnt);
  70. }