--- /dev/null
+//===----RTLs/amdgpu/utils/UtilitiesRTL.h ------------------------- C++ -*-===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+//
+// RTL Utilities for AMDGPU plugins
+//
+//===----------------------------------------------------------------------===//
+
+#include <cstdint>
+
+#include "Debug.h"
+#include "omptarget.h"
+
+#include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/StringRef.h"
+
+namespace llvm {
+namespace omp {
+namespace target {
+namespace plugin {
+namespace utils {
+
+// The implicit arguments of AMDGPU kernels.
+struct AMDGPUImplicitArgsTy {
+ uint64_t OffsetX;
+ uint64_t OffsetY;
+ uint64_t OffsetZ;
+ uint64_t HostcallPtr;
+ uint64_t Unused0;
+ uint64_t Unused1;
+ uint64_t Unused2;
+};
+
+static_assert(sizeof(AMDGPUImplicitArgsTy) == 56,
+ "Unexpected size of implicit arguments");
+
+/// Parse a TargetID to get processor arch and feature map.
+/// Returns processor subarch.
+/// Returns TargetID features in \p FeatureMap argument.
+/// If the \p TargetID contains feature+, FeatureMap it to true.
+/// If the \p TargetID contains feature-, FeatureMap it to false.
+/// If the \p TargetID does not contain a feature (default), do not map it.
+StringRef parseTargetID(StringRef TargetID, StringMap<bool> &FeatureMap) {
+ if (TargetID.empty())
+ return llvm::StringRef();
+
+ auto ArchFeature = TargetID.split(":");
+ auto Arch = ArchFeature.first;
+ auto Features = ArchFeature.second;
+ if (Features.empty())
+ return Arch;
+
+ if (Features.contains("sramecc+")) {
+ FeatureMap.insert(std::pair<StringRef, bool>("sramecc", true));
+ } else if (Features.contains("sramecc-")) {
+ FeatureMap.insert(std::pair<StringRef, bool>("sramecc", false));
+ }
+ if (Features.contains("xnack+")) {
+ FeatureMap.insert(std::pair<StringRef, bool>("xnack", true));
+ } else if (Features.contains("xnack-")) {
+ FeatureMap.insert(std::pair<StringRef, bool>("xnack", false));
+ }
+
+ return Arch;
+}
+
+/// Check if an image is compatible with current system's environment.
+bool isImageCompatibleWithEnv(const __tgt_image_info *Info,
+ StringRef EnvTargetID) {
+ llvm::StringRef ImageTargetID(Info->Arch);
+
+ // Compatible in case of exact match.
+ if (ImageTargetID == EnvTargetID) {
+ DP("Compatible: Exact match \t[Image: %s]\t:\t[Env: %s]\n",
+ ImageTargetID.data(), EnvTargetID.data());
+ return true;
+ }
+
+ // Incompatible if Archs mismatch.
+ StringMap<bool> ImgMap, EnvMap;
+ StringRef ImgArch = utils::parseTargetID(ImageTargetID, ImgMap);
+ StringRef EnvArch = utils::parseTargetID(EnvTargetID, EnvMap);
+
+ // Both EnvArch and ImgArch can't be empty here.
+ if (EnvArch.empty() || ImgArch.empty() || !ImgArch.contains(EnvArch)) {
+ DP("Incompatible: Processor mismatch \t[Image: %s]\t:\t[Env: %s]\n",
+ ImageTargetID.data(), EnvTargetID.data());
+ return false;
+ }
+
+ // Incompatible if image has more features than the environment,
+ // irrespective of type or sign of features.
+ if (ImgMap.size() > EnvMap.size()) {
+ DP("Incompatible: Image has more features than the Environment \t[Image: "
+ "%s]\t:\t[Env: %s]\n",
+ ImageTargetID.data(), EnvTargetID.data());
+ return false;
+ }
+
+ // Compatible if each target feature specified by the environment is
+ // compatible with target feature of the image. The target feature is
+ // compatible if the iamge does not specify it (meaning Any), or if it
+ // specifies it with the same value (meaning On or Off).
+ for (const auto &ImgFeature : ImgMap) {
+ auto EnvFeature = EnvMap.find(ImgFeature.first());
+ if (EnvFeature == EnvMap.end() ||
+ (EnvFeature->first() == ImgFeature.first() &&
+ EnvFeature->second != ImgFeature.second)) {
+ DP("Incompatible: Value of Image's non-ANY feature is not matching with "
+ "the Environment's non-ANY feature \t[Image: %s]\t:\t[Env: %s]\n",
+ ImageTargetID.data(), EnvTargetID.data());
+ return false;
+ }
+ }
+
+ // Image is compatible if all features of Environment are:
+ // - either, present in the Image's features map with the same sign,
+ // - or, the feature is missing from Image's features map i.e. it is
+ // set to ANY
+ DP("Compatible: Target IDs are compatible \t[Image: %s]\t:\t[Env: %s]\n",
+ ImageTargetID.data(), EnvTargetID.data());
+
+ return true;
+}
+
+} // namespace utils
+} // namespace plugin
+} // namespace target
+} // namespace omp
+} // namespace llvm
//
//===----------------------------------------------------------------------===//
-#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Frontend/OpenMP/OMPConstants.h"
#include "llvm/Frontend/OpenMP/OMPGridValues.h"
#include "impl_runtime.h"
#include "interop_hsa.h"
+#include "UtilitiesRTL.h"
#include "internal.h"
#include "rt.h"
using namespace llvm;
using namespace llvm::object;
using namespace llvm::ELF;
+using namespace llvm::omp::target::plugin::utils;
// hostrpc interface, FIXME: consider moving to its own include these are
// statically linked into amdgpu/plugin if present from hostrpc_services.a,
std::queue<int> FreeKernargSegments;
uint32_t kernargSizeIncludingImplicit() {
- return KernargSegmentSize + sizeof(impl_implicit_args_t);
+ return KernargSegmentSize + sizeof(AMDGPUImplicitArgsTy);
}
~KernelArgPool() {
}
// Initialize implicit arguments. TODO: Which of these can be dropped
- impl_implicit_args_t *ImplArgs = reinterpret_cast<impl_implicit_args_t *>(
+ AMDGPUImplicitArgsTy *ImplArgs = reinterpret_cast<AMDGPUImplicitArgsTy *>(
static_cast<char *>(KernArg) + ArgPool->KernargSegmentSize);
memset(ImplArgs, 0,
- sizeof(impl_implicit_args_t)); // may not be necessary
- ImplArgs->offset_x = 0;
- ImplArgs->offset_y = 0;
- ImplArgs->offset_z = 0;
+ sizeof(AMDGPUImplicitArgsTy)); // may not be necessary
+ ImplArgs->OffsetX = 0;
+ ImplArgs->OffsetY = 0;
+ ImplArgs->OffsetZ = 0;
// assign a hostcall buffer for the selected Q
if (__atomic_load_n(&DeviceInfo().HostcallRequired, __ATOMIC_ACQUIRE)) {
}
// initialise pointer for implicit_argument_count == 0 ABI
- ImplArgs->hostcall_ptr = Buffer;
+ ImplArgs->HostcallPtr = Buffer;
}
Packet->kernarg_address = KernArg;
return HSA_STATUS_SUCCESS;
}
-/// Parse a TargetID to get processor arch and feature map.
-/// Returns processor subarch.
-/// Returns TargetID features in \p FeatureMap argument.
-/// If the \p TargetID contains feature+, FeatureMap it to true.
-/// If the \p TargetID contains feature-, FeatureMap it to false.
-/// If the \p TargetID does not contain a feature (default), do not map it.
-StringRef parseTargetID(StringRef TargetID, StringMap<bool> &FeatureMap) {
- if (TargetID.empty())
- return llvm::StringRef();
-
- auto ArchFeature = TargetID.split(":");
- auto Arch = ArchFeature.first;
- auto Features = ArchFeature.second;
- if (Features.empty())
- return Arch;
-
- if (Features.contains("sramecc+")) {
- FeatureMap.insert(std::pair<std::string, bool>("sramecc", true));
- } else if (Features.contains("sramecc-")) {
- FeatureMap.insert(std::pair<std::string, bool>("sramecc", false));
- }
- if (Features.contains("xnack+")) {
- FeatureMap.insert(std::pair<std::string, bool>("xnack", true));
- } else if (Features.contains("xnack-")) {
- FeatureMap.insert(std::pair<std::string, bool>("xnack", false));
- }
-
- return Arch;
-}
-
-/// Checks if an image \p ImgInfo is compatible with current
-/// system's environment \p EnvInfo
-bool IsImageCompatibleWithEnv(const char *ImgInfo, std::string EnvInfo) {
- llvm::StringRef ImgTID(ImgInfo), EnvTID(EnvInfo);
-
- // Compatible in case of exact match
- if (ImgTID == EnvTID) {
- DP("Compatible: Exact match \t[Image: %s]\t:\t[Environment: %s]\n",
- ImgTID.data(), EnvTID.data());
- return true;
- }
-
- // Incompatible if Archs mismatch.
- StringMap<bool> ImgMap, EnvMap;
- StringRef ImgArch = parseTargetID(ImgTID, ImgMap);
- StringRef EnvArch = parseTargetID(EnvTID, EnvMap);
-
- // Both EnvArch and ImgArch can't be empty here.
- if (EnvArch.empty() || ImgArch.empty() || !ImgArch.contains(EnvArch)) {
- DP("Incompatible: Processor mismatch \t[Image: %s]\t:\t[Environment: %s]\n",
- ImgTID.data(), EnvTID.data());
- return false;
- }
-
- // Incompatible if image has more features than the environment, irrespective
- // of type or sign of features.
- if (ImgMap.size() > EnvMap.size()) {
- DP("Incompatible: Image has more features than the environment \t[Image: "
- "%s]\t:\t[Environment: %s]\n",
- ImgTID.data(), EnvTID.data());
- return false;
- }
-
- // Compatible if each target feature specified by the environment is
- // compatible with target feature of the image. The target feature is
- // compatible if the iamge does not specify it (meaning Any), or if it
- // specifies it with the same value (meaning On or Off).
- for (const auto &ImgFeature : ImgMap) {
- auto EnvFeature = EnvMap.find(ImgFeature.first());
- if (EnvFeature == EnvMap.end()) {
- DP("Incompatible: Value of Image's non-ANY feature is not matching with "
- "the Environment feature's ANY value \t[Image: %s]\t:\t[Environment: "
- "%s]\n",
- ImgTID.data(), EnvTID.data());
- return false;
- } else if (EnvFeature->first() == ImgFeature.first() &&
- EnvFeature->second != ImgFeature.second) {
- DP("Incompatible: Value of Image's non-ANY feature is not matching with "
- "the Environment feature's non-ANY value \t[Image: "
- "%s]\t:\t[Environment: %s]\n",
- ImgTID.data(), EnvTID.data());
- return false;
- }
- }
-
- // Image is compatible if all features of Environment are:
- // - either, present in the Image's features map with the same sign,
- // - or, the feature is missing from Image's features map i.e. it is
- // set to ANY
- DP("Compatible: Target IDs are compatible \t[Image: %s]\t:\t[Environment: "
- "%s]\n",
- ImgTID.data(), EnvTID.data());
- return true;
-}
-
extern "C" {
int32_t __tgt_rtl_is_valid_binary(__tgt_device_image *Image) {
return elfMachineIdIsAmdgcn(Image);
DP("Error iterating ISAs\n");
return false;
}
- if (!IsImageCompatibleWithEnv(info->Arch, DeviceInfo().TargetID[DeviceId]))
+ if (!isImageCompatibleWithEnv(info, DeviceInfo().TargetID[DeviceId]))
return false;
}
DP("Image has Target ID compatible with the current environment: %s\n",