cl_createbuffer.c 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. /* StarPU --- Runtime system for heterogeneous multicore architectures.
  2. *
  3. * Copyright (C) 2010,2011 University of Bordeaux
  4. *
  5. * StarPU 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. * StarPU 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 "socl.h"
  17. static void release_callback_memobject(void * e) {
  18. cl_mem mem = (cl_mem)e;
  19. /* Release references */
  20. gc_entity_unstore(&mem->context);
  21. //Delete this mem_object from the mem_object list
  22. mem_object_release(mem);
  23. /* Destruct object */
  24. starpu_data_unregister_no_coherency(mem->handle);
  25. if (!(mem->flags & CL_MEM_USE_HOST_PTR))
  26. free(mem->ptr);
  27. }
  28. /**
  29. * \brief Create a buffer
  30. *
  31. * A buffer has always an allocated region in host memory. If CL_MEM_USE_HOST_PTR
  32. * is set, we use memory pointed by host_ptr, otherwise some host memory is
  33. * allocated.
  34. *
  35. * If CL_MEM_USE_HOST_PTR or CL_MEM_ALLOC_HOST_PTR are set, memory pointed by host_ptr
  36. * is not coherent. To enforce coherency, you have to map the buffer (clEnqueueMapBuffer).
  37. *
  38. * If CL_MEM_COPY_HOST_PTR is set, the buffer will be duplicated in host memory. You
  39. * should avoid it.
  40. *
  41. */
  42. CL_API_ENTRY cl_mem CL_API_CALL
  43. soclCreateBuffer(cl_context context,
  44. cl_mem_flags flags,
  45. size_t size,
  46. void * host_ptr,
  47. cl_int * errcode_ret) CL_API_SUFFIX__VERSION_1_0
  48. {
  49. if (errcode_ret != NULL)
  50. *errcode_ret = CL_SUCCESS;
  51. //Check flags
  52. if (((flags & CL_MEM_READ_ONLY) && (flags & CL_MEM_WRITE_ONLY))
  53. || ((flags & CL_MEM_READ_WRITE) && (flags & CL_MEM_READ_ONLY))
  54. || ((flags & CL_MEM_READ_WRITE) && (flags & CL_MEM_WRITE_ONLY))
  55. || ((flags & CL_MEM_USE_HOST_PTR) && (flags & CL_MEM_ALLOC_HOST_PTR))
  56. || ((flags & CL_MEM_USE_HOST_PTR) && (flags & CL_MEM_COPY_HOST_PTR))) {
  57. if (errcode_ret != NULL)
  58. *errcode_ret = CL_INVALID_VALUE;
  59. return NULL;
  60. }
  61. if (size == 0) {
  62. if (errcode_ret != NULL)
  63. *errcode_ret = CL_INVALID_BUFFER_SIZE;
  64. return NULL;
  65. }
  66. if ((host_ptr == NULL && (flags & (CL_MEM_USE_HOST_PTR | CL_MEM_COPY_HOST_PTR)))
  67. || (host_ptr != NULL && !(flags & (CL_MEM_USE_HOST_PTR | CL_MEM_COPY_HOST_PTR)))) {
  68. if (errcode_ret != NULL)
  69. *errcode_ret = CL_INVALID_HOST_PTR;
  70. return NULL;
  71. }
  72. {
  73. cl_mem mem;
  74. //Alloc cl_mem structure
  75. mem = (cl_mem)gc_entity_alloc(sizeof(struct _cl_mem), release_callback_memobject);
  76. if (mem == NULL) {
  77. if (errcode_ret != NULL)
  78. *errcode_ret = CL_OUT_OF_HOST_MEMORY;
  79. return NULL;
  80. }
  81. mem->ptr = NULL;
  82. mem->map_count = 0;
  83. gc_entity_store(&mem->context, context);
  84. mem->flags = flags;
  85. mem->size = size;
  86. mem->host_ptr = host_ptr;
  87. #ifdef DEBUG
  88. static int id = 0;
  89. mem->id = id++;
  90. #endif
  91. mem_object_store(mem);
  92. //TODO: we shouldn't allocate the buffer ourselves. StarPU allocates it if a NULL pointer is given
  93. // If not MEM_USE_HOST_PTR, we need to alloc the buffer ourselves
  94. if (!(flags & CL_MEM_USE_HOST_PTR)) {
  95. mem->ptr = valloc(size);
  96. if (mem->ptr == NULL) {
  97. if (errcode_ret != NULL)
  98. *errcode_ret = CL_MEM_OBJECT_ALLOCATION_FAILURE;
  99. free(mem);
  100. return NULL;
  101. }
  102. //The buffer doesn't contain meaningful data
  103. mem->scratch = 1;
  104. }
  105. else {
  106. //The buffer may contain meaningful data
  107. mem->scratch = 0;
  108. mem->ptr = host_ptr;
  109. }
  110. // Access mode
  111. if (flags & CL_MEM_READ_ONLY)
  112. mem->mode = CL_MEM_READ_ONLY;
  113. else if (flags & CL_MEM_WRITE_ONLY)
  114. mem->mode = CL_MEM_WRITE_ONLY;
  115. else
  116. mem->mode = CL_MEM_READ_WRITE;
  117. // Perform data copy if necessary
  118. if (flags & CL_MEM_COPY_HOST_PTR)
  119. memcpy(mem->ptr, host_ptr, size);
  120. // Create StarPU buffer (on home node? what's this?)
  121. starpu_variable_data_register(&mem->handle, 0, (uintptr_t)mem->ptr, size);
  122. DEBUG_MSG("[Buffer %d] Initialized (cl_mem %p handle %p)\n", mem->id, mem, mem->handle);
  123. return mem;
  124. }
  125. }