static void create_task_12(starpu_data_handle *dataAp, unsigned nblocks, unsigned k, unsigned j, starpu_data_handle (* get_block)(starpu_data_handle *, unsigned, unsigned, unsigned)) { // printf("task 12 k,i = %d,%d TAG = %llx\n", k,i, TAG12(k,i)); struct starpu_task *task = create_task(); task->cl = &cl12; task->cl_arg = NULL; /* which sub-data is manipulated ? */ task->buffers[0].handle = get_block(dataAp, nblocks, k, k); task->buffers[0].mode = STARPU_R; task->buffers[1].handle = get_block(dataAp, nblocks, j, k); task->buffers[1].mode = STARPU_RW; if (!no_prio && (j == k+1)) { task->priority = STARPU_MAX_PRIO; } /* enforce dependencies ... */ #if 0 starpu_tag_declare_deps(TAG12(k, i), 1, PIVOT(k, i)); #endif if (k > 0) { starpu_task_declare_deps_array(task, 1, &EVENT(k,k)); starpu_task_declare_deps_array(task, 1, &EVENT(k,j)); } else { starpu_task_declare_deps_array(task, 1, &EVENT(k,k)); } starpu_task_submit(task, NULL); }
static void create_task_pivot(starpu_data_handle *dataAp, unsigned nblocks, struct piv_s *piv_description, unsigned k, unsigned i, starpu_data_handle (* get_block)(starpu_data_handle *, unsigned, unsigned, unsigned)) { struct starpu_task *task = create_task(); task->cl = &cl_pivot; /* which sub-data is manipulated ? */ task->buffers[0].handle = get_block(dataAp, nblocks, k, i); task->buffers[0].mode = STARPU_RW; task->cl_arg = &piv_description[k]; /* this is an important task */ if (!no_prio && (i == k+1)) task->priority = STARPU_MAX_PRIO; /* enforce dependencies ... */ if (k == 0) { starpu_task_declare_deps_array(task, 1, &EVENT(k,k)); } else { if (i > k) { starpu_event deps[] = {EVENT(k,k), EVENT(i,k)}; starpu_task_declare_deps_array(task, 2, deps); } else { starpu_task_declare_deps_array(task, 1, &EVENT(k,k)); unsigned ind; for (ind = k + 1; ind < nblocks; ind++) starpu_task_declare_deps_array(task, 1, &EVENT(ind,k)); } } starpu_task_submit(task, &PIVOT(i)); }
int main(int argc, char **argv) { int ret; unsigned loop, nloops=NLOOPS; ret = starpu_initialize(NULL, &argc, &argv); if (ret == -ENODEV) return STARPU_TEST_SKIPPED; STARPU_CHECK_RETURN_VALUE(ret, "starpu_init"); struct starpu_task *taskA, *taskB; for (loop = 0; loop < nloops; loop++) { taskA = create_dummy_task(); taskB = create_dummy_task(); /* By default, dynamically allocated tasks are destroyed at * termination, we cannot declare a dependency on something * that does not exist anymore. */ taskA->destroy = 0; taskA->synchronous = 1; ret = starpu_task_submit(taskA); if (ret == -ENODEV) goto enodev; STARPU_CHECK_RETURN_VALUE(ret, "starpu_task_submit"); starpu_task_declare_deps_array(taskB, 1, &taskA); taskB->synchronous = 1; ret = starpu_task_submit(taskB); if (ret == -ENODEV) goto enodev; STARPU_CHECK_RETURN_VALUE(ret, "starpu_task_submit"); starpu_task_destroy(taskA); } ret = starpu_task_wait_for_all(); STARPU_CHECK_RETURN_VALUE(ret, "starpu_task_wait_for_all"); starpu_shutdown(); return EXIT_SUCCESS; enodev: fprintf(stderr, "WARNING: No one can execute this task\n"); /* yes, we do not perform the computation but we did detect that no one * could perform the kernel, so this is not an error from StarPU */ starpu_shutdown(); return STARPU_TEST_SKIPPED; }
static void create_task_22(starpu_data_handle *dataAp, unsigned nblocks, unsigned k, unsigned i, unsigned j, starpu_data_handle (* get_block)(starpu_data_handle *, unsigned, unsigned, unsigned)) { // printf("task 22 k,i,j = %d,%d,%d TAG = %llx\n", k,i,j, TAG22(k,i,j)); struct starpu_task *task = create_task(); task->cl = &cl22; task->cl_arg = NULL; /* which sub-data is manipulated ? */ task->buffers[0].handle = get_block(dataAp, nblocks, k, i); /* produced by TAG21(k, i) */ task->buffers[0].mode = STARPU_R; task->buffers[1].handle = get_block(dataAp, nblocks, j, k); /* produced by TAG12(k, j) */ task->buffers[1].mode = STARPU_R; task->buffers[2].handle = get_block(dataAp, nblocks, j, i); /* produced by TAG22(k-1, i, j) */ task->buffers[2].mode = STARPU_RW; if (!no_prio && (i == k + 1) && (j == k +1) ) { task->priority = STARPU_MAX_PRIO; } /* enforce dependencies ... */ if (k > 0) { starpu_event deps[] = {EVENT(i,j), EVENT(k,j), EVENT(i,k)}; starpu_task_declare_deps_array(task, 3, deps); starpu_event_release(EVENT(i,j)); } else { starpu_event deps[] = {EVENT(k,j), EVENT(i,k)}; starpu_task_declare_deps_array(task, 2, deps); } starpu_task_submit(task, &EVENT(i,j)); }
int _starpu_data_cpy(starpu_data_handle_t dst_handle, starpu_data_handle_t src_handle, int asynchronous, void (*callback_func)(void*), void *callback_arg, int reduction, struct starpu_task *reduction_dep_task) { struct starpu_task *task = starpu_task_create(); STARPU_ASSERT(task); task->name = "data_cpy"; struct _starpu_job *j = _starpu_get_job_associated_to_task(task); if (reduction) { j->reduction_task = reduction; if (reduction_dep_task) starpu_task_declare_deps_array(task, 1, &reduction_dep_task); } task->cl = ©_cl; unsigned *interface_id = malloc(sizeof(*interface_id)); *interface_id = dst_handle->ops->interfaceid; task->cl_arg = interface_id; task->cl_arg_size = sizeof(*interface_id); task->cl_arg_free = 1; task->callback_func = callback_func; task->callback_arg = callback_arg; STARPU_TASK_SET_HANDLE(task, dst_handle, 0); STARPU_TASK_SET_HANDLE(task, src_handle, 1); task->synchronous = !asynchronous; int ret = _starpu_task_submit_internally(task); STARPU_ASSERT(!ret); return 0; }
/* NB : handle->sequential_consistency_mutex must be hold by the caller */ void _starpu_detect_implicit_data_deps_with_handle(struct starpu_task *pre_sync_task, struct starpu_task *post_sync_task, starpu_data_handle handle, starpu_access_mode mode) { STARPU_ASSERT(!(mode & STARPU_SCRATCH)); if (handle->sequential_consistency) { #ifdef STARPU_USE_FXT /* In case we are generating the DAG, we add an implicit * dependency between the pre and the post sync tasks in case * they are not the same. */ if (pre_sync_task != post_sync_task) { starpu_job_t pre_sync_job = _starpu_get_job_associated_to_task(pre_sync_task); starpu_job_t post_sync_job = _starpu_get_job_associated_to_task(post_sync_task); STARPU_TRACE_GHOST_TASK_DEPS(pre_sync_job->job_id, post_sync_job->job_id); } #endif starpu_access_mode previous_mode = handle->last_submitted_mode; if (mode & STARPU_W) { _STARPU_DEP_DEBUG("W %p\n", handle); if (previous_mode & STARPU_W) { _STARPU_DEP_DEBUG("WAW %p\n", handle); /* (Read) Write */ /* This task depends on the previous writer */ if (handle->last_submitted_writer) { starpu_job_t job = _starpu_get_job_associated_to_task(handle->last_submitted_writer); starpu_task_declare_deps_array(pre_sync_task, 1, &job->event); } #ifdef STARPU_USE_FXT /* If there is a ghost writer instead, we * should declare a ghost dependency here, and * invalidate the ghost value. */ if (handle->last_submitted_ghost_writer_id_is_valid) { starpu_job_t post_sync_job = _starpu_get_job_associated_to_task(post_sync_task); STARPU_TRACE_GHOST_TASK_DEPS(handle->last_submitted_ghost_writer_id, post_sync_job->job_id); handle->last_submitted_ghost_writer_id_is_valid = 0; } #endif handle->last_submitted_writer = post_sync_task; } else { /* The task submitted previously were in read-only * mode: this task must depend on all those read-only * tasks and we get rid of the list of readers */ _STARPU_DEP_DEBUG("WAR %p\n", handle); /* Count the readers */ unsigned nreaders = 0; struct starpu_task_wrapper_list *l; l = handle->last_submitted_readers; while (l) { nreaders++; l = l->next; } _STARPU_DEP_DEBUG("%d readers\n", nreaders); starpu_event events[nreaders]; unsigned i = 0; l = handle->last_submitted_readers; while (l) { STARPU_ASSERT(l->task); starpu_job_t job = _starpu_get_job_associated_to_task(l->task); events[i++] = job->event; struct starpu_task_wrapper_list *prev = l; l = l->next; free(prev); } #ifdef STARPU_USE_FXT /* Declare all dependencies with ghost readers */ starpu_job_t post_sync_job = _starpu_get_job_associated_to_task(post_sync_task); struct starpu_jobid_list *ghost_readers_id = handle->last_submitted_ghost_readers_id; while (ghost_readers_id) { unsigned long id = ghost_readers_id->id; STARPU_TRACE_GHOST_TASK_DEPS(id, post_sync_job->job_id); struct starpu_jobid_list *prev = ghost_readers_id; ghost_readers_id = ghost_readers_id->next; free(prev); } handle->last_submitted_ghost_readers_id = NULL; #endif handle->last_submitted_readers = NULL; handle->last_submitted_writer = post_sync_task; starpu_task_declare_deps_array(pre_sync_task, nreaders, events); } } else { _STARPU_DEP_DEBUG("R %p\n", handle); /* Add a reader */ STARPU_ASSERT(pre_sync_task); STARPU_ASSERT(post_sync_task); /* Add this task to the list of readers */ struct starpu_task_wrapper_list *link = malloc(sizeof(struct starpu_task_wrapper_list)); link->task = post_sync_task; link->next = handle->last_submitted_readers; handle->last_submitted_readers = link; /* This task depends on the previous writer if any */ if (handle->last_submitted_writer) { _STARPU_DEP_DEBUG("RAW %p\n", handle); starpu_job_t job = _starpu_get_job_associated_to_task(handle->last_submitted_writer); starpu_task_declare_deps_array(pre_sync_task, 1, &job->event); } #ifdef STARPU_USE_FXT /* There was perhaps no last submitted writer but a * ghost one, we should report that here, and keep the * ghost writer valid */ if (handle->last_submitted_ghost_writer_id_is_valid) { starpu_job_t post_sync_job = _starpu_get_job_associated_to_task(post_sync_task); STARPU_TRACE_GHOST_TASK_DEPS(handle->last_submitted_ghost_writer_id, post_sync_job->job_id); } #endif } handle->last_submitted_mode = mode; } }