Example #1
0
int main(int argc, char **argv)
{
	double timing;
	struct timeval start;
	struct timeval end;

	starpu_init(NULL);

	fprintf(stderr, "#tasks : %d\n", ntasks);

	unsigned i;
	for (i = 0; i < ntasks; i++)
	{
		struct starpu_task *task = starpu_task_create();

		/* We check if the function is valid from the codelet or from
		 * the callback */
		task->cl = &dummy_cl;
		task->cl_arg = task;

		task->callback_func = check_task_callback;
		task->callback_arg = task;

		int ret = starpu_task_submit(task, NULL);
		STARPU_ASSERT(!ret);
	}

	starpu_task_wait_for_all();
	
	fprintf(stderr, "#empty tasks : %d\n", ntasks);

	/* We repeat the same experiment with null codelets */

	for (i = 0; i < ntasks; i++)
	{
		struct starpu_task *task = starpu_task_create();

		task->cl = NULL;

		/* We check if the function is valid from the callback */
		task->callback_func = check_task_callback;
		task->callback_arg = task;

		int ret = starpu_task_submit(task, NULL);
		STARPU_ASSERT(!ret);
	}

	starpu_task_wait_for_all();

	starpu_shutdown();

	return 0;
}
Example #2
0
/* The data must be released by calling starpu_data_release later on */
int starpu_data_acquire_cb(starpu_data_handle handle,
		starpu_access_mode mode, void (*callback)(void *), void *arg)
{
	STARPU_ASSERT(handle);

	struct user_interaction_wrapper *wrapper = malloc(sizeof(struct user_interaction_wrapper));
	STARPU_ASSERT(wrapper);

	wrapper->handle = handle;
	wrapper->mode = mode;
	wrapper->callback = callback;
	wrapper->callback_arg = arg;
	PTHREAD_COND_INIT(&wrapper->cond, NULL);
	PTHREAD_MUTEX_INIT(&wrapper->lock, NULL);
	wrapper->finished = 0;

//TODO: instead of having the is_prefetch argument, _starpu_fetch_data shoud consider two flags: async and detached
	_starpu_spin_lock(&handle->header_lock);
	handle->per_node[0].refcnt++;
	_starpu_spin_unlock(&handle->header_lock);

	PTHREAD_MUTEX_LOCK(&handle->sequential_consistency_mutex);
	int sequential_consistency = handle->sequential_consistency;
	if (sequential_consistency)
	{
		wrapper->pre_sync_task = starpu_task_create();
		wrapper->pre_sync_task->callback_func = starpu_data_acquire_cb_pre_sync_callback;
		wrapper->pre_sync_task->callback_arg = wrapper;

		wrapper->post_sync_task = starpu_task_create();

#ifdef STARPU_USE_FXT
                starpu_job_t job = _starpu_get_job_associated_to_task(wrapper->pre_sync_task);
                job->model_name = "acquire_cb_pre";
                job = _starpu_get_job_associated_to_task(wrapper->post_sync_task);
                job->model_name = "acquire_cb_post";
#endif

		_starpu_detect_implicit_data_deps_with_handle(wrapper->pre_sync_task, wrapper->post_sync_task, handle, mode);
		PTHREAD_MUTEX_UNLOCK(&handle->sequential_consistency_mutex);

		/* TODO detect if this is superflous */
		int ret = starpu_task_submit(wrapper->pre_sync_task, NULL);
		STARPU_ASSERT(!ret);
	}
	else {
		PTHREAD_MUTEX_UNLOCK(&handle->sequential_consistency_mutex);

		starpu_data_acquire_cb_pre_sync_callback(wrapper);
	}

	return 0;
}
static int create_task_grid(unsigned piter)
{
	unsigned i, j;
	int ret;

/*	FPRINTF(stderr, "start iter %d...\n", piter); */
	callback_cnt = (ni*nj);

	/* create non-entry tasks */
	for (j = 0; j < nj; j++)
	for (i = 1; i < ni; i++)
	{
		/* create a new task */
		struct starpu_task *task = starpu_task_create();
		task->callback_func = callback_cpu;
		/* jb->argcb = &coords[i][j]; */
		task->cl = &cl;
		task->cl_arg = NULL;

		task->use_tag = 1;
		task->tag_id = TAG(i, j, piter);

		/* express deps : (i,j) depends on (i-1, j-1) & (i-1, j+1) */
		express_deps(i, j, piter);

		ret = starpu_task_submit(task);
		if (ret == -ENODEV) return 77;
		STARPU_CHECK_RETURN_VALUE(ret, "starpu_task_submit");
	}

	/* create entry tasks */
	for (j = 0; j < nj; j++)
	{
		/* create a new task */
		struct starpu_task *task = starpu_task_create();
		task->callback_func = callback_cpu;
		task->cl = &cl;
		task->cl_arg = NULL;

		task->use_tag = 1;
		/* this is an entry task */
		task->tag_id = TAG(0, j, piter);

		ret = starpu_task_submit(task);
		if (ret == -ENODEV) return 77;
		STARPU_CHECK_RETURN_VALUE(ret, "starpu_task_submit");
	}
	return 0;
}
static int create_task_11_pivot(starpu_data_handle_t *dataAp, unsigned nblocks,
				unsigned k, struct piv_s *piv_description,
				starpu_data_handle_t (* get_block)(starpu_data_handle_t *, unsigned, unsigned, unsigned))
{
	int ret;

	struct starpu_task *task = starpu_task_create();

	task->cl = &cl11_pivot;

	task->cl_arg = &piv_description[k];

	/* which sub-data is manipulated ? */
	task->handles[0] = get_block(dataAp, nblocks, k, k);

	task->tag_id = TAG11(k);

	/* this is an important task */
	if (!no_prio)
		task->priority = STARPU_MAX_PRIO;

	ret = starpu_task_submit(task);
	if (ret != -ENODEV) STARPU_CHECK_RETURN_VALUE(ret, "starpu_task_submit");
	return ret;
}
static void create_task_grid(unsigned iter)
{
	unsigned i;

	FPRINTF(stderr, "init iter %u ni %u...\n", iter, ni);

	for (i = 0; i < ni; i++)
	{
		/* create a new task */
		struct starpu_task *task = tasks[iter][i] = starpu_task_create();

		task->cl = &cl;
		/* task->cl_arg = (void*)(uintptr_t) (i | (iter << 16)); */

		task->use_tag = 1;
		task->tag_id = TAG(i, iter);

		task->detach = 1;
		task->destroy = 0;

		if (i != 0)
			starpu_tag_declare_deps(TAG(i,iter), 1, TAG(i-1,iter));
	}

}
Example #6
0
static struct starpu_task *create_task()
{
   struct starpu_task *task = starpu_task_create();
   task->cl_arg = NULL;

