gcc/libgomp/icv.c
Jakub Jelinek 74c9882b80 openmp: Change omp_get_initial_device () to match OpenMP 5.1 requirements
> Therefore, I think until omp_get_initial_device () value is changed, we

The following so far untested patch implements that change.

OpenMP 4.5 said for omp_get_initial_device:
The value of the device number is implementation defined. If it is between 0 and one less than
omp_get_num_devices() then it is valid for use with all device constructs and routines; if it is
outside that range, then it is only valid for use with the device memory routines and not in the
device clause.
and OpenMP 5.0 similarly, but OpenMP 5.1 says:
The value of the device number is the value returned by the omp_get_num_devices routine.

As the new value is compatible with what has been required earlier, I think
we can change it already now.

2020-10-22  Jakub Jelinek  <jakub@redhat.com>

	* icv.c (omp_get_initial_device): Remove including corresponding
	ialias.
	* icv-device.c (omp_get_initial_device): New function.  Return
	gomp_get_num_devices ().  Add ialias.
	* target.c (resolve_device): Don't fail with
	OMP_TARGET_OFFLOAD=mandatory if device_id is equal to
	gomp_get_num_devices ().
	(omp_target_alloc, omp_target_free, omp_target_is_present,
	omp_target_memcpy, omp_target_memcpy_rect, omp_target_associate_ptr,
	omp_target_disassociate_ptr, omp_pause_resource): Use
	gomp_get_num_devices () instead of GOMP_DEVICE_HOST_FALLBACK on the
	first use in the functions, in uses dominated by the
	gomp_get_num_devices call use num_devices_openmp instead.
	* libgomp.texi (omp_get_initial_device): Document.
	* config/gcn/icv-device.c (omp_get_initial_device): New function.
	Add ialias.
	* config/nvptx/icv-device.c (omp_get_initial_device): Likewise.
	* testsuite/libgomp.c/target-40.c: New test.
2020-10-22 09:31:01 +02:00

245 lines
5.4 KiB
C

/* Copyright (C) 2005-2020 Free Software Foundation, Inc.
Contributed by Richard Henderson <rth@redhat.com>.
This file is part of the GNU Offloading and Multi Processing Library
(libgomp).
Libgomp is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.
Libgomp 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 General Public License for
more details.
Under Section 7 of GPL version 3, you are granted additional
permissions described in the GCC Runtime Library Exception, version
3.1, as published by the Free Software Foundation.
You should have received a copy of the GNU General Public License and
a copy of the GCC Runtime Library Exception along with this program;
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
<http://www.gnu.org/licenses/>. */
/* This file defines the OpenMP API entry points that operate on internal
control variables. */
#include "libgomp.h"
#include "gomp-constants.h"
#include <limits.h>
void
omp_set_num_threads (int n)
{
struct gomp_task_icv *icv = gomp_icv (true);
icv->nthreads_var = (n > 0 ? n : 1);
}
void
omp_set_dynamic (int val)
{
struct gomp_task_icv *icv = gomp_icv (true);
icv->dyn_var = val;
}
int
omp_get_dynamic (void)
{
struct gomp_task_icv *icv = gomp_icv (false);
return icv->dyn_var;
}
void
omp_set_nested (int val)
{
struct gomp_task_icv *icv = gomp_icv (true);
icv->nest_var = val;
}
int
omp_get_nested (void)
{
struct gomp_task_icv *icv = gomp_icv (false);
return icv->nest_var;
}
void
omp_set_schedule (omp_sched_t kind, int chunk_size)
{
struct gomp_task_icv *icv = gomp_icv (true);
switch (kind & ~omp_sched_monotonic)
{
case omp_sched_static:
if (chunk_size < 1)
chunk_size = 0;
icv->run_sched_chunk_size = chunk_size;
break;
case omp_sched_dynamic:
case omp_sched_guided:
if (chunk_size < 1)
chunk_size = 1;
icv->run_sched_chunk_size = chunk_size;
break;
case omp_sched_auto:
break;
default:
return;
}
icv->run_sched_var = kind;
}
void
omp_get_schedule (omp_sched_t *kind, int *chunk_size)
{
struct gomp_task_icv *icv = gomp_icv (false);
*kind = icv->run_sched_var;
*chunk_size = icv->run_sched_chunk_size;
}
int
omp_get_max_threads (void)
{
struct gomp_task_icv *icv = gomp_icv (false);
return icv->nthreads_var;
}
int
omp_get_thread_limit (void)
{
struct gomp_task_icv *icv = gomp_icv (false);
return icv->thread_limit_var > INT_MAX ? INT_MAX : icv->thread_limit_var;
}
void
omp_set_max_active_levels (int max_levels)
{
if (max_levels >= 0)
{
if (max_levels <= gomp_supported_active_levels)
gomp_max_active_levels_var = max_levels;
else
gomp_max_active_levels_var = gomp_supported_active_levels;
}
}
int
omp_get_max_active_levels (void)
{
return gomp_max_active_levels_var;
}
int
omp_get_supported_active_levels (void)
{
return gomp_supported_active_levels;
}
int
omp_get_cancellation (void)
{
return gomp_cancel_var;
}
int
omp_get_max_task_priority (void)
{
return gomp_max_task_priority_var;
}
omp_proc_bind_t
omp_get_proc_bind (void)
{
struct gomp_task_icv *icv = gomp_icv (false);
return icv->bind_var;
}
int
omp_get_num_places (void)
{
return gomp_places_list_len;
}
int
omp_get_place_num (void)
{
if (gomp_places_list == NULL)
return -1;
struct gomp_thread *thr = gomp_thread ();
if (thr->place == 0)
gomp_init_affinity ();
return (int) thr->place - 1;
}
int
omp_get_partition_num_places (void)
{
if (gomp_places_list == NULL)
return 0;
struct gomp_thread *thr = gomp_thread ();
if (thr->place == 0)
gomp_init_affinity ();
return thr->ts.place_partition_len;
}
void
omp_get_partition_place_nums (int *place_nums)
{
if (gomp_places_list == NULL)
return;
struct gomp_thread *thr = gomp_thread ();
if (thr->place == 0)
gomp_init_affinity ();
unsigned int i;
for (i = 0; i < thr->ts.place_partition_len; i++)
*place_nums++ = thr->ts.place_partition_off + i;
}
void
omp_set_default_allocator (omp_allocator_handle_t allocator)
{
struct gomp_thread *thr = gomp_thread ();
if (allocator == omp_null_allocator)
allocator = omp_default_mem_alloc;
thr->ts.def_allocator = (uintptr_t) allocator;
}
omp_allocator_handle_t
omp_get_default_allocator (void)
{
struct gomp_thread *thr = gomp_thread ();
if (thr->ts.def_allocator == omp_null_allocator)
return (omp_allocator_handle_t) gomp_def_allocator;
else
return (omp_allocator_handle_t) thr->ts.def_allocator;
}
ialias (omp_set_dynamic)
ialias (omp_set_nested)
ialias (omp_set_num_threads)
ialias (omp_get_dynamic)
ialias (omp_get_nested)
ialias (omp_set_schedule)
ialias (omp_get_schedule)
ialias (omp_get_max_threads)
ialias (omp_get_thread_limit)
ialias (omp_set_max_active_levels)
ialias (omp_get_max_active_levels)
ialias (omp_get_supported_active_levels)
ialias (omp_get_cancellation)
ialias (omp_get_proc_bind)
ialias (omp_get_max_task_priority)
ialias (omp_get_num_places)
ialias (omp_get_place_num)
ialias (omp_get_partition_num_places)
ialias (omp_get_partition_place_nums)
ialias (omp_set_default_allocator)
ialias (omp_get_default_allocator)