cl_createbuffer.c 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. /* StarPU --- Runtime system for heterogeneous multicore architectures.
  2. *
  3. * Copyright (C) 2011-2013 Inria
  4. * Copyright (C) 2012,2017 CNRS
  5. * Copyright (C) 2010-2011,2013, 2018 Université de Bordeaux
  6. *
  7. * StarPU is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU Lesser General Public License as published by
  9. * the Free Software Foundation; either version 2.1 of the License, or (at
  10. * your option) any later version.
  11. *
  12. * StarPU is distributed in the hope that it will be useful, but
  13. * WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  15. *
  16. * See the GNU Lesser General Public License in COPYING.LGPL for more details.
  17. */
  18. #include "socl.h"
  19. static void release_callback_memobject(void * e)
  20. {
  21. cl_mem mem = (cl_mem)e;
  22. /* Release references */
  23. gc_entity_unstore(&mem->context);
  24. //Delete this mem_object from the mem_object list
  25. mem_object_release(mem);
  26. /* Destruct object */
  27. starpu_data_unregister_submit(mem->handle);
  28. if (!(mem->flags & CL_MEM_USE_HOST_PTR))
  29. free(mem->ptr);
  30. }
  31. /**
  32. * \brief Create a buffer
  33. *
  34. * A buffer has always an allocated region in host memory. If CL_MEM_USE_HOST_PTR
  35. * is set, we use memory pointed by host_ptr, otherwise some host memory is
  36. * allocated.
  37. *
  38. * If CL_MEM_USE_HOST_PTR or CL_MEM_ALLOC_HOST_PTR are set, memory pointed by host_ptr
  39. * is not coherent. To enforce coherency, you have to map the buffer (clEnqueueMapBuffer).
  40. *
  41. * If CL_MEM_COPY_HOST_PTR is set, the buffer will be duplicated in host memory. You
  42. * should avoid it.
  43. *
  44. */
  45. CL_API_SUFFIX__VERSION_1_0
  46. CL_API_ENTRY cl_mem CL_API_CALL
  47. soclCreateBuffer(cl_context context,
  48. cl_mem_flags flags,
  49. size_t size,
  50. void * host_ptr,
  51. cl_int * errcode_ret)
  52. {
  53. cl_mem mem;
  54. if (errcode_ret != NULL)
  55. *errcode_ret = CL_SUCCESS;
  56. //Check flags
  57. if (((flags & CL_MEM_READ_ONLY) && (flags & CL_MEM_WRITE_ONLY))
  58. || ((flags & CL_MEM_READ_WRITE) && (flags & CL_MEM_READ_ONLY))
  59. || ((flags & CL_MEM_READ_WRITE) && (flags & CL_MEM_WRITE_ONLY))
  60. || ((flags & CL_MEM_USE_HOST_PTR) && (flags & CL_MEM_ALLOC_HOST_PTR))
  61. || ((flags & CL_MEM_USE_HOST_PTR) && (flags & CL_MEM_COPY_HOST_PTR)))
  62. {
  63. if (errcode_ret != NULL)
  64. *errcode_ret = CL_INVALID_VALUE;
  65. return NULL;
  66. }
  67. if (size == 0)
  68. {
  69. if (errcode_ret != NULL)
  70. *errcode_ret = CL_INVALID_BUFFER_SIZE;
  71. return NULL;
  72. }
  73. if ((host_ptr == NULL && (flags & (CL_MEM_USE_HOST_PTR | CL_MEM_COPY_HOST_PTR)))
  74. || (host_ptr != NULL && !(flags & (CL_MEM_USE_HOST_PTR | CL_MEM_COPY_HOST_PTR))))
  75. {
  76. if (errcode_ret != NULL)
  77. *errcode_ret = CL_INVALID_HOST_PTR;
  78. return NULL;
  79. }
  80. //Alloc cl_mem structure
  81. mem = (cl_mem)gc_entity_alloc(sizeof(struct _cl_mem), release_callback_memobject, "buffer");
  82. if (mem == NULL)
  83. {
  84. if (errcode_ret != NULL)
  85. *errcode_ret = CL_OUT_OF_HOST_MEMORY;
  86. return NULL;
  87. }
  88. mem->ptr = NULL;
  89. mem->map_count = 0;
  90. gc_entity_store(&mem->context, context);
  91. mem->flags = flags;
  92. mem->size = size;
  93. mem->host_ptr = host_ptr;
  94. #ifdef DEBUG
  95. static int id = 0;
  96. mem->id = id++;
  97. #endif
  98. mem_object_store(mem);
  99. //TODO: we shouldn't allocate the buffer ourselves. StarPU allocates it if a NULL pointer is given
  100. // If not MEM_USE_HOST_PTR, we need to alloc the buffer ourselves
  101. if (!(flags & CL_MEM_USE_HOST_PTR))
  102. {
  103. mem->ptr = valloc(size);
  104. if (mem->ptr == NULL)
  105. {
  106. if (errcode_ret != NULL)
  107. *errcode_ret = CL_MEM_OBJECT_ALLOCATION_FAILURE;
  108. free(mem);
  109. return NULL;
  110. }
  111. //The buffer doesn't contain meaningful data
  112. mem->scratch = 1;
  113. }
  114. else
  115. {
  116. //The buffer may contain meaningful data
  117. mem->scratch = 0;
  118. mem->ptr = host_ptr;
  119. }
  120. // Access mode
  121. mem->mode = (flags & CL_MEM_READ_ONLY) ? CL_MEM_READ_ONLY :
  122. (flags & CL_MEM_WRITE_ONLY) ? CL_MEM_WRITE_ONLY : CL_MEM_READ_WRITE;
  123. // Perform data copy if necessary
  124. if (flags & CL_MEM_COPY_HOST_PTR)
  125. memcpy(mem->ptr, host_ptr, size);
  126. // Create StarPU buffer (on home node? what's this?)
  127. starpu_variable_data_register(&mem->handle, STARPU_MAIN_RAM, (uintptr_t)mem->ptr, size);
  128. DEBUG_MSG("[Buffer %d] Initialized (cl_mem %p handle %p)\n", mem->id, mem, mem->handle);
  129. return mem;
  130. }