	return task;
}
Example #7
0
int main(int argc, char ** argv) {
  starpu_init(NULL);

  struct starpu_codelet cl = {
    .where = STARPU_CPU,
    .cpu_funcs[0] = cpu_func,
    .cpu_funcs[1] = NULL,
    .nbuffers = 0
  };

  struct starpu_task* task = starpu_task_create();

  // pointer to the codelet
  task->cl = &cl;

  struct params params = { 1, 2.0f };
  task->cl_arg = &params;
  task->cl_arg_size = sizeof(params);

  task->callback_func = callback_func;
  task->callback_arg  = (void*) 0x42;

  // starpu_task_submit will be a blocking call
  task->synchronous = 1;

  // submit the task to StarPU
  starpu_task_submit(task);

  // terminate StarPU
  starpu_shutdown();

  return 0;
}
int main(int argc, char **argv)
{
	int ntasks = NTASKS;
	int ret;
	struct starpu_conf conf;

	starpu_conf_init(&conf);
	conf.sched_policy = &dummy_sched_policy,
	ret = starpu_init(&conf);
	if (ret == -ENODEV)
		return 77;
	STARPU_CHECK_RETURN_VALUE(ret, "starpu_init");

#ifdef STARPU_QUICK_CHECK
	ntasks /= 100;
#endif

	int i;
	for (i = 0; i < ntasks; i++)
	{
		struct starpu_task *task = starpu_task_create();

		task->cl = &dummy_codelet;
		task->cl_arg = NULL;

		ret = starpu_task_submit(task);
		STARPU_CHECK_RETURN_VALUE(ret, "starpu_task_submit");
	}

	starpu_task_wait_for_all();

	starpu_shutdown();

	return 0;
}
static int
create_and_submit_task(unsigned int dev)
{
	struct starpu_task *task = starpu_task_create();
	switch (dev)
	{
#ifdef STARPU_USE_CPU
		case STARPU_CPU:
			task->cl = &cpu_cl;
			break;
#endif
#ifdef STARPU_USE_CUDA
		case STARPU_CUDA:
			task->cl = &cuda_cl;
			break;
#endif
#ifdef STARPU_USE_OPENCL
		case STARPU_OPENCL:
			task->cl = &opencl_cl;
			break;
#endif
		default:
			assert(0);
	}
	task->synchronous = 1;
	task->handles[0] = array_of_structs_handle;
	task->cl_arg = NULL;
	task->cl_arg_size = 0;
	return starpu_task_submit(task);
}
Example #10
0
/* If sequential consistency mode is enabled, this function blocks until the
 * handle is available in the requested access mode. */
