Skip to content

Commit c89b262

Browse files
committed
[ClangOffloadBundler] Add file size to header
__hipRegisterFatBinary only accepts one pointer argument. It is expected to get the fat binary size from the header. This patch adds a file size field to the header of the compressed bundle.
1 parent 2e26ee9 commit c89b262

File tree

4 files changed

+47
-26
lines changed

4 files changed

+47
-26
lines changed

clang/docs/ClangOffloadBundler.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -517,6 +517,9 @@ The compressed offload bundle begins with a header followed by the compressed bi
517517
- **Magic Number (4 bytes)**:
518518
This is a unique identifier to distinguish compressed offload bundles. The value is the string 'CCOB' (Compressed Clang Offload Bundle).
519519

520+
- **Total File Size (32-bit unsigned int)**:
521+
This is the total size (in bytes) of the file, including the header.
522+
520523
- **Version Number (16-bit unsigned int)**:
521524
This denotes the version of the compressed offload bundle format. The current version is `1`.
522525

clang/include/clang/Driver/OffloadBundler.h

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ struct OffloadTargetInfo {
9797
//
9898
// The format is as follows:
9999
// - Magic Number (4 bytes) - A constant "CCOB".
100+
// - Total file size (4 bytes).
100101
// - Version (2 bytes)
101102
// - Compression Method (2 bytes) - Uses the values from
102103
// llvm::compression::Format.
@@ -107,13 +108,14 @@ struct OffloadTargetInfo {
107108
class CompressedOffloadBundle {
108109
private:
109110
static inline const size_t MagicSize = 4;
111+
static inline const size_t FileSizeFieldSize = sizeof(uint32_t);
110112
static inline const size_t VersionFieldSize = sizeof(uint16_t);
111113
static inline const size_t MethodFieldSize = sizeof(uint16_t);
112-
static inline const size_t SizeFieldSize = sizeof(uint32_t);
113-
static inline const size_t HashFieldSize = 8;
114-
static inline const size_t HeaderSize = MagicSize + VersionFieldSize +
115-
MethodFieldSize + SizeFieldSize +
116-
HashFieldSize;
114+
static inline const size_t UncompressedSizeFieldSize = sizeof(uint32_t);
115+
static inline const size_t HashFieldSize = sizeof(uint64_t);
116+
static inline const size_t HeaderSize =
117+
MagicSize + FileSizeFieldSize + VersionFieldSize + MethodFieldSize +
118+
UncompressedSizeFieldSize + HashFieldSize;
117119
static inline const llvm::StringRef MagicNumber = "CCOB";
118120
static inline const uint16_t Version = 1;
119121

clang/lib/Driver/OffloadBundler.cpp

Lines changed: 28 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1010,10 +1010,16 @@ CompressedOffloadBundle::compress(llvm::compression::Params P,
10101010

10111011
uint16_t CompressionMethod = static_cast<uint16_t>(P.format);
10121012
uint32_t UncompressedSize = Input.getBuffer().size();
1013+
uint32_t TotalFileSize = MagicNumber.size() + sizeof(TotalFileSize) +
1014+
sizeof(Version) + sizeof(CompressionMethod) +
1015+
sizeof(UncompressedSize) + sizeof(TruncatedHash) +
1016+
CompressedBuffer.size();
10131017

10141018
SmallVector<char, 0> FinalBuffer;
10151019
llvm::raw_svector_ostream OS(FinalBuffer);
10161020
OS << MagicNumber;
1021+
OS.write(reinterpret_cast<const char *>(&TotalFileSize),
1022+
sizeof(TotalFileSize));
10171023
OS.write(reinterpret_cast<const char *>(&Version), sizeof(Version));
10181024
OS.write(reinterpret_cast<const char *>(&CompressionMethod),
10191025
sizeof(CompressionMethod));
@@ -1033,7 +1039,9 @@ CompressedOffloadBundle::compress(llvm::compression::Params P,
10331039
double CompressionSpeedMBs =
10341040
(UncompressedSize / (1024.0 * 1024.0)) / CompressionTimeSeconds;
10351041

1036-
llvm::errs() << "Compressed bundle format version: " << Version << "\n"
1042+
llvm::errs() << "Total file size (including headers): "
1043+
<< formatWithCommas(TotalFileSize) << " bytes\n"
1044+
<< "Compressed bundle format version: " << Version << "\n"
10371045
<< "Compression method used: " << MethodUsed << "\n"
10381046
<< "Compression level: " << P.level << "\n"
10391047
<< "Binary size before compression: "
@@ -1069,21 +1077,26 @@ CompressedOffloadBundle::decompress(const llvm::MemoryBuffer &Input,
10691077
return llvm::MemoryBuffer::getMemBufferCopy(Blob);
10701078
}
10711079

1080+
size_t CurrentOffset = MagicSize;
1081+
uint32_t TotalFileSize;
1082+
memcpy(&TotalFileSize, Blob.data() + CurrentOffset, sizeof(uint32_t));
1083+
CurrentOffset += FileSizeFieldSize;
1084+
10721085
uint16_t ThisVersion;
1086+
memcpy(&ThisVersion, Blob.data() + CurrentOffset, sizeof(uint16_t));
1087+
CurrentOffset += VersionFieldSize;
1088+
10731089
uint16_t CompressionMethod;
1090+
memcpy(&CompressionMethod, Blob.data() + CurrentOffset, sizeof(uint16_t));
1091+
CurrentOffset += MethodFieldSize;
1092+
10741093
uint32_t UncompressedSize;
1094+
memcpy(&UncompressedSize, Blob.data() + CurrentOffset, sizeof(uint32_t));
1095+
CurrentOffset += UncompressedSizeFieldSize;
1096+
10751097
uint64_t StoredHash;
1076-
memcpy(&ThisVersion, Input.getBuffer().data() + MagicNumber.size(),
1077-
sizeof(uint16_t));
1078-
memcpy(&CompressionMethod, Blob.data() + MagicSize + VersionFieldSize,
1079-
sizeof(uint16_t));
1080-
memcpy(&UncompressedSize,
1081-
Blob.data() + MagicSize + VersionFieldSize + MethodFieldSize,
1082-
sizeof(uint32_t));
1083-
memcpy(&StoredHash,
1084-
Blob.data() + MagicSize + VersionFieldSize + MethodFieldSize +
1085-
SizeFieldSize,
1086-
sizeof(uint64_t));
1098+
memcpy(&StoredHash, Blob.data() + CurrentOffset, sizeof(uint64_t));
1099+
CurrentOffset += HashFieldSize;
10871100

10881101
llvm::compression::Format CompressionFormat;
10891102
if (CompressionMethod ==
@@ -1135,7 +1148,9 @@ CompressedOffloadBundle::decompress(const llvm::MemoryBuffer &Input,
11351148
double DecompressionSpeedMBs =
11361149
(UncompressedSize / (1024.0 * 1024.0)) / DecompressionTimeSeconds;
11371150

1138-
llvm::errs() << "Compressed bundle format version: " << ThisVersion << "\n"
1151+
llvm::errs() << "Total file size (from header): "
1152+
<< formatWithCommas(TotalFileSize) << " bytes\n"
1153+
<< "Compressed bundle format version: " << ThisVersion << "\n"
11391154
<< "Decompression method: "
11401155
<< (CompressionFormat == llvm::compression::Format::Zlib
11411156
? "zlib"

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

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -22,19 +22,20 @@
2222
// Check compression/decompression of offload bundle.
2323
//
2424
// RUN: clang-offload-bundler -type=bc -targets=hip-amdgcn-amd-amdhsa--gfx900,hip-amdgcn-amd-amdhsa--gfx906 \
25-
// RUN: -input=%t.tgt1 -input=%t.tgt2 -output=%t.hip.bundle.bc -compress -verbose 2>&1 | \
26-
// RUN: FileCheck -check-prefix=COMPRESS %s
25+
// RUN: -input=%t.tgt1 -input=%t.tgt2 -output=%t.hip.bundle.bc -compress -verbose >%t.1.txt 2>&1
2726
// RUN: clang-offload-bundler -type=bc -list -input=%t.hip.bundle.bc | FileCheck -check-prefix=NOHOST %s
2827
// RUN: clang-offload-bundler -type=bc -targets=hip-amdgcn-amd-amdhsa--gfx900,hip-amdgcn-amd-amdhsa--gfx906 \
29-
// RUN: -output=%t.res.tgt1 -output=%t.res.tgt2 -input=%t.hip.bundle.bc -unbundle -verbose 2>&1 | \
30-
// RUN: FileCheck -check-prefix=DECOMPRESS %s
28+
// RUN: -output=%t.res.tgt1 -output=%t.res.tgt2 -input=%t.hip.bundle.bc -unbundle -verbose >%t.2.txt 2>&1
29+
// RUN: cat %t.1.txt %t.2.txt | FileCheck %s
3130
// RUN: diff %t.tgt1 %t.res.tgt1
3231
// RUN: diff %t.tgt2 %t.res.tgt2
3332
//
34-
// COMPRESS: Compression method used: zstd
35-
// COMPRESS: Compression level: 3
36-
// DECOMPRESS: Decompression method: zstd
37-
// DECOMPRESS: Hashes match: Yes
33+
// CHECK: Total file size (including headers): [[SIZE:[0-9]*]] bytes
34+
// CHECK: Compression method used: zstd
35+
// CHECK: Compression level: 3
36+
// CHECK: Total file size (from header): [[SIZE]] bytes
37+
// CHECK: Decompression method: zstd
38+
// CHECK: Hashes match: Yes
3839
// NOHOST-NOT: host-
3940
// NOHOST-DAG: hip-amdgcn-amd-amdhsa--gfx900
4041
// NOHOST-DAG: hip-amdgcn-amd-amdhsa--gfx906

0 commit comments

Comments
 (0)