|
@@ -24,74 +24,161 @@
|
|
|
* its command queue.
|
|
|
*/
|
|
|
|
|
|
+
|
|
|
/**
|
|
|
- * Enqueue the given task but put fake_event into the command queue.
|
|
|
- * This is used when a tag notified by application is used (cf clEnqueueMapBuffer, etc.)
|
|
|
+ * Returned implicit dependencies for a task
|
|
|
+ * Command queue must be locked!
|
|
|
*/
|
|
|
-cl_int command_queue_enqueue_fakeevent(cl_command_queue cq, starpu_task *task, cl_int barrier, cl_int num_events, const cl_event * events, cl_event fake_event) {
|
|
|
-
|
|
|
- int in_order = !(cq->properties & CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE);
|
|
|
-
|
|
|
- /* Set explicit task dependencies */
|
|
|
- task_dependency_add(task, num_events, events);
|
|
|
-
|
|
|
- /* Lock command queue */
|
|
|
- pthread_spin_lock(&cq->spin);
|
|
|
-
|
|
|
- /* Add dependency to last barrier if applicable */
|
|
|
- if (cq->barrier != NULL)
|
|
|
- task_dependency_add(task, 1, &cq->barrier);
|
|
|
-
|
|
|
- /* Add dependencies to out-of-order events (if any) */
|
|
|
- if (barrier) {
|
|
|
- while (cq->events != NULL) {
|
|
|
- task_dependency_add(task, 1, &cq->events);
|
|
|
- cq->events = cq->events->next;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- cl_event ev = (fake_event == NULL ? task_event(task) : fake_event);
|
|
|
+void command_queue_dependencies_implicit(
|
|
|
+ cl_command_queue cq, /* Command queue */
|
|
|
+ char is_barrier, /* Is the task a barrier */
|
|
|
+ cl_int * ret_num_events, /* Returned number of dependencies */
|
|
|
+ cl_event ** ret_events /* Returned dependencies */
|
|
|
+) {
|
|
|
+
|
|
|
+ /*********************
|
|
|
+ * Count dependencies
|
|
|
+ *********************/
|
|
|
+ int ndeps = 0;
|
|
|
+
|
|
|
+ /* Add dependency to last barrier if applicable */
|
|
|
+ if (cq->barrier != NULL)
|
|
|
+ ndeps++;
|
|
|
+
|
|
|
+ /* Add dependencies to out-of-order events (if any) */
|
|
|
+ if (is_barrier) {
|
|
|
+ cl_event ev = cq->events;
|
|
|
+ while (ev != NULL) {
|
|
|
+ ndeps++;
|
|
|
+ ev = ev->next;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /*********************
|
|
|
+ * Return dependencies
|
|
|
+ *********************/
|
|
|
+
|
|
|
+ cl_event * evs = malloc(ndeps * sizeof(cl_event));
|
|
|
+ int n = 0;
|
|
|
+
|
|
|
+ /* Add dependency to last barrier if applicable */
|
|
|
+ if (cq->barrier != NULL)
|
|
|
+ evs[n++] = cq->barrier;
|
|
|
+
|
|
|
+ /* Add dependencies to out-of-order events (if any) */
|
|
|
+ if (is_barrier) {
|
|
|
+ cl_event ev = cq->events;
|
|
|
+ while (ev != NULL) {
|
|
|
+ evs[n++] = ev;
|
|
|
+ ev = ev->next;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ *ret_num_events = ndeps;
|
|
|
+ *ret_events = evs;
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * Insert a task in the command queue
|
|
|
+ * The command queue must be locked!
|
|
|
+ */
|
|
|
+void command_queue_insert(
|
|
|
+ cl_command_queue cq, /* Command queue */
|
|
|
+ cl_event task_event, /* Event for the task */
|
|
|
+ char is_barrier /* Is the task a barrier */
|
|
|
+) {
|
|
|
+
|
|
|
+ int in_order = !(cq->properties & CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE);
|
|
|
+
|
|
|
+ /*********************
|
|
|
+ * Insert event
|
|
|
+ *********************/
|
|
|
+
|
|
|
+ if (is_barrier)
|
|
|
+ cq->events = NULL;
|
|
|
+
|
|
|
+ /* Add event to the list of out-of-order events */
|
|
|
+ if (!in_order) {
|
|
|
+ task_event->next = cq->events;
|
|
|
+ task_event->prev = NULL;
|
|
|
+ if (cq->events != NULL)
|
|
|
+ cq->events->prev = task_event;
|
|
|
+ cq->events = task_event;
|
|
|
+ }
|
|
|
+
|
|
|
+ /* Register this event as last barrier */
|
|
|
+ if (is_barrier || in_order)
|
|
|
+ cq->barrier = task_event;
|
|
|
+
|
|
|
+ /* Add reference to the command queue */
|
|
|
+ gc_entity_store(&task_event->cq, cq);
|
|
|
+}
|
|
|
|
|
|
- /* Add event to the list of out-of-order events */
|
|
|
- if (!in_order) {
|
|
|
- ev->next = cq->events;
|
|
|
- ev->prev = NULL;
|
|
|
- if (cq->events != NULL)
|
|
|
- cq->events->prev = ev;
|
|
|
- cq->events = ev;
|
|
|
- }
|
|
|
+/**
|
|
|
+ * Return implicit and explicit dependencies for a task
|
|
|
+ * The command queue must be locked!
|
|
|
+ */
|
|
|
+void command_queue_dependencies(
|
|
|
+ cl_command_queue cq, /* Command queue */
|
|
|
+ char is_barrier, /* Is the task a barrier */
|
|
|
+ cl_int num_events, /* Number of explicit dependencies */
|
|
|
+ const cl_event events, /* Explicit dependencies */
|
|
|
+ cl_int * ret_num_events, /* Returned number of dependencies */
|
|
|
+ cl_event ** ret_events /* Returned dependencies */
|
|
|
+) {
|
|
|
+ cl_int implicit_num_events;
|
|
|
+ cl_event * implicit_events;
|
|
|
+
|
|
|
+ /* Implicit dependencies */
|
|
|
+ command_queue_dependencies_implicit(cq, is_barrier, &implicit_num_events, &implicit_events);
|
|
|
+
|
|
|
+ /* Explicit dependencies */
|
|
|
+ cl_int ndeps = implicit_num_events + num_events;
|
|
|
+ cl_event * evs = malloc(sizeof(cl_event) * ndeps);
|
|
|
+ memcpy(evs, implicit_events, sizeof(cl_event) * implicit_num_events);
|
|
|
+ memcpy(&evs[implicit_num_events], events, sizeof(cl_event) * num_events);
|
|
|
+
|
|
|
+ *ret_num_events = ndeps;
|
|
|
+ *ret_events = evs;
|
|
|
+}
|
|
|
|
|
|
- /* Register this event as last barrier */
|
|
|
- if (barrier || in_order)
|
|
|
- cq->barrier = ev;
|
|
|
+/**
|
|
|
+ * Enqueue the given task and put ev into the command queue.
|
|
|
+ */
|
|
|
+void command_queue_enqueue(
|
|
|
+ cl_command_queue cq, /* Command queue */
|
|
|
+ cl_event ev, /* Event triggered on task completion (can be NULL if task event should be used)*/
|
|
|
+ cl_int is_barrier, /* True if the task acts as a barrier */
|
|
|
+ cl_int num_events, /* Number of dependencies */
|
|
|
+ const cl_event * events, /* Dependencies */
|
|
|
+ cl_int * ret_num_events, /* Returned number of events */
|
|
|
+ cl_event ** ret_events /* Returned events */
|
|
|
+ ) {
|
|
|
|
|
|
- /* Unlock command queue */
|
|
|
- pthread_spin_unlock(&cq->spin);
|
|
|
+ /* Lock command queue */
|
|
|
+ pthread_spin_lock(&cq->spin);
|
|
|
|
|
|
- /* Add reference to the command queue */
|
|
|
- gc_entity_store(&ev->cq, cq);
|
|
|
+ command_queue_dependencies(cq, is_barrier, num_events, events, ret_num_events, ret_events);
|
|
|
|
|
|
- /* Submit task */
|
|
|
- gc_entity_retain(task_event(task));
|
|
|
- int ret = starpu_task_submit(task);
|
|
|
- if (ret != 0)
|
|
|
- DEBUG_ERROR("Unable to submit a task. Error %d\n", ret);
|
|
|
+ command_queue_insert(cq, ev, is_barrier);
|
|
|
|
|
|
- return CL_SUCCESS;
|
|
|
+ /* Unlock command queue */
|
|
|
+ pthread_spin_unlock(&cq->spin);
|
|
|
}
|
|
|
|
|
|
-cl_int command_queue_enqueue(cl_command_queue cq, starpu_task *task, cl_int barrier, cl_int num_events, const cl_event * events) {
|
|
|
- return command_queue_enqueue_fakeevent(cq, task, barrier, num_events, events, NULL);
|
|
|
-}
|
|
|
|
|
|
+cl_event command_queue_barrier(cl_command_queue cq) {
|
|
|
+
|
|
|
+ cl_int ndeps;
|
|
|
+ cl_event *deps;
|
|
|
|
|
|
-cl_event enqueueBarrier(cl_command_queue cq) {
|
|
|
+ //CL_COMMAND_MARKER has been chosen as CL_COMMAND_BARRIER doesn't exist
|
|
|
+ starpu_task * task = task_create(CL_COMMAND_MARKER);
|
|
|
|
|
|
- //CL_COMMAND_MARKER has been chosen as CL_COMMAND_BARRIER doesn't exist
|
|
|
- starpu_task * task = task_create(CL_COMMAND_MARKER);
|
|
|
+ DEBUG_MSG("Submitting barrier task (event %d)\n", task->tag_id);
|
|
|
+ command_queue_enqueue(cq, task_event(task), 1, 0, NULL, &ndeps, &deps);
|
|
|
|
|
|
- DEBUG_MSG("Submitting barrier task (event %d)\n", task->tag_id);
|
|
|
- command_queue_enqueue(cq, task, 1, 0, NULL);
|
|
|
+ task_submit(task, ndeps, deps);
|
|
|
|
|
|
- return task_event(task);
|
|
|
+ return task_event(task);
|
|
|
}
|