int _starpu_data_wait_until_available(starpu_data_handle handle, starpu_access_mode mode)
{
	/* If sequential consistency is enabled, wait until data is available */
	PTHREAD_MUTEX_LOCK(&handle->sequential_consistency_mutex);
	int sequential_consistency = handle->sequential_consistency;
	if (sequential_consistency)
	{
		struct starpu_task *sync_task;
		sync_task = starpu_task_create();
		sync_task->destroy = 1;

		/* It is not really a RW access, but we want to make sure that
		 * all previous accesses are done */
		_starpu_detect_implicit_data_deps_with_handle(sync_task, sync_task, handle, mode);
		PTHREAD_MUTEX_UNLOCK(&handle->sequential_consistency_mutex);

		/* TODO detect if this is superflous */
      starpu_event event;
		int ret = starpu_task_submit(sync_task, &event);
		STARPU_ASSERT(!ret);
      starpu_event_wait(event);
      starpu_event_release(event);
	}
	else {
		PTHREAD_MUTEX_UNLOCK(&handle->sequential_consistency_mutex);
	}

	return 0;
}
int main(int argc, char **argv)
{
	int ret;

	/* initialize StarPU */
	ret = starpu_init(NULL);
	STARPU_CHECK_RETURN_VALUE(ret, "starpu_init");

	struct starpu_task *task = starpu_task_create();

	task->cl = &cl; /* Pointer to the codelet defined above */

	struct params params = { 1, 2.0f };
	task->cl_arg = &params;
	task->cl_arg_size = sizeof(params);

	task->callback_func = callback_func;
	task->callback_arg = (void*) (uintptr_t) 0x42;

	/* starpu_task_submit will be a blocking call */
	task->synchronous = 1;

	/* submit the task to StarPU */
	ret = starpu_task_submit(task);
	STARPU_CHECK_RETURN_VALUE(ret, "starpu_task_submit");

	/* terminate StarPU */
	starpu_shutdown();

	return 0;
}
Example #12
0
/* R(z) = R(z+d) = local, just call the save kernel */
static void create_task_save_local(unsigned iter, unsigned z, int dir, int local_rank)
{
	struct starpu_task *save_task = starpu_task_create();
	struct block_description *descr = get_block_description(z);

	save_task->cl = (dir == -1)?&save_cl_bottom:&save_cl_top;
	save_task->cl_arg = descr;

	/* Saving our border... */
	save_task->handles[0] = descr->layers_handle[0];
	save_task->handles[1] = descr->layers_handle[1];

	/* ... to the neighbour's copy */
	struct block_description *neighbour = descr->boundary_blocks[(1+dir)/2];
	save_task->handles[2] = neighbour->boundaries_handle[(1-dir)/2][0];
	save_task->handles[3] = neighbour->boundaries_handle[(1-dir)/2][1];

	/* Bind */
	if (iter <= BIND_LAST)
		save_task->execute_on_a_specific_worker = get_bind_tasks();
	save_task->workerid = descr->preferred_worker;

	int ret = starpu_task_submit(save_task);
	if (ret)
	{
		FPRINTF(stderr, "Could not submit task save: %d\n", ret);
		STARPU_ABORT();
	}
}
int main(int argc, char **argv)
{
	int ret;

	ret = starpu_initialize(NULL, &argc, &argv);
	if (ret == -ENODEV) return STARPU_TEST_SKIPPED;
	STARPU_CHECK_RETURN_VALUE(ret, "starpu_init");

	starpu_malloc((void**)&data, sizeof(*data));
	*data = 42;

	/* register a piece of data */
	starpu_vector_data_register(&handle, STARPU_MAIN_RAM, (uintptr_t)data,
						1, sizeof(unsigned));

	struct starpu_task *task = starpu_task_create();

	task->cl = &wrong_codelet;

	task->handles[0] = handle;

	task->use_tag = 1;
	task->tag_id = TAG;

	task->callback_func = wrong_callback;
	task->detach = 0;

	ret = starpu_task_submit(task);
	if (ret == -ENODEV) goto enodev;
	STARPU_CHECK_RETURN_VALUE(ret, "starpu_task_submit");

	ret = starpu_tag_wait(TAG);
	STARPU_CHECK_RETURN_VALUE(ret, "starpu_tag_wait");

	/* This call is valid as it is done by the application outside a
	 * callback */
	ret = starpu_data_acquire(handle, STARPU_RW);
	STARPU_CHECK_RETURN_VALUE(ret, "starpu_data_acquire");

	starpu_data_release(handle);

	ret = starpu_task_wait(task);
	STARPU_CHECK_RETURN_VALUE(ret, "starpu_task_wait");
	starpu_data_unregister(handle);

	starpu_free(data);

	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;
}
Example #14
0
static int
run(struct starpu_sched_policy *policy)
{
    int ret;
    struct starpu_conf conf;
    int i;

    starpu_conf_init(&conf);
    conf.sched_policy = policy;
    ret = starpu_init(&conf);
    if (ret != 0)
        exit(STARPU_TEST_SKIPPED);
    starpu_profiling_status_set(1);

    struct starpu_codelet clA =
    {
        .cpu_funcs = {A},
        .nbuffers = 0
    };

    struct starpu_codelet clB =
    {
        .cpu_funcs = {B},
        .nbuffers = 0
    };

    starpu_srand48(0);

    for (i = 0; i < NTASKS; i++)
    {
        struct starpu_task *task = starpu_task_create();

        if (((int)(starpu_drand48()*2))%2)
        {
            task->cl = &clA;
            task->priority=STARPU_MIN_PRIO;
        }
        else
        {
            task->cl = &clB;
            task->priority=STARPU_MAX_PRIO;
        }
        task->detach=1;
        ret = starpu_task_submit(task);
        if (ret == -ENODEV) goto enodev;
        STARPU_CHECK_RETURN_VALUE(ret, "starpu_task_submit");
    }

    starpu_task_wait_for_all();
    FPRINTF(stdout,"\n");

    starpu_shutdown();
    return 0;

enodev:
    starpu_shutdown();
    return -ENODEV;
}
static struct starpu_task *create_task(starpu_tag_t id)
{
	struct starpu_task *task = starpu_task_create();
		task->cl_arg = NULL;
		task->use_tag = 1;
		task->tag_id = id;

