Move utils/ to spvtools::utils

Currently the utils/ folder uses both spvutils:: and spvtools::utils.
This CL changes the namespace to consistenly be spvtools::utils to match
the rest of the codebase.
This commit is contained in:
dan sinclair 2018-07-06 13:25:17 -04:00 committed by David Neto
parent 9836b05acd
commit 76e0bde196
35 changed files with 238 additions and 227 deletions

View File

@ -64,11 +64,11 @@ using libspirv::DiagnosticStream;
using libspirv::IdDescriptorCollection;
using libspirv::Instruction;
using libspirv::ValidationState_t;
using spvutils::BitReaderWord64;
using spvutils::BitWriterWord64;
using spvutils::HuffmanCodec;
using MoveToFront = spvutils::MoveToFront<uint32_t>;
using MultiMoveToFront = spvutils::MultiMoveToFront<uint32_t>;
using spvtools::utils::BitReaderWord64;
using spvtools::utils::BitWriterWord64;
using spvtools::utils::HuffmanCodec;
using MoveToFront = spvtools::utils::MoveToFront<uint32_t>;
using MultiMoveToFront = spvtools::utils::MultiMoveToFront<uint32_t>;
namespace spvtools {
namespace comp {
@ -497,7 +497,7 @@ class MarkvCodecBase {
// Returns Huffman codec for ranks of the mtf with given |handle|.
// Different mtfs can use different rank distributions.
// May return nullptr if the codec doesn't exist.
const spvutils::HuffmanCodec<uint32_t>* GetMtfHuffmanCodec(
const spvtools::utils::HuffmanCodec<uint32_t>* GetMtfHuffmanCodec(
uint64_t handle) const {
const auto it = mtf_huffman_codecs_.find(handle);
if (it == mtf_huffman_codecs_.end()) return nullptr;

View File

@ -98,7 +98,7 @@ class MarkvModel {
// Returns a codec for common opcode_and_num_operands words for the given
// previous opcode. May return nullptr if the codec doesn't exist.
const spvutils::HuffmanCodec<uint64_t>*
const utils::HuffmanCodec<uint64_t>*
GetOpcodeAndNumOperandsMarkovHuffmanCodec(uint32_t prev_opcode) const {
if (prev_opcode == SpvOpNop)
return opcode_and_num_operands_huffman_codec_.get();
@ -113,7 +113,7 @@ class MarkvModel {
// Returns a codec for common non-id words used for given operand slot.
// Operand slot is defined by the opcode and the operand index.
// May return nullptr if the codec doesn't exist.
const spvutils::HuffmanCodec<uint64_t>* GetNonIdWordHuffmanCodec(
const utils::HuffmanCodec<uint64_t>* GetNonIdWordHuffmanCodec(
uint32_t opcode, uint32_t operand_index) const {
const auto it = non_id_word_huffman_codecs_.find(
std::pair<uint32_t, uint32_t>(opcode, operand_index));
@ -124,7 +124,7 @@ class MarkvModel {
// Returns a codec for common id descriptos used for given operand slot.
// Operand slot is defined by the opcode and the operand index.
// May return nullptr if the codec doesn't exist.
const spvutils::HuffmanCodec<uint64_t>* GetIdDescriptorHuffmanCodec(
const utils::HuffmanCodec<uint64_t>* GetIdDescriptorHuffmanCodec(
uint32_t opcode, uint32_t operand_index) const {
const auto it = id_descriptor_huffman_codecs_.find(
std::pair<uint32_t, uint32_t>(opcode, operand_index));
@ -135,7 +135,7 @@ class MarkvModel {
// Returns a codec for common strings used by the given opcode.
// Operand slot is defined by the opcode and the operand index.
// May return nullptr if the codec doesn't exist.
const spvutils::HuffmanCodec<std::string>* GetLiteralStringHuffmanCodec(
const utils::HuffmanCodec<std::string>* GetLiteralStringHuffmanCodec(
uint32_t opcode) const {
const auto it = literal_string_huffman_codecs_.find(opcode);
if (it == literal_string_huffman_codecs_.end()) return nullptr;
@ -179,23 +179,23 @@ class MarkvModel {
protected:
// Huffman codec for base-rate of opcode_and_num_operands.
std::unique_ptr<spvutils::HuffmanCodec<uint64_t>>
std::unique_ptr<utils::HuffmanCodec<uint64_t>>
opcode_and_num_operands_huffman_codec_;
// Huffman codecs for opcode_and_num_operands. The map key is previous opcode.
std::map<uint32_t, std::unique_ptr<spvutils::HuffmanCodec<uint64_t>>>
std::map<uint32_t, std::unique_ptr<utils::HuffmanCodec<uint64_t>>>
opcode_and_num_operands_markov_huffman_codecs_;
// Huffman codecs for non-id single-word operand values.
// The map key is pair <opcode, operand_index>.
std::map<std::pair<uint32_t, uint32_t>,
std::unique_ptr<spvutils::HuffmanCodec<uint64_t>>>
std::unique_ptr<utils::HuffmanCodec<uint64_t>>>
non_id_word_huffman_codecs_;
// Huffman codecs for id descriptors. The map key is pair
// <opcode, operand_index>.
std::map<std::pair<uint32_t, uint32_t>,
std::unique_ptr<spvutils::HuffmanCodec<uint64_t>>>
std::unique_ptr<utils::HuffmanCodec<uint64_t>>>
id_descriptor_huffman_codecs_;
// Set of all descriptors which have a coding scheme in any of
@ -206,7 +206,7 @@ class MarkvModel {
// current instruction. This assumes, that there is no more than one literal
// string operand per instruction, but would still work even if this is not
// the case. Names and debug information strings are not collected.
std::map<uint32_t, std::unique_ptr<spvutils::HuffmanCodec<std::string>>>
std::map<uint32_t, std::unique_ptr<utils::HuffmanCodec<std::string>>>
literal_string_huffman_codecs_;
// Chunk lengths used for variable width encoding of operands (index is

View File

@ -168,8 +168,7 @@ ConstantFoldingRule FoldVectorTimesScalar() {
if (float_type->width() == 32) {
float scalar = c2->GetFloat();
for (uint32_t i = 0; i < c1_components.size(); ++i) {
spvutils::FloatProxy<float> result(c1_components[i]->GetFloat() *
scalar);
utils::FloatProxy<float> result(c1_components[i]->GetFloat() * scalar);
std::vector<uint32_t> words = result.GetWords();
const analysis::Constant* new_elem =
const_mgr->GetConstant(float_type, words);
@ -179,8 +178,8 @@ ConstantFoldingRule FoldVectorTimesScalar() {
} else if (float_type->width() == 64) {
double scalar = c2->GetDouble();
for (uint32_t i = 0; i < c1_components.size(); ++i) {
spvutils::FloatProxy<double> result(c1_components[i]->GetDouble() *
scalar);
utils::FloatProxy<double> result(c1_components[i]->GetDouble() *
scalar);
std::vector<uint32_t> words = result.GetWords();
const analysis::Constant* new_elem =
const_mgr->GetConstant(float_type, words);
@ -384,14 +383,14 @@ UnaryScalarFoldingRule FoldIToFOp() {
float result_val = integer_type->IsSigned()
? static_cast<float>(static_cast<int32_t>(ua))
: static_cast<float>(ua);
spvutils::FloatProxy<float> result(result_val);
utils::FloatProxy<float> result(result_val);
std::vector<uint32_t> words = {result.data()};
return const_mgr->GetConstant(result_type, words);
} else if (float_type->width() == 64) {
double result_val = integer_type->IsSigned()
? static_cast<double>(static_cast<int32_t>(ua))
: static_cast<double>(ua);
spvutils::FloatProxy<double> result(result_val);
utils::FloatProxy<double> result(result_val);
std::vector<uint32_t> words = result.GetWords();
return const_mgr->GetConstant(result_type, words);
}
@ -413,13 +412,13 @@ UnaryScalarFoldingRule FoldIToFOp() {
if (float_type_in_macro->width() == 32) { \
float fa = a->GetFloat(); \
float fb = b->GetFloat(); \
spvutils::FloatProxy<float> result_in_macro(fa op fb); \
utils::FloatProxy<float> result_in_macro(fa op fb); \
std::vector<uint32_t> words_in_macro = result_in_macro.GetWords(); \
return const_mgr_in_macro->GetConstant(result_type, words_in_macro); \
} else if (float_type_in_macro->width() == 64) { \
double fa = a->GetDouble(); \
double fb = b->GetDouble(); \
spvutils::FloatProxy<double> result_in_macro(fa op fb); \
utils::FloatProxy<double> result_in_macro(fa op fb); \
std::vector<uint32_t> words_in_macro = result_in_macro.GetWords(); \
return const_mgr_in_macro->GetConstant(result_type, words_in_macro); \
} \
@ -548,12 +547,12 @@ ConstantFoldingRule FoldOpDotWithConstants() {
if (has_zero_operand) {
if (float_type->width() == 32) {
spvutils::FloatProxy<float> result(0.0f);
utils::FloatProxy<float> result(0.0f);
std::vector<uint32_t> words = result.GetWords();
return const_mgr->GetConstant(float_type, words);
}
if (float_type->width() == 64) {
spvutils::FloatProxy<double> result(0.0);
utils::FloatProxy<double> result(0.0);
std::vector<uint32_t> words = result.GetWords();
return const_mgr->GetConstant(float_type, words);
}
@ -570,7 +569,7 @@ ConstantFoldingRule FoldOpDotWithConstants() {
a_components = constants[0]->GetVectorComponents(const_mgr);
b_components = constants[1]->GetVectorComponents(const_mgr);
spvutils::FloatProxy<double> result(0.0);
utils::FloatProxy<double> result(0.0);
std::vector<uint32_t> words = result.GetWords();
const analysis::Constant* result_const =
const_mgr->GetConstant(float_type, words);
@ -599,12 +598,12 @@ UnaryScalarFoldingRule FoldFNegateOp() {
assert(float_type != nullptr);
if (float_type->width() == 32) {
float fa = a->GetFloat();
spvutils::FloatProxy<float> result(-fa);
utils::FloatProxy<float> result(-fa);
std::vector<uint32_t> words = result.GetWords();
return const_mgr->GetConstant(result_type, words);
} else if (float_type->width() == 64) {
double da = a->GetDouble();
spvutils::FloatProxy<double> result(-da);
utils::FloatProxy<double> result(-da);
std::vector<uint32_t> words = result.GetWords();
return const_mgr->GetConstant(result_type, words);
}

View File

@ -233,7 +233,7 @@ class FloatConstant : public ScalarConstant {
float GetFloatValue() const {
assert(type()->AsFloat()->width() == 32 &&
"Not a 32-bit floating point value.");
spvutils::FloatProxy<float> a(words()[0]);
utils::FloatProxy<float> a(words()[0]);
return a.getAsFloat();
}
@ -245,7 +245,7 @@ class FloatConstant : public ScalarConstant {
uint64_t combined_words = words()[1];
combined_words = combined_words << 32;
combined_words |= words()[0];
spvutils::FloatProxy<double> a(combined_words);
utils::FloatProxy<double> a(combined_words);
return a.getAsFloat();
}
};

View File

@ -93,10 +93,10 @@ uint32_t NegateFloatingPointConstant(analysis::ConstantManager* const_mgr,
assert(width == 32 || width == 64);
std::vector<uint32_t> words;
if (width == 64) {
spvutils::FloatProxy<double> result(c->GetDouble() * -1.0);
utils::FloatProxy<double> result(c->GetDouble() * -1.0);
words = result.GetWords();
} else {
spvutils::FloatProxy<float> result(c->GetFloat() * -1.0f);
utils::FloatProxy<float> result(c->GetFloat() * -1.0f);
words = result.GetWords();
}
@ -183,11 +183,11 @@ uint32_t Reciprocal(analysis::ConstantManager* const_mgr,
assert(width == 32 || width == 64);
std::vector<uint32_t> words;
if (width == 64) {
spvutils::FloatProxy<double> result(1.0 / c->GetDouble());
spvtools::utils::FloatProxy<double> result(1.0 / c->GetDouble());
if (!IsValidResult(result.getAsFloat())) return 0;
words = result.GetWords();
} else {
spvutils::FloatProxy<float> result(1.0f / c->GetFloat());
spvtools::utils::FloatProxy<float> result(1.0f / c->GetFloat());
if (!IsValidResult(result.getAsFloat())) return 0;
words = result.GetWords();
}
@ -421,19 +421,18 @@ uint32_t PerformFloatingPointOperation(analysis::ConstantManager* const_mgr,
uint32_t width = type->AsFloat()->width();
assert(width == 32 || width == 64);
std::vector<uint32_t> words;
#define FOLD_OP(op) \
if (width == 64) { \
spvutils::FloatProxy<double> val = \
input1->GetDouble() op input2->GetDouble(); \
double dval = val.getAsFloat(); \
if (!IsValidResult(dval)) return 0; \
words = val.GetWords(); \
} else { \
spvutils::FloatProxy<float> val = \
input1->GetFloat() op input2->GetFloat(); \
float fval = val.getAsFloat(); \
if (!IsValidResult(fval)) return 0; \
words = val.GetWords(); \
#define FOLD_OP(op) \
if (width == 64) { \
utils::FloatProxy<double> val = \
input1->GetDouble() op input2->GetDouble(); \
double dval = val.getAsFloat(); \
if (!IsValidResult(dval)) return 0; \
words = val.GetWords(); \
} else { \
utils::FloatProxy<float> val = input1->GetFloat() op input2->GetFloat(); \
float fval = val.getAsFloat(); \
if (!IsValidResult(fval)) return 0; \
words = val.GetWords(); \
}
switch (opcode) {
case SpvOpFMul:

View File

@ -32,10 +32,10 @@ namespace spvtools {
namespace opt {
namespace {
using spvutils::EncodeNumberStatus;
using spvutils::NumberType;
using spvutils::ParseAndEncodeNumber;
using spvutils::ParseNumber;
using utils::EncodeNumberStatus;
using utils::NumberType;
using utils::ParseAndEncodeNumber;
using utils::ParseNumber;
// Given a numeric value in a null-terminated c string and the expected type of
// the value, parses the string and encodes it in a vector of words. If the

View File

@ -39,11 +39,11 @@ void EmitNumericLiteral(std::ostream* out, const spv_parsed_instruction_t& inst,
break;
case SPV_NUMBER_FLOATING:
if (operand.number_bit_width == 16) {
*out << spvutils::FloatProxy<spvutils::Float16>(
*out << spvtools::utils::FloatProxy<spvtools::utils::Float16>(
uint16_t(word & 0xFFFF));
} else {
// Assume 32-bit floats.
*out << spvutils::FloatProxy<float>(word);
*out << spvtools::utils::FloatProxy<float>(word);
}
break;
default:
@ -62,7 +62,7 @@ void EmitNumericLiteral(std::ostream* out, const spv_parsed_instruction_t& inst,
break;
case SPV_NUMBER_FLOATING:
// Assume only 64-bit floats.
*out << spvutils::FloatProxy<double>(bits);
*out << spvtools::utils::FloatProxy<double>(bits);
break;
default:
assert(false && "Unreachable");

View File

@ -162,7 +162,7 @@ spv_result_t encodeImmediate(libspirv::AssemblyContext* context,
const char* text, spv_instruction_t* pInst) {
assert(*text == '!');
uint32_t parse_result;
if (!spvutils::ParseNumber(text + 1, &parse_result)) {
if (!spvtools::utils::ParseNumber(text + 1, &parse_result)) {
return context->diagnostic(SPV_ERROR_INVALID_TEXT)
<< "Invalid immediate integer: !" << text + 1;
}

View File

@ -157,7 +157,7 @@ const IdType kUnknownType = {0, false, IdTypeClass::kBottom};
uint32_t AssemblyContext::spvNamedIdAssignOrGet(const char* textValue) {
if (!ids_to_preserve_.empty()) {
uint32_t id = 0;
if (spvutils::ParseNumber(textValue, &id)) {
if (spvtools::utils::ParseNumber(textValue, &id)) {
if (ids_to_preserve_.find(id) != ids_to_preserve_.end()) {
bound_ = std::max(bound_, id + 1);
return id;
@ -239,9 +239,9 @@ spv_result_t AssemblyContext::binaryEncodeU32(const uint32_t value,
spv_result_t AssemblyContext::binaryEncodeNumericLiteral(
const char* val, spv_result_t error_code, const IdType& type,
spv_instruction_t* pInst) {
using spvutils::EncodeNumberStatus;
using spvtools::utils::EncodeNumberStatus;
// Populate the NumberType from the IdType for parsing.
spvutils::NumberType number_type;
spvtools::utils::NumberType number_type;
switch (type.type_class) {
case IdTypeClass::kOtherType:
return diagnostic(SPV_ERROR_INTERNAL)
@ -389,7 +389,7 @@ std::set<uint32_t> AssemblyContext::GetNumericIds() const {
std::set<uint32_t> ids;
for (const auto& kv : named_ids_) {
uint32_t id;
if (spvutils::ParseNumber(kv.first.c_str(), &id)) ids.insert(id);
if (spvtools::utils::ParseNumber(kv.first.c_str(), &id)) ids.insert(id);
}
return ids;
}

View File

@ -20,8 +20,8 @@
#include "util/bit_stream.h"
namespace spvutils {
namespace spvtools {
namespace utils {
namespace {
// Returns if the system is little-endian. Unfortunately only works during
@ -434,4 +434,5 @@ bool BitReaderWord64::OnlyZeroesLeft() const {
return !remaining_bits;
}
} // namespace spvutils
} // namespace utils
} // namespace spvtools

View File

@ -25,7 +25,8 @@
#include <string>
#include <vector>
namespace spvutils {
namespace spvtools {
namespace utils {
// Returns rounded down log2(val). log2(0) is considered 0.
size_t Log2U64(uint64_t val);
@ -442,6 +443,7 @@ class BitReaderWord64 : public BitReaderInterface {
std::function<void(const std::string&)> callback_;
};
} // namespace spvutils
} // namespace utils
} // namespace spvtools
#endif // LIBSPIRV_UTIL_BIT_STREAM_H_

View File

@ -18,7 +18,8 @@
#include <cstdint>
#include <cstring>
namespace spvutils {
namespace spvtools {
namespace utils {
// Performs a bitwise copy of source to the destination type Dest.
template <typename Dest, typename Src>
@ -89,6 +90,7 @@ size_t CountSetBits(T word) {
return count;
}
} // namespace spvutils
} // namespace utils
} // namespace spvtools
#endif // LIBSPIRV_UTIL_BITUTILS_H_

View File

@ -33,7 +33,8 @@
(__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
#endif
namespace spvutils {
namespace spvtools {
namespace utils {
class Float16 {
public:
@ -317,8 +318,7 @@ class HexFloat {
// The representation of the fraction, not the actual bits. This
// includes the leading bit that is usually implicit.
static const uint_type fraction_represent_mask =
spvutils::SetBits<uint_type, 0,
num_fraction_bits + num_overflow_bits>::get;
SetBits<uint_type, 0, num_fraction_bits + num_overflow_bits>::get;
// The topmost bit in the nibble-aligned fraction.
static const uint_type fraction_top_bit =
@ -332,14 +332,14 @@ class HexFloat {
// The mask for the encoded fraction. It does not include the
// implicit bit.
static const uint_type fraction_encode_mask =
spvutils::SetBits<uint_type, 0, num_fraction_bits>::get;
SetBits<uint_type, 0, num_fraction_bits>::get;
// The bit that is used as a sign.
static const uint_type sign_mask = uint_type(1) << top_bit_left_shift;
// The bits that represent the exponent.
static const uint_type exponent_mask =
spvutils::SetBits<uint_type, num_fraction_bits, num_exponent_bits>::get;
SetBits<uint_type, num_fraction_bits, num_exponent_bits>::get;
// How far left the exponent is shifted.
static const uint32_t exponent_left_shift = num_fraction_bits;
@ -568,7 +568,7 @@ class HexFloat {
static const uint_type throwaway_mask_bits =
num_throwaway_bits > 0 ? num_throwaway_bits : 0;
static const uint_type throwaway_mask =
spvutils::SetBits<uint_type, 0, throwaway_mask_bits>::get;
SetBits<uint_type, 0, throwaway_mask_bits>::get;
*carry_bit = false;
other_uint_type out_val = 0;
@ -1143,6 +1143,8 @@ inline std::ostream& operator<<<Float16>(std::ostream& os,
os << HexFloat<FloatProxy<Float16>>(value);
return os;
}
} // namespace spvutils
} // namespace utils
} // namespace spvtools
#endif // LIBSPIRV_UTIL_HEX_FLOAT_H_

View File

@ -31,7 +31,8 @@
#include <unordered_map>
#include <vector>
namespace spvutils {
namespace spvtools {
namespace utils {
// Used to generate and apply a Huffman coding scheme.
// |Val| is the type of variable being encoded (for example a string or a
@ -380,6 +381,7 @@ class HuffmanCodec {
uint32_t next_node_id_ = 1;
};
} // namespace spvutils
} // namespace utils
} // namespace spvtools
#endif // LIBSPIRV_UTIL_HUFFMAN_CODEC_H_

View File

@ -28,7 +28,8 @@
#include <unordered_set>
#include <vector>
namespace spvutils {
namespace spvtools {
namespace utils {
// Log(n) move-to-front implementation. Implements the following functions:
// Insert - pushes value to the front of the mtf sequence
@ -820,6 +821,7 @@ void MoveToFront<Val>::UpdateNode(uint32_t node) {
1 + std::max(HeightOf(LeftOf(node)), HeightOf(RightOf(node)));
}
} // namespace spvutils
} // namespace utils
} // namespace spvtools
#endif // LIBSPIRV_UTIL_MOVE_TO_FRONT_H_

View File

@ -23,9 +23,10 @@
#include "util/hex_float.h"
namespace spvutils {
namespace spvtools {
namespace utils {
namespace {
// A helper class that temporarily stores error messages and dump the messages
// to a string which given as as pointer when it is destructed. If the given
// pointer is a nullptr, this class does not store error message.
@ -145,12 +146,12 @@ EncodeNumberStatus ParseAndEncodeFloatingPointNumber(
const auto bit_width = AssumedBitWidth(type);
switch (bit_width) {
case 16: {
HexFloat<FloatProxy<spvutils::Float16>> hVal(0);
HexFloat<FloatProxy<Float16>> hVal(0);
if (!ParseNumber(text, &hVal)) {
ErrorMsgStream(error_msg) << "Invalid 16-bit float literal: " << text;
return EncodeNumberStatus::kInvalidText;
}
// getAsFloat will return the spvutils::Float16 value, and get_value
// getAsFloat will return the Float16 value, and get_value
// will return a uint16_t representing the bits of the float.
// The encoding is therefore correct from the perspective of the SPIR-V
// spec since the top 16 bits will be 0.
@ -211,4 +212,5 @@ EncodeNumberStatus ParseAndEncodeNumber(const char* text,
return ParseAndEncodeIntegerNumber(text, type, emit, error_msg);
}
} // namespace spvutils
} // namespace utils
} // namespace spvtools

View File

@ -22,7 +22,8 @@
#include "spirv-tools/libspirv.h"
#include "util/hex_float.h"
namespace spvutils {
namespace spvtools {
namespace utils {
// A struct to hold the expected type information for the number in text to be
// parsed.
@ -245,6 +246,7 @@ EncodeNumberStatus ParseAndEncodeNumber(const char* text,
std::function<void(uint32_t)> emit,
std::string* error_msg);
} // namespace spvutils
} // namespace utils
} // namespace spvtools
#endif // LIBSPIRV_UTIL_PARSE_NUMBER_H_

View File

@ -18,7 +18,8 @@
#include "util/string_utils.h"
namespace spvutils {
namespace spvtools {
namespace utils {
std::string CardinalToOrdinal(size_t cardinal) {
const size_t mod10 = cardinal % 10;
@ -36,4 +37,5 @@ std::string CardinalToOrdinal(size_t cardinal) {
return ToString(cardinal) + suffix;
}
} // namespace spvutils
} // namespace utils
} // namespace spvtools

View File

@ -20,13 +20,15 @@
#include "util/string_utils.h"
namespace spvutils {
namespace spvtools {
namespace utils {
// Converts arithmetic value |val| to its default string representation.
template <class T>
std::string ToString(T val) {
static_assert(std::is_arithmetic<T>::value,
"spvutils::ToString is restricted to only arithmetic values");
static_assert(
std::is_arithmetic<T>::value,
"spvtools::utils::ToString is restricted to only arithmetic values");
std::stringstream os;
os << val;
return os.str();
@ -35,6 +37,7 @@ std::string ToString(T val) {
// Converts cardinal number to ordinal number string.
std::string CardinalToOrdinal(size_t cardinal);
} // namespace spvutils
} // namespace utils
} // namespace spvtools
#endif // LIBSPIRV_UTIL_STRING_UTILS_H_

View File

@ -20,7 +20,8 @@
#include <iostream>
#include <string>
namespace spvutils {
namespace spvtools {
namespace utils {
#if defined(SPIRV_TIMER_ENABLED)
@ -97,4 +98,5 @@ void Timer::Report(const char* tag) {
#endif // defined(SPIRV_TIMER_ENABLED)
} // namespace spvutils
} // namespace utils
} // namespace spvtools

View File

@ -23,16 +23,17 @@
#include <cassert>
#include <iostream>
// A macro to call spvutils::PrintTimerDescription(std::ostream*, bool). The
// first argument must be given as std::ostream*. If it is NULL, the function
// does nothing. Otherwise, it prints resource types measured by Timer class.
// The second is optional and if it is true, the function also prints resource
// type fields related to memory. Otherwise, it does not print memory related
// fields. Its default is false. In usual, this must be placed before calling
// Timer::Report() to inform what those fields printed by Timer::Report()
// indicate (or spvutils::PrintTimerDescription() must be used instead).
// A macro to call spvtools::utils::PrintTimerDescription(std::ostream*, bool).
// The first argument must be given as std::ostream*. If it is NULL, the
// function does nothing. Otherwise, it prints resource types measured by Timer
// class. The second is optional and if it is true, the function also prints
// resource type fields related to memory. Otherwise, it does not print memory
// related fields. Its default is false. In usual, this must be placed before
// calling Timer::Report() to inform what those fields printed by
// Timer::Report() indicate (or spvtools::utils::PrintTimerDescription() must be
// used instead).
#define SPIRV_TIMER_DESCRIPTION(...) \
spvutils::PrintTimerDescription(__VA_ARGS__)
spvtools::utils::PrintTimerDescription(__VA_ARGS__)
// Creates an object of ScopedTimer to measure the resource utilization for the
// scope surrounding it as the following example:
@ -47,10 +48,12 @@
//
// } // <-- end of this scope. The destructor of ScopedTimer prints tag and
// the resource utilization to std::cout.
#define SPIRV_TIMER_SCOPED(...) \
spvutils::ScopedTimer<spvutils::Timer> timer##__LINE__(__VA_ARGS__)
#define SPIRV_TIMER_SCOPED(...) \
spvtools::utils::ScopedTimer<spvtools::utils::Timer> timer##__LINE__( \
__VA_ARGS__)
namespace spvutils {
namespace spvtools {
namespace utils {
// Prints the description of resource types measured by Timer class. If |out| is
// NULL, it does nothing. Otherwise, it prints resource types. The second is
@ -78,7 +81,7 @@ enum UsageStatus {
// only when |measure_mem_usage| given to the constructor is true. This class
// should be used as the following example:
//
// spvutils::Timer timer(std::cout);
// spvtools::utils::Timer timer(std::cout);
// timer.Start(); // <-- set |usage_before_|, |wall_before_|,
// and |cpu_before_|
//
@ -232,7 +235,8 @@ class Timer {
//
// /* ... code out of interest ... */
//
// spvutils::ScopedTimer<spvutils::Timer> scopedtimer(std::cout, tag);
// spvtools::utils::ScopedTimer<spvtools::utils::Timer>
// scopedtimer(std::cout, tag);
//
// /* ... lines of code that we want to know its resource usage ... */
//
@ -375,7 +379,8 @@ class CumulativeTimer : public Timer {
long pgfaults_;
};
} // namespace spvutils
} // namespace utils
} // namespace spvtools
#else // defined(SPIRV_TIMER_ENABLED)

View File

@ -83,7 +83,7 @@ spv_result_t ValidateMemorySemantics(ValidationState_t& _,
return SPV_SUCCESS;
}
if (spvutils::CountSetBits(
if (spvtools::utils::CountSetBits(
flags &
(SpvMemorySemanticsAcquireMask | SpvMemorySemanticsReleaseMask |
SpvMemorySemanticsAcquireReleaseMask |

View File

@ -141,7 +141,7 @@ spv_result_t ValidateMemorySemantics(ValidationState_t& _,
return SPV_SUCCESS;
}
const size_t num_memory_order_set_bits = spvutils::CountSetBits(
const size_t num_memory_order_set_bits = spvtools::utils::CountSetBits(
value & (SpvMemorySemanticsAcquireMask | SpvMemorySemanticsReleaseMask |
SpvMemorySemanticsAcquireReleaseMask |
SpvMemorySemanticsSequentiallyConsistentMask));

View File

@ -208,7 +208,7 @@ spv_result_t ValidateImageOperands(ValidationState_t& _,
const SpvOp opcode = static_cast<SpvOp>(inst.opcode);
const uint32_t num_words = inst.num_words;
size_t expected_num_image_operand_words = spvutils::CountSetBits(mask);
size_t expected_num_image_operand_words = spvtools::utils::CountSetBits(mask);
if (mask & SpvImageOperandsGradMask) {
// Grad uses two words.
++expected_num_image_operand_words;
@ -220,9 +220,9 @@ spv_result_t ValidateImageOperands(ValidationState_t& _,
<< spvOpcodeString(opcode);
}
if (spvutils::CountSetBits(mask & (SpvImageOperandsOffsetMask |
SpvImageOperandsConstOffsetMask |
SpvImageOperandsConstOffsetsMask)) > 1) {
if (spvtools::utils::CountSetBits(
mask & (SpvImageOperandsOffsetMask | SpvImageOperandsConstOffsetMask |
SpvImageOperandsConstOffsetsMask)) > 1) {
return _.diag(SPV_ERROR_INVALID_DATA)
<< "Image Operands Offset, ConstOffset, ConstOffsets cannot be used "
<< "together: " << spvOpcodeString(opcode);

View File

@ -271,9 +271,9 @@ spv_result_t ExtensionCheck(ValidationState_t& _,
RequiredExtensions(_, operand.type, word);
if (!_.HasAnyOfExtensions(required_extensions)) {
return _.diag(SPV_ERROR_MISSING_EXTENSION)
<< spvutils::CardinalToOrdinal(operand_index + 1) << " operand of "
<< spvOpcodeString(opcode) << ": operand " << word
<< " requires one of these extensions: "
<< spvtools::utils::CardinalToOrdinal(operand_index + 1)
<< " operand of " << spvOpcodeString(opcode) << ": operand "
<< word << " requires one of these extensions: "
<< ExtensionSetToString(required_extensions);
}
}

View File

@ -19,25 +19,10 @@
#include "gmock/gmock.h"
#include "util/bit_stream.h"
namespace spvtools {
namespace utils {
namespace {
using spvutils::BitReaderInterface;
using spvutils::BitReaderWord64;
using spvutils::BitsetToStream;
using spvutils::BitsToStream;
using spvutils::BitWriterInterface;
using spvutils::BitWriterWord64;
using spvutils::BufferToStream;
using spvutils::DecodeZigZag;
using spvutils::EncodeZigZag;
using spvutils::GetLowerBits;
using spvutils::Log2U64;
using spvutils::NumBitsToNumWords;
using spvutils::PadToWord;
using spvutils::StreamToBits;
using spvutils::StreamToBitset;
using spvutils::StreamToBuffer;
// A simple and inefficient implementatition of BitWriterInterface,
// using std::stringstream. Intended for tests only.
class BitWriterStringStream : public BitWriterInterface {
@ -1421,4 +1406,6 @@ TEST(FixedWidthRead, Fail) {
ASSERT_FALSE(reader.ReadFixedWidth(&val, 127));
}
} // anonymous namespace
} // namespace
} // namespace utils
} // namespace spvtools

View File

@ -24,12 +24,10 @@
#include "source/util/hex_float.h"
#include "unit_spirv.h"
namespace spvtools {
namespace utils {
namespace {
using spvutils::BitwiseCast;
using spvutils::Float16;
using spvutils::FloatProxy;
using spvutils::HexFloat;
using spvutils::ParseNormalFloat;
using ::testing::Eq;
// In this file "encode" means converting a number into a string,
@ -50,7 +48,7 @@ using RoundTripDoubleTest = ::testing::TestWithParam<double>;
template <typename T>
std::string EncodeViaHexFloat(const T& value) {
std::stringstream ss;
ss << spvutils::HexFloat<T>(value);
ss << spvtools::utils::HexFloat<T>(value);
return ss.str();
}
@ -68,7 +66,7 @@ TEST_P(HexDoubleTest, EncodeCorrectly) {
// Decodes a hex-float string.
template <typename T>
FloatProxy<T> Decode(const std::string& str) {
spvutils::HexFloat<FloatProxy<T>> decoded(0.f);
HexFloat<FloatProxy<T>> decoded(0.f);
EXPECT_TRUE((std::stringstream(str) >> decoded).eof());
return decoded.value();
}
@ -575,13 +573,12 @@ INSTANTIATE_TEST_CASE_P(
// double is used so that unbiased_exponent can be used with the output
// of ldexp directly.
int32_t unbiased_exponent(double f) {
return spvutils::HexFloat<spvutils::FloatProxy<float>>(static_cast<float>(f))
return HexFloat<FloatProxy<float>>(static_cast<float>(f))
.getUnbiasedNormalizedExponent();
}
int16_t unbiased_half_exponent(uint16_t f) {
return spvutils::HexFloat<spvutils::FloatProxy<spvutils::Float16>>(f)
.getUnbiasedNormalizedExponent();
return HexFloat<FloatProxy<Float16>>(f).getUnbiasedNormalizedExponent();
}
TEST(HexFloatOperationTest, UnbiasedExponent) {
@ -591,9 +588,9 @@ TEST(HexFloatOperationTest, UnbiasedExponent) {
EXPECT_EQ(42, unbiased_exponent(ldexp(1.0f, 42)));
EXPECT_EQ(125, unbiased_exponent(ldexp(1.0f, 125)));
EXPECT_EQ(128, spvutils::HexFloat<spvutils::FloatProxy<float>>(
std::numeric_limits<float>::infinity())
.getUnbiasedNormalizedExponent());
EXPECT_EQ(128,
HexFloat<FloatProxy<float>>(std::numeric_limits<float>::infinity())
.getUnbiasedNormalizedExponent());
EXPECT_EQ(-100, unbiased_exponent(ldexp(1.0f, -100)));
EXPECT_EQ(-127, unbiased_exponent(ldexp(1.0f, -127))); // First denorm
@ -633,7 +630,7 @@ float float_fractions(const std::vector<uint32_t>& fractions) {
// raised to the power of exp.
uint32_t normalized_significand(const std::vector<uint32_t>& fractions,
uint32_t exp) {
return spvutils::HexFloat<spvutils::FloatProxy<float>>(
return HexFloat<FloatProxy<float>>(
static_cast<float>(ldexp(float_fractions(fractions), exp)))
.getNormalizedSignificand();
}
@ -686,7 +683,7 @@ TEST(HexFloatOperationTest, NormalizedSignificand) {
// on a HexFloat<FloatProxy<float>>
float set_from_sign(bool negative, int32_t unbiased_exponent,
uint32_t significand, bool round_denorm_up) {
spvutils::HexFloat<spvutils::FloatProxy<float>> f(0.f);
HexFloat<FloatProxy<float>> f(0.f);
f.setFromSignUnbiasedExponentAndNormalizedSignificand(
negative, unbiased_exponent, significand, round_denorm_up);
return f.value().getAsFloat();
@ -729,17 +726,16 @@ TEST(HexFloatOperationTests,
TEST(HexFloatOperationTests, NonRounding) {
// Rounding from 32-bit hex-float to 32-bit hex-float should be trivial,
// except in the denorm case which is a bit more complex.
using HF = spvutils::HexFloat<spvutils::FloatProxy<float>>;
using HF = HexFloat<FloatProxy<float>>;
bool carry_bit = false;
spvutils::round_direction rounding[] = {
spvutils::round_direction::kToZero,
spvutils::round_direction::kToNearestEven,
spvutils::round_direction::kToPositiveInfinity,
spvutils::round_direction::kToNegativeInfinity};
round_direction rounding[] = {round_direction::kToZero,
round_direction::kToNearestEven,
round_direction::kToPositiveInfinity,
round_direction::kToNegativeInfinity};
// Everything fits, so this should be straight-forward
for (spvutils::round_direction round : rounding) {
for (round_direction round : rounding) {
EXPECT_EQ(bits_set({}),
HF(0.f).getRoundedNormalizedSignificand<HF>(round, &carry_bit));
EXPECT_FALSE(carry_bit);
@ -767,18 +763,18 @@ TEST(HexFloatOperationTests, NonRounding) {
}
}
using RD = spvutils::round_direction;
using RD = round_direction;
struct RoundSignificandCase {
float source_float;
std::pair<int16_t, bool> expected_results;
spvutils::round_direction round;
round_direction round;
};
using HexFloatRoundTest = ::testing::TestWithParam<RoundSignificandCase>;
TEST_P(HexFloatRoundTest, RoundDownToFP16) {
using HF = spvutils::HexFloat<spvutils::FloatProxy<float>>;
using HF16 = spvutils::HexFloat<spvutils::FloatProxy<spvutils::Float16>>;
using HF = HexFloat<FloatProxy<float>>;
using HF16 = HexFloat<FloatProxy<Float16>>;
HF input_value(GetParam().source_float);
bool carry_bit = false;
@ -846,18 +842,17 @@ struct UpCastSignificandCase {
using HexFloatRoundUpSignificandTest =
::testing::TestWithParam<UpCastSignificandCase>;
TEST_P(HexFloatRoundUpSignificandTest, Widening) {
using HF = spvutils::HexFloat<spvutils::FloatProxy<float>>;
using HF16 = spvutils::HexFloat<spvutils::FloatProxy<spvutils::Float16>>;
using HF = HexFloat<FloatProxy<float>>;
using HF16 = HexFloat<FloatProxy<Float16>>;
bool carry_bit = false;
spvutils::round_direction rounding[] = {
spvutils::round_direction::kToZero,
spvutils::round_direction::kToNearestEven,
spvutils::round_direction::kToPositiveInfinity,
spvutils::round_direction::kToNegativeInfinity};
round_direction rounding[] = {round_direction::kToZero,
round_direction::kToNearestEven,
round_direction::kToPositiveInfinity,
round_direction::kToNegativeInfinity};
// Everything fits, so everything should just be bit-shifts.
for (spvutils::round_direction round : rounding) {
for (round_direction round : rounding) {
carry_bit = false;
HF16 input_value(GetParam().source_half);
EXPECT_EQ(
@ -884,19 +879,19 @@ INSTANTIATE_TEST_CASE_P(
struct DownCastTest {
float source_float;
uint16_t expected_half;
std::vector<spvutils::round_direction> directions;
std::vector<round_direction> directions;
};
std::string get_round_text(spvutils::round_direction direction) {
std::string get_round_text(round_direction direction) {
#define CASE(round_direction) \
case round_direction: \
return #round_direction
switch (direction) {
CASE(spvutils::round_direction::kToZero);
CASE(spvutils::round_direction::kToPositiveInfinity);
CASE(spvutils::round_direction::kToNegativeInfinity);
CASE(spvutils::round_direction::kToNearestEven);
CASE(round_direction::kToZero);
CASE(round_direction::kToPositiveInfinity);
CASE(round_direction::kToNegativeInfinity);
CASE(round_direction::kToNearestEven);
}
#undef CASE
return "";
@ -905,15 +900,15 @@ std::string get_round_text(spvutils::round_direction direction) {
using HexFloatFP32To16Tests = ::testing::TestWithParam<DownCastTest>;
TEST_P(HexFloatFP32To16Tests, NarrowingCasts) {
using HF = spvutils::HexFloat<spvutils::FloatProxy<float>>;
using HF16 = spvutils::HexFloat<spvutils::FloatProxy<spvutils::Float16>>;
using HF = HexFloat<FloatProxy<float>>;
using HF16 = HexFloat<FloatProxy<Float16>>;
HF f(GetParam().source_float);
for (auto round : GetParam().directions) {
HF16 half(0);
f.castTo(half, round);
EXPECT_EQ(GetParam().expected_half, half.value().getAsFloat().get_value())
<< get_round_text(round) << " " << std::hex
<< spvutils::BitwiseCast<uint32_t>(GetParam().source_float)
<< BitwiseCast<uint32_t>(GetParam().source_float)
<< " cast to: " << half.value().getAsFloat().get_value();
}
}
@ -1021,23 +1016,22 @@ struct UpCastCase {
using HexFloatFP16To32Tests = ::testing::TestWithParam<UpCastCase>;
TEST_P(HexFloatFP16To32Tests, WideningCasts) {
using HF = spvutils::HexFloat<spvutils::FloatProxy<float>>;
using HF16 = spvutils::HexFloat<spvutils::FloatProxy<spvutils::Float16>>;
using HF = HexFloat<FloatProxy<float>>;
using HF16 = HexFloat<FloatProxy<Float16>>;
HF16 f(GetParam().source_half);
spvutils::round_direction rounding[] = {
spvutils::round_direction::kToZero,
spvutils::round_direction::kToNearestEven,
spvutils::round_direction::kToPositiveInfinity,
spvutils::round_direction::kToNegativeInfinity};
round_direction rounding[] = {round_direction::kToZero,
round_direction::kToNearestEven,
round_direction::kToPositiveInfinity,
round_direction::kToNegativeInfinity};
// Everything fits, so everything should just be bit-shifts.
for (spvutils::round_direction round : rounding) {
for (round_direction round : rounding) {
HF flt(0.f);
f.castTo(flt, round);
EXPECT_EQ(GetParam().expected_float, flt.value().getAsFloat())
<< get_round_text(round) << " " << std::hex
<< spvutils::BitwiseCast<uint16_t>(GetParam().source_half)
<< BitwiseCast<uint16_t>(GetParam().source_half)
<< " cast to: " << flt.value().getAsFloat();
}
}
@ -1066,16 +1060,15 @@ INSTANTIATE_TEST_CASE_P(
})), );
TEST(HexFloatOperationTests, NanTests) {
using HF = spvutils::HexFloat<spvutils::FloatProxy<float>>;
using HF16 = spvutils::HexFloat<spvutils::FloatProxy<spvutils::Float16>>;
spvutils::round_direction rounding[] = {
spvutils::round_direction::kToZero,
spvutils::round_direction::kToNearestEven,
spvutils::round_direction::kToPositiveInfinity,
spvutils::round_direction::kToNegativeInfinity};
using HF = HexFloat<FloatProxy<float>>;
using HF16 = HexFloat<FloatProxy<Float16>>;
round_direction rounding[] = {round_direction::kToZero,
round_direction::kToNearestEven,
round_direction::kToPositiveInfinity,
round_direction::kToNegativeInfinity};
// Everything fits, so everything should just be bit-shifts.
for (spvutils::round_direction round : rounding) {
for (round_direction round : rounding) {
HF16 f16(0);
HF f(0.f);
HF(std::numeric_limits<float>::quiet_NaN()).castTo(f16, round);
@ -1326,4 +1319,6 @@ TEST(FloatProxy, Lowest) {
}
// TODO(awoloszyn): Add fp16 tests and HexFloatTraits.
} // anonymous namespace
} // namespace
} // namespace utils
} // namespace spvtools

View File

@ -23,11 +23,10 @@
#include "util/bit_stream.h"
#include "util/huffman_codec.h"
namespace spvtools {
namespace utils {
namespace {
using spvutils::BitsToStream;
using spvutils::HuffmanCodec;
const std::map<std::string, uint32_t>& GetTestSet() {
static const std::map<std::string, uint32_t> hist = {
{"a", 4}, {"e", 7}, {"f", 3}, {"h", 2}, {"i", 3},
@ -312,4 +311,6 @@ TEST(Huffman, CreateFromTextU64) {
EXPECT_EQ("00", BitsToStream(bits, num_bits));
}
} // anonymous namespace
} // namespace
} // namespace utils
} // namespace spvtools

View File

@ -21,13 +21,14 @@
#include "source/util/bitutils.h"
#include "test_fixture.h"
namespace spvtools {
namespace utils {
namespace {
using spvtest::Concatenate;
using spvtest::MakeInstruction;
using spvtest::ScopedContext;
using spvtest::TextToBinaryTest;
using spvutils::BitwiseCast;
using ::testing::ElementsAre;
using ::testing::Eq;
using ::testing::HasSubstr;
@ -286,4 +287,6 @@ TEST_F(ImmediateIntTest, NotInteger) {
EXPECT_THAT(CompileFailure("!12K"), StrEq("Invalid immediate integer: !12K"));
}
} // anonymous namespace
} // namespace
} // namespace utils
} // namespace spvtools

View File

@ -19,11 +19,10 @@
#include "gmock/gmock.h"
#include "util/move_to_front.h"
namespace spvtools {
namespace utils {
namespace {
using spvutils::MoveToFront;
using spvutils::MultiMoveToFront;
// Class used to test the inner workings of MoveToFront.
class MoveToFrontTester : public MoveToFront<uint32_t> {
public:
@ -938,4 +937,6 @@ TEST(MultiMoveToFront, TwoSequences) {
EXPECT_EQ(1u, rank);
}
} // anonymous namespace
} // namespace
} // namespace utils
} // namespace spvtools

View File

@ -19,13 +19,10 @@
#include "source/util/parse_number.h"
#include "spirv-tools/libspirv.h"
namespace spvtools {
namespace utils {
namespace {
using spvutils::EncodeNumberStatus;
using spvutils::NumberType;
using spvutils::ParseAndEncodeFloatingPointNumber;
using spvutils::ParseAndEncodeIntegerNumber;
using spvutils::ParseAndEncodeNumber;
using spvutils::ParseNumber;
using testing::Eq;
using testing::IsNull;
using testing::NotNull;
@ -191,7 +188,7 @@ TEST(ParseFloat, Overflow) {
// range values. When it does overflow, the value is set to the
// nearest finite value, matching C++11 behavior for operator>>
// on floating point.
spvutils::HexFloat<spvutils::FloatProxy<float>> f(0.0f);
HexFloat<FloatProxy<float>> f(0.0f);
EXPECT_TRUE(ParseNumber("1e38", &f));
EXPECT_EQ(1e38f, f.value().getAsFloat());
@ -236,7 +233,7 @@ TEST(ParseDouble, Overflow) {
// range values. When it does overflow, the value is set to the
// nearest finite value, matching C++11 behavior for operator>>
// on floating point.
spvutils::HexFloat<spvutils::FloatProxy<double>> f(0.0);
HexFloat<FloatProxy<double>> f(0.0);
EXPECT_TRUE(ParseNumber("1e38", &f));
EXPECT_EQ(1e38, f.value().getAsFloat());
@ -256,7 +253,7 @@ TEST(ParseFloat16, Overflow) {
// range values. When it does overflow, the value is set to the
// nearest finite value, matching C++11 behavior for operator>>
// on floating point.
spvutils::HexFloat<spvutils::FloatProxy<spvutils::Float16>> f(0);
HexFloat<FloatProxy<Float16>> f(0);
EXPECT_FALSE(ParseNumber(nullptr, &f));
EXPECT_TRUE(ParseNumber("-0.0", &f));
@ -967,4 +964,6 @@ TEST(ParseAndEncodeNumber, Sample) {
EXPECT_EQ(EncodeNumberStatus::kSuccess, rc);
}
} // anonymous namespace
} // namespace
} // namespace utils
} // namespace spvtools

View File

@ -18,11 +18,10 @@
#include "source/util/string_utils.h"
#include "spirv-tools/libspirv.h"
namespace spvtools {
namespace utils {
namespace {
using ::spvutils::CardinalToOrdinal;
using ::spvutils::ToString;
TEST(ToString, Int) {
EXPECT_EQ("0", ToString(0));
EXPECT_EQ("1000", ToString(1000));
@ -187,4 +186,6 @@ TEST(CardinalToOrdinal, Test) {
EXPECT_EQ("1225th", CardinalToOrdinal(1225));
}
} // anonymous namespace
} // namespace
} // namespace utils
} // namespace spvtools

View File

@ -18,13 +18,10 @@
#include "gtest/gtest.h"
#include "source/util/timer.h"
namespace spvtools {
namespace utils {
namespace {
using ::spvutils::CumulativeTimer;
using ::spvutils::PrintTimerDescription;
using ::spvutils::ScopedTimer;
using ::spvutils::Timer;
// A mock class to mimic Timer class for a testing purpose. It has fixed
// CPU/WALL/USR/SYS time, RSS delta, and the delta of the number of page faults.
class MockTimer : public Timer {
@ -140,4 +137,6 @@ TEST(MockCumulativeTimer, DoNothing) {
if (ctimer) delete ctimer;
}
} // anonymous namespace
} // namespace
} // namespace utils
} // namespace spvtools

View File

@ -21,7 +21,7 @@
#include <unordered_set>
#include <vector>
using spvutils::HuffmanCodec;
using spvtools::utils::HuffmanCodec;
namespace spvtools {
namespace comp {

View File

@ -32,7 +32,7 @@
#include "source/util/huffman_codec.h"
using libspirv::SpirvStats;
using spvutils::HuffmanCodec;
using spvtools::utils::HuffmanCodec;
namespace {