@@ -924,6 +924,17 @@ CreateFileHandler(MemoryBuffer &FirstInput,
924
924
}
925
925
926
926
OffloadBundlerConfig::OffloadBundlerConfig () {
927
+ if (llvm::compression::zstd::isAvailable ()) {
928
+ CompressionFormat = llvm::compression::Format::Zstd;
929
+ // Compression level 3 is usually sufficient for zstd since long distance
930
+ // matching is enabled.
931
+ CompressionLevel = 3 ;
932
+ } else if (llvm::compression::zlib::isAvailable ()) {
933
+ CompressionFormat = llvm::compression::Format::Zlib;
934
+ // Use default level for zlib since higher level does not have significant
935
+ // improvement.
936
+ CompressionLevel = llvm::compression::zlib::DefaultCompression;
937
+ }
927
938
auto IgnoreEnvVarOpt =
928
939
llvm::sys::Process::GetEnv (" OFFLOAD_BUNDLER_IGNORE_ENV_VAR" );
929
940
if (IgnoreEnvVarOpt.has_value () && IgnoreEnvVarOpt.value () == " 1" )
@@ -937,11 +948,41 @@ OffloadBundlerConfig::OffloadBundlerConfig() {
937
948
llvm::sys::Process::GetEnv (" OFFLOAD_BUNDLER_COMPRESS" );
938
949
if (CompressEnvVarOpt.has_value ())
939
950
Compress = CompressEnvVarOpt.value () == " 1" ;
951
+
952
+ auto CompressionLevelEnvVarOpt =
953
+ llvm::sys::Process::GetEnv (" OFFLOAD_BUNDLER_COMPRESSION_LEVEL" );
954
+ if (CompressionLevelEnvVarOpt.has_value ()) {
955
+ llvm::StringRef CompressionLevelStr = CompressionLevelEnvVarOpt.value ();
956
+ int Level;
957
+ if (!CompressionLevelStr.getAsInteger (10 , Level))
958
+ CompressionLevel = Level;
959
+ else
960
+ llvm::errs ()
961
+ << " Warning: Invalid value for OFFLOAD_BUNDLER_COMPRESSION_LEVEL: "
962
+ << CompressionLevelStr.str () << " . Ignoring it.\n " ;
963
+ }
964
+ }
965
+
966
+ // Utility function to format numbers with commas
967
+ static std::string formatWithCommas (unsigned long long Value) {
968
+ std::string Num = std::to_string (Value);
969
+ int InsertPosition = Num.length () - 3 ;
970
+ while (InsertPosition > 0 ) {
971
+ Num.insert (InsertPosition, " ," );
972
+ InsertPosition -= 3 ;
973
+ }
974
+ return Num;
940
975
}
941
976
942
977
llvm::Expected<std::unique_ptr<llvm::MemoryBuffer>>
943
- CompressedOffloadBundle::compress (const llvm::MemoryBuffer &Input,
978
+ CompressedOffloadBundle::compress (llvm::compression::Params P,
979
+ const llvm::MemoryBuffer &Input,
944
980
bool Verbose) {
981
+ if (!llvm::compression::zstd::isAvailable () &&
982
+ !llvm::compression::zlib::isAvailable ())
983
+ return createStringError (llvm::inconvertibleErrorCode (),
984
+ " Compression not supported" );
985
+
945
986
llvm::Timer HashTimer (" Hash Calculation Timer" , " Hash calculation time" ,
946
987
ClangOffloadBundlerTimerGroup);
947
988
if (Verbose)
@@ -959,25 +1000,15 @@ CompressedOffloadBundle::compress(const llvm::MemoryBuffer &Input,
959
1000
reinterpret_cast <const uint8_t *>(Input.getBuffer ().data ()),
960
1001
Input.getBuffer ().size ());
961
1002
962
- llvm::compression::Format CompressionFormat;
963
-
964
- if (llvm::compression::zstd::isAvailable ())
965
- CompressionFormat = llvm::compression::Format::Zstd;
966
- else if (llvm::compression::zlib::isAvailable ())
967
- CompressionFormat = llvm::compression::Format::Zlib;
968
- else
969
- return createStringError (llvm::inconvertibleErrorCode (),
970
- " Compression not supported" );
971
-
972
1003
llvm::Timer CompressTimer (" Compression Timer" , " Compression time" ,
973
1004
ClangOffloadBundlerTimerGroup);
974
1005
if (Verbose)
975
1006
CompressTimer.startTimer ();
976
- llvm::compression::compress (CompressionFormat , BufferUint8, CompressedBuffer);
1007
+ llvm::compression::compress (P , BufferUint8, CompressedBuffer);
977
1008
if (Verbose)
978
1009
CompressTimer.stopTimer ();
979
1010
980
- uint16_t CompressionMethod = static_cast <uint16_t >(CompressionFormat );
1011
+ uint16_t CompressionMethod = static_cast <uint16_t >(P. format );
981
1012
uint32_t UncompressedSize = Input.getBuffer ().size ();
982
1013
983
1014
SmallVector<char , 0 > FinalBuffer;
@@ -995,17 +1026,29 @@ CompressedOffloadBundle::compress(const llvm::MemoryBuffer &Input,
995
1026
996
1027
if (Verbose) {
997
1028
auto MethodUsed =
998
- CompressionFormat == llvm::compression::Format::Zstd ? " zstd" : " zlib" ;
1029
+ P.format == llvm::compression::Format::Zstd ? " zstd" : " zlib" ;
1030
+ double CompressionRate =
1031
+ static_cast <double >(UncompressedSize) / CompressedBuffer.size ();
1032
+ double CompressionTimeSeconds = CompressTimer.getTotalTime ().getWallTime ();
1033
+ double CompressionSpeedMBs =
1034
+ (UncompressedSize / (1024.0 * 1024.0 )) / CompressionTimeSeconds;
1035
+
999
1036
llvm::errs () << " Compressed bundle format version: " << Version << " \n "
1000
1037
<< " Compression method used: " << MethodUsed << " \n "
1001
- << " Binary size before compression: " << UncompressedSize
1002
- << " bytes\n "
1003
- << " Binary size after compression: " << CompressedBuffer.size ()
1004
- << " bytes\n "
1038
+ << " Compression level: " << P.level << " \n "
1039
+ << " Binary size before compression: "
1040
+ << formatWithCommas (UncompressedSize) << " bytes\n "
1041
+ << " Binary size after compression: "
1042
+ << formatWithCommas (CompressedBuffer.size ()) << " bytes\n "
1043
+ << " Compression rate: "
1044
+ << llvm::format (" %.2lf" , CompressionRate) << " \n "
1045
+ << " Compression ratio: "
1046
+ << llvm::format (" %.2lf%%" , 100.0 / CompressionRate) << " \n "
1047
+ << " Compression speed: "
1048
+ << llvm::format (" %.2lf MB/s" , CompressionSpeedMBs) << " \n "
1005
1049
<< " Truncated MD5 hash: "
1006
1050
<< llvm::format_hex (TruncatedHash, 16 ) << " \n " ;
1007
1051
}
1008
-
1009
1052
return llvm::MemoryBuffer::getMemBufferCopy (
1010
1053
llvm::StringRef (FinalBuffer.data (), FinalBuffer.size ()));
1011
1054
}
@@ -1070,7 +1113,10 @@ CompressedOffloadBundle::decompress(const llvm::MemoryBuffer &Input,
1070
1113
if (Verbose) {
1071
1114
DecompressTimer.stopTimer ();
1072
1115
1073
- // Recalculate MD5 hash
1116
+ double DecompressionTimeSeconds =
1117
+ DecompressTimer.getTotalTime ().getWallTime ();
1118
+
1119
+ // Recalculate MD5 hash for integrity check
1074
1120
llvm::Timer HashRecalcTimer (" Hash Recalculation Timer" ,
1075
1121
" Hash recalculation time" ,
1076
1122
ClangOffloadBundlerTimerGroup);
@@ -1084,16 +1130,27 @@ CompressedOffloadBundle::decompress(const llvm::MemoryBuffer &Input,
1084
1130
HashRecalcTimer.stopTimer ();
1085
1131
bool HashMatch = (StoredHash == RecalculatedHash);
1086
1132
1133
+ double CompressionRate =
1134
+ static_cast <double >(UncompressedSize) / CompressedData.size ();
1135
+ double DecompressionSpeedMBs =
1136
+ (UncompressedSize / (1024.0 * 1024.0 )) / DecompressionTimeSeconds;
1137
+
1087
1138
llvm::errs () << " Compressed bundle format version: " << ThisVersion << " \n "
1088
1139
<< " Decompression method: "
1089
1140
<< (CompressionFormat == llvm::compression::Format::Zlib
1090
1141
? " zlib"
1091
1142
: " zstd" )
1092
1143
<< " \n "
1093
- << " Size before decompression: " << CompressedData.size ()
1094
- << " bytes\n "
1095
- << " Size after decompression: " << UncompressedSize
1096
- << " bytes\n "
1144
+ << " Size before decompression: "
1145
+ << formatWithCommas (CompressedData.size ()) << " bytes\n "
1146
+ << " Size after decompression: "
1147
+ << formatWithCommas (UncompressedSize) << " bytes\n "
1148
+ << " Compression rate: "
1149
+ << llvm::format (" %.2lf" , CompressionRate) << " \n "
1150
+ << " Compression ratio: "
1151
+ << llvm::format (" %.2lf%%" , 100.0 / CompressionRate) << " \n "
1152
+ << " Decompression speed: "
1153
+ << llvm::format (" %.2lf MB/s" , DecompressionSpeedMBs) << " \n "
1097
1154
<< " Stored hash: " << llvm::format_hex (StoredHash, 16 ) << " \n "
1098
1155
<< " Recalculated hash: "
1099
1156
<< llvm::format_hex (RecalculatedHash, 16 ) << " \n "
@@ -1287,8 +1344,10 @@ Error OffloadBundler::BundleFiles() {
1287
1344
std::unique_ptr<llvm::MemoryBuffer> BufferMemory =
1288
1345
llvm::MemoryBuffer::getMemBufferCopy (
1289
1346
llvm::StringRef (Buffer.data (), Buffer.size ()));
1290
- auto CompressionResult =
1291
- CompressedOffloadBundle::compress (*BufferMemory, BundlerConfig.Verbose );
1347
+ auto CompressionResult = CompressedOffloadBundle::compress (
1348
+ {BundlerConfig.CompressionFormat , BundlerConfig.CompressionLevel ,
1349
+ /* zstdEnableLdm=*/ true },
1350
+ *BufferMemory, BundlerConfig.Verbose );
1292
1351
if (auto Error = CompressionResult.takeError ())
1293
1352
return Error;
1294
1353
0 commit comments