30#include "coders/huffman/phf/hf.h"
39#include <unordered_map>
44namespace phf {
template<
typename E>
struct Buf; }
121 std::is_same_v<T, uint8_t> ||
122 std::is_same_v<T, uint16_t> ||
123 std::is_same_v<T, uint32_t>,
124 "HuffmanStage: T must be uint8_t, uint16_t, or uint32_t.");
169 constexpr uint32_t kMul = (4u /
sizeof(T)) ? (4u /
sizeof(T)) : 1u;
170 bklen_ = ((bklen + kMul - 1u) / kMul) * kMul;
172 uint32_t getBklen()
const {
return bklen_; }
262 bool getValidateSymbolRange()
const {
return validate_symbol_range_; }
284 uint8_t getAdaptiveFloorShift()
const {
return adaptive_floor_shift_; }
307 if (adaptive_fallback_)
return {
"huffman_adaptive_fallback"};
329 float getRefitThreshold()
const {
return refit_threshold_; }
350 uint32_t getRefitInterval()
const {
return refit_interval_; }
395 bool isInverse()
const override {
return is_inverse_; }
423 const std::vector<void*>& inputs,
424 const std::vector<void*>& outputs,
425 const std::vector<size_t>& sizes
429 std::string
getName()
const override {
return "Huffman"; }
430 size_t getNumInputs()
const override {
return 1; }
431 size_t getNumOutputs()
const override {
return 1; }
434 const std::vector<size_t>& input_sizes
436 if (input_sizes.empty())
return {0};
439 return {input_sizes[0] * 2 + 4096};
442 return {original_len_ *
sizeof(T)};
445 std::unordered_map<std::string, size_t>
447 return {{
"output", actual_output_size_}};
451 return (index == 0) ? actual_output_size_ : 0;
456 return static_cast<uint16_t
>(StageType::HUFFMAN);
469 size_t , uint8_t* buf,
size_t max_size
471 if (max_size < 11)
return 0;
472 buf[0] =
static_cast<uint8_t
>(dataTypeOf<T>());
473 uint16_t bk =
static_cast<uint16_t
>(bklen_);
474 std::memcpy(buf + 1, &bk,
sizeof(uint16_t));
475 std::memcpy(buf + 3, &original_len_,
sizeof(uint64_t));
482 std::memcpy(&bk, buf + 1,
sizeof(uint16_t));
493 if ((
sizeof(T) *
static_cast<size_t>(bk)) % 4u != 0)
494 throw std::runtime_error(
495 "HuffmanStage: archive declares bklen=" + std::to_string(bk) +
496 " with a " + std::to_string(
sizeof(T)) +
"-byte symbol, which puts "
497 "the bitstream at a non-4-byte offset. Such archives were written "
498 "by a build predating the alignment fix and cannot be decoded "
499 "correctly — the stream itself is malformed, not just this reader.");
503 std::memcpy(&original_len_, buf + 3,
sizeof(uint64_t));
509 saved_bklen_ = bklen_;
510 saved_original_len_ = original_len_;
511 saved_output_size_ = actual_output_size_;
514 void restoreState()
override {
515 bklen_ = saved_bklen_;
516 original_len_ = saved_original_len_;
517 actual_output_size_ = saved_output_size_;
521 bool is_inverse_ =
false;
522 uint32_t bklen_ = defaultBklen();
527 std::vector<uint32_t> fixed_freq_;
529 HuffmanBookSpec book_spec_ {};
530 bool has_book_spec_ =
false;
531 uint8_t adaptive_floor_shift_ = 24;
532 uint8_t adaptive_shift_used_ = 24;
537 bool adaptive_fallback_ =
false;
540 float refit_threshold_ = 1.2f;
541 bool validate_symbol_range_ =
true;
542 uint32_t refit_interval_ = 0;
543 uint32_t calls_since_fit_ = 0;
544 double fit_bits_per_sym_ = 0.0;
545 bool just_fitted_ =
false;
546 uint32_t refit_count_ = 0;
549 bool fixed_book_resident_ =
false;
553 bool last_used_fine_ =
false;
554 uint8_t last_max_codelen_ = 0;
557 uint8_t warned_max_codelen_ = 0;
559 uint64_t original_len_ = 0;
560 size_t actual_output_size_ = 0;
561 size_t cap_inlen_ = 0;
562 uint32_t last_bklen_ = 0;
566 int hist_grid_dim_ = 0;
567 int hist_block_dim_ = 0;
568 int hist_shmem_use_ = 0;
569 int hist_r_per_block_ = 0;
572 std::unique_ptr<phf::Buf<T>> buf_;
573 phf_header header_ {};
578 MemoryPool* pool_ =
nullptr;
581 uint32_t saved_bklen_ = defaultBklen();
582 uint64_t saved_original_len_ = 0;
583 size_t saved_output_size_ = 0;
585 static constexpr uint32_t defaultBklen() {
586 if constexpr (std::is_same_v<T, uint8_t>)
return 256;
591 static constexpr DataType dataTypeOf() {
592 if constexpr (std::is_same_v<U, uint8_t>)
return DataType::UINT8;
593 if constexpr (std::is_same_v<U, uint16_t>)
return DataType::UINT16;
594 return DataType::UINT32;
601 void initBuf(
size_t inlen, MemoryPool* pool);
605 void buildFixedBook(fz::stream_t stream);
609 void buildAdaptiveBook(
const uint32_t* h_hist, fz::stream_t stream);
612 int findUnusableCode(
const uint32_t* freq)
const;
615extern template class HuffmanStage<uint8_t>;
616extern template class HuffmanStage<uint16_t>;
617extern template class HuffmanStage<uint32_t>;
Definition huffman_stage.h:119
size_t estimateDeviceFootprintBytes(size_t inlen) const override
void setRefitThreshold(float ratio)
Definition huffman_stage.h:328
size_t getMaxHeaderSize(size_t) const override
Definition huffman_stage.h:506
size_t serializeHeader(size_t, uint8_t *buf, size_t max_size) const override
Definition huffman_stage.h:468
uint16_t getStageTypeId() const override
Definition huffman_stage.h:455
uint8_t getLastMaxCodeLen() const
Definition huffman_stage.h:385
bool isGraphCompatible() const override
Definition huffman_stage.h:402
double getFitBitsPerSymbol() const
Definition huffman_stage.h:360
std::vector< std::string > getRunNotes() const override
Definition huffman_stage.h:306
void onFinalize(size_t estimated_inlen, MemoryPool *pool) override
size_t getActualOutputSize(int index) const override
Definition huffman_stage.h:450
uint32_t getRefitCount() const
Definition huffman_stage.h:355
void saveState() override
Definition huffman_stage.h:508
bool getAdaptiveFallbackUsed() const
Definition huffman_stage.h:301
bool hasBookSpec() const
Definition huffman_stage.h:390
uint8_t getAdaptiveFloorShiftUsed() const
Definition huffman_stage.h:288
void setInverse(bool inv) override
Definition huffman_stage.h:394
std::vector< size_t > estimateOutputSizes(const std::vector< size_t > &input_sizes) const override
Definition huffman_stage.h:433
void deserializeHeader(const uint8_t *buf, size_t size) override
Definition huffman_stage.h:479
void setFixedBookFromFreq(const uint32_t *h_freq, uint32_t n)
void setAdaptiveFloorShift(uint8_t shift)
Definition huffman_stage.h:283
bool getLastUsedFineEncode() const
Definition huffman_stage.h:374
size_t estimatePinnedFootprintBytes(size_t inlen) const override
std::string getName() const override
Definition huffman_stage.h:429
const std::vector< uint32_t > & getFixedBookFreq() const
Frequency table backing the fixed codebook; empty when none has been set.
Definition huffman_stage.h:265
void execute(fz::stream_t stream, MemoryPool *pool, const std::vector< void * > &inputs, const std::vector< void * > &outputs, const std::vector< size_t > &sizes) override
void setBookSource(HuffmanBookSource src)
Definition huffman_stage.h:205
uint8_t getOutputDataType(size_t) const override
Definition huffman_stage.h:460
std::unordered_map< std::string, size_t > getActualOutputSizesByName() const override
Definition huffman_stage.h:446
void setRefitInterval(uint32_t n)
Definition huffman_stage.h:349
void setFixedBookFromModel(const HuffmanBookSpec &spec)
void setBklen(uint32_t bklen)
Definition huffman_stage.h:168
void setEncodeMode(HuffmanEncodeMode mode)
Definition huffman_stage.h:189
uint8_t getInputDataType(size_t) const override
Definition huffman_stage.h:463
void setValidateSymbolRange(bool on)
Definition huffman_stage.h:261
Definition algorithms.h:48
HuffmanBookSource
Definition huffman_stage.h:70
@ Adaptive
Histogram the first call only, then reuse that codebook forever.
@ PerBlock
Histogram + build a fresh codebook on every forward call (default).
@ Fixed
Build one codebook up front and reuse it for every forward call.
HuffmanBookModel
Definition huffman_stage.h:77
@ Laplace
exp(-|i-center|/scale)
@ GeneralizedNormal
exp(-(|i-center|/scale)^shape)
@ Uniform
flat; every symbol equally likely
@ Gaussian
exp(-((i-center)/scale)^2 / 2)
DataType
Element data type identifiers used in buffer and stage descriptors.
Definition fzm_format.h:117
@ UNKNOWN
Byte-transparent stages: skip type checking at finalize()
HuffmanEncodeMode
Definition huffman_stage.h:49
@ Coarse
Multi-kernel coarse path; CPU prefix-sum sync in phase 3 (default).
Base class interface for all compression stages.
Definition huffman_stage.h:92
double shape
Exponent for GeneralizedNormal only (2.0 == Gaussian, 1.0 == Laplace).
Definition huffman_stage.h:101
double scale
Definition huffman_stage.h:99
double center
Definition huffman_stage.h:96
Backend-neutral GPU type aliases.