Browse Source

- implementation of omp's API functions (on-going work)

Olivier Aumage 11 years ago
parent
commit
001a552330

+ 3 - 1
include/starpu_openmp.h

@@ -30,15 +30,17 @@ enum starpu_omp_sched_value
 	starpu_omp_sched_dynamic   = 2,
 	starpu_omp_sched_guided    = 3,
 	starpu_omp_sched_auto      = 4,
+	starpu_omp_sched_runtime   = 5
 };
 
 enum starpu_omp_proc_bind_value
 {
+	starpu_omp_proc_bind_undefined  = -1,
 	starpu_omp_proc_bind_false  = 0,
 	starpu_omp_proc_bind_true   = 1,
 	starpu_omp_proc_bind_master = 2,
 	starpu_omp_proc_bind_close  = 3,
-	starpu_omp_proc_bind_spread = 4,
+	starpu_omp_proc_bind_spread = 4
 };
 
 struct starpu_omp_parallel_region_attr

+ 59 - 40
src/util/openmp_runtime_support.c

@@ -594,9 +594,10 @@ static void omp_initial_thread_exit()
 static void omp_initial_region_setup(void)
 {
 	omp_initial_thread_setup();
-	const int max_levels = _starpu_omp_initial_icv_values->max_active_levels_var;
+	const int max_active_levels = _starpu_omp_initial_icv_values->max_active_levels_var;
 	const int max_threads = (int)starpu_cpu_worker_get_count();
 	
+	/* implementation specific initial ICV values override */
 	if (_starpu_omp_initial_icv_values->nthreads_var[0] == 0)
 	{
 		_starpu_omp_initial_icv_values->nthreads_var[0] = max_threads;
@@ -605,7 +606,7 @@ static void omp_initial_region_setup(void)
 	else
 	{
 		int i;
-		for (i = 0; i < max_levels; i++)
+		for (i = 0; i < max_active_levels; i++)
 		{
 			if (_starpu_omp_initial_icv_values->nthreads_var[i] == 0)
 				break;
@@ -615,8 +616,10 @@ static void omp_initial_region_setup(void)
 			}
 		}
 	}
+	_starpu_omp_initial_icv_values->dyn_var = 0;
+	_starpu_omp_initial_icv_values->nest_var = 0;
 
-	_global_state.initial_device->icvs.max_active_levels_var = max_levels;
+	_global_state.initial_device->icvs.max_active_levels_var = max_active_levels;
 	_global_state.initial_device->icvs.stacksize_var = _starpu_omp_initial_icv_values->stacksize_var;
 	_global_state.initial_device->icvs.wait_policy_var = _starpu_omp_initial_icv_values->wait_policy_var;
 
@@ -626,9 +629,9 @@ static void omp_initial_region_setup(void)
 	_global_state.initial_region->icvs.nest_var = _starpu_omp_initial_icv_values->nest_var;
 	if (_starpu_omp_initial_icv_values->nthreads_var[1] != 0)
 	{
-		_global_state.initial_region->icvs.nthreads_var = malloc((1+max_levels-_global_state.initial_region->level) * sizeof(*_global_state.initial_region->icvs.nthreads_var));
+		_global_state.initial_region->icvs.nthreads_var = malloc((1+max_active_levels-_global_state.initial_region->level) * sizeof(*_global_state.initial_region->icvs.nthreads_var));
 		int i,j;
-		for (i = _global_state.initial_region->level, j = 0; i < max_levels; i++, j++)
+		for (i = _global_state.initial_region->level, j = 0; i < max_active_levels; i++, j++)
 		{
 			_global_state.initial_region->icvs.nthreads_var[j] = _starpu_omp_initial_icv_values->nthreads_var[j];
 		}
@@ -641,25 +644,27 @@ static void omp_initial_region_setup(void)
 		_global_state.initial_region->icvs.nthreads_var[1] = 0;
 	}
 
-	if (_starpu_omp_initial_icv_values->bind_var[1] != starpu_omp_bind_undefined)
+	if (_starpu_omp_initial_icv_values->bind_var[1] != starpu_omp_proc_bind_undefined)
 	{
-		_global_state.initial_region->icvs.bind_var = malloc((1+max_levels-_global_state.initial_region->level) * sizeof(*_global_state.initial_region->icvs.bind_var));
+		_global_state.initial_region->icvs.bind_var = malloc((1+max_active_levels-_global_state.initial_region->level) * sizeof(*_global_state.initial_region->icvs.bind_var));
 		int i,j;
-		for (i = _global_state.initial_region->level, j = 0; i < max_levels; i++, j++)
+		for (i = _global_state.initial_region->level, j = 0; i < max_active_levels; i++, j++)
 		{
 			_global_state.initial_region->icvs.bind_var[j] = _starpu_omp_initial_icv_values->bind_var[j];
 		}
-		_global_state.initial_region->icvs.bind_var[j] = starpu_omp_bind_undefined;
+		_global_state.initial_region->icvs.bind_var[j] = starpu_omp_proc_bind_undefined;
 	}
 	else
 	{
 		_global_state.initial_region->icvs.bind_var = malloc(2 * sizeof(*_global_state.initial_region->icvs.bind_var));
 		_global_state.initial_region->icvs.bind_var[0] = _starpu_omp_initial_icv_values->bind_var[0];
-		_global_state.initial_region->icvs.bind_var[1] = starpu_omp_bind_undefined;
+		_global_state.initial_region->icvs.bind_var[1] = starpu_omp_proc_bind_undefined;
 	}
 	_global_state.initial_region->icvs.thread_limit_var = _starpu_omp_initial_icv_values->thread_limit_var;
 	_global_state.initial_region->icvs.active_levels_var = 0;
 	_global_state.initial_region->icvs.levels_var = 0;
+	_global_state.initial_region->icvs.run_sched_var = _starpu_omp_initial_icv_values->run_sched_var;
+	_global_state.initial_region->icvs.run_sched_chunk_var = _starpu_omp_initial_icv_values->run_sched_chunk_var;
 	_global_state.initial_region->icvs.default_device_var = _starpu_omp_initial_icv_values->default_device_var;
 	starpu_omp_task_list_push_back(_global_state.initial_region->implicit_task_list,
 			_global_state.initial_task);
@@ -684,8 +689,6 @@ int starpu_omp_init(void)
 {
 	STARPU_PTHREAD_KEY_CREATE(&omp_thread_key, NULL);
 	STARPU_PTHREAD_KEY_CREATE(&omp_task_key, NULL);
-	_starpu_omp_environment_init();
-	_global_state.icvs.cancel_var = _starpu_omp_initial_icv_values->cancel_var;
 	_global_state.initial_device = create_omp_device_struct();
 	_global_state.initial_region = create_omp_region_struct(NULL, _global_state.initial_device);
 	_global_state.initial_thread = create_omp_thread_struct(_global_state.initial_region);
@@ -696,13 +699,16 @@ int starpu_omp_init(void)
 	_starpu_spin_init(&_global_state.named_criticals_lock);
 	_global_state.hash_workers = NULL;
 	_starpu_spin_init(&_global_state.hash_workers_lock);
-	_starpu_omp_global_state = &_global_state;
 
+	_starpu_omp_environment_init();
+	_global_state.icvs.cancel_var = _starpu_omp_initial_icv_values->cancel_var;
 	omp_initial_region_setup();
 
 	/* init clock reference for starpu_omp_get_wtick */
 	_starpu_omp_clock_ref = starpu_timing_now();
 
+	_starpu_omp_global_state = &_global_state;
+
 	return 0;
 }
 
@@ -755,43 +761,45 @@ void starpu_omp_parallel_region(const struct starpu_omp_parallel_region_attr *at
 	struct starpu_omp_thread *master_thread = STARPU_PTHREAD_GETSPECIFIC(omp_thread_key);
 	struct starpu_omp_task *task = STARPU_PTHREAD_GETSPECIFIC(omp_task_key);
 	struct starpu_omp_region *generating_region = task->owner_region;
-	int ret;
-
-	const int max_levels = generating_region->owner_device->icvs.max_active_levels_var;
+	const int max_active_levels = generating_region->owner_device->icvs.max_active_levels_var;
 	struct starpu_omp_region *new_region = 
 		create_omp_region_struct(generating_region, _global_state.initial_device);
-
+	int ret;
 	int nb_threads = 1;
 
 	/* TODO: for now, nested parallel sections are not supported, thus we
 	 * open an active parallel section only if the generating region is the
 	 * initial region */
-	if (generating_region->level == 0)
+	if (attr->if_clause != 0)
 	{
-		if (attr->if_clause != 0)
+		const int max_threads = (int)starpu_cpu_worker_get_count();
+		if (generating_region->icvs.nthreads_var[0] < max_threads)
 		{
-			const int max_threads = (int)starpu_cpu_worker_get_count();
-			if (generating_region->icvs.nthreads_var[0] < max_threads)
-			{
-				nb_threads = generating_region->icvs.nthreads_var[0];
-			}
-			else
-			{
-				nb_threads = max_threads;
-			}
+			nb_threads = generating_region->icvs.nthreads_var[0];
+		}
+		else
+		{
+			nb_threads = max_threads;
+		}
+		if (nb_threads > 1 && generating_region->icvs.active_levels_var+1 > max_active_levels)
+		{
+			nb_threads = 1;
 		}
 	}
 	STARPU_ASSERT(nb_threads > 0);
 
 	new_region->icvs.dyn_var = generating_region->icvs.dyn_var;
 	new_region->icvs.nest_var = generating_region->icvs.nest_var;
-	if (new_region->level < max_levels)
+	/* the nthreads_var and bind_var arrays do not hold more than
+	 * max_active_levels entries at most, even if some in-between levels
+	 * are inactive */
+	if (new_region->level < max_active_levels)
 	{
 		if (generating_region->icvs.nthreads_var[1] != 0)
 		{
-			new_region->icvs.nthreads_var = malloc((1+max_levels-new_region->level) * sizeof(*new_region->icvs.nthreads_var));
+			new_region->icvs.nthreads_var = malloc((1+max_active_levels-new_region->level) * sizeof(*new_region->icvs.nthreads_var));
 			int i,j;
-			for (i = new_region->level, j = 0; i < max_levels; i++, j++)
+			for (i = new_region->level, j = 0; i < max_active_levels; i++, j++)
 			{
 				new_region->icvs.nthreads_var[j] = generating_region->icvs.nthreads_var[j+1];
 			}
@@ -804,21 +812,21 @@ void starpu_omp_parallel_region(const struct starpu_omp_parallel_region_attr *at
 			new_region->icvs.nthreads_var[1] = 0;
 		}
 
-		if (generating_region->icvs.bind_var[1] != starpu_omp_bind_undefined)
+		if (generating_region->icvs.bind_var[1] != starpu_omp_proc_bind_undefined)
 		{
-			new_region->icvs.bind_var = malloc((1+max_levels-new_region->level) * sizeof(*new_region->icvs.bind_var));
+			new_region->icvs.bind_var = malloc((1+max_active_levels-new_region->level) * sizeof(*new_region->icvs.bind_var));
 			int i,j;
-			for (i = new_region->level, j = 0; i < max_levels; i++, j++)
+			for (i = new_region->level, j = 0; i < max_active_levels; i++, j++)
 			{
 				new_region->icvs.bind_var[j] = generating_region->icvs.bind_var[j+1];
 			}
-			new_region->icvs.bind_var[j] = starpu_omp_bind_undefined;
+			new_region->icvs.bind_var[j] = starpu_omp_proc_bind_undefined;
 		}
 		else
 		{
 			new_region->icvs.bind_var = malloc(2 * sizeof(*new_region->icvs.bind_var));
 			new_region->icvs.bind_var[0] = generating_region->icvs.bind_var[0];
-			new_region->icvs.bind_var[1] = starpu_omp_bind_undefined;
+			new_region->icvs.bind_var[1] = starpu_omp_proc_bind_undefined;
 		}
 	}
 	else
@@ -832,13 +840,15 @@ void starpu_omp_parallel_region(const struct starpu_omp_parallel_region_attr *at
 	new_region->icvs.thread_limit_var = generating_region->icvs.thread_limit_var;
 	new_region->icvs.active_levels_var = (nb_threads > 1)?generating_region->icvs.active_levels_var+1:generating_region->icvs.active_levels_var;
 	new_region->icvs.levels_var = generating_region->icvs.levels_var+1;
+	new_region->icvs.run_sched_var = generating_region->icvs.run_sched_var;
+	new_region->icvs.run_sched_chunk_var = generating_region->icvs.run_sched_chunk_var;
 	new_region->icvs.default_device_var = generating_region->icvs.default_device_var;
 
 	int i;
 	for (i = 0; i < nb_threads; i++)
 	{
 		struct starpu_omp_thread *new_thread;
-		
+
 		if (i == 0)
 		{
 			new_thread = master_thread;
@@ -1504,7 +1514,16 @@ static inline void _starpu_omp_for_loop(struct starpu_omp_region *parallel_regio
 		unsigned long long nb_iterations, unsigned long long chunk, int schedule, int ordered, unsigned long long *_first_i, unsigned long long *_nb_i)
 {
 	*_nb_i = 0;
-	if (schedule == starpu_omp_schedule_static || schedule == starpu_omp_schedule_auto)
+	if (schedule == starpu_omp_sched_runtime)
+	{
+		schedule = parallel_region->icvs.run_sched_var;
+		chunk = parallel_region->icvs.run_sched_chunk_var;
+	}
+	STARPU_ASSERT(     schedule == starpu_omp_sched_static
+			|| schedule == starpu_omp_sched_dynamic
+			|| schedule == starpu_omp_sched_guided
+			|| schedule == starpu_omp_sched_auto);
+	if (schedule == starpu_omp_sched_static || schedule == starpu_omp_sched_auto)
 	{
 		if (chunk > 0)
 		{
@@ -1552,7 +1571,7 @@ static inline void _starpu_omp_for_loop(struct starpu_omp_region *parallel_regio
 			}
 		}
 	}
-	else if (schedule == starpu_omp_schedule_dynamic)
+	else if (schedule == starpu_omp_sched_dynamic)
 	{
 		if (chunk == 0)
 		{
@@ -1578,7 +1597,7 @@ static inline void _starpu_omp_for_loop(struct starpu_omp_region *parallel_regio
 		}
 		_starpu_spin_unlock(&parallel_region->lock);
 	}
-	else if (schedule == starpu_omp_schedule_guided)
+	else if (schedule == starpu_omp_sched_guided)
 	{
 		if (chunk == 0)
 		{

+ 4 - 25
src/util/openmp_runtime_support.h

@@ -37,29 +37,7 @@
 /*
  * Arbitrary limit on the number of nested parallel sections
  */
-#define STARPU_OMP_MAX_ACTIVE_LEVELS 4
-
-/*
- * Proc bind modes defined by the OpenMP spec
- */
-enum starpu_omp_bind_mode
-{
-	starpu_omp_bind_undefined  = -1,
-	starpu_omp_bind_false  = 0,
-	starpu_omp_bind_true   = 1,
-	starpu_omp_bind_master = 2,
-	starpu_omp_bind_close  = 3,
-	starpu_omp_bind_spread = 4
-};
-
-enum starpu_omp_schedule_mode
-{
-	starpu_omp_schedule_undefined = 0,
-	starpu_omp_schedule_static    = 1,
-	starpu_omp_schedule_dynamic   = 2,
-	starpu_omp_schedule_guided    = 3,
-	starpu_omp_schedule_auto      = 4
-};
+#define STARPU_OMP_MAX_ACTIVE_LEVELS 1
 
 /*
  * Possible abstract names for OpenMP places
@@ -111,7 +89,8 @@ struct starpu_omp_data_environment_icvs
 	int *bind_var; /* bind_var ICV is a list */
 
 	/* loop region icvs */
-	/* unused: int run_sched_var; */
+	int run_sched_var;
+	unsigned long long run_sched_chunk_var;
 
 	/* program execution icvs */
 	int default_device_var;
@@ -148,7 +127,7 @@ struct starpu_omp_initial_icv_values
 	int nest_var;
 	int *nthreads_var;
 	int run_sched_var;
-	int run_sched_chunk_var;
+	unsigned long long run_sched_chunk_var;
 	int def_sched_var;
 	int *bind_var;
 	int stacksize_var;

+ 21 - 18
src/util/openmp_runtime_support_environment.c

@@ -185,7 +185,7 @@ static void read_size_var(const char *var, int *dest)
 	}
 }
 
-static void read_sched_var(const char *var, int *dest, int *dest_chunk)
+static void read_sched_var(const char *var, int *dest, unsigned long long *dest_chunk)
 {
 	const char *env = getenv(var);
 	if (env)
@@ -208,10 +208,13 @@ static void read_sched_var(const char *var, int *dest, int *dest_chunk)
 		if (str[offset] == ',')
 		{
 			offset++;
-			int v = (int)strtol(str+offset, NULL, 10);
+			long long v = strtoll(str+offset, NULL, 10);
 			if (errno != 0)
 				_STARPU_ERROR("could not parse environment variable %s, strtol failed with error %s\n", var, strerror(errno));
-			*dest_chunk = v;
+			if (v < 0)
+				_STARPU_ERROR("invalid negative modifier in environment variable %s\n", var);
+			unsigned long long uv = (unsigned long long) v;
+			*dest_chunk = uv;
 		}
 		else
 		{
@@ -310,7 +313,7 @@ static void convert_bind_string(const char *_str, int *bind_list, const int max_
 			if (n == 0)
 				_STARPU_ERROR("proc_bind list parse error\n");
 			int mode = convert_bind_mode(str+i,n);
-			STARPU_ASSERT(mode >= starpu_omp_bind_false && mode <= starpu_omp_bind_spread);
+			STARPU_ASSERT(mode >= starpu_omp_proc_bind_false && mode <= starpu_omp_proc_bind_spread);
 			bind_list[level] = mode;
 			level++;
 			if (level == max_levels)
@@ -679,7 +682,7 @@ static void read_omp_environment(void)
 		for (level = 0;level < max_levels;level++)
 		{
 			/* TODO: check what should be used as default value */
-			bind_list[level] = starpu_omp_bind_true;
+			bind_list[level] = starpu_omp_proc_bind_true;
 		}
 		const char *env = getenv("OMP_PROC_BIND");
 		if (env)
@@ -760,17 +763,17 @@ static void display_omp_environment(int verbosity_level)
 		printf("  [host] OMP_SCHEDULE='");
 		switch (_starpu_omp_initial_icv_values->run_sched_var)
 		{
-			case starpu_omp_schedule_static:
-				printf("static, %d", _starpu_omp_initial_icv_values->run_sched_chunk_var);
+			case starpu_omp_sched_static:
+				printf("static, %llu", _starpu_omp_initial_icv_values->run_sched_chunk_var);
 				break;
-			case starpu_omp_schedule_dynamic:
-				printf("dynamic, %d", _starpu_omp_initial_icv_values->run_sched_chunk_var);
+			case starpu_omp_sched_dynamic:
+				printf("dynamic, %llu", _starpu_omp_initial_icv_values->run_sched_chunk_var);
 				break;
-			case starpu_omp_schedule_guided:
-				printf("guided, %d", _starpu_omp_initial_icv_values->run_sched_chunk_var);
+			case starpu_omp_sched_guided:
+				printf("guided, %llu", _starpu_omp_initial_icv_values->run_sched_chunk_var);
 				break;
-			case starpu_omp_schedule_auto:
-				printf("auto, %d", _starpu_omp_initial_icv_values->run_sched_chunk_var);
+			case starpu_omp_sched_auto:
+				printf("auto, %llu", _starpu_omp_initial_icv_values->run_sched_chunk_var);
 				break;
 			default:
 				printf("<unknown>");
@@ -794,19 +797,19 @@ static void display_omp_environment(int verbosity_level)
 				}
 				switch (_starpu_omp_initial_icv_values->bind_var[level])
 				{
-					case starpu_omp_bind_false:
+					case starpu_omp_proc_bind_false:
 						printf("false");
 						break;
-					case starpu_omp_bind_true:
+					case starpu_omp_proc_bind_true:
 						printf("true");
 						break;
-					case starpu_omp_bind_master:
+					case starpu_omp_proc_bind_master:
 						printf("master");
 						break;
-					case starpu_omp_bind_close:
+					case starpu_omp_proc_bind_close:
 						printf("close");
 						break;
-					case starpu_omp_bind_spread:
+					case starpu_omp_proc_bind_spread:
 						printf("spread");
 						break;
 					default:

+ 84 - 71
src/util/openmp_runtime_support_omp_api.c

@@ -37,18 +37,12 @@ int starpu_omp_get_num_threads()
 	return region->nb_threads;
 }
 
-int starpu_omp_get_thread_num()
+static int _starpu_omp_get_region_thread_num(const struct starpu_omp_region * const region)
 {
 	struct starpu_omp_thread *thread = _starpu_omp_get_thread();
-	struct starpu_omp_task *task = _starpu_omp_get_task();
-	struct starpu_omp_region *region;
-	if (thread == NULL || task == NULL)
-		return 0;
-
-	region = task->owner_region;
+	STARPU_ASSERT(thread != NULL);
 	if (thread == region->master_thread)
 		return 0;
-
 	struct starpu_omp_thread * region_thread;
 	int tid = 1;
 	for (region_thread  = starpu_omp_thread_list_begin(region->thread_list);
@@ -64,10 +58,27 @@ int starpu_omp_get_thread_num()
 	_STARPU_ERROR("unrecognized omp thread\n");
 }
 
+int starpu_omp_get_thread_num()
+{
+	struct starpu_omp_task *task = _starpu_omp_get_task();
+	if (task == NULL)
+		return 0;
+	return _starpu_omp_get_region_thread_num(task->owner_region);
+}
+
 int starpu_omp_get_max_threads()
 {
-	/* arbitrary limit */
-	return starpu_cpu_worker_get_count();
+	const struct starpu_omp_region * const parallel_region = _starpu_omp_get_task()->owner_region;
+	int max_threads = parallel_region->icvs.nthreads_var[0];
+	/* TODO: for now, nested parallel sections are not supported, thus we
+	 * open an active parallel section only if the generating region is the
+	 * initial region */
+	if (parallel_region->level > 0)
+	{
+		max_threads = 1;
+	}
+
+	return max_threads;
 }
 
 int starpu_omp_get_num_procs (void)
@@ -78,7 +89,8 @@ int starpu_omp_get_num_procs (void)
 
 int starpu_omp_in_parallel (void)
 {
-	__not_implemented__;
+	const struct starpu_omp_region * const parallel_region = _starpu_omp_get_task()->owner_region;
+	return parallel_region->icvs.active_levels_var > 0;
 }
 
 void starpu_omp_set_dynamic (int dynamic_threads)
@@ -89,9 +101,8 @@ void starpu_omp_set_dynamic (int dynamic_threads)
 
 int starpu_omp_get_dynamic (void)
 {
-	/* TODO: dynamic adjustment of the number of threads is not supported for now 
-	 * return false as required */
-	return 0;
+	const struct starpu_omp_region * const parallel_region = _starpu_omp_get_task()->owner_region;
+	return parallel_region->icvs.dyn_var;
 }
 
 void starpu_omp_set_nested (int nested)
@@ -102,110 +113,113 @@ void starpu_omp_set_nested (int nested)
 
 int starpu_omp_get_nested (void)
 {
-	/* TODO: nested parallelism not supported for now
-	 * return false as required */
-	return 0;
+	const struct starpu_omp_region * const parallel_region = _starpu_omp_get_task()->owner_region;
+	return parallel_region->icvs.nest_var;
 }
 
 int starpu_omp_get_cancellation(void)
 {
-	/* TODO: cancellation not supported for now
-	 * return false as required */
-	return 0;
+	return _starpu_omp_global_state->icvs.cancel_var;
 }
 
 void starpu_omp_set_schedule (enum starpu_omp_sched_value kind, int modifier)
 {
-	(void) kind;
-	(void) modifier;
-	/* TODO: no starpu_omp scheduler scheme implemented for now */
-	__not_implemented__;
-	assert(kind >= 1 && kind <=4);
+	struct starpu_omp_region * const parallel_region = _starpu_omp_get_task()->owner_region;
+	STARPU_ASSERT(     kind == starpu_omp_sched_static
+			|| kind == starpu_omp_sched_dynamic
+			|| kind == starpu_omp_sched_guided
+			|| kind == starpu_omp_sched_auto);
+	STARPU_ASSERT(modifier >= 0);
+	parallel_region->icvs.run_sched_var = kind;
+	parallel_region->icvs.run_sched_chunk_var = (unsigned long long)modifier;
 }
 
 void starpu_omp_get_schedule (enum starpu_omp_sched_value *kind, int *modifier)
 {
-	(void) kind;
-	(void) modifier;
-	/* TODO: no starpu_omp scheduler scheme implemented for now */
-	__not_implemented__;
+	const struct starpu_omp_region * const parallel_region = _starpu_omp_get_task()->owner_region;
+	*kind = parallel_region->icvs.run_sched_var;
+	*modifier = (int)parallel_region->icvs.run_sched_chunk_var;
 }
 
 int starpu_omp_get_thread_limit (void)
 {
-	/* arbitrary limit */
-	return 1024;
+	return starpu_cpu_worker_get_count();
 }
 
 void starpu_omp_set_max_active_levels (int max_levels)
 {
-	(void) max_levels;
-	/* TODO: nested parallelism not supported for now */
+	struct starpu_omp_device * const device = _starpu_omp_get_task()->owner_region->owner_device;
+	if (max_levels > 1)
+	{
+		/* TODO: nested parallelism not supported for now */
+		max_levels = 1;
+	}
+	device->icvs.max_active_levels_var = max_levels;
 }
 
 int starpu_omp_get_max_active_levels (void)
 {
-	/* TODO: nested parallelism not supported for now
-	 * assume a single level */
-	return 1;
+	const struct starpu_omp_device * const device = _starpu_omp_get_task()->owner_region->owner_device;
+	return device->icvs.max_active_levels_var;
 }
 
 int starpu_omp_get_level (void)
 {
-	/* TODO: nested parallelism not supported for now
-	 * assume a single level */
-	return 1;
+	const struct starpu_omp_region * const parallel_region = _starpu_omp_get_task()->owner_region;
+	return parallel_region->icvs.levels_var;
 }
 
 int starpu_omp_get_ancestor_thread_num (int level)
 {
-	if (level == 0) {
-		return 0; /* spec required answer */
-	}
-
-	if (level == starpu_omp_get_level()) {
-		return starpu_omp_get_thread_num(); /* spec required answer */
+	if (level == 0)
+		return 0;
+	const struct starpu_omp_task *task = _starpu_omp_get_task();
+	if (task == NULL)
+		return -1;
+	const struct starpu_omp_region *parallel_region = task->owner_region;
+	if (level < 0 || level > parallel_region->icvs.levels_var)
+		return -1;
+	while (level < parallel_region->icvs.levels_var)
+	{
+		parallel_region = parallel_region->parent_region;
 	}
-
-	/* TODO: nested parallelism not supported for now
-	 * assume ancestor is thread number '0' */
-	return 0;
+	return _starpu_omp_get_region_thread_num(parallel_region);
 }
 
 int starpu_omp_get_team_size (int level)
 {
-	if (level == 0) {
-		return 1; /* spec required answer */
-	}
-
-	if (level == starpu_omp_get_level()) {
-		return starpu_omp_get_num_threads(); /* spec required answer */
+	if (level == 0)
+		return 1;
+	const struct starpu_omp_task *task = _starpu_omp_get_task();
+	if (task == NULL)
+		return -1;
+	const struct starpu_omp_region *parallel_region = task->owner_region;
+	if (level < 0 || level > parallel_region->icvs.levels_var)
+		return -1;
+	while (level < parallel_region->icvs.levels_var)
+	{
+		parallel_region = parallel_region->parent_region;
 	}
-
-	/* TODO: nested parallelism not supported for now
-	 * assume the team size to be the number of cpu workers */
-	return starpu_cpu_worker_get_count();
+	return parallel_region->nb_threads;
 }
 
 int starpu_omp_get_active_level (void)
 {
-	/* TODO: nested parallelism not supported for now
-	 * assume a single active level */
-	return 1;
+	const struct starpu_omp_region * const parallel_region = _starpu_omp_get_task()->owner_region;
+	return parallel_region->icvs.active_levels_var;
 }
 
 int starpu_omp_in_final(void)
 {
-	/* TODO: final not supported for now
-	 * assume not in final */
-	return 0;
+	const struct starpu_omp_task *task = _starpu_omp_get_task();
+	return task->is_final;
 }
 
 enum starpu_omp_proc_bind_value starpu_omp_get_proc_bind(void)
 {
-	/* TODO: proc_bind not supported for now
-	 * assumre false */
-	return starpu_omp_proc_bind_false;
+	const struct starpu_omp_region * const parallel_region = _starpu_omp_get_task()->owner_region;
+	int proc_bind = parallel_region->icvs.bind_var[0];
+	return proc_bind;
 }
 
 void starpu_omp_set_default_device(int device_num)
@@ -216,9 +230,8 @@ void starpu_omp_set_default_device(int device_num)
 
 int starpu_omp_get_default_device(void)
 {
-	/* TODO: set_default_device not supported for now
-	 * assume device 0 as default */
-	return 0;
+	const struct starpu_omp_region * const parallel_region = _starpu_omp_get_task()->owner_region;
+	return parallel_region->icvs.default_device_var;
 }
 
 int starpu_omp_get_num_devices(void)