Home | History | Annotate | Line # | Download | only in ToolChains
      1 //===--- ROCm.h - ROCm installation detector --------------------*- C++ -*-===//
      2 //
      3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
      4 // See https://llvm.org/LICENSE.txt for license information.
      5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
      6 //
      7 //===----------------------------------------------------------------------===//
      8 
      9 #ifndef LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_ROCM_H
     10 #define LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_ROCM_H
     11 
     12 #include "clang/Basic/Cuda.h"
     13 #include "clang/Basic/LLVM.h"
     14 #include "clang/Driver/Driver.h"
     15 #include "clang/Driver/Options.h"
     16 #include "llvm/ADT/SmallString.h"
     17 #include "llvm/ADT/StringMap.h"
     18 #include "llvm/ADT/Triple.h"
     19 #include "llvm/Option/ArgList.h"
     20 #include "llvm/Support/VersionTuple.h"
     21 
     22 namespace clang {
     23 namespace driver {
     24 
     25 /// A class to find a viable ROCM installation
     26 /// TODO: Generalize to handle libclc.
     27 class RocmInstallationDetector {
     28 private:
     29   struct ConditionalLibrary {
     30     SmallString<0> On;
     31     SmallString<0> Off;
     32 
     33     bool isValid() const { return !On.empty() && !Off.empty(); }
     34 
     35     StringRef get(bool Enabled) const {
     36       assert(isValid());
     37       return Enabled ? On : Off;
     38     }
     39   };
     40 
     41   // Installation path candidate.
     42   struct Candidate {
     43     llvm::SmallString<0> Path;
     44     bool StrictChecking;
     45     // Release string for ROCm packages built with SPACK if not empty. The
     46     // installation directories of ROCm packages built with SPACK follow the
     47     // convention <package_name>-<rocm_release_string>-<hash>.
     48     std::string SPACKReleaseStr;
     49 
     50     bool isSPACK() const { return !SPACKReleaseStr.empty(); }
     51     Candidate(std::string Path, bool StrictChecking = false,
     52               StringRef SPACKReleaseStr = {})
     53         : Path(Path), StrictChecking(StrictChecking),
     54           SPACKReleaseStr(SPACKReleaseStr.str()) {}
     55   };
     56 
     57   const Driver &D;
     58   bool HasHIPRuntime = false;
     59   bool HasDeviceLibrary = false;
     60 
     61   // Default version if not detected or specified.
     62   const unsigned DefaultVersionMajor = 3;
     63   const unsigned DefaultVersionMinor = 5;
     64   const char *DefaultVersionPatch = "0";
     65 
     66   // The version string in Major.Minor.Patch format.
     67   std::string DetectedVersion;
     68   // Version containing major and minor.
     69   llvm::VersionTuple VersionMajorMinor;
     70   // Version containing patch.
     71   std::string VersionPatch;
     72 
     73   // ROCm path specified by --rocm-path.
     74   StringRef RocmPathArg;
     75   // ROCm device library paths specified by --rocm-device-lib-path.
     76   std::vector<std::string> RocmDeviceLibPathArg;
     77   // HIP runtime path specified by --hip-path.
     78   StringRef HIPPathArg;
     79   // HIP version specified by --hip-version.
     80   StringRef HIPVersionArg;
     81   // Wheter -nogpulib is specified.
     82   bool NoBuiltinLibs = false;
     83 
     84   // Paths
     85   SmallString<0> InstallPath;
     86   SmallString<0> BinPath;
     87   SmallString<0> LibPath;
     88   SmallString<0> LibDevicePath;
     89   SmallString<0> IncludePath;
     90   llvm::StringMap<std::string> LibDeviceMap;
     91 
     92   // Libraries that are always linked.
     93   SmallString<0> OCML;
     94   SmallString<0> OCKL;
     95 
     96   // Libraries that are always linked depending on the language
     97   SmallString<0> OpenCL;
     98   SmallString<0> HIP;
     99 
    100   // Asan runtime library
    101   SmallString<0> AsanRTL;
    102 
    103   // Libraries swapped based on compile flags.
    104   ConditionalLibrary WavefrontSize64;
    105   ConditionalLibrary FiniteOnly;
    106   ConditionalLibrary UnsafeMath;
    107   ConditionalLibrary DenormalsAreZero;
    108   ConditionalLibrary CorrectlyRoundedSqrt;
    109 
    110   // Cache ROCm installation search paths.
    111   SmallVector<Candidate, 4> ROCmSearchDirs;
    112   bool PrintROCmSearchDirs;
    113   bool Verbose;
    114 
    115   bool allGenericLibsValid() const {
    116     return !OCML.empty() && !OCKL.empty() && !OpenCL.empty() && !HIP.empty() &&
    117            WavefrontSize64.isValid() && FiniteOnly.isValid() &&
    118            UnsafeMath.isValid() && DenormalsAreZero.isValid() &&
    119            CorrectlyRoundedSqrt.isValid();
    120   }
    121 
    122   void scanLibDevicePath(llvm::StringRef Path);
    123   bool parseHIPVersionFile(llvm::StringRef V);
    124   const SmallVectorImpl<Candidate> &getInstallationPathCandidates();
    125 
    126   /// Find the path to a SPACK package under the ROCm candidate installation
    127   /// directory if the candidate is a SPACK ROCm candidate. \returns empty
    128   /// string if the candidate is not SPACK ROCm candidate or the requested
    129   /// package is not found.
    130   llvm::SmallString<0> findSPACKPackage(const Candidate &Cand,
    131                                         StringRef PackageName);
    132 
    133 public:
    134   RocmInstallationDetector(const Driver &D, const llvm::Triple &HostTriple,
    135                            const llvm::opt::ArgList &Args,
    136                            bool DetectHIPRuntime = true,
    137                            bool DetectDeviceLib = false);
    138 
    139   /// Get file paths of default bitcode libraries common to AMDGPU based
    140   /// toolchains.
    141   llvm::SmallVector<std::string, 12>
    142   getCommonBitcodeLibs(const llvm::opt::ArgList &DriverArgs,
    143                        StringRef LibDeviceFile, bool Wave64, bool DAZ,
    144                        bool FiniteOnly, bool UnsafeMathOpt,
    145                        bool FastRelaxedMath, bool CorrectSqrt) const;
    146 
    147   /// Check whether we detected a valid HIP runtime.
    148   bool hasHIPRuntime() const { return HasHIPRuntime; }
    149 
    150   /// Check whether we detected a valid ROCm device library.
    151   bool hasDeviceLibrary() const { return HasDeviceLibrary; }
    152 
    153   /// Print information about the detected ROCm installation.
    154   void print(raw_ostream &OS) const;
    155 
    156   /// Get the detected Rocm install's version.
    157   // RocmVersion version() const { return Version; }
    158 
    159   /// Get the detected Rocm installation path.
    160   StringRef getInstallPath() const { return InstallPath; }
    161 
    162   /// Get the detected path to Rocm's bin directory.
    163   // StringRef getBinPath() const { return BinPath; }
    164 
    165   /// Get the detected Rocm Include path.
    166   StringRef getIncludePath() const { return IncludePath; }
    167 
    168   /// Get the detected Rocm library path.
    169   StringRef getLibPath() const { return LibPath; }
    170 
    171   /// Get the detected Rocm device library path.
    172   StringRef getLibDevicePath() const { return LibDevicePath; }
    173 
    174   StringRef getOCMLPath() const {
    175     assert(!OCML.empty());
    176     return OCML;
    177   }
    178 
    179   StringRef getOCKLPath() const {
    180     assert(!OCKL.empty());
    181     return OCKL;
    182   }
    183 
    184   StringRef getOpenCLPath() const {
    185     assert(!OpenCL.empty());
    186     return OpenCL;
    187   }
    188 
    189   StringRef getHIPPath() const {
    190     assert(!HIP.empty());
    191     return HIP;
    192   }
    193 
    194   /// Returns empty string of Asan runtime library is not available.
    195   StringRef getAsanRTLPath() const { return AsanRTL; }
    196 
    197   StringRef getWavefrontSize64Path(bool Enabled) const {
    198     return WavefrontSize64.get(Enabled);
    199   }
    200 
    201   StringRef getFiniteOnlyPath(bool Enabled) const {
    202     return FiniteOnly.get(Enabled);
    203   }
    204 
    205   StringRef getUnsafeMathPath(bool Enabled) const {
    206     return UnsafeMath.get(Enabled);
    207   }
    208 
    209   StringRef getDenormalsAreZeroPath(bool Enabled) const {
    210     return DenormalsAreZero.get(Enabled);
    211   }
    212 
    213   StringRef getCorrectlyRoundedSqrtPath(bool Enabled) const {
    214     return CorrectlyRoundedSqrt.get(Enabled);
    215   }
    216 
    217   /// Get libdevice file for given architecture
    218   std::string getLibDeviceFile(StringRef Gpu) const {
    219     return LibDeviceMap.lookup(Gpu);
    220   }
    221 
    222   void AddHIPIncludeArgs(const llvm::opt::ArgList &DriverArgs,
    223                          llvm::opt::ArgStringList &CC1Args) const;
    224 
    225   void detectDeviceLibrary();
    226   void detectHIPRuntime();
    227 
    228   /// Get the values for --rocm-device-lib-path arguments
    229   std::vector<std::string> getRocmDeviceLibPathArg() const {
    230     return RocmDeviceLibPathArg;
    231   }
    232 
    233   /// Get the value for --rocm-path argument
    234   StringRef getRocmPathArg() const { return RocmPathArg; }
    235 
    236   /// Get the value for --hip-version argument
    237   StringRef getHIPVersionArg() const { return HIPVersionArg; }
    238 
    239   std::string getHIPVersion() const { return DetectedVersion; }
    240 };
    241 
    242 } // end namespace driver
    243 } // end namespace clang
    244 
    245 #endif // LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_ROCM_H
    246