cl_createprogramwithsource.c 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  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. struct cpws_data {
  18. struct _cl_program *program;
  19. cl_int *errcodes;
  20. cl_uint count;
  21. char **strings;
  22. size_t *lengths;
  23. };
  24. static void soclCreateProgramWithSource_task(void *data) {
  25. struct cpws_data *d = (struct cpws_data*)data;
  26. cl_context context;
  27. int wid = starpu_worker_get_id();
  28. DEBUG_MSG("Worker id: %d\n", wid);
  29. int range = starpu_worker_get_range();
  30. starpu_opencl_get_context(wid, &context);
  31. d->program->cl_programs[range] = clCreateProgramWithSource(context, d->count, (const char**)d->strings, d->lengths, &d->errcodes[range]);
  32. }
  33. static void rp_task(void *data) {
  34. cl_program program = (cl_program)data;
  35. int range = starpu_worker_get_range();
  36. cl_int err = clReleaseProgram(program->cl_programs[range]);
  37. if (err != CL_SUCCESS)
  38. DEBUG_CL("clReleaseProgram", err);
  39. }
  40. static void release_callback_program(void * e) {
  41. cl_program program = (cl_program)e;
  42. /* Destruct object */
  43. starpu_execute_on_each_worker(rp_task, program, STARPU_OPENCL);
  44. /* Release references */
  45. gc_entity_unstore(&program->context);
  46. free(program->cl_programs);
  47. if (program->options != NULL)
  48. free(program->options);
  49. }
  50. CL_API_ENTRY cl_program CL_API_CALL
  51. soclCreateProgramWithSource(cl_context context,
  52. cl_uint count,
  53. const char ** strings,
  54. const size_t * lengths,
  55. cl_int * errcode_ret) CL_API_SUFFIX__VERSION_1_0
  56. {
  57. cl_program p;
  58. struct cpws_data *data;
  59. int device_count;
  60. if (errcode_ret != NULL)
  61. *errcode_ret = CL_SUCCESS;
  62. device_count = starpu_opencl_worker_get_count();
  63. assert(device_count > 0);
  64. DEBUG_MSG("Worker count: %d\n", device_count);
  65. /* Check arguments */
  66. if (count == 0 || strings == NULL) {
  67. if (errcode_ret != NULL)
  68. *errcode_ret = CL_INVALID_VALUE;
  69. return NULL;
  70. }
  71. /* Alloc cl_program structure */
  72. p = (cl_program)gc_entity_alloc(sizeof(struct _cl_program), release_callback_program);
  73. if (p == NULL) {
  74. if (errcode_ret != NULL)
  75. *errcode_ret = CL_OUT_OF_HOST_MEMORY;
  76. return NULL;
  77. }
  78. gc_entity_store(&p->context, context);
  79. p->options = NULL;
  80. #ifdef DEBUG
  81. static int id = 0;
  82. p->id = id++;
  83. #endif
  84. p->cl_programs = (cl_program*)malloc(sizeof(cl_program) * device_count);
  85. if (p->cl_programs == NULL) {
  86. if (errcode_ret != NULL)
  87. *errcode_ret = CL_OUT_OF_HOST_MEMORY;
  88. return NULL;
  89. }
  90. {
  91. int i;
  92. for (i=0; i<device_count; i++)
  93. p->cl_programs[i] = NULL;
  94. }
  95. /* Construct structure to pass arguments to workers */
  96. data = (struct cpws_data*)malloc(sizeof(struct cpws_data));
  97. if (data == NULL) {
  98. if (errcode_ret != NULL)
  99. *errcode_ret = CL_OUT_OF_HOST_MEMORY;
  100. return NULL;
  101. }
  102. data->count = count;
  103. data->program = p;
  104. data->strings = (char**)strings;
  105. data->lengths = (size_t*)lengths;
  106. data->errcodes = (cl_int*)malloc(sizeof(cl_int) * device_count);
  107. /* Init real cl_program for each OpenCL device */
  108. starpu_execute_on_each_worker(soclCreateProgramWithSource_task, data, STARPU_OPENCL);
  109. if (errcode_ret != NULL) {
  110. int i;
  111. *errcode_ret = CL_SUCCESS;
  112. for (i=0; i<device_count; i++) {
  113. if (data->errcodes[i] != CL_SUCCESS) {
  114. DEBUG_MSG("Worker [%d] failed\n", i);
  115. DEBUG_CL("clCreateProgramWithSource", data->errcodes[i]);
  116. *errcode_ret = data->errcodes[i];
  117. break;
  118. }
  119. }
  120. }
  121. free(data->errcodes);
  122. free(data);
  123. return p;
  124. }