malloc.c 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250
  1. /* StarPU --- Runtime system for heterogeneous multicore architectures.
  2. *
  3. * Copyright (C) 2009-2010, 2012 Université de Bordeaux 1
  4. * Copyright (C) 2010, 2011, 2012 Centre National de la Recherche Scientifique
  5. *
  6. * StarPU is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU Lesser General Public License as published by
  8. * the Free Software Foundation; either version 2.1 of the License, or (at
  9. * your option) any later version.
  10. *
  11. * StarPU is distributed in the hope that it will be useful, but
  12. * WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  14. *
  15. * See the GNU Lesser General Public License in COPYING.LGPL for more details.
  16. */
  17. #include <errno.h>
  18. #include <core/workers.h>
  19. #include <common/config.h>
  20. #include <starpu.h>
  21. #include <starpu_data.h>
  22. #include <starpu_cuda.h>
  23. #include <drivers/opencl/driver_opencl.h>
  24. #if (defined(STARPU_USE_CUDA) && !defined(HAVE_CUDA_MEMCPY_PEER))// || defined(STARPU_USE_OPENCL)
  25. struct malloc_pinned_codelet_struct
  26. {
  27. void **ptr;
  28. size_t dim;
  29. };
  30. #endif
  31. //#ifdef STARPU_USE_OPENCL
  32. //static void malloc_pinned_opencl_codelet(void *buffers[] STARPU_ATTRIBUTE_UNUSED, void *arg)
  33. //{
  34. // struct malloc_pinned_codelet_struct *s = arg;
  35. // // *(s->ptr) = malloc(s->dim);
  36. // starpu_opencl_allocate_memory((void **)(s->ptr), s->dim, CL_MEM_READ_WRITE|CL_MEM_ALLOC_HOST_PTR);
  37. //}
  38. //#endif
  39. #if defined(STARPU_USE_CUDA) && !defined(HAVE_CUDA_MEMCPY_PEER)
  40. static void malloc_pinned_cuda_codelet(void *buffers[] STARPU_ATTRIBUTE_UNUSED, void *arg)
  41. {
  42. struct malloc_pinned_codelet_struct *s = arg;
  43. cudaError_t cures;
  44. cures = cudaHostAlloc((void **)(s->ptr), s->dim, cudaHostAllocPortable);
  45. if (STARPU_UNLIKELY(cures))
  46. STARPU_CUDA_REPORT_ERROR(cures);
  47. }
  48. #endif
  49. #if (defined(STARPU_USE_CUDA) && !defined(HAVE_CUDA_MEMCPY_PEER))// || defined(STARPU_USE_OPENCL)
  50. static struct starpu_perfmodel malloc_pinned_model =
  51. {
  52. .type = STARPU_HISTORY_BASED,
  53. .symbol = "malloc_pinned"
  54. };
  55. static struct starpu_codelet malloc_pinned_cl =
  56. {
  57. .cuda_funcs = {malloc_pinned_cuda_codelet, NULL},
  58. //#ifdef STARPU_USE_OPENCL
  59. // .opencl_funcs = {malloc_pinned_opencl_codelet, NULL},
  60. //#endif
  61. .nbuffers = 0,
  62. .model = &malloc_pinned_model
  63. };
  64. #endif
  65. int starpu_malloc(void **A, size_t dim)
  66. {
  67. if (STARPU_UNLIKELY(!_starpu_worker_may_perform_blocking_calls()))
  68. return -EDEADLK;
  69. STARPU_ASSERT(A);
  70. if (_starpu_can_submit_cuda_task())
  71. {
  72. #ifdef STARPU_USE_CUDA
  73. #ifdef HAVE_CUDA_MEMCPY_PEER
  74. cudaError_t cures;
  75. cures = cudaHostAlloc(A, dim, cudaHostAllocPortable);
  76. if (STARPU_UNLIKELY(cures))
  77. STARPU_CUDA_REPORT_ERROR(cures);
  78. #else
  79. int push_res;
  80. struct malloc_pinned_codelet_struct s =
  81. {
  82. .ptr = A,
  83. .dim = dim
  84. };
  85. malloc_pinned_cl.where = STARPU_CUDA;
  86. struct starpu_task *task = starpu_task_create();
  87. task->callback_func = NULL;
  88. task->cl = &malloc_pinned_cl;
  89. task->cl_arg = &s;
  90. task->synchronous = 1;
  91. _starpu_exclude_task_from_dag(task);
  92. push_res = starpu_task_submit(task);
  93. STARPU_ASSERT(push_res != -ENODEV);
  94. #endif
  95. #endif
  96. }
  97. // else if (_starpu_can_submit_opencl_task())
  98. // {
  99. //#ifdef STARPU_USE_OPENCL
  100. // int push_res;
  101. //
  102. // struct malloc_pinned_codelet_struct s =
  103. // {
  104. // .ptr = A,
  105. // .dim = dim
  106. // };
  107. //
  108. // malloc_pinned_cl.where = STARPU_OPENCL;
  109. // struct starpu_task *task = starpu_task_create();
  110. // task->callback_func = NULL;
  111. // task->cl = &malloc_pinned_cl;
  112. // task->cl_arg = &s;
  113. //
  114. // task->synchronous = 1;
  115. //
  116. // _starpu_exclude_task_from_dag(task);
  117. //
  118. // push_res = starpu_task_submit(task);
  119. // STARPU_ASSERT(push_res != -ENODEV);
  120. //#endif
  121. // }
  122. else
  123. {
  124. *A = malloc(dim);
  125. }
  126. STARPU_ASSERT(*A);
  127. return 0;
  128. }
  129. #if defined(STARPU_USE_CUDA) && !defined(HAVE_CUDA_MEMCPY_PEER)
  130. static void free_pinned_cuda_codelet(void *buffers[] STARPU_ATTRIBUTE_UNUSED, void *arg)
  131. {
  132. cudaError_t cures;
  133. cures = cudaFreeHost(arg);
  134. if (STARPU_UNLIKELY(cures))
  135. STARPU_CUDA_REPORT_ERROR(cures);
  136. }
  137. #endif
  138. //#ifdef STARPU_USE_OPENCL
  139. //static void free_pinned_opencl_codelet(void *buffers[] STARPU_ATTRIBUTE_UNUSED, void *arg)
  140. //{
  141. // // free(arg);
  142. // int err = clReleaseMemObject(arg);
  143. // if (err != CL_SUCCESS) STARPU_OPENCL_REPORT_ERROR(err);
  144. //}
  145. //#endif
  146. #if (defined(STARPU_USE_CUDA) && !defined(HAVE_CUDA_MEMCPY_PEER)) // || defined(STARPU_USE_OPENCL)
  147. static struct starpu_perfmodel free_pinned_model =
  148. {
  149. .type = STARPU_HISTORY_BASED,
  150. .symbol = "free_pinned"
  151. };
  152. static struct starpu_codelet free_pinned_cl =
  153. {
  154. .cuda_funcs = {free_pinned_cuda_codelet, NULL},
  155. //#ifdef STARPU_USE_OPENCL
  156. // .opencl_funcs = {free_pinned_opencl_codelet, NULL},
  157. //#endif
  158. .nbuffers = 0,
  159. .model = &free_pinned_model
  160. };
  161. #endif
  162. int starpu_free(void *A)
  163. {
  164. if (STARPU_UNLIKELY(!_starpu_worker_may_perform_blocking_calls()))
  165. return -EDEADLK;
  166. #ifdef STARPU_USE_CUDA
  167. if (_starpu_can_submit_cuda_task())
  168. {
  169. #ifndef HAVE_CUDA_MEMCPY_PEER
  170. if (!_starpu_is_initialized())
  171. {
  172. #endif
  173. /* This is especially useful when starpu_free is called from
  174. * the GCC-plugin. starpu_shutdown will probably have already
  175. * been called, so we will not be able to submit a task. */
  176. cudaError_t err = cudaFreeHost(A);
  177. if (STARPU_UNLIKELY(err))
  178. STARPU_CUDA_REPORT_ERROR(err);
  179. #ifndef HAVE_CUDA_MEMCPY_PEER
  180. }
  181. else
  182. {
  183. int push_res;
  184. free_pinned_cl.where = STARPU_CUDA;
  185. struct starpu_task *task = starpu_task_create();
  186. task->callback_func = NULL;
  187. task->cl = &free_pinned_cl;
  188. task->cl_arg = A;
  189. task->synchronous = 1;
  190. _starpu_exclude_task_from_dag(task);
  191. push_res = starpu_task_submit(task);
  192. STARPU_ASSERT(push_res != -ENODEV);
  193. }
  194. #endif
  195. // else if (_starpu_can_submit_opencl_task())
  196. // {
  197. //#ifdef STARPU_USE_OPENCL
  198. // int push_res;
  199. //
  200. // free_pinned_cl.where = STARPU_OPENCL;
  201. // struct starpu_task *task = starpu_task_create();
  202. // task->callback_func = NULL;
  203. // task->cl = &free_pinned_cl;
  204. // task->cl_arg = A;
  205. //
  206. // task->synchronous = 1;
  207. //
  208. // _starpu_exclude_task_from_dag(task);
  209. //
  210. // push_res = starpu_task_submit(task);
  211. // STARPU_ASSERT(push_res != -ENODEV);
  212. //#endif
  213. // }
  214. } else
  215. #endif
  216. {
  217. free(A);
  218. }
  219. return 0;
  220. }