35
35
#include " omptargetplugin.h"
36
36
#include " print_tracing.h"
37
37
38
+ #include " llvm/ADT/StringMap.h"
39
+ #include " llvm/ADT/StringRef.h"
38
40
#include " llvm/Frontend/OpenMP/OMPConstants.h"
39
41
#include " llvm/Frontend/OpenMP/OMPGridValues.h"
40
42
43
+ using namespace llvm ;
44
+
41
45
// hostrpc interface, FIXME: consider moving to its own include these are
42
46
// statically linked into amdgpu/plugin if present from hostrpc_services.a,
43
47
// linked as --whole-archive to override the weak symbols that are used to
@@ -465,6 +469,7 @@ class RTLDeviceInfoTy : HSALifetime {
465
469
std::vector<int > ThreadsPerGroup;
466
470
std::vector<int > WarpSize;
467
471
std::vector<std::string> GPUName;
472
+ std::vector<std::string> TargetID;
468
473
469
474
// OpenMP properties
470
475
std::vector<int > NumTeams;
@@ -1893,11 +1898,156 @@ hsa_status_t allow_access_to_all_gpu_agents(void *Ptr) {
1893
1898
}
1894
1899
} // namespace core
1895
1900
1901
+ static hsa_status_t GetIsaInfo (hsa_isa_t isa, void *data) {
1902
+ hsa_status_t err;
1903
+ uint32_t name_len;
1904
+ err = hsa_isa_get_info_alt (isa, HSA_ISA_INFO_NAME_LENGTH, &name_len);
1905
+ if (err != HSA_STATUS_SUCCESS) {
1906
+ DP (" Error getting ISA info length\n " );
1907
+ return err;
1908
+ }
1909
+
1910
+ char TargetID[name_len];
1911
+ err = hsa_isa_get_info_alt (isa, HSA_ISA_INFO_NAME, TargetID);
1912
+ if (err != HSA_STATUS_SUCCESS) {
1913
+ DP (" Error getting ISA info name\n " );
1914
+ return err;
1915
+ }
1916
+
1917
+ auto TripleTargetID = llvm::StringRef (TargetID);
1918
+ if (TripleTargetID.consume_front (" amdgcn-amd-amdhsa" )) {
1919
+ DeviceInfo.TargetID .push_back (TripleTargetID.ltrim (' -' ).str ());
1920
+ }
1921
+ return HSA_STATUS_SUCCESS;
1922
+ }
1923
+
1924
+ // / Parse a TargetID to get processor arch and feature map.
1925
+ // / Returns processor subarch.
1926
+ // / Returns TargetID features in \p FeatureMap argument.
1927
+ // / If the \p TargetID contains feature+, FeatureMap it to true.
1928
+ // / If the \p TargetID contains feature-, FeatureMap it to false.
1929
+ // / If the \p TargetID does not contain a feature (default), do not map it.
1930
+ StringRef parseTargetID (StringRef TargetID, StringMap<bool > &FeatureMap) {
1931
+ if (TargetID.empty ())
1932
+ return llvm::StringRef ();
1933
+
1934
+ auto ArchFeature = TargetID.split (" :" );
1935
+ auto Arch = ArchFeature.first ;
1936
+ auto Features = ArchFeature.second ;
1937
+ if (Features.empty ())
1938
+ return Arch;
1939
+
1940
+ if (Features.contains (" sramecc+" )) {
1941
+ FeatureMap.insert (std::pair<std::string, bool >(" sramecc" , true ));
1942
+ } else if (Features.contains (" sramecc-" )) {
1943
+ FeatureMap.insert (std::pair<std::string, bool >(" sramecc" , false ));
1944
+ }
1945
+ if (Features.contains (" xnack+" )) {
1946
+ FeatureMap.insert (std::pair<std::string, bool >(" xnack" , true ));
1947
+ } else if (Features.contains (" xnack-" )) {
1948
+ FeatureMap.insert (std::pair<std::string, bool >(" xnack" , false ));
1949
+ }
1950
+
1951
+ return Arch;
1952
+ }
1953
+
1954
+ // / Checks if an image \p ImgInfo is compatible with current
1955
+ // / system's environment \p EnvInfo
1956
+ bool IsImageCompatibleWithEnv (const char *ImgInfo, std::string EnvInfo) {
1957
+ llvm::StringRef ImgTID (ImgInfo), EnvTID (EnvInfo);
1958
+
1959
+ // Compatible in case of exact match
1960
+ if (ImgTID == EnvTID) {
1961
+ DP (" Compatible: Exact match \t [Image: %s]\t :\t [Environment: %s]\n " ,
1962
+ ImgTID.data (), EnvTID.data ());
1963
+ return true ;
1964
+ }
1965
+
1966
+ // Incompatible if Archs mismatch.
1967
+ StringMap<bool > ImgMap, EnvMap;
1968
+ StringRef ImgArch = parseTargetID (ImgTID, ImgMap);
1969
+ StringRef EnvArch = parseTargetID (EnvTID, EnvMap);
1970
+
1971
+ // Both EnvArch and ImgArch can't be empty here.
1972
+ if (EnvArch.empty () || ImgArch.empty () || !ImgArch.contains (EnvArch)) {
1973
+ DP (" Incompatible: Processor mismatch \t [Image: %s]\t :\t [Environment: %s]\n " ,
1974
+ ImgTID.data (), EnvTID.data ());
1975
+ return false ;
1976
+ }
1977
+
1978
+ // Incompatible if image has more features than the environment, irrespective
1979
+ // of type or sign of features.
1980
+ if (ImgMap.size () > EnvMap.size ()) {
1981
+ DP (" Incompatible: Image has more features than the environment \t [Image: "
1982
+ " %s]\t :\t [Environment: %s]\n " ,
1983
+ ImgTID.data (), EnvTID.data ());
1984
+ return false ;
1985
+ }
1986
+
1987
+ // Compatible if each target feature specified by the environment is
1988
+ // compatible with target feature of the image. The target feature is
1989
+ // compatible if the iamge does not specify it (meaning Any), or if it
1990
+ // specifies it with the same value (meaning On or Off).
1991
+ for (const auto &ImgFeature : ImgMap) {
1992
+ auto EnvFeature = EnvMap.find (ImgFeature.first ());
1993
+ if (EnvFeature == EnvMap.end ()) {
1994
+ DP (" Incompatible: Value of Image's non-ANY feature is not matching with "
1995
+ " the Environment feature's ANY value \t [Image: %s]\t :\t [Environment: "
1996
+ " %s]\n " ,
1997
+ ImgTID.data (), EnvTID.data ());
1998
+ return false ;
1999
+ } else if (EnvFeature->first () == ImgFeature.first () &&
2000
+ EnvFeature->second != ImgFeature.second ) {
2001
+ DP (" Incompatible: Value of Image's non-ANY feature is not matching with "
2002
+ " the Environment feature's non-ANY value \t [Image: "
2003
+ " %s]\t :\t [Environment: %s]\n " ,
2004
+ ImgTID.data (), EnvTID.data ());
2005
+ return false ;
2006
+ }
2007
+ }
2008
+
2009
+ // Image is compatible if all features of Environment are:
2010
+ // - either, present in the Image's features map with the same sign,
2011
+ // - or, the feature is missing from Image's features map i.e. it is
2012
+ // set to ANY
2013
+ DP (" Compatible: Target IDs are compatible \t [Image: %s]\t :\t [Environment: "
2014
+ " %s]\n " ,
2015
+ ImgTID.data (), EnvTID.data ());
2016
+ return true ;
2017
+ }
2018
+
1896
2019
extern " C" {
1897
2020
int32_t __tgt_rtl_is_valid_binary (__tgt_device_image *Image) {
1898
2021
return elfMachineIdIsAmdgcn (Image);
1899
2022
}
1900
2023
2024
+ int32_t __tgt_rtl_is_valid_binary_info (__tgt_device_image *image,
2025
+ __tgt_image_info *info) {
2026
+ if (!__tgt_rtl_is_valid_binary (image))
2027
+ return false ;
2028
+
2029
+ // A subarchitecture was not specified. Assume it is compatible.
2030
+ if (!info->Arch )
2031
+ return true ;
2032
+
2033
+ int32_t NumberOfDevices = __tgt_rtl_number_of_devices ();
2034
+
2035
+ for (int32_t DeviceId = 0 ; DeviceId < NumberOfDevices; ++DeviceId) {
2036
+ __tgt_rtl_init_device (DeviceId);
2037
+ hsa_agent_t agent = DeviceInfo.HSAAgents [DeviceId];
2038
+ hsa_status_t err = hsa_agent_iterate_isas (agent, GetIsaInfo, &DeviceId);
2039
+ if (err != HSA_STATUS_SUCCESS) {
2040
+ DP (" Error iterating ISAs\n " );
2041
+ return false ;
2042
+ }
2043
+ if (!IsImageCompatibleWithEnv (info->Arch , DeviceInfo.TargetID [DeviceId]))
2044
+ return false ;
2045
+ }
2046
+ DP (" Image has Target ID compatible with the current environment: %s\n " ,
2047
+ info->Arch );
2048
+ return true ;
2049
+ }
2050
+
1901
2051
int __tgt_rtl_number_of_devices () {
1902
2052
// If the construction failed, no methods are safe to call
1903
2053
if (DeviceInfo.ConstructionSucceeded ) {
@@ -1914,8 +2064,11 @@ int64_t __tgt_rtl_init_requires(int64_t RequiresFlags) {
1914
2064
}
1915
2065
1916
2066
int32_t __tgt_rtl_init_device (int DeviceId) {
1917
- hsa_status_t Err;
1918
-
2067
+ hsa_status_t Err = hsa_init ();
2068
+ if (Err != HSA_STATUS_SUCCESS) {
2069
+ DP (" HSA Initialization Failed.\n " );
2070
+ return HSA_STATUS_ERROR;
2071
+ }
1919
2072
// this is per device id init
1920
2073
DP (" Initialize the device id: %d\n " , DeviceId);
1921
2074
0 commit comments