	return task;
}
static struct starpu_task *create_dummy_task(void)
{
	struct starpu_task *task = starpu_task_create();

	task->cl = &dummy_codelet;
	task->cl_arg = NULL;

	return task;
}
void increment_token(void)
{
	struct starpu_task *task = starpu_task_create();

	task->cl = &increment_cl;
	task->handles[0] = token_handle;

	int ret = starpu_task_submit(task);
	STARPU_CHECK_RETURN_VALUE(ret, "starpu_task_submit");
}
Example #18
0
void callback_func(void *callback_arg)
{
	int ret;

	struct starpu_task *task = starpu_task_create();
	task->cl = &cl;
	task->handles[0] = handle;

	ret = starpu_task_submit(task);
	STARPU_CHECK_RETURN_VALUE(ret, "starpu_task_submit");
}
Example #19
0
void inject_one_task(void)
{
	struct starpu_task *task = starpu_task_create();

	task->cl = &dummy_codelet;
	task->cl_arg = NULL;
	task->callback_func = NULL;
	task->synchronous = 1;

	starpu_task_submit(task, NULL);
}
Example #20
0
void call() {
  struct starpu_task *t = starpu_task_create();
  t->cl = &cl;

  int param = 1;
  t->cl_arg = &param;
  t->cl_arg_size = sizeof(int);

  t->synchronous = 1;

  starpu_task_submit(t);
}
Example #21
0
int main(int argc, char **argv)
{
	starpu_init(NULL);

	starpu_data_malloc_pinned_if_possible((void **)&v, VECTORSIZE*sizeof(unsigned));
	starpu_vector_data_register(&v_handle, 0, (uintptr_t)v, VECTORSIZE, sizeof(unsigned));

	unsigned nworker = starpu_worker_get_count();

	cnt = nworker*N;

	unsigned iter, worker;
	for (iter = 0; iter < N; iter++)
	{
		for (worker = 0; worker < nworker; worker++)
		{
			/* synchronous prefetch */
			unsigned node = starpu_worker_get_memory_node(worker);
			starpu_data_prefetch_on_node(v_handle, node, 0);

			/* execute a task */
			struct starpu_task *task = starpu_task_create();
			task->cl = &cl;

			task->buffers[0].handle = v_handle;
			task->buffers[0].mode = select_random_mode();

			task->callback_func = callback;
			task->callback_arg = NULL;

			task->synchronous = 1;

			int ret = starpu_task_submit(task, NULL);
			if (ret == -ENODEV)
				goto enodev;
		}
	}

	pthread_mutex_lock(&mutex);
	if (!finished)
		pthread_cond_wait(&cond, &mutex);
	pthread_mutex_unlock(&mutex);

	starpu_shutdown();

	return 0;

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 */
	return 0;
}
static
int use_handle(starpu_data_handle_t handle)
{
	int ret;
	struct starpu_task *task;

	task = starpu_task_create();
		task->cl = &cl;
		task->handles[0] = handle;

	ret = starpu_task_submit(task);
	return ret;
}
Example #23
0
int use_handle(starpu_data_handle handle)
{
	int ret;
	struct starpu_task *task;

	task = starpu_task_create();
		task->cl = &cl;
		task->buffers[0].handle = handle;
		task->buffers[0].mode = STARPU_RW;

	ret = starpu_task_submit(task, NULL);

	return ret;
}
Example #24
0
static void launch_codelets(void)
{
#ifdef STARPU_USE_FXT
	_starpu_fxt_register_thread(0);
#endif
	/* partition the work into slices */
	unsigned taskx, tasky;

	srand(time(NULL));

	/* should we use a single performance model for all archs and use an
 	 * acceleration factor ? */
	if (use_common_model) {
		cl.model = &sgemm_model_common;
	}
	else {
		cl.model = &sgemm_model;
	}

	for (taskx = 0; taskx < nslicesx; taskx++) 
	{
		for (tasky = 0; tasky < nslicesy; tasky++)
		{
			/* A B[task] = C[task] */
			struct starpu_task *task = starpu_task_create();

			task->cl = &cl;
			task->cl_arg = &conf;
			task->cl_arg_size = sizeof(struct block_conf);

			task->callback_func = callback_func;
			task->callback_arg = NULL;

			starpu_tag_t tag = TAG(taskx, tasky); 

			task->use_tag = 1;
			task->tag_id = tag;

			task->buffers[0].handle = starpu_data_get_sub_data(A_handle, 1, tasky);
			task->buffers[0].mode = STARPU_R;
			task->buffers[1].handle = starpu_data_get_sub_data(B_handle, 1, taskx);
			task->buffers[1].mode = STARPU_R;
			task->buffers[2].handle = 
				starpu_data_get_sub_data(C_handle, 2, taskx, tasky);
			task->buffers[2].mode = STARPU_RW;

			starpu_task_submit(task, NULL);
		}
	}
}
static struct starpu_task *create_dummy_task(starpu_tag_t tag)
{
	struct starpu_task *task = starpu_task_create();

	task->cl = &dummy_codelet;
	task->cl_arg = NULL;
	task->callback_func = callback;
	task->callback_arg = (void *)tag;

	task->use_tag = 1;
	task->tag_id = tag;

	return task;
}
Example #26
0
	static inline starpu_task* spu_task_decode_siho(SPU_Decoder_SIHO<B,R> *decoder, starpu_data_handle_t &in_data,
	                                                                                starpu_data_handle_t &out_data)
	{
		auto task = starpu_task_create();

		task->name        = "dec::decode_siho";
		task->cl          = &SPU_Decoder_SIHO<B,R>::spu_cl_decode_siho;
		task->cl_arg      = (void*)(decoder);
		task->cl_arg_size = sizeof(*decoder);
		task->handles[0]  = in_data;
		task->handles[1]  = out_data;

		return task;
	}
Example #27
0
int main(int argc, char **argv)
{
	double timing;
	struct timeval start;
	struct timeval end;

	parse_args(argc, argv);

	starpu_init(NULL);

	fprintf(stderr, "#tasks : %d\n", ntasks);

	gettimeofday(&start, NULL);

	unsigned i;
	for (i = 0; i < ntasks; i++)
	{
		struct starpu_task *task = starpu_task_create();

		task->cl = &dummy_codelet;
		task->cl_arg = NULL;
		task->callback_func = NULL;
		task->callback_arg = NULL;

		task->destroy = 0;
		
      starpu_event event;
		int ret = starpu_task_submit(task, &event);
		STARPU_ASSERT(!ret);

		ret = starpu_event_wait(event);
		STARPU_ASSERT(!ret);

      starpu_event_release(event);

		starpu_task_destroy(task);
	}

	gettimeofday(&end, NULL);

	timing = (double)((end.tv_sec - start.tv_sec)*1000000 + (end.tv_usec - start.tv_usec));

	fprintf(stderr, "Total: %lf secs\n", timing/1000000);
	fprintf(stderr, "Per task: %lf usecs\n", timing/ntasks);

	starpu_shutdown();

	return 0;
}
static
int inject_one_task(void)
{
    int ret;
    struct starpu_task *task = starpu_task_create();

    task->cl = &dummy_codelet;
    task->cl_arg = NULL;
    task->callback_func = NULL;
    task->synchronous = 1;

    ret = starpu_task_submit(task);
    return ret;

}
Example #29
0
int main(int argc, char **argv)
{
	int v=40;
	int ret;

	ret = starpu_init(NULL);
	if (ret == -ENODEV)
		return 77;
	STARPU_CHECK_RETURN_VALUE(ret, "starpu_init");

	starpu_variable_data_register(&handle, STARPU_MAIN_RAM, (uintptr_t)&v, sizeof(int));
	double *x = (double*)malloc(sizeof(double));

	struct starpu_task *task = starpu_task_create();
	task->cl = &cl;
	task->prologue_callback_func = callback_func;
	task->prologue_callback_arg = NULL;

	task->prologue_callback_pop_func = pop_prologue_callback_func;
	task->prologue_callback_pop_arg = (void*) 5;

	task->handles[0] = handle;

	ret = starpu_task_submit(task);
	if (ret == -ENODEV) goto enodev;
	STARPU_CHECK_RETURN_VALUE(ret, "starpu_task_submit");

	*x = -999.0;
	ret = starpu_task_insert(&cl,
				 STARPU_RW, handle,
				 STARPU_PROLOGUE_CALLBACK, prologue_callback_func,
				 STARPU_PROLOGUE_CALLBACK_ARG, x,
				 STARPU_PROLOGUE_CALLBACK_POP, pop_prologue_callback_func,
				 STARPU_PROLOGUE_CALLBACK_POP_ARG, 5,
				 0);
	if (ret == -ENODEV) goto enodev;
	STARPU_CHECK_RETURN_VALUE(ret, "starpu_task_insert");

	starpu_task_wait_for_all();

enodev:
	starpu_data_unregister(handle);
	free(x);
	FPRINTF(stderr, "v -> %d\n", v);
	starpu_shutdown();
	return (ret == -ENODEV) ? 77 : 0;
}
Example #30
0
void use_handle(starpu_data_handle handle)
{
	int ret;
	struct starpu_task *task;

	task = starpu_task_create();
		task->cl = &cl;
		task->buffers[0].handle = handle;
		task->buffers[0].mode = STARPU_RW;

	ret = starpu_task_submit(task, NULL);
	if (ret == -ENODEV)
	{
		/* No one can execute such a task, but that's not a failure
		 * of the test either. */
		exit(0);
	}
}