In OpenMP v5.2, the constant `omp_initial_device` was introduced, which was defined as a value of `-1`. Support for this value was added to Clang and Flang in09cd294482and3c14034c55. However, runtime calls are not aware of this constant. As such, execution of a runtime function, passing `omp_initial_device` as the `device_num`, would abort with e.g.,: ``` omptarget fatal error -1: "invalid value" device number '-1' out of range, only 1 devices available ``` To fix this issue, also extend the host device checks in the API functions to also check for `omp_initial_device`. For testing, extend API tests using `omp_get_initial_device()` to also test `omp_initial_device` and extend `omp_device_uid.c` to check if the UID for `omp_initial_device` and `omp_get_initial_device()` matches. Partially addresses https://github.com/llvm/llvm-project/issues/192980 (see https://github.com/llvm/llvm-project/issues/192980#issuecomment-4404241994) --------- Signed-off-by: Jan André Reuter <j.reuter@fz-juelich.de> Signed-off-by: Jan André Reuter <jan@zyten.de>
100 lines
3.8 KiB
C++
100 lines
3.8 KiB
C++
//===---------- private.h - Target independent OpenMP target RTL ----------===//
|
|
//
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// Private function declarations and helper macros for debugging output.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#ifndef _OMPTARGET_PRIVATE_H
|
|
#define _OMPTARGET_PRIVATE_H
|
|
|
|
#include "Shared/Debug.h"
|
|
#include "Shared/SourceInfo.h"
|
|
|
|
#include "OpenMP/InternalTypes.h"
|
|
#include "OpenMP/omp.h"
|
|
|
|
#include "device.h"
|
|
#include "omptarget.h"
|
|
|
|
#include <cstdint>
|
|
|
|
extern int target(ident_t *Loc, DeviceTy &Device, void *HostPtr,
|
|
KernelArgsTy &KernelArgs, AsyncInfoTy &AsyncInfo);
|
|
|
|
extern int target_activate_rr(DeviceTy &Device, uint64_t MemorySize,
|
|
void *ReqAddr, bool IsRecord, bool SaveOutput,
|
|
bool EmitReport, const char *OutputDirPath);
|
|
|
|
extern int
|
|
target_replay(ident_t *Loc, DeviceTy &Device, void *HostPtr, void *DeviceMemory,
|
|
int64_t DeviceMemorySize, void *ReuseDeviceAlloc,
|
|
const llvm::offloading::EntryTy *Globals, int32_t NumGlobals,
|
|
void **TgtArgs, ptrdiff_t *TgtOffsets, int32_t NumArgs,
|
|
int32_t NumTeams, int32_t ThreadLimit, uint32_t SharedMemorySize,
|
|
uint64_t LoopTripCount, AsyncInfoTy &AsyncInfo,
|
|
KernelReplayOutcomeTy *ReplayOutcome);
|
|
|
|
extern void handleTargetOutcome(bool Success, ident_t *Loc);
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// Print out the names and properties of the arguments to each kernel
|
|
static inline void
|
|
printKernelArguments(const ident_t *Loc, const int64_t DeviceId,
|
|
const int32_t ArgNum, const int64_t *ArgSizes,
|
|
const int64_t *ArgTypes, const map_var_info_t *ArgNames,
|
|
const char *RegionType) {
|
|
SourceInfo Info(Loc);
|
|
INFO(OMP_INFOTYPE_ALL, DeviceId, "%s at %s:%d:%d with %d arguments:\n",
|
|
RegionType, Info.getFilename(), Info.getLine(), Info.getColumn(),
|
|
ArgNum);
|
|
|
|
for (int32_t I = 0; I < ArgNum; ++I) {
|
|
const map_var_info_t VarName = (ArgNames) ? ArgNames[I] : nullptr;
|
|
const char *Type = nullptr;
|
|
const char *Implicit =
|
|
(ArgTypes[I] & OMP_TGT_MAPTYPE_IMPLICIT) ? "(implicit)" : "";
|
|
|
|
if (ArgTypes[I] & OMP_TGT_MAPTYPE_ATTACH &&
|
|
ArgTypes[I] & OMP_TGT_MAPTYPE_ALWAYS)
|
|
Type = "attach:always";
|
|
else if (ArgTypes[I] & OMP_TGT_MAPTYPE_ATTACH)
|
|
Type = "attach";
|
|
else if (ArgTypes[I] & OMP_TGT_MAPTYPE_TO &&
|
|
ArgTypes[I] & OMP_TGT_MAPTYPE_FROM)
|
|
Type = "tofrom";
|
|
else if (ArgTypes[I] & OMP_TGT_MAPTYPE_TO)
|
|
Type = "to";
|
|
else if (ArgTypes[I] & OMP_TGT_MAPTYPE_FROM)
|
|
Type = "from";
|
|
else if (ArgTypes[I] & OMP_TGT_MAPTYPE_PRIVATE)
|
|
Type = "private";
|
|
else if (ArgTypes[I] & OMP_TGT_MAPTYPE_LITERAL)
|
|
Type = "firstprivate";
|
|
else if (ArgSizes[I] != 0)
|
|
Type = "alloc";
|
|
else
|
|
Type = "use_address";
|
|
|
|
INFO(OMP_INFOTYPE_ALL, DeviceId, "%s(%s)[%" PRId64 "] %s\n", Type,
|
|
getNameFromMapping(VarName).c_str(), ArgSizes[I], Implicit);
|
|
}
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// Checks if the passed device is the initial device (i.e., host device)
|
|
/// While the device number is defined as the value of the total number of
|
|
/// host devices (i.e. omp_get_initial_device()), the alias omp_initial_device
|
|
/// can be used as well (Ref. OpenMP v5.2, p.23 l.33 - p.24 l.6).
|
|
static inline bool isInitialDevice(const int &DeviceNum) {
|
|
return DeviceNum == omp_get_initial_device() ||
|
|
DeviceNum == omp_initial_device;
|
|
}
|
|
|
|
#endif
|