blob: d3f299dc1c6fe273d495119ec6e43536de277fa0 [file] [log] [blame]
//===----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