Skip to content

Commit 72c560d

Browse files
committed
Revert "[OffloadBundler] Compress bundles over 4GB (#122307)"
revert due to failure in buildbot https://lab.llvm.org/buildbot/#/builders/144/builds/16114 This reverts commit 4e2efc3.
1 parent 4e2efc3 commit 72c560d

File tree

5 files changed

+43
-172
lines changed

5 files changed

+43
-172
lines changed

clang/docs/ClangOffloadBundler.rst

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -542,5 +542,3 @@ The compressed offload bundle begins with a header followed by the compressed bi
542542

543543
- **Compressed Data**:
544544
The actual compressed binary data follows the header. Its size can be inferred from the total size of the file minus the header size.
545-
546-
> **Note**: Version 3 of the format is under development. It uses 64-bit fields for Total File Size and Uncompressed Binary Size to support files larger than 4GB. To experiment with version 3, set the environment variable `COMPRESSED_BUNDLE_FORMAT_VERSION=3`. This support is experimental and not recommended for production use.

clang/docs/ReleaseNotes.rst

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1133,7 +1133,6 @@ RISC-V Support
11331133
CUDA/HIP Language Changes
11341134
^^^^^^^^^^^^^^^^^^^^^^^^^
11351135
- Fixed a bug about overriding a constexpr pure-virtual member function with a non-constexpr virtual member function which causes compilation failure when including standard C++ header `format`.
1136-
- Added initial support for version 3 of the compressed offload bundle format, which uses 64-bit fields for Total File Size and Uncompressed Binary Size. This enables support for files larger than 4GB. The support is currently experimental and can be enabled by setting the environment variable `COMPRESSED_BUNDLE_FORMAT_VERSION=3`.
11371136

11381137
CUDA Support
11391138
^^^^^^^^^^^^

clang/include/clang/Driver/OffloadBundler.h

Lines changed: 11 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@ class OffloadBundlerConfig {
3939
bool Verbose = false;
4040
llvm::compression::Format CompressionFormat;
4141
int CompressionLevel;
42-
uint16_t CompressedBundleVersion;
4342

4443
unsigned BundleAlignment = 1;
4544
unsigned HostInputIndex = ~0u;
@@ -101,63 +100,36 @@ struct OffloadTargetInfo {
101100
// - Version (2 bytes)
102101
// - Compression Method (2 bytes) - Uses the values from
103102
// 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).
103+
// - Total file size (4 bytes). Available in version 2 and above.
104+
// - Uncompressed Size (4 bytes).
106105
// - Truncated MD5 Hash (8 bytes).
107106
// - Compressed Data (variable length).
107+
108108
class CompressedOffloadBundle {
109109
private:
110110
static inline const size_t MagicSize = 4;
111111
static inline const size_t VersionFieldSize = sizeof(uint16_t);
112112
static inline const size_t MethodFieldSize = sizeof(uint16_t);
113-
// Legacy size fields for V1/V2
114-
static inline const size_t FileSizeFieldSizeV2 = sizeof(uint32_t);
115-
static inline const size_t UncompressedSizeFieldSizeV2 = sizeof(uint32_t);
116-
// New size fields for V3
117-
static inline const size_t FileSizeFieldSizeV3 = sizeof(uint64_t);
118-
static inline const size_t UncompressedSizeFieldSizeV3 = sizeof(uint64_t);
113+
static inline const size_t FileSizeFieldSize = sizeof(uint32_t);
114+
static inline const size_t UncompressedSizeFieldSize = sizeof(uint32_t);
119115
static inline const size_t HashFieldSize = sizeof(uint64_t);
120-
121-
// Keep V1 header size for backward compatibility
122116
static inline const size_t V1HeaderSize =
123117
MagicSize + VersionFieldSize + MethodFieldSize +
124-
UncompressedSizeFieldSizeV2 + HashFieldSize;
125-
126-
// Keep V2 header size for backward compatibility
118+
UncompressedSizeFieldSize + HashFieldSize;
127119
static inline const size_t V2HeaderSize =
128-
MagicSize + VersionFieldSize + FileSizeFieldSizeV2 + MethodFieldSize +
129-
UncompressedSizeFieldSizeV2 + HashFieldSize;
130-
131-
// Add V3 header size with 64-bit fields
132-
static inline const size_t V3HeaderSize =
133-
MagicSize + VersionFieldSize + FileSizeFieldSizeV3 + MethodFieldSize +
134-
UncompressedSizeFieldSizeV3 + HashFieldSize;
135-
120+
MagicSize + VersionFieldSize + FileSizeFieldSize + MethodFieldSize +
121+
UncompressedSizeFieldSize + HashFieldSize;
136122
static inline const llvm::StringRef MagicNumber = "CCOB";
123+
static inline const uint16_t Version = 2;
137124

138125
public:
139-
static inline const uint16_t DefaultVersion = 2;
140-
141-
// Helper method to get header size based on version
142-
static size_t getHeaderSize(uint16_t Version) {
143-
switch (Version) {
144-
case 1:
145-
return V1HeaderSize;
146-
case 2:
147-
return V2HeaderSize;
148-
case 3:
149-
return V3HeaderSize;
150-
default:
151-
llvm_unreachable("Unsupported version");
152-
}
153-
}
154-
155126
static llvm::Expected<std::unique_ptr<llvm::MemoryBuffer>>
156127
compress(llvm::compression::Params P, const llvm::MemoryBuffer &Input,
157-
uint16_t Version, bool Verbose = false);
128+
bool Verbose = false);
158129
static llvm::Expected<std::unique_ptr<llvm::MemoryBuffer>>
159130
decompress(const llvm::MemoryBuffer &Input, bool Verbose = false);
160131
};
132+
161133
} // namespace clang
162134

163135
#endif // LLVM_CLANG_DRIVER_OFFLOADBUNDLER_H

clang/lib/Driver/OffloadBundler.cpp

Lines changed: 32 additions & 106 deletions
Original file line numberDiff line numberDiff line change
@@ -935,8 +935,7 @@ CreateFileHandler(MemoryBuffer &FirstInput,
935935
"'" + FilesType + "': invalid file type specified");
936936
}
937937

938-
OffloadBundlerConfig::OffloadBundlerConfig()
939-
: CompressedBundleVersion(CompressedOffloadBundle::DefaultVersion) {
938+
OffloadBundlerConfig::OffloadBundlerConfig() {
940939
if (llvm::compression::zstd::isAvailable()) {
941940
CompressionFormat = llvm::compression::Format::Zstd;
942941
// Compression level 3 is usually sufficient for zstd since long distance
@@ -952,13 +951,16 @@ OffloadBundlerConfig::OffloadBundlerConfig()
952951
llvm::sys::Process::GetEnv("OFFLOAD_BUNDLER_IGNORE_ENV_VAR");
953952
if (IgnoreEnvVarOpt.has_value() && IgnoreEnvVarOpt.value() == "1")
954953
return;
954+
955955
auto VerboseEnvVarOpt = llvm::sys::Process::GetEnv("OFFLOAD_BUNDLER_VERBOSE");
956956
if (VerboseEnvVarOpt.has_value())
957957
Verbose = VerboseEnvVarOpt.value() == "1";
958+
958959
auto CompressEnvVarOpt =
959960
llvm::sys::Process::GetEnv("OFFLOAD_BUNDLER_COMPRESS");
960961
if (CompressEnvVarOpt.has_value())
961962
Compress = CompressEnvVarOpt.value() == "1";
963+
962964
auto CompressionLevelEnvVarOpt =
963965
llvm::sys::Process::GetEnv("OFFLOAD_BUNDLER_COMPRESSION_LEVEL");
964966
if (CompressionLevelEnvVarOpt.has_value()) {
@@ -971,26 +973,6 @@ OffloadBundlerConfig::OffloadBundlerConfig()
971973
<< "Warning: Invalid value for OFFLOAD_BUNDLER_COMPRESSION_LEVEL: "
972974
<< CompressionLevelStr.str() << ". Ignoring it.\n";
973975
}
974-
auto CompressedBundleFormatVersionOpt =
975-
llvm::sys::Process::GetEnv("COMPRESSED_BUNDLE_FORMAT_VERSION");
976-
if (CompressedBundleFormatVersionOpt.has_value()) {
977-
llvm::StringRef VersionStr = CompressedBundleFormatVersionOpt.value();
978-
uint16_t Version;
979-
if (!VersionStr.getAsInteger(10, Version)) {
980-
if (Version >= 2 && Version <= 3)
981-
CompressedBundleVersion = Version;
982-
else
983-
llvm::errs()
984-
<< "Warning: Invalid value for COMPRESSED_BUNDLE_FORMAT_VERSION: "
985-
<< VersionStr.str()
986-
<< ". Valid values are 2 or 3. Using default version "
987-
<< CompressedBundleVersion << ".\n";
988-
} else
989-
llvm::errs()
990-
<< "Warning: Invalid value for COMPRESSED_BUNDLE_FORMAT_VERSION: "
991-
<< VersionStr.str() << ". Using default version "
992-
<< CompressedBundleVersion << ".\n";
993-
}
994976
}
995977

996978
// Utility function to format numbers with commas
@@ -1007,11 +989,12 @@ static std::string formatWithCommas(unsigned long long Value) {
1007989
llvm::Expected<std::unique_ptr<llvm::MemoryBuffer>>
1008990
CompressedOffloadBundle::compress(llvm::compression::Params P,
1009991
const llvm::MemoryBuffer &Input,
1010-
uint16_t Version, bool Verbose) {
992+
bool Verbose) {
1011993
if (!llvm::compression::zstd::isAvailable() &&
1012994
!llvm::compression::zlib::isAvailable())
1013995
return createStringError(llvm::inconvertibleErrorCode(),
1014996
"Compression not supported");
997+
1015998
llvm::Timer HashTimer("Hash Calculation Timer", "Hash calculation time",
1016999
*ClangOffloadBundlerTimerGroup);
10171000
if (Verbose)
@@ -1028,6 +1011,7 @@ CompressedOffloadBundle::compress(llvm::compression::Params P,
10281011
auto BufferUint8 = llvm::ArrayRef<uint8_t>(
10291012
reinterpret_cast<const uint8_t *>(Input.getBuffer().data()),
10301013
Input.getBuffer().size());
1014+
10311015
llvm::Timer CompressTimer("Compression Timer", "Compression time",
10321016
*ClangOffloadBundlerTimerGroup);
10331017
if (Verbose)
@@ -1037,54 +1021,22 @@ CompressedOffloadBundle::compress(llvm::compression::Params P,
10371021
CompressTimer.stopTimer();
10381022

10391023
uint16_t CompressionMethod = static_cast<uint16_t>(P.format);
1040-
1041-
// Store sizes in 64-bit variables first
1042-
uint64_t UncompressedSize64 = Input.getBuffer().size();
1043-
uint64_t TotalFileSize64;
1044-
1045-
// Calculate total file size based on version
1046-
if (Version == 2) {
1047-
// For V2, ensure the sizes don't exceed 32-bit limit
1048-
if (UncompressedSize64 > std::numeric_limits<uint32_t>::max())
1049-
return createStringError(llvm::inconvertibleErrorCode(),
1050-
"Uncompressed size exceeds version 2 limit");
1051-
if ((MagicNumber.size() + sizeof(uint32_t) + sizeof(Version) +
1052-
sizeof(CompressionMethod) + sizeof(uint32_t) + sizeof(TruncatedHash) +
1053-
CompressedBuffer.size()) > std::numeric_limits<uint32_t>::max())
1054-
return createStringError(llvm::inconvertibleErrorCode(),
1055-
"Total file size exceeds version 2 limit");
1056-
1057-
TotalFileSize64 = MagicNumber.size() + sizeof(uint32_t) + sizeof(Version) +
1058-
sizeof(CompressionMethod) + sizeof(uint32_t) +
1059-
sizeof(TruncatedHash) + CompressedBuffer.size();
1060-
} else { // Version 3
1061-
TotalFileSize64 = MagicNumber.size() + sizeof(uint64_t) + sizeof(Version) +
1062-
sizeof(CompressionMethod) + sizeof(uint64_t) +
1063-
sizeof(TruncatedHash) + CompressedBuffer.size();
1064-
}
1024+
uint32_t UncompressedSize = Input.getBuffer().size();
1025+
uint32_t TotalFileSize = MagicNumber.size() + sizeof(TotalFileSize) +
1026+
sizeof(Version) + sizeof(CompressionMethod) +
1027+
sizeof(UncompressedSize) + sizeof(TruncatedHash) +
1028+
CompressedBuffer.size();
10651029

10661030
SmallVector<char, 0> FinalBuffer;
10671031
llvm::raw_svector_ostream OS(FinalBuffer);
10681032
OS << MagicNumber;
10691033
OS.write(reinterpret_cast<const char *>(&Version), sizeof(Version));
10701034
OS.write(reinterpret_cast<const char *>(&CompressionMethod),
10711035
sizeof(CompressionMethod));
1072-
1073-
// Write size fields according to version
1074-
if (Version == 2) {
1075-
uint32_t TotalFileSize32 = static_cast<uint32_t>(TotalFileSize64);
1076-
uint32_t UncompressedSize32 = static_cast<uint32_t>(UncompressedSize64);
1077-
OS.write(reinterpret_cast<const char *>(&TotalFileSize32),
1078-
sizeof(TotalFileSize32));
1079-
OS.write(reinterpret_cast<const char *>(&UncompressedSize32),
1080-
sizeof(UncompressedSize32));
1081-
} else { // Version 3
1082-
OS.write(reinterpret_cast<const char *>(&TotalFileSize64),
1083-
sizeof(TotalFileSize64));
1084-
OS.write(reinterpret_cast<const char *>(&UncompressedSize64),
1085-
sizeof(UncompressedSize64));
1086-
}
1087-
1036+
OS.write(reinterpret_cast<const char *>(&TotalFileSize),
1037+
sizeof(TotalFileSize));
1038+
OS.write(reinterpret_cast<const char *>(&UncompressedSize),
1039+
sizeof(UncompressedSize));
10881040
OS.write(reinterpret_cast<const char *>(&TruncatedHash),
10891041
sizeof(TruncatedHash));
10901042
OS.write(reinterpret_cast<const char *>(CompressedBuffer.data()),
@@ -1094,17 +1046,18 @@ CompressedOffloadBundle::compress(llvm::compression::Params P,
10941046
auto MethodUsed =
10951047
P.format == llvm::compression::Format::Zstd ? "zstd" : "zlib";
10961048
double CompressionRate =
1097-
static_cast<double>(UncompressedSize64) / CompressedBuffer.size();
1049+
static_cast<double>(UncompressedSize) / CompressedBuffer.size();
10981050
double CompressionTimeSeconds = CompressTimer.getTotalTime().getWallTime();
10991051
double CompressionSpeedMBs =
1100-
(UncompressedSize64 / (1024.0 * 1024.0)) / CompressionTimeSeconds;
1052+
(UncompressedSize / (1024.0 * 1024.0)) / CompressionTimeSeconds;
1053+
11011054
llvm::errs() << "Compressed bundle format version: " << Version << "\n"
11021055
<< "Total file size (including headers): "
1103-
<< formatWithCommas(TotalFileSize64) << " bytes\n"
1056+
<< formatWithCommas(TotalFileSize) << " bytes\n"
11041057
<< "Compression method used: " << MethodUsed << "\n"
11051058
<< "Compression level: " << P.level << "\n"
11061059
<< "Binary size before compression: "
1107-
<< formatWithCommas(UncompressedSize64) << " bytes\n"
1060+
<< formatWithCommas(UncompressedSize) << " bytes\n"
11081061
<< "Binary size after compression: "
11091062
<< formatWithCommas(CompressedBuffer.size()) << " bytes\n"
11101063
<< "Compression rate: "
@@ -1116,17 +1069,16 @@ CompressedOffloadBundle::compress(llvm::compression::Params P,
11161069
<< "Truncated MD5 hash: "
11171070
<< llvm::format_hex(TruncatedHash, 16) << "\n";
11181071
}
1119-
11201072
return llvm::MemoryBuffer::getMemBufferCopy(
11211073
llvm::StringRef(FinalBuffer.data(), FinalBuffer.size()));
11221074
}
11231075

11241076
llvm::Expected<std::unique_ptr<llvm::MemoryBuffer>>
11251077
CompressedOffloadBundle::decompress(const llvm::MemoryBuffer &Input,
11261078
bool Verbose) {
1079+
11271080
StringRef Blob = Input.getBuffer();
11281081

1129-
// Check minimum header size (using V1 as it's the smallest)
11301082
if (Blob.size() < V1HeaderSize)
11311083
return llvm::MemoryBuffer::getMemBufferCopy(Blob);
11321084

@@ -1139,56 +1091,31 @@ CompressedOffloadBundle::decompress(const llvm::MemoryBuffer &Input,
11391091

11401092
size_t CurrentOffset = MagicSize;
11411093

1142-
// Read version
11431094
uint16_t ThisVersion;
11441095
memcpy(&ThisVersion, Blob.data() + CurrentOffset, sizeof(uint16_t));
11451096
CurrentOffset += VersionFieldSize;
11461097

1147-
// Verify header size based on version
1148-
if (ThisVersion >= 2 && ThisVersion <= 3) {
1149-
size_t RequiredSize = (ThisVersion == 2) ? V2HeaderSize : V3HeaderSize;
1150-
if (Blob.size() < RequiredSize)
1151-
return createStringError(inconvertibleErrorCode(),
1152-
"Compressed bundle header size too small");
1153-
}
1154-
1155-
// Read compression method
11561098
uint16_t CompressionMethod;
11571099
memcpy(&CompressionMethod, Blob.data() + CurrentOffset, sizeof(uint16_t));
11581100
CurrentOffset += MethodFieldSize;
11591101

1160-
// Read total file size (version 2+)
1161-
uint64_t TotalFileSize = 0;
1102+
uint32_t TotalFileSize;
11621103
if (ThisVersion >= 2) {
1163-
if (ThisVersion == 2) {
1164-
uint32_t TotalFileSize32;
1165-
memcpy(&TotalFileSize32, Blob.data() + CurrentOffset, sizeof(uint32_t));
1166-
TotalFileSize = TotalFileSize32;
1167-
CurrentOffset += FileSizeFieldSizeV2;
1168-
} else { // Version 3
1169-
memcpy(&TotalFileSize, Blob.data() + CurrentOffset, sizeof(uint64_t));
1170-
CurrentOffset += FileSizeFieldSizeV3;
1171-
}
1104+
if (Blob.size() < V2HeaderSize)
1105+
return createStringError(inconvertibleErrorCode(),
1106+
"Compressed bundle header size too small");
1107+
memcpy(&TotalFileSize, Blob.data() + CurrentOffset, sizeof(uint32_t));
1108+
CurrentOffset += FileSizeFieldSize;
11721109
}
11731110

1174-
// Read uncompressed size
1175-
uint64_t UncompressedSize = 0;
1176-
if (ThisVersion <= 2) {
1177-
uint32_t UncompressedSize32;
1178-
memcpy(&UncompressedSize32, Blob.data() + CurrentOffset, sizeof(uint32_t));
1179-
UncompressedSize = UncompressedSize32;
1180-
CurrentOffset += UncompressedSizeFieldSizeV2;
1181-
} else { // Version 3
1182-
memcpy(&UncompressedSize, Blob.data() + CurrentOffset, sizeof(uint64_t));
1183-
CurrentOffset += UncompressedSizeFieldSizeV3;
1184-
}
1111+
uint32_t UncompressedSize;
1112+
memcpy(&UncompressedSize, Blob.data() + CurrentOffset, sizeof(uint32_t));
1113+
CurrentOffset += UncompressedSizeFieldSize;
11851114

1186-
// Read hash
11871115
uint64_t StoredHash;
11881116
memcpy(&StoredHash, Blob.data() + CurrentOffset, sizeof(uint64_t));
11891117
CurrentOffset += HashFieldSize;
11901118

1191-
// Determine compression format
11921119
llvm::compression::Format CompressionFormat;
11931120
if (CompressionMethod ==
11941121
static_cast<uint16_t>(llvm::compression::Format::Zlib))
@@ -1454,8 +1381,7 @@ Error OffloadBundler::BundleFiles() {
14541381
auto CompressionResult = CompressedOffloadBundle::compress(
14551382
{BundlerConfig.CompressionFormat, BundlerConfig.CompressionLevel,
14561383
/*zstdEnableLdm=*/true},
1457-
*BufferMemory, BundlerConfig.CompressedBundleVersion,
1458-
BundlerConfig.Verbose);
1384+
*BufferMemory, BundlerConfig.Verbose);
14591385
if (auto Error = CompressionResult.takeError())
14601386
return Error;
14611387

clang/test/Driver/clang-offload-bundler-zlib.c

Lines changed: 0 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -42,30 +42,6 @@
4242
// NOHOST-DAG: hip-amdgcn-amd-amdhsa--gfx906
4343
//
4444

45-
// Check compression/decompression of offload bundle using version 3 format.
46-
//
47-
// RUN: env OFFLOAD_BUNDLER_COMPRESS=1 OFFLOAD_BUNDLER_VERBOSE=1 COMPRESSED_BUNDLE_FORMAT_VERSION=3 \
48-
// RUN: clang-offload-bundler -type=bc -targets=hip-amdgcn-amd-amdhsa--gfx900,hip-amdgcn-amd-amdhsa--gfx906 \
49-
// RUN: -input=%t.tgt1 -input=%t.tgt2 -output=%t.hip.bundle.bc 2>&1 | \
50-
// RUN: FileCheck -check-prefix=COMPRESS %s
51-
// RUN: clang-offload-bundler -type=bc -list -input=%t.hip.bundle.bc | FileCheck -check-prefix=NOHOST %s
52-
// RUN: env OFFLOAD_BUNDLER_VERBOSE=1 \
53-
// RUN: clang-offload-bundler -type=bc -targets=hip-amdgcn-amd-amdhsa--gfx900,hip-amdgcn-amd-amdhsa--gfx906 \
54-
// RUN: -output=%t.res.tgt1 -output=%t.res.tgt2 -input=%t.hip.bundle.bc -unbundle 2>&1 | \
55-
// RUN: FileCheck -check-prefix=DECOMPRESS %s
56-
// RUN: diff %t.tgt1 %t.res.tgt1
57-
// RUN: diff %t.tgt2 %t.res.tgt2
58-
//
59-
// COMPRESS: Compressed bundle format version: 3
60-
// COMPRESS: Compression method used: zlib
61-
// COMPRESS: Compression level: 6
62-
// DECOMPRESS: Compressed bundle format version: 3
63-
// DECOMPRESS: Decompression method: zlib
64-
// DECOMPRESS: Hashes match: Yes
65-
// NOHOST-NOT: host-
66-
// NOHOST-DAG: hip-amdgcn-amd-amdhsa--gfx900
67-
// NOHOST-DAG: hip-amdgcn-amd-amdhsa--gfx906
68-
6945
// Check -compression-level= option
7046

7147
// RUN: clang-offload-bundler -type=bc -targets=hip-amdgcn-amd-amdhsa--gfx900,hip-amdgcn-amd-amdhsa--gfx906 \

0 commit comments

Comments
 (0)