123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119 |
- /* StarPU --- Runtime system for heterogeneous multicore architectures.
- *
- * Copyright (C) 2010,2011 University of Bordeaux
- *
- * StarPU is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or (at
- * your option) any later version.
- *
- * StarPU is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *
- * See the GNU Lesser General Public License in COPYING.LGPL for more details.
- */
- #include "socl.h"
- struct bp_data {
- cl_program program;
- char * options;
- const cl_device_id * device_list;
- cl_uint num_devices;
- };
- static void soclBuildProgram_task(void *data) {
- struct bp_data *d = (struct bp_data*)data;
- cl_device_id device;
- cl_int err;
- unsigned int i;
- int wid = starpu_worker_get_id();
- /* Check if the kernel has to be built for this device */
- for (i=0; i <= d->num_devices; i++) {
- if (i == d->num_devices)
- return;
- if (d->device_list[i]->worker_id == wid)
- break;
- }
- int range = starpu_worker_get_range();
- starpu_opencl_get_device(wid, &device);
- DEBUG_MSG("[Worker %d] Building program...\n", wid);
- cl_device_type dev_type;
- clGetDeviceInfo(device, CL_DEVICE_TYPE, sizeof(cl_device_type), &dev_type, NULL);
- char * dev_type_str = (dev_type == CL_DEVICE_TYPE_CPU ? "CPU" :
- dev_type == CL_DEVICE_TYPE_GPU ? "GPU" :
- dev_type == CL_DEVICE_TYPE_ACCELERATOR ? "ACCELERATOR" : "UNKNOWN");
- char opts[4096];
- sprintf(opts, "-DSOCL_DEVICE_TYPE_%s %s",
- dev_type_str, (d->options != NULL ? d->options : ""));
- err = clBuildProgram(d->program->cl_programs[range], 1, &device, opts, NULL, NULL);
- if (err != CL_SUCCESS) {
- size_t len;
- clGetProgramBuildInfo(d->program->cl_programs[range], device, CL_PROGRAM_BUILD_LOG, 0, NULL, &len);
- char * buffer = malloc(len+1);
- buffer[len] = '\0';
- clGetProgramBuildInfo(d->program->cl_programs[range], device, CL_PROGRAM_BUILD_LOG, len, buffer, NULL);
- DEBUG_CL("clBuildProgram", err);
- ERROR_MSG("clBuildProgram: %s\n Aborting.\n", buffer);
- free(buffer);
- }
- DEBUG_MSG("[Worker %d] Done building.\n", wid);
- }
- CL_API_ENTRY cl_int CL_API_CALL
- soclBuildProgram(cl_program program,
- cl_uint num_devices,
- const cl_device_id * device_list,
- const char * options,
- void (*pfn_notify)(cl_program program, void * user_data),
- void * user_data) CL_API_SUFFIX__VERSION_1_0
- {
- struct bp_data *data;
- program->options = options != NULL ? strdup(options) : NULL;
- program->options_size = options != NULL ? strlen(options)+1 : 0;
- data = (struct bp_data*)malloc(sizeof(struct bp_data));
- gc_entity_store(&data->program, program);
- data->options = (char*)options;
- /* If the device list is empty, we compile for every device in the context associated to the program */
- if (device_list == NULL) {
- num_devices = program->context->num_devices;
- device_list = program->context->devices;
- }
- data->num_devices = num_devices;
- data->device_list = device_list;
- /*FIXME: starpu_execute_on_specific_workers is synchronous.
- * However pfn_notify is useful only because build is supposed to be asynchronous
- */
- unsigned workers[num_devices];
- unsigned i;
- for (i=0; i<num_devices; i++) {
- workers[i] = device_list[i]->worker_id;
- }
- starpu_execute_on_specific_workers(soclBuildProgram_task, data, num_devices, workers, "SOCL_BUILD_PROGRAM");
- if (pfn_notify != NULL)
- pfn_notify(program, user_data);
- gc_entity_unstore(&data->program);
- free(data);
- return CL_SUCCESS;
- }
|