gcc/libgomp/testsuite/libgomp.c/target-50a.c
Tobias Burnus 18c8b56c7d OpenMP: Set default-device-var with OMP_TARGET_OFFLOAD=mandatory
OMP_TARGET_OFFLOAD=mandatory handling was before inconsistent. Hence, in
OpenMP 5.2 it was clarified/extended by having implications on the
default-device-var; additionally, omp_initial_device and omp_invalid_device
enum values/PARAMETERs were added; support for it was added
in r13-1066-g1158fe43407568 including aborting for omp_invalid_device and
non-conforming device numbers. Only the mandatory handling was missing.

Namely, while the default-device-var is usually initialized to value 0,
with 'mandatory' it must have the value 'omp_invalid_device' if and only if
zero non-host devices are available. (The OMP_DEFAULT_DEVICE env var
overrides this as it comes semantically after the initialization.)

To achieve this, default-device-var is now initialized to MIN_INT. If
there is no 'mandatory', it is set to 0 directly after env var parsing.
Otherwise, it is updated in gomp_target_init to either 0 or
omp_invalid_device. To ensure INT_MIN is never seen by the user, both
the omp_get_default_device API routine and omp_display_env (user call
and OMP_DISPLAY_ENV env var) call gomp_init_targets_once() in that case.

libgomp/ChangeLog:

	* env.c (gomp_default_icv_values): Init default_device_var to
	an nonconforming value - INT_MIN.
	(initialize_env): After env-var parsing, set default_device_var to
	device 0 unless OMP_TARGET_OFFLOAD=mandatory.
	(omp_display_env): If default_device_var is INT_MIN, call
	gomp_init_targets_once.
	* icv-device.c (omp_get_default_device): Likewise.
	* libgomp.texi (OMP_DEFAULT_DEVICE): Update init description.
	(OpenMP 5.2 Impl. Status): Mark OMP_TARGET_OFFLOAD=mandatory as 'Y'.
	* target.c (resolve_device): Improve error message device-num < 0
	with 'mandatory' and no no-host devices available.
	(gomp_target_init): Set default-device-var if INT_MIN.
	* testsuite/libgomp.c/target-48.c: New test.
	* testsuite/libgomp.c/target-49.c: New test.
	* testsuite/libgomp.c/target-50.c: New test.
	* testsuite/libgomp.c/target-50a.c: New test.
	* testsuite/libgomp.c/target-51.c: New test.
	* testsuite/libgomp.c/target-52.c: New test.
	* testsuite/libgomp.c/target-53.c: New test.
	* testsuite/libgomp.c/target-54.c: New test.
2023-06-14 07:53:02 +02:00

43 lines
1.6 KiB
C

/* Check OMP_TARGET_OFFLOAD on systems with non-host devices but no executable
code due to -foffload=disable.
Note: While one might expect that -foffload=disable implies no non-host
devices, libgomp actually detects the devices and only fails when trying to
run as no executable code is availale for that device.
(Without MANDATORY it simply uses host fallback, which should usually be fine
but might have issues in corner cases.)
We have default-device-var = 0 (default but also explicitly set), which will
fail at runtime. For -foffload=disable without non-host devices, see
target-50.c testcase. */
/* { dg-do run { target offload_device } } */
/* { dg-additional-options "-foffload=disable" } */
/* { dg-set-target-env-var OMP_TARGET_OFFLOAD "mandatory" } */
/* { dg-set-target-env-var OMP_DEFAULT_DEVICE "0" } */
/* { dg-set-target-env-var OMP_DISPLAY_ENV "true" } */
/* { dg-output ".*OMP_DEFAULT_DEVICE = '0'.*OMP_TARGET_OFFLOAD = 'MANDATORY'.*" } */
#include <omp.h>
int
main ()
{
int x;
/* We know that there are non-host devices. With GCC, we still find them as
available devices, hence, check for it. */
if (omp_get_num_devices() <= 0)
__builtin_abort ();
/* But due to -foffload=disable, there are no binary code for (default) device '0' */
/* { dg-output ".*libgomp: OMP_TARGET_OFFLOAD is set to MANDATORY, but device cannot be used for offloading.*" } */
/* { dg-shouldfail "OMP_TARGET_OFFLOAD=mandatory and no binary code for a non-host device" } */
#pragma omp target map(tofrom:x)
x = 5;
if (x != 5)
__builtin_abort ();
return 0;
}