1 //===- OffloadBundler.h - File Bundling and Unbundling ----------*- 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 /// \file 10 /// This file defines an offload bundling API that bundles different files 11 /// that relate with the same source code but different targets into a single 12 /// one. Also the implements the opposite functionality, i.e. unbundle files 13 /// previous created by this API. 14 /// 15 //===----------------------------------------------------------------------===// 16 17 #ifndef LLVM_CLANG_DRIVER_OFFLOADBUNDLER_H 18 #define LLVM_CLANG_DRIVER_OFFLOADBUNDLER_H 19 20 #include "llvm/Support/Compression.h" 21 #include "llvm/Support/Error.h" 22 #include "llvm/TargetParser/Triple.h" 23 #include <llvm/Support/MemoryBuffer.h> 24 #include <string> 25 #include <vector> 26 27 namespace clang { 28 29 class OffloadBundlerConfig { 30 public: 31 OffloadBundlerConfig(); 32 33 bool AllowNoHost = false; 34 bool AllowMissingBundles = false; 35 bool CheckInputArchive = false; 36 bool PrintExternalCommands = false; 37 bool HipOpenmpCompatible = false; 38 bool Compress = false; 39 bool Verbose = false; 40 llvm::compression::Format CompressionFormat; 41 int CompressionLevel; 42 uint16_t CompressedBundleVersion; 43 44 unsigned BundleAlignment = 1; 45 unsigned HostInputIndex = ~0u; 46 47 std::string FilesType; 48 std::string ObjcopyPath; 49 50 // TODO: Convert these to llvm::SmallVector 51 std::vector<std::string> TargetNames; 52 std::vector<std::string> InputFileNames; 53 std::vector<std::string> OutputFileNames; 54 }; 55 56 class OffloadBundler { 57 public: 58 const OffloadBundlerConfig &BundlerConfig; 59 60 // TODO: Add error checking from ClangOffloadBundler.cpp OffloadBundler(const OffloadBundlerConfig & BC)61 OffloadBundler(const OffloadBundlerConfig &BC) : BundlerConfig(BC) {} 62 63 // List bundle IDs. Return true if an error was found. 64 static llvm::Error 65 ListBundleIDsInFile(llvm::StringRef InputFileName, 66 const OffloadBundlerConfig &BundlerConfig); 67 68 llvm::Error BundleFiles(); 69 llvm::Error UnbundleFiles(); 70 llvm::Error UnbundleArchive(); 71 }; 72 73 /// Obtain the offload kind, real machine triple, and an optional TargetID 74 /// out of the target information specified by the user. 75 /// Bundle Entry ID (or, Offload Target String) has following components: 76 /// * Offload Kind - Host, OpenMP, or HIP 77 /// * Triple - Standard LLVM Triple 78 /// * TargetID (Optional) - target ID, like gfx906:xnack+ or sm_30 79 struct OffloadTargetInfo { 80 llvm::StringRef OffloadKind; 81 llvm::Triple Triple; 82 llvm::StringRef TargetID; 83 84 const OffloadBundlerConfig &BundlerConfig; 85 86 OffloadTargetInfo(const llvm::StringRef Target, 87 const OffloadBundlerConfig &BC); 88 bool hasHostKind() const; 89 bool isOffloadKindValid() const; 90 bool isOffloadKindCompatible(const llvm::StringRef TargetOffloadKind) const; 91 bool isTripleValid() const; 92 bool operator==(const OffloadTargetInfo &Target) const; 93 std::string str() const; 94 }; 95 96 // CompressedOffloadBundle represents the format for the compressed offload 97 // bundles. 98 // 99 // The format is as follows: 100 // - Magic Number (4 bytes) - A constant "CCOB". 101 // - Version (2 bytes) 102 // - Compression Method (2 bytes) - Uses the values from 103 // llvm::compression::Format. 104 // - Total file size (4 bytes in V2, 8 bytes in V3). 105 // - Uncompressed Size (4 bytes in V1/V2, 8 bytes in V3). 106 // - Truncated MD5 Hash (8 bytes). 107 // - Compressed Data (variable length). 108 class CompressedOffloadBundle { 109 private: 110 static inline const llvm::StringRef MagicNumber = "CCOB"; 111 112 public: 113 struct CompressedBundleHeader { 114 unsigned Version; 115 llvm::compression::Format CompressionFormat; 116 std::optional<size_t> FileSize; 117 size_t UncompressedFileSize; 118 uint64_t Hash; 119 120 static llvm::Expected<CompressedBundleHeader> tryParse(llvm::StringRef); 121 }; 122 123 static inline const uint16_t DefaultVersion = 2; 124 125 static llvm::Expected<std::unique_ptr<llvm::MemoryBuffer>> 126 compress(llvm::compression::Params P, const llvm::MemoryBuffer &Input, 127 uint16_t Version, bool Verbose = false); 128 static llvm::Expected<std::unique_ptr<llvm::MemoryBuffer>> 129 decompress(const llvm::MemoryBuffer &Input, bool Verbose = false); 130 }; 131 132 /// Check whether the bundle id is in the following format: 133 /// <kind>-<triple>[-<target id>[:target features]] 134 /// <triple> := <arch>-<vendor>-<os>-<env> 135 bool checkOffloadBundleID(const llvm::StringRef Str); 136 } // namespace clang 137 138 #endif // LLVM_CLANG_DRIVER_OFFLOADBUNDLER_H 139