First commit

This commit is contained in:
Tomer Even 2022-03-18 12:17:23 +02:00
commit da77ff2b7d
104 changed files with 24962 additions and 0 deletions

66
.clang-format Normal file
View File

@ -0,0 +1,66 @@
# Generated from CLion C/C++ Code Style settings
BasedOnStyle: LLVM
AccessModifierOffset: -4
AlignAfterOpenBracket: Align
AlignConsecutiveAssignments: false
AlignOperands: true
AllowAllArgumentsOnNextLine: false
AllowAllConstructorInitializersOnNextLine: false
AllowAllParametersOfDeclarationOnNextLine: false
AllowShortBlocksOnASingleLine: Always
AllowShortCaseLabelsOnASingleLine: false
AllowShortFunctionsOnASingleLine: All
AllowShortIfStatementsOnASingleLine: Always
AllowShortLambdasOnASingleLine: All
AllowShortLoopsOnASingleLine: true
AlwaysBreakAfterReturnType: None
AlwaysBreakTemplateDeclarations: Yes
BreakBeforeBraces: Custom
BraceWrapping:
AfterCaseLabel: false
AfterClass: false
AfterControlStatement: Never
AfterEnum: false
AfterFunction: false
AfterNamespace: false
AfterUnion: false
BeforeCatch: false
BeforeElse: false
IndentBraces: false
SplitEmptyFunction: false
SplitEmptyRecord: true
BreakBeforeBinaryOperators: None
BreakBeforeTernaryOperators: true
BreakConstructorInitializers: BeforeColon
BreakInheritanceList: BeforeColon
ColumnLimit: 0
CompactNamespaces: false
ContinuationIndentWidth: 8
IndentCaseLabels: true
IndentPPDirectives: None
IndentWidth: 4
KeepEmptyLinesAtTheStartOfBlocks: true
MaxEmptyLinesToKeep: 2
NamespaceIndentation: All
ObjCSpaceAfterProperty: false
ObjCSpaceBeforeProtocolList: true
PointerAlignment: Right
ReflowComments: false
SpaceAfterCStyleCast: true
SpaceAfterLogicalNot: false
SpaceAfterTemplateKeyword: false
SpaceBeforeAssignmentOperators: true
SpaceBeforeCpp11BracedList: false
SpaceBeforeCtorInitializerColon: true
SpaceBeforeInheritanceColon: true
SpaceBeforeParens: ControlStatements
SpaceBeforeRangeBasedForLoopColon: true
SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 0
SpacesInAngles: false
SpacesInCStyleCastParentheses: false
SpacesInContainerLiterals: false
SpacesInParentheses: false
SpacesInSquareBrackets: false
TabWidth: 4
UseTab: Never

8
.idea/.gitignore vendored Normal file
View File

@ -0,0 +1,8 @@
# Default ignored files
/shelf/
/workspace.xml
# Editor-based HTTP Client requests
/httpRequests/
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml

1
.idea/.name Normal file
View File

@ -0,0 +1 @@
APD_ONLY

2
.idea/Public-PF.iml Normal file
View File

@ -0,0 +1,2 @@
<?xml version="1.0" encoding="UTF-8"?>
<module classpath="CMake" type="CPP_MODULE" version="4" />

View File

@ -0,0 +1,14 @@
<component name="ProjectCodeStyleConfiguration">
<code_scheme name="Project" version="173">
<Objective-C-extensions>
<extensions>
<pair source="cpp" header="hpp" fileNamingConvention="NONE" />
<pair source="c" header="h" fileNamingConvention="NONE" />
<pair source="cu" header="cuh" fileNamingConvention="NONE" />
</extensions>
</Objective-C-extensions>
<clangFormatSettings>
<option name="ENABLED" value="true" />
</clangFormatSettings>
</code_scheme>
</component>

View File

@ -0,0 +1,5 @@
<component name="ProjectCodeStyleConfiguration">
<state>
<option name="USE_PER_PROJECT_SETTINGS" value="true" />
</state>
</component>

4
.idea/misc.xml Normal file
View File

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CMakeWorkspace" PROJECT_DIR="$PROJECT_DIR$" />
</project>

8
.idea/modules.xml Normal file
View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/Public-PF.iml" filepath="$PROJECT_DIR$/.idea/Public-PF.iml" />
</modules>
</component>
</project>

6
.idea/vcs.xml Normal file
View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>

210
Bloom_Filter/Impala512.h Normal file
View File

@ -0,0 +1,210 @@
// Copied from Apache Impala (incubating), usable under the terms in the Apache License,
// Version 2.0.
// This is a block Bloom filter (from Putze et al.'s "Cache-, Hash- and Space-Efficient
// Bloom Filters") with some twists:
//
// 1. Each block is a split Bloom filter - see Section 2.1 of Broder and Mitzenmacher's
// "Network Applications of Bloom Filters: A Survey".
//
// 2. The number of bits set per Add() is contant in order to take advantage of SIMD
// instructions.
#pragma once
#include <cstdint>
#include <cstdlib>
#include <algorithm>
#include <new>
#include "../hashutil.h"
using uint32_t = ::std::uint32_t;
using uint64_t = ::std::uint64_t;
namespace Impala {
__attribute__((always_inline)) inline uint32_t reduce(uint32_t hash, uint32_t n) {
// http://lemire.me/blog/2016/06/27/a-fast-alternative-to-the-modulo-reduction/
return (uint32_t) (((uint64_t) hash * n) >> 32);
}
__attribute__((always_inline)) inline uint64_t reduce64(uint64_t hash, uint64_t n) {
// return hash % n;
// http://lemire.me/blog/2016/06/27/a-fast-alternative-to-the-modulo-reduction/
return (uint64_t) (((__uint128_t) hash * (__uint128_t) n) >> 64);
// return (uint32_t) (((uint64_t) hash * n) >> 32);
}
static inline uint64_t rotl64(uint64_t n, unsigned int c) {
// assumes width is a power of 2
const unsigned int mask = (CHAR_BIT * sizeof(n) - 1);
// assert ( (c<=mask) &&"rotate by type width or more");
c &= mask;
return (n << c) | (n >> ((-c) & mask));
}
static inline size_t get_number_of_buckets(size_t max_items) {
constexpr size_t log2_one_over_eps = 8;
constexpr double overhead = 1.5225;
constexpr size_t bucket_size_in_bits = 512;
size_t blooms_m = std::ceil(max_items * log2_one_over_eps * overhead);
size_t number_of_buckets = (blooms_m + bucket_size_in_bits - 1) / bucket_size_in_bits;
return number_of_buckets;
}
}// namespace Impala
#include <x86intrin.h>
template<typename HashFamily = ::hashing::TwoIndependentMultiplyShift>
class Impala512 {
private:
// The filter is divided up into Buckets:
using Bucket = uint64_t[8];
const int bucketCount;
Bucket *directory_;
HashFamily hasher_;
public:
// Consumes at most (1 << log_heap_space) bytes on the heap:
explicit Impala512(const int bits);
~Impala512() noexcept;
void Add(const uint64_t key) noexcept;
bool Find(const uint64_t key) const noexcept;
uint64_t SizeInBytes() const { return sizeof(Bucket) * bucketCount; }
size_t get_cap() const noexcept {
return -1;
}
float density() const noexcept {
size_t set_bits = 0;
for (int i = 0; i < bucketCount; i++) {
uint64_t temp;
memcpy(&temp, directory_+ i, 8);
set_bits += _mm_popcnt_u64(temp);
}
float res = 1.0 * set_bits / (bucketCount * 64);
return res;
}
private:
// A helper function for Insert()/Find(). Turns a 64-bit hash into a 512-bit Bucket
// with 1 single 1-bit set in each 32-bit lane.
static __m512i MakeMask(const uint64_t hash) noexcept;
};
template<typename HashFamily>
Impala512<HashFamily>::Impala512(const int n)
: bucketCount(Impala::get_number_of_buckets(n)),
directory_(nullptr),
hasher_() {
if (!__builtin_cpu_supports("avx2")) {
throw ::std::runtime_error("Impala512 does not work without AVX2 instructions");
}
const size_t alloc_size = bucketCount * sizeof(Bucket);
const int malloc_failed =
posix_memalign(reinterpret_cast<void **>(&directory_), 64, alloc_size);
if (malloc_failed) throw ::std::bad_alloc();
// std::cout << "Ctor: SIMD-fixed byte size: " << SizeInBytes() << std::endl;
memset(directory_, 0, alloc_size);
}
template<typename HashFamily>
Impala512<HashFamily>::~Impala512() noexcept {
// std::cout << "Dtor: SIMD-fixed byte size: " << SizeInBytes() << std::endl;
// std::cout << "density: " << density() << std::endl;
free(directory_);
directory_ = nullptr;
}
// The SIMD reinterpret_casts technically violate C++'s strict aliasing rules. However, we
// compile with -fno-strict-aliasing.
template<typename HashFamily>
[[gnu::always_inline]] inline __m512i
Impala512<HashFamily>::MakeMask(const uint64_t hash) noexcept {
const __m512i ones = _mm512_set1_epi64(1);
// Odd contants for hashing:
const __m512i rehash = _mm512_setr_epi64(0x89cdc1c02b2352b9ULL,
0x2b9aed3c5d9c5085ULL,
0xfb087273c257911bULL,
0x5ffd7847830af377ULL,
0x287348157aed6753ULL,
0x4e7292d5d251e97dULL,
0xe00e4fc1185d71cbULL,
0x4e3ebc18dc4c950bULL);
// const __m512i rehash = _mm512_setr_epi64(0x47b6137bU, 0x44974d91U, 0x8824ad5bU, 0xa2b7289dU, 0x705495c7U, 0x2df1424bU, 0x9efc4947U, 0x5c6bfb31U);
// Load hash into a YMM register, repeated eight times
__m512i hash_data = _mm512_set1_epi64(hash);
// Multiply-shift hashing ala Dietzfelbinger et al.: multiply 'hash' by eight different
// odd constants, then keep the 5 most significant bits from each product.
hash_data = _mm512_mullo_epi64(rehash, hash_data);
hash_data = _mm512_srli_epi64(hash_data, 64 - 6);
// Use these 5 bits to shift a single bit to a location in each 32-bit lane
/* #ifndef DNDEBUG
uint64_t a[8] = {0};
memcpy(a, (uint64_t *) (&hash_data), 64);
if ((hash & ((1ULL<<20)-1)) == 0){
std::cout << "hash: " << hash << std::endl;
for (size_t i = 0; i < 8; i++) {
std::cout << "a[i]: " << a[i] << std::endl;
}
}
auto temp = _mm512_sllv_epi64(ones, hash_data);
// uint64_t a[8] = {0};
memcpy(a, (uint64_t *) (&temp), 64);
int s = 0;
for (size_t i = 0; i < 8; i++) {
auto block_temp = _mm_popcnt_u64(a[i]);
assert(block_temp == 1);
s += _mm_popcnt_u64(a[i]);
}
if (s != 8) {
std::cout << "s: " << s << std::endl;
for (size_t i = 0; i < 8; i++) {
std::cout << "a[i]: " << a[i] << std::endl;
}
}
assert(s == 8);
#endif
*/
return _mm512_sllv_epi64(ones, hash_data);
}
template<typename HashFamily>
[[gnu::always_inline]] inline void
Impala512<HashFamily>::Add(const uint64_t key) noexcept {
const auto hash = hasher_(key);
const uint32_t bucket_idx = Impala::reduce(Impala::rotl64(hash, 32), bucketCount);
// const uint32_t bucket_idx = Impala::reduce64(hash, bucketCount);
const __m512i mask = MakeMask(hash);
__m512i *const bucket = &reinterpret_cast<__m512i *>(directory_)[bucket_idx];
_mm512_store_si512(bucket, _mm512_or_si512(*bucket, mask));
assert(Find(key));
}
template<typename HashFamily>
[[gnu::always_inline]] inline bool
Impala512<HashFamily>::Find(const uint64_t key) const noexcept {
const auto hash = hasher_(key);
// const uint32_t bucket_idx = Impala::reduce64(hash, bucketCount);
const uint32_t bucket_idx = Impala::reduce(Impala::rotl64(hash, 32), bucketCount);
const __m512i mask = MakeMask(hash);
const __m512i bucket = reinterpret_cast<__m512i *>(directory_)[bucket_idx];
// We should return true if 'bucket' has a one wherever 'mask' does. _mm512_testc_si512
// takes the negation of its first argument and ands that with its second argument. In
// our case, the result is zero everywhere iff there is a one in 'bucket' wherever
// 'mask' is one. testc returns 1 if the result is 0 everywhere and returns 0 otherwise.
constexpr __m512i zero_vec = {0, 0, 0, 0, 0, 0, 0, 0};
const __m512i res = _mm512_andnot_epi64(bucket, mask);
return _mm512_cmpeq_epi64_mask(res, zero_vec) == 0xff;
// const __m256i* array = reinterpret_cast<__m256i *>(&res);
}

453
Bloom_Filter/bloom.hpp Normal file
View File

@ -0,0 +1,453 @@
/* Taken from https://github.com/FastFilter/fastfilter_cpp */
#ifndef BLOOM_FILTER_BLOOM_FILTER_H_
#define BLOOM_FILTER_BLOOM_FILTER_H_
#include <algorithm>
#include <assert.h>
#include <sstream>
#include "../hashutil.h"
using namespace std;
using namespace hashing;
namespace bloomfilter {
// status returned by a Bloom filter operation
enum Status {
Ok = 0,
NotFound = 1,
NotEnoughSpace = 2,
NotSupported = 3,
};
inline uint32_t reduce(uint32_t hash, uint32_t n) {
// http://lemire.me/blog/2016/06/27/a-fast-alternative-to-the-modulo-reduction/
return (uint32_t) (((uint64_t) hash * n) >> 32);
}
/**
* Given a value "word", produces an integer in [0,p) without division.
* The function is as fair as possible in the sense that if you iterate
* through all possible values of "word", then you will generate all
* possible outputs as uniformly as possible.
*/
static inline uint32_t fastrange32(uint32_t word, uint32_t p) {
// http://lemire.me/blog/2016/06/27/a-fast-alternative-to-the-modulo-reduction/
return (uint32_t) (((uint64_t) word * (uint64_t) p) >> 32);
}
/**
* Given a value "word", produces an integer in [0,p) without division.
* The function is as fair as possible in the sense that if you iterate
* through all possible values of "word", then you will generate all
* possible outputs as uniformly as possible.
*/
static inline uint64_t fastrange64(uint64_t word, uint64_t p) {
// http://lemire.me/blog/2016/06/27/a-fast-alternative-to-the-modulo-reduction/
// #ifdef __SIZEOF_INT128__// then we know we have a 128-bit int
return (uint64_t) (((__uint128_t) word * (__uint128_t) p) >> 64);
}
#ifndef UINT32_MAX
#define UINT32_MAX (0xffffffff)
#endif// UINT32_MAX
/**
* Given a value "word", produces an integer in [0,p) without division.
* The function is as fair as possible in the sense that if you iterate
* through all possible values of "word", then you will generate all
* possible outputs as uniformly as possible.
*/
static inline size_t fastrangesize(uint64_t word, size_t p) {
#if (SIZE_MAX == UINT32_MAX)
return (size_t) fastrange32(word, p);
#else // assume 64-bit
return (size_t) fastrange64(word, p);
#endif// SIZE_MAX == UINT32_MAX
}
static inline size_t getBestK(size_t bitsPerItem) {
return max(1, (int) round((double) bitsPerItem * log(2)));
}
inline uint64_t getBit(uint32_t index) { return 1L << (index & 63); }
template<typename ItemType, size_t bits_per_item, bool branchless,
typename HashFamily = TwoIndependentMultiplyShift,
int k = (int) ((double) bits_per_item * 0.693147180559945 + 0.5)>
class BloomFilter {
public:
uint64_t *data;
size_t size;
size_t arrayLength;
size_t bitCount;
int kk;
HashFamily hasher;
double BitsPerItem() const { return k; }
explicit BloomFilter(const size_t n) : hasher() {
this->size = 0;
this->kk = getBestK(bits_per_item);
this->bitCount = n * bits_per_item;
this->arrayLength = (bitCount + 63) / 64;
data = new uint64_t[arrayLength];
std::fill_n(data, arrayLength, 0);
}
~BloomFilter() { delete[] data; }
// Add an item to the filter.
Status Add(const ItemType &item);
// Add multiple items to the filter.
Status AddAll(const vector<ItemType> &data, const size_t start,
const size_t end) {
return AddAll(data.data(), start, end);
}
Status AddAll(const ItemType *data, const size_t start,
const size_t end);
// Report if the item is inserted, with false positive rate.
Status Contain(const ItemType &item) const;
/* methods for providing stats */
// summary infomation
std::string Info() const;
// number of current inserted items;
size_t Size() const { return size; }
// size of the filter in bytes.
size_t SizeInBytes() const { return arrayLength * 8; }
std::string get_name() const {
size_t BPI = bits_per_item;
size_t hash_k = k;
std::string name = "Lem-BF-" + std::to_string(BPI) + "[k=" + std::to_string(hash_k) + "]";
return name;
// if (branchless) {
// return name + "-{branchless}";
// } else {
// return name + "-{with-branch}";
// }
}
};
template<typename ItemType, size_t bits_per_item, bool branchless,
typename HashFamily, int k>
Status BloomFilter<ItemType, bits_per_item, branchless, HashFamily, k>::Add(
const ItemType &key) {
uint64_t hash = hasher(key);
uint64_t a = (hash >> 32) | (hash << 32);
uint64_t b = hash;
for (int i = 0; i < k; i++) {
// int index = reduce(a, this->bitCount);
// data[index >> 6] |= getBit(index);
// reworked to avoid overflows
// use the fact that reduce is not very sensitive to lower bits of a
data[fastrangesize(a, this->arrayLength)] |= getBit(a);
a += b;
}
return Ok;
}
const int blockShift = 15;
const int blockLen = 1 << blockShift;
inline void applyBlock(uint32_t *tmp, int block, int len, uint64_t *data) {
for (int i = 0; i < len; i++) {
uint32_t index = tmp[(block << blockShift) + i];
data[index >> 6] |= getBit(index);
}
}
template<typename ItemType, size_t bits_per_item, bool branchless,
typename HashFamily, int k>
Status BloomFilter<ItemType, bits_per_item, branchless, HashFamily, k>::AddAll(
const ItemType *keys, const size_t start, const size_t end) {
// we have that AddAll assumes that arrayLength << 6 is a
// 32-bit integer
if (arrayLength > 0x3ffffff) {
for (size_t i = start; i < end; i++) {
Add(keys[i]);
}
return Ok;
}
int blocks = 1 + arrayLength / blockLen;
uint32_t *tmp = new uint32_t[blocks * blockLen];
int *tmpLen = new int[blocks]();
for (size_t i = start; i < end; i++) {
uint64_t key = keys[i];
uint64_t hash = hasher(key);
uint64_t a = (hash >> 32) | (hash << 32);
uint64_t b = hash;
for (int j = 0; j < k; j++) {
int index = fastrangesize(a, this->arrayLength);
int block = index >> blockShift;
int len = tmpLen[block];
tmp[(block << blockShift) + len] = (index << 6) + (a & 63);
tmpLen[block] = len + 1;
if (len + 1 == blockLen) {
applyBlock(tmp, block, len + 1, data);
tmpLen[block] = 0;
}
a += b;
}
}
for (int block = 0; block < blocks; block++) {
applyBlock(tmp, block, tmpLen[block], data);
}
delete[] tmp;
delete[] tmpLen;
return Ok;
}
inline char bittest64(const uint64_t *t, uint64_t bit) {
return (*t & (1L << (bit & 63))) != 0;
}
template<typename ItemType, size_t bits_per_item, bool branchless,
typename HashFamily, int k>
Status BloomFilter<ItemType, bits_per_item, branchless, HashFamily, k>::Contain(
const ItemType &key) const {
uint64_t hash = hasher(key);
uint64_t a = (hash >> 32) | (hash << 32);
uint64_t b = hash;
if (branchless && k >= 3) {
int b0 = data[fastrangesize(a, this->arrayLength)] >> (a & 63);
a += b;
int b1 = data[fastrangesize(a, this->arrayLength)] >> (a & 63);
a += b;
int b2 = data[fastrangesize(a, this->arrayLength)] >> (a & 63);
if ((b0 & b1 & b2 & 1) == 0) {
return NotFound;
}
for (int i = 3; i < k; i++) {
a += b;
if (((data[fastrangesize(a, this->arrayLength)] >> (a & 63)) & 1) == 0) {
return NotFound;
}
}
return Ok;
}
for (int i = 0; i < k; i++) {
if ((data[fastrangesize(a, this->arrayLength)] & getBit(a)) == 0) {
return NotFound;
}
a += b;
}
return Ok;
}
template<typename ItemType, size_t bits_per_item, bool branchless,
typename HashFamily, int k>
std::string
BloomFilter<ItemType, bits_per_item, branchless, HashFamily, k>::Info() const {
std::stringstream ss;
ss << "BloomFilter Status:\n"
<< "\t\tKeys stored: " << Size() << "\n";
if (Size() > 0) {
ss << "\t\tk: " << BitsPerItem() << "\n";
} else {
ss << "\t\tk: N/A\n";
}
return ss.str();
}
template<size_t m_up, size_t m_down, size_t k, bool branchless,
typename HashFamily = TwoIndependentMultiplyShift>
class BF_MA {
public:
uint64_t *data;
// const size_t m;
size_t cap = 0;
size_t arrayLength;
size_t bitCount;
int kk = k;
HashFamily hasher;
double BitsPerItem() const { return k; }
size_t get_m(size_t n) {
size_t res = (n * m_up + m_down - 1) / m_down;
assert(res > 0);
assert(res < (1ULL << 60u));
return res;
}
explicit BF_MA(const size_t n) : bitCount(get_m(n)),
arrayLength((get_m(n) + 63) / 64), hasher() {
//
// arrayLength((bitCount + 63) / 64),bitCount(n * bits_per_item),kk(k),hasher() {
// this->cap = 0;
// this->kk = getBestK(bits_per_item);
// this->bitCount = n * bits_per_item;
// bitCount(n * bits_per_item) this->arrayLength = (bitCount + 63) / 64;
data = new uint64_t[arrayLength];
std::fill_n(data, arrayLength, 0);
}
~BF_MA() { delete[] data; }
// Add an item to the filter.
Status Add(const uint64_t &item);
// Report if the item is inserted, with false positive rate.
Status Contain(const uint64_t &item) const;
Status contain_branchless(const uint64_t &item) const;
/* methods for providing stats */
// summary infomation
std::string Info() const;
// number of current inserted items;
size_t get_cap() const { return cap; }
// size of the filter in bytes.
size_t SizeInBytes() const { return arrayLength * 8; }
std::string get_name() const {
float BPI = (100 * m_up / m_down) / 100.0;
// double BPI = BPI_full * 100
size_t hash_k = k;
std::string name = "BF-MA-[bpi=10,k=" + std::to_string(k) + "]";
// std::string name = "BF-MA-" + std::to_string(BPI) + "[k=" + std::to_string(k) + "]";
if (branchless) {
return name + "-{branchless}";
} else {
return name + "-{with-branch}";
}
}
};
template<size_t m_up, size_t m_down, size_t k, bool branchless, typename HashFamily>
Status BF_MA<m_up, m_down, k, branchless, HashFamily>::Add(const uint64_t &key) {
cap++;
uint64_t hash = hasher(key);
uint64_t a = (hash >> 32) | (hash << 32);
uint64_t b = hash;
for (int i = 0; i < k; i++) {
// int index = reduce(a, this->bitCount);
// data[index >> 6] |= getBit(index);
// reworked to avoid overflows
// use the fact that reduce is not very sensitive to lower bits of a
data[fastrangesize(a, this->arrayLength)] |= getBit(a);
a += b;
}
return Ok;
}
template<size_t m_up, size_t m_down, size_t k, bool branchless, typename HashFamily>
Status BF_MA<m_up, m_down, k, branchless, HashFamily>::Contain(
const uint64_t &key) const {
uint64_t hash = hasher(key);
uint64_t a = (hash >> 32) | (hash << 32);
uint64_t b = hash;
for (int i = 0; i < k; i++) {
if ((data[fastrangesize(a, this->arrayLength)] & getBit(a)) == 0) {
return NotFound;
}
a += b;
}
return Ok;
if ((k == 2) and branchless) {
int b0 = data[fastrangesize(a, this->arrayLength)] >> (a & 63);
a += b;
int b1 = data[fastrangesize(a, this->arrayLength)] >> (a & 63);
if ((b0 & b1 & 1) == 0)
return NotFound;
return Ok;
} else if (k == 2) {
if (!(data[fastrangesize(a, this->arrayLength)] >> (a & 63)))
return NotFound;
a += b;
if (data[fastrangesize(a, this->arrayLength)] >> (a & 63)) {
return Ok;
}
return NotFound;
}
if (branchless && k >= 3) {
int b0 = data[fastrangesize(a, this->arrayLength)] >> (a & 63);
a += b;
int b1 = data[fastrangesize(a, this->arrayLength)] >> (a & 63);
a += b;
int b2 = data[fastrangesize(a, this->arrayLength)] >> (a & 63);
if ((b0 & b1 & b2 & 1) == 0) {
return NotFound;
}
for (int i = 3; i < k; i++) {
a += b;
if (((data[fastrangesize(a, this->arrayLength)] >> (a & 63)) & 1) == 0) {
return NotFound;
}
}
return Ok;
}
for (int i = 0; i < k; i++) {
if ((data[fastrangesize(a, this->arrayLength)] & getBit(a)) == 0) {
return NotFound;
}
a += b;
}
return Ok;
}
/* template<size_t m_up, size_t m_down, size_t k, bool branchless, typename HashFamily>
Status BF_MA<m_up, m_down, k, branchless, HashFamily>::contain_branchless(
const uint64_t &key) const {
uint64_t hash = hasher(key);
uint64_t a = (hash >> 32) | (hash << 32);
uint64_t b = hash;
size_t locations[k] = {0};
for (size_t i = 0; i < k; i++)
{
locations[i] = fastrangesize(a, this->arrayLength);
a += b;
}
int res = 1u;
for (size_t i = 0; i < k; i++)
{
res &= data[locations[i]] >> ()
}
}
*/
template<size_t m_up, size_t m_down, size_t k, bool branchless, typename HashFamily>
std::string
BF_MA<m_up, m_down, k, branchless, HashFamily>::Info() const {
std::stringstream ss;
ss << "BloomFilter Status:\n"
<< "\t\tKeys stored: " << get_cap() << "\n";
if (get_cap() > 0) {
ss << "\t\tk: " << BitsPerItem() << "\n";
} else {
ss << "\t\tk: N/A\n";
}
return ss.str();
}
}// namespace bloomfilter
#endif// BLOOM_FILTER_BLOOM_FILTER_H_

View File

@ -0,0 +1,500 @@
// Copied from Apache Impala (incubating), usable under the terms in the Apache License,
// Version 2.0.
// This is a block Bloom filter (from Putze et al.'s "Cache-, Hash- and Space-Efficient
// Bloom Filters") with some twists:
//
// 1. Each block is a split Bloom filter - see Section 2.1 of Broder and Mitzenmacher's
// "Network Applications of Bloom Filters: A Survey".
//
// 2. The number of bits set per Add() is contant in order to take advantage of SIMD
// instructions.
#pragma once
#include <cstdint>
#include <cstdlib>
#include <algorithm>
#include <new>
#include "../hashutil.h"
using uint32_t = ::std::uint32_t;
using uint64_t = ::std::uint64_t;
__attribute__((always_inline))
inline uint32_t reduce(uint32_t hash, uint32_t n) {
// http://lemire.me/blog/2016/06/27/a-fast-alternative-to-the-modulo-reduction/
return (uint32_t) (((uint64_t) hash * n) >> 32);
}
static inline uint64_t rotl64(uint64_t n, unsigned int c) {
// assumes width is a power of 2
const unsigned int mask = (CHAR_BIT * sizeof(n) - 1);
// assert ( (c<=mask) &&"rotate by type width or more");
c &= mask;
return (n << c) | (n >> ((-c) & mask));
}
#ifdef __AVX2__
#include <x86intrin.h>
template<typename HashFamily = ::hashing::TwoIndependentMultiplyShift>
class SimdBlockFilterFixed {
private:
// The filter is divided up into Buckets:
using Bucket = uint32_t[8];
const int bucketCount;
Bucket *directory_;
HashFamily hasher_;
public:
// Consumes at most (1 << log_heap_space) bytes on the heap:
explicit SimdBlockFilterFixed(const int bits);
~SimdBlockFilterFixed() noexcept;
void Add(const uint64_t key) noexcept;
// Add multiple items to the filter.
void AddAll(const std::vector<uint64_t> &data, const size_t start, const size_t end) {
return AddAll(data.data(), start, end);
}
void AddAll(const uint64_t *data, const size_t start, const size_t end);
bool Find(const uint64_t key) const noexcept;
uint64_t SizeInBytes() const { return sizeof(Bucket) * bucketCount; }
size_t get_cap() const noexcept {
return -1;
}
private:
// A helper function for Insert()/Find(). Turns a 32-bit hash into a 256-bit Bucket
// with 1 single 1-bit set in each 32-bit lane.
static __m256i MakeMask(const uint32_t hash) noexcept;
void ApplyBlock(uint64_t *tmp, int block, int len);
};
template<typename HashFamily>
SimdBlockFilterFixed<HashFamily>::SimdBlockFilterFixed(const int bits)
// bits / 16: fpp 0.1777%, 75.1%
// bits / 20: fpp 0.4384%, 63.4%
// bits / 22: fpp 0.6692%, 61.1%
// bits / 24: fpp 0.9765%, 59.7% <<== seems to be best (1% fpp seems important)
// bits / 26: fpp 1.3769%, 59.3%
// bits / 28: fpp 1.9197%, 60.3%
// bits / 32: fpp 3.3280%, 63.0%
: bucketCount(::std::max(1, bits / 24)),
directory_(nullptr),
hasher_() {
if (!__builtin_cpu_supports("avx2")) {
throw ::std::runtime_error("SimdBlockFilterFixed does not work without AVX2 instructions");
}
const size_t alloc_size = bucketCount * sizeof(Bucket);
const int malloc_failed =
posix_memalign(reinterpret_cast<void **>(&directory_), 64, alloc_size);
if (malloc_failed) throw ::std::bad_alloc();
// std::cout << "Ctor: SIMD-fixed byte size: " << SizeInBytes() << std::endl;
memset(directory_, 0, alloc_size);
}
template<typename HashFamily>
SimdBlockFilterFixed<HashFamily>::~SimdBlockFilterFixed() noexcept {
// std::cout << "Dtor: SIMD-fixed byte size: " << SizeInBytes() << std::endl;
free(directory_);
directory_ = nullptr;
}
// The SIMD reinterpret_casts technically violate C++'s strict aliasing rules. However, we
// compile with -fno-strict-aliasing.
template<typename HashFamily>
[[gnu::always_inline]] inline __m256i
SimdBlockFilterFixed<HashFamily>::MakeMask(const uint32_t hash) noexcept {
const __m256i ones = _mm256_set1_epi32(1);
// Odd contants for hashing:
const __m256i rehash = _mm256_setr_epi32(0x47b6137bU, 0x44974d91U, 0x8824ad5bU,
0xa2b7289dU, 0x705495c7U, 0x2df1424bU, 0x9efc4947U, 0x5c6bfb31U);
// Load hash into a YMM register, repeated eight times
__m256i hash_data = _mm256_set1_epi32(hash);
// Multiply-shift hashing ala Dietzfelbinger et al.: multiply 'hash' by eight different
// odd constants, then keep the 5 most significant bits from each product.
hash_data = _mm256_mullo_epi32(rehash, hash_data);
hash_data = _mm256_srli_epi32(hash_data, 27);
// Use these 5 bits to shift a single bit to a location in each 32-bit lane
return _mm256_sllv_epi32(ones, hash_data);
}
template<typename HashFamily>
[[gnu::always_inline]] inline void
SimdBlockFilterFixed<HashFamily>::Add(const uint64_t key) noexcept {
const auto hash = hasher_(key);
const uint32_t bucket_idx = reduce(rotl64(hash, 32), bucketCount);
const __m256i mask = MakeMask(hash);
__m256i *const bucket = &reinterpret_cast<__m256i *>(directory_)[bucket_idx];
_mm256_store_si256(bucket, _mm256_or_si256(*bucket, mask));
}
const int blockShift = 14;
const int blockLen = 1 << blockShift;
template<typename HashFamily>
void SimdBlockFilterFixed<HashFamily>::ApplyBlock(uint64_t *tmp, int block, int len) {
for (int i = 0; i < len; i += 2) {
uint64_t hash = tmp[(block << blockShift) + i];
uint32_t bucket_idx = tmp[(block << blockShift) + i + 1];
const __m256i mask = MakeMask(hash);
__m256i *const bucket = &reinterpret_cast<__m256i *>(directory_)[bucket_idx];
_mm256_store_si256(bucket, _mm256_or_si256(*bucket, mask));
}
}
template<typename HashFamily>
void SimdBlockFilterFixed<HashFamily>::AddAll(
const uint64_t *keys, const size_t start, const size_t end) {
int blocks = 1 + bucketCount / blockLen;
uint64_t *tmp = new uint64_t[blocks * blockLen];
int *tmpLen = new int[blocks]();
for (size_t i = start; i < end; i++) {
uint64_t key = keys[i];
uint64_t hash = hasher_(key);
uint32_t bucket_idx = reduce(rotl64(hash, 32), bucketCount);
int block = bucket_idx >> blockShift;
int len = tmpLen[block];
tmp[(block << blockShift) + len] = hash;
tmp[(block << blockShift) + len + 1] = bucket_idx;
tmpLen[block] = len + 2;
if (len + 2 == blockLen) {
ApplyBlock(tmp, block, len + 1);
tmpLen[block] = 0;
}
}
for (int block = 0; block < blocks; block++) {
ApplyBlock(tmp, block, tmpLen[block]);
}
delete[] tmp;
delete[] tmpLen;
}
template<typename HashFamily>
[[gnu::always_inline]] inline bool
SimdBlockFilterFixed<HashFamily>::Find(const uint64_t key) const noexcept {
const auto hash = hasher_(key);
const uint32_t bucket_idx = reduce(rotl64(hash, 32), bucketCount);
const __m256i mask = MakeMask(hash);
const __m256i bucket = reinterpret_cast<__m256i *>(directory_)[bucket_idx];
// We should return true if 'bucket' has a one wherever 'mask' does. _mm256_testc_si256
// takes the negation of its first argument and ands that with its second argument. In
// our case, the result is zero everywhere iff there is a one in 'bucket' wherever
// 'mask' is one. testc returns 1 if the result is 0 everywhere and returns 0 otherwise.
return _mm256_testc_si256(bucket, mask);
}
///////////////////////////////////////////////////////////////////
/// 64-byte version
///////////////////////////////////////////////////////////////////
struct mask64bytes {
__m256i first;
__m256i second;
};
typedef struct mask64bytes mask64bytes_t;
template<typename HashFamily = ::hashing::TwoIndependentMultiplyShift>
class SimdBlockFilterFixed64 {
private:
// The filter is divided up into Buckets:
using Bucket = mask64bytes_t;
const int bucketCount;
Bucket *directory_;
HashFamily hasher_;
public:
// Consumes at most (1 << log_heap_space) bytes on the heap:
explicit SimdBlockFilterFixed64(const int bits);
~SimdBlockFilterFixed64() noexcept;
void Add(const uint64_t key) noexcept;
bool Find(const uint64_t key) const noexcept;
uint64_t SizeInBytes() const { return sizeof(Bucket) * bucketCount; }
private:
static mask64bytes_t MakeMask(const uint64_t hash) noexcept;
};
template<typename HashFamily>
SimdBlockFilterFixed64<HashFamily>::SimdBlockFilterFixed64(const int bits)
: bucketCount(::std::max(1, bits / 50)),
directory_(nullptr),
hasher_() {
if (!__builtin_cpu_supports("avx2")) {
throw ::std::runtime_error("SimdBlockFilterFixed64 does not work without AVX2 instructions");
}
const size_t alloc_size = bucketCount * sizeof(Bucket);
const int malloc_failed =
posix_memalign(reinterpret_cast<void **>(&directory_), 64, alloc_size);
if (malloc_failed) throw ::std::bad_alloc();
memset(directory_, 0, alloc_size);
}
template<typename HashFamily>
SimdBlockFilterFixed64<HashFamily>::~SimdBlockFilterFixed64() noexcept {
free(directory_);
directory_ = nullptr;
}
template<typename HashFamily>
[[gnu::always_inline]] inline mask64bytes_t
SimdBlockFilterFixed64<HashFamily>::MakeMask(const uint64_t hash) noexcept {
const __m256i ones = _mm256_set1_epi64x(1);
const __m256i rehash1 = _mm256_setr_epi32(0x47b6137bU, 0x44974d91U, 0x8824ad5bU,
0xa2b7289dU, 0x705495c7U, 0x2df1424bU, 0x9efc4947U, 0x5c6bfb31U);
mask64bytes_t answer;
__m256i hash_data = _mm256_set1_epi32(hash);
__m256i h = _mm256_mullo_epi32(rehash1, hash_data);
h = _mm256_srli_epi32(h, 26);
answer.first = _mm256_unpackhi_epi32(h, _mm256_setzero_si256());
answer.first = _mm256_sllv_epi64(ones, answer.first);
answer.second = _mm256_unpacklo_epi32(h, _mm256_setzero_si256());
answer.second = _mm256_sllv_epi64(ones, answer.second);
return answer;
}
template<typename HashFamily>
[[gnu::always_inline]] inline void
SimdBlockFilterFixed64<HashFamily>::Add(const uint64_t key) noexcept {
const auto hash = hasher_(key);
const uint32_t bucket_idx = reduce(rotl64(hash, 32), bucketCount);
mask64bytes_t mask = MakeMask(hash);
mask64bytes_t *const bucket = &reinterpret_cast<mask64bytes_t *>(directory_)[bucket_idx];
bucket->first = _mm256_or_si256(mask.first, bucket->first);
bucket->second = _mm256_or_si256(mask.second, bucket->second);
}
template<typename HashFamily>
[[gnu::always_inline]] inline bool
SimdBlockFilterFixed64<HashFamily>::Find(const uint64_t key) const noexcept {
const auto hash = hasher_(key);
const uint32_t bucket_idx = reduce(rotl64(hash, 32), bucketCount);
const mask64bytes_t mask = MakeMask(hash);
const mask64bytes_t bucket = reinterpret_cast<mask64bytes_t *>(directory_)[bucket_idx];
return _mm256_testc_si256(bucket.first, mask.first) & _mm256_testc_si256(bucket.second, mask.second);
}
#endif //__AVX2__
///////////////////
// 16-byte version ARM
//////////////////
#ifdef __aarch64__
#include <arm_neon.h>
template<typename HashFamily = ::hashing::TwoIndependentMultiplyShift>
class SimdBlockFilterFixed {
private:
// The filter is divided up into Buckets:
using Bucket = uint16x8_t;
const int bucketCount;
Bucket* directory_;
HashFamily hasher_;
public:
// Consumes at most (1 << log_heap_space) bytes on the heap:
explicit SimdBlockFilterFixed(const int bits);
~SimdBlockFilterFixed() noexcept;
void Add(const uint64_t key) noexcept;
// Add multiple items to the filter.
void AddAll(const vector<uint64_t>& data, const size_t start, const size_t end) {
return AddAll(data.data(),start,end);
}
void AddAll(const uint64_t* data, const size_t start, const size_t end);
bool Find(const uint64_t key) const noexcept;
uint64_t SizeInBytes() const { return sizeof(Bucket) * bucketCount; }
private:
// A helper function for Insert()/Find(). Turns a 32-bit hash into a 256-bit Bucket
// with 1 single 1-bit set in each 32-bit lane.
static Bucket MakeMask(const uint16_t hash) noexcept;
void ApplyBlock(uint64_t* tmp, int block, int len);
};
template<typename HashFamily>
SimdBlockFilterFixed<HashFamily>::SimdBlockFilterFixed(const int bits)
: bucketCount(::std::max(1, bits / 10)),
directory_(nullptr),
hasher_() {
const size_t alloc_size = bucketCount * sizeof(Bucket);
const int malloc_failed =
posix_memalign(reinterpret_cast<void**>(&directory_), 64, alloc_size);
if (malloc_failed) throw ::std::bad_alloc();
memset(directory_, 0, alloc_size);
}
template<typename HashFamily>
SimdBlockFilterFixed<HashFamily>::~SimdBlockFilterFixed() noexcept {
free(directory_);
directory_ = nullptr;
}
template <typename HashFamily>
[[gnu::always_inline]] inline uint16x8_t
SimdBlockFilterFixed<HashFamily>::MakeMask(const uint16_t hash) noexcept {
const uint16x8_t ones = {1,1,1,1,1,1,1,1};
const uint16x8_t rehash = {0x79d8, 0xe722, 0xf2fb, 0x21ec, 0x121b, 0x2302, 0x705a, 0x6e87};
uint16x8_t hash_data = {hash,hash,hash,hash,hash,hash,hash,hash};
uint16x8_t answer = vmulq_u16(hash_data,rehash);
answer = vshrq_n_u16(answer, 12);
answer = vshlq_u16(ones, vreinterpretq_s16_u16(answer));
return answer;
}
template <typename HashFamily>
[[gnu::always_inline]] inline void
SimdBlockFilterFixed<HashFamily>::Add(const uint64_t key) noexcept {
const auto hash = hasher_(key);
const uint32_t bucket_idx = reduce(rotl64(hash, 32), bucketCount);
const uint16x8_t mask = MakeMask(hash);
uint16x8_t bucket = directory_[bucket_idx];
directory_[bucket_idx] = vorrq_u16(mask, bucket);
}
template <typename HashFamily>
[[gnu::always_inline]] inline bool
SimdBlockFilterFixed<HashFamily>::Find(const uint64_t key) const noexcept {
const auto hash = hasher_(key);
const uint32_t bucket_idx = reduce(rotl64(hash, 32), bucketCount);
const uint16x8_t mask = MakeMask(hash);
const uint16x8_t bucket = directory_[bucket_idx];
uint16x8_t an = vbicq_u16(mask, bucket);
uint64x2_t v64 = vreinterpretq_u64_u16(an);
uint32x2_t v32 = vqmovn_u64(v64);
uint64x1_t result = vreinterpret_u64_u32(v32);
return vget_lane_u64(result, 0) == 0;
}
#endif // __aarch64__
///////////////////////////////////////////////////////////////////
/// 16-byte version (not very good)
///////////////////////////////////////////////////////////////////
#ifdef __SSE41__
#include <smmintrin.h>
template<typename HashFamily = ::hashing::TwoIndependentMultiplyShift>
class SimdBlockFilterFixed16 {
private:
// The filter is divided up into Buckets:
using Bucket = __m128i;
const int bucketCount;
Bucket* directory_;
HashFamily hasher_;
public:
// Consumes at most (1 << log_heap_space) bytes on the heap:
explicit SimdBlockFilterFixed16(const int bits);
~SimdBlockFilterFixed16() noexcept;
void Add(const uint64_t key) noexcept;
bool Find(const uint64_t key) const noexcept;
uint64_t SizeInBytes() const { return sizeof(Bucket) * bucketCount; }
private:
static __m128i MakeMask(const uint64_t hash) noexcept;
};
template<typename HashFamily>
SimdBlockFilterFixed16<HashFamily>::SimdBlockFilterFixed16(const int bits)
: bucketCount(::std::max(1, bits / 10)),
directory_(nullptr),
hasher_() {
const size_t alloc_size = bucketCount * sizeof(Bucket);
const int malloc_failed =
posix_memalign(reinterpret_cast<void**>(&directory_), 64, alloc_size);
if (malloc_failed) throw ::std::bad_alloc();
memset(directory_, 0, alloc_size);
}
template<typename HashFamily>
SimdBlockFilterFixed16<HashFamily>::~SimdBlockFilterFixed16() noexcept {
free(directory_);
directory_ = nullptr;
}
template <typename HashFamily>
[[gnu::always_inline]] inline __m128i
SimdBlockFilterFixed16<HashFamily>::MakeMask(const uint64_t hash) noexcept {
const __m128i rehash1 = _mm_setr_epi16(0x47b5, 0x4497, 0x8823,
0xa2b7, 0x7053, 0x2df1, 0x9efc, 0x5c6b);
__m128i hash_data = _mm_set1_epi32(hash );
__m128i h = _mm_mulhi_epi16(rehash1, hash_data);
return _mm_shuffle_epi8(_mm_set_epi8(1,2,4,8,16,32,64,-128,1,2,4,8,16,32,64,-128),h);
}
template <typename HashFamily>
[[gnu::always_inline]] inline void
SimdBlockFilterFixed16<HashFamily>::Add(const uint64_t key) noexcept {
const auto hash = hasher_(key);
const uint32_t bucket_idx = reduce(rotl64(hash, 32), bucketCount);
__m128i mask = MakeMask(hash);
__m128i* const bucket = reinterpret_cast<__m128i*>(directory_) + bucket_idx;
__m128i bucketvalue = _mm_loadu_si128(bucket);
bucketvalue = _mm_or_si128(bucketvalue, mask);
_mm_storeu_si128(bucket,bucketvalue);
}
template <typename HashFamily>
[[gnu::always_inline]] inline bool
SimdBlockFilterFixed16<HashFamily>::Find(const uint64_t key) const noexcept {
const auto hash = hasher_(key);
const uint32_t bucket_idx = reduce(rotl64(hash, 32), bucketCount);
const __m128i mask = MakeMask(hash);
__m128i* const bucket = reinterpret_cast<__m128i*>(directory_) + bucket_idx;
__m128i bucketvalue = _mm_loadu_si128(bucket);
return _mm_testc_si128(bucketvalue,mask);
}
#endif // #ifdef __SSE41__

152
Bloom_Filter/simd-block.h Normal file
View File

@ -0,0 +1,152 @@
// Copied from Apache Impala (incubating), usable under the terms in the Apache License,
// Version 2.0.
// This is a block Bloom filter (from Putze et al.'s "Cache-, Hash- and Space-Efficient
// Bloom Filters") with some twists:
//
// 1. Each block is a split Bloom filter - see Section 2.1 of Broder and Mitzenmacher's
// "Network Applications of Bloom Filters: A Survey".
//
// 2. The number of bits set per Add() is contant in order to take advantage of SIMD
// instructions.
#pragma once
#include <cstdint>
#include <cstdlib>
#include <algorithm>
#include <new>
#include "../hashutil.h"
#include <immintrin.h>
using uint32_t = ::std::uint32_t;
using uint64_t = ::std::uint64_t;
template<typename HashFamily = ::hashing::TwoIndependentMultiplyShift>
class SimdBlockFilter {
private:
// The filter is divided up into Buckets:
using Bucket = uint32_t[8];
// log2(number of bytes in a bucket):
static constexpr int LOG_BUCKET_BYTE_SIZE = 5;
static_assert(
(1 << LOG_BUCKET_BYTE_SIZE) == sizeof(Bucket) && sizeof(Bucket) == sizeof(__m256i),
"Bucket sizing has gone awry.");
// log_num_buckets_ is the log (base 2) of the number of buckets in the directory:
const int log_num_buckets_;
// directory_mask_ is (1 << log_num_buckets_) - 1. It is precomputed in the contructor
// for efficiency reasons:
const uint32_t directory_mask_;
Bucket *directory_;
HashFamily hasher_;
public:
// Consumes at most (1 << log_heap_space) bytes on the heap:
explicit SimdBlockFilter(const int log_heap_space);
SimdBlockFilter(SimdBlockFilter &&that)
: log_num_buckets_(that.log_num_buckets_),
directory_mask_(that.directory_mask_),
directory_(that.directory_),
hasher_(that.hasher_) {}
~SimdBlockFilter() noexcept;
void Add(const uint64_t key) noexcept;
bool Find(const uint64_t key) const noexcept;
uint64_t SizeInBytes() const { return sizeof(Bucket) * (1ull << log_num_buckets_); }
size_t get_cap() const noexcept {
return -1;
}
private:
// A helper function for Insert()/Find(). Turns a 32-bit hash into a 256-bit Bucket
// with 1 single 1-bit set in each 32-bit lane.
static __m256i MakeMask(const uint32_t hash) noexcept;
SimdBlockFilter(const SimdBlockFilter &) = delete;
void operator=(const SimdBlockFilter &) = delete;
};
template<typename HashFamily>
SimdBlockFilter<HashFamily>::SimdBlockFilter(const int log_heap_space)
: // Since log_heap_space is in bytes, we need to convert it to the number of Buckets
// we will use.
log_num_buckets_(::std::max(1, log_heap_space - LOG_BUCKET_BYTE_SIZE)),
// Don't use log_num_buckets_ if it will lead to undefined behavior by a shift that is
// too large.
directory_mask_((1ull << ::std::min(63, log_num_buckets_)) - 1),
directory_(nullptr),
hasher_() {
if (!__builtin_cpu_supports("avx2")) {
throw ::std::runtime_error("SimdBlockFilter does not work without AVX2 instructions");
}
const size_t alloc_size = 1ull << (log_num_buckets_ + LOG_BUCKET_BYTE_SIZE);
const int malloc_failed =
posix_memalign(reinterpret_cast<void **>(&directory_), 64, alloc_size);
if (malloc_failed) throw ::std::bad_alloc();
memset(directory_, 0, alloc_size);
}
template<typename HashFamily>
SimdBlockFilter<HashFamily>::~SimdBlockFilter() noexcept {
// std::cout << "SIMD byte size: " << SizeInBytes() << std::endl;
free(directory_);
directory_ = nullptr;
}
// The SIMD reinterpret_casts technically violate C++'s strict aliasing rules. However, we
// compile with -fno-strict-aliasing.
template<typename HashFamily>
[[gnu::always_inline]] inline __m256i
SimdBlockFilter<HashFamily>::MakeMask(const uint32_t hash) noexcept {
const __m256i ones = _mm256_set1_epi32(1);
// Odd contants for hashing:
const __m256i rehash = _mm256_setr_epi32(0x47b6137bU, 0x44974d91U, 0x8824ad5bU,
0xa2b7289dU, 0x705495c7U, 0x2df1424bU, 0x9efc4947U, 0x5c6bfb31U);
// Load hash into a YMM register, repeated eight times
__m256i hash_data = _mm256_set1_epi32(hash);
// Multiply-shift hashing ala Dietzfelbinger et al.: multiply 'hash' by eight different
// odd constants, then keep the 5 most significant bits from each product.
hash_data = _mm256_mullo_epi32(rehash, hash_data);
hash_data = _mm256_srli_epi32(hash_data, 27);
// Use these 5 bits to shift a single bit to a location in each 32-bit lane
return _mm256_sllv_epi32(ones, hash_data);
}
template<typename HashFamily>
[[gnu::always_inline]] inline void
SimdBlockFilter<HashFamily>::Add(const uint64_t key) noexcept {
const auto hash = hasher_(key);
const uint32_t bucket_idx = hash & directory_mask_;
const __m256i mask = MakeMask(hash >> log_num_buckets_);
__m256i *const bucket = &reinterpret_cast<__m256i *>(directory_)[bucket_idx];
_mm256_store_si256(bucket, _mm256_or_si256(*bucket, mask));
}
template<typename HashFamily>
[[gnu::always_inline]] inline bool
SimdBlockFilter<HashFamily>::Find(const uint64_t key) const noexcept {
const auto hash = hasher_(key);
const uint32_t bucket_idx = hash & directory_mask_;
const __m256i mask = MakeMask(hash >> log_num_buckets_);
const __m256i bucket = reinterpret_cast<__m256i *>(directory_)[bucket_idx];
// We should return true if 'bucket' has a one wherever 'mask' does. _mm256_testc_si256
// takes the negation of its first argument and ands that with its second argument. In
// our case, the result is zero everywhere iff there is a one in 'bucket' wherever
// 'mask' is one. testc returns 1 if the result is 0 everywhere and returns 0 otherwise.
return _mm256_testc_si256(bucket, mask);
}

116
CMakeLists.txt Normal file
View File

@ -0,0 +1,116 @@
cmake_minimum_required(VERSION 3.10)
# set(CMAKE_C_COMPILER gcc-10)
# set(CMAKE_CXX_COMPILER g++-10)
# set(CMAKE_C_COMPILER clang)
# set(CMAKE_CXX_COMPILER clang++)
set(CMAKE_CXX_STANDARD 17)
project(APD_ONLY)
# set(COMPILE_FLAGS "-fprofile-instr-generate -fcoverage-mapping")
# set(CMAKE_EXE_LINKER_FLAGS "-fprofile-instr-generate")
set(CMAKE_CXX_FLAGS "-march=native")
# Seems like those are necessary.
# set(CMAKE_CXX_FLAGS "-mavx2 -mbmi -mbmi2 -mlzcnt -mpopcnt -mavx512vl -mavx512vbmi -mavx512dq -mavx512f -mavx512cd")
#-fsanitize=undefined
#-fsanitize=memory
#set (CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -fsanitize=undefined -fno-omit-frame-pointer")
#set (CMAKE_LINKER_FLAGS_DEBUG "${CMAKE_LINKER_FLAGS_DEBUG} -fsanitize=address -fno-omit-frame-pointer")
set(PF_FILES
Prefix-Filter/Shift_op.hpp Prefix-Filter/Shift_op.cpp
Prefix-Filter/min_pd256.hpp Prefix-Filter/min_pd256.cpp
)
set(CF_FILES
cuckoofilter/src/bitsutil.h cuckoofilter/src/permencoding.h
cuckoofilter/src/printutil.cc cuckoofilter/src/debug.h
cuckoofilter/src/singletable.h cuckoofilter/src/packedtable.h
cuckoofilter/src/cuckoofilter.h
cuckoofilter/src/cuckoofilter_stable.h
)
set(TESTS_FILES
hashutil.h
Tests/wrappers.hpp
Tests/smart_tests.hpp
Tests/smart_tests.cpp
# Tests/PerfEvent.hpp
)
set(TC_SHORTCUT_FILES
# hashutil.h
TC-Shortcut/tc-sym.hpp
TC-Shortcut/tc-sym.cpp
TC-Shortcut/TC-shortcut.hpp)
set(Bloom_Files
Bloom_Filter/simd-block.h
Bloom_Filter/simd-block-fixed-fpp.h
Bloom_Filter/Impala512.h
Bloom_Filter/bloom.hpp
# Bloom_Filter/bloom-simple.hpp
)
set(ALL_FILES_NM
${Bloom_Files}
${TESTS_FILES}
${PF_FILES}
${CF_FILES}
${TC_SHORTCUT_FILES}
)
set(ALL_FILES
${ALL_FILES_NM}
# ${XOR_FILES}
all_main.cpp
)
################################################################################
################################################################################
################################################################################
################################################################################
# Measure built
add_executable(measure_built0 ${ALL_FILES_NM} main-built.cpp)
add_executable(measure_built3 ${ALL_FILES_NM} main-built.cpp)
add_executable(measure_built ${ALL_FILES_NM} main-built.cpp)
target_compile_options(measure_built0 PRIVATE -O0 -g3 -W)
target_compile_options(measure_built3 PRIVATE -O3 -g3)
target_compile_options(measure_built PRIVATE -Ofast -DNDEBUG)
################################################################################
# Measure fpp
add_executable(measure_fpp0 ${ALL_FILES_NM} main-fpp.cpp)
add_executable(measure_fpp3 ${ALL_FILES_NM} main-fpp.cpp)
add_executable(measure_fpp ${ALL_FILES_NM} main-fpp.cpp)
target_compile_options(measure_fpp0 PRIVATE -O0 -g3 -W)
target_compile_options(measure_fpp3 PRIVATE -O3 -g3)
target_compile_options(measure_fpp PRIVATE -Ofast -DNDEBUG )
################################################################################
# Measure perf
add_executable(measure_perf0 ${ALL_FILES_NM} main-perf.cpp)
add_executable(measure_perf3 ${ALL_FILES_NM} main-perf.cpp)
add_executable(measure_perf ${ALL_FILES_NM} main-perf.cpp)
target_compile_options(measure_perf0 PRIVATE -O0 -g3 -W)
target_compile_options(measure_perf3 PRIVATE -O3 -g3)
target_compile_options(measure_perf PRIVATE -Ofast -DNDEBUG)
################################################################################
# Measure example
add_executable(example0 ${ALL_FILES_NM} example.cpp)
add_executable(example ${ALL_FILES_NM} example.cpp)
target_compile_options(example0 PRIVATE -O0 -g3 -W)
target_compile_options(example PRIVATE -Ofast -DNDEBUG)
################################################################################

13
LICENSE.md Normal file
View File

@ -0,0 +1,13 @@
Copyright (c) 2021, All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

2539
Prefix-Filter/Shift_op.cpp Normal file

File diff suppressed because it is too large Load Diff

2148
Prefix-Filter/Shift_op.hpp Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,41 @@
#include "min_pd256.hpp"
namespace min_pd::check {
bool validate_decoding(const __m256i *pd) {
constexpr size_t t = MAX_CAP0 - 1;
const u64 dirty_h = ((const u64 *) pd)[0];
size_t status = dirty_h & 31;
size_t last_quot = select64(~(dirty_h >> 6), t) - t;
if(status != last_quot) {
std::cout << "status: \t" << status << std::endl;
std::cout << "last_quot: \t" << last_quot << std::endl;
assert(0);
}
return true;
}
bool val_header(const __m256i *pd) {
const uint64_t h0 = reinterpret_cast<const u64 *>(pd)[0];
const u64 h = (h0 >> 6) & H_mask;
auto pop0 = _mm_popcnt_u64(h);
assert(pop0 == QUOTS);
return true;
}
bool val_last_quot_is_sorted(const __m256i *pd){
if (!did_pd_overflowed(pd))
return true;
size_t last_quot = get_last_occupied_quot_only_full_pd(pd);
size_t lq_cap = get_spec_quot_cap(last_quot, pd);
assert(lq_cap);
if (lq_cap == 1)
return true;
auto mp = (u8*)pd + 32 - lq_cap;
for (size_t i = 1; i < lq_cap; ++i) {
assert(mp[i-1] <= mp[i]);
}
return true;
}
}// namespace min_pd::check

549
Prefix-Filter/min_pd256.hpp Normal file
View File

@ -0,0 +1,549 @@
#ifndef FILTERS_MIN_PD256_HPP
#define FILTERS_MIN_PD256_HPP
#include <assert.h>
#include <limits.h>
#include <stdint.h>
#include <string.h>
#include <iostream>
#include <immintrin.h>
#include <x86intrin.h>
#include "Shift_op.hpp"
namespace min_pd::check {
bool validate_decoding(const __m256i *pd);
bool val_header(const __m256i *pd);
/**
* If pd did overflowed checks that the last quotient is sorted.
* @param pd
* @return
*/
bool val_last_quot_is_sorted(const __m256i *pd);
}// namespace min_pd::check
namespace min_pd {
constexpr size_t QUOTS = 25;
constexpr size_t MAX_CAP0 = 25;
constexpr u64 H_mask = (1ULL << (QUOTS + MAX_CAP0)) - 1;
struct add_res {
u8 quot;
u8 rem;
bool passed;
};
bool find_core(int64_t quot, uint8_t rem, const __m256i *pd);
/**
* Remark: if `x` has `j` set bits, then: select(x,j) == 64.
* @param x
* @param j
* @return The position (starting from 0) of the jth set bit of x.
*/
inline uint64_t select64(uint64_t x, int64_t j) {
assert(j < 64);
const uint64_t y = _pdep_u64(UINT64_C(1) << j, x);
return _tzcnt_u64(y);
}
inline unsigned get_status(const __m256i *pd) {
u8 temp;
memcpy(&temp, pd, 1);
return temp & 31;
}
inline unsigned get_h_first_byte(const __m256i *pd) {
u8 temp;
memcpy(&temp, pd, 1);
return temp;
}
inline uint8_t get_last_byte(const __m256i *pd) {
uint8_t x;
memcpy(&x, ((uint8_t *) pd) + 31, 1);
return x;
}
inline uint64_t get_header(const __m256i *pd) {
return ((uint64_t *) pd)[0] & ((1ULL << 56) - 1);
}
inline uint64_t get_clean_header(const __m256i *pd) {
// uint64_t res = (_mm_cvtsi128_si64(_mm256_castsi256_si128(*pd)) >> 6) & ((1ULL << 50) - 1);
return ((((uint64_t *) pd)[0]) >> 6ul) & ((1ULL << 50ul) - 1);
}
inline bool did_pd_overflowed(const __m256i *pd) {
return !(((uint64_t *) pd)[0] & 32);
}
inline void set_overflow_bit(__m256i *pd) {
uint64_t *h_array = ((uint64_t *) pd);
h_array[0] |= 32;
h_array[0] ^= 32;
assert(did_pd_overflowed(pd));
}
inline void clear_overflow_bit(__m256i *pd) {
uint64_t *h_array = ((uint64_t *) pd);
h_array[0] |= 32;
// h_array[0] ^= 32;
assert(!did_pd_overflowed(pd));
}
inline uint64_t decode_last_quot(const __m256i *pd) {
return ((uint64_t *) pd)[0] & 31;
}
inline size_t get_cap_naive(const __m256i *pd) {
// constexpr u64 mask = (1ULL << (QUOTS + MAX_CAP0)) - 1;
constexpr size_t t = QUOTS - 1;
const uint64_t header = reinterpret_cast<const u64 *>(pd)[0];
u64 h0 = (header >> 6);// & H_mask;
size_t res = select64(h0, t) - t;
return res;
// auto pop0 = _mm_popcnt_u64(h0);
// assert(pop0 == QUOTS);
// size_t zeros = 64 - pop0;
// size_t cap = zeros - 14;
// return cap;
}
inline size_t get_capacity(const __m256i *pd) {
const uint64_t header = reinterpret_cast<const u64 *>(pd)[0];
auto temp = _lzcnt_u64(header << 8);
uint64_t res = MAX_CAP0 - temp;
assert(res == get_cap_naive(pd));
return res;
}
inline size_t get_cap(const __m256i *pd) {
const uint64_t header = reinterpret_cast<const u64 *>(pd)[0];
auto temp = _lzcnt_u64(header << 8);
uint64_t res = MAX_CAP0 - temp;
assert(res == get_cap_naive(pd));
return res;
}
inline bool is_pd_full(const __m256i *pd) {
const uint64_t header = reinterpret_cast<const u64 *>(pd)[0];
bool res = header & (1ULL << 55);
assert(res == (get_cap(pd) == MAX_CAP0));
return res;
}
inline bool pd_full(const __m256i *pd) {
return is_pd_full(pd);
}
inline bool is_header_full(const __m256i *pd) {
u8 temp;
memcpy(&temp, (const u8 *) pd + 6, 1);
return temp & 128;
}
inline unsigned header_last_two_bits(const __m256i *pd) {
const uint64_t header = reinterpret_cast<const u64 *>(pd)[0];
unsigned res = (header >> 54) & 3;
return res;
}
inline __m256i shift_right(__m256i a) {
constexpr __m256i idx = {0x605040302010000, 0xe0d0c0b0a090807, 0x161514131211100f, 0x1e1d1c1b1a191817};
constexpr uint64_t mask = 18446744073709551614ULL;
__m256i res = _mm256_permutexvar_epi8(idx, a);
return res;
}
inline size_t get_spec_quot_cap(size_t quot, const __m256i *pd) {
assert(quot < QUOTS);
const u64 clean_h = get_clean_header(pd);
if (quot == 0) {
return _tzcnt_u64(clean_h);
}
const u64 p_mask = 3 << (quot - 1);
u64 pdep_res = _pdep_u64(p_mask, clean_h);
assert(__builtin_popcountll(pdep_res) == 2);
size_t begin = _tzcnt_u64(pdep_res) + 1;
size_t end = _tzcnt_u64(_blsr_u64(pdep_res));
size_t res = end - begin;
return res;
}
inline void body_add_case0_avx(size_t body_index, uint8_t rem, __m256i *pd) {
constexpr unsigned kBytes2copy = 7;
const __m256i shifted_pd = shift_right(*pd);
((uint8_t *) pd)[kBytes2copy + body_index] = rem;
const uint64_t mask = _bzhi_u64(-1, kBytes2copy + body_index + 1);
_mm256_store_si256(pd, _mm256_mask_blend_epi8(mask, shifted_pd, *pd));
}
inline void body_add_simple(size_t body_index, uint8_t rem, __m256i *pd) {
// const size_t body_index = end - quot;
auto mp = (u8 *) pd + 7 + body_index;
const size_t b2m = (32 - 7) - (body_index + 1);
memmove(mp + 1, mp, b2m);
mp[0] = rem;
}
inline bool body_add(size_t body_index, u8 rem, __m256i *pd) {
__m256i pd0 = *pd;
__m256i pd1 = *pd;
body_add_case0_avx(body_index, rem, &pd0);
body_add_simple(body_index, rem, &pd1);
bool res = memcmp(&pd0, &pd1, 32) == 0;
if (res)
return true;
std::cout << "h0:\t" << str_bitsMani::format_word_to_string(((u64 *) &pd0)[0]) << std::endl;
std::cout << "h1:\t" << str_bitsMani::format_word_to_string(((u64 *) &pd1)[0]) << std::endl;
// std::cout << "h1:\t" << str_bitsMani::format_word_to_string(((u64 *) &pd1)[0]) << std::endl;
// std::cout << "h1:\t" << str_bitsMani::format_word_to_string(((u64 *) &pd1)[0]) << std::endl;
assert(0);
return false;
}
inline void add_case0(int64_t quot, u8 rem, __m256i *pd) {
// static int A[4] = {0};
// A[0]++;
assert(!is_pd_full(pd));
const uint64_t dirty_h0 = reinterpret_cast<const u64 *>(pd)[0];
size_t end = select64(dirty_h0 >> 6, quot);
// constexpr u64 h_mask = ((1ULL << 56) - 1);
assert(check::val_header(pd));
const size_t h_index = end + 6;
const u64 mask = _bzhi_u64(-1, h_index);
const u64 lo = dirty_h0 & mask;
const u64 hi = ((dirty_h0 & ~mask) << 1u);// & h_mask;
assert(!(lo & hi));
const u64 h7 = lo | hi;
memcpy(pd, &h7, 7);
assert(check::val_header(pd));
const size_t body_index = end - quot;
auto mp = (u8 *) pd + 7 + body_index;
const size_t b2m = (32 - 7) - (body_index + 1);
memmove(mp + 1, mp, b2m);
mp[0] = rem;
assert(find_core(quot, rem, pd));
}
inline size_t get_last_occupied_quot_only_full_pd(const __m256i *pd) {
assert(is_pd_full(pd));
const u64 clean_h = get_clean_header(pd);
const size_t last_quot = select64(~clean_h, MAX_CAP0 - 1) - (MAX_CAP0 - 1);
assert(last_quot < QUOTS);
#ifndef NDEBUG
for (size_t i = last_quot + 1; i < QUOTS; i++) {
assert(!get_spec_quot_cap(i, pd));
}
#endif//!NDEBUG
return last_quot;
}
inline void sort_k_last_rem(size_t k, __m256i *pd) {
// taken from https://stackoverflow.com/questions/2786899/fastest-sort-of-fixed-length-6-int-array/2789530#2789530
int i, j;
u8 *d = (u8 *) pd + 32 - k;
for (i = 1; i < k; i++) {
u8 tmp = d[i];
for (j = i; j >= 1 && tmp < d[j - 1]; j--)
d[j] = d[j - 1];
d[j] = tmp;
}
}
/**
* @brief Sorts the remainders in the last run in non-decsending order, and returns the value of the last quot.
*
* @param pd
* @return size_t
*/
inline size_t sort_last_quot(__m256i *pd) {
assert(is_pd_full(pd));
const u64 clean_h = get_clean_header(pd);
const size_t last_quot = select64(~clean_h, MAX_CAP0 - 1) - (MAX_CAP0 - 1);
assert(get_last_occupied_quot_only_full_pd(pd) == last_quot);
size_t last_zero_index = last_quot + (MAX_CAP0 - 1);
u64 shifted_h = clean_h << (63 - last_zero_index);
assert(!_bextr_u64(shifted_h, 63, 1));
const size_t lq_cap = _lzcnt_u64(shifted_h);
assert(lq_cap == get_spec_quot_cap(last_quot, pd));
sort_k_last_rem(lq_cap, pd);
return last_quot;
}
inline size_t get_last_occ_quot_cap(const __m256i *pd) {
assert(is_pd_full(pd));
const u64 dirty_h = reinterpret_cast<const u64 *>(pd)[0] >> 6;
const size_t last_quot = select64(~dirty_h, MAX_CAP0 - 1) - (MAX_CAP0 - 1);
assert(get_last_occupied_quot_only_full_pd(pd) == last_quot);
size_t last_zero_index = last_quot + (MAX_CAP0 - 1);
u64 shifted_h = dirty_h << (63 - last_zero_index);
assert(!_bextr_u64(shifted_h, 63, 1));
size_t lq_cap = _lzcnt_u64(shifted_h);
assert(lq_cap == get_spec_quot_cap(last_quot, pd));
return lq_cap;
}
inline void update_status_old(int64_t last_quot, __m256i *pd) {
//check this
uint8_t byte_to_write = last_quot | (get_header(pd) & (32 + 64 + 128));
memcpy(pd, &byte_to_write, 1);
assert(decode_last_quot(pd) == last_quot);
}
inline void update_status(size_t last_occ_quot, __m256i *pd) {
assert(last_occ_quot < 32);
auto pd64 = reinterpret_cast<u64 *>(pd);
pd64[0] = ((pd64[0] | 31) ^ 31) | last_occ_quot;
}
inline void pd_add_50_only_rem(uint8_t rem, size_t quot_capacity, __m256i *pd) {
//FIXME use cmp_leq_as mask for shift avx.
constexpr unsigned kBytes2copy = 7;
// const __m256i target = _mm256_set1_epi8(rem);
const uint64_t begin_fingerprint = MAX_CAP0 - quot_capacity;
const uint64_t end_fingerprint = MAX_CAP0;
assert(begin_fingerprint < end_fingerprint);
assert(end_fingerprint <= MAX_CAP0);
uint64_t i = begin_fingerprint;
auto cp0 = (const u8 *) pd + 7;
for (; i < end_fingerprint; ++i) {
if (rem <= cp0[i]) break;
}
assert((i == end_fingerprint) ||
(rem <= ((const uint8_t *) pd)[kBytes2copy + i]));
u8 *mp = (u8 *) pd + 7 + i;
size_t b2m = (32 - 7) - (i + 1);
assert(b2m < 32);
memmove(mp + 1, mp, b2m);
mp[0] = rem;
}
inline void add_full_pd(bool did_pd_previously_overflowed, size_t last_occ_quot, int64_t quot, u8 rem, __m256i *pd) {
assert(is_pd_full(pd));
assert(last_occ_quot < QUOTS);
assert(get_spec_quot_cap(last_occ_quot, pd));
#ifndef NDEBUG
size_t v_lq_cap = get_spec_quot_cap(last_occ_quot, pd);
#endif//!NDEBUG
const uint64_t dirty_h0 = reinterpret_cast<const u64 *>(pd)[0];
const size_t set_last_zero_index = (MAX_CAP0 + last_occ_quot + 6);// -1?
const u64 set_last_zero = 1ULL << set_last_zero_index;
const bool change_last_quot = (!did_pd_previously_overflowed) | (dirty_h0 & (set_last_zero >> 2));
#ifndef NDEBUG
if (did_pd_previously_overflowed)
assert(change_last_quot == (get_spec_quot_cap(last_occ_quot, pd) == 1));
#endif//!NDEBUG
const size_t end = select64(dirty_h0 >> 6, quot);
constexpr u64 h_mask = ((1ULL << 56) - 1);
assert(check::val_header(pd));
const size_t h_index = end + 6;
const u64 mask = _bzhi_u64(-1, h_index);
const u64 lo = dirty_h0 & mask;
const u64 pre_hi = ((dirty_h0 & ~mask) << 1u); // | set_last_zero;// & h_mask;
const u64 hi = ((dirty_h0 & ~mask) << 1u) | set_last_zero;// & h_mask;
#ifndef NDEBUG
size_t cap = get_cap(pd);
// if (cap == MAX_CAP0) {
// std::cout << "h0: \t" << str_bitsMani::format_word_to_string(((u64 *) pd)[0], 56) << std::endl;
// std::cout << "pre_hi: \t" << str_bitsMani::format_word_to_string(pre_hi, 56) << std::endl;
// std::cout << "hi: \t" << str_bitsMani::format_word_to_string(hi, 56) << std::endl;
// std::cout << std::string(80, '-') << std::endl;
// }
auto a64 = &pre_hi;
size_t a_size = 1;
bool must_be0 = !bitsMani::is_single_bit_set(a64, set_last_zero_index, a_size);
size_t i = set_last_zero_index + 1;
for (; i < 56; ++i) {
if (!bitsMani::is_single_bit_set(a64, i, a_size)) {
std::cout << "i: \t" << i << std::endl;
break;
}
}
bool should_assert = (!must_be0) or (i < 56);
if (should_assert) {
std::string S[4];
S[0] = str_bitsMani::format_word_to_string(((u64 *) pd)[0]);
S[1] = str_bitsMani::format_word_to_string(pre_hi);
std::cout << "prev: \t" << S[0] << std::endl;
std::cout << "post: \t" << S[1] << std::endl;
assert(0);
}
#endif//!NDEBUG
assert(!(lo & hi));
const u64 h7 = lo | hi;
memcpy(pd, &h7, 7);
assert(check::val_header(pd));
const size_t body_index = end - quot;
body_add_case0_avx(body_index, rem, pd);
// auto mp = (u8 *) pd + 7 + body_index;
// const size_t b2m = (32 - 7) - (body_index + 1);
// memmove(mp + 1, mp, b2m);
// mp[0] = rem;
if (!change_last_quot)
return;
size_t new_last_occ_quot = sort_last_quot(pd);
update_status(new_last_occ_quot, pd);
}
inline add_res new_pd_swap_short(int64_t quot, uint8_t rem, __m256i *pd) {
uint64_t last_quot = decode_last_quot(pd);
const bool did_ovf = did_pd_overflowed(pd);
if (!did_ovf) {
last_quot = sort_last_quot(pd);
auto pd64 = reinterpret_cast<u64 *>(pd);
pd64[0] ^= (last_quot | 32);
}
if (last_quot < quot) {
assert(check::val_last_quot_is_sorted(pd));
return {(u8) quot, rem, false};
} else if (last_quot == quot) {
const uint8_t old_rem = get_last_byte(pd);
if (old_rem < rem) {//todo can be <= instead of <.
return {(u8) quot, rem, false};
}
size_t quot_capacity = get_spec_quot_cap(quot, pd);
assert(get_spec_quot_cap(quot, pd));
pd_add_50_only_rem(rem, quot_capacity, pd);
assert(find_core(quot, rem, pd));
return {(u8) last_quot, old_rem, false};
} else {
const u8 old_rem = get_last_byte(pd);
add_full_pd(did_ovf, last_quot, quot, rem, pd);
assert(find_core(quot, rem, pd));
return {(u8) last_quot, old_rem, false};
}
}
inline add_res add_full_wrap(int64_t quot, u8 rem, __m256i *pd) {
auto res = new_pd_swap_short(quot, rem, pd);
assert(check::val_last_quot_is_sorted(pd));
return res;
}
inline add_res Add_Wrap(int64_t quot, u8 rem, __m256i *pd) {
constexpr u64 full_mask = (1ULL << 55);
const uint64_t header = reinterpret_cast<const u64 *>(pd)[0];
if (!(header & full_mask)) {
assert(!is_pd_full(pd));
size_t end = select64(header >> 6, quot);
assert(check::val_header(pd));
const size_t h_index = end + 6;
const u64 mask = _bzhi_u64(-1, h_index);
const u64 lo = header & mask;
const u64 hi = ((header & ~mask) << 1u);// & h_mask;
assert(!(lo & hi));
const u64 h7 = lo | hi;
memcpy(pd, &h7, 7);
assert(check::val_header(pd));
const size_t body_index = end - quot;
assert(body_add(body_index, rem, pd));
auto mp = (u8 *) pd + 7 + body_index;
const size_t b2m = (32 - 7) - (body_index + 1);
memmove(mp + 1, mp, b2m);
mp[0] = rem;
assert(find_core(quot, rem, pd));
constexpr add_res passed = {0, 0, true};
return passed;
} else {
// std::cout << "I1=" << A[2]++;// << std::endl;
auto res = new_pd_swap_short(quot, rem, pd);
assert(check::val_last_quot_is_sorted(pd));
#ifndef NDEBUG
auto status = decode_last_quot(pd);
if (status == 0) {
std::cout << "Here!: \t" << std::endl;
}
#endif//!NDEBUG
return res;
}
}
inline bool find_core(int64_t quot, uint8_t rem, const __m256i *pd) {
assert(0 == (reinterpret_cast<uintptr_t>(pd) % 32));
assert(quot < QUOTS);
const __m256i target = _mm256_set1_epi8(rem);
const uint64_t v = _mm256_cmpeq_epu8_mask(target, *pd) >> 7ul;
if (!v) return false;
const uint64_t v_off = _blsr_u64(v);
const uint64_t h0 = get_clean_header(pd);
if (v_off == 0) {
const uint64_t mask = v << quot;
return (_mm_popcnt_u64(h0 & (mask - 1)) == quot) && (!(h0 & mask));
}
if (quot == 0)
return v & (_blsmsk_u64(h0) >> 1ul);
uint64_t new_v = (v << quot) & ~h0;
const uint64_t mask = (~_bzhi_u64(-1, quot - 1));
const uint64_t h_cleared_quot_set_bits = _pdep_u64(mask, h0);
const uint64_t h_cleared_quot_plus_one_set_bits = _blsr_u64(h_cleared_quot_set_bits);
const uint64_t v_mask = _blsmsk_u64(h_cleared_quot_set_bits) ^ _blsmsk_u64(h_cleared_quot_plus_one_set_bits);
// bool att = v_mask & new_v;
return v_mask & new_v;
}
/**
* @brief indicate if we should solely look for the element in the next level.
*
* @param qr
* @param pd
* @return true Look only in the second level.
* @return false Look only in this PD.
*/
inline bool cmp_qr1(uint16_t qr, const __m256i *pd) {
if (((uint64_t *) pd)[0] & 32) {
assert(!did_pd_overflowed(pd));
return false;
}
const uint64_t hfb = ((uint64_t *) pd)[0] & 31;
const uint16_t old_qr = (hfb << 8ul) | get_last_byte(pd);
return old_qr < qr;
}
}// namespace min_pd
#endif// FILTERS_PD256_PLUS_HPP

108
README.md Normal file
View File

@ -0,0 +1,108 @@
# The Prefix Filter
Implementation of **Prefix-Filter**, which is an incremental filter (approximate set-membership queries).
If you plan on using the Prefix-Filter, please cite our paper:
**Prefix Filter: Practically and Theoretically Better Than Bloom.** Tomer Even, Guy Even, Adam Morrison.
To appear in PVLDB, 15(7).
## Prerequisites
- **Compiler:** A C++17 compiler such as GNU G++ or LLVM Clang++.
- CMake (Version 3.10 or more).
- **System:** Linux.
- **Hardware:** Intel. Support of AVX2 is a must. AVX512 is need to run the code "as is". (Although the Prefix-Filter does not use it directly.).
###### Python Packages To Produce The Graphs
- matplotlib
- brokenaxes (From [here](https://github.com/bendichter/brokenaxes)).
- pandas
<!-- ###### Optional - Perf Event Wrapper.
- **Root Access:** Using the linux perf event wrapper (Link: [viktorleis/perfevent](https://github.com/viktorleis/perfevent)) requires root access.
# How To Use -->
There are three main targets for three different benchmarks.
1) `measure_perf` for benchmarking performance of insertions and lookups under various loads.
2) `measure_build` for build-time.
3) `measure_fpp` for evaluating the false positive probability, and the "effective space consumption".
There is also an example of how to use the Prefix-Filter in the file `example.cpp`:
```cpp
#include "Tests/wrappers.hpp"
int main(){
using spare = TC_shortcut; // Any incremental filter can replace TC_shortcut.
using prefixFilter = Prefix_Filter<spare>;
size_t filter_max_capacity = 1'000'000; // Choose any size.
prefixFilter example_filter = FilterAPI<prefixFilter>::ConstructFromAddCount(filter_max_capacity);
uint64_t x1 = 0x0123'4567'89ab'cdef;
FilterAPI<prefixFilter>::Add(x1, &example_filter); // Insertions of an item x1. Insertion can be performed only one step at a time.
bool res = FilterAPI<prefixFilter>::Contain(x1, &example_filter); // Lookup of x1.
assert(res); //No false negative.
uint64_t y1 = ~0x0123'4567'89ab'cdef;
bool res2 = FilterAPI<prefixFilter>::Contain(y1, &example_filter); // Lookup of y1.
std::cout << res2 << std::endl; // Possible false positive. (Although with one item in the filter, this is highly unlikely.)
return 0;
}
```
### To build
```
git clone -b master https://github.com/TheHolyJoker/Prefix-Filter.git
cd Prefix-Filter
mkdir build
cd build
cmake .. -DCMAKE_C_COMPILER=gcc-10 -DCMAKE_CXX_COMPILER=g++-10
t="measure_perf measure_built measure_fpp"; time cmake --build ./ --target $t -j 20
```
**On GCC release:** Older releases like 9.3 will work. We recommend using newer releases, which seems to perform better.
### To Run
To run all benchmarks (from `Prefix-Filter/build` directory):
```
cp ../RunAll.sh RunAll.sh
./RunAll.sh
```
<!-- If you are planning on using the perf event wrapper, the last line should run with root privilege: `sudo ./RunAll.sh` -->
###### Specific Target
Any specific target (for example `measure_perf`) can be built and executed with as follows:
```
t="measure_perf"; time cmake --build ./ --target $t -j 20 && time taskset -c 2 ./$t
```
<!-- If you are planning on using the perf event wrapper, then use `sudo` after the `&&`.
For running on different core than `2`, line 78 in `Tests/PerfEvent.hpp` should be changed. -->
# Credits
- **Xor Filter**:
["Xor Filters: Faster and Smaller Than Bloom and Cuckoo
Filters."](https://arxiv.org/pdf/1912.08258.pdf)
Graf, Thomas Mueller, and Daniel Lemire. \
[Repository](https://github.com/FastFilter/fastfilter_cpp).\
We build upon Xor filter's benchmarks.
We also used Its BBF variant, its fast Bloom filter, and its [fast modulo alternative](https://lemire.me/blog/2016/06/27/a-fast-alternative-to-the-modulo-reduction/).
<!-- ---
We Integrated a perf event wrapper taken from [viktorleis/perfevent](https://github.com/viktorleis/perfevent). This requires running the code as root.
--- -->
- **Cuckoo Filter** \
["Cuckoo Filter: Practically Better Than Bloom." ](https://www.cs.cmu.edu/~dga/papers/cuckoo-conext2014.pdf) Fan B, Andersen DG, Kaminsky M, Mitzenmacher MD.
[Repository](https://github.com/efficient/cuckoofilter)
- **Blocked Bloom Filter**\
We used two variants taken from the Xor filter's repository.
<!-- One taken from Impala repository, one from Xor filter's repository, and we also implemented another one, using AVX512 instructions, which is build upon the Xor filter's variant. -->
<!-- --- -->
- **Vector Quotient Filter**\
["Vector Quotient Filters: Overcoming The Time/Space Trade-Off In Filter Design."](https://research.vmware.com/files/attachments/0/0/0/0/1/4/7/sigmod21.pdf). Pandey P, Conway A, Durie J, Bender MA, Farach-Colton M, Johnson R. Vector quotient filters: Overcoming the time/space trade-off in filter design.\
[Repository](https://github.com/splatlab/vqf).\
However, we used our own implementation, called *twoChoicer* (In file `TC-Shortcut/TC-shortcut.hpp`).

33
RunAll.sh Executable file
View File

@ -0,0 +1,33 @@
mkdir -p ../scripts/Inputs
t="measure_perf";
s="measure_built";
time cmake --build ./ --target $t -j 50
if ! [ $? -eq 0 ]; then
exit 1;
fi
time cmake --build ./ --target $s -j 50
if ! [ $? -eq 0 ]; then
exit 2;
fi
if ! [ -z "$(ls -A ../scripts/Inputs)" ]; then
echo "Inputs is not empty!"
exit 3;
fi
time taskset -c 2 ./$t
if ! [ $? -eq 0 ]; then
echo "The benchmark was not completed!"
exit;
fi
#sleep 120
time taskset -c 2 ./$s
if ! [ $? -eq 0 ]; then
echo "The Built-bench was not completed!"
exit;
fi
files_path="../scripts/Inputs/"
../scripts/arg-plotter.py $files_path
../scripts/build-csv-parser.py
time cmake --build ./ --target measure_fpp -j 50 && time taskset -c 2 ./measure_fpp

309
TC-Shortcut/TC-shortcut.hpp Normal file
View File

@ -0,0 +1,309 @@
#ifndef TC_SHORTCUT_HPP
#define TC_SHORTCUT_HPP
#include "../hashutil.h"
#include "./tc-sym.hpp"
class TC_shortcut {
hashing::TwoIndependentMultiplyShift h0;
size_t capacity{0};
const size_t filter_max_capacity;
// const size_t remainder_length = 8;
const size_t quotient_range = tc_sym::QUOTS;
// const uint16_t qr_range = 12800UL;
// const size_t quotient_length = 6;
const size_t single_pd_capacity = tc_sym::MAX_CAP;
const size_t number_of_pd;
const double load;
__m512i *pd_array;
size_t insert_existing_counter = 0;
size_t add_op_counter = 0;
public:
static inline auto TC_compute_number_of_PD(size_t max_number_of_elements, size_t single_pd_max_cap, double l1_load) -> size_t {
double b = single_pd_max_cap * l1_load;
size_t res = (std::size_t) ceil(max_number_of_elements / ((double) b));
return (res & 1) ? res + 1 : res;
}
TC_shortcut(size_t max_number_of_elements, double level1_load_factor)
: filter_max_capacity(max_number_of_elements),
number_of_pd(TC_compute_number_of_PD(max_number_of_elements, single_pd_capacity, level1_load_factor)),
load(level1_load_factor), h0()
// pd_index_length(ceil_log2(compute_number_of_PD(max_number_of_elements, max_capacity, level1_load_factor, 1)))
{
// hashing_test = false;
assert(quotient_range + single_pd_capacity * 9 <= 512);
assert(!(number_of_pd & 1));
assert(single_pd_capacity == tc_sym::MAX_CAP);
int ok = posix_memalign((void **) &pd_array, 64, 64 * number_of_pd);
if (ok != 0) {
std::cout << "Failed!!!" << std::endl;
assert(false);
return;
}
// std::fill(pd_array, pd_array + number_of_pd, __m512i{(INT64_C(1) << 50) - 1, 0, 0, 0, 0, 0, 0, 0});
static_assert(UINT64_C(-1) == 0xffff'ffff'ffff'ffff);
// __m512i init_pd = {0xffff'ffff'ffff'ffff, 0x00000000'0000ffff, 0, 0, 0, 0, 0, 0};
;
std::fill(pd_array, pd_array + number_of_pd, __m512i{-1, 0x00000000'0000ffff, 0, 0, 0, 0, 0, 0});
}
virtual ~TC_shortcut() {
free(pd_array);
// pd_capacity_vec.clear();
}
__attribute__((always_inline)) inline static uint32_t reduce32(uint32_t hash, uint32_t n) {
// http://lemire.me/blog/2016/06/27/a-fast-alternative-to-the-modulo-reduction/
return (uint32_t) (((uint64_t) hash * n) >> 32);
}
static inline uint32_t reduce(uint64_t hash, uint32_t n) {
// http://lemire.me/blog/2016/06/27/a-fast-alternative-to-the-modulo-reduction/
return (uint32_t) (((hash & 0xffffffffL) * n) >> 32);
}
__attribute__((always_inline)) inline static uint16_t fixed_reduce(u32 hash) {
// http://lemire.me/blog/2016/06/27/a-fast-alternative-to-the-modulo-reduction/
constexpr u32 mod = tc_sym::QUOTS << 8;
// static_assert(mod == 12800UL);
return (uint16_t) (((uint32_t) hash * mod) >> 16);
}
bool v_alt_cfs(uint32_t bin_index, uint32_t rem) const {
uint32_t alt_bin_index = get_alt_index_cf_stable(bin_index, rem);
uint32_t alt_alt_bin_index = get_alt_index_cf_stable(alt_bin_index, rem);
bool res = (bin_index == alt_alt_bin_index);
if (!res) {
// auto offset = Morton_offset(rem);
int diff1 = bin_index - alt_bin_index;
int diff2 = alt_alt_bin_index - alt_bin_index;
std::cout << std::string(80, '=') << std::endl;
std::cout << "number_of_pd: \t" << number_of_pd << std::endl;
std::cout << std::string(80, '~') << std::endl;
// std::cout << "offset: \t" << offset << std::endl;
std::cout << "bin_index: \t" << bin_index << std::endl;
std::cout << "alt_bin_index: \t" << alt_bin_index << std::endl;
std::cout << "alt_alt_bin_index: \t" << alt_alt_bin_index << std::endl;
std::cout << std::string(80, '~') << std::endl;
std::cout << "diff1: \t" << diff1 << "\t|\t" << (number_of_pd - diff1) << std::endl;
std::cout << "diff2: \t" << diff2 << "\t|\t" << (number_of_pd - diff2) << std::endl;
std::cout << std::string(80, '=') << std::endl;
// auto offset1 = Morton_offset(rem);
}
assert(res);
return res;
}
inline uint32_t get_alt_index_simp(uint32_t bin_index, uint32_t qr) const {
return (bin_index + qr) % number_of_pd;
}
// inline uint32_t get_alt_index_cf_stable(uint32_t bin_index, uint32_t rem) const {
inline uint32_t get_alt_index_cf_stable(uint32_t bin_index, uint32_t qr) const {
//Taken from https://github.com/FastFilter/fastfilter_cpp/blob/master/src/cuckoo/cuckoofilter_stable.h
// (The variables names where changed).
uint64_t hash = qr * 0xc4ceb9fe1a85ec53L;
// we don't use xor; instead, we ensure bucketCount is even,
// and bucket2 = bucketCount - bucket - y,
// and if negative add the bucketCount,
// where y is 1..bucketCount - 1 and odd -
// that way, bucket2 is never the original bucket,
// and running this twice will give the original bucket, as needed
uint32_t r = (reduce(hash, number_of_pd >> 1) << 1) + 1;
// this is needed because the bucket size is not always 2^n:
int32_t b2 = number_of_pd - bin_index - r;
if (b2 < 0) {
b2 += number_of_pd;
}
// I tried the following alternatives (also combinations),
// but performance is the same:
// uint32_t b2 = bucketCount - index - r;
// b2 += bucketCount * (b2 >> 31);
// int32_t b2 = bucketCount - index - r;
// b2 += bucketCount & (b2 >> 31);
// int32_t b2 = r - index;
// b2 += bucketCount & (b2 >> 31);
return b2;
}
inline auto lookup(const uint64_t &item) const -> bool {
const u64 s = h0(item);
uint32_t out1 = s >> 32u, out2 = s;
const uint32_t pd_index1 = reduce32(out1, (uint32_t) number_of_pd);
const uint16_t qr = fixed_reduce((uint16_t) out2);
const int64_t quot = qr >> 8;
const uint8_t rem = qr;
assert(pd_index1 < number_of_pd);
assert(quot <= tc_sym::QUOTS);
// assert(validate_get_alt_index_non_2power(pd_index1, rem));
assert(v_alt_cfs(pd_index1, qr));
assert(v_alt_cfs(pd_index1, rem));
return (tc_sym::find(quot, rem, pd_array + pd_index1)) || (tc_sym::find(quot, rem, pd_array + get_alt_index_cf_stable(pd_index1, qr)));
// return (tc_sym::find(quot, rem, pd_array + pd_index1)) || (tc_sym::find(quot, rem, pd_array + get_alt_index_simp(pd_index1, qr)));
// (tc_sym::find(quot, rem, pd_array + get_alt_index_non_2power(pd_index1, rem)));
}
bool insert_no_shortcut(const uint64_t &item) {
// add_op_counter++;
const u64 s = h0(item);
uint32_t out1 = s >> 32u, out2 = s;
const uint32_t pd_index1 = reduce32(out1, (uint32_t) number_of_pd);
const uint16_t qr = fixed_reduce((uint16_t) out2);
const int64_t quot = qr >> 8;
const uint8_t rem = qr;
assert(pd_index1 < number_of_pd);
assert(quot <= quotient_range);
assert(rem <= 255);
// assert(validate_get_alt_index_non_2power(pd_index1, rem));
assert(v_alt_cfs(pd_index1, rem));
assert(v_alt_cfs(pd_index1, qr));
// const uint32_t pd_index2 = get_alt_index_non_2power(pd_index1, rem);
const uint32_t pd_index2 = get_alt_index_cf_stable(pd_index1, qr);
assert(pd_index2 < number_of_pd);
auto cap1 = tc_sym::get_cap(pd_array + pd_index1);
auto cap2 = tc_sym::get_cap(pd_array + pd_index2);
if (cap1 < cap2) {
auto res = tc_sym::add(quot, rem, &pd_array[pd_index1]);
assert((!res) or lookup(item));
return res;
} else {
if (cap2 == tc_sym::MAX_CAP) {
return false;
}
auto res = tc_sym::add(quot, rem, &pd_array[pd_index2]);
assert((!res) or lookup(item));
return res;
}
}
bool insert(const uint64_t &item) {
const u64 s = h0(item);
uint32_t out1 = s >> 32u, out2 = s;
const uint32_t pd_index1 = reduce32(out1, (uint32_t) number_of_pd);
const uint16_t qr = fixed_reduce((uint16_t) out2);
const int64_t quot = qr >> 8;
const uint8_t rem = qr;
assert(pd_index1 < number_of_pd);
assert(quot <= quotient_range);
assert(rem <= 255);
// assert(validate_get_alt_index_non_2power(pd_index1, rem));
assert(v_alt_cfs(pd_index1, rem));
assert(v_alt_cfs(pd_index1, qr));
if (tc_sym::pd_less_than_thres(pd_array + pd_index1)) {
#ifndef NDEBUG
auto res = tc_sym::add(quot, rem, &pd_array[pd_index1]);
assert((!res) or lookup(item));
return res;
#endif//!NDEBUG
return tc_sym::add(quot, rem, &pd_array[pd_index1]);
}
const uint32_t pd_index2 = get_alt_index_cf_stable(pd_index1, qr);
// const uint32_t pd_index2 = get_alt_index_simp(pd_index1, qr);
assert(pd_index2 < number_of_pd);
const uint64_t *word1 = ((const uint64_t *) (pd_array + pd_index1)) + 1;
const uint64_t *word2 = ((const uint64_t *) (pd_array + pd_index2)) + 1;
if (word1[0] < word2[0]) {
assert(tc_sym::get_cap(pd_array + pd_index1) <= tc_sym::get_cap(pd_array + pd_index2));
if (word1[0] >> 63) {
assert(tc_sym::pd_full(pd_array + pd_index1));
return false;
}
auto res = tc_sym::add(quot, rem, &pd_array[pd_index1]);
assert((!res) or lookup(item));
return res;
} else {
assert(tc_sym::get_cap(pd_array + pd_index1) >= tc_sym::get_cap(pd_array + pd_index2));
if (word2[0] >> 63) {
assert(tc_sym::pd_full(pd_array + pd_index2));
return false;
}
auto res = tc_sym::add(quot, rem, &pd_array[pd_index2]);
assert((!res) or lookup(item));
return res;
}
}
void remove(const uint64_t &item) {
// add_op_counter++;
const u64 s = h0(item);
assert(lookup(item));
uint32_t out1 = s >> 32u, out2 = s;
const uint32_t pd_index1 = reduce32(out1, (uint32_t) number_of_pd);
const uint16_t qr = fixed_reduce((uint16_t) out2);
const int64_t quot = qr >> 8;
const uint8_t rem = qr;
// assert(validate_get_alt_index_non_2power(pd_index1, rem));
assert(v_alt_cfs(pd_index1, rem));
assert(v_alt_cfs(pd_index1, qr));
tc_sym::conditional_remove(quot, rem, &pd_array[pd_index1]) || tc_sym::remove(quot, rem, &pd_array[get_alt_index_cf_stable(pd_index1, qr)]);
}
auto get_capacity() const -> size_t {
size_t res = 0;
for (size_t i = 0; i < number_of_pd; ++i) {
res += tc_sym::get_cap(&pd_array[i]);
}
return res;
}
size_t get_byte_size() const {
return number_of_pd * sizeof(pd_array[0]);
}
auto get_name() const -> std::string {
return "TC-shortcut";
}
auto get_cap() const -> size_t {
return get_capacity();
}
auto get_effective_load() const -> double {
const size_t slots = number_of_pd * tc_sym::MAX_CAP;
const size_t filter_cap = get_cap();
double ratio = 1.0 * filter_cap / slots;
return ratio;
}
std::string info() const {
std::stringstream ss;
size_t cap = get_cap();
ss << std::string(80, '=') << std::endl;
double ratio = (1.0 * cap) / filter_max_capacity;
ss << "filter_max_capacity: \t" << filter_max_capacity << std::endl;
ss << "cap: \t" << cap << std::endl;
ss << "ratio: \t" << ratio << std::endl;
ss << "number_of_pd: \t" << number_of_pd << std::endl;
ss << "given-load: \t" << load << std::endl;
// ss << "actual-load: \t" << load << std::endl;
ss << std::string(80, '=') << std::endl;
return ss.str();
}
};
#endif// TWOCHOICER_HEADER

135
TC-Shortcut/tc-sym.cpp Normal file
View File

@ -0,0 +1,135 @@
#include "tc-sym.hpp"
namespace tc_sym::check {
auto validate_number_of_quotient(const __m512i *pd) -> bool {
auto pd64 = (const u64 *) pd;
u64 h0 = pd64[0];
u64 h1 = pd64[1];
u64 h1_masked = pd64[1] & _bzhi_u64(-1, QUOTS + MAX_CAP - 64);
auto pop0 = _mm_popcnt_u64(h0);
auto pop1 = _mm_popcnt_u64(h1_masked);
auto pop1_extended = _mm_popcnt_u64(h1);
auto pop1_e2 = _mm_popcnt_u64(h1 & _bzhi_u64(-1, 40));
if (pop0 + pop1 == QUOTS)
return true;
std::cout << "h0: \t" << format_word_to_string(h0) << std::endl;
std::cout << "h1: \t" << format_word_to_string(h1) << std::endl;
std::cout << "h1_m: \t" << format_word_to_string(h1_masked) << std::endl;
assert(0);
return false;
}
auto validate_number_of_quotient(const __m512i *pd, const __m512i *backup_pd) -> bool {
auto pd64 = (const u64 *) pd;
u64 h0 = pd64[0];
u64 h1 = pd64[1];
u64 h1_masked = pd64[1] & _bzhi_u64(-1, QUOTS + MAX_CAP - 64);
auto pop0 = _mm_popcnt_u64(h0);
auto pop1 = _mm_popcnt_u64(h1_masked);
auto pop1_extended = _mm_popcnt_u64(h1);
auto pop1_e2 = _mm_popcnt_u64(h1 & _bzhi_u64(-1, 40));
if (pop0 + pop1 == QUOTS)
return true;
auto bpd64 = (const u64 *) backup_pd;
std::cout << std::string(80, '=') << std::endl;
std::cout << "h0: \t" << format_word_to_string(h0) << std::endl;
std::cout << "h0: \t" << format_word_to_string(bpd64[0]) << std::endl;
std::cout << std::endl;
std::cout << "h1: \t" << format_word_to_string(h1) << std::endl;
std::cout << "h1: \t" << format_word_to_string(bpd64[1]) << std::endl;
std::cout << std::endl;
std::cout << "h1_m: \t" << format_word_to_string(h1_masked) << std::endl;
std::cout << "h1_m: \t" << format_word_to_string(bpd64[1] & _bzhi_u64(-1, 40)) << std::endl;
std::cout << std::string(80, '=') << std::endl;
// std::cout << std::string(80, '~') << std::endl;
// std::cout << "h1: \t" << format_word_to_string(bpd64[1]) << std::endl;
assert(0);
return false;
}
}// namespace tc_sym::check
// for printing
namespace tc_sym::check {
void p_format_word(uint64_t x) {
std::string res = to_bin(x, 64);
std::cout << space_string(res) << std::endl;
}
auto format_word_to_string(uint64_t x, size_t length) -> std::string {
std::string res = to_bin(x, length);// + "\n";
return space_string(res);
// std::cout << space_string(res) << std::endl;
}
/**
* @brief This prints the binary representation of x. Usually, a reversed representation is needed.
*
* @param x
* @param length
* @return std::string
*/
auto to_bin(uint64_t x, size_t length) -> std::string {
assert(length <= 64);
uint64_t b = 1ULL;
std::string res;
for (size_t i = 0; i < length; i++) {
res += (b & x) ? "1" : "0";
b <<= 1ul;
}
return res;
}
auto space_string(std::string s) -> std::string {
std::string new_s = "";
for (size_t i = 0; i < s.size(); i += 4) {
if (i) {
if (i % 16 == 0) {
new_s += "|";
} else if (i % 4 == 0) {
new_s += ".";
}
}
new_s += s.substr(i, 4);
}
return new_s;
}
void print_pd_first_two_words(const __m512i *pd, size_t tabs = 1) {
uint64_t h0 = 0, h1 = 0;
memcpy(&h0, pd, 8);
memcpy(&h1, reinterpret_cast<const uint64_t *>(pd) + 1, 8);
auto s0 = format_word_to_string(h0, 64);
auto s1 = format_word_to_string(h1, 64);
auto tabs_to_add = std::string(tabs, '\t');
// size_t pops[2] = {_mm_popcnt_u64(h0), _mm_popcnt_u64(h1)};
std::cout << "h0: \t" + tabs_to_add << s0;
std::cout << "\t|\t (" << _mm_popcnt_u64(h0) << ", " << (64 - _mm_popcnt_u64(h0)) << ")" << std::endl;
std::cout << "h1: \t" + tabs_to_add << s1;
std::cout << "\t|\t (" << _mm_popcnt_u64(h1) << ", " << (64 - _mm_popcnt_u64(h1)) << ")" << std::endl;
}
void print_pd(const __m512i *pd) {
std::cout << std::string(80, '~') << std::endl;
// assert(pd512::get_capacity(pd) == pd512::get_capacity_naive(pd));
std::cout << "pd capacity:" << get_cap(pd) << std::endl;
// v_pd512_plus::print_headers_extended(pd);
print_pd_first_two_words(pd);
auto mp = ((const u8 *) pd) + 16;
auto body_str = str_bitsMani::str_array_with_line_numbers(mp, MAX_CAP);
std::cout << body_str << std::endl;
std::cout << std::string(80, '~') << std::endl;
}
}// namespace tc_sym::check

733
TC-Shortcut/tc-sym.hpp Normal file
View File

@ -0,0 +1,733 @@
/*
* My implementation of twoChoicer. A filter with "Power-of-2-choices" insertion policy.
* Also known as Vector-Quotient-Filter.
* In this version, deletion should work, but was not extensively tested.
*/
#ifndef TC_SYM_HPP
#define TC_SYM_HPP
#include "../Prefix-Filter/Shift_op.hpp"
#include <algorithm>
#include <assert.h>
#include <immintrin.h>
#include <iomanip>
#include <iostream>
#include <limits.h>
#include <stdint.h>
#include <string.h>
typedef uint64_t u64;
typedef uint32_t u32;
typedef uint16_t u16;
typedef uint8_t u8;
typedef uint_fast64_t uf64;
typedef uint_fast32_t uf32;
typedef uint_fast16_t uf16;
typedef uint_fast8_t uf8;
namespace tc_sym::check {
template<typename T>
void zero_array(T *a, size_t a_size) {
for (size_t i = 0; i < a_size; i++) {
a[i] = 0;
}
}
auto space_string(std::string s) -> std::string;
auto to_bin(uint64_t x, size_t length) -> std::string;
void p_format_word(uint64_t x);
auto format_word_to_string(uint64_t x, size_t length = 64) -> std::string;
void print_pd(const __m512i *pd);
auto validate_number_of_quotient(const __m512i *pd) -> bool;
auto validate_number_of_quotient(const __m512i *pd, const __m512i *backup_pd) -> bool;
}// namespace tc_sym::check
namespace tc_sym {
constexpr size_t QUOTS = 80;
constexpr size_t MAX_CAP = 48;
constexpr unsigned kBytes2copy = (QUOTS + MAX_CAP + CHAR_BIT - 1) / CHAR_BIT;
inline uint_fast8_t popcount128(unsigned __int128 x) {
const uint64_t hi = x >> 64;
const uint64_t lo = x;
return _mm_popcnt_u64(lo) + _mm_popcnt_u64(hi);
}
inline uint_fast8_t popcount128_on_pd(const __m512i *pd) {
const auto temp = _mm512_castsi512_si128(*pd);
return _mm_popcnt_u64(_mm_extract_epi64(temp, 0)) + _mm_popcnt_u64(_mm_extract_epi64(temp, 1));
}
__attribute__((always_inline)) inline uint64_t select64(uint64_t x, int64_t j) {
assert(j < 64);
const uint64_t y = _pdep_u64(UINT64_C(1) << j, x);
return _tzcnt_u64(y);
}
inline uint64_t select128(unsigned __int128 x, int64_t j) {
const int64_t pop = _mm_popcnt_u64(x);
if (j < pop)
return select64(x, j);
return 64 + select64(x >> 64, j - pop);
}
__attribute__((always_inline)) inline size_t select_on_first_part(int64_t quot, const __m512i *pd) {
return select128(((unsigned __int128 const *) pd)[0], quot);
}
__attribute__((always_inline)) inline size_t select_on_pd_cap(const __m512i *pd) {
constexpr size_t t = QUOTS - 1;
u64 Header[2];
memcpy(Header, pd, 16);
// = (const u64*) pd;
const int64_t pop = _mm_popcnt_u64(Header[0]);
if (t < pop)
return select64(Header[0], t);
return 64 + select64(Header[1], t - pop);
// return select128(((unsigned __int128 const *) pd)[0], quot);
}
__attribute__((always_inline)) inline void select_both_on_word_arr(u64 x, size_t j, uf8 res[2]) {
assert(j < 64);
const uint64_t y = _pdep_u64(UINT64_C(3) << j, x);
assert(_mm_popcnt_u64(y) == 2);
res[0] = _tzcnt_u64(y);
res[1] = _tzcnt_u64(_blsr_u64(y));
}
inline void select_both_case0_arr(size_t k, u8 res[2], const __m512i *pd) {
const u64 h0 = ((const u64 *) pd)[0];
const u64 h1 = ((const u64 *) pd)[1];
if (k == 0) {
res[0] = 0;
res[1] = _tzcnt_u64(h0);
return;
}
auto pop0 = _mm_popcnt_u64(h0);
if (k < pop0) {
select_both_on_word_arr(h0, k - 1, res);
return;
}
if (k > pop0) {
auto new_k = k - pop0;
select_both_on_word_arr(h1, new_k - 1, res);
res[0] += 64;
res[1] += 64;
return;
} else {
res[0] = 63 - _lzcnt_u64(h0);
res[1] = 64 + _tzcnt_u64(h1);
}
}
/**
* @brief Get the select mask object
*
* keeps the (j)'th 1 and the (j + 1)'th 1 in x turn on, and turn off the other bits.
* @param x
* @param j >= 0
* @return uint64_t
*/
inline uint64_t get_select_mask(uint64_t x, int64_t j) {
assert(_mm_popcnt_u64(x) > j);
return _pdep_u64(3ul << (j), x);
}
/**
* @brief
*
* @param x a number with only two set bits. (62 zeros, and 2 ones).
* @return uint64_t turn on the bits between the currently set bits.
* Also turn off the previously turned on bits.
*/
inline uint64_t mask_between_bits(uint64_t x) {
assert(_mm_popcnt_u64(x) == 2);
uint64_t hi_bit = (x - 1) & x;
uint64_t clear_hi = hi_bit - 1;
uint64_t lo_set = (x - 1);
uint64_t res = (clear_hi ^ lo_set) & (~x);
return res;
}
inline bool pd_full(const __m512i *pd) {
uint8_t header_end;
memcpy(&header_end, reinterpret_cast<const uint8_t *>(pd) + 15, 1);
return header_end & 128;
}
inline uf8 get_cap_naive(const __m512i *pd) {
auto res = select_on_pd_cap(pd) - (QUOTS - 1);
#ifndef NDEBUG
auto res0 = select_on_first_part(QUOTS - 1, pd) - (QUOTS - 1);
assert(res == res0);
#endif//!NDEBUG
return res;
}
__attribute__((always_inline)) inline size_t get_cap(const __m512i *pd) {
u64 h_last;
// memcpy(&h_last, (const u8 *) pd + (kBytes2copy - 8), 8);
memcpy(&h_last, (const u8 *) pd + 8, 8);
auto temp = _lzcnt_u64(h_last);
auto res = MAX_CAP - temp;
#ifndef NDEBUG
auto val = get_cap_naive(pd);
if (res == val)
return res;
std::cout << "res: " << res << std::endl;
std::cout << "val: " << val << std::endl;
assert(0);
#endif//!NDEBUG
assert(res == get_cap_naive(pd));
assert((res == MAX_CAP) == pd_full(pd));
return res;
}
inline bool pd_less_than_thres(const __m512i *pd) {
constexpr size_t thres_cap = 36;
//We need to to test if the last 12+1 bits contains only zeros.
constexpr u64 thres = (1ULL << (128 - 13 - 64)) - 1;
const uint64_t h1 = _mm_extract_epi64(_mm512_castsi512_si128(*pd), 1);
const bool res = h1 < thres;
#ifndef NDEBUG
auto cap = get_cap(pd);
bool val = cap < thres_cap;
if (val != res) {
get_cap(pd);
std::cout << "cap: " << cap << std::endl;
std::cout << "val: " << val << std::endl;
std::cout << "res: " << res << std::endl;
}
#endif//!NDEBUG
return res;
}
inline size_t get_spec_quot_cap_inside_word(size_t quot, u64 word) {
const u64 p_mask = 3 << (quot - 1);
u64 pdep_res = _pdep_u64(p_mask, word);
assert(__builtin_popcountll(pdep_res) == 2);
size_t begin = _tzcnt_u64(pdep_res) + 1;
size_t end = _tzcnt_u64(_blsr_u64(pdep_res));
size_t res = end - begin;
return res;
}
inline size_t get_spec_quot_cap(size_t quot, const __m512i *pd) {
assert(0);
assert(quot < QUOTS);
const u64 *pd64 = (const u64 *) pd;
// const u64 clean_h = get_clean_header(pd);
if (quot == 0) {
std::cout << "h0" << std::endl;
return _tzcnt_u64(pd64[0]);
}
const size_t pop0 = _mm_popcnt_u64(pd64[0]);
if (quot < pop0) {
std::cout << "h1" << std::endl;
return get_spec_quot_cap_inside_word(quot - 1, pd64[0]);
} else if (pop0 < quot) {
std::cout << "h2" << std::endl;
size_t new_q = quot - pop0;
return get_spec_quot_cap_inside_word(new_q - 1, pd64[1]);
}
std::cout << "h3" << std::endl;
const size_t part1 = _lzcnt_u64(pd64[0]);
const size_t part2 = _tzcnt_u64(pd64[1]);
return part1 + part2;
}
inline size_t get_spec_quot_cap2(size_t quot, const __m512i *pd) {
assert(quot < QUOTS);
const u64 *pd64 = (const u64 *) pd;
if (quot == 0) {
// std::cout << "h0" << std::endl;
return _tzcnt_u64(pd64[0]);
}
size_t begin = select_on_first_part(quot - 1, pd) + 1;
size_t end = select_on_first_part(quot, pd);
return end - begin;
}
/**
* @brief Shift 'a' 8 bits right.
* @param a
* @return __m512i
*/
inline __m512i shift_right(__m512i a) {
// The indices encoded here actually encode shift left.
// idx is an "uint8_t arr[64]" where "arr[i] = i-1" (arr[0] = 0).
constexpr __m512i idx = {433757350076153919, 1012478732780767239, 1591200115485380623, 2169921498189994007,
2748642880894607391, 3327364263599220775, 3906085646303834159, 4484807029008447543};
constexpr uint64_t mask = 18446744073709551614ULL;
__m512i res = _mm512_maskz_permutexvar_epi8(mask, idx, a);
return res;
}
inline __m512i shift_left(__m512i a) {
constexpr __m512i idx = {578437695752307201, 1157159078456920585, 1735880461161533969, 2314601843866147353, 2893323226570760737, 3472044609275374121, 4050765991979987505, 17801356257212985};
constexpr uint64_t mask = 9223372036854775807ULL;
__m512i res = _mm512_maskz_permutexvar_epi8(mask, idx, a);
return res;
}
inline bool pd_find_naive(int64_t quot, uint8_t rem, const __m512i *pd) {
assert(0 == (reinterpret_cast<uintptr_t>(pd) % 64));
assert(quot < QUOTS);
const __m512i target = _mm512_set1_epi8(rem);
uint64_t v = _mm512_cmpeq_epu8_mask(target, *pd) >> 16ul;
if (!v) return false;
// const unsigned __int128 *h = (const unsigned __int128 *) pd;
// constexpr unsigned __int128 kLeftoverMask = (((unsigned __int128) 1) << (50 + 51)) - 1;
const unsigned __int128 header = ((const unsigned __int128 *) pd)[0];
assert(popcount128(header) == QUOTS);
const uint64_t begin = quot ? select128(header, quot - 1) + 1 - quot : 0;
const uint64_t end = select128(header, quot) - quot;
assert(begin <= end);
assert(end <= MAX_CAP);
return (v & ((UINT64_C(1) << end) - 1)) >> begin;
}
inline bool pd_find_50_v18(int64_t quot, uint8_t rem, const __m512i *pd) {
assert(0 == (reinterpret_cast<uintptr_t>(pd) % 64));
assert(quot < QUOTS);
const __m512i target = _mm512_set1_epi8(rem);
uint64_t v = _mm512_cmpeq_epu8_mask(target, *pd) >> 16ul;
if (!v) return false;
const uint64_t h0 = _mm_extract_epi64(_mm512_castsi512_si128(*pd), 0);
const uint64_t h1 = _mm_extract_epi64(_mm512_castsi512_si128(*pd), 1);
if (_blsr_u64(v) == 0) {
// if ((v << quot)) {
if ((quot < 64) && (v << quot)) {
// const unsigned __int128 *h = (const unsigned __int128 *) pd;
// const unsigned __int128 header = (*h);
const int64_t mask = v << quot;
const bool att = (!(h0 & mask)) && (_mm_popcnt_u64(h0 & (mask - 1)) == quot);
/* if (att != pd_find_naive(quot, rem, pd)) {
bool val = pd_find_naive(quot, rem, pd);
std::cout << std::string(80, '=') << std::endl;
std::cout << "val: \t" << val << std::endl;
std::cout << "att: \t" << att << std::endl;
std::cout << "quot: \t" << quot << std::endl;
std::cout << "rem: \t" << (u16) rem << std::endl;
std::cout << "cap: \t" << get_cap(pd) << std::endl;
std::cout << std::string(80, '~') << std::endl;
bool a = (!(h0 & mask));
bool b = (_mm_popcnt_u64(h0 & (mask - 1)) == quot);
std::cout << "a: " << a << std::endl;
std::cout << "b: " << b << std::endl;
std::cout << std::string(80, '=') << std::endl;
assert(att == pd_find_naive(quot, rem, pd));
}
*/
assert(att == pd_find_naive(quot, rem, pd));
return (!(h0 & mask)) && (_mm_popcnt_u64(h0 & (mask - 1)) == quot);
} else {
// auto *h = (const unsigned __int128 *) pd;
// constexpr unsigned __int128 kLeftoverMask = (((unsigned __int128) 1) << (50 + 51)) - 1;
// const unsigned __int128 header = (*h) & kLeftoverMask;
const unsigned __int128 header = ((const unsigned __int128 *) pd)[0];
const unsigned __int128 mask = ((unsigned __int128) v) << quot;
const bool att = (!(header & mask)) && (popcount128(header & (mask - 1)) == quot);
assert(att == pd_find_naive(quot, rem, pd));
return (!(header & mask)) && (popcount128(header & (mask - 1)) == quot);
}
}
const int64_t pop = _mm_popcnt_u64(h0);
if (quot == 0) {
// std::cout << "h0" << std::endl;
return v & (_blsmsk_u64(h0) >> 1ul);
} else if (quot < pop) {
// std::cout << "h1" << std::endl;
const uint64_t mask = (~_bzhi_u64(-1, quot - 1));
const uint64_t h_cleared_quot_set_bits = _pdep_u64(mask, h0);
return (((_blsmsk_u64(h_cleared_quot_set_bits) ^ _blsmsk_u64(_blsr_u64(h_cleared_quot_set_bits))) & (~h0)) >> quot) & v;
} else if (quot > pop) {
// std::cout << "h2" << std::endl;
const uint64_t mask = (~_bzhi_u64(-1, quot - pop - 1));
const uint64_t h_cleared_quot_set_bits = _pdep_u64(mask, h1);
return (((_blsmsk_u64(h_cleared_quot_set_bits) ^ _blsmsk_u64(_blsr_u64(h_cleared_quot_set_bits))) & (~h1)) >> (quot - pop)) & (v >> (64 - pop));
} else {
// std::cout << "h3" << std::endl;
const uint64_t helper = _lzcnt_u64(h0);
const uint64_t temp = (63 - helper) + 1;
const uint64_t diff = helper + _tzcnt_u64(h1);
return diff && ((v >> (temp - quot)) & ((UINT64_C(1) << diff) - 1));
}
}
inline bool find(int64_t quot, uint8_t rem, const __m512i *pd) {
#ifndef NDEBUG
bool val = pd_find_naive(quot, rem, pd);
bool res = pd_find_50_v18(quot, rem, pd);
if (val != res) {
std::cout << "val: \t" << val << std::endl;
std::cout << "res: \t" << res << std::endl;
std::cout << "quot: \t" << quot << std::endl;
std::cout << "rem: \t" << (u16) rem << std::endl;
std::cout << "cap: \t" << get_cap(pd) << std::endl;
assert(0);
}
#endif//!NDEBUG
return pd_find_50_v18(quot, rem, pd);
}
inline void body_remove_case0_avx(size_t index, __m512i *pd) {
const __m512i shifted_pd = shift_left(*pd);
const uint64_t mask = _bzhi_u64(-1, kBytes2copy + index);
_mm512_store_si512(pd, _mm512_mask_blend_epi8(mask, shifted_pd, *pd));
}
inline void header_remove_branch(size_t h_end, __m512i *pd) {
#ifndef NDEBUG
const __m512i backup = *pd;
#endif// DEBUG \
// assert(check::validate_number_of_quotient_case0(pd)); \
// assert(get_cap_wrap(pd)); \
// assert(get_cap_wrap(pd) <= MAX_CAP0);
constexpr uint64_t J = 64;
uint64_t *pd64 = ((uint64_t *) pd);
if (h_end >= 64) {
const size_t rel_index = h_end - 64u;
assert(rel_index < J);
const uint64_t index_mask = _bzhi_u64(-1, rel_index);
uint64_t lo = pd64[1] & index_mask;
uint64_t hi = ((pd64[1] & ~index_mask) >> 1u);// & _bzhi_u64(-1, J);
// uint64_t hi = (pd64[1] >> rel_index) << (rel_index + 1);
assert(!(lo & hi));
const uint64_t new_h1 = (lo | hi);
memcpy(pd64 + 1, &new_h1, 8);
assert(check::validate_number_of_quotient(pd, &backup));
assert(check::validate_number_of_quotient(pd));
return;
}
uint64_t h0, h1;
// memcpy(&h0, (const uint64_t *) pd, 8);
memcpy(&h0, pd64, 8);
memcpy(&h1, pd64 + 1, 8);
const uint64_t bit_to_move = pd64[1] << 63u;
const uint64_t h0_mask = _bzhi_u64(-1, h_end);
const uint64_t h0_lower = h0 & h0_mask;
const uint64_t h0_hi = (h0 & ~h0_mask) >> 1u;
assert(!(h0_lower & h0_hi));
pd64[0] = h0_lower | h0_hi | bit_to_move;
pd64[1] >>= 1u;
// const uint64_t new_h1 = (pd64[1] >> 1u
// memcpy(pd64 + 1, &new_h1, 5);
assert(check::validate_number_of_quotient(pd, &backup));
assert(check::validate_number_of_quotient(pd));
}
inline bool conditional_remove(int64_t quot, uint8_t rem, __m512i *pd) {
assert(quot < QUOTS);
const __m512i target = _mm512_set1_epi8(rem);
uint64_t v = _mm512_cmpeq_epu8_mask(target, *pd) >> 13ul;
if (!v)
return false;
/* if (_blsr_u64(v) == 0) {
const uint64_t i = _tzcnt_u64(v);
const bool find_res = (!(header & (((unsigned __int128) 1) << (quot + i)))) &&
(pd512::popcount128(header & (((unsigned __int128) 1 << (quot + i)) - 1)) == quot);
if (find_res) {
assert(rem == ((const uint8_t *) pd)[kBytes2copy + i]);
const uint64_t shift = i + quot;
unsigned __int128 new_header = header & ((((unsigned __int128) 1) << shift) - 1);
new_header |= ((header >> (shift + 1)) << (shift));
// new_header |= ((header >> shift) << (shift - 1));
assert(pd512::popcount128(header) == 50);
assert(pd512::validate_number_of_quotient(pd));
memcpy(pd, &new_header, kBytes2copy);
assert(pd512::validate_number_of_quotient(pd));
memmove(&((uint8_t *) pd)[kBytes2copy + i],
&((const uint8_t *) pd)[kBytes2copy + i + 1],
sizeof(*pd) - (kBytes2copy + i + 1));
}
return find_res;
}
*/
uf8 res[2] = {0, 0};
select_both_case0_arr(quot, res, pd);
const uf64 begin = res[0] + (quot != 0);
uf64 end = res[1];
assert(begin <= end);
const uint64_t begin_fingerprint = begin - quot;
const uint64_t end_fingerprint = end - quot;
assert(begin_fingerprint <= end_fingerprint);
assert(end_fingerprint <= MAX_CAP);
uint64_t v1 = v >> begin_fingerprint;
uint64_t i = _tzcnt_u64(v1) + begin_fingerprint;
// assert(((1 << end_fingerprint) < v) == (i < end_fingerprint));
if (i >= end_fingerprint)
return false;
assert(pd_find_naive(quot, rem, pd));
assert(rem == ((const uint8_t *) pd)[kBytes2copy + i]);
const uint64_t shift = i + quot;
header_remove_branch(shift, pd);
body_remove_case0_avx(i, pd);
return true;
}
inline bool remove(int64_t quot, uint8_t rem, __m512i *pd) {
assert(quot < QUOTS);
assert(find(quot, rem, pd));
const __m512i target = _mm512_set1_epi8(rem);
uint64_t v = _mm512_cmpeq_epu8_mask(target, *pd) >> 16ul;
assert(v);
if (_blsr_u64(v) == 0) {
const uint64_t i = _tzcnt_u64(v);
size_t h_index = i + quot;
header_remove_branch(h_index, pd);
body_remove_case0_avx(i, pd);
return true;
}
uf8 res[2] = {0, 0};
select_both_case0_arr(quot, res, pd);
const uf64 begin = res[0] + (quot != 0);
uf64 end = res[1];
assert(end == select_on_first_part(quot, pd));
assert(begin <= end);
const uint64_t begin_fingerprint = begin - quot;
const uint64_t end_fingerprint = end - quot;
const uint64_t b_mask = ~((1ull << (begin_fingerprint)) - 1);
const uint64_t end_mask = ((1ull << end_fingerprint) - 1);
const uint64_t mask = b_mask & end_mask;
assert((begin < end) ? mask : !mask);
const uint64_t v_masked = v & mask;
assert(v_masked);
const uint64_t i = _tzcnt_u64(v_masked);
header_remove_branch(end - 1, pd);
body_remove_case0_avx(i, pd);
return true;
}
inline void body_add3(size_t end_fingerprint, uint8_t rem, __m512i *pd) {
const __m512i shifted_pd = shift_right(*pd);
((uint8_t *) pd)[kBytes2copy + end_fingerprint] = rem;
const uint64_t mask = _bzhi_u64(-1, kBytes2copy + end_fingerprint + 1);
_mm512_store_si512(pd, _mm512_mask_blend_epi8(mask, shifted_pd, *pd));
}
inline void write_header6(uint64_t index, __m512i *pd) {
assert(check::validate_number_of_quotient(pd));
// v_pd512_plus::print_headers(pd);
// constexpr uint64_t h1_mask = ((1ULL << (101 - 64)) - 1);
uint64_t *pd64 = (uint64_t *) pd;
// const uint64_t low_h1 = ((pd64[1] << 1) & h1_const_mask) | (pd64[0] >> 63u);
const uint64_t low_h1 = (pd64[1] << 1) | (pd64[0] >> 63u);
const uint64_t h0_mask = _bzhi_u64(-1, index);
const uint64_t h0_lower = pd64[0] & h0_mask;
// pd64[0] = h0_lower | ((pd64[0] << 1u) & ~h0_mask);
pd64[0] = h0_lower | ((pd64[0] & ~h0_mask) << 1u);
memcpy(pd64 + 1, &low_h1, kBytes2copy - 8);
// v_pd512_plus::print_headers(pd);
assert(check::validate_number_of_quotient(pd));
}
inline void header_remove_naive(uint64_t index, __m512i *pd) {
assert(check::validate_number_of_quotient(pd));
const unsigned __int128 *h = (const unsigned __int128 *) pd;
constexpr unsigned __int128 kLeftoverMask = (((unsigned __int128) 1) << (50 + 51)) - 1;
const unsigned __int128 header = (*h) & kLeftoverMask;
// const uint64_t end = select128(header, quot);
const unsigned __int128 mask = (((unsigned __int128) 1) << index) - 1ull;
unsigned __int128 high_header = (header & ~mask) >> 1ull;
unsigned __int128 low_header = header & mask;
// assert(!(high_header & low_header));
unsigned __int128 new_header = high_header | low_header;
memcpy(pd, &new_header, kBytes2copy);
assert(check::validate_number_of_quotient(pd));
}
inline void header_remove(uint64_t index, __m512i *pd) {
assert(tc_sym::check::validate_number_of_quotient(pd));
// v_pd512_plus::print_headers(pd);
uint64_t *pd64 = (uint64_t *) pd;
const uint64_t h1_lsb = pd64[1] << 63u;
// const uint64_t low_h1 = (pd64[1] & h1_const_mask) >> 1u;
pd64[1] >>= 1u;
// const uint64_t low_h1 = pd64[1] & h1_const_mask) >> 1u;
const uint64_t h0_mask = _bzhi_u64(-1, index);
const uint64_t h0_lower = pd64[0] & h0_mask;
const uint64_t h0_higher = ((pd64[0] & ~h0_mask) >> 1u) | h1_lsb;
pd64[0] = h0_lower | h0_higher;
// memcpy(pd64 + 1, &low_h1, kBytes2copy - 8);
// v_pd512_plus::print_headers(pd);
assert(tc_sym::check::validate_number_of_quotient(pd));
}
inline void add_quot0(uint8_t rem, __m512i *pd) {
assert(check::validate_number_of_quotient(pd));
uint64_t *pd64 = (uint64_t *) pd;
//TODO: end can always be zero.
const uint64_t end = _tzcnt_u64(pd64[0]);
const uint64_t low_h1 = ((pd64[1] << 1)) | (pd64[0] >> 63u);
memcpy(pd64 + 1, &low_h1, kBytes2copy - 8);
pd64[0] <<= 1u;
assert(check::validate_number_of_quotient(pd));
body_add3(end, rem, pd);
}
/**
* @brief Inserting a new element when pd is not full.
*
* @param quot
* @param rem
* @param pd
*/
inline void add_wrap(int64_t quot, uint8_t rem, __m512i *pd) {
assert(!pd_full(pd));
assert(quot < QUOTS);
if (quot == 0) {
add_quot0(rem, pd);
return;
}
// constexpr uint64_t h1_const_mask = ((1ULL << (101 - 64)) - 1);
const uint64_t h0 = _mm_extract_epi64(_mm512_castsi512_si128(*pd), 0);
const uint64_t pop = _mm_popcnt_u64(h0);
// const uint64_t pop = (h0 ^ (h0 >> 8u)) % QUOTS;
if (quot < pop) {
const uint64_t end = select64(h0, quot);
write_header6(end, pd);
// write_header_naive(quot, end, pd);
body_add3(end - quot, rem, pd);
return;
} else {
const uint64_t h1 = _mm_extract_epi64(_mm512_castsi512_si128(*pd), 1);
const uint64_t end = select64(h1, quot - pop);
//header
assert(tc_sym::check::validate_number_of_quotient(pd));
const uint64_t h1_mask = _bzhi_u64(-1, end);
const uint64_t h1_low = h1 & h1_mask;
assert(end < 64);
const uint64_t h1_high = (h1 >> end) << (end + 1);
assert(!(h1_low & h1_high));
const uint64_t new_h1 = h1_low | h1_high;
memcpy(&((uint64_t *) pd)[1], &new_h1, kBytes2copy - 8);
assert(tc_sym::check::validate_number_of_quotient(pd));
//body
const uint64_t index = 64 + end - quot;
// body_add_naive(index, rem, pd);
body_add3(index, rem, pd);
assert(tc_sym::check::validate_number_of_quotient(pd));
assert(find(quot, rem, pd));
return;
}
}
inline bool add_db(int64_t quot, uint8_t rem, __m512i *pd) {
// if (pd_full(pd))
assert(!pd_full(pd));
auto prev_q_occ = get_spec_quot_cap2(quot, pd);
add_wrap(quot, rem, pd);
auto post_q_occ = get_spec_quot_cap2(quot, pd);
auto post_q_occ2 = quot ? bitsMani::count_zeros_between_consecutive_ones(quot - 1, (const u64 *) pd, 512) : select_on_first_part(0, pd);
// auto post_q_occ3 = get_spec_quot_cap2(quot, pd);
// if ((post_q_occ != post_q_occ2) or (post_q_occ != post_q_occ3)) {
if (post_q_occ != post_q_occ2) {
std::cout << "post_q_occ: \t" << post_q_occ << std::endl;
std::cout << "post_q_occ2: \t" << post_q_occ2 << std::endl;
// std::cout << "post_q_occ3: \t" << post_q_occ3 << std::endl;
tc_sym::check::print_pd(pd);
assert(0);
}
if (prev_q_occ + 1 != post_q_occ) {
std::cout << "prev_q_occ: \t" << prev_q_occ << std::endl;
std::cout << "post_q_occ: \t" << post_q_occ << std::endl;
std::cout << "quot: \t" << quot << std::endl;
std::cout << "rem: \t" << (u16) rem << std::endl;
tc_sym::check::print_pd(pd);
}
assert(prev_q_occ + 1 == post_q_occ);
assert(find(quot, rem, pd));
return true;
}
inline bool add(int64_t quot, uint8_t rem, __m512i *pd) {
// return add_db(quot, rem, pd);
assert(!pd_full(pd));
add_wrap(quot, rem, pd);
assert(find(quot, rem, pd));
return true;
}
}// namespace tc_sym
#endif// TC_SYM_HPP

266
Tests/PerfEvent.hpp Normal file
View File

@ -0,0 +1,266 @@
/*
Copyright (c) 2018 Viktor Leis
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#pragma once
#include <chrono>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <map>
#include <string>
#include <vector>
#include <asm/unistd.h>
#include <linux/perf_event.h>
#include <sys/ioctl.h>
#include <unistd.h>
struct PerfEvent {
struct event {
struct read_format {
uint64_t value;
uint64_t time_enabled;
uint64_t time_running;
uint64_t id;
};
perf_event_attr pe;
int fd;
read_format prev;
read_format data;
double readCounter() {
double multiplexingCorrection = static_cast<double>(data.time_enabled - prev.time_enabled) / (data.time_running - prev.time_running);
return (data.value - prev.value) * multiplexingCorrection;
}
};
std::vector<event> events;
std::vector<std::string> names;
std::chrono::time_point<std::chrono::steady_clock> startTime;
std::chrono::time_point<std::chrono::steady_clock> stopTime;
PerfEvent() {
registerCounter("cycles", PERF_TYPE_HARDWARE, PERF_COUNT_HW_CPU_CYCLES);
registerCounter("instructions", PERF_TYPE_HARDWARE, PERF_COUNT_HW_INSTRUCTIONS);
registerCounter("L1-misses", PERF_TYPE_HW_CACHE, PERF_COUNT_HW_CACHE_L1D | (PERF_COUNT_HW_CACHE_OP_READ << 8) | (PERF_COUNT_HW_CACHE_RESULT_MISS << 16));
registerCounter("LLC-misses", PERF_TYPE_HARDWARE, PERF_COUNT_HW_CACHE_MISSES);
registerCounter("branch-misses", PERF_TYPE_HARDWARE, PERF_COUNT_HW_BRANCH_MISSES);
registerCounter("task-clock", PERF_TYPE_SOFTWARE, PERF_COUNT_SW_TASK_CLOCK);
// additional counters can be found in linux/perf_event.h
const int pid = 0; // the current process
const int cpu = 2;
const int group = -1;// all CPUs
const unsigned long flags = 0;
for (unsigned i = 0; i < events.size(); i++) {
auto &event = events[i];
event.fd = syscall(__NR_perf_event_open, &event.pe, pid, cpu, group, flags);
if (event.fd < 0) {
std::cerr << "Error opening counter " << names[i] << std::endl;
events.resize(0);
names.resize(0);
return;
}
}
}
void registerCounter(const std::string &name, uint64_t type, uint64_t eventID) {
names.push_back(name);
events.push_back(event());
auto &event = events.back();
auto &pe = event.pe;
memset(&pe, 0, sizeof(struct perf_event_attr));
pe.type = type;
pe.size = sizeof(struct perf_event_attr);
pe.config = eventID;
pe.disabled = true;
pe.inherit = 1;
pe.inherit_stat = 0;
pe.exclude_kernel = false;
pe.exclude_hv = false;
pe.read_format = PERF_FORMAT_TOTAL_TIME_ENABLED | PERF_FORMAT_TOTAL_TIME_RUNNING;
}
void startCounters() {
for (unsigned i = 0; i < events.size(); i++) {
auto &event = events[i];
ioctl(event.fd, PERF_EVENT_IOC_RESET, 0);
ioctl(event.fd, PERF_EVENT_IOC_ENABLE, 0);
if (read(event.fd, &event.prev, sizeof(uint64_t) * 3) != sizeof(uint64_t) * 3)
std::cerr << "Error reading counter " << names[i] << std::endl;
}
startTime = std::chrono::steady_clock::now();
}
~PerfEvent() {
for (auto &event : events) {
close(event.fd);
}
}
void stopCounters() {
stopTime = std::chrono::steady_clock::now();
for (unsigned i = 0; i < events.size(); i++) {
auto &event = events[i];
if (read(event.fd, &event.data, sizeof(uint64_t) * 3) != sizeof(uint64_t) * 3)
std::cerr << "Error reading counter " << names[i] << std::endl;
ioctl(event.fd, PERF_EVENT_IOC_DISABLE, 0);
}
}
double getDuration() {
return std::chrono::duration<double>(stopTime - startTime).count();
}
ulong get_time() {
return std::chrono::duration_cast<std::chrono::nanoseconds>(stopTime - startTime).count();
// return std::chrono::duration<double>(stopTime - startTime).count();
}
double getIPC() {
return getCounter("instructions") / getCounter("cycles");
}
double getCPUs() {
return getCounter("task-clock") / (getDuration() * 1e9);
}
double getGHz() {
return getCounter("cycles") / getCounter("task-clock");
}
double getCounter(const std::string &name) {
for (unsigned i = 0; i < events.size(); i++)
if (names[i] == name)
return events[i].readCounter();
return -1;
}
static void printCounter(std::ostream &headerOut, std::ostream &dataOut, std::string name, std::string counterValue, bool addComma = true) {
auto width = std::max(name.length(), counterValue.length());
headerOut << std::setw(width) << name << (addComma ? "," : "") << " ";
dataOut << std::setw(width) << counterValue << (addComma ? "," : "") << " ";
}
template<typename T>
static void printCounter(std::ostream &headerOut, std::ostream &dataOut, std::string name, T counterValue, bool addComma = true) {
std::stringstream stream;
stream << std::fixed << std::setprecision(2) << counterValue;
PerfEvent::printCounter(headerOut, dataOut, name, stream.str(), addComma);
}
void printReport(std::ostream &out, uint64_t normalizationConstant) {
std::stringstream header;
std::stringstream data;
printReport(header, data, normalizationConstant);
out << header.str() << std::endl;
out << data.str() << std::endl;
}
void printReport_NoHeader(std::ostream &out, uint64_t normalizationConstant) {
std::stringstream header;
std::stringstream data;
printReport(header, data, normalizationConstant);
out << data.str() << std::endl;
// out << header.str() << std::endl;
}
void printReport(std::ostream &headerOut, std::ostream &dataOut, uint64_t normalizationConstant) {
if (!events.size())
return;
// print all metrics
for (unsigned i = 0; i < events.size(); i++) {
printCounter(headerOut, dataOut, names[i], events[i].readCounter() / normalizationConstant);
}
printCounter(headerOut, dataOut, "scale", normalizationConstant);
// derived metrics
printCounter(headerOut, dataOut, "IPC", getIPC());
printCounter(headerOut, dataOut, "CPUs", getCPUs());
printCounter(headerOut, dataOut, "GHz", getGHz(), false);
}
};
struct BenchmarkParameters {
void setParam(const std::string &name, const std::string &value) {
params[name] = value;
}
void setParam(const std::string &name, const char *value) {
params[name] = value;
}
template<typename T>
void setParam(const std::string &name, T value) {
setParam(name, std::to_string(value));
}
void printParams(std::ostream &header, std::ostream &data) {
for (auto &p : params) {
PerfEvent::printCounter(header, data, p.first, p.second);
}
}
BenchmarkParameters(std::string name = "") {
if (name.length())
setParam("name", name);
}
private:
std::map<std::string, std::string> params;
};
struct PerfEventBlock {
PerfEvent e;
uint64_t scale;
BenchmarkParameters parameters;
bool printHeader;
PerfEventBlock(uint64_t scale = 1, BenchmarkParameters params = {}, bool printHeader = true)
: scale(scale),
parameters(params),
printHeader(printHeader) {
e.startCounters();
}
~PerfEventBlock() {
e.stopCounters();
std::stringstream header;
std::stringstream data;
parameters.printParams(header, data);
PerfEvent::printCounter(header, data, "time sec", e.getDuration());
e.printReport(header, data, scale);
if (printHeader)
std::cout << header.str() << std::endl;
std::cout << data.str() << std::endl;
}
};

171
Tests/smart_tests.cpp Normal file
View File

@ -0,0 +1,171 @@
#include "smart_tests.hpp"
namespace testSmart {
size_t count_uniques(std::vector<u64> *v) {
std::sort(v->begin(), v->end());
auto uniqueCount = std::unique(v->begin(), v->end()) - v->begin();
return uniqueCount;
}
void vector_concatenate_and_shuffle(const std::vector<u64> *v1, const std::vector<u64> *v2, std::vector<u64> *res, std::mt19937_64 rng) {
size_t all_size = v1->size() + v2->size();
res->resize(all_size);
res->insert(res->end(), v1->begin(), v1->end());
res->insert(res->end(), v2->begin(), v2->end());
std::shuffle(res->begin(), res->end(), rng);
}
void weighted_vector_concatenate_and_shuffle(const std::vector<u64> *v_yes, const std::vector<u64> *v_uni, std::vector<u64> *res, double yes_div, std::mt19937_64 rng) {
assert(yes_div <= 1);
auto v_yes_items = std::ceil(v_yes->size() * yes_div);
size_t all_size = v_yes_items + v_uni->size();
res->resize(all_size);
res->insert(res->end(), v_yes->begin(), v_yes->begin() + v_yes_items);
res->insert(res->end(), v_uni->begin(), v_uni->end());
std::shuffle(res->begin(), res->end(), rng);
}
void vector_concatenate_and_shuffle(const std::vector<u64> *v1, const std::vector<u64> *v2, std::vector<u64> *res) {
std::uint_least64_t seed;
sysrandom(&seed, sizeof(seed));
std::mt19937_64 new_rng(seed);
vector_concatenate_and_shuffle(v1, v2, res, new_rng);
}
size_t test_shuffle_function(const std::vector<u64> *v1, const std::vector<u64> *v2, std::vector<u64> *res) {
size_t all_size = v1->size() + v2->size();
res->resize(all_size);
res->insert(res->end(), v1->begin(), v1->end());
res->insert(res->end(), v2->begin(), v2->end());
res->shrink_to_fit();
std::vector<u64> temp_vec(*res);
for (size_t i = 0; i < 100; i++) { assert(temp_vec.at(i) == res->at(i)); }
std::uint_least64_t seed;
sysrandom(&seed, sizeof(seed));
std::mt19937_64 new_rng(seed);
std::shuffle(res->begin(), res->end(), new_rng);
new_rng();
// std::shuffle(res->begin(), res->end(), new_rng);new_rng();
// std::shuffle(res->begin(), res->end(), new_rng);new_rng();
// std::shuffle(res->begin(), res->end(), new_rng);new_rng();
size_t counter = 0;
for (size_t i = 0; i < all_size; i++) { counter += (temp_vec.at(i) == res->at(i)); }
auto u_count = count_uniques(&temp_vec);
std::cout << "u_count: \t" << u_count << std::endl;
auto ratio = (1.0 * u_count) / temp_vec.size();
std::cout << "ratio: \t" << ratio << std::endl;
return counter;
// assert
}
void print_vector(const std::vector<u64> *vec) {
std::cout << vec->at(0);// << std::endl;
for (size_t i = 1; i < vec->size(); i++) {
std::cout << ", " << vec->at(i);// << std::endl;
}
std::cout << std::endl;
}
void print_vector(const std::vector<u64> *vec, size_t start, size_t end) {
assert(start < end);
assert(end < vec->size());
std::cout << vec->at(start);// << std::endl;
for (size_t i = start + 1; i < end; i++) {
std::cout << ", " << vec->at(i);// << std::endl;
}
std::cout << std::endl;
}
std::mt19937_64 fill_vec_smart(std::vector<u64> *vec, size_t number_of_elements) {
std::uint_least64_t seed;
sysrandom(&seed, sizeof(seed));
// if (1) {
// std::cout << "seed is constant: " << 0xf1234'5678'9abc << std::endl;
// seed = 0xf1234'5678'9abc;
// }
std::mt19937_64 rng(seed);
std::uniform_int_distribution<uint64_t> dist(0, UINT64_MAX);
vec->resize(number_of_elements);
for (size_t i = 0; i < number_of_elements; ++i) {
vec->at(i) = dist(rng);
}
return rng;
}
void fill_vec_from_range_and_shuffle(size_t start, size_t end, size_t length, const std::vector<u64> *input_vec, std::vector<u64> *temp_vec, std::mt19937_64 rng) {
assert(start < end);
assert(start + length <= end);
temp_vec->resize(end - start);
for (size_t i = start; i < end; i++) {
temp_vec->at(i - start) = input_vec->at(i);
}
std::shuffle(temp_vec->begin(), temp_vec->end(), rng);
}
void my_naive_sample(size_t start, size_t end, size_t length, const std::vector<u64> *input_vec, std::vector<u64> *temp_vec, std::mt19937_64 &rng) {
std::uniform_int_distribution<> dis(start, end);
for (size_t i = 0; i < length; i++) {
u64 temp_item = input_vec->at(dis(rng));
temp_vec->at(i) = temp_item;
}
}
void fill_vec_by_samples(size_t start, size_t end, size_t length, const std::vector<u64> *input_vec, std::vector<u64> *temp_vec, std::mt19937_64 rng) {
std::uint_least64_t seed;
sysrandom(&seed, sizeof(seed));
std::mt19937_64 new_rng(seed);
assert(start < end);
assert(start + length <= end);
temp_vec->resize(length);
// auto it_start = input_vec->begin() + start;
// auto it_end = input_vec->begin() + end;
// std::sample(it_start, it_end, temp_vec->begin(), length, new_rng);
my_naive_sample(start, end, length, input_vec, temp_vec, new_rng);
temp_vec->shrink_to_fit();
assert(temp_vec->size() == length);
std::shuffle(temp_vec->begin(), temp_vec->end(), new_rng);
}
void fill_vec_by_samples(size_t start, size_t end, size_t length, const std::vector<u64> *input_vec, std::vector<u64> *temp_vec) {
std::uint_least64_t seed;
sysrandom(&seed, sizeof(seed));
std::mt19937_64 new_rng(seed);
assert(start < end);
assert(start + length <= end);
temp_vec->resize(length);
// auto it_start = input_vec->begin() + start;
// auto it_end = input_vec->begin() + end;
// std::sample(it_start, it_end, temp_vec->begin(), length, new_rng);
my_naive_sample(start, end, length, input_vec, temp_vec, new_rng);
temp_vec->shrink_to_fit();
assert(temp_vec->size() == length);
std::shuffle(temp_vec->begin(), temp_vec->end(), new_rng);
}
void print_data(const u64 *data, size_t size, size_t bench_precision, size_t find_step) {
const unsigned width = 12;
const unsigned items_in_line = 4;
const unsigned lines = bench_precision / items_in_line;
for (size_t i = 0; i < lines; i++) {
auto temp_sum = 0;
size_t index = i * items_in_line;
std::cout << i << ":\t" << std::setw(width) << ((1.0 * find_step) / (1.0 * data[index] / 1e9));
temp_sum += data[index];
for (size_t j = 1; j < items_in_line; j++) {
std::cout << ", " << std::setw(width) << ((1.0 * find_step) / (1.0 * data[index + j] / 1e9));
temp_sum += data[index + j];
}
std::cout << "|Average:\t" << ((1.0 * items_in_line * find_step) / (1.0 * temp_sum / 1e9)) << std::endl;
// std::cout << std::endl;
}
}
}// namespace testSmart

688
Tests/smart_tests.hpp Normal file
View File

@ -0,0 +1,688 @@
#ifndef FILTERS_SMART_TESTS_HPP
#define FILTERS_SMART_TESTS_HPP
#define PREVENT_PIPELINING (1)
#include "../Tests/wrappers.hpp"
// #include "PerfEvent.hpp"
#include <chrono>
#include <fstream>
#include <random>
#include <unistd.h>
#include <vector>
// #include "timing.hpp"
// #include <execution>
typedef std::chrono::nanoseconds ns;
namespace testSmart {
constexpr size_t db_speeder = 1;
constexpr size_t ROUNDS = 9;
size_t count_uniques(std::vector<u64> *v);
void vector_concatenate_and_shuffle(const std::vector<u64> *v1, const std::vector<u64> *v2, std::vector<u64> *res, std::mt19937_64 rng);
void vector_concatenate_and_shuffle(const std::vector<u64> *v1, const std::vector<u64> *v2, std::vector<u64> *res);
void weighted_vector_concatenate_and_shuffle(const std::vector<u64> *v_yes, const std::vector<u64> *v_uni, std::vector<u64> *res, double yes_div, std::mt19937_64 rng);
size_t test_shuffle_function(const std::vector<u64> *v1, const std::vector<u64> *v2, std::vector<u64> *res);
void print_data(const u64 *data, size_t size, size_t bench_precision, size_t find_step);
//Building elements vector
std::mt19937_64 fill_vec_smart(std::vector<u64> *vec, size_t number_of_elements);
void my_naive_sample(size_t start, size_t end, size_t length, const std::vector<u64> *input_vec, std::vector<u64> *temp_vec, std::mt19937_64 &rng);
void fill_vec_by_samples(size_t start, size_t end, size_t length, const std::vector<u64> *input_vec, std::vector<u64> *temp_vec, std::mt19937_64 rng);
void fill_vec_by_samples(size_t start, size_t end, size_t length, const std::vector<u64> *input_vec, std::vector<u64> *temp_vec);
}// namespace testSmart
namespace testSmart {
template<typename Table>
void write_res_to_file_core(const Table *wrap_filter, size_t init_time, size_t filter_max_capacity, size_t lookup_reps, size_t bench_precision, const u64 *data, std::string file_prefix);
template<typename Table>
void write_perf_res_to_file(const Table *wrap_filter, size_t init_time, size_t filter_max_capacity, size_t lookup_reps, size_t bench_precision, const u64 *data, std::string file_prefix, std::stringstream &add_ss, std::stringstream &uni_find_ss, std::stringstream &yes_find_ss);
template<class Table>
void FPR_test0_after_build(const Table *wrap_filter, const std::vector<u64> *v_add, const std::vector<u64> *v_find, size_t bench_precision);
template<class Table>
std::string FPR_parse_data_str_22(const Table *wrap_filter, const std::vector<u64> *v_add, const std::vector<u64> *v_find, size_t yes_res);
inline size_t sysrandom(void *dst, size_t dstlen) {
char *buffer = reinterpret_cast<char *>(dst);
std::ifstream stream("/dev/urandom", std::ios_base::binary | std::ios_base::in);
stream.read(buffer, dstlen);
return dstlen;
}
template<class Table>
__attribute__((noinline)) auto time_lookups(const Table *wrap_filter, const std::vector<u64> *element_set, size_t start, size_t end) -> ulong {
static volatile bool dummy;
bool x = 0;
auto t0 = std::chrono::high_resolution_clock::now();
for (size_t i = start; i < end; ++i) {
x ^= FilterAPI<Table>::Contain(element_set->at(i), wrap_filter);
// #if PREVENT_PIPELINING
// asm volatile(
// "rdtscp\n\t"
// "lfence"
// :
// :
// : "rax", "rcx", "rdx", "memory");
// #endif
}
auto t1 = std::chrono::high_resolution_clock::now();
dummy = x;
return std::chrono::duration_cast<ns>(t1 - t0).count();
}
template<class Table>
__attribute__((noinline)) auto time_insertions(Table *wrap_filter, const std::vector<u64> *element_set, size_t start, size_t end) -> ulong {
auto t0 = std::chrono::steady_clock::now();
for (size_t i = start; i < end; ++i) {
FilterAPI<Table>::Add(element_set->at(i), wrap_filter);
// #if PREVENT_PIPELINING
// asm volatile(
// "rdtscp\n\t"
// "lfence"
// :
// :
// : "rax", "rcx", "rdx", "memory");
// #endif
}
// FilterAPI<Table>::AddAll(*element_set, start, end, wrap_filter);
auto t1 = std::chrono::steady_clock::now();
return std::chrono::duration_cast<ns>(t1 - t0).count();
}
/*template<class Table>
__attribute__((noinline)) auto time_lookups_perf(const Table *wrap_filter, const std::vector<u64> *element_set, size_t start, size_t end, std::stringstream &ss, bool with_header) -> ulong {
static volatile bool dummy;
bool x = 0;
PerfEvent e;
asm volatile(
"rdtscp\n\t"
"lfence"
:
:
: "rax", "rcx", "rdx", "memory");
e.startCounters();
// auto t0 = std::chrono::high_resolution_clock::now();
for (size_t i = start; i < end; ++i) {
x ^= FilterAPI<Table>::Contain(element_set->at(i), wrap_filter);
// #if PREVENT_PIPELINING
// asm volatile(
// "rdtscp\n\t"
// "lfence"
// :
// :
// : "rax", "rcx", "rdx", "memory");
// #endif
}
// auto t1 = std::chrono::high_resolution_clock::now();
dummy = x;
e.stopCounters();
asm volatile(
"rdtscp\n\t"
"lfence"
:
:
: "rax", "rcx", "rdx", "memory");
if (with_header) {
e.printReport(ss, end - start);
} else {
e.printReport_NoHeader(ss, end - start);
}
// return std::chrono::duration_cast<ns>(t1 - t0).count();
return e.get_time();
}
template<class Table>
__attribute__((noinline)) auto time_insertions_perf(Table *wrap_filter, const std::vector<u64> *element_set, size_t start, size_t end, std::stringstream &ss) -> ulong {
PerfEvent e;
e.startCounters();
// auto t0 = std::chrono::high_resolution_clock::now();
for (size_t i = start; i < end; ++i) {
FilterAPI<Table>::Add(element_set->at(i), wrap_filter);
// #if PREVENT_PIPELINING
// asm volatile(
// "rdtscp\n\t"
// "lfence"
// :
// :
// : "rax", "rcx", "rdx", "memory");
// #endif
}
// FilterAPI<Table>::AddAll(*element_set, start, end, wrap_filter);
// auto t1 = std::chrono::high_resolution_clock::now();
e.stopCounters();
asm volatile(
"rdtscp\n\t"
"lfence"
:
:
: "rax", "rcx", "rdx", "memory");
if (start == 0) {
e.printReport(ss, end - start);
} else {
e.printReport_NoHeader(ss, end - start);
}
// return std::chrono::duration_cast<ns>(t1 - t0).count();
return e.get_time();
// return std::chrono::duration_cast<ns>(t1 - t0).count();
}
*/
template<class Table>
__attribute__((noinline)) auto time_deletions(Table *wrap_filter, const std::vector<u64> *element_set, size_t start, size_t end) -> ulong {
if (!(FilterAPI<Table>::get_functionality(wrap_filter) & 4)) {
//FIXME: UNCOMMENT!
std::cout << FilterAPI<Table>::get_name(wrap_filter) << " does not support deletions." << std::endl;
return 0;
}
auto t0 = std::chrono::steady_clock::now();
for (size_t i = start; i < end; ++i) {
FilterAPI<Table>::Remove(element_set->at(i), wrap_filter);
}
auto t1 = std::chrono::steady_clock::now();
return std::chrono::duration_cast<ns>(t1 - t0).count();
}
template<class Table>
void benchmark_single_round_np_incremental(Table *wrap_filter, const std::vector<u64> *add_vec, const std::vector<u64> *find_vec, size_t round_counter, size_t benchmark_precision, u64 *data, bool to_print, std::stringstream &add_ss, std::stringstream &uni_find_ss, std::stringstream &yes_find_ss) {
/* switch between the commented lines with "time_time_insertions" and "time_insertions_perf" to also get a csv file with data on the performances counters.*/
const size_t find_step = find_vec->size() / benchmark_precision;
size_t add_step = add_vec->size() / benchmark_precision;
const size_t true_find_step = add_step;
size_t add_start = round_counter * add_step;
auto insertion_time = time_insertions(wrap_filter, add_vec, add_start, add_start + add_step);
// auto insertion_time = time_insertions_perf(wrap_filter, add_vec, add_start, add_start + add_step, add_ss);
asm volatile(
"rdtscp\n\t"
"lfence"
:
:
: "rax", "rcx", "rdx", "memory");
auto find_start = find_step * round_counter;
auto uniform_lookup_time = time_lookups(wrap_filter, find_vec, find_start, find_start + find_step);
// auto uniform_lookup_time = time_lookups_perf(wrap_filter, find_vec, find_start, find_start + find_step, uni_find_ss, round_counter == 0);
asm volatile(
"rdtscp\n\t"
"lfence"
:
:
: "rax", "rcx", "rdx", "memory");
// auto true_lookup_time = time_lookups(wrap_filter, add_vec, del_start, del_start + add_step);
std::vector<u64> temp_vec;
fill_vec_by_samples(0, add_start + add_step, true_find_step, add_vec, &temp_vec);
asm volatile(
"rdtscp\n\t"
"lfence"
:
:
: "rax", "rcx", "rdx", "memory");
auto true_lookup_time = time_lookups(wrap_filter, &temp_vec, 0, true_find_step);
// auto true_lookup_time = time_lookups_perf(wrap_filter, &temp_vec, 0, true_find_step, yes_find_ss, round_counter == 0);
asm volatile(
"rdtscp\n\t"
"lfence"
:
:
: "rax", "rcx", "rdx", "memory");
size_t index = 4 * (round_counter);
data[index + 0] = insertion_time;
data[index + 1] = uniform_lookup_time;
data[index + 2] = true_lookup_time;
data[index + 3] = 0;
if (to_print) {
constexpr size_t width = 12;
std::cout << round_counter << ": \t";
std::cout << std::setw(width) << std::left << ((1.0 * add_step) / (1.0 * data[index + 0] / 1e9)) << ", ";
std::cout << std::setw(width) << std::left << ((1.0 * find_step) / (1.0 * data[index + 1] / 1e9)) << ", ";
std::cout << std::setw(width) << std::left << ((1.0 * add_step) / (1.0 * data[index + 2] / 1e9)) << ", ";
std::cout << std::setw(width) << std::left << ((1.0 * add_step) / (1.0 * data[index + 3] / 1e9)) << std::endl;
}
}
template<typename Table>
void Bench_res_to_file_incremental_22(size_t filter_max_capacity, size_t bench_precision, const std::vector<u64> *add_vec, const std::vector<u64> *lookup_vec, std::string file_prefix, bool to_print = false) {
const size_t data_size = (bench_precision + 2) * 4;
assert(data_size < 1024);
u64 data[data_size];
std::fill(data, data + data_size, 0);
// std::cout << "H0!" << std::endl;
auto t0 = std::chrono::high_resolution_clock::now();
Table filter = FilterAPI<Table>::ConstructFromAddCount(filter_max_capacity);
auto t1 = std::chrono::high_resolution_clock::now();
// std::cout << "Here!" << std::endl;
auto init_time = std::chrono::duration_cast<ns>(t1 - t0).count();
Table *wrap_filter = &filter;
std::string filter_name = FilterAPI<Table>::get_name(wrap_filter);
if (to_print)
std::cout << "filter_name: " << filter_name << std::endl;
// benchmark_round0_np(wrap_filter, add_vec, lookup_vec, bench_precision, rng, data, to_print);
if (to_print) std::cout << std::string(80, '=') << std::endl;
std::stringstream add_ss, uni_find_ss, yes_find_ss;
for (size_t round = 0; round < bench_precision; ++round) {
benchmark_single_round_np_incremental(wrap_filter, add_vec, lookup_vec, round, bench_precision, data, to_print, add_ss, uni_find_ss, yes_find_ss);
// if (to_print) std::cout << std::string(80, '=') << std::endl;
asm volatile(
"rdtscp\n\t"
"lfence"
:
:
: "rax", "rcx", "rdx", "memory");
}
if (to_print) std::cout << std::string(80, '=') << std::endl;
//UNCOMMENT me to get CSV files.
// write_perf_res_to_file(wrap_filter, init_time, filter_max_capacity, lookup_vec->size(), bench_precision, data, file_prefix, add_ss, uni_find_ss, yes_find_ss);
write_res_to_file_core(wrap_filter, init_time, filter_max_capacity, lookup_vec->size(), bench_precision, data, file_prefix);
if (to_print)
FPR_test0_after_build(wrap_filter, add_vec, lookup_vec, bench_precision);
}
template<typename Table>
void write_perf_res_to_file(const Table *wrap_filter, size_t init_time, size_t filter_max_capacity, size_t lookup_reps, size_t bench_precision, const u64 *data, std::string file_prefix, std::stringstream &add_ss, std::stringstream &uni_find_ss, std::stringstream &yes_find_ss) {
std::string filter_name = FilterAPI<Table>::get_name(wrap_filter);
std::string file_name = file_prefix + filter_name + ".csv";
std::cout << "file_name: " << file_name << std::endl;
std::fstream file(file_name, std::fstream::in | std::fstream::out | std::fstream::app);
// file << std::endl;
// std::fstream file(file_name, std::fstream::in | std::fstream::out | std::fstream::trunc);
// std::string str_add = add_ss.str();
// std::cout << std::string(80, '@') << std::endl;
// std::cout << str_add << std::endl;
// std::cout << std::string(80, '@') << std::endl;
file << "add, uni_find, yes_find" << std::endl;
for (size_t i = 0; i < bench_precision + 1; i++) {
std::string temp[3];
std::getline(add_ss, temp[0]);
std::getline(uni_find_ss, temp[1]);
std::getline(yes_find_ss, temp[2]);
file << temp[0] << ",";
file << temp[1] << ",";
file << temp[2] << std::endl;
}
file.close();
}
template<typename Table>
void write_res_to_file_core(const Table *wrap_filter, size_t init_time, size_t filter_max_capacity, size_t lookup_reps, size_t bench_precision, const u64 *data, std::string file_prefix) {
std::string filter_name = FilterAPI<Table>::get_name(wrap_filter);
std::string file_name = file_prefix + filter_name;
std::cout << "file_name: " << file_name << std::endl;
std::fstream file(file_name, std::fstream::in | std::fstream::out | std::fstream::app);
file << endl;
// std::fstream file(file_name, std::fstream::in | std::fstream::out | std::fstream::trunc);
file << "# This is a comment." << std::endl;
file << "NAME\t" << filter_name << std::endl;
file << "INIT_TIME(NANO_SECOND)\t" << init_time << std::endl;
file << "FILTER_MAX_CAPACITY\t" << filter_max_capacity << std::endl;
file << "BYTE_SIZE\t" << FilterAPI<Table>::get_byte_size(wrap_filter) << std::endl;
file << "NUMBER_OF_LOOKUP\t" << lookup_reps << std::endl;
file << std::endl;
file << "# add, uniform lookup, true_lookup, deletions. Each columns unit is in nano second." << std::endl;
file << std::endl;
file << "BENCH_START" << std::endl;
for (size_t i = 0; i < bench_precision; i++) {
size_t index = i * 4;
file << data[index];
for (size_t j = 1; j < 4; j++) {
file << ", " << data[index + j];
}
file << std::endl;
}
file << std::endl;
file << "BENCH_END" << std::endl;
file << "END_OF_FILE!" << std::endl;
file.close();
}
template<typename Table>
void write_build_res_to_file(const Table *wrap_filter, size_t init_time, size_t built_time, size_t filter_max_capacity, std::string file_prefix) {
std::string filter_name = FilterAPI<Table>::get_name(wrap_filter);
std::string file_name = file_prefix + filter_name;
std::cout << "file_name: " << file_name << std::endl;
std::fstream file(file_name, std::fstream::in | std::fstream::out | std::fstream::app);
file << endl;
// std::fstream file(file_name, std::fstream::in | std::fstream::out | std::fstream::trunc);
file << "# This is a comment." << std::endl;
file << "# Results for build." << std::endl;
file << "NAME\t" << filter_name << std::endl;
file << "INIT_TIME(NANO_SECOND)\t" << init_time << std::endl;
file << "BUILT_TIME(NANO_SECOND)\t" << built_time << std::endl;
file << "FILTER_MAX_CAPACITY(Actually-number-of-items-in-the-filter)\t" << filter_max_capacity << std::endl;
file << "BYTE_SIZE\t" << FilterAPI<Table>::get_byte_size(wrap_filter) << std::endl;
file << std::endl;
file << "END_OF_FILE!" << std::endl;
file.close();
}
template<typename Table>
void bench_build_to_file(size_t filter_max_capacity, const std::vector<u64> *v_add, std::string file_prefix) {
auto t0 = std::chrono::high_resolution_clock::now();
Table filter = FilterAPI<Table>::ConstructFromAddCount(filter_max_capacity);
auto t1 = std::chrono::high_resolution_clock::now();
auto init_time = std::chrono::duration_cast<ns>(t1 - t0).count();
Table *wrap_filter = &filter;
std::string filter_name = FilterAPI<Table>::get_name(wrap_filter);
auto is_static = (FilterAPI<Table>::get_functionality(wrap_filter) == 1);
auto built_time = time_insertions(wrap_filter, v_add, 0, v_add->size());
write_build_res_to_file(wrap_filter, init_time, built_time, filter_max_capacity, file_prefix);
}
template<typename Table>
size_t bench_build_to_file22(size_t filter_max_capacity, const std::vector<u64> *v_add) {
auto t0 = std::chrono::high_resolution_clock::now();
Table filter = FilterAPI<Table>::ConstructFromAddCount(filter_max_capacity);
auto t1 = std::chrono::high_resolution_clock::now();
auto init_time = std::chrono::duration_cast<ns>(t1 - t0).count();
Table *wrap_filter = &filter;
// std::string filter_name = FilterAPI<Table>::get_name(wrap_filter);
// auto is_static = (FilterAPI<Table>::get_functionality(wrap_filter) == 1);
auto built_time = time_insertions(wrap_filter, v_add, 0, v_add->size());
return built_time;
}
//////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////
/* template<class Table, typename ItemType>
size_t count_finds(Table *wrap_filter, const std::vector<ItemType> *vec) {
size_t counter = 0;
for (size_t i = 0; i < vec->size(); i++) { counter += FilterAPI<Table>::Contain(vec->at(i), wrap_filter);
}
return counter;
} */
template<class Table>
size_t count_finds(const Table *wrap_filter, const std::vector<u64> *vec) {
size_t counter = 0;
for (size_t i = 0; i < vec->size(); i++) { counter += FilterAPI<Table>::Contain(vec->at(i), wrap_filter); }
return counter;
}
/**
* @brief Get the FPR (false positive probability) test0 object.
*
* @tparam Table
* @param wrap_filter
* @param yes_vec
* @return std::tuple<size_t, size_t>
*/
template<class Table>
size_t get_FPR_test0(Table *wrap_filter, const std::vector<u64> *v_add, const std::vector<u64> *v_find) {
/**Insertion*/
for (auto el : *v_add) {
FilterAPI<Table>::Add(el, wrap_filter);
}
size_t counter = 0;
for (auto el : *v_add) {
counter++;
if (!FilterAPI<Table>::Contain(el, wrap_filter)) {
auto name = FilterAPI<Table>::get_name(wrap_filter);
std::cout << "Filter (" << name << ") has2 a false negative. exiting." << std::endl;
std::cout << "counter: \t" << counter << std::endl;
FilterAPI<Table>::Contain(el, wrap_filter);
assert(0);
exit(-42);
}
}
size_t yes_res = count_finds(wrap_filter, v_find);
return yes_res;
}
template<class Table>
void FPR_test0_after_build(const Table *wrap_filter, const std::vector<u64> *v_add, const std::vector<u64> *v_find, size_t bench_precision) {
// Table filter = FilterAPI<Table>::ConstructFromAddCount(v_add->size());
// Table *wrap_filter = &filter;
size_t counter = 0;
const size_t lim = v_add->size() / bench_precision * bench_precision;
for (auto el : *v_add) {
counter++;
if (counter >= lim)
break;
if (!FilterAPI<Table>::Contain(el, wrap_filter)) {
auto name = FilterAPI<Table>::get_name(wrap_filter);
std::cout << "Filter (" << name << ") has3 a false negative. exiting." << std::endl;
std::cout << "counter: \t" << counter << std::endl;
FilterAPI<Table>::Contain(el, wrap_filter);
assert(0);
exit(-42);
}
}
size_t yes_res = count_finds(wrap_filter, v_find);
// auto yes_res = get_FPR_test0(wrap_filter, v_add, v_find);
auto s = FPR_parse_data_str_22(wrap_filter, v_add, v_find, yes_res);
std::cout << "s:\n"
<< s << std::endl;
// FPR_printer(wrap_filter, v_add, v_find, yes_res);
}
template<class Table>
std::string FPR_parse_data_str_22(const Table *wrap_filter, const std::vector<u64> *v_add, const std::vector<u64> *v_find, size_t yes_res) {
size_t true_counter = yes_res;
// size_t true_counter = yes_res;
assert(true_counter <= v_find->size());
size_t false_counter = v_find->size() - yes_res;
const size_t filter_max_capacity = v_add->size();
const size_t filter_true_cap = FilterAPI<Table>::get_cap(wrap_filter);
auto filter_id = FilterAPI<Table>::get_ID(wrap_filter);
bool skip = (filter_id == BBF) or (filter_id == SIMD_fixed);
if ((!skip) and (filter_max_capacity != filter_true_cap)) {
std::cout << "filter_name: \t" << FilterAPI<Table>::get_name(wrap_filter) << std::endl;
std::cout << "filter_max_cap: \t" << filter_max_capacity << std::endl;
std::cout << "filter_true_cap: \t" << filter_true_cap << std::endl;
}
std::string filter_name = FilterAPI<Table>::get_name(wrap_filter);
const size_t filter_byte_size = FilterAPI<Table>::get_byte_size(wrap_filter);
double positive_ratio = 1.0 * true_counter / (false_counter + true_counter);
double bpi = filter_byte_size * 8.0 / filter_max_capacity;
double optimal_bits_for_err = -log2(positive_ratio);
double bpi_diff = (bpi - optimal_bits_for_err);
double bpi_ratio = (bpi / optimal_bits_for_err);
double fpp_mult_factor = positive_ratio / (1.0 / 256);
double data[] = {positive_ratio, bpi, optimal_bits_for_err, bpi_diff, bpi_ratio, fpp_mult_factor};
std::stringstream ss;
ss << std::setw(34) << std::left << filter_name << "\t, " << std::setw(12) << std::left << filter_byte_size;
for (auto &&x : data) { ss << ", " << std::setw(12) << std::left << x; }
ss << std::endl;
std::string line = ss.str();
return line;
}
template<class Table>
std::string FPR_test_as_str(Table *wrap_filter, const std::vector<u64> *v_add, const std::vector<u64> *v_find) {
auto yes_res = get_FPR_test0(wrap_filter, v_add, v_find);
size_t true_counter = yes_res;
assert(true_counter <= v_find->size());
size_t false_counter = v_find->size() - yes_res;
const size_t filter_max_capacity = v_add->size();
const size_t filter_true_cap = FilterAPI<Table>::get_cap(wrap_filter);
auto filter_id = FilterAPI<Table>::get_ID(wrap_filter);
bool skip = (filter_id == BBF) or (filter_id == SIMD_fixed);
if ((!skip) and (filter_max_capacity != filter_true_cap)) {
// UNCOMMENT ME!!! FIXME!!!
std::cout << "filter_name: \t" << FilterAPI<Table>::get_name(wrap_filter) << std::endl;
std::cout << "filter_max_cap: \t" << filter_max_capacity << std::endl;
std::cout << "filter_true_cap: \t" << filter_true_cap << std::endl;
}
std::string filter_name = FilterAPI<Table>::get_name(wrap_filter);
const size_t filter_byte_size = FilterAPI<Table>::get_byte_size(wrap_filter);
double positive_ratio = 1.0 * true_counter / (false_counter + true_counter);
double bpi = filter_byte_size * 8.0 / filter_max_capacity;
double optimal_bits_for_err = -log2(positive_ratio);
double bpi_diff = (bpi - optimal_bits_for_err);
double bpi_ratio = (bpi / optimal_bits_for_err);
// double fpp_mult_factor = positive_ratio / (1.0 / 256);
double data[] = {positive_ratio, bpi, optimal_bits_for_err, bpi_diff, bpi_ratio};
std::stringstream ss;
ss << std::setw(34) << std::left << filter_name << "\t, " << std::setw(12) << std::left << filter_byte_size;
for (auto &&x : data) { ss << ", " << std::setw(12) << std::left << x; }
ss << std::endl;
std::string line = ss.str();
return line;
// std::cout << line;// << std::endl;
}
template<class Table>
void FPR_test(const std::vector<u64> *v_add, const std::vector<u64> *v_find, std::string path, bool create_file = false) {
const size_t filter_max_capacity = v_add->size();
Table filter = FilterAPI<Table>::ConstructFromAddCount(v_add->size());
Table *wrap_filter = &filter;
auto line = FPR_test_as_str(wrap_filter, v_add, v_find);
std::fstream file(path, std::fstream::in | std::fstream::out | std::fstream::app);
file << line;
file.close();
// std::cout << line << std::endl;
}
template<class Table>
void profile_benchmark(Table *wrap_filter, const std::vector<const std::vector<u64> *> *elements) {
auto add_vec = elements->at(0);
auto find_vec = elements->at(1);
auto delete_vec = elements->at(2);
auto insertion_time = time_insertions(wrap_filter, add_vec, 0, add_vec->size());
printf("insertions done\n");
fflush(stdout);
ulong uniform_lookup_time = 0;
ulong true_lookup_time = 0;
// size_t true_lookup_time = 0;
char buf[1024];
// sprintf(buf, "perf record -p %d &", getpid());
// sprintf(buf, "perf stat -p %d -e cycles -e instructions -e cache-misses -e cache-references -e L1-dcache-load-misses -e L1-dcache-loads -e LLC-load-misses -e LLC-loads -e dTLB-load-misses -e dTLB-loads -e node-load-misses -e node-loads -e branches -e branch-misses &", getpid());
sprintf(buf, "perf stat -p %d \
-e cycles \
-e instructions \
-e cache-misses \
-e cache-references \
-e L1-dcache-load-misses \
-e L1-dcache-loads \
-e LLC-load-misses \
-e LLC-loads \
-e dTLB-load-misses \
-e dTLB-loads \
-e node-load-misses \
-e node-loads \
-e alignment-faults \
-e branches \
-e branch-misses \
-e branch-loads \
-e branch-loads-misses \
&",
getpid());
// sprintf(buf, "perf stat -p %d -e cycles -e instructions -e cache-misses -e cache-references -e L1-dcache-load-misses -e L1-dcache-loads -e LLC-load-misses -e LLC-loads -e dTLB-load-misses -e dTLB-loads -e node-load-misses -e node-loads -e branches -e branch-misses -e uops_executed.stall_cycles &", getpid());
auto junk = system(buf);
for (int i = 0; i < 16; i++) {
// true_lookup_time = time_lookups(wrap_filter, add_vec, 0, add_step);
uniform_lookup_time += time_lookups(wrap_filter, find_vec, 0, find_vec->size());
// true_lookup_time += time_lookups(wrap_filter, add_vec, 0, add_vec->size());
// uniform_lookup_time += time_lookups(wrap_filter, find_vec, 0, find_vec->size());
}
// printf("%zd\n", 500 * add_step);
printf("%zd\n", 16 * find_vec->size());
// printf("%zd\n", 16 * add_vec->size());
// printf("%zd\n", 8 * find_vec->size() + 8 * add_vec->size() );
// printf("%zd\n", 500 * true_find_step);
exit(0);
}
inline std::string get_int_with_commas(uint64_t x) {
auto s = std::to_string(x);
if (s.size() <= 3)
return s;
std::string res;
std::string prefix = s;
// const size_t s_size = s.size();
while (prefix.size() > 3) {
size_t index = prefix.size() - 3;
std::string temp = prefix.substr(index, 3);
res = "," + temp + res;
prefix = prefix.substr(0, index);
}
res = prefix + res;
return res;
}
template<class Table>
void profile_benchmark_cache(Table *wrap_filter, const std::vector<const std::vector<u64> *> *elements) {
auto add_vec = elements->at(0);
auto find_vec = elements->at(1);
// auto delete_vec = elements->at(2);
auto insertion_time = time_insertions(wrap_filter, add_vec, 0, add_vec->size());
printf("insertions done\n");
fflush(stdout);
ulong uniform_lookup_time = 0;
// ulong true_lookup_time = 0;
// size_t true_lookup_time = 0;
char buf[1024];
// sprintf(buf, "perf stat -p %d
sprintf(buf, "perf stat -p %d \
-e cpu/event=0x2e,umask=0x41,name=LONGEST_LAT_CACHE.MISS/ \
& ",
getpid());
/* -e cache-misses \
-e cache-references \
-e L1-dcache-load-misses \
-e L1-dcache-loads \
-e LLC-load-misses \
-e LLC-loads \
-e dTLB-load-misses \
-e dTLB-loads \
-e node-load-misses \
-e node-loads \
-e branches \
-e branch-misses \
*/
auto junk = system(buf);
constexpr size_t reps = 16;
for (size_t i = 0; i < reps; i++) {
uniform_lookup_time += time_lookups(wrap_filter, find_vec, 0, find_vec->size());
}
// printf("%zd\n", 16 * find_vec->size());
std::cout << "Number of lookups: \t" << get_int_with_commas(reps * find_vec->size()) << std::endl;
printf("Number of lookups: %zd\n", reps * find_vec->size());
exit(0);
}
}// namespace testSmart
#endif// FILTERS_CON_TESTS_HPP

959
Tests/wrappers.hpp Normal file
View File

@ -0,0 +1,959 @@
/* Taken from
* https://github.com/FastFilter/fastfilter_cpp
* */
//#pragma once
#ifndef FILTERS_WRAPPERS_HPP
#define FILTERS_WRAPPERS_HPP
// #define CONTAIN_ATTRIBUTES inline
#define CONTAIN_ATTRIBUTES __attribute__((always_inline))
// #define CONTAIN_ATTRIBUTES __attribute__((noinline))
#include <stdexcept>
#include "../Bloom_Filter/bloom.hpp"
#include "../Bloom_Filter/simd-block-fixed-fpp.h"
#include "../Bloom_Filter/Impala512.h"
#include "../Bloom_Filter/simd-block.h"
#include "../Prefix-Filter/min_pd256.hpp"
#include "../TC-Shortcut/TC-shortcut.hpp"
#include "../cuckoofilter/src/cuckoofilter.h"
#include "../cuckoofilter/src/cuckoofilter_stable.h"
// #include "linux-perf-events.h"
#include <map>
enum filter_id {
Trivial_id,
CF,
SIMD,
BBF,
BBF_gen_id,
SIMD_fixed,
BBF_Flex,
prefix_id,
TC_shortcut_id,
VQF_Wrapper_id,
cf1ma_id,
cf3ma_id,
cf_stable_id,
cf_flex_id,
bloom_id,
bf_ma_id,
bloomSimple_id,
bloomTrivial_id,
bloomPower_id,
bloomPowerDoubleHash_id,
simple_bbf_id,
};
template<typename Table>
struct FilterAPI {
};
class TrivialFilter {
public:
TrivialFilter(size_t max_items) {
}
__attribute__((always_inline)) inline static constexpr uint16_t fixed_reduce(uint16_t hash) {
// http://lemire.me/blog/2016/06/27/a-fast-alternative-to-the-modulo-reduction/
return (uint16_t) (((uint32_t) hash * 6400) >> 16);
}
inline auto Find(const u64 &item) const -> bool {
return true;
}
void Add(const u64 &item) {}
auto get_capacity() const -> size_t {
return -1;
}
auto get_name() const -> std::string {
return "Trivial-Filter ";
}
auto get_byte_size() const -> size_t {
return 0;
}
auto get_cap() const -> size_t {
return -1;
}
};
template<>
struct FilterAPI<TrivialFilter> {
using Table = TrivialFilter;
static Table ConstructFromAddCount(size_t add_count) {
return Table(add_count);
}
static void Add(uint64_t key, Table *table) {
table->Add(key);
}
CONTAIN_ATTRIBUTES static bool Contain(uint64_t key, const Table *table) {
return table->Find(key);
}
static void Remove(uint64_t key, Table *table) {
throw std::runtime_error("Unsupported");
}
static std::string get_name(const Table *table) {
return table->get_name();
}
static auto get_functionality(const Table *table) -> uint32_t {
return 0;
}
static auto get_ID(const Table *table) -> filter_id {
return Trivial_id;
}
static size_t get_byte_size(const Table *table) {
return table->get_byte_size();
}
static size_t get_cap(const Table *table) {
return table->get_cap();
}
};
template<typename ItemType, size_t bits_per_item, template<size_t> class TableType, typename HashFamily>
struct FilterAPI<cuckoofilter::CuckooFilter<ItemType, bits_per_item, TableType, HashFamily>> {
using Table = cuckoofilter::CuckooFilter<ItemType, bits_per_item, TableType, HashFamily>;
static Table ConstructFromAddCount(size_t add_count) {
return Table(add_count);
}
static void Add(uint64_t key, Table *table) {
if (table->Add(key) != cuckoofilter::Ok) {
std::cerr << "Cuckoo filter is too full. Insertion of the element (" << key << ") failed.\n";
std::cout << get_info(table).str() << std::endl;
throw std::logic_error("The filter is too small to hold all of the elements");
}
}
static bool Add_attempt(uint64_t key, Table *table) {
if (table->Add(key) != cuckoofilter::Ok) {
std::cout << get_info(table).str() << std::endl;
return false;
// throw std::logic_error("The filter is too small to hold all of the elements");
}
return true;
}
static void Remove(uint64_t key, Table *table) {
table->Delete(key);
}
CONTAIN_ATTRIBUTES static bool Contain(uint64_t key, const Table *table) {
return (0 == table->Contain(key));
}
static std::string get_name(const Table *table) {
auto ss = table->Info();
std::string temp = "PackedHashtable";
if (ss.find(temp) != std::string::npos) {
return "CF-ss";
}
if (bits_per_item == 8) {
// return "Cuckoo-8-mod-m1";
return "Cuckoo-8";
} else if (bits_per_item == 12) {
return "Cuckoo-12";
// return "Cuckoo-12-mod-m1";
} else if (bits_per_item == 16)
return "Cuckoo-16";
else if (bits_per_item == 32) {
return "Cuckoo-32";
}
return "Cuckoo-?";
// return "Cuckoo-" + std::to_string(bits_per_item);
}
static auto get_info(const Table *table) -> std::stringstream {
std::string state = table->Info();
std::stringstream ss;
ss << state;
return ss;
// std::cout << state << std::endl;
}
/**
* Returns int indicating which function can the filter do.
* 1 is for lookups.
* 2 is for adds.
* 4 is for deletions.
*/
static auto get_functionality(const Table *table) -> uint32_t {
return 7;
}
static auto get_ID(const Table *table) -> filter_id {
return CF;
}
static size_t get_byte_size(const Table *table) {
return table->SizeInBytes();
}
static size_t get_cap(const Table *table) {
return table->get_cap();
}
};
template<typename ItemType, size_t bits_per_item, template<size_t> class TableType, typename HashFamily>
struct FilterAPI<cuckoofilter::CuckooFilterStable<ItemType, bits_per_item, TableType, HashFamily>> {
using Table = cuckoofilter::CuckooFilterStable<ItemType, bits_per_item, TableType, HashFamily>;
static Table ConstructFromAddCount(size_t add_count) {
return Table(add_count);
}
static void Add(uint64_t key, Table *table) {
if (table->Add(key) != cuckoofilter::Ok) {
std::cerr << "Stable Cuckoo filter is too full. Insertion of the element (" << key << ") failed.\n";
std::cout << get_info(table).str() << std::endl;
throw std::logic_error("The filter is too small to hold all of the elements");
}
}
static void Remove(uint64_t key, Table *table) {
table->Delete(key);
}
CONTAIN_ATTRIBUTES static bool Contain(uint64_t key, const Table *table) {
return (0 == table->Contain(key));
}
static std::string get_name(const Table *table) {
auto ss = table->Info();
std::string temp = "PackedHashtable";
if (ss.find(temp) != std::string::npos) {
return "CF-ss";
}
if (bits_per_item == 8) {
// return "Cuckoo-8-mod-m1";
return "CuckooStable-8";
} else if (bits_per_item == 12) {
return "CuckooStable-12";
} else if (bits_per_item == 16)
return "CuckooStable-16";
else if (bits_per_item == 32) {
return "CuckooStable-32";
}
return "Cuckoo-?";
}
static auto get_info(const Table *table) -> std::stringstream {
std::string state = table->Info();
std::stringstream ss;
ss << state;
return ss;
// std::cout << state << std::endl;
}
/**
* Returns int indicating which function can the filter do.
* 1 is for lookups.
* 2 is for adds.
* 4 is for deletions.
*/
static auto get_functionality(const Table *table) -> uint32_t {
return 7;
}
static auto get_ID(const Table *table) -> filter_id {
return cf_stable_id;
}
static size_t get_byte_size(const Table *table) {
return table->SizeInBytes();
}
static size_t get_cap(const Table *table) {
return table->get_cap();
}
static double get_eLoad(const Table *table) {
return table->get_effective_load();
}
};
template<>
struct FilterAPI<SimdBlockFilter<>> {
using Table = SimdBlockFilter<>;
static Table ConstructFromAddCount(size_t add_count) {
Table ans(ceil(log2(add_count * 8.0 / CHAR_BIT)));
return ans;
}
static void Add(uint64_t key, Table *table) {
table->Add(key);
}
CONTAIN_ATTRIBUTES static bool Contain(uint64_t key, const Table *table) {
return table->Find(key);
}
static void Remove(uint64_t key, Table *table) {
throw std::runtime_error("Unsupported");
}
static std::string get_name(const Table *table) {
return "SimdBlockFilter";
}
static auto get_info(const Table *table) -> std::stringstream {
assert(false);
std::stringstream ss;
return ss;
}
/**
* Returns int indicating which function can the filter do.
* 1 is for lookups.
* 2 is for adds.
* 4 is for deletions.
*/
static auto get_functionality(const Table *table) -> uint32_t {
return 3;
}
static auto get_ID(const Table *table) -> filter_id {
return BBF;
}
static size_t get_byte_size(const Table *table) {
return table->SizeInBytes();
}
static size_t get_cap(const Table *table) {
return table->get_cap();
}
};
template<>
struct FilterAPI<SimdBlockFilterFixed<>> {
using Table = SimdBlockFilterFixed<>;
static Table ConstructFromAddCount(size_t add_count) {
Table ans(ceil(add_count * 8.0 / CHAR_BIT));
return ans;
}
static void Add(uint64_t key, Table *table) {
table->Add(key);
}
CONTAIN_ATTRIBUTES static bool Contain(uint64_t key, const Table *table) {
return table->Find(key);
}
static void Remove(uint64_t key, Table *table) {
throw std::runtime_error("Unsupported");
}
static std::string get_name(const Table *table) {
return "BBF-Fixed";
}
static auto get_info(const Table *table) -> std::stringstream {
assert(false);
std::stringstream ss;
return ss;
}
/**
* Returns int indicating which function can the filter do.
* 1 is for lookups.
* 2 is for adds.
* 4 is for deletions.
*/
static auto get_functionality(const Table *table) -> uint32_t {
return 3;
}
static auto get_ID(const Table *table) -> filter_id {
return SIMD_fixed;
}
static size_t get_byte_size(const Table *table) {
return table->SizeInBytes();
}
static size_t get_cap(const Table *table) {
return table->get_cap();
}
};
template<>
struct FilterAPI<Impala512<>> {
using Table = Impala512<>;
static Table ConstructFromAddCount(size_t add_count) {
return Table(add_count);
// return ans;
}
static void Add(uint64_t key, Table *table) {
table->Add(key);
}
CONTAIN_ATTRIBUTES static bool Contain(uint64_t key, const Table *table) {
return table->Find(key);
}
static void Remove(uint64_t key, Table *table) {
throw std::runtime_error("Unsupported");
}
static std::string get_name(const Table *table) {
return "Impala512";
}
static auto get_info(const Table *table) -> std::stringstream {
assert(false);
std::stringstream ss;
return ss;
}
/**
* Returns int indicating which function can the filter do.
* 1 is for lookups.
* 2 is for adds.
* 4 is for deletions.
*/
static auto get_functionality(const Table *table) -> uint32_t {
return 3;
}
static auto get_ID(const Table *table) -> filter_id {
return SIMD_fixed;
}
static size_t get_byte_size(const Table *table) {
return table->SizeInBytes();
}
static size_t get_cap(const Table *table) {
return table->get_cap();
}
};
template<>
struct FilterAPI<TC_shortcut> {
using Table = TC_shortcut;
// using Table = dict512<TableType, spareItemType, itemType>;
static Table ConstructFromAddCount(size_t add_count) {
constexpr float load = .935;
return Table(add_count, load);
}
static void Add(uint64_t key, Table *table) {
if (!table->insert(key)) {
std::cout << table->info() << std::endl;
// std::cout << "max_load: \t" << 0.945 << std::endl;
throw std::logic_error(table->get_name() + " is too small to hold all of the elements");
}
}
static bool Add_attempt(uint64_t key, Table *table) {
if (!table->insert(key)) {
std::cout << "load when failed: \t" << table->get_effective_load() << std::endl;
std::cout << table->info() << std::endl;
return false;
}
return true;
}
static void Remove(uint64_t key, Table *table) {
// throw std::runtime_error("Unsupported");
table->remove(key);
}
CONTAIN_ATTRIBUTES static bool Contain(uint64_t key, const Table *table) {
// std::cout << "here!!!" << std::endl;
return table->lookup(key);
// return table->lookup_consecutive_only_body(key);
// return table->lookup_consecutive(key);
}
static std::string get_name(const Table *table) {
return table->get_name();
}
static auto get_info(const Table *table) -> std::stringstream {
std::stringstream ss;
ss << "";
return ss;
// return table->get_extended_info();
}
static auto get_functionality(const Table *table) -> uint32_t {
return 7;
}
static auto get_ID(const Table *table) -> filter_id {
return TC_shortcut_id;
}
static size_t get_byte_size(const Table *table) {
return table->get_byte_size();
}
static size_t get_cap(const Table *table) {
return table->get_cap();
}
static double get_eLoad(const Table *table) {
return table->get_effective_load();
}
};
template<typename Table>
inline size_t get_l2_slots(size_t l1_items, const double overflowing_items_ratio, const float loads[2]) {
const double expected_items_reaching_next_level = l1_items * overflowing_items_ratio;
size_t slots_in_l2 = (expected_items_reaching_next_level / loads[1]);
return slots_in_l2;
}
template<>
inline size_t get_l2_slots<cuckoofilter::CuckooFilterStable<u64, 12>>(size_t l1_items, const double overflowing_items_ratio, const float loads[2]) {
// const double expected_items_reaching_next_level = l1_items * 0.0752;
// const double spare_workload = 0.0752 / 0.0586;
// size_t slots_in_l2 = std::ceil(expected_items_reaching_next_level);
// return slots_in_l2;
constexpr auto expected_items95 = 0.0586;
constexpr auto expected_items100 = 0.07952;
constexpr auto expected_items105 = 0.1031;
constexpr auto spare_workload = 0.94;
constexpr auto safety = 1.08;
constexpr auto factor95 = safety * expected_items95 / spare_workload;
constexpr auto factor100 = safety * expected_items100 / spare_workload;
constexpr auto factor105 = safety * expected_items105 / spare_workload;
// const double expected_items_reaching_next_level = l1_items * (0.06 / 0.9);
const double expected_items_reaching_next_level = l1_items * factor95;
return expected_items_reaching_next_level;
}
template<>
inline size_t get_l2_slots<TC_shortcut>(size_t l1_items, const double overflowing_items_ratio, const float loads[2]) {
constexpr auto expected_items95 = 0.0586;
constexpr auto expected_items100 = 0.07952;
constexpr auto expected_items105 = 0.1031;
constexpr auto spare_workload = 0.935;
constexpr auto safety = 1.08;
constexpr auto factor95 = safety * expected_items95 / spare_workload;
constexpr auto factor100 = safety * expected_items100 / spare_workload;
constexpr auto factor105 = safety * expected_items105 / spare_workload;
// const double expected_items_reaching_next_level = l1_items * (0.06 / 0.9);
const double expected_items_reaching_next_level = l1_items * factor95;
size_t slots_in_l2 = std::ceil(expected_items_reaching_next_level);
return slots_in_l2;
}
template<>
inline size_t get_l2_slots<SimdBlockFilter<>>(size_t l1_items, const double overflowing_items_ratio, const float loads[2]) {
const double expected_items_reaching_next_level = l1_items * overflowing_items_ratio;
size_t slots_in_l2 = (expected_items_reaching_next_level / loads[1]);
return slots_in_l2 * 4;
}
template<>
inline size_t get_l2_slots<SimdBlockFilterFixed<>>(size_t l1_items, const double overflowing_items_ratio, const float loads[2]) {
const double expected_items_reaching_next_level = l1_items * overflowing_items_ratio;
size_t slots_in_l2 = (expected_items_reaching_next_level / loads[1]);
return slots_in_l2 * 2;
}
template<>
inline size_t get_l2_slots<Impala512<>>(size_t l1_items, const double overflowing_items_ratio, const float loads[2]) {
constexpr auto expected_items95 = 0.0586;
constexpr auto expected_items100 = 0.07952;
constexpr auto expected_items105 = 0.1031;
constexpr auto spare_workload = 1;
constexpr auto safety = 1.08;
constexpr auto factor95 = safety * expected_items95 / spare_workload;
constexpr auto factor100 = safety * expected_items100 / spare_workload;
constexpr auto factor105 = safety * expected_items105 / spare_workload;
// const double expected_items_reaching_next_level = l1_items * (0.06 / 0.9);
const double expected_items_reaching_next_level = l1_items * factor95;
size_t slots_in_l2 = std::ceil(expected_items_reaching_next_level);
return slots_in_l2;
}
template<typename Table>
class Prefix_Filter {
const size_t filter_max_capacity;
const size_t number_of_pd;
size_t cap[2] = {0};
hashing::TwoIndependentMultiplyShift Hasher, H0;
__m256i *pd_array;
Table GenSpare;
static double constexpr overflowing_items_ratio = 0.0586;// = expected_items95
public:
Prefix_Filter(size_t max_items, const float loads[2])
: filter_max_capacity(max_items),
number_of_pd(std::ceil(1.0 * max_items / (min_pd::MAX_CAP0 * loads[0]))),
GenSpare(FilterAPI<Table>::ConstructFromAddCount(get_l2_slots<Table>(max_items, overflowing_items_ratio, loads))),
Hasher(), H0() {
int ok = posix_memalign((void **) &pd_array, 32, 32 * number_of_pd);
if (ok != 0) {
std::cout << "Space allocation failed!" << std::endl;
assert(false);
exit(-3);
}
constexpr uint64_t pd256_plus_init_header = (((INT64_C(1) << min_pd::QUOTS) - 1) << 6) | 32;
std::fill(pd_array, pd_array + number_of_pd, __m256i{pd256_plus_init_header, 0, 0, 0});
// size_t l1 = sizeof(__m256i) * number_of_pd;
// size_t l2 = FilterAPI<Table>::get_byte_size(&GenSpare);
// double ratio = 1.0 * l2 / l1;
// std::cout << get_name() << ".\t";
// std::cout << "spare-size / First level:\t\t " << ratio << std::endl;
}
~Prefix_Filter() {
free(pd_array);
}
__attribute__((always_inline)) inline static constexpr uint32_t reduce32(uint32_t hash, uint32_t n) {
// http://lemire.me/blog/2016/06/27/a-fast-alternative-to-the-modulo-reduction/
return (uint32_t) (((uint64_t) hash * n) >> 32);
}
__attribute__((always_inline)) inline static constexpr uint16_t fixed_reduce(uint16_t hash) {
// http://lemire.me/blog/2016/06/27/a-fast-alternative-to-the-modulo-reduction/
return (uint16_t) (((uint32_t) hash * 6400) >> 16);
}
inline auto Find(const u64 &item) const -> bool {
const u64 s = H0(item);
uint32_t out1 = s >> 32u, out2 = s;
const uint32_t pd_index = reduce32(out1, (uint32_t) number_of_pd);
const uint16_t qr = fixed_reduce(out2);
const int64_t quot = qr >> 8;
const uint8_t rem = qr;
// return min_pd::pd_find_25(quot, rem, &pd_array[pd_index]);
// return (!min_pd::cmp_qr1(qr, &pd_array[pd_index])) ? min_pd::pd_find_25(quot, rem, &pd_array[pd_index])
return (!min_pd::cmp_qr1(qr, &pd_array[pd_index])) ? min_pd::find_core(quot, rem, &pd_array[pd_index])
: incSpare_lookup(pd_index, qr);
}
inline auto incSpare_lookup(size_t pd_index, u16 qr) const -> bool {
const u64 data = (pd_index << 13u) | qr;
// u64 hashed_res = Hasher(data);
return FilterAPI<Table>::Contain(data, &GenSpare);
}
inline void incSpare_add(size_t pd_index, const min_pd::add_res &a_info) {
cap[1]++;
u16 qr = (((u16) a_info.quot) << 8u) | a_info.rem;
const u64 data = (pd_index << 13u) | qr;
// u64 hashed_res = Hasher(data);
return FilterAPI<Table>::Add(data, &GenSpare);
}
void Add(const u64 &item) {
const u64 s = H0(item);
constexpr u64 full_mask = (1ULL << 55);
uint32_t out1 = s >> 32u, out2 = s;
const uint32_t pd_index = reduce32(out1, (uint32_t) number_of_pd);
auto pd = pd_array + pd_index;
const uint64_t header = reinterpret_cast<const u64 *>(pd)[0];
const bool not_full = !(header & full_mask);
const uint16_t qr = fixed_reduce(out2);
const int64_t quot = qr >> 8;
const uint8_t rem = qr;
if (not_full) {
cap[0]++;
assert(!min_pd::is_pd_full(pd));
size_t end = min_pd::select64(header >> 6, quot);
assert(min_pd::check::val_header(pd));
const size_t h_index = end + 6;
const u64 mask = _bzhi_u64(-1, h_index);
const u64 lo = header & mask;
const u64 hi = ((header & ~mask) << 1u);// & h_mask;
assert(!(lo & hi));
const u64 h7 = lo | hi;
memcpy(pd, &h7, 7);
assert(min_pd::check::val_header(pd));
const size_t body_index = end - quot;
min_pd::body_add_case0_avx(body_index, rem, pd);
// auto mp = (u8 *) pd + 7 + body_index;
// const size_t b2m = (32 - 7) - (body_index + 1);
// memmove(mp + 1, mp, b2m);
// mp[0] = rem;
assert(min_pd::find_core(quot, rem, pd));
assert(Find(item));
return;
} else {
auto add_res = min_pd::new_pd_swap_short(quot, rem, pd);
assert(min_pd::check::val_last_quot_is_sorted(pd));
incSpare_add(pd_index, add_res);
assert(Find(item));
}
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////// Validation functions.////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
auto get_capacity() const -> size_t {
size_t res = 0;
for (size_t i = 0; i < number_of_pd; ++i) {
res += min_pd::get_capacity(&pd_array[i]);
}
assert(res == cap[0]);
return res;
}
auto get_name() const -> std::string {
std::string s0 = "Prefix-Filter ";
std::string s1 = FilterAPI<Table>::get_name(&GenSpare);
return s0 + "[ " + s1 + " ]";
}
auto count_overflowing_PDs() -> size_t {
size_t count_overflowing_PD = 0;
for (int i = 0; i < number_of_pd; ++i) {
bool add_cond = min_pd::pd_full(&pd_array[i]);
count_overflowing_PD += add_cond;
bool is_full = min_pd::pd_full(&pd_array[i]);
// bool is_full2 = pd_vec[i]->is_full();
// assert(is_full == is_full2);
bool final = (!add_cond or is_full);
// assert(final);
}
return count_overflowing_PD;
}
auto count_empty_PDs() -> size_t {
size_t count_empty_PD = 0;
for (int i = 0; i < number_of_pd; ++i) {
bool add_cond = (min_pd::get_capacity(&pd_array[i]) <= 0);
count_empty_PD += add_cond;
}
return count_empty_PD;
}
auto get_byte_size() const -> size_t {
size_t l1 = sizeof(__m256i) * number_of_pd;
// size_t l2 = FilterAPI<Table>::get_byte_size(GenSpare);
size_t l2 = FilterAPI<Table>::get_byte_size(&GenSpare);
auto res = l1 + l2;
return res;
}
auto get_cap() const -> size_t {
return cap[0] + cap[1];
}
};
template<typename filterTable>
struct FilterAPI<Prefix_Filter<filterTable>> {
using Table = Prefix_Filter<filterTable>;
static Table ConstructFromAddCount(size_t add_count) {
constexpr float loads[2] = {.95, .95};
// std::cout << "Lower workload" << std::endl;
// std::cout << "Workload 1!" << std::endl;
return Table(add_count, loads);
}
static void Add(u64 key, Table *table) {
table->Add(key);
}
static void Remove(u64 key, Table *table) {
throw std::runtime_error("Unsupported");
}
CONTAIN_ATTRIBUTES static bool Contain(u64 key, const Table *table) {
return table->Find(key);
}
static std::string get_name(const Table *table) {
return table->get_name();
}
static auto get_functionality(const Table *table) -> uint32_t {
return 3;
}
static auto get_ID(const Table *table) -> filter_id {
return prefix_id;
}
static size_t get_byte_size(const Table *table) {
return table->get_byte_size();
}
static size_t get_cap(const Table *table) {
return table->get_cap();
}
};
template<typename ItemType,
size_t bits_per_item,
bool branchless,
typename HashFamily>
struct FilterAPI<bloomfilter::BloomFilter<ItemType, bits_per_item, branchless, HashFamily>> {
using Table = bloomfilter::BloomFilter<ItemType, bits_per_item, branchless, HashFamily>;
static Table ConstructFromAddCount(size_t add_count) {
return Table(add_count);
}
static void Add(uint64_t key, Table *table) {
table->Add(key);
}
static void Remove(uint64_t key, Table *table) {
throw std::runtime_error("Unsupported");
}
inline static bool Contain(uint64_t key, const Table *table) {
return table->Contain(key) == bloomfilter::Ok;
}
static std::string get_name(const Table *table) {
return table->get_name();
}
static auto get_info(const Table *table) -> std::stringstream {
assert(0);
std::stringstream ss;
return ss;
}
static auto get_functionality(const Table *table) -> uint32_t {
return 3;
}
static auto get_ID(const Table *table) -> filter_id {
return bloom_id;
}
static size_t get_byte_size(const Table *table) {
return table->SizeInBytes();
}
static size_t get_cap(const Table *table) {
return -1;
// return table->get_cap();
}
};
/*
// The statistics gathered for each table type:
struct Statistics {
size_t add_count;
double nanos_per_add;
double nanos_per_remove;
// key: percent of queries that were expected to be positive
map<int, double> nanos_per_finds;
double false_positive_probabilty;
double bits_per_item;
};
// Output for the first row of the table of results. type_width is the maximum number of
// characters of the description of any table type, and find_percent_count is the number
// of different lookup statistics gathered for each table. This function assumes the
// lookup expected positive probabiilties are evenly distributed, with the first being 0%
// and the last 100%.
inline string StatisticsTableHeader(int type_width, const std::vector<double> &found_probabilities) {
ostringstream os;
os << string(type_width, ' ');
os << setw(8) << right << "";
os << setw(8) << right << "";
for (size_t i = 0; i < found_probabilities.size(); ++i) {
os << setw(8) << "find";
}
os << setw(8) << "1*add+";
os << setw(8) << "" << setw(11) << "" << setw(11)
<< "optimal" << setw(8) << "wasted" << setw(8) << "million" << endl;
os << string(type_width, ' ');
os << setw(8) << right << "add";
os << setw(8) << right << "remove";
for (double prob : found_probabilities) {
os << setw(8 - 1) << static_cast<int>(prob * 100.0) << '%';
}
os << setw(8) << "3*find";
os << setw(9) << "ε%" << setw(11) << "bits/item" << setw(11)
<< "bits/item" << setw(8) << "space%" << setw(8) << "keys";
return os.str();
}
// Overloading the usual operator<< as used in "std::cout << foo", but for Statistics
template<class CharT, class Traits>
basic_ostream<CharT, Traits> &operator<<(
basic_ostream<CharT, Traits> &os, const Statistics &stats) {
os << fixed << setprecision(2) << setw(8) << right
<< stats.nanos_per_add;
double add_and_find = 0;
os << fixed << setprecision(2) << setw(8) << right
<< stats.nanos_per_remove;
for (const auto &fps : stats.nanos_per_finds) {
os << setw(8) << fps.second;
add_and_find += fps.second;
}
add_and_find = add_and_find * 3 / stats.nanos_per_finds.size();
add_and_find += stats.nanos_per_add;
os << setw(8) << add_and_find;
// we get some nonsensical result for very small fpps
if (stats.false_positive_probabilty > 0.0000001) {
const auto minbits = log2(1 / stats.false_positive_probabilty);
os << setw(8) << setprecision(4) << stats.false_positive_probabilty * 100
<< setw(11) << setprecision(2) << stats.bits_per_item << setw(11) << minbits
<< setw(8) << setprecision(1) << 100 * (stats.bits_per_item / minbits - 1)
<< " " << setw(7) << setprecision(3) << (stats.add_count / 1000000.);
} else {
os << setw(8) << setprecision(4) << stats.false_positive_probabilty * 100
<< setw(11) << setprecision(2) << stats.bits_per_item << setw(11) << 64
<< setw(8) << setprecision(1) << 0
<< " " << setw(7) << setprecision(3) << (stats.add_count / 1000000.);
}
return os;
}
struct samples {
double found_probability;
std::vector<uint64_t> to_lookup_mixed;
size_t true_match;
size_t actual_sample_size;
};
typedef struct samples samples_t;
*/
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,729 @@
{
"inputs" :
[
{
"path" : "CMakeLists.txt"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/snap/clion/184/bin/cmake/linux/share/cmake-3.21/Modules/CMakeDetermineSystem.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/snap/clion/184/bin/cmake/linux/share/cmake-3.21/Modules/CMakeSystem.cmake.in"
},
{
"isGenerated" : true,
"path" : "cmake-build-debug/CMakeFiles/3.21.1/CMakeSystem.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/snap/clion/184/bin/cmake/linux/share/cmake-3.21/Modules/CMakeSystemSpecificInitialize.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/snap/clion/184/bin/cmake/linux/share/cmake-3.21/Modules/CMakeDetermineCCompiler.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/snap/clion/184/bin/cmake/linux/share/cmake-3.21/Modules/CMakeDetermineCompiler.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/snap/clion/184/bin/cmake/linux/share/cmake-3.21/Modules/CMakeDetermineCompilerId.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/snap/clion/184/bin/cmake/linux/share/cmake-3.21/Modules/CMakeCompilerIdDetection.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/snap/clion/184/bin/cmake/linux/share/cmake-3.21/Modules/Compiler/ADSP-DetermineCompiler.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/snap/clion/184/bin/cmake/linux/share/cmake-3.21/Modules/Compiler/ARMCC-DetermineCompiler.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/snap/clion/184/bin/cmake/linux/share/cmake-3.21/Modules/Compiler/ARMClang-DetermineCompiler.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/snap/clion/184/bin/cmake/linux/share/cmake-3.21/Modules/Compiler/AppleClang-DetermineCompiler.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/snap/clion/184/bin/cmake/linux/share/cmake-3.21/Modules/Compiler/Clang-DetermineCompilerInternal.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/snap/clion/184/bin/cmake/linux/share/cmake-3.21/Modules/Compiler/Borland-DetermineCompiler.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/snap/clion/184/bin/cmake/linux/share/cmake-3.21/Modules/Compiler/Bruce-C-DetermineCompiler.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/snap/clion/184/bin/cmake/linux/share/cmake-3.21/Modules/Compiler/Clang-DetermineCompiler.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/snap/clion/184/bin/cmake/linux/share/cmake-3.21/Modules/Compiler/Clang-DetermineCompilerInternal.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/snap/clion/184/bin/cmake/linux/share/cmake-3.21/Modules/Compiler/Compaq-C-DetermineCompiler.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/snap/clion/184/bin/cmake/linux/share/cmake-3.21/Modules/Compiler/Cray-DetermineCompiler.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/snap/clion/184/bin/cmake/linux/share/cmake-3.21/Modules/Compiler/Embarcadero-DetermineCompiler.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/snap/clion/184/bin/cmake/linux/share/cmake-3.21/Modules/Compiler/Fujitsu-DetermineCompiler.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/snap/clion/184/bin/cmake/linux/share/cmake-3.21/Modules/Compiler/FujitsuClang-DetermineCompiler.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/snap/clion/184/bin/cmake/linux/share/cmake-3.21/Modules/Compiler/GHS-DetermineCompiler.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/snap/clion/184/bin/cmake/linux/share/cmake-3.21/Modules/Compiler/GNU-C-DetermineCompiler.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/snap/clion/184/bin/cmake/linux/share/cmake-3.21/Modules/Compiler/HP-C-DetermineCompiler.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/snap/clion/184/bin/cmake/linux/share/cmake-3.21/Modules/Compiler/IAR-DetermineCompiler.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/snap/clion/184/bin/cmake/linux/share/cmake-3.21/Modules/Compiler/Intel-DetermineCompiler.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/snap/clion/184/bin/cmake/linux/share/cmake-3.21/Modules/Compiler/IntelLLVM-DetermineCompiler.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/snap/clion/184/bin/cmake/linux/share/cmake-3.21/Modules/Compiler/MSVC-DetermineCompiler.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/snap/clion/184/bin/cmake/linux/share/cmake-3.21/Modules/Compiler/NVHPC-DetermineCompiler.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/snap/clion/184/bin/cmake/linux/share/cmake-3.21/Modules/Compiler/NVIDIA-DetermineCompiler.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/snap/clion/184/bin/cmake/linux/share/cmake-3.21/Modules/Compiler/OpenWatcom-DetermineCompiler.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/snap/clion/184/bin/cmake/linux/share/cmake-3.21/Modules/Compiler/PGI-DetermineCompiler.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/snap/clion/184/bin/cmake/linux/share/cmake-3.21/Modules/Compiler/PathScale-DetermineCompiler.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/snap/clion/184/bin/cmake/linux/share/cmake-3.21/Modules/Compiler/ROCMClang-DetermineCompiler.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/snap/clion/184/bin/cmake/linux/share/cmake-3.21/Modules/Compiler/SCO-DetermineCompiler.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/snap/clion/184/bin/cmake/linux/share/cmake-3.21/Modules/Compiler/SDCC-C-DetermineCompiler.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/snap/clion/184/bin/cmake/linux/share/cmake-3.21/Modules/Compiler/SunPro-C-DetermineCompiler.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/snap/clion/184/bin/cmake/linux/share/cmake-3.21/Modules/Compiler/TI-DetermineCompiler.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/snap/clion/184/bin/cmake/linux/share/cmake-3.21/Modules/Compiler/TinyCC-C-DetermineCompiler.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/snap/clion/184/bin/cmake/linux/share/cmake-3.21/Modules/Compiler/VisualAge-C-DetermineCompiler.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/snap/clion/184/bin/cmake/linux/share/cmake-3.21/Modules/Compiler/IBMCPP-C-DetermineVersionInternal.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/snap/clion/184/bin/cmake/linux/share/cmake-3.21/Modules/Compiler/Watcom-DetermineCompiler.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/snap/clion/184/bin/cmake/linux/share/cmake-3.21/Modules/Compiler/XL-C-DetermineCompiler.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/snap/clion/184/bin/cmake/linux/share/cmake-3.21/Modules/Compiler/IBMCPP-C-DetermineVersionInternal.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/snap/clion/184/bin/cmake/linux/share/cmake-3.21/Modules/Compiler/XLClang-C-DetermineCompiler.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/snap/clion/184/bin/cmake/linux/share/cmake-3.21/Modules/Compiler/zOS-C-DetermineCompiler.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/snap/clion/184/bin/cmake/linux/share/cmake-3.21/Modules/Compiler/IBMCPP-C-DetermineVersionInternal.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/snap/clion/184/bin/cmake/linux/share/cmake-3.21/Modules/CMakeFindBinUtils.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/snap/clion/184/bin/cmake/linux/share/cmake-3.21/Modules/Compiler/GNU-FindBinUtils.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/snap/clion/184/bin/cmake/linux/share/cmake-3.21/Modules/CMakeCCompiler.cmake.in"
},
{
"isGenerated" : true,
"path" : "cmake-build-debug/CMakeFiles/3.21.1/CMakeCCompiler.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/snap/clion/184/bin/cmake/linux/share/cmake-3.21/Modules/CMakeDetermineCXXCompiler.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/snap/clion/184/bin/cmake/linux/share/cmake-3.21/Modules/CMakeDetermineCompiler.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/snap/clion/184/bin/cmake/linux/share/cmake-3.21/Modules/Platform/Linux-Determine-CXX.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/snap/clion/184/bin/cmake/linux/share/cmake-3.21/Modules/CMakeDetermineCompilerId.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/snap/clion/184/bin/cmake/linux/share/cmake-3.21/Modules/CMakeCompilerIdDetection.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/snap/clion/184/bin/cmake/linux/share/cmake-3.21/Modules/Compiler/ADSP-DetermineCompiler.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/snap/clion/184/bin/cmake/linux/share/cmake-3.21/Modules/Compiler/ARMCC-DetermineCompiler.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/snap/clion/184/bin/cmake/linux/share/cmake-3.21/Modules/Compiler/ARMClang-DetermineCompiler.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/snap/clion/184/bin/cmake/linux/share/cmake-3.21/Modules/Compiler/AppleClang-DetermineCompiler.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/snap/clion/184/bin/cmake/linux/share/cmake-3.21/Modules/Compiler/Clang-DetermineCompilerInternal.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/snap/clion/184/bin/cmake/linux/share/cmake-3.21/Modules/Compiler/Borland-DetermineCompiler.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/snap/clion/184/bin/cmake/linux/share/cmake-3.21/Modules/Compiler/Clang-DetermineCompiler.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/snap/clion/184/bin/cmake/linux/share/cmake-3.21/Modules/Compiler/Clang-DetermineCompilerInternal.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/snap/clion/184/bin/cmake/linux/share/cmake-3.21/Modules/Compiler/Comeau-CXX-DetermineCompiler.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/snap/clion/184/bin/cmake/linux/share/cmake-3.21/Modules/Compiler/Compaq-CXX-DetermineCompiler.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/snap/clion/184/bin/cmake/linux/share/cmake-3.21/Modules/Compiler/Cray-DetermineCompiler.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/snap/clion/184/bin/cmake/linux/share/cmake-3.21/Modules/Compiler/Embarcadero-DetermineCompiler.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/snap/clion/184/bin/cmake/linux/share/cmake-3.21/Modules/Compiler/Fujitsu-DetermineCompiler.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/snap/clion/184/bin/cmake/linux/share/cmake-3.21/Modules/Compiler/FujitsuClang-DetermineCompiler.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/snap/clion/184/bin/cmake/linux/share/cmake-3.21/Modules/Compiler/GHS-DetermineCompiler.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/snap/clion/184/bin/cmake/linux/share/cmake-3.21/Modules/Compiler/GNU-CXX-DetermineCompiler.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/snap/clion/184/bin/cmake/linux/share/cmake-3.21/Modules/Compiler/HP-CXX-DetermineCompiler.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/snap/clion/184/bin/cmake/linux/share/cmake-3.21/Modules/Compiler/IAR-DetermineCompiler.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/snap/clion/184/bin/cmake/linux/share/cmake-3.21/Modules/Compiler/Intel-DetermineCompiler.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/snap/clion/184/bin/cmake/linux/share/cmake-3.21/Modules/Compiler/IntelLLVM-DetermineCompiler.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/snap/clion/184/bin/cmake/linux/share/cmake-3.21/Modules/Compiler/MSVC-DetermineCompiler.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/snap/clion/184/bin/cmake/linux/share/cmake-3.21/Modules/Compiler/NVHPC-DetermineCompiler.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/snap/clion/184/bin/cmake/linux/share/cmake-3.21/Modules/Compiler/NVIDIA-DetermineCompiler.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/snap/clion/184/bin/cmake/linux/share/cmake-3.21/Modules/Compiler/OpenWatcom-DetermineCompiler.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/snap/clion/184/bin/cmake/linux/share/cmake-3.21/Modules/Compiler/PGI-DetermineCompiler.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/snap/clion/184/bin/cmake/linux/share/cmake-3.21/Modules/Compiler/PathScale-DetermineCompiler.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/snap/clion/184/bin/cmake/linux/share/cmake-3.21/Modules/Compiler/ROCMClang-DetermineCompiler.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/snap/clion/184/bin/cmake/linux/share/cmake-3.21/Modules/Compiler/SCO-DetermineCompiler.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/snap/clion/184/bin/cmake/linux/share/cmake-3.21/Modules/Compiler/SunPro-CXX-DetermineCompiler.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/snap/clion/184/bin/cmake/linux/share/cmake-3.21/Modules/Compiler/TI-DetermineCompiler.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/snap/clion/184/bin/cmake/linux/share/cmake-3.21/Modules/Compiler/VisualAge-CXX-DetermineCompiler.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/snap/clion/184/bin/cmake/linux/share/cmake-3.21/Modules/Compiler/IBMCPP-CXX-DetermineVersionInternal.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/snap/clion/184/bin/cmake/linux/share/cmake-3.21/Modules/Compiler/Watcom-DetermineCompiler.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/snap/clion/184/bin/cmake/linux/share/cmake-3.21/Modules/Compiler/XL-CXX-DetermineCompiler.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/snap/clion/184/bin/cmake/linux/share/cmake-3.21/Modules/Compiler/IBMCPP-CXX-DetermineVersionInternal.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/snap/clion/184/bin/cmake/linux/share/cmake-3.21/Modules/Compiler/XLClang-CXX-DetermineCompiler.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/snap/clion/184/bin/cmake/linux/share/cmake-3.21/Modules/Compiler/zOS-CXX-DetermineCompiler.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/snap/clion/184/bin/cmake/linux/share/cmake-3.21/Modules/Compiler/IBMCPP-CXX-DetermineVersionInternal.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/snap/clion/184/bin/cmake/linux/share/cmake-3.21/Modules/CMakeFindBinUtils.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/snap/clion/184/bin/cmake/linux/share/cmake-3.21/Modules/Compiler/GNU-FindBinUtils.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/snap/clion/184/bin/cmake/linux/share/cmake-3.21/Modules/CMakeCXXCompiler.cmake.in"
},
{
"isGenerated" : true,
"path" : "cmake-build-debug/CMakeFiles/3.21.1/CMakeCXXCompiler.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/snap/clion/184/bin/cmake/linux/share/cmake-3.21/Modules/CMakeSystemSpecificInformation.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/snap/clion/184/bin/cmake/linux/share/cmake-3.21/Modules/CMakeGenericSystem.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/snap/clion/184/bin/cmake/linux/share/cmake-3.21/Modules/CMakeInitializeConfigs.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/snap/clion/184/bin/cmake/linux/share/cmake-3.21/Modules/Platform/Linux.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/snap/clion/184/bin/cmake/linux/share/cmake-3.21/Modules/Platform/UnixPaths.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/snap/clion/184/bin/cmake/linux/share/cmake-3.21/Modules/CMakeCInformation.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/snap/clion/184/bin/cmake/linux/share/cmake-3.21/Modules/CMakeLanguageInformation.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/snap/clion/184/bin/cmake/linux/share/cmake-3.21/Modules/Compiler/GNU-C.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/snap/clion/184/bin/cmake/linux/share/cmake-3.21/Modules/Compiler/GNU.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/snap/clion/184/bin/cmake/linux/share/cmake-3.21/Modules/Compiler/CMakeCommonCompilerMacros.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/snap/clion/184/bin/cmake/linux/share/cmake-3.21/Modules/Platform/Linux-GNU-C.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/snap/clion/184/bin/cmake/linux/share/cmake-3.21/Modules/Platform/Linux-GNU.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/snap/clion/184/bin/cmake/linux/share/cmake-3.21/Modules/CMakeCommonLanguageInclude.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/snap/clion/184/bin/cmake/linux/share/cmake-3.21/Modules/CMakeTestCCompiler.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/snap/clion/184/bin/cmake/linux/share/cmake-3.21/Modules/CMakeTestCompilerCommon.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/snap/clion/184/bin/cmake/linux/share/cmake-3.21/Modules/CMakeDetermineCompilerABI.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/snap/clion/184/bin/cmake/linux/share/cmake-3.21/Modules/CMakeParseImplicitIncludeInfo.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/snap/clion/184/bin/cmake/linux/share/cmake-3.21/Modules/CMakeParseImplicitLinkInfo.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/snap/clion/184/bin/cmake/linux/share/cmake-3.21/Modules/CMakeParseLibraryArchitecture.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/snap/clion/184/bin/cmake/linux/share/cmake-3.21/Modules/CMakeTestCompilerCommon.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/snap/clion/184/bin/cmake/linux/share/cmake-3.21/Modules/CMakeCCompilerABI.c"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/snap/clion/184/bin/cmake/linux/share/cmake-3.21/Modules/CMakeDetermineCompileFeatures.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/snap/clion/184/bin/cmake/linux/share/cmake-3.21/Modules/Internal/FeatureTesting.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/snap/clion/184/bin/cmake/linux/share/cmake-3.21/Modules/CMakeCCompiler.cmake.in"
},
{
"isGenerated" : true,
"path" : "cmake-build-debug/CMakeFiles/3.21.1/CMakeCCompiler.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/snap/clion/184/bin/cmake/linux/share/cmake-3.21/Modules/CMakeCXXInformation.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/snap/clion/184/bin/cmake/linux/share/cmake-3.21/Modules/CMakeLanguageInformation.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/snap/clion/184/bin/cmake/linux/share/cmake-3.21/Modules/Compiler/GNU-CXX.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/snap/clion/184/bin/cmake/linux/share/cmake-3.21/Modules/Compiler/GNU.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/snap/clion/184/bin/cmake/linux/share/cmake-3.21/Modules/Platform/Linux-GNU-CXX.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/snap/clion/184/bin/cmake/linux/share/cmake-3.21/Modules/Platform/Linux-GNU.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/snap/clion/184/bin/cmake/linux/share/cmake-3.21/Modules/CMakeCommonLanguageInclude.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/snap/clion/184/bin/cmake/linux/share/cmake-3.21/Modules/CMakeTestCXXCompiler.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/snap/clion/184/bin/cmake/linux/share/cmake-3.21/Modules/CMakeTestCompilerCommon.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/snap/clion/184/bin/cmake/linux/share/cmake-3.21/Modules/CMakeDetermineCompilerABI.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/snap/clion/184/bin/cmake/linux/share/cmake-3.21/Modules/CMakeParseImplicitIncludeInfo.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/snap/clion/184/bin/cmake/linux/share/cmake-3.21/Modules/CMakeParseImplicitLinkInfo.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/snap/clion/184/bin/cmake/linux/share/cmake-3.21/Modules/CMakeParseLibraryArchitecture.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/snap/clion/184/bin/cmake/linux/share/cmake-3.21/Modules/CMakeTestCompilerCommon.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/snap/clion/184/bin/cmake/linux/share/cmake-3.21/Modules/CMakeCXXCompilerABI.cpp"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/snap/clion/184/bin/cmake/linux/share/cmake-3.21/Modules/CMakeDetermineCompileFeatures.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/snap/clion/184/bin/cmake/linux/share/cmake-3.21/Modules/Internal/FeatureTesting.cmake"
},
{
"isCMake" : true,
"isExternal" : true,
"path" : "/snap/clion/184/bin/cmake/linux/share/cmake-3.21/Modules/CMakeCXXCompiler.cmake.in"
},
{
"isGenerated" : true,
"path" : "cmake-build-debug/CMakeFiles/3.21.1/CMakeCXXCompiler.cmake"
}
],
"kind" : "cmakeFiles",
"paths" :
{
"build" : "/home/tomer/Github/Public-PF/cmake-build-debug",
"source" : "/home/tomer/Github/Public-PF"
},
"version" :
{
"major" : 1,
"minor" : 0
}
}

View File

@ -0,0 +1,150 @@
{
"configurations" :
[
{
"directories" :
[
{
"build" : ".",
"jsonFile" : "directory-.-Debug-f5ebdc15457944623624.json",
"minimumCMakeVersion" :
{
"string" : "3.10"
},
"projectIndex" : 0,
"source" : ".",
"targetIndexes" :
[
0,
1,
2,
3,
4,
5,
6,
7,
8,
9,
10
]
}
],
"name" : "Debug",
"projects" :
[
{
"directoryIndexes" :
[
0
],
"name" : "APD_ONLY",
"targetIndexes" :
[
0,
1,
2,
3,
4,
5,
6,
7,
8,
9,
10
]
}
],
"targets" :
[
{
"directoryIndex" : 0,
"id" : "example::@6890427a1f51a3e7e1df",
"jsonFile" : "target-example-Debug-f2fd9bd66abbfca03f37.json",
"name" : "example",
"projectIndex" : 0
},
{
"directoryIndex" : 0,
"id" : "example0::@6890427a1f51a3e7e1df",
"jsonFile" : "target-example0-Debug-722e45bf24620d8a1287.json",
"name" : "example0",
"projectIndex" : 0
},
{
"directoryIndex" : 0,
"id" : "measure_built::@6890427a1f51a3e7e1df",
"jsonFile" : "target-measure_built-Debug-0ba116b65bf3d7ab6884.json",
"name" : "measure_built",
"projectIndex" : 0
},
{
"directoryIndex" : 0,
"id" : "measure_built0::@6890427a1f51a3e7e1df",
"jsonFile" : "target-measure_built0-Debug-1c26e7153ab9b4dbb397.json",
"name" : "measure_built0",
"projectIndex" : 0
},
{
"directoryIndex" : 0,
"id" : "measure_built3::@6890427a1f51a3e7e1df",
"jsonFile" : "target-measure_built3-Debug-9e60f0edabd112451332.json",
"name" : "measure_built3",
"projectIndex" : 0
},
{
"directoryIndex" : 0,
"id" : "measure_fpp::@6890427a1f51a3e7e1df",
"jsonFile" : "target-measure_fpp-Debug-6218804baa2d893c8235.json",
"name" : "measure_fpp",
"projectIndex" : 0
},
{
"directoryIndex" : 0,
"id" : "measure_fpp0::@6890427a1f51a3e7e1df",
"jsonFile" : "target-measure_fpp0-Debug-ae3e716da61914872325.json",
"name" : "measure_fpp0",
"projectIndex" : 0
},
{
"directoryIndex" : 0,
"id" : "measure_fpp3::@6890427a1f51a3e7e1df",
"jsonFile" : "target-measure_fpp3-Debug-12090f7133d04d45c993.json",
"name" : "measure_fpp3",
"projectIndex" : 0
},
{
"directoryIndex" : 0,
"id" : "measure_perf::@6890427a1f51a3e7e1df",
"jsonFile" : "target-measure_perf-Debug-a7f31f032634834b67c5.json",
"name" : "measure_perf",
"projectIndex" : 0
},
{
"directoryIndex" : 0,
"id" : "measure_perf0::@6890427a1f51a3e7e1df",
"jsonFile" : "target-measure_perf0-Debug-b41767523d8bde5ed7bd.json",
"name" : "measure_perf0",
"projectIndex" : 0
},
{
"directoryIndex" : 0,
"id" : "measure_perf3::@6890427a1f51a3e7e1df",
"jsonFile" : "target-measure_perf3-Debug-1815e855f242cbd76a5a.json",
"name" : "measure_perf3",
"projectIndex" : 0
}
]
}
],
"kind" : "codemodel",
"paths" :
{
"build" : "/home/tomer/Github/Public-PF/cmake-build-debug",
"source" : "/home/tomer/Github/Public-PF"
},
"version" :
{
"major" : 2,
"minor" : 3
}
}

View File

@ -0,0 +1,14 @@
{
"backtraceGraph" :
{
"commands" : [],
"files" : [],
"nodes" : []
},
"installers" : [],
"paths" :
{
"build" : ".",
"source" : "."
}
}

View File

@ -0,0 +1,108 @@
{
"cmake" :
{
"generator" :
{
"multiConfig" : false,
"name" : "Ninja"
},
"paths" :
{
"cmake" : "/snap/clion/184/bin/cmake/linux/bin/cmake",
"cpack" : "/snap/clion/184/bin/cmake/linux/bin/cpack",
"ctest" : "/snap/clion/184/bin/cmake/linux/bin/ctest",
"root" : "/snap/clion/184/bin/cmake/linux/share/cmake-3.21"
},
"version" :
{
"isDirty" : false,
"major" : 3,
"minor" : 21,
"patch" : 1,
"string" : "3.21.1",
"suffix" : ""
}
},
"objects" :
[
{
"jsonFile" : "codemodel-v2-5879e526388a2efa61dd.json",
"kind" : "codemodel",
"version" :
{
"major" : 2,
"minor" : 3
}
},
{
"jsonFile" : "cache-v2-2dd2a3e80239b44d83cc.json",
"kind" : "cache",
"version" :
{
"major" : 2,
"minor" : 0
}
},
{
"jsonFile" : "cmakeFiles-v1-eb5f60b98dcb2065ce32.json",
"kind" : "cmakeFiles",
"version" :
{
"major" : 1,
"minor" : 0
}
},
{
"jsonFile" : "toolchains-v1-b0b7064a037a803f7bb5.json",
"kind" : "toolchains",
"version" :
{
"major" : 1,
"minor" : 0
}
}
],
"reply" :
{
"cache-v2" :
{
"jsonFile" : "cache-v2-2dd2a3e80239b44d83cc.json",
"kind" : "cache",
"version" :
{
"major" : 2,
"minor" : 0
}
},
"cmakeFiles-v1" :
{
"jsonFile" : "cmakeFiles-v1-eb5f60b98dcb2065ce32.json",
"kind" : "cmakeFiles",
"version" :
{
"major" : 1,
"minor" : 0
}
},
"codemodel-v2" :
{
"jsonFile" : "codemodel-v2-5879e526388a2efa61dd.json",
"kind" : "codemodel",
"version" :
{
"major" : 2,
"minor" : 3
}
},
"toolchains-v1" :
{
"jsonFile" : "toolchains-v1-b0b7064a037a803f7bb5.json",
"kind" : "toolchains",
"version" :
{
"major" : 1,
"minor" : 0
}
}
}
}

View File

@ -0,0 +1,271 @@
{
"artifacts" :
[
{
"path" : "example"
}
],
"backtrace" : 1,
"backtraceGraph" :
{
"commands" :
[
"add_executable",
"target_compile_options"
],
"files" :
[
"CMakeLists.txt"
],
"nodes" :
[
{
"file" : 0
},
{
"command" : 0,
"file" : 0,
"line" : 111,
"parent" : 0
},
{
"command" : 1,
"file" : 0,
"line" : 113,
"parent" : 0
}
]
},
"compileGroups" :
[
{
"compileCommandFragments" :
[
{
"fragment" : "-march=native -g"
},
{
"backtrace" : 2,
"fragment" : "-Ofast"
},
{
"backtrace" : 2,
"fragment" : "-DNDEBUG"
},
{
"fragment" : "-std=gnu++17"
}
],
"language" : "CXX",
"languageStandard" :
{
"backtraces" :
[
1
],
"standard" : "17"
},
"sourceIndexes" :
[
7,
9,
11,
14,
21,
23
]
}
],
"id" : "example::@6890427a1f51a3e7e1df",
"link" :
{
"commandFragments" :
[
{
"fragment" : "-march=native -g",
"role" : "flags"
},
{
"fragment" : "",
"role" : "flags"
}
],
"language" : "CXX"
},
"name" : "example",
"nameOnDisk" : "example",
"paths" :
{
"build" : ".",
"source" : "."
},
"sourceGroups" :
[
{
"name" : "Header Files",
"sourceIndexes" :
[
0,
1,
2,
3,
4,
5,
6,
8,
10,
12,
13,
15,
16,
17,
18,
19,
20,
22
]
},
{
"name" : "Source Files",
"sourceIndexes" :
[
7,
9,
11,
14,
21,
23
]
}
],
"sources" :
[
{
"backtrace" : 1,
"path" : "Bloom_Filter/simd-block.h",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"path" : "Bloom_Filter/simd-block-fixed-fpp.h",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"path" : "Bloom_Filter/Impala512.h",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"path" : "Bloom_Filter/bloom.hpp",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"path" : "hashutil.h",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"path" : "Tests/wrappers.hpp",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"path" : "Tests/smart_tests.hpp",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"compileGroupIndex" : 0,
"path" : "Tests/smart_tests.cpp",
"sourceGroupIndex" : 1
},
{
"backtrace" : 1,
"path" : "Prefix-Filter/Shift_op.hpp",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"compileGroupIndex" : 0,
"path" : "Prefix-Filter/Shift_op.cpp",
"sourceGroupIndex" : 1
},
{
"backtrace" : 1,
"path" : "Prefix-Filter/min_pd256.hpp",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"compileGroupIndex" : 0,
"path" : "Prefix-Filter/min_pd256.cpp",
"sourceGroupIndex" : 1
},
{
"backtrace" : 1,
"path" : "cuckoofilter/src/bitsutil.h",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"path" : "cuckoofilter/src/permencoding.h",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"compileGroupIndex" : 0,
"path" : "cuckoofilter/src/printutil.cc",
"sourceGroupIndex" : 1
},
{
"backtrace" : 1,
"path" : "cuckoofilter/src/debug.h",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"path" : "cuckoofilter/src/singletable.h",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"path" : "cuckoofilter/src/packedtable.h",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"path" : "cuckoofilter/src/cuckoofilter.h",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"path" : "cuckoofilter/src/cuckoofilter_stable.h",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"path" : "TC-Shortcut/tc-sym.hpp",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"compileGroupIndex" : 0,
"path" : "TC-Shortcut/tc-sym.cpp",
"sourceGroupIndex" : 1
},
{
"backtrace" : 1,
"path" : "TC-Shortcut/TC-shortcut.hpp",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"compileGroupIndex" : 0,
"path" : "example.cpp",
"sourceGroupIndex" : 1
}
],
"type" : "EXECUTABLE"
}

View File

@ -0,0 +1,275 @@
{
"artifacts" :
[
{
"path" : "example0"
}
],
"backtrace" : 1,
"backtraceGraph" :
{
"commands" :
[
"add_executable",
"target_compile_options"
],
"files" :
[
"CMakeLists.txt"
],
"nodes" :
[
{
"file" : 0
},
{
"command" : 0,
"file" : 0,
"line" : 110,
"parent" : 0
},
{
"command" : 1,
"file" : 0,
"line" : 112,
"parent" : 0
}
]
},
"compileGroups" :
[
{
"compileCommandFragments" :
[
{
"fragment" : "-march=native -g"
},
{
"backtrace" : 2,
"fragment" : "-O0"
},
{
"backtrace" : 2,
"fragment" : "-g3"
},
{
"backtrace" : 2,
"fragment" : "-W"
},
{
"fragment" : "-std=gnu++17"
}
],
"language" : "CXX",
"languageStandard" :
{
"backtraces" :
[
1
],
"standard" : "17"
},
"sourceIndexes" :
[
7,
9,
11,
14,
21,
23
]
}
],
"id" : "example0::@6890427a1f51a3e7e1df",
"link" :
{
"commandFragments" :
[
{
"fragment" : "-march=native -g",
"role" : "flags"
},
{
"fragment" : "",
"role" : "flags"
}
],
"language" : "CXX"
},
"name" : "example0",
"nameOnDisk" : "example0",
"paths" :
{
"build" : ".",
"source" : "."
},
"sourceGroups" :
[
{
"name" : "Header Files",
"sourceIndexes" :
[
0,
1,
2,
3,
4,
5,
6,
8,
10,
12,
13,
15,
16,
17,
18,
19,
20,
22
]
},
{
"name" : "Source Files",
"sourceIndexes" :
[
7,
9,
11,
14,
21,
23
]
}
],
"sources" :
[
{
"backtrace" : 1,
"path" : "Bloom_Filter/simd-block.h",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"path" : "Bloom_Filter/simd-block-fixed-fpp.h",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"path" : "Bloom_Filter/Impala512.h",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"path" : "Bloom_Filter/bloom.hpp",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"path" : "hashutil.h",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"path" : "Tests/wrappers.hpp",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"path" : "Tests/smart_tests.hpp",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"compileGroupIndex" : 0,
"path" : "Tests/smart_tests.cpp",
"sourceGroupIndex" : 1
},
{
"backtrace" : 1,
"path" : "Prefix-Filter/Shift_op.hpp",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"compileGroupIndex" : 0,
"path" : "Prefix-Filter/Shift_op.cpp",
"sourceGroupIndex" : 1
},
{
"backtrace" : 1,
"path" : "Prefix-Filter/min_pd256.hpp",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"compileGroupIndex" : 0,
"path" : "Prefix-Filter/min_pd256.cpp",
"sourceGroupIndex" : 1
},
{
"backtrace" : 1,
"path" : "cuckoofilter/src/bitsutil.h",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"path" : "cuckoofilter/src/permencoding.h",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"compileGroupIndex" : 0,
"path" : "cuckoofilter/src/printutil.cc",
"sourceGroupIndex" : 1
},
{
"backtrace" : 1,
"path" : "cuckoofilter/src/debug.h",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"path" : "cuckoofilter/src/singletable.h",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"path" : "cuckoofilter/src/packedtable.h",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"path" : "cuckoofilter/src/cuckoofilter.h",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"path" : "cuckoofilter/src/cuckoofilter_stable.h",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"path" : "TC-Shortcut/tc-sym.hpp",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"compileGroupIndex" : 0,
"path" : "TC-Shortcut/tc-sym.cpp",
"sourceGroupIndex" : 1
},
{
"backtrace" : 1,
"path" : "TC-Shortcut/TC-shortcut.hpp",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"compileGroupIndex" : 0,
"path" : "example.cpp",
"sourceGroupIndex" : 1
}
],
"type" : "EXECUTABLE"
}

View File

@ -0,0 +1,271 @@
{
"artifacts" :
[
{
"path" : "measure_built"
}
],
"backtrace" : 1,
"backtraceGraph" :
{
"commands" :
[
"add_executable",
"target_compile_options"
],
"files" :
[
"CMakeLists.txt"
],
"nodes" :
[
{
"file" : 0
},
{
"command" : 0,
"file" : 0,
"line" : 82,
"parent" : 0
},
{
"command" : 1,
"file" : 0,
"line" : 85,
"parent" : 0
}
]
},
"compileGroups" :
[
{
"compileCommandFragments" :
[
{
"fragment" : "-march=native -g"
},
{
"backtrace" : 2,
"fragment" : "-Ofast"
},
{
"backtrace" : 2,
"fragment" : "-DNDEBUG"
},
{
"fragment" : "-std=gnu++17"
}
],
"language" : "CXX",
"languageStandard" :
{
"backtraces" :
[
1
],
"standard" : "17"
},
"sourceIndexes" :
[
7,
9,
11,
14,
21,
23
]
}
],
"id" : "measure_built::@6890427a1f51a3e7e1df",
"link" :
{
"commandFragments" :
[
{
"fragment" : "-march=native -g",
"role" : "flags"
},
{
"fragment" : "",
"role" : "flags"
}
],
"language" : "CXX"
},
"name" : "measure_built",
"nameOnDisk" : "measure_built",
"paths" :
{
"build" : ".",
"source" : "."
},
"sourceGroups" :
[
{
"name" : "Header Files",
"sourceIndexes" :
[
0,
1,
2,
3,
4,
5,
6,
8,
10,
12,
13,
15,
16,
17,
18,
19,
20,
22
]
},
{
"name" : "Source Files",
"sourceIndexes" :
[
7,
9,
11,
14,
21,
23
]
}
],
"sources" :
[
{
"backtrace" : 1,
"path" : "Bloom_Filter/simd-block.h",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"path" : "Bloom_Filter/simd-block-fixed-fpp.h",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"path" : "Bloom_Filter/Impala512.h",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"path" : "Bloom_Filter/bloom.hpp",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"path" : "hashutil.h",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"path" : "Tests/wrappers.hpp",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"path" : "Tests/smart_tests.hpp",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"compileGroupIndex" : 0,
"path" : "Tests/smart_tests.cpp",
"sourceGroupIndex" : 1
},
{
"backtrace" : 1,
"path" : "Prefix-Filter/Shift_op.hpp",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"compileGroupIndex" : 0,
"path" : "Prefix-Filter/Shift_op.cpp",
"sourceGroupIndex" : 1
},
{
"backtrace" : 1,
"path" : "Prefix-Filter/min_pd256.hpp",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"compileGroupIndex" : 0,
"path" : "Prefix-Filter/min_pd256.cpp",
"sourceGroupIndex" : 1
},
{
"backtrace" : 1,
"path" : "cuckoofilter/src/bitsutil.h",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"path" : "cuckoofilter/src/permencoding.h",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"compileGroupIndex" : 0,
"path" : "cuckoofilter/src/printutil.cc",
"sourceGroupIndex" : 1
},
{
"backtrace" : 1,
"path" : "cuckoofilter/src/debug.h",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"path" : "cuckoofilter/src/singletable.h",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"path" : "cuckoofilter/src/packedtable.h",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"path" : "cuckoofilter/src/cuckoofilter.h",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"path" : "cuckoofilter/src/cuckoofilter_stable.h",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"path" : "TC-Shortcut/tc-sym.hpp",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"compileGroupIndex" : 0,
"path" : "TC-Shortcut/tc-sym.cpp",
"sourceGroupIndex" : 1
},
{
"backtrace" : 1,
"path" : "TC-Shortcut/TC-shortcut.hpp",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"compileGroupIndex" : 0,
"path" : "main-built.cpp",
"sourceGroupIndex" : 1
}
],
"type" : "EXECUTABLE"
}

View File

@ -0,0 +1,275 @@
{
"artifacts" :
[
{
"path" : "measure_built0"
}
],
"backtrace" : 1,
"backtraceGraph" :
{
"commands" :
[
"add_executable",
"target_compile_options"
],
"files" :
[
"CMakeLists.txt"
],
"nodes" :
[
{
"file" : 0
},
{
"command" : 0,
"file" : 0,
"line" : 80,
"parent" : 0
},
{
"command" : 1,
"file" : 0,
"line" : 83,
"parent" : 0
}
]
},
"compileGroups" :
[
{
"compileCommandFragments" :
[
{
"fragment" : "-march=native -g"
},
{
"backtrace" : 2,
"fragment" : "-O0"
},
{
"backtrace" : 2,
"fragment" : "-g3"
},
{
"backtrace" : 2,
"fragment" : "-W"
},
{
"fragment" : "-std=gnu++17"
}
],
"language" : "CXX",
"languageStandard" :
{
"backtraces" :
[
1
],
"standard" : "17"
},
"sourceIndexes" :
[
7,
9,
11,
14,
21,
23
]
}
],
"id" : "measure_built0::@6890427a1f51a3e7e1df",
"link" :
{
"commandFragments" :
[
{
"fragment" : "-march=native -g",
"role" : "flags"
},
{
"fragment" : "",
"role" : "flags"
}
],
"language" : "CXX"
},
"name" : "measure_built0",
"nameOnDisk" : "measure_built0",
"paths" :
{
"build" : ".",
"source" : "."
},
"sourceGroups" :
[
{
"name" : "Header Files",
"sourceIndexes" :
[
0,
1,
2,
3,
4,
5,
6,
8,
10,
12,
13,
15,
16,
17,
18,
19,
20,
22
]
},
{
"name" : "Source Files",
"sourceIndexes" :
[
7,
9,
11,
14,
21,
23
]
}
],
"sources" :
[
{
"backtrace" : 1,
"path" : "Bloom_Filter/simd-block.h",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"path" : "Bloom_Filter/simd-block-fixed-fpp.h",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"path" : "Bloom_Filter/Impala512.h",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"path" : "Bloom_Filter/bloom.hpp",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"path" : "hashutil.h",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"path" : "Tests/wrappers.hpp",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"path" : "Tests/smart_tests.hpp",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"compileGroupIndex" : 0,
"path" : "Tests/smart_tests.cpp",
"sourceGroupIndex" : 1
},
{
"backtrace" : 1,
"path" : "Prefix-Filter/Shift_op.hpp",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"compileGroupIndex" : 0,
"path" : "Prefix-Filter/Shift_op.cpp",
"sourceGroupIndex" : 1
},
{
"backtrace" : 1,
"path" : "Prefix-Filter/min_pd256.hpp",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"compileGroupIndex" : 0,
"path" : "Prefix-Filter/min_pd256.cpp",
"sourceGroupIndex" : 1
},
{
"backtrace" : 1,
"path" : "cuckoofilter/src/bitsutil.h",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"path" : "cuckoofilter/src/permencoding.h",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"compileGroupIndex" : 0,
"path" : "cuckoofilter/src/printutil.cc",
"sourceGroupIndex" : 1
},
{
"backtrace" : 1,
"path" : "cuckoofilter/src/debug.h",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"path" : "cuckoofilter/src/singletable.h",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"path" : "cuckoofilter/src/packedtable.h",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"path" : "cuckoofilter/src/cuckoofilter.h",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"path" : "cuckoofilter/src/cuckoofilter_stable.h",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"path" : "TC-Shortcut/tc-sym.hpp",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"compileGroupIndex" : 0,
"path" : "TC-Shortcut/tc-sym.cpp",
"sourceGroupIndex" : 1
},
{
"backtrace" : 1,
"path" : "TC-Shortcut/TC-shortcut.hpp",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"compileGroupIndex" : 0,
"path" : "main-built.cpp",
"sourceGroupIndex" : 1
}
],
"type" : "EXECUTABLE"
}

View File

@ -0,0 +1,271 @@
{
"artifacts" :
[
{
"path" : "measure_built3"
}
],
"backtrace" : 1,
"backtraceGraph" :
{
"commands" :
[
"add_executable",
"target_compile_options"
],
"files" :
[
"CMakeLists.txt"
],
"nodes" :
[
{
"file" : 0
},
{
"command" : 0,
"file" : 0,
"line" : 81,
"parent" : 0
},
{
"command" : 1,
"file" : 0,
"line" : 84,
"parent" : 0
}
]
},
"compileGroups" :
[
{
"compileCommandFragments" :
[
{
"fragment" : "-march=native -g"
},
{
"backtrace" : 2,
"fragment" : "-O3"
},
{
"backtrace" : 2,
"fragment" : "-g3"
},
{
"fragment" : "-std=gnu++17"
}
],
"language" : "CXX",
"languageStandard" :
{
"backtraces" :
[
1
],
"standard" : "17"
},
"sourceIndexes" :
[
7,
9,
11,
14,
21,
23
]
}
],
"id" : "measure_built3::@6890427a1f51a3e7e1df",
"link" :
{
"commandFragments" :
[
{
"fragment" : "-march=native -g",
"role" : "flags"
},
{
"fragment" : "",
"role" : "flags"
}
],
"language" : "CXX"
},
"name" : "measure_built3",
"nameOnDisk" : "measure_built3",
"paths" :
{
"build" : ".",
"source" : "."
},
"sourceGroups" :
[
{
"name" : "Header Files",
"sourceIndexes" :
[
0,
1,
2,
3,
4,
5,
6,
8,
10,
12,
13,
15,
16,
17,
18,
19,
20,
22
]
},
{
"name" : "Source Files",
"sourceIndexes" :
[
7,
9,
11,
14,
21,
23
]
}
],
"sources" :
[
{
"backtrace" : 1,
"path" : "Bloom_Filter/simd-block.h",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"path" : "Bloom_Filter/simd-block-fixed-fpp.h",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"path" : "Bloom_Filter/Impala512.h",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"path" : "Bloom_Filter/bloom.hpp",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"path" : "hashutil.h",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"path" : "Tests/wrappers.hpp",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"path" : "Tests/smart_tests.hpp",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"compileGroupIndex" : 0,
"path" : "Tests/smart_tests.cpp",
"sourceGroupIndex" : 1
},
{
"backtrace" : 1,
"path" : "Prefix-Filter/Shift_op.hpp",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"compileGroupIndex" : 0,
"path" : "Prefix-Filter/Shift_op.cpp",
"sourceGroupIndex" : 1
},
{
"backtrace" : 1,
"path" : "Prefix-Filter/min_pd256.hpp",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"compileGroupIndex" : 0,
"path" : "Prefix-Filter/min_pd256.cpp",
"sourceGroupIndex" : 1
},
{
"backtrace" : 1,
"path" : "cuckoofilter/src/bitsutil.h",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"path" : "cuckoofilter/src/permencoding.h",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"compileGroupIndex" : 0,
"path" : "cuckoofilter/src/printutil.cc",
"sourceGroupIndex" : 1
},
{
"backtrace" : 1,
"path" : "cuckoofilter/src/debug.h",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"path" : "cuckoofilter/src/singletable.h",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"path" : "cuckoofilter/src/packedtable.h",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"path" : "cuckoofilter/src/cuckoofilter.h",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"path" : "cuckoofilter/src/cuckoofilter_stable.h",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"path" : "TC-Shortcut/tc-sym.hpp",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"compileGroupIndex" : 0,
"path" : "TC-Shortcut/tc-sym.cpp",
"sourceGroupIndex" : 1
},
{
"backtrace" : 1,
"path" : "TC-Shortcut/TC-shortcut.hpp",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"compileGroupIndex" : 0,
"path" : "main-built.cpp",
"sourceGroupIndex" : 1
}
],
"type" : "EXECUTABLE"
}

View File

@ -0,0 +1,271 @@
{
"artifacts" :
[
{
"path" : "measure_fpp"
}
],
"backtrace" : 1,
"backtraceGraph" :
{
"commands" :
[
"add_executable",
"target_compile_options"
],
"files" :
[
"CMakeLists.txt"
],
"nodes" :
[
{
"file" : 0
},
{
"command" : 0,
"file" : 0,
"line" : 92,
"parent" : 0
},
{
"command" : 1,
"file" : 0,
"line" : 95,
"parent" : 0
}
]
},
"compileGroups" :
[
{
"compileCommandFragments" :
[
{
"fragment" : "-march=native -g"
},
{
"backtrace" : 2,
"fragment" : "-Ofast"
},
{
"backtrace" : 2,
"fragment" : "-DNDEBUG"
},
{
"fragment" : "-std=gnu++17"
}
],
"language" : "CXX",
"languageStandard" :
{
"backtraces" :
[
1
],
"standard" : "17"
},
"sourceIndexes" :
[
7,
9,
11,
14,
21,
23
]
}
],
"id" : "measure_fpp::@6890427a1f51a3e7e1df",
"link" :
{
"commandFragments" :
[
{
"fragment" : "-march=native -g",
"role" : "flags"
},
{
"fragment" : "",
"role" : "flags"
}
],
"language" : "CXX"
},
"name" : "measure_fpp",
"nameOnDisk" : "measure_fpp",
"paths" :
{
"build" : ".",
"source" : "."
},
"sourceGroups" :
[
{
"name" : "Header Files",
"sourceIndexes" :
[
0,
1,
2,
3,
4,
5,
6,
8,
10,
12,
13,
15,
16,
17,
18,
19,
20,
22
]
},
{
"name" : "Source Files",
"sourceIndexes" :
[
7,
9,
11,
14,
21,
23
]
}
],
"sources" :
[
{
"backtrace" : 1,
"path" : "Bloom_Filter/simd-block.h",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"path" : "Bloom_Filter/simd-block-fixed-fpp.h",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"path" : "Bloom_Filter/Impala512.h",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"path" : "Bloom_Filter/bloom.hpp",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"path" : "hashutil.h",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"path" : "Tests/wrappers.hpp",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"path" : "Tests/smart_tests.hpp",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"compileGroupIndex" : 0,
"path" : "Tests/smart_tests.cpp",
"sourceGroupIndex" : 1
},
{
"backtrace" : 1,
"path" : "Prefix-Filter/Shift_op.hpp",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"compileGroupIndex" : 0,
"path" : "Prefix-Filter/Shift_op.cpp",
"sourceGroupIndex" : 1
},
{
"backtrace" : 1,
"path" : "Prefix-Filter/min_pd256.hpp",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"compileGroupIndex" : 0,
"path" : "Prefix-Filter/min_pd256.cpp",
"sourceGroupIndex" : 1
},
{
"backtrace" : 1,
"path" : "cuckoofilter/src/bitsutil.h",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"path" : "cuckoofilter/src/permencoding.h",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"compileGroupIndex" : 0,
"path" : "cuckoofilter/src/printutil.cc",
"sourceGroupIndex" : 1
},
{
"backtrace" : 1,
"path" : "cuckoofilter/src/debug.h",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"path" : "cuckoofilter/src/singletable.h",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"path" : "cuckoofilter/src/packedtable.h",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"path" : "cuckoofilter/src/cuckoofilter.h",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"path" : "cuckoofilter/src/cuckoofilter_stable.h",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"path" : "TC-Shortcut/tc-sym.hpp",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"compileGroupIndex" : 0,
"path" : "TC-Shortcut/tc-sym.cpp",
"sourceGroupIndex" : 1
},
{
"backtrace" : 1,
"path" : "TC-Shortcut/TC-shortcut.hpp",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"compileGroupIndex" : 0,
"path" : "main-fpp.cpp",
"sourceGroupIndex" : 1
}
],
"type" : "EXECUTABLE"
}

View File

@ -0,0 +1,275 @@
{
"artifacts" :
[
{
"path" : "measure_fpp0"
}
],
"backtrace" : 1,
"backtraceGraph" :
{
"commands" :
[
"add_executable",
"target_compile_options"
],
"files" :
[
"CMakeLists.txt"
],
"nodes" :
[
{
"file" : 0
},
{
"command" : 0,
"file" : 0,
"line" : 90,
"parent" : 0
},
{
"command" : 1,
"file" : 0,
"line" : 93,
"parent" : 0
}
]
},
"compileGroups" :
[
{
"compileCommandFragments" :
[
{
"fragment" : "-march=native -g"
},
{
"backtrace" : 2,
"fragment" : "-O0"
},
{
"backtrace" : 2,
"fragment" : "-g3"
},
{
"backtrace" : 2,
"fragment" : "-W"
},
{
"fragment" : "-std=gnu++17"
}
],
"language" : "CXX",
"languageStandard" :
{
"backtraces" :
[
1
],
"standard" : "17"
},
"sourceIndexes" :
[
7,
9,
11,
14,
21,
23
]
}
],
"id" : "measure_fpp0::@6890427a1f51a3e7e1df",
"link" :
{
"commandFragments" :
[
{
"fragment" : "-march=native -g",
"role" : "flags"
},
{
"fragment" : "",
"role" : "flags"
}
],
"language" : "CXX"
},
"name" : "measure_fpp0",
"nameOnDisk" : "measure_fpp0",
"paths" :
{
"build" : ".",
"source" : "."
},
"sourceGroups" :
[
{
"name" : "Header Files",
"sourceIndexes" :
[
0,
1,
2,
3,
4,
5,
6,
8,
10,
12,
13,
15,
16,
17,
18,
19,
20,
22
]
},
{
"name" : "Source Files",
"sourceIndexes" :
[
7,
9,
11,
14,
21,
23
]
}
],
"sources" :
[
{
"backtrace" : 1,
"path" : "Bloom_Filter/simd-block.h",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"path" : "Bloom_Filter/simd-block-fixed-fpp.h",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"path" : "Bloom_Filter/Impala512.h",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"path" : "Bloom_Filter/bloom.hpp",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"path" : "hashutil.h",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"path" : "Tests/wrappers.hpp",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"path" : "Tests/smart_tests.hpp",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"compileGroupIndex" : 0,
"path" : "Tests/smart_tests.cpp",
"sourceGroupIndex" : 1
},
{
"backtrace" : 1,
"path" : "Prefix-Filter/Shift_op.hpp",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"compileGroupIndex" : 0,
"path" : "Prefix-Filter/Shift_op.cpp",
"sourceGroupIndex" : 1
},
{
"backtrace" : 1,
"path" : "Prefix-Filter/min_pd256.hpp",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"compileGroupIndex" : 0,
"path" : "Prefix-Filter/min_pd256.cpp",
"sourceGroupIndex" : 1
},
{
"backtrace" : 1,
"path" : "cuckoofilter/src/bitsutil.h",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"path" : "cuckoofilter/src/permencoding.h",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"compileGroupIndex" : 0,
"path" : "cuckoofilter/src/printutil.cc",
"sourceGroupIndex" : 1
},
{
"backtrace" : 1,
"path" : "cuckoofilter/src/debug.h",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"path" : "cuckoofilter/src/singletable.h",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"path" : "cuckoofilter/src/packedtable.h",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"path" : "cuckoofilter/src/cuckoofilter.h",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"path" : "cuckoofilter/src/cuckoofilter_stable.h",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"path" : "TC-Shortcut/tc-sym.hpp",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"compileGroupIndex" : 0,
"path" : "TC-Shortcut/tc-sym.cpp",
"sourceGroupIndex" : 1
},
{
"backtrace" : 1,
"path" : "TC-Shortcut/TC-shortcut.hpp",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"compileGroupIndex" : 0,
"path" : "main-fpp.cpp",
"sourceGroupIndex" : 1
}
],
"type" : "EXECUTABLE"
}

View File

@ -0,0 +1,271 @@
{
"artifacts" :
[
{
"path" : "measure_fpp3"
}
],
"backtrace" : 1,
"backtraceGraph" :
{
"commands" :
[
"add_executable",
"target_compile_options"
],
"files" :
[
"CMakeLists.txt"
],
"nodes" :
[
{
"file" : 0
},
{
"command" : 0,
"file" : 0,
"line" : 91,
"parent" : 0
},
{
"command" : 1,
"file" : 0,
"line" : 94,
"parent" : 0
}
]
},
"compileGroups" :
[
{
"compileCommandFragments" :
[
{
"fragment" : "-march=native -g"
},
{
"backtrace" : 2,
"fragment" : "-O3"
},
{
"backtrace" : 2,
"fragment" : "-g3"
},
{
"fragment" : "-std=gnu++17"
}
],
"language" : "CXX",
"languageStandard" :
{
"backtraces" :
[
1
],
"standard" : "17"
},
"sourceIndexes" :
[
7,
9,
11,
14,
21,
23
]
}
],
"id" : "measure_fpp3::@6890427a1f51a3e7e1df",
"link" :
{
"commandFragments" :
[
{
"fragment" : "-march=native -g",
"role" : "flags"
},
{
"fragment" : "",
"role" : "flags"
}
],
"language" : "CXX"
},
"name" : "measure_fpp3",
"nameOnDisk" : "measure_fpp3",
"paths" :
{
"build" : ".",
"source" : "."
},
"sourceGroups" :
[
{
"name" : "Header Files",
"sourceIndexes" :
[
0,
1,
2,
3,
4,
5,
6,
8,
10,
12,
13,
15,
16,
17,
18,
19,
20,
22
]
},
{
"name" : "Source Files",
"sourceIndexes" :
[
7,
9,
11,
14,
21,
23
]
}
],
"sources" :
[
{
"backtrace" : 1,
"path" : "Bloom_Filter/simd-block.h",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"path" : "Bloom_Filter/simd-block-fixed-fpp.h",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"path" : "Bloom_Filter/Impala512.h",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"path" : "Bloom_Filter/bloom.hpp",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"path" : "hashutil.h",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"path" : "Tests/wrappers.hpp",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"path" : "Tests/smart_tests.hpp",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"compileGroupIndex" : 0,
"path" : "Tests/smart_tests.cpp",
"sourceGroupIndex" : 1
},
{
"backtrace" : 1,
"path" : "Prefix-Filter/Shift_op.hpp",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"compileGroupIndex" : 0,
"path" : "Prefix-Filter/Shift_op.cpp",
"sourceGroupIndex" : 1
},
{
"backtrace" : 1,
"path" : "Prefix-Filter/min_pd256.hpp",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"compileGroupIndex" : 0,
"path" : "Prefix-Filter/min_pd256.cpp",
"sourceGroupIndex" : 1
},
{
"backtrace" : 1,
"path" : "cuckoofilter/src/bitsutil.h",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"path" : "cuckoofilter/src/permencoding.h",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"compileGroupIndex" : 0,
"path" : "cuckoofilter/src/printutil.cc",
"sourceGroupIndex" : 1
},
{
"backtrace" : 1,
"path" : "cuckoofilter/src/debug.h",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"path" : "cuckoofilter/src/singletable.h",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"path" : "cuckoofilter/src/packedtable.h",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"path" : "cuckoofilter/src/cuckoofilter.h",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"path" : "cuckoofilter/src/cuckoofilter_stable.h",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"path" : "TC-Shortcut/tc-sym.hpp",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"compileGroupIndex" : 0,
"path" : "TC-Shortcut/tc-sym.cpp",
"sourceGroupIndex" : 1
},
{
"backtrace" : 1,
"path" : "TC-Shortcut/TC-shortcut.hpp",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"compileGroupIndex" : 0,
"path" : "main-fpp.cpp",
"sourceGroupIndex" : 1
}
],
"type" : "EXECUTABLE"
}

View File

@ -0,0 +1,271 @@
{
"artifacts" :
[
{
"path" : "measure_perf"
}
],
"backtrace" : 1,
"backtraceGraph" :
{
"commands" :
[
"add_executable",
"target_compile_options"
],
"files" :
[
"CMakeLists.txt"
],
"nodes" :
[
{
"file" : 0
},
{
"command" : 0,
"file" : 0,
"line" : 102,
"parent" : 0
},
{
"command" : 1,
"file" : 0,
"line" : 105,
"parent" : 0
}
]
},
"compileGroups" :
[
{
"compileCommandFragments" :
[
{
"fragment" : "-march=native -g"
},
{
"backtrace" : 2,
"fragment" : "-Ofast"
},
{
"backtrace" : 2,
"fragment" : "-DNDEBUG"
},
{
"fragment" : "-std=gnu++17"
}
],
"language" : "CXX",
"languageStandard" :
{
"backtraces" :
[
1
],
"standard" : "17"
},
"sourceIndexes" :
[
7,
9,
11,
14,
21,
23
]
}
],
"id" : "measure_perf::@6890427a1f51a3e7e1df",
"link" :
{
"commandFragments" :
[
{
"fragment" : "-march=native -g",
"role" : "flags"
},
{
"fragment" : "",
"role" : "flags"
}
],
"language" : "CXX"
},
"name" : "measure_perf",
"nameOnDisk" : "measure_perf",
"paths" :
{
"build" : ".",
"source" : "."
},
"sourceGroups" :
[
{
"name" : "Header Files",
"sourceIndexes" :
[
0,
1,
2,
3,
4,
5,
6,
8,
10,
12,
13,
15,
16,
17,
18,
19,
20,
22
]
},
{
"name" : "Source Files",
"sourceIndexes" :
[
7,
9,
11,
14,
21,
23
]
}
],
"sources" :
[
{
"backtrace" : 1,
"path" : "Bloom_Filter/simd-block.h",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"path" : "Bloom_Filter/simd-block-fixed-fpp.h",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"path" : "Bloom_Filter/Impala512.h",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"path" : "Bloom_Filter/bloom.hpp",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"path" : "hashutil.h",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"path" : "Tests/wrappers.hpp",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"path" : "Tests/smart_tests.hpp",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"compileGroupIndex" : 0,
"path" : "Tests/smart_tests.cpp",
"sourceGroupIndex" : 1
},
{
"backtrace" : 1,
"path" : "Prefix-Filter/Shift_op.hpp",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"compileGroupIndex" : 0,
"path" : "Prefix-Filter/Shift_op.cpp",
"sourceGroupIndex" : 1
},
{
"backtrace" : 1,
"path" : "Prefix-Filter/min_pd256.hpp",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"compileGroupIndex" : 0,
"path" : "Prefix-Filter/min_pd256.cpp",
"sourceGroupIndex" : 1
},
{
"backtrace" : 1,
"path" : "cuckoofilter/src/bitsutil.h",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"path" : "cuckoofilter/src/permencoding.h",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"compileGroupIndex" : 0,
"path" : "cuckoofilter/src/printutil.cc",
"sourceGroupIndex" : 1
},
{
"backtrace" : 1,
"path" : "cuckoofilter/src/debug.h",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"path" : "cuckoofilter/src/singletable.h",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"path" : "cuckoofilter/src/packedtable.h",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"path" : "cuckoofilter/src/cuckoofilter.h",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"path" : "cuckoofilter/src/cuckoofilter_stable.h",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"path" : "TC-Shortcut/tc-sym.hpp",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"compileGroupIndex" : 0,
"path" : "TC-Shortcut/tc-sym.cpp",
"sourceGroupIndex" : 1
},
{
"backtrace" : 1,
"path" : "TC-Shortcut/TC-shortcut.hpp",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"compileGroupIndex" : 0,
"path" : "main-perf.cpp",
"sourceGroupIndex" : 1
}
],
"type" : "EXECUTABLE"
}

View File

@ -0,0 +1,275 @@
{
"artifacts" :
[
{
"path" : "measure_perf0"
}
],
"backtrace" : 1,
"backtraceGraph" :
{
"commands" :
[
"add_executable",
"target_compile_options"
],
"files" :
[
"CMakeLists.txt"
],
"nodes" :
[
{
"file" : 0
},
{
"command" : 0,
"file" : 0,
"line" : 100,
"parent" : 0
},
{
"command" : 1,
"file" : 0,
"line" : 103,
"parent" : 0
}
]
},
"compileGroups" :
[
{
"compileCommandFragments" :
[
{
"fragment" : "-march=native -g"
},
{
"backtrace" : 2,
"fragment" : "-O0"
},
{
"backtrace" : 2,
"fragment" : "-g3"
},
{
"backtrace" : 2,
"fragment" : "-W"
},
{
"fragment" : "-std=gnu++17"
}
],
"language" : "CXX",
"languageStandard" :
{
"backtraces" :
[
1
],
"standard" : "17"
},
"sourceIndexes" :
[
7,
9,
11,
14,
21,
23
]
}
],
"id" : "measure_perf0::@6890427a1f51a3e7e1df",
"link" :
{
"commandFragments" :
[
{
"fragment" : "-march=native -g",
"role" : "flags"
},
{
"fragment" : "",
"role" : "flags"
}
],
"language" : "CXX"
},
"name" : "measure_perf0",
"nameOnDisk" : "measure_perf0",
"paths" :
{
"build" : ".",
"source" : "."
},
"sourceGroups" :
[
{
"name" : "Header Files",
"sourceIndexes" :
[
0,
1,
2,
3,
4,
5,
6,
8,
10,
12,
13,
15,
16,
17,
18,
19,
20,
22
]
},
{
"name" : "Source Files",
"sourceIndexes" :
[
7,
9,
11,
14,
21,
23
]
}
],
"sources" :
[
{
"backtrace" : 1,
"path" : "Bloom_Filter/simd-block.h",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"path" : "Bloom_Filter/simd-block-fixed-fpp.h",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"path" : "Bloom_Filter/Impala512.h",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"path" : "Bloom_Filter/bloom.hpp",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"path" : "hashutil.h",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"path" : "Tests/wrappers.hpp",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"path" : "Tests/smart_tests.hpp",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"compileGroupIndex" : 0,
"path" : "Tests/smart_tests.cpp",
"sourceGroupIndex" : 1
},
{
"backtrace" : 1,
"path" : "Prefix-Filter/Shift_op.hpp",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"compileGroupIndex" : 0,
"path" : "Prefix-Filter/Shift_op.cpp",
"sourceGroupIndex" : 1
},
{
"backtrace" : 1,
"path" : "Prefix-Filter/min_pd256.hpp",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"compileGroupIndex" : 0,
"path" : "Prefix-Filter/min_pd256.cpp",
"sourceGroupIndex" : 1
},
{
"backtrace" : 1,
"path" : "cuckoofilter/src/bitsutil.h",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"path" : "cuckoofilter/src/permencoding.h",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"compileGroupIndex" : 0,
"path" : "cuckoofilter/src/printutil.cc",
"sourceGroupIndex" : 1
},
{
"backtrace" : 1,
"path" : "cuckoofilter/src/debug.h",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"path" : "cuckoofilter/src/singletable.h",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"path" : "cuckoofilter/src/packedtable.h",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"path" : "cuckoofilter/src/cuckoofilter.h",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"path" : "cuckoofilter/src/cuckoofilter_stable.h",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"path" : "TC-Shortcut/tc-sym.hpp",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"compileGroupIndex" : 0,
"path" : "TC-Shortcut/tc-sym.cpp",
"sourceGroupIndex" : 1
},
{
"backtrace" : 1,
"path" : "TC-Shortcut/TC-shortcut.hpp",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"compileGroupIndex" : 0,
"path" : "main-perf.cpp",
"sourceGroupIndex" : 1
}
],
"type" : "EXECUTABLE"
}

View File

@ -0,0 +1,271 @@
{
"artifacts" :
[
{
"path" : "measure_perf3"
}
],
"backtrace" : 1,
"backtraceGraph" :
{
"commands" :
[
"add_executable",
"target_compile_options"
],
"files" :
[
"CMakeLists.txt"
],
"nodes" :
[
{
"file" : 0
},
{
"command" : 0,
"file" : 0,
"line" : 101,
"parent" : 0
},
{
"command" : 1,
"file" : 0,
"line" : 104,
"parent" : 0
}
]
},
"compileGroups" :
[
{
"compileCommandFragments" :
[
{
"fragment" : "-march=native -g"
},
{
"backtrace" : 2,
"fragment" : "-O3"
},
{
"backtrace" : 2,
"fragment" : "-g3"
},
{
"fragment" : "-std=gnu++17"
}
],
"language" : "CXX",
"languageStandard" :
{
"backtraces" :
[
1
],
"standard" : "17"
},
"sourceIndexes" :
[
7,
9,
11,
14,
21,
23
]
}
],
"id" : "measure_perf3::@6890427a1f51a3e7e1df",
"link" :
{
"commandFragments" :
[
{
"fragment" : "-march=native -g",
"role" : "flags"
},
{
"fragment" : "",
"role" : "flags"
}
],
"language" : "CXX"
},
"name" : "measure_perf3",
"nameOnDisk" : "measure_perf3",
"paths" :
{
"build" : ".",
"source" : "."
},
"sourceGroups" :
[
{
"name" : "Header Files",
"sourceIndexes" :
[
0,
1,
2,
3,
4,
5,
6,
8,
10,
12,
13,
15,
16,
17,
18,
19,
20,
22
]
},
{
"name" : "Source Files",
"sourceIndexes" :
[
7,
9,
11,
14,
21,
23
]
}
],
"sources" :
[
{
"backtrace" : 1,
"path" : "Bloom_Filter/simd-block.h",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"path" : "Bloom_Filter/simd-block-fixed-fpp.h",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"path" : "Bloom_Filter/Impala512.h",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"path" : "Bloom_Filter/bloom.hpp",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"path" : "hashutil.h",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"path" : "Tests/wrappers.hpp",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"path" : "Tests/smart_tests.hpp",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"compileGroupIndex" : 0,
"path" : "Tests/smart_tests.cpp",
"sourceGroupIndex" : 1
},
{
"backtrace" : 1,
"path" : "Prefix-Filter/Shift_op.hpp",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"compileGroupIndex" : 0,
"path" : "Prefix-Filter/Shift_op.cpp",
"sourceGroupIndex" : 1
},
{
"backtrace" : 1,
"path" : "Prefix-Filter/min_pd256.hpp",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"compileGroupIndex" : 0,
"path" : "Prefix-Filter/min_pd256.cpp",
"sourceGroupIndex" : 1
},
{
"backtrace" : 1,
"path" : "cuckoofilter/src/bitsutil.h",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"path" : "cuckoofilter/src/permencoding.h",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"compileGroupIndex" : 0,
"path" : "cuckoofilter/src/printutil.cc",
"sourceGroupIndex" : 1
},
{
"backtrace" : 1,
"path" : "cuckoofilter/src/debug.h",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"path" : "cuckoofilter/src/singletable.h",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"path" : "cuckoofilter/src/packedtable.h",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"path" : "cuckoofilter/src/cuckoofilter.h",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"path" : "cuckoofilter/src/cuckoofilter_stable.h",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"path" : "TC-Shortcut/tc-sym.hpp",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"compileGroupIndex" : 0,
"path" : "TC-Shortcut/tc-sym.cpp",
"sourceGroupIndex" : 1
},
{
"backtrace" : 1,
"path" : "TC-Shortcut/TC-shortcut.hpp",
"sourceGroupIndex" : 0
},
{
"backtrace" : 1,
"compileGroupIndex" : 0,
"path" : "main-perf.cpp",
"sourceGroupIndex" : 1
}
],
"type" : "EXECUTABLE"
}

View File

@ -0,0 +1,107 @@
{
"kind" : "toolchains",
"toolchains" :
[
{
"compiler" :
{
"id" : "GNU",
"implicit" :
{
"includeDirectories" :
[
"/usr/lib/gcc/x86_64-linux-gnu/10/include",
"/usr/local/include",
"/usr/include/x86_64-linux-gnu",
"/usr/include"
],
"linkDirectories" :
[
"/usr/lib/gcc/x86_64-linux-gnu/10",
"/usr/lib/x86_64-linux-gnu",
"/usr/lib",
"/lib/x86_64-linux-gnu",
"/lib"
],
"linkFrameworkDirectories" : [],
"linkLibraries" :
[
"gcc",
"gcc_s",
"c",
"gcc",
"gcc_s"
]
},
"path" : "/usr/bin/gcc-10",
"version" : "10.3.0"
},
"language" : "C",
"sourceFileExtensions" :
[
"c",
"m"
]
},
{
"compiler" :
{
"id" : "GNU",
"implicit" :
{
"includeDirectories" :
[
"/usr/include/c++/10",
"/usr/include/x86_64-linux-gnu/c++/10",
"/usr/include/c++/10/backward",
"/usr/lib/gcc/x86_64-linux-gnu/10/include",
"/usr/local/include",
"/usr/include/x86_64-linux-gnu",
"/usr/include"
],
"linkDirectories" :
[
"/usr/lib/gcc/x86_64-linux-gnu/10",
"/usr/lib/x86_64-linux-gnu",
"/usr/lib",
"/lib/x86_64-linux-gnu",
"/lib"
],
"linkFrameworkDirectories" : [],
"linkLibraries" :
[
"stdc++",
"m",
"gcc_s",
"gcc",
"c",
"gcc_s",
"gcc"
]
},
"path" : "/usr/bin/g++-10",
"version" : "10.3.0"
},
"language" : "CXX",
"sourceFileExtensions" :
[
"C",
"M",
"c++",
"cc",
"cpp",
"cxx",
"mm",
"mpp",
"CPP",
"ixx",
"cppm"
]
}
],
"version" :
{
"major" : 1,
"minor" : 0
}
}

View File

@ -0,0 +1,362 @@
# This is the CMakeCache file.
# For build in directory: /home/tomer/Github/Public-PF/cmake-build-debug
# It was generated by CMake: /snap/clion/184/bin/cmake/linux/bin/cmake
# You can edit this file to change values found and used by cmake.
# If you do not want to change any of the values, simply exit the editor.
# If you do want to change a value, simply edit, save, and exit the editor.
# The syntax for the file is as follows:
# KEY:TYPE=VALUE
# KEY is the name of a variable in the cache.
# TYPE is a hint to GUIs for the type of VALUE, DO NOT EDIT TYPE!.
# VALUE is the current value for the KEY.
########################
# EXTERNAL cache entries
########################
//Value Computed by CMake
APD_ONLY_BINARY_DIR:STATIC=/home/tomer/Github/Public-PF/cmake-build-debug
//Value Computed by CMake
APD_ONLY_IS_TOP_LEVEL:STATIC=ON
//Value Computed by CMake
APD_ONLY_SOURCE_DIR:STATIC=/home/tomer/Github/Public-PF
//Path to a program.
CMAKE_ADDR2LINE:FILEPATH=/usr/bin/addr2line
//Path to a program.
CMAKE_AR:FILEPATH=/usr/bin/ar
//Choose the type of build, options are: None Debug Release RelWithDebInfo
// MinSizeRel ...
CMAKE_BUILD_TYPE:STRING=Debug
//CXX compiler
CMAKE_CXX_COMPILER:STRING=/usr/bin/g++-10
//A wrapper around 'ar' adding the appropriate '--plugin' option
// for the GCC compiler
CMAKE_CXX_COMPILER_AR:FILEPATH=/usr/bin/gcc-ar-10
//A wrapper around 'ranlib' adding the appropriate '--plugin' option
// for the GCC compiler
CMAKE_CXX_COMPILER_RANLIB:FILEPATH=/usr/bin/gcc-ranlib-10
//Flags used by the CXX compiler during all build types.
CMAKE_CXX_FLAGS:STRING=
//Flags used by the CXX compiler during DEBUG builds.
CMAKE_CXX_FLAGS_DEBUG:STRING=-g
//Flags used by the CXX compiler during MINSIZEREL builds.
CMAKE_CXX_FLAGS_MINSIZEREL:STRING=-Os -DNDEBUG
//Flags used by the CXX compiler during RELEASE builds.
CMAKE_CXX_FLAGS_RELEASE:STRING=-O3 -DNDEBUG
//Flags used by the CXX compiler during RELWITHDEBINFO builds.
CMAKE_CXX_FLAGS_RELWITHDEBINFO:STRING=-O2 -g -DNDEBUG
//C compiler
CMAKE_C_COMPILER:STRING=/usr/bin/gcc-10
//A wrapper around 'ar' adding the appropriate '--plugin' option
// for the GCC compiler
CMAKE_C_COMPILER_AR:FILEPATH=/usr/bin/gcc-ar-10
//A wrapper around 'ranlib' adding the appropriate '--plugin' option
// for the GCC compiler
CMAKE_C_COMPILER_RANLIB:FILEPATH=/usr/bin/gcc-ranlib-10
//Flags used by the C compiler during all build types.
CMAKE_C_FLAGS:STRING=
//Flags used by the C compiler during DEBUG builds.
CMAKE_C_FLAGS_DEBUG:STRING=-g
//Flags used by the C compiler during MINSIZEREL builds.
CMAKE_C_FLAGS_MINSIZEREL:STRING=-Os -DNDEBUG
//Flags used by the C compiler during RELEASE builds.
CMAKE_C_FLAGS_RELEASE:STRING=-O3 -DNDEBUG
//Flags used by the C compiler during RELWITHDEBINFO builds.
CMAKE_C_FLAGS_RELWITHDEBINFO:STRING=-O2 -g -DNDEBUG
//Path to a program.
CMAKE_DLLTOOL:FILEPATH=CMAKE_DLLTOOL-NOTFOUND
//Flags used by the linker during all build types.
CMAKE_EXE_LINKER_FLAGS:STRING=
//Flags used by the linker during DEBUG builds.
CMAKE_EXE_LINKER_FLAGS_DEBUG:STRING=
//Flags used by the linker during MINSIZEREL builds.
CMAKE_EXE_LINKER_FLAGS_MINSIZEREL:STRING=
//Flags used by the linker during RELEASE builds.
CMAKE_EXE_LINKER_FLAGS_RELEASE:STRING=
//Flags used by the linker during RELWITHDEBINFO builds.
CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO:STRING=
//Enable/Disable output of compile commands during generation.
CMAKE_EXPORT_COMPILE_COMMANDS:BOOL=
//Install path prefix, prepended onto install directories.
CMAKE_INSTALL_PREFIX:PATH=/usr/local
//Path to a program.
CMAKE_LINKER:FILEPATH=/usr/bin/ld
//No help, variable specified on the command line.
CMAKE_MAKE_PROGRAM:UNINITIALIZED=/snap/clion/184/bin/ninja/linux/ninja
//Flags used by the linker during the creation of modules during
// all build types.
CMAKE_MODULE_LINKER_FLAGS:STRING=
//Flags used by the linker during the creation of modules during
// DEBUG builds.
CMAKE_MODULE_LINKER_FLAGS_DEBUG:STRING=
//Flags used by the linker during the creation of modules during
// MINSIZEREL builds.
CMAKE_MODULE_LINKER_FLAGS_MINSIZEREL:STRING=
//Flags used by the linker during the creation of modules during
// RELEASE builds.
CMAKE_MODULE_LINKER_FLAGS_RELEASE:STRING=
//Flags used by the linker during the creation of modules during
// RELWITHDEBINFO builds.
CMAKE_MODULE_LINKER_FLAGS_RELWITHDEBINFO:STRING=
//Path to a program.
CMAKE_NM:FILEPATH=/usr/bin/nm
//Path to a program.
CMAKE_OBJCOPY:FILEPATH=/usr/bin/objcopy
//Path to a program.
CMAKE_OBJDUMP:FILEPATH=/usr/bin/objdump
//Value Computed by CMake
CMAKE_PROJECT_DESCRIPTION:STATIC=
//Value Computed by CMake
CMAKE_PROJECT_HOMEPAGE_URL:STATIC=
//Value Computed by CMake
CMAKE_PROJECT_NAME:STATIC=APD_ONLY
//Path to a program.
CMAKE_RANLIB:FILEPATH=/usr/bin/ranlib
//Path to a program.
CMAKE_READELF:FILEPATH=/usr/bin/readelf
//Flags used by the linker during the creation of shared libraries
// during all build types.
CMAKE_SHARED_LINKER_FLAGS:STRING=
//Flags used by the linker during the creation of shared libraries
// during DEBUG builds.
CMAKE_SHARED_LINKER_FLAGS_DEBUG:STRING=
//Flags used by the linker during the creation of shared libraries
// during MINSIZEREL builds.
CMAKE_SHARED_LINKER_FLAGS_MINSIZEREL:STRING=
//Flags used by the linker during the creation of shared libraries
// during RELEASE builds.
CMAKE_SHARED_LINKER_FLAGS_RELEASE:STRING=
//Flags used by the linker during the creation of shared libraries
// during RELWITHDEBINFO builds.
CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO:STRING=
//If set, runtime paths are not added when installing shared libraries,
// but are added when building.
CMAKE_SKIP_INSTALL_RPATH:BOOL=NO
//If set, runtime paths are not added when using shared libraries.
CMAKE_SKIP_RPATH:BOOL=NO
//Flags used by the linker during the creation of static libraries
// during all build types.
CMAKE_STATIC_LINKER_FLAGS:STRING=
//Flags used by the linker during the creation of static libraries
// during DEBUG builds.
CMAKE_STATIC_LINKER_FLAGS_DEBUG:STRING=
//Flags used by the linker during the creation of static libraries
// during MINSIZEREL builds.
CMAKE_STATIC_LINKER_FLAGS_MINSIZEREL:STRING=
//Flags used by the linker during the creation of static libraries
// during RELEASE builds.
CMAKE_STATIC_LINKER_FLAGS_RELEASE:STRING=
//Flags used by the linker during the creation of static libraries
// during RELWITHDEBINFO builds.
CMAKE_STATIC_LINKER_FLAGS_RELWITHDEBINFO:STRING=
//Path to a program.
CMAKE_STRIP:FILEPATH=/usr/bin/strip
//If this value is on, makefiles will be generated without the
// .SILENT directive, and all commands will be echoed to the console
// during the make. This is useful for debugging only. With Visual
// Studio IDE projects all commands are done without /nologo.
CMAKE_VERBOSE_MAKEFILE:BOOL=FALSE
########################
# INTERNAL cache entries
########################
//ADVANCED property for variable: CMAKE_ADDR2LINE
CMAKE_ADDR2LINE-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_AR
CMAKE_AR-ADVANCED:INTERNAL=1
//This is the directory where this CMakeCache.txt was created
CMAKE_CACHEFILE_DIR:INTERNAL=/home/tomer/Github/Public-PF/cmake-build-debug
//Major version of cmake used to create the current loaded cache
CMAKE_CACHE_MAJOR_VERSION:INTERNAL=3
//Minor version of cmake used to create the current loaded cache
CMAKE_CACHE_MINOR_VERSION:INTERNAL=21
//Patch version of cmake used to create the current loaded cache
CMAKE_CACHE_PATCH_VERSION:INTERNAL=1
//Path to CMake executable.
CMAKE_COMMAND:INTERNAL=/snap/clion/184/bin/cmake/linux/bin/cmake
//Path to cpack program executable.
CMAKE_CPACK_COMMAND:INTERNAL=/snap/clion/184/bin/cmake/linux/bin/cpack
//Path to ctest program executable.
CMAKE_CTEST_COMMAND:INTERNAL=/snap/clion/184/bin/cmake/linux/bin/ctest
//ADVANCED property for variable: CMAKE_CXX_COMPILER
CMAKE_CXX_COMPILER-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_CXX_COMPILER_AR
CMAKE_CXX_COMPILER_AR-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_CXX_COMPILER_RANLIB
CMAKE_CXX_COMPILER_RANLIB-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_CXX_FLAGS
CMAKE_CXX_FLAGS-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_CXX_FLAGS_DEBUG
CMAKE_CXX_FLAGS_DEBUG-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_CXX_FLAGS_MINSIZEREL
CMAKE_CXX_FLAGS_MINSIZEREL-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_CXX_FLAGS_RELEASE
CMAKE_CXX_FLAGS_RELEASE-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_CXX_FLAGS_RELWITHDEBINFO
CMAKE_CXX_FLAGS_RELWITHDEBINFO-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_C_COMPILER
CMAKE_C_COMPILER-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_C_COMPILER_AR
CMAKE_C_COMPILER_AR-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_C_COMPILER_RANLIB
CMAKE_C_COMPILER_RANLIB-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_C_FLAGS
CMAKE_C_FLAGS-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_C_FLAGS_DEBUG
CMAKE_C_FLAGS_DEBUG-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_C_FLAGS_MINSIZEREL
CMAKE_C_FLAGS_MINSIZEREL-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_C_FLAGS_RELEASE
CMAKE_C_FLAGS_RELEASE-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_C_FLAGS_RELWITHDEBINFO
CMAKE_C_FLAGS_RELWITHDEBINFO-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_DLLTOOL
CMAKE_DLLTOOL-ADVANCED:INTERNAL=1
//Executable file format
CMAKE_EXECUTABLE_FORMAT:INTERNAL=ELF
//ADVANCED property for variable: CMAKE_EXE_LINKER_FLAGS
CMAKE_EXE_LINKER_FLAGS-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_EXE_LINKER_FLAGS_DEBUG
CMAKE_EXE_LINKER_FLAGS_DEBUG-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_EXE_LINKER_FLAGS_MINSIZEREL
CMAKE_EXE_LINKER_FLAGS_MINSIZEREL-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_EXE_LINKER_FLAGS_RELEASE
CMAKE_EXE_LINKER_FLAGS_RELEASE-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO
CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_EXPORT_COMPILE_COMMANDS
CMAKE_EXPORT_COMPILE_COMMANDS-ADVANCED:INTERNAL=1
//Name of external makefile project generator.
CMAKE_EXTRA_GENERATOR:INTERNAL=
//Name of generator.
CMAKE_GENERATOR:INTERNAL=Ninja
//Generator instance identifier.
CMAKE_GENERATOR_INSTANCE:INTERNAL=
//Name of generator platform.
CMAKE_GENERATOR_PLATFORM:INTERNAL=
//Name of generator toolset.
CMAKE_GENERATOR_TOOLSET:INTERNAL=
//Source directory with the top level CMakeLists.txt file for this
// project
CMAKE_HOME_DIRECTORY:INTERNAL=/home/tomer/Github/Public-PF
//Install .so files without execute permission.
CMAKE_INSTALL_SO_NO_EXE:INTERNAL=1
//ADVANCED property for variable: CMAKE_LINKER
CMAKE_LINKER-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_MODULE_LINKER_FLAGS
CMAKE_MODULE_LINKER_FLAGS-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_MODULE_LINKER_FLAGS_DEBUG
CMAKE_MODULE_LINKER_FLAGS_DEBUG-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_MODULE_LINKER_FLAGS_MINSIZEREL
CMAKE_MODULE_LINKER_FLAGS_MINSIZEREL-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_MODULE_LINKER_FLAGS_RELEASE
CMAKE_MODULE_LINKER_FLAGS_RELEASE-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_MODULE_LINKER_FLAGS_RELWITHDEBINFO
CMAKE_MODULE_LINKER_FLAGS_RELWITHDEBINFO-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_NM
CMAKE_NM-ADVANCED:INTERNAL=1
//number of local generators
CMAKE_NUMBER_OF_MAKEFILES:INTERNAL=1
//ADVANCED property for variable: CMAKE_OBJCOPY
CMAKE_OBJCOPY-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_OBJDUMP
CMAKE_OBJDUMP-ADVANCED:INTERNAL=1
//Platform information initialized
CMAKE_PLATFORM_INFO_INITIALIZED:INTERNAL=1
//ADVANCED property for variable: CMAKE_RANLIB
CMAKE_RANLIB-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_READELF
CMAKE_READELF-ADVANCED:INTERNAL=1
//Path to CMake installation.
CMAKE_ROOT:INTERNAL=/snap/clion/184/bin/cmake/linux/share/cmake-3.21
//ADVANCED property for variable: CMAKE_SHARED_LINKER_FLAGS
CMAKE_SHARED_LINKER_FLAGS-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_SHARED_LINKER_FLAGS_DEBUG
CMAKE_SHARED_LINKER_FLAGS_DEBUG-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_SHARED_LINKER_FLAGS_MINSIZEREL
CMAKE_SHARED_LINKER_FLAGS_MINSIZEREL-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_SHARED_LINKER_FLAGS_RELEASE
CMAKE_SHARED_LINKER_FLAGS_RELEASE-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO
CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_SKIP_INSTALL_RPATH
CMAKE_SKIP_INSTALL_RPATH-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_SKIP_RPATH
CMAKE_SKIP_RPATH-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_STATIC_LINKER_FLAGS
CMAKE_STATIC_LINKER_FLAGS-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_STATIC_LINKER_FLAGS_DEBUG
CMAKE_STATIC_LINKER_FLAGS_DEBUG-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_STATIC_LINKER_FLAGS_MINSIZEREL
CMAKE_STATIC_LINKER_FLAGS_MINSIZEREL-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_STATIC_LINKER_FLAGS_RELEASE
CMAKE_STATIC_LINKER_FLAGS_RELEASE-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_STATIC_LINKER_FLAGS_RELWITHDEBINFO
CMAKE_STATIC_LINKER_FLAGS_RELWITHDEBINFO-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_STRIP
CMAKE_STRIP-ADVANCED:INTERNAL=1
//uname command
CMAKE_UNAME:INTERNAL=/usr/bin/uname
//ADVANCED property for variable: CMAKE_VERBOSE_MAKEFILE
CMAKE_VERBOSE_MAKEFILE-ADVANCED:INTERNAL=1

View File

@ -0,0 +1,80 @@
set(CMAKE_C_COMPILER "/usr/bin/gcc-10")
set(CMAKE_C_COMPILER_ARG1 "")
set(CMAKE_C_COMPILER_ID "GNU")
set(CMAKE_C_COMPILER_VERSION "10.3.0")
set(CMAKE_C_COMPILER_VERSION_INTERNAL "")
set(CMAKE_C_COMPILER_WRAPPER "")
set(CMAKE_C_STANDARD_COMPUTED_DEFAULT "17")
set(CMAKE_C_COMPILE_FEATURES "c_std_90;c_function_prototypes;c_std_99;c_restrict;c_variadic_macros;c_std_11;c_static_assert;c_std_17;c_std_23")
set(CMAKE_C90_COMPILE_FEATURES "c_std_90;c_function_prototypes")
set(CMAKE_C99_COMPILE_FEATURES "c_std_99;c_restrict;c_variadic_macros")
set(CMAKE_C11_COMPILE_FEATURES "c_std_11;c_static_assert")
set(CMAKE_C17_COMPILE_FEATURES "c_std_17")
set(CMAKE_C23_COMPILE_FEATURES "c_std_23")
set(CMAKE_C_PLATFORM_ID "Linux")
set(CMAKE_C_SIMULATE_ID "")
set(CMAKE_C_COMPILER_FRONTEND_VARIANT "")
set(CMAKE_C_SIMULATE_VERSION "")
set(CMAKE_AR "/usr/bin/ar")
set(CMAKE_C_COMPILER_AR "/usr/bin/gcc-ar-10")
set(CMAKE_RANLIB "/usr/bin/ranlib")
set(CMAKE_C_COMPILER_RANLIB "/usr/bin/gcc-ranlib-10")
set(CMAKE_LINKER "/usr/bin/ld")
set(CMAKE_MT "")
set(CMAKE_COMPILER_IS_GNUCC 1)
set(CMAKE_C_COMPILER_LOADED 1)
set(CMAKE_C_COMPILER_WORKS TRUE)
set(CMAKE_C_ABI_COMPILED TRUE)
set(CMAKE_COMPILER_IS_MINGW )
set(CMAKE_COMPILER_IS_CYGWIN )
if(CMAKE_COMPILER_IS_CYGWIN)
set(CYGWIN 1)
set(UNIX 1)
endif()
set(CMAKE_C_COMPILER_ENV_VAR "CC")
if(CMAKE_COMPILER_IS_MINGW)
set(MINGW 1)
endif()
set(CMAKE_C_COMPILER_ID_RUN 1)
set(CMAKE_C_SOURCE_FILE_EXTENSIONS c;m)
set(CMAKE_C_IGNORE_EXTENSIONS h;H;o;O;obj;OBJ;def;DEF;rc;RC)
set(CMAKE_C_LINKER_PREFERENCE 10)
# Save compiler ABI information.
set(CMAKE_C_SIZEOF_DATA_PTR "8")
set(CMAKE_C_COMPILER_ABI "ELF")
set(CMAKE_C_BYTE_ORDER "LITTLE_ENDIAN")
set(CMAKE_C_LIBRARY_ARCHITECTURE "x86_64-linux-gnu")
if(CMAKE_C_SIZEOF_DATA_PTR)
set(CMAKE_SIZEOF_VOID_P "${CMAKE_C_SIZEOF_DATA_PTR}")
endif()
if(CMAKE_C_COMPILER_ABI)
set(CMAKE_INTERNAL_PLATFORM_ABI "${CMAKE_C_COMPILER_ABI}")
endif()
if(CMAKE_C_LIBRARY_ARCHITECTURE)
set(CMAKE_LIBRARY_ARCHITECTURE "x86_64-linux-gnu")
endif()
set(CMAKE_C_CL_SHOWINCLUDES_PREFIX "")
if(CMAKE_C_CL_SHOWINCLUDES_PREFIX)
set(CMAKE_CL_SHOWINCLUDES_PREFIX "${CMAKE_C_CL_SHOWINCLUDES_PREFIX}")
endif()
set(CMAKE_C_IMPLICIT_INCLUDE_DIRECTORIES "/usr/lib/gcc/x86_64-linux-gnu/10/include;/usr/local/include;/usr/include/x86_64-linux-gnu;/usr/include")
set(CMAKE_C_IMPLICIT_LINK_LIBRARIES "gcc;gcc_s;c;gcc;gcc_s")
set(CMAKE_C_IMPLICIT_LINK_DIRECTORIES "/usr/lib/gcc/x86_64-linux-gnu/10;/usr/lib/x86_64-linux-gnu;/usr/lib;/lib/x86_64-linux-gnu;/lib")
set(CMAKE_C_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES "")

View File

@ -0,0 +1,91 @@
set(CMAKE_CXX_COMPILER "/usr/bin/g++-10")
set(CMAKE_CXX_COMPILER_ARG1 "")
set(CMAKE_CXX_COMPILER_ID "GNU")
set(CMAKE_CXX_COMPILER_VERSION "10.3.0")
set(CMAKE_CXX_COMPILER_VERSION_INTERNAL "")
set(CMAKE_CXX_COMPILER_WRAPPER "")
set(CMAKE_CXX_STANDARD_COMPUTED_DEFAULT "14")
set(CMAKE_CXX_COMPILE_FEATURES "cxx_std_98;cxx_template_template_parameters;cxx_std_11;cxx_alias_templates;cxx_alignas;cxx_alignof;cxx_attributes;cxx_auto_type;cxx_constexpr;cxx_decltype;cxx_decltype_incomplete_return_types;cxx_default_function_template_args;cxx_defaulted_functions;cxx_defaulted_move_initializers;cxx_delegating_constructors;cxx_deleted_functions;cxx_enum_forward_declarations;cxx_explicit_conversions;cxx_extended_friend_declarations;cxx_extern_templates;cxx_final;cxx_func_identifier;cxx_generalized_initializers;cxx_inheriting_constructors;cxx_inline_namespaces;cxx_lambdas;cxx_local_type_template_args;cxx_long_long_type;cxx_noexcept;cxx_nonstatic_member_init;cxx_nullptr;cxx_override;cxx_range_for;cxx_raw_string_literals;cxx_reference_qualified_functions;cxx_right_angle_brackets;cxx_rvalue_references;cxx_sizeof_member;cxx_static_assert;cxx_strong_enums;cxx_thread_local;cxx_trailing_return_types;cxx_unicode_literals;cxx_uniform_initialization;cxx_unrestricted_unions;cxx_user_literals;cxx_variadic_macros;cxx_variadic_templates;cxx_std_14;cxx_aggregate_default_initializers;cxx_attribute_deprecated;cxx_binary_literals;cxx_contextual_conversions;cxx_decltype_auto;cxx_digit_separators;cxx_generic_lambdas;cxx_lambda_init_captures;cxx_relaxed_constexpr;cxx_return_type_deduction;cxx_variable_templates;cxx_std_17;cxx_std_20")
set(CMAKE_CXX98_COMPILE_FEATURES "cxx_std_98;cxx_template_template_parameters")
set(CMAKE_CXX11_COMPILE_FEATURES "cxx_std_11;cxx_alias_templates;cxx_alignas;cxx_alignof;cxx_attributes;cxx_auto_type;cxx_constexpr;cxx_decltype;cxx_decltype_incomplete_return_types;cxx_default_function_template_args;cxx_defaulted_functions;cxx_defaulted_move_initializers;cxx_delegating_constructors;cxx_deleted_functions;cxx_enum_forward_declarations;cxx_explicit_conversions;cxx_extended_friend_declarations;cxx_extern_templates;cxx_final;cxx_func_identifier;cxx_generalized_initializers;cxx_inheriting_constructors;cxx_inline_namespaces;cxx_lambdas;cxx_local_type_template_args;cxx_long_long_type;cxx_noexcept;cxx_nonstatic_member_init;cxx_nullptr;cxx_override;cxx_range_for;cxx_raw_string_literals;cxx_reference_qualified_functions;cxx_right_angle_brackets;cxx_rvalue_references;cxx_sizeof_member;cxx_static_assert;cxx_strong_enums;cxx_thread_local;cxx_trailing_return_types;cxx_unicode_literals;cxx_uniform_initialization;cxx_unrestricted_unions;cxx_user_literals;cxx_variadic_macros;cxx_variadic_templates")
set(CMAKE_CXX14_COMPILE_FEATURES "cxx_std_14;cxx_aggregate_default_initializers;cxx_attribute_deprecated;cxx_binary_literals;cxx_contextual_conversions;cxx_decltype_auto;cxx_digit_separators;cxx_generic_lambdas;cxx_lambda_init_captures;cxx_relaxed_constexpr;cxx_return_type_deduction;cxx_variable_templates")
set(CMAKE_CXX17_COMPILE_FEATURES "cxx_std_17")
set(CMAKE_CXX20_COMPILE_FEATURES "cxx_std_20")
set(CMAKE_CXX23_COMPILE_FEATURES "")
set(CMAKE_CXX_PLATFORM_ID "Linux")
set(CMAKE_CXX_SIMULATE_ID "")
set(CMAKE_CXX_COMPILER_FRONTEND_VARIANT "")
set(CMAKE_CXX_SIMULATE_VERSION "")
set(CMAKE_AR "/usr/bin/ar")
set(CMAKE_CXX_COMPILER_AR "/usr/bin/gcc-ar-10")
set(CMAKE_RANLIB "/usr/bin/ranlib")
set(CMAKE_CXX_COMPILER_RANLIB "/usr/bin/gcc-ranlib-10")
set(CMAKE_LINKER "/usr/bin/ld")
set(CMAKE_MT "")
set(CMAKE_COMPILER_IS_GNUCXX 1)
set(CMAKE_CXX_COMPILER_LOADED 1)
set(CMAKE_CXX_COMPILER_WORKS TRUE)
set(CMAKE_CXX_ABI_COMPILED TRUE)
set(CMAKE_COMPILER_IS_MINGW )
set(CMAKE_COMPILER_IS_CYGWIN )
if(CMAKE_COMPILER_IS_CYGWIN)
set(CYGWIN 1)
set(UNIX 1)
endif()
set(CMAKE_CXX_COMPILER_ENV_VAR "CXX")
if(CMAKE_COMPILER_IS_MINGW)
set(MINGW 1)
endif()
set(CMAKE_CXX_COMPILER_ID_RUN 1)
set(CMAKE_CXX_SOURCE_FILE_EXTENSIONS C;M;c++;cc;cpp;cxx;m;mm;mpp;CPP;ixx;cppm)
set(CMAKE_CXX_IGNORE_EXTENSIONS inl;h;hpp;HPP;H;o;O;obj;OBJ;def;DEF;rc;RC)
foreach (lang C OBJC OBJCXX)
if (CMAKE_${lang}_COMPILER_ID_RUN)
foreach(extension IN LISTS CMAKE_${lang}_SOURCE_FILE_EXTENSIONS)
list(REMOVE_ITEM CMAKE_CXX_SOURCE_FILE_EXTENSIONS ${extension})
endforeach()
endif()
endforeach()
set(CMAKE_CXX_LINKER_PREFERENCE 30)
set(CMAKE_CXX_LINKER_PREFERENCE_PROPAGATES 1)
# Save compiler ABI information.
set(CMAKE_CXX_SIZEOF_DATA_PTR "8")
set(CMAKE_CXX_COMPILER_ABI "ELF")
set(CMAKE_CXX_BYTE_ORDER "LITTLE_ENDIAN")
set(CMAKE_CXX_LIBRARY_ARCHITECTURE "x86_64-linux-gnu")
if(CMAKE_CXX_SIZEOF_DATA_PTR)
set(CMAKE_SIZEOF_VOID_P "${CMAKE_CXX_SIZEOF_DATA_PTR}")
endif()
if(CMAKE_CXX_COMPILER_ABI)
set(CMAKE_INTERNAL_PLATFORM_ABI "${CMAKE_CXX_COMPILER_ABI}")
endif()
if(CMAKE_CXX_LIBRARY_ARCHITECTURE)
set(CMAKE_LIBRARY_ARCHITECTURE "x86_64-linux-gnu")
endif()
set(CMAKE_CXX_CL_SHOWINCLUDES_PREFIX "")
if(CMAKE_CXX_CL_SHOWINCLUDES_PREFIX)
set(CMAKE_CL_SHOWINCLUDES_PREFIX "${CMAKE_CXX_CL_SHOWINCLUDES_PREFIX}")
endif()
set(CMAKE_CXX_IMPLICIT_INCLUDE_DIRECTORIES "/usr/include/c++/10;/usr/include/x86_64-linux-gnu/c++/10;/usr/include/c++/10/backward;/usr/lib/gcc/x86_64-linux-gnu/10/include;/usr/local/include;/usr/include/x86_64-linux-gnu;/usr/include")
set(CMAKE_CXX_IMPLICIT_LINK_LIBRARIES "stdc++;m;gcc_s;gcc;c;gcc_s;gcc")
set(CMAKE_CXX_IMPLICIT_LINK_DIRECTORIES "/usr/lib/gcc/x86_64-linux-gnu/10;/usr/lib/x86_64-linux-gnu;/usr/lib;/lib/x86_64-linux-gnu;/lib")
set(CMAKE_CXX_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES "")

View File

@ -0,0 +1,15 @@
set(CMAKE_HOST_SYSTEM "Linux-5.14.0-1027-oem")
set(CMAKE_HOST_SYSTEM_NAME "Linux")
set(CMAKE_HOST_SYSTEM_VERSION "5.14.0-1027-oem")
set(CMAKE_HOST_SYSTEM_PROCESSOR "x86_64")
set(CMAKE_SYSTEM "Linux-5.14.0-1027-oem")
set(CMAKE_SYSTEM_NAME "Linux")
set(CMAKE_SYSTEM_VERSION "5.14.0-1027-oem")
set(CMAKE_SYSTEM_PROCESSOR "x86_64")
set(CMAKE_CROSSCOMPILING "FALSE")
set(CMAKE_SYSTEM_LOADED 1)

View File

@ -0,0 +1,807 @@
#ifdef __cplusplus
# error "A C++ compiler has been selected for C."
#endif
#if defined(__18CXX)
# define ID_VOID_MAIN
#endif
#if defined(__CLASSIC_C__)
/* cv-qualifiers did not exist in K&R C */
# define const
# define volatile
#endif
#if !defined(__has_include)
/* If the compiler does not have __has_include, pretend the answer is
always no. */
# define __has_include(x) 0
#endif
/* Version number components: V=Version, R=Revision, P=Patch
Version date components: YYYY=Year, MM=Month, DD=Day */
#if defined(__INTEL_COMPILER) || defined(__ICC)
# define COMPILER_ID "Intel"
# if defined(_MSC_VER)
# define SIMULATE_ID "MSVC"
# endif
# if defined(__GNUC__)
# define SIMULATE_ID "GNU"
# endif
/* __INTEL_COMPILER = VRP prior to 2021, and then VVVV for 2021 and later,
except that a few beta releases use the old format with V=2021. */
# if __INTEL_COMPILER < 2021 || __INTEL_COMPILER == 202110 || __INTEL_COMPILER == 202111
# define COMPILER_VERSION_MAJOR DEC(__INTEL_COMPILER/100)
# define COMPILER_VERSION_MINOR DEC(__INTEL_COMPILER/10 % 10)
# if defined(__INTEL_COMPILER_UPDATE)
# define COMPILER_VERSION_PATCH DEC(__INTEL_COMPILER_UPDATE)
# else
# define COMPILER_VERSION_PATCH DEC(__INTEL_COMPILER % 10)
# endif
# else
# define COMPILER_VERSION_MAJOR DEC(__INTEL_COMPILER)
# define COMPILER_VERSION_MINOR DEC(__INTEL_COMPILER_UPDATE)
/* The third version component from --version is an update index,
but no macro is provided for it. */
# define COMPILER_VERSION_PATCH DEC(0)
# endif
# if defined(__INTEL_COMPILER_BUILD_DATE)
/* __INTEL_COMPILER_BUILD_DATE = YYYYMMDD */
# define COMPILER_VERSION_TWEAK DEC(__INTEL_COMPILER_BUILD_DATE)
# endif
# if defined(_MSC_VER)
/* _MSC_VER = VVRR */
# define SIMULATE_VERSION_MAJOR DEC(_MSC_VER / 100)
# define SIMULATE_VERSION_MINOR DEC(_MSC_VER % 100)
# endif
# if defined(__GNUC__)
# define SIMULATE_VERSION_MAJOR DEC(__GNUC__)
# elif defined(__GNUG__)
# define SIMULATE_VERSION_MAJOR DEC(__GNUG__)
# endif
# if defined(__GNUC_MINOR__)
# define SIMULATE_VERSION_MINOR DEC(__GNUC_MINOR__)
# endif
# if defined(__GNUC_PATCHLEVEL__)
# define SIMULATE_VERSION_PATCH DEC(__GNUC_PATCHLEVEL__)
# endif
#elif (defined(__clang__) && defined(__INTEL_CLANG_COMPILER)) || defined(__INTEL_LLVM_COMPILER)
# define COMPILER_ID "IntelLLVM"
#if defined(_MSC_VER)
# define SIMULATE_ID "MSVC"
#endif
#if defined(__GNUC__)
# define SIMULATE_ID "GNU"
#endif
/* __INTEL_LLVM_COMPILER = VVVVRP prior to 2021.2.0, VVVVRRPP for 2021.2.0 and
* later. Look for 6 digit vs. 8 digit version number to decide encoding.
* VVVV is no smaller than the current year when a version is released.
*/
#if __INTEL_LLVM_COMPILER < 1000000L
# define COMPILER_VERSION_MAJOR DEC(__INTEL_LLVM_COMPILER/100)
# define COMPILER_VERSION_MINOR DEC(__INTEL_LLVM_COMPILER/10 % 10)
# define COMPILER_VERSION_PATCH DEC(__INTEL_LLVM_COMPILER % 10)
#else
# define COMPILER_VERSION_MAJOR DEC(__INTEL_LLVM_COMPILER/10000)
# define COMPILER_VERSION_MINOR DEC(__INTEL_LLVM_COMPILER/100 % 100)
# define COMPILER_VERSION_PATCH DEC(__INTEL_LLVM_COMPILER % 100)
#endif
#if defined(_MSC_VER)
/* _MSC_VER = VVRR */
# define SIMULATE_VERSION_MAJOR DEC(_MSC_VER / 100)
# define SIMULATE_VERSION_MINOR DEC(_MSC_VER % 100)
#endif
#if defined(__GNUC__)
# define SIMULATE_VERSION_MAJOR DEC(__GNUC__)
#elif defined(__GNUG__)
# define SIMULATE_VERSION_MAJOR DEC(__GNUG__)
#endif
#if defined(__GNUC_MINOR__)
# define SIMULATE_VERSION_MINOR DEC(__GNUC_MINOR__)
#endif
#if defined(__GNUC_PATCHLEVEL__)
# define SIMULATE_VERSION_PATCH DEC(__GNUC_PATCHLEVEL__)
#endif
#elif defined(__PATHCC__)
# define COMPILER_ID "PathScale"
# define COMPILER_VERSION_MAJOR DEC(__PATHCC__)
# define COMPILER_VERSION_MINOR DEC(__PATHCC_MINOR__)
# if defined(__PATHCC_PATCHLEVEL__)
# define COMPILER_VERSION_PATCH DEC(__PATHCC_PATCHLEVEL__)
# endif
#elif defined(__BORLANDC__) && defined(__CODEGEARC_VERSION__)
# define COMPILER_ID "Embarcadero"
# define COMPILER_VERSION_MAJOR HEX(__CODEGEARC_VERSION__>>24 & 0x00FF)
# define COMPILER_VERSION_MINOR HEX(__CODEGEARC_VERSION__>>16 & 0x00FF)
# define COMPILER_VERSION_PATCH DEC(__CODEGEARC_VERSION__ & 0xFFFF)
#elif defined(__BORLANDC__)
# define COMPILER_ID "Borland"
/* __BORLANDC__ = 0xVRR */
# define COMPILER_VERSION_MAJOR HEX(__BORLANDC__>>8)
# define COMPILER_VERSION_MINOR HEX(__BORLANDC__ & 0xFF)
#elif defined(__WATCOMC__) && __WATCOMC__ < 1200
# define COMPILER_ID "Watcom"
/* __WATCOMC__ = VVRR */
# define COMPILER_VERSION_MAJOR DEC(__WATCOMC__ / 100)
# define COMPILER_VERSION_MINOR DEC((__WATCOMC__ / 10) % 10)
# if (__WATCOMC__ % 10) > 0
# define COMPILER_VERSION_PATCH DEC(__WATCOMC__ % 10)
# endif
#elif defined(__WATCOMC__)
# define COMPILER_ID "OpenWatcom"
/* __WATCOMC__ = VVRP + 1100 */
# define COMPILER_VERSION_MAJOR DEC((__WATCOMC__ - 1100) / 100)
# define COMPILER_VERSION_MINOR DEC((__WATCOMC__ / 10) % 10)
# if (__WATCOMC__ % 10) > 0
# define COMPILER_VERSION_PATCH DEC(__WATCOMC__ % 10)
# endif
#elif defined(__SUNPRO_C)
# define COMPILER_ID "SunPro"
# if __SUNPRO_C >= 0x5100
/* __SUNPRO_C = 0xVRRP */
# define COMPILER_VERSION_MAJOR HEX(__SUNPRO_C>>12)
# define COMPILER_VERSION_MINOR HEX(__SUNPRO_C>>4 & 0xFF)
# define COMPILER_VERSION_PATCH HEX(__SUNPRO_C & 0xF)
# else
/* __SUNPRO_CC = 0xVRP */
# define COMPILER_VERSION_MAJOR HEX(__SUNPRO_C>>8)
# define COMPILER_VERSION_MINOR HEX(__SUNPRO_C>>4 & 0xF)
# define COMPILER_VERSION_PATCH HEX(__SUNPRO_C & 0xF)
# endif
#elif defined(__HP_cc)
# define COMPILER_ID "HP"
/* __HP_cc = VVRRPP */
# define COMPILER_VERSION_MAJOR DEC(__HP_cc/10000)
# define COMPILER_VERSION_MINOR DEC(__HP_cc/100 % 100)
# define COMPILER_VERSION_PATCH DEC(__HP_cc % 100)
#elif defined(__DECC)
# define COMPILER_ID "Compaq"
/* __DECC_VER = VVRRTPPPP */
# define COMPILER_VERSION_MAJOR DEC(__DECC_VER/10000000)
# define COMPILER_VERSION_MINOR DEC(__DECC_VER/100000 % 100)
# define COMPILER_VERSION_PATCH DEC(__DECC_VER % 10000)
#elif defined(__IBMC__) && defined(__COMPILER_VER__)
# define COMPILER_ID "zOS"
/* __IBMC__ = VRP */
# define COMPILER_VERSION_MAJOR DEC(__IBMC__/100)
# define COMPILER_VERSION_MINOR DEC(__IBMC__/10 % 10)
# define COMPILER_VERSION_PATCH DEC(__IBMC__ % 10)
#elif defined(__ibmxl__) && defined(__clang__)
# define COMPILER_ID "XLClang"
# define COMPILER_VERSION_MAJOR DEC(__ibmxl_version__)
# define COMPILER_VERSION_MINOR DEC(__ibmxl_release__)
# define COMPILER_VERSION_PATCH DEC(__ibmxl_modification__)
# define COMPILER_VERSION_TWEAK DEC(__ibmxl_ptf_fix_level__)
#elif defined(__IBMC__) && !defined(__COMPILER_VER__) && __IBMC__ >= 800
# define COMPILER_ID "XL"
/* __IBMC__ = VRP */
# define COMPILER_VERSION_MAJOR DEC(__IBMC__/100)
# define COMPILER_VERSION_MINOR DEC(__IBMC__/10 % 10)
# define COMPILER_VERSION_PATCH DEC(__IBMC__ % 10)
#elif defined(__IBMC__) && !defined(__COMPILER_VER__) && __IBMC__ < 800
# define COMPILER_ID "VisualAge"
/* __IBMC__ = VRP */
# define COMPILER_VERSION_MAJOR DEC(__IBMC__/100)
# define COMPILER_VERSION_MINOR DEC(__IBMC__/10 % 10)
# define COMPILER_VERSION_PATCH DEC(__IBMC__ % 10)
#elif defined(__NVCOMPILER)
# define COMPILER_ID "NVHPC"
# define COMPILER_VERSION_MAJOR DEC(__NVCOMPILER_MAJOR__)
# define COMPILER_VERSION_MINOR DEC(__NVCOMPILER_MINOR__)
# if defined(__NVCOMPILER_PATCHLEVEL__)
# define COMPILER_VERSION_PATCH DEC(__NVCOMPILER_PATCHLEVEL__)
# endif
#elif defined(__PGI)
# define COMPILER_ID "PGI"
# define COMPILER_VERSION_MAJOR DEC(__PGIC__)
# define COMPILER_VERSION_MINOR DEC(__PGIC_MINOR__)
# if defined(__PGIC_PATCHLEVEL__)
# define COMPILER_VERSION_PATCH DEC(__PGIC_PATCHLEVEL__)
# endif
#elif defined(_CRAYC)
# define COMPILER_ID "Cray"
# define COMPILER_VERSION_MAJOR DEC(_RELEASE_MAJOR)
# define COMPILER_VERSION_MINOR DEC(_RELEASE_MINOR)
#elif defined(__TI_COMPILER_VERSION__)
# define COMPILER_ID "TI"
/* __TI_COMPILER_VERSION__ = VVVRRRPPP */
# define COMPILER_VERSION_MAJOR DEC(__TI_COMPILER_VERSION__/1000000)
# define COMPILER_VERSION_MINOR DEC(__TI_COMPILER_VERSION__/1000 % 1000)
# define COMPILER_VERSION_PATCH DEC(__TI_COMPILER_VERSION__ % 1000)
#elif defined(__CLANG_FUJITSU)
# define COMPILER_ID "FujitsuClang"
# define COMPILER_VERSION_MAJOR DEC(__FCC_major__)
# define COMPILER_VERSION_MINOR DEC(__FCC_minor__)
# define COMPILER_VERSION_PATCH DEC(__FCC_patchlevel__)
# define COMPILER_VERSION_INTERNAL_STR __clang_version__
#elif defined(__FUJITSU)
# define COMPILER_ID "Fujitsu"
# if defined(__FCC_version__)
# define COMPILER_VERSION __FCC_version__
# elif defined(__FCC_major__)
# define COMPILER_VERSION_MAJOR DEC(__FCC_major__)
# define COMPILER_VERSION_MINOR DEC(__FCC_minor__)
# define COMPILER_VERSION_PATCH DEC(__FCC_patchlevel__)
# endif
# if defined(__fcc_version)
# define COMPILER_VERSION_INTERNAL DEC(__fcc_version)
# elif defined(__FCC_VERSION)
# define COMPILER_VERSION_INTERNAL DEC(__FCC_VERSION)
# endif
#elif defined(__ghs__)
# define COMPILER_ID "GHS"
/* __GHS_VERSION_NUMBER = VVVVRP */
# ifdef __GHS_VERSION_NUMBER
# define COMPILER_VERSION_MAJOR DEC(__GHS_VERSION_NUMBER / 100)
# define COMPILER_VERSION_MINOR DEC(__GHS_VERSION_NUMBER / 10 % 10)
# define COMPILER_VERSION_PATCH DEC(__GHS_VERSION_NUMBER % 10)
# endif
#elif defined(__TINYC__)
# define COMPILER_ID "TinyCC"
#elif defined(__BCC__)
# define COMPILER_ID "Bruce"
#elif defined(__SCO_VERSION__)
# define COMPILER_ID "SCO"
#elif defined(__ARMCC_VERSION) && !defined(__clang__)
# define COMPILER_ID "ARMCC"
#if __ARMCC_VERSION >= 1000000
/* __ARMCC_VERSION = VRRPPPP */
# define COMPILER_VERSION_MAJOR DEC(__ARMCC_VERSION/1000000)
# define COMPILER_VERSION_MINOR DEC(__ARMCC_VERSION/10000 % 100)
# define COMPILER_VERSION_PATCH DEC(__ARMCC_VERSION % 10000)
#else
/* __ARMCC_VERSION = VRPPPP */
# define COMPILER_VERSION_MAJOR DEC(__ARMCC_VERSION/100000)
# define COMPILER_VERSION_MINOR DEC(__ARMCC_VERSION/10000 % 10)
# define COMPILER_VERSION_PATCH DEC(__ARMCC_VERSION % 10000)
#endif
#elif defined(__clang__) && defined(__apple_build_version__)
# define COMPILER_ID "AppleClang"
# if defined(_MSC_VER)
# define SIMULATE_ID "MSVC"
# endif
# define COMPILER_VERSION_MAJOR DEC(__clang_major__)
# define COMPILER_VERSION_MINOR DEC(__clang_minor__)
# define COMPILER_VERSION_PATCH DEC(__clang_patchlevel__)
# if defined(_MSC_VER)
/* _MSC_VER = VVRR */
# define SIMULATE_VERSION_MAJOR DEC(_MSC_VER / 100)
# define SIMULATE_VERSION_MINOR DEC(_MSC_VER % 100)
# endif
# define COMPILER_VERSION_TWEAK DEC(__apple_build_version__)
#elif defined(__clang__) && defined(__ARMCOMPILER_VERSION)
# define COMPILER_ID "ARMClang"
# define COMPILER_VERSION_MAJOR DEC(__ARMCOMPILER_VERSION/1000000)
# define COMPILER_VERSION_MINOR DEC(__ARMCOMPILER_VERSION/10000 % 100)
# define COMPILER_VERSION_PATCH DEC(__ARMCOMPILER_VERSION % 10000)
# define COMPILER_VERSION_INTERNAL DEC(__ARMCOMPILER_VERSION)
#elif defined(__clang__) && __has_include(<hip/hip_version.h>)
# define COMPILER_ID "ROCMClang"
# if defined(_MSC_VER)
# define SIMULATE_ID "MSVC"
# elif defined(__clang__)
# define SIMULATE_ID "Clang"
# elif defined(__GNUC__)
# define SIMULATE_ID "GNU"
# endif
# if defined(__clang__) && __has_include(<hip/hip_version.h>)
# include <hip/hip_version.h>
# define COMPILER_VERSION_MAJOR DEC(HIP_VERSION_MAJOR)
# define COMPILER_VERSION_MINOR DEC(HIP_VERSION_MINOR)
# define COMPILER_VERSION_PATCH DEC(HIP_VERSION_PATCH)
# endif
#elif defined(__clang__)
# define COMPILER_ID "Clang"
# if defined(_MSC_VER)
# define SIMULATE_ID "MSVC"
# endif
# define COMPILER_VERSION_MAJOR DEC(__clang_major__)
# define COMPILER_VERSION_MINOR DEC(__clang_minor__)
# define COMPILER_VERSION_PATCH DEC(__clang_patchlevel__)
# if defined(_MSC_VER)
/* _MSC_VER = VVRR */
# define SIMULATE_VERSION_MAJOR DEC(_MSC_VER / 100)
# define SIMULATE_VERSION_MINOR DEC(_MSC_VER % 100)
# endif
#elif defined(__GNUC__)
# define COMPILER_ID "GNU"
# define COMPILER_VERSION_MAJOR DEC(__GNUC__)
# if defined(__GNUC_MINOR__)
# define COMPILER_VERSION_MINOR DEC(__GNUC_MINOR__)
# endif
# if defined(__GNUC_PATCHLEVEL__)
# define COMPILER_VERSION_PATCH DEC(__GNUC_PATCHLEVEL__)
# endif
#elif defined(_MSC_VER)
# define COMPILER_ID "MSVC"
/* _MSC_VER = VVRR */
# define COMPILER_VERSION_MAJOR DEC(_MSC_VER / 100)
# define COMPILER_VERSION_MINOR DEC(_MSC_VER % 100)
# if defined(_MSC_FULL_VER)
# if _MSC_VER >= 1400
/* _MSC_FULL_VER = VVRRPPPPP */
# define COMPILER_VERSION_PATCH DEC(_MSC_FULL_VER % 100000)
# else
/* _MSC_FULL_VER = VVRRPPPP */
# define COMPILER_VERSION_PATCH DEC(_MSC_FULL_VER % 10000)
# endif
# endif
# if defined(_MSC_BUILD)
# define COMPILER_VERSION_TWEAK DEC(_MSC_BUILD)
# endif
#elif defined(__VISUALDSPVERSION__) || defined(__ADSPBLACKFIN__) || defined(__ADSPTS__) || defined(__ADSP21000__)
# define COMPILER_ID "ADSP"
#if defined(__VISUALDSPVERSION__)
/* __VISUALDSPVERSION__ = 0xVVRRPP00 */
# define COMPILER_VERSION_MAJOR HEX(__VISUALDSPVERSION__>>24)
# define COMPILER_VERSION_MINOR HEX(__VISUALDSPVERSION__>>16 & 0xFF)
# define COMPILER_VERSION_PATCH HEX(__VISUALDSPVERSION__>>8 & 0xFF)
#endif
#elif defined(__IAR_SYSTEMS_ICC__) || defined(__IAR_SYSTEMS_ICC)
# define COMPILER_ID "IAR"
# if defined(__VER__) && defined(__ICCARM__)
# define COMPILER_VERSION_MAJOR DEC((__VER__) / 1000000)
# define COMPILER_VERSION_MINOR DEC(((__VER__) / 1000) % 1000)
# define COMPILER_VERSION_PATCH DEC((__VER__) % 1000)
# define COMPILER_VERSION_INTERNAL DEC(__IAR_SYSTEMS_ICC__)
# elif defined(__VER__) && (defined(__ICCAVR__) || defined(__ICCRX__) || defined(__ICCRH850__) || defined(__ICCRL78__) || defined(__ICC430__) || defined(__ICCRISCV__) || defined(__ICCV850__) || defined(__ICC8051__) || defined(__ICCSTM8__))
# define COMPILER_VERSION_MAJOR DEC((__VER__) / 100)
# define COMPILER_VERSION_MINOR DEC((__VER__) - (((__VER__) / 100)*100))
# define COMPILER_VERSION_PATCH DEC(__SUBVERSION__)
# define COMPILER_VERSION_INTERNAL DEC(__IAR_SYSTEMS_ICC__)
# endif
#elif defined(__SDCC_VERSION_MAJOR) || defined(SDCC)
# define COMPILER_ID "SDCC"
# if defined(__SDCC_VERSION_MAJOR)
# define COMPILER_VERSION_MAJOR DEC(__SDCC_VERSION_MAJOR)
# define COMPILER_VERSION_MINOR DEC(__SDCC_VERSION_MINOR)
# define COMPILER_VERSION_PATCH DEC(__SDCC_VERSION_PATCH)
# else
/* SDCC = VRP */
# define COMPILER_VERSION_MAJOR DEC(SDCC/100)
# define COMPILER_VERSION_MINOR DEC(SDCC/10 % 10)
# define COMPILER_VERSION_PATCH DEC(SDCC % 10)
# endif
/* These compilers are either not known or too old to define an
identification macro. Try to identify the platform and guess that
it is the native compiler. */
#elif defined(__hpux) || defined(__hpua)
# define COMPILER_ID "HP"
#else /* unknown compiler */
# define COMPILER_ID ""
#endif
/* Construct the string literal in pieces to prevent the source from
getting matched. Store it in a pointer rather than an array
because some compilers will just produce instructions to fill the
array rather than assigning a pointer to a static array. */
char const* info_compiler = "INFO" ":" "compiler[" COMPILER_ID "]";
#ifdef SIMULATE_ID
char const* info_simulate = "INFO" ":" "simulate[" SIMULATE_ID "]";
#endif
#ifdef __QNXNTO__
char const* qnxnto = "INFO" ":" "qnxnto[]";
#endif
#if defined(__CRAYXT_COMPUTE_LINUX_TARGET)
char const *info_cray = "INFO" ":" "compiler_wrapper[CrayPrgEnv]";
#endif
#define STRINGIFY_HELPER(X) #X
#define STRINGIFY(X) STRINGIFY_HELPER(X)
/* Identify known platforms by name. */
#if defined(__linux) || defined(__linux__) || defined(linux)
# define PLATFORM_ID "Linux"
#elif defined(__MSYS__)
# define PLATFORM_ID "MSYS"
#elif defined(__CYGWIN__)
# define PLATFORM_ID "Cygwin"
#elif defined(__MINGW32__)
# define PLATFORM_ID "MinGW"
#elif defined(__APPLE__)
# define PLATFORM_ID "Darwin"
#elif defined(_WIN32) || defined(__WIN32__) || defined(WIN32)
# define PLATFORM_ID "Windows"
#elif defined(__FreeBSD__) || defined(__FreeBSD)
# define PLATFORM_ID "FreeBSD"
#elif defined(__NetBSD__) || defined(__NetBSD)
# define PLATFORM_ID "NetBSD"
#elif defined(__OpenBSD__) || defined(__OPENBSD)
# define PLATFORM_ID "OpenBSD"
#elif defined(__sun) || defined(sun)
# define PLATFORM_ID "SunOS"
#elif defined(_AIX) || defined(__AIX) || defined(__AIX__) || defined(__aix) || defined(__aix__)
# define PLATFORM_ID "AIX"
#elif defined(__hpux) || defined(__hpux__)
# define PLATFORM_ID "HP-UX"
#elif defined(__HAIKU__)
# define PLATFORM_ID "Haiku"
#elif defined(__BeOS) || defined(__BEOS__) || defined(_BEOS)
# define PLATFORM_ID "BeOS"
#elif defined(__QNX__) || defined(__QNXNTO__)
# define PLATFORM_ID "QNX"
#elif defined(__tru64) || defined(_tru64) || defined(__TRU64__)
# define PLATFORM_ID "Tru64"
#elif defined(__riscos) || defined(__riscos__)
# define PLATFORM_ID "RISCos"
#elif defined(__sinix) || defined(__sinix__) || defined(__SINIX__)
# define PLATFORM_ID "SINIX"
#elif defined(__UNIX_SV__)
# define PLATFORM_ID "UNIX_SV"
#elif defined(__bsdos__)
# define PLATFORM_ID "BSDOS"
#elif defined(_MPRAS) || defined(MPRAS)
# define PLATFORM_ID "MP-RAS"
#elif defined(__osf) || defined(__osf__)
# define PLATFORM_ID "OSF1"
#elif defined(_SCO_SV) || defined(SCO_SV) || defined(sco_sv)
# define PLATFORM_ID "SCO_SV"
#elif defined(__ultrix) || defined(__ultrix__) || defined(_ULTRIX)
# define PLATFORM_ID "ULTRIX"
#elif defined(__XENIX__) || defined(_XENIX) || defined(XENIX)
# define PLATFORM_ID "Xenix"
#elif defined(__WATCOMC__)
# if defined(__LINUX__)
# define PLATFORM_ID "Linux"
# elif defined(__DOS__)
# define PLATFORM_ID "DOS"
# elif defined(__OS2__)
# define PLATFORM_ID "OS2"
# elif defined(__WINDOWS__)
# define PLATFORM_ID "Windows3x"
# elif defined(__VXWORKS__)
# define PLATFORM_ID "VxWorks"
# else /* unknown platform */
# define PLATFORM_ID
# endif
#elif defined(__INTEGRITY)
# if defined(INT_178B)
# define PLATFORM_ID "Integrity178"
# else /* regular Integrity */
# define PLATFORM_ID "Integrity"
# endif
#else /* unknown platform */
# define PLATFORM_ID
#endif
/* For windows compilers MSVC and Intel we can determine
the architecture of the compiler being used. This is because
the compilers do not have flags that can change the architecture,
but rather depend on which compiler is being used
*/
#if defined(_WIN32) && defined(_MSC_VER)
# if defined(_M_IA64)
# define ARCHITECTURE_ID "IA64"
# elif defined(_M_ARM64EC)
# define ARCHITECTURE_ID "ARM64EC"
# elif defined(_M_X64) || defined(_M_AMD64)
# define ARCHITECTURE_ID "x64"
# elif defined(_M_IX86)
# define ARCHITECTURE_ID "X86"
# elif defined(_M_ARM64)
# define ARCHITECTURE_ID "ARM64"
# elif defined(_M_ARM)
# if _M_ARM == 4
# define ARCHITECTURE_ID "ARMV4I"
# elif _M_ARM == 5
# define ARCHITECTURE_ID "ARMV5I"
# else
# define ARCHITECTURE_ID "ARMV" STRINGIFY(_M_ARM)
# endif
# elif defined(_M_MIPS)
# define ARCHITECTURE_ID "MIPS"
# elif defined(_M_SH)
# define ARCHITECTURE_ID "SHx"
# else /* unknown architecture */
# define ARCHITECTURE_ID ""
# endif
#elif defined(__WATCOMC__)
# if defined(_M_I86)
# define ARCHITECTURE_ID "I86"
# elif defined(_M_IX86)
# define ARCHITECTURE_ID "X86"
# else /* unknown architecture */
# define ARCHITECTURE_ID ""
# endif
#elif defined(__IAR_SYSTEMS_ICC__) || defined(__IAR_SYSTEMS_ICC)
# if defined(__ICCARM__)
# define ARCHITECTURE_ID "ARM"
# elif defined(__ICCRX__)
# define ARCHITECTURE_ID "RX"
# elif defined(__ICCRH850__)
# define ARCHITECTURE_ID "RH850"
# elif defined(__ICCRL78__)
# define ARCHITECTURE_ID "RL78"
# elif defined(__ICCRISCV__)
# define ARCHITECTURE_ID "RISCV"
# elif defined(__ICCAVR__)
# define ARCHITECTURE_ID "AVR"
# elif defined(__ICC430__)
# define ARCHITECTURE_ID "MSP430"
# elif defined(__ICCV850__)
# define ARCHITECTURE_ID "V850"
# elif defined(__ICC8051__)
# define ARCHITECTURE_ID "8051"
# elif defined(__ICCSTM8__)
# define ARCHITECTURE_ID "STM8"
# else /* unknown architecture */
# define ARCHITECTURE_ID ""
# endif
#elif defined(__ghs__)
# if defined(__PPC64__)
# define ARCHITECTURE_ID "PPC64"
# elif defined(__ppc__)
# define ARCHITECTURE_ID "PPC"
# elif defined(__ARM__)
# define ARCHITECTURE_ID "ARM"
# elif defined(__x86_64__)
# define ARCHITECTURE_ID "x64"
# elif defined(__i386__)
# define ARCHITECTURE_ID "X86"
# else /* unknown architecture */
# define ARCHITECTURE_ID ""
# endif
#elif defined(__TI_COMPILER_VERSION__)
# if defined(__TI_ARM__)
# define ARCHITECTURE_ID "ARM"
# elif defined(__MSP430__)
# define ARCHITECTURE_ID "MSP430"
# elif defined(__TMS320C28XX__)
# define ARCHITECTURE_ID "TMS320C28x"
# elif defined(__TMS320C6X__) || defined(_TMS320C6X)
# define ARCHITECTURE_ID "TMS320C6x"
# else /* unknown architecture */
# define ARCHITECTURE_ID ""
# endif
#else
# define ARCHITECTURE_ID
#endif
/* Convert integer to decimal digit literals. */
#define DEC(n) \
('0' + (((n) / 10000000)%10)), \
('0' + (((n) / 1000000)%10)), \
('0' + (((n) / 100000)%10)), \
('0' + (((n) / 10000)%10)), \
('0' + (((n) / 1000)%10)), \
('0' + (((n) / 100)%10)), \
('0' + (((n) / 10)%10)), \
('0' + ((n) % 10))
/* Convert integer to hex digit literals. */
#define HEX(n) \
('0' + ((n)>>28 & 0xF)), \
('0' + ((n)>>24 & 0xF)), \
('0' + ((n)>>20 & 0xF)), \
('0' + ((n)>>16 & 0xF)), \
('0' + ((n)>>12 & 0xF)), \
('0' + ((n)>>8 & 0xF)), \
('0' + ((n)>>4 & 0xF)), \
('0' + ((n) & 0xF))
/* Construct a string literal encoding the version number. */
#ifdef COMPILER_VERSION
char const* info_version = "INFO" ":" "compiler_version[" COMPILER_VERSION "]";
/* Construct a string literal encoding the version number components. */
#elif defined(COMPILER_VERSION_MAJOR)
char const info_version[] = {
'I', 'N', 'F', 'O', ':',
'c','o','m','p','i','l','e','r','_','v','e','r','s','i','o','n','[',
COMPILER_VERSION_MAJOR,
# ifdef COMPILER_VERSION_MINOR
'.', COMPILER_VERSION_MINOR,
# ifdef COMPILER_VERSION_PATCH
'.', COMPILER_VERSION_PATCH,
# ifdef COMPILER_VERSION_TWEAK
'.', COMPILER_VERSION_TWEAK,
# endif
# endif
# endif
']','\0'};
#endif
/* Construct a string literal encoding the internal version number. */
#ifdef COMPILER_VERSION_INTERNAL
char const info_version_internal[] = {
'I', 'N', 'F', 'O', ':',
'c','o','m','p','i','l','e','r','_','v','e','r','s','i','o','n','_',
'i','n','t','e','r','n','a','l','[',
COMPILER_VERSION_INTERNAL,']','\0'};
#elif defined(COMPILER_VERSION_INTERNAL_STR)
char const* info_version_internal = "INFO" ":" "compiler_version_internal[" COMPILER_VERSION_INTERNAL_STR "]";
#endif
/* Construct a string literal encoding the version number components. */
#ifdef SIMULATE_VERSION_MAJOR
char const info_simulate_version[] = {
'I', 'N', 'F', 'O', ':',
's','i','m','u','l','a','t','e','_','v','e','r','s','i','o','n','[',
SIMULATE_VERSION_MAJOR,
# ifdef SIMULATE_VERSION_MINOR
'.', SIMULATE_VERSION_MINOR,
# ifdef SIMULATE_VERSION_PATCH
'.', SIMULATE_VERSION_PATCH,
# ifdef SIMULATE_VERSION_TWEAK
'.', SIMULATE_VERSION_TWEAK,
# endif
# endif
# endif
']','\0'};
#endif
/* Construct the string literal in pieces to prevent the source from
getting matched. Store it in a pointer rather than an array
because some compilers will just produce instructions to fill the
array rather than assigning a pointer to a static array. */
char const* info_platform = "INFO" ":" "platform[" PLATFORM_ID "]";
char const* info_arch = "INFO" ":" "arch[" ARCHITECTURE_ID "]";
#if !defined(__STDC__) && !defined(__clang__)
# if defined(_MSC_VER) || defined(__ibmxl__) || defined(__IBMC__)
# define C_DIALECT "90"
# else
# define C_DIALECT
# endif
#elif __STDC_VERSION__ > 201710L
# define C_DIALECT "23"
#elif __STDC_VERSION__ >= 201710L
# define C_DIALECT "17"
#elif __STDC_VERSION__ >= 201000L
# define C_DIALECT "11"
#elif __STDC_VERSION__ >= 199901L
# define C_DIALECT "99"
#else
# define C_DIALECT "90"
#endif
const char* info_language_dialect_default =
"INFO" ":" "dialect_default[" C_DIALECT "]";
/*--------------------------------------------------------------------------*/
#ifdef ID_VOID_MAIN
void main() {}
#else
# if defined(__CLASSIC_C__)
int main(argc, argv) int argc; char *argv[];
# else
int main(int argc, char* argv[])
# endif
{
int require = 0;
require += info_compiler[argc];
require += info_platform[argc];
require += info_arch[argc];
#ifdef COMPILER_VERSION_MAJOR
require += info_version[argc];
#endif
#ifdef COMPILER_VERSION_INTERNAL
require += info_version_internal[argc];
#endif
#ifdef SIMULATE_ID
require += info_simulate[argc];
#endif
#ifdef SIMULATE_VERSION_MAJOR
require += info_simulate_version[argc];
#endif
#if defined(__CRAYXT_COMPUTE_LINUX_TARGET)
require += info_cray[argc];
#endif
require += info_language_dialect_default[argc];
(void)argv;
return require;
}
#endif

Binary file not shown.

View File

@ -0,0 +1,795 @@
/* This source file must have a .cpp extension so that all C++ compilers
recognize the extension without flags. Borland does not know .cxx for
example. */
#ifndef __cplusplus
# error "A C compiler has been selected for C++."
#endif
#if !defined(__has_include)
/* If the compiler does not have __has_include, pretend the answer is
always no. */
# define __has_include(x) 0
#endif
/* Version number components: V=Version, R=Revision, P=Patch
Version date components: YYYY=Year, MM=Month, DD=Day */
#if defined(__COMO__)
# define COMPILER_ID "Comeau"
/* __COMO_VERSION__ = VRR */
# define COMPILER_VERSION_MAJOR DEC(__COMO_VERSION__ / 100)
# define COMPILER_VERSION_MINOR DEC(__COMO_VERSION__ % 100)
#elif defined(__INTEL_COMPILER) || defined(__ICC)
# define COMPILER_ID "Intel"
# if defined(_MSC_VER)
# define SIMULATE_ID "MSVC"
# endif
# if defined(__GNUC__)
# define SIMULATE_ID "GNU"
# endif
/* __INTEL_COMPILER = VRP prior to 2021, and then VVVV for 2021 and later,
except that a few beta releases use the old format with V=2021. */
# if __INTEL_COMPILER < 2021 || __INTEL_COMPILER == 202110 || __INTEL_COMPILER == 202111
# define COMPILER_VERSION_MAJOR DEC(__INTEL_COMPILER/100)
# define COMPILER_VERSION_MINOR DEC(__INTEL_COMPILER/10 % 10)
# if defined(__INTEL_COMPILER_UPDATE)
# define COMPILER_VERSION_PATCH DEC(__INTEL_COMPILER_UPDATE)
# else
# define COMPILER_VERSION_PATCH DEC(__INTEL_COMPILER % 10)
# endif
# else
# define COMPILER_VERSION_MAJOR DEC(__INTEL_COMPILER)
# define COMPILER_VERSION_MINOR DEC(__INTEL_COMPILER_UPDATE)
/* The third version component from --version is an update index,
but no macro is provided for it. */
# define COMPILER_VERSION_PATCH DEC(0)
# endif
# if defined(__INTEL_COMPILER_BUILD_DATE)
/* __INTEL_COMPILER_BUILD_DATE = YYYYMMDD */
# define COMPILER_VERSION_TWEAK DEC(__INTEL_COMPILER_BUILD_DATE)
# endif
# if defined(_MSC_VER)
/* _MSC_VER = VVRR */
# define SIMULATE_VERSION_MAJOR DEC(_MSC_VER / 100)
# define SIMULATE_VERSION_MINOR DEC(_MSC_VER % 100)
# endif
# if defined(__GNUC__)
# define SIMULATE_VERSION_MAJOR DEC(__GNUC__)
# elif defined(__GNUG__)
# define SIMULATE_VERSION_MAJOR DEC(__GNUG__)
# endif
# if defined(__GNUC_MINOR__)
# define SIMULATE_VERSION_MINOR DEC(__GNUC_MINOR__)
# endif
# if defined(__GNUC_PATCHLEVEL__)
# define SIMULATE_VERSION_PATCH DEC(__GNUC_PATCHLEVEL__)
# endif
#elif (defined(__clang__) && defined(__INTEL_CLANG_COMPILER)) || defined(__INTEL_LLVM_COMPILER)
# define COMPILER_ID "IntelLLVM"
#if defined(_MSC_VER)
# define SIMULATE_ID "MSVC"
#endif
#if defined(__GNUC__)
# define SIMULATE_ID "GNU"
#endif
/* __INTEL_LLVM_COMPILER = VVVVRP prior to 2021.2.0, VVVVRRPP for 2021.2.0 and
* later. Look for 6 digit vs. 8 digit version number to decide encoding.
* VVVV is no smaller than the current year when a version is released.
*/
#if __INTEL_LLVM_COMPILER < 1000000L
# define COMPILER_VERSION_MAJOR DEC(__INTEL_LLVM_COMPILER/100)
# define COMPILER_VERSION_MINOR DEC(__INTEL_LLVM_COMPILER/10 % 10)
# define COMPILER_VERSION_PATCH DEC(__INTEL_LLVM_COMPILER % 10)
#else
# define COMPILER_VERSION_MAJOR DEC(__INTEL_LLVM_COMPILER/10000)
# define COMPILER_VERSION_MINOR DEC(__INTEL_LLVM_COMPILER/100 % 100)
# define COMPILER_VERSION_PATCH DEC(__INTEL_LLVM_COMPILER % 100)
#endif
#if defined(_MSC_VER)
/* _MSC_VER = VVRR */
# define SIMULATE_VERSION_MAJOR DEC(_MSC_VER / 100)
# define SIMULATE_VERSION_MINOR DEC(_MSC_VER % 100)
#endif
#if defined(__GNUC__)
# define SIMULATE_VERSION_MAJOR DEC(__GNUC__)
#elif defined(__GNUG__)
# define SIMULATE_VERSION_MAJOR DEC(__GNUG__)
#endif
#if defined(__GNUC_MINOR__)
# define SIMULATE_VERSION_MINOR DEC(__GNUC_MINOR__)
#endif
#if defined(__GNUC_PATCHLEVEL__)
# define SIMULATE_VERSION_PATCH DEC(__GNUC_PATCHLEVEL__)
#endif
#elif defined(__PATHCC__)
# define COMPILER_ID "PathScale"
# define COMPILER_VERSION_MAJOR DEC(__PATHCC__)
# define COMPILER_VERSION_MINOR DEC(__PATHCC_MINOR__)
# if defined(__PATHCC_PATCHLEVEL__)
# define COMPILER_VERSION_PATCH DEC(__PATHCC_PATCHLEVEL__)
# endif
#elif defined(__BORLANDC__) && defined(__CODEGEARC_VERSION__)
# define COMPILER_ID "Embarcadero"
# define COMPILER_VERSION_MAJOR HEX(__CODEGEARC_VERSION__>>24 & 0x00FF)
# define COMPILER_VERSION_MINOR HEX(__CODEGEARC_VERSION__>>16 & 0x00FF)
# define COMPILER_VERSION_PATCH DEC(__CODEGEARC_VERSION__ & 0xFFFF)
#elif defined(__BORLANDC__)
# define COMPILER_ID "Borland"
/* __BORLANDC__ = 0xVRR */
# define COMPILER_VERSION_MAJOR HEX(__BORLANDC__>>8)
# define COMPILER_VERSION_MINOR HEX(__BORLANDC__ & 0xFF)
#elif defined(__WATCOMC__) && __WATCOMC__ < 1200
# define COMPILER_ID "Watcom"
/* __WATCOMC__ = VVRR */
# define COMPILER_VERSION_MAJOR DEC(__WATCOMC__ / 100)
# define COMPILER_VERSION_MINOR DEC((__WATCOMC__ / 10) % 10)
# if (__WATCOMC__ % 10) > 0
# define COMPILER_VERSION_PATCH DEC(__WATCOMC__ % 10)
# endif
#elif defined(__WATCOMC__)
# define COMPILER_ID "OpenWatcom"
/* __WATCOMC__ = VVRP + 1100 */
# define COMPILER_VERSION_MAJOR DEC((__WATCOMC__ - 1100) / 100)
# define COMPILER_VERSION_MINOR DEC((__WATCOMC__ / 10) % 10)
# if (__WATCOMC__ % 10) > 0
# define COMPILER_VERSION_PATCH DEC(__WATCOMC__ % 10)
# endif
#elif defined(__SUNPRO_CC)
# define COMPILER_ID "SunPro"
# if __SUNPRO_CC >= 0x5100
/* __SUNPRO_CC = 0xVRRP */
# define COMPILER_VERSION_MAJOR HEX(__SUNPRO_CC>>12)
# define COMPILER_VERSION_MINOR HEX(__SUNPRO_CC>>4 & 0xFF)
# define COMPILER_VERSION_PATCH HEX(__SUNPRO_CC & 0xF)
# else
/* __SUNPRO_CC = 0xVRP */
# define COMPILER_VERSION_MAJOR HEX(__SUNPRO_CC>>8)
# define COMPILER_VERSION_MINOR HEX(__SUNPRO_CC>>4 & 0xF)
# define COMPILER_VERSION_PATCH HEX(__SUNPRO_CC & 0xF)
# endif
#elif defined(__HP_aCC)
# define COMPILER_ID "HP"
/* __HP_aCC = VVRRPP */
# define COMPILER_VERSION_MAJOR DEC(__HP_aCC/10000)
# define COMPILER_VERSION_MINOR DEC(__HP_aCC/100 % 100)
# define COMPILER_VERSION_PATCH DEC(__HP_aCC % 100)
#elif defined(__DECCXX)
# define COMPILER_ID "Compaq"
/* __DECCXX_VER = VVRRTPPPP */
# define COMPILER_VERSION_MAJOR DEC(__DECCXX_VER/10000000)
# define COMPILER_VERSION_MINOR DEC(__DECCXX_VER/100000 % 100)
# define COMPILER_VERSION_PATCH DEC(__DECCXX_VER % 10000)
#elif defined(__IBMCPP__) && defined(__COMPILER_VER__)
# define COMPILER_ID "zOS"
/* __IBMCPP__ = VRP */
# define COMPILER_VERSION_MAJOR DEC(__IBMCPP__/100)
# define COMPILER_VERSION_MINOR DEC(__IBMCPP__/10 % 10)
# define COMPILER_VERSION_PATCH DEC(__IBMCPP__ % 10)
#elif defined(__ibmxl__) && defined(__clang__)
# define COMPILER_ID "XLClang"
# define COMPILER_VERSION_MAJOR DEC(__ibmxl_version__)
# define COMPILER_VERSION_MINOR DEC(__ibmxl_release__)
# define COMPILER_VERSION_PATCH DEC(__ibmxl_modification__)
# define COMPILER_VERSION_TWEAK DEC(__ibmxl_ptf_fix_level__)
#elif defined(__IBMCPP__) && !defined(__COMPILER_VER__) && __IBMCPP__ >= 800
# define COMPILER_ID "XL"
/* __IBMCPP__ = VRP */
# define COMPILER_VERSION_MAJOR DEC(__IBMCPP__/100)
# define COMPILER_VERSION_MINOR DEC(__IBMCPP__/10 % 10)
# define COMPILER_VERSION_PATCH DEC(__IBMCPP__ % 10)
#elif defined(__IBMCPP__) && !defined(__COMPILER_VER__) && __IBMCPP__ < 800
# define COMPILER_ID "VisualAge"
/* __IBMCPP__ = VRP */
# define COMPILER_VERSION_MAJOR DEC(__IBMCPP__/100)
# define COMPILER_VERSION_MINOR DEC(__IBMCPP__/10 % 10)
# define COMPILER_VERSION_PATCH DEC(__IBMCPP__ % 10)
#elif defined(__NVCOMPILER)
# define COMPILER_ID "NVHPC"
# define COMPILER_VERSION_MAJOR DEC(__NVCOMPILER_MAJOR__)
# define COMPILER_VERSION_MINOR DEC(__NVCOMPILER_MINOR__)
# if defined(__NVCOMPILER_PATCHLEVEL__)
# define COMPILER_VERSION_PATCH DEC(__NVCOMPILER_PATCHLEVEL__)
# endif
#elif defined(__PGI)
# define COMPILER_ID "PGI"
# define COMPILER_VERSION_MAJOR DEC(__PGIC__)
# define COMPILER_VERSION_MINOR DEC(__PGIC_MINOR__)
# if defined(__PGIC_PATCHLEVEL__)
# define COMPILER_VERSION_PATCH DEC(__PGIC_PATCHLEVEL__)
# endif
#elif defined(_CRAYC)
# define COMPILER_ID "Cray"
# define COMPILER_VERSION_MAJOR DEC(_RELEASE_MAJOR)
# define COMPILER_VERSION_MINOR DEC(_RELEASE_MINOR)
#elif defined(__TI_COMPILER_VERSION__)
# define COMPILER_ID "TI"
/* __TI_COMPILER_VERSION__ = VVVRRRPPP */
# define COMPILER_VERSION_MAJOR DEC(__TI_COMPILER_VERSION__/1000000)
# define COMPILER_VERSION_MINOR DEC(__TI_COMPILER_VERSION__/1000 % 1000)
# define COMPILER_VERSION_PATCH DEC(__TI_COMPILER_VERSION__ % 1000)
#elif defined(__CLANG_FUJITSU)
# define COMPILER_ID "FujitsuClang"
# define COMPILER_VERSION_MAJOR DEC(__FCC_major__)
# define COMPILER_VERSION_MINOR DEC(__FCC_minor__)
# define COMPILER_VERSION_PATCH DEC(__FCC_patchlevel__)
# define COMPILER_VERSION_INTERNAL_STR __clang_version__
#elif defined(__FUJITSU)
# define COMPILER_ID "Fujitsu"
# if defined(__FCC_version__)
# define COMPILER_VERSION __FCC_version__
# elif defined(__FCC_major__)
# define COMPILER_VERSION_MAJOR DEC(__FCC_major__)
# define COMPILER_VERSION_MINOR DEC(__FCC_minor__)
# define COMPILER_VERSION_PATCH DEC(__FCC_patchlevel__)
# endif
# if defined(__fcc_version)
# define COMPILER_VERSION_INTERNAL DEC(__fcc_version)
# elif defined(__FCC_VERSION)
# define COMPILER_VERSION_INTERNAL DEC(__FCC_VERSION)
# endif
#elif defined(__ghs__)
# define COMPILER_ID "GHS"
/* __GHS_VERSION_NUMBER = VVVVRP */
# ifdef __GHS_VERSION_NUMBER
# define COMPILER_VERSION_MAJOR DEC(__GHS_VERSION_NUMBER / 100)
# define COMPILER_VERSION_MINOR DEC(__GHS_VERSION_NUMBER / 10 % 10)
# define COMPILER_VERSION_PATCH DEC(__GHS_VERSION_NUMBER % 10)
# endif
#elif defined(__SCO_VERSION__)
# define COMPILER_ID "SCO"
#elif defined(__ARMCC_VERSION) && !defined(__clang__)
# define COMPILER_ID "ARMCC"
#if __ARMCC_VERSION >= 1000000
/* __ARMCC_VERSION = VRRPPPP */
# define COMPILER_VERSION_MAJOR DEC(__ARMCC_VERSION/1000000)
# define COMPILER_VERSION_MINOR DEC(__ARMCC_VERSION/10000 % 100)
# define COMPILER_VERSION_PATCH DEC(__ARMCC_VERSION % 10000)
#else
/* __ARMCC_VERSION = VRPPPP */
# define COMPILER_VERSION_MAJOR DEC(__ARMCC_VERSION/100000)
# define COMPILER_VERSION_MINOR DEC(__ARMCC_VERSION/10000 % 10)
# define COMPILER_VERSION_PATCH DEC(__ARMCC_VERSION % 10000)
#endif
#elif defined(__clang__) && defined(__apple_build_version__)
# define COMPILER_ID "AppleClang"
# if defined(_MSC_VER)
# define SIMULATE_ID "MSVC"
# endif
# define COMPILER_VERSION_MAJOR DEC(__clang_major__)
# define COMPILER_VERSION_MINOR DEC(__clang_minor__)
# define COMPILER_VERSION_PATCH DEC(__clang_patchlevel__)
# if defined(_MSC_VER)
/* _MSC_VER = VVRR */
# define SIMULATE_VERSION_MAJOR DEC(_MSC_VER / 100)
# define SIMULATE_VERSION_MINOR DEC(_MSC_VER % 100)
# endif
# define COMPILER_VERSION_TWEAK DEC(__apple_build_version__)
#elif defined(__clang__) && defined(__ARMCOMPILER_VERSION)
# define COMPILER_ID "ARMClang"
# define COMPILER_VERSION_MAJOR DEC(__ARMCOMPILER_VERSION/1000000)
# define COMPILER_VERSION_MINOR DEC(__ARMCOMPILER_VERSION/10000 % 100)
# define COMPILER_VERSION_PATCH DEC(__ARMCOMPILER_VERSION % 10000)
# define COMPILER_VERSION_INTERNAL DEC(__ARMCOMPILER_VERSION)
#elif defined(__clang__) && __has_include(<hip/hip_version.h>)
# define COMPILER_ID "ROCMClang"
# if defined(_MSC_VER)
# define SIMULATE_ID "MSVC"
# elif defined(__clang__)
# define SIMULATE_ID "Clang"
# elif defined(__GNUC__)
# define SIMULATE_ID "GNU"
# endif
# if defined(__clang__) && __has_include(<hip/hip_version.h>)
# include <hip/hip_version.h>
# define COMPILER_VERSION_MAJOR DEC(HIP_VERSION_MAJOR)
# define COMPILER_VERSION_MINOR DEC(HIP_VERSION_MINOR)
# define COMPILER_VERSION_PATCH DEC(HIP_VERSION_PATCH)
# endif
#elif defined(__clang__)
# define COMPILER_ID "Clang"
# if defined(_MSC_VER)
# define SIMULATE_ID "MSVC"
# endif
# define COMPILER_VERSION_MAJOR DEC(__clang_major__)
# define COMPILER_VERSION_MINOR DEC(__clang_minor__)
# define COMPILER_VERSION_PATCH DEC(__clang_patchlevel__)
# if defined(_MSC_VER)
/* _MSC_VER = VVRR */
# define SIMULATE_VERSION_MAJOR DEC(_MSC_VER / 100)
# define SIMULATE_VERSION_MINOR DEC(_MSC_VER % 100)
# endif
#elif defined(__GNUC__) || defined(__GNUG__)
# define COMPILER_ID "GNU"
# if defined(__GNUC__)
# define COMPILER_VERSION_MAJOR DEC(__GNUC__)
# else
# define COMPILER_VERSION_MAJOR DEC(__GNUG__)
# endif
# if defined(__GNUC_MINOR__)
# define COMPILER_VERSION_MINOR DEC(__GNUC_MINOR__)
# endif
# if defined(__GNUC_PATCHLEVEL__)
# define COMPILER_VERSION_PATCH DEC(__GNUC_PATCHLEVEL__)
# endif
#elif defined(_MSC_VER)
# define COMPILER_ID "MSVC"
/* _MSC_VER = VVRR */
# define COMPILER_VERSION_MAJOR DEC(_MSC_VER / 100)
# define COMPILER_VERSION_MINOR DEC(_MSC_VER % 100)
# if defined(_MSC_FULL_VER)
# if _MSC_VER >= 1400
/* _MSC_FULL_VER = VVRRPPPPP */
# define COMPILER_VERSION_PATCH DEC(_MSC_FULL_VER % 100000)
# else
/* _MSC_FULL_VER = VVRRPPPP */
# define COMPILER_VERSION_PATCH DEC(_MSC_FULL_VER % 10000)
# endif
# endif
# if defined(_MSC_BUILD)
# define COMPILER_VERSION_TWEAK DEC(_MSC_BUILD)
# endif
#elif defined(__VISUALDSPVERSION__) || defined(__ADSPBLACKFIN__) || defined(__ADSPTS__) || defined(__ADSP21000__)
# define COMPILER_ID "ADSP"
#if defined(__VISUALDSPVERSION__)
/* __VISUALDSPVERSION__ = 0xVVRRPP00 */
# define COMPILER_VERSION_MAJOR HEX(__VISUALDSPVERSION__>>24)
# define COMPILER_VERSION_MINOR HEX(__VISUALDSPVERSION__>>16 & 0xFF)
# define COMPILER_VERSION_PATCH HEX(__VISUALDSPVERSION__>>8 & 0xFF)
#endif
#elif defined(__IAR_SYSTEMS_ICC__) || defined(__IAR_SYSTEMS_ICC)
# define COMPILER_ID "IAR"
# if defined(__VER__) && defined(__ICCARM__)
# define COMPILER_VERSION_MAJOR DEC((__VER__) / 1000000)
# define COMPILER_VERSION_MINOR DEC(((__VER__) / 1000) % 1000)
# define COMPILER_VERSION_PATCH DEC((__VER__) % 1000)
# define COMPILER_VERSION_INTERNAL DEC(__IAR_SYSTEMS_ICC__)
# elif defined(__VER__) && (defined(__ICCAVR__) || defined(__ICCRX__) || defined(__ICCRH850__) || defined(__ICCRL78__) || defined(__ICC430__) || defined(__ICCRISCV__) || defined(__ICCV850__) || defined(__ICC8051__) || defined(__ICCSTM8__))
# define COMPILER_VERSION_MAJOR DEC((__VER__) / 100)
# define COMPILER_VERSION_MINOR DEC((__VER__) - (((__VER__) / 100)*100))
# define COMPILER_VERSION_PATCH DEC(__SUBVERSION__)
# define COMPILER_VERSION_INTERNAL DEC(__IAR_SYSTEMS_ICC__)
# endif
/* These compilers are either not known or too old to define an
identification macro. Try to identify the platform and guess that
it is the native compiler. */
#elif defined(__hpux) || defined(__hpua)
# define COMPILER_ID "HP"
#else /* unknown compiler */
# define COMPILER_ID ""
#endif
/* Construct the string literal in pieces to prevent the source from
getting matched. Store it in a pointer rather than an array
because some compilers will just produce instructions to fill the
array rather than assigning a pointer to a static array. */
char const* info_compiler = "INFO" ":" "compiler[" COMPILER_ID "]";
#ifdef SIMULATE_ID
char const* info_simulate = "INFO" ":" "simulate[" SIMULATE_ID "]";
#endif
#ifdef __QNXNTO__
char const* qnxnto = "INFO" ":" "qnxnto[]";
#endif
#if defined(__CRAYXT_COMPUTE_LINUX_TARGET)
char const *info_cray = "INFO" ":" "compiler_wrapper[CrayPrgEnv]";
#endif
#define STRINGIFY_HELPER(X) #X
#define STRINGIFY(X) STRINGIFY_HELPER(X)
/* Identify known platforms by name. */
#if defined(__linux) || defined(__linux__) || defined(linux)
# define PLATFORM_ID "Linux"
#elif defined(__MSYS__)
# define PLATFORM_ID "MSYS"
#elif defined(__CYGWIN__)
# define PLATFORM_ID "Cygwin"
#elif defined(__MINGW32__)
# define PLATFORM_ID "MinGW"
#elif defined(__APPLE__)
# define PLATFORM_ID "Darwin"
#elif defined(_WIN32) || defined(__WIN32__) || defined(WIN32)
# define PLATFORM_ID "Windows"
#elif defined(__FreeBSD__) || defined(__FreeBSD)
# define PLATFORM_ID "FreeBSD"
#elif defined(__NetBSD__) || defined(__NetBSD)
# define PLATFORM_ID "NetBSD"
#elif defined(__OpenBSD__) || defined(__OPENBSD)
# define PLATFORM_ID "OpenBSD"
#elif defined(__sun) || defined(sun)
# define PLATFORM_ID "SunOS"
#elif defined(_AIX) || defined(__AIX) || defined(__AIX__) || defined(__aix) || defined(__aix__)
# define PLATFORM_ID "AIX"
#elif defined(__hpux) || defined(__hpux__)
# define PLATFORM_ID "HP-UX"
#elif defined(__HAIKU__)
# define PLATFORM_ID "Haiku"
#elif defined(__BeOS) || defined(__BEOS__) || defined(_BEOS)
# define PLATFORM_ID "BeOS"
#elif defined(__QNX__) || defined(__QNXNTO__)
# define PLATFORM_ID "QNX"
#elif defined(__tru64) || defined(_tru64) || defined(__TRU64__)
# define PLATFORM_ID "Tru64"
#elif defined(__riscos) || defined(__riscos__)
# define PLATFORM_ID "RISCos"
#elif defined(__sinix) || defined(__sinix__) || defined(__SINIX__)
# define PLATFORM_ID "SINIX"
#elif defined(__UNIX_SV__)
# define PLATFORM_ID "UNIX_SV"
#elif defined(__bsdos__)
# define PLATFORM_ID "BSDOS"
#elif defined(_MPRAS) || defined(MPRAS)
# define PLATFORM_ID "MP-RAS"
#elif defined(__osf) || defined(__osf__)
# define PLATFORM_ID "OSF1"
#elif defined(_SCO_SV) || defined(SCO_SV) || defined(sco_sv)
# define PLATFORM_ID "SCO_SV"
#elif defined(__ultrix) || defined(__ultrix__) || defined(_ULTRIX)
# define PLATFORM_ID "ULTRIX"
#elif defined(__XENIX__) || defined(_XENIX) || defined(XENIX)
# define PLATFORM_ID "Xenix"
#elif defined(__WATCOMC__)
# if defined(__LINUX__)
# define PLATFORM_ID "Linux"
# elif defined(__DOS__)
# define PLATFORM_ID "DOS"
# elif defined(__OS2__)
# define PLATFORM_ID "OS2"
# elif defined(__WINDOWS__)
# define PLATFORM_ID "Windows3x"
# elif defined(__VXWORKS__)
# define PLATFORM_ID "VxWorks"
# else /* unknown platform */
# define PLATFORM_ID
# endif
#elif defined(__INTEGRITY)
# if defined(INT_178B)
# define PLATFORM_ID "Integrity178"
# else /* regular Integrity */
# define PLATFORM_ID "Integrity"
# endif
#else /* unknown platform */
# define PLATFORM_ID
#endif
/* For windows compilers MSVC and Intel we can determine
the architecture of the compiler being used. This is because
the compilers do not have flags that can change the architecture,
but rather depend on which compiler is being used
*/
#if defined(_WIN32) && defined(_MSC_VER)
# if defined(_M_IA64)
# define ARCHITECTURE_ID "IA64"
# elif defined(_M_ARM64EC)
# define ARCHITECTURE_ID "ARM64EC"
# elif defined(_M_X64) || defined(_M_AMD64)
# define ARCHITECTURE_ID "x64"
# elif defined(_M_IX86)
# define ARCHITECTURE_ID "X86"
# elif defined(_M_ARM64)
# define ARCHITECTURE_ID "ARM64"
# elif defined(_M_ARM)
# if _M_ARM == 4
# define ARCHITECTURE_ID "ARMV4I"
# elif _M_ARM == 5
# define ARCHITECTURE_ID "ARMV5I"
# else
# define ARCHITECTURE_ID "ARMV" STRINGIFY(_M_ARM)
# endif
# elif defined(_M_MIPS)
# define ARCHITECTURE_ID "MIPS"
# elif defined(_M_SH)
# define ARCHITECTURE_ID "SHx"
# else /* unknown architecture */
# define ARCHITECTURE_ID ""
# endif
#elif defined(__WATCOMC__)
# if defined(_M_I86)
# define ARCHITECTURE_ID "I86"
# elif defined(_M_IX86)
# define ARCHITECTURE_ID "X86"
# else /* unknown architecture */
# define ARCHITECTURE_ID ""
# endif
#elif defined(__IAR_SYSTEMS_ICC__) || defined(__IAR_SYSTEMS_ICC)
# if defined(__ICCARM__)
# define ARCHITECTURE_ID "ARM"
# elif defined(__ICCRX__)
# define ARCHITECTURE_ID "RX"
# elif defined(__ICCRH850__)
# define ARCHITECTURE_ID "RH850"
# elif defined(__ICCRL78__)
# define ARCHITECTURE_ID "RL78"
# elif defined(__ICCRISCV__)
# define ARCHITECTURE_ID "RISCV"
# elif defined(__ICCAVR__)
# define ARCHITECTURE_ID "AVR"
# elif defined(__ICC430__)
# define ARCHITECTURE_ID "MSP430"
# elif defined(__ICCV850__)
# define ARCHITECTURE_ID "V850"
# elif defined(__ICC8051__)
# define ARCHITECTURE_ID "8051"
# elif defined(__ICCSTM8__)
# define ARCHITECTURE_ID "STM8"
# else /* unknown architecture */
# define ARCHITECTURE_ID ""
# endif
#elif defined(__ghs__)
# if defined(__PPC64__)
# define ARCHITECTURE_ID "PPC64"
# elif defined(__ppc__)
# define ARCHITECTURE_ID "PPC"
# elif defined(__ARM__)
# define ARCHITECTURE_ID "ARM"
# elif defined(__x86_64__)
# define ARCHITECTURE_ID "x64"
# elif defined(__i386__)
# define ARCHITECTURE_ID "X86"
# else /* unknown architecture */
# define ARCHITECTURE_ID ""
# endif
#elif defined(__TI_COMPILER_VERSION__)
# if defined(__TI_ARM__)
# define ARCHITECTURE_ID "ARM"
# elif defined(__MSP430__)
# define ARCHITECTURE_ID "MSP430"
# elif defined(__TMS320C28XX__)
# define ARCHITECTURE_ID "TMS320C28x"
# elif defined(__TMS320C6X__) || defined(_TMS320C6X)
# define ARCHITECTURE_ID "TMS320C6x"
# else /* unknown architecture */
# define ARCHITECTURE_ID ""
# endif
#else
# define ARCHITECTURE_ID
#endif
/* Convert integer to decimal digit literals. */
#define DEC(n) \
('0' + (((n) / 10000000)%10)), \
('0' + (((n) / 1000000)%10)), \
('0' + (((n) / 100000)%10)), \
('0' + (((n) / 10000)%10)), \
('0' + (((n) / 1000)%10)), \
('0' + (((n) / 100)%10)), \
('0' + (((n) / 10)%10)), \
('0' + ((n) % 10))
/* Convert integer to hex digit literals. */
#define HEX(n) \
('0' + ((n)>>28 & 0xF)), \
('0' + ((n)>>24 & 0xF)), \
('0' + ((n)>>20 & 0xF)), \
('0' + ((n)>>16 & 0xF)), \
('0' + ((n)>>12 & 0xF)), \
('0' + ((n)>>8 & 0xF)), \
('0' + ((n)>>4 & 0xF)), \
('0' + ((n) & 0xF))
/* Construct a string literal encoding the version number. */
#ifdef COMPILER_VERSION
char const* info_version = "INFO" ":" "compiler_version[" COMPILER_VERSION "]";
/* Construct a string literal encoding the version number components. */
#elif defined(COMPILER_VERSION_MAJOR)
char const info_version[] = {
'I', 'N', 'F', 'O', ':',
'c','o','m','p','i','l','e','r','_','v','e','r','s','i','o','n','[',
COMPILER_VERSION_MAJOR,
# ifdef COMPILER_VERSION_MINOR
'.', COMPILER_VERSION_MINOR,
# ifdef COMPILER_VERSION_PATCH
'.', COMPILER_VERSION_PATCH,
# ifdef COMPILER_VERSION_TWEAK
'.', COMPILER_VERSION_TWEAK,
# endif
# endif
# endif
']','\0'};
#endif
/* Construct a string literal encoding the internal version number. */
#ifdef COMPILER_VERSION_INTERNAL
char const info_version_internal[] = {
'I', 'N', 'F', 'O', ':',
'c','o','m','p','i','l','e','r','_','v','e','r','s','i','o','n','_',
'i','n','t','e','r','n','a','l','[',
COMPILER_VERSION_INTERNAL,']','\0'};
#elif defined(COMPILER_VERSION_INTERNAL_STR)
char const* info_version_internal = "INFO" ":" "compiler_version_internal[" COMPILER_VERSION_INTERNAL_STR "]";
#endif
/* Construct a string literal encoding the version number components. */
#ifdef SIMULATE_VERSION_MAJOR
char const info_simulate_version[] = {
'I', 'N', 'F', 'O', ':',
's','i','m','u','l','a','t','e','_','v','e','r','s','i','o','n','[',
SIMULATE_VERSION_MAJOR,
# ifdef SIMULATE_VERSION_MINOR
'.', SIMULATE_VERSION_MINOR,
# ifdef SIMULATE_VERSION_PATCH
'.', SIMULATE_VERSION_PATCH,
# ifdef SIMULATE_VERSION_TWEAK
'.', SIMULATE_VERSION_TWEAK,
# endif
# endif
# endif
']','\0'};
#endif
/* Construct the string literal in pieces to prevent the source from
getting matched. Store it in a pointer rather than an array
because some compilers will just produce instructions to fill the
array rather than assigning a pointer to a static array. */
char const* info_platform = "INFO" ":" "platform[" PLATFORM_ID "]";
char const* info_arch = "INFO" ":" "arch[" ARCHITECTURE_ID "]";
#if defined(__INTEL_COMPILER) && defined(_MSVC_LANG) && _MSVC_LANG < 201403L
# if defined(__INTEL_CXX11_MODE__)
# if defined(__cpp_aggregate_nsdmi)
# define CXX_STD 201402L
# else
# define CXX_STD 201103L
# endif
# else
# define CXX_STD 199711L
# endif
#elif defined(_MSC_VER) && defined(_MSVC_LANG)
# define CXX_STD _MSVC_LANG
#else
# define CXX_STD __cplusplus
#endif
const char* info_language_dialect_default = "INFO" ":" "dialect_default["
#if CXX_STD > 202002L
"23"
#elif CXX_STD > 201703L
"20"
#elif CXX_STD >= 201703L
"17"
#elif CXX_STD >= 201402L
"14"
#elif CXX_STD >= 201103L
"11"
#else
"98"
#endif
"]";
/*--------------------------------------------------------------------------*/
int main(int argc, char* argv[])
{
int require = 0;
require += info_compiler[argc];
require += info_platform[argc];
#ifdef COMPILER_VERSION_MAJOR
require += info_version[argc];
#endif
#ifdef COMPILER_VERSION_INTERNAL
require += info_version_internal[argc];
#endif
#ifdef SIMULATE_ID
require += info_simulate[argc];
#endif
#ifdef SIMULATE_VERSION_MAJOR
require += info_simulate_version[argc];
#endif
#if defined(__CRAYXT_COMPUTE_LINUX_TARGET)
require += info_cray[argc];
#endif
require += info_language_dialect_default[argc];
(void)argv;
return require;
}

Binary file not shown.

View File

@ -0,0 +1,427 @@
The system is: Linux - 5.14.0-1027-oem - x86_64
Compiling the C compiler identification source file "CMakeCCompilerId.c" succeeded.
Compiler: /usr/bin/gcc-10
Build flags:
Id flags:
The output was:
0
Compilation of the C compiler identification source "CMakeCCompilerId.c" produced "a.out"
The C compiler identification is GNU, found in "/home/tomer/Github/Public-PF/cmake-build-debug/CMakeFiles/3.21.1/CompilerIdC/a.out"
Compiling the CXX compiler identification source file "CMakeCXXCompilerId.cpp" succeeded.
Compiler: /usr/bin/g++-10
Build flags:
Id flags:
The output was:
0
Compilation of the CXX compiler identification source "CMakeCXXCompilerId.cpp" produced "a.out"
The CXX compiler identification is GNU, found in "/home/tomer/Github/Public-PF/cmake-build-debug/CMakeFiles/3.21.1/CompilerIdCXX/a.out"
Detecting C compiler ABI info compiled with the following output:
Change Dir: /home/tomer/Github/Public-PF/cmake-build-debug/CMakeFiles/CMakeTmp
Run Build Command(s):/snap/clion/184/bin/ninja/linux/ninja cmTC_f2ba8 && [1/2] Building C object CMakeFiles/cmTC_f2ba8.dir/CMakeCCompilerABI.c.o
Using built-in specs.
COLLECT_GCC=/usr/bin/gcc-10
OFFLOAD_TARGET_NAMES=nvptx-none:amdgcn-amdhsa:hsa
OFFLOAD_TARGET_DEFAULT=1
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu 10.3.0-1ubuntu1~20.04' --with-bugurl=file:///usr/share/doc/gcc-10/README.Bugs --enable-languages=c,ada,c++,go,brig,d,fortran,objc,obj-c++,m2 --prefix=/usr --with-gcc-major-version-only --program-suffix=-10 --program-prefix=x86_64-linux-gnu- --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --enable-bootstrap --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-vtable-verify --enable-plugin --enable-default-pie --with-system-zlib --enable-libphobos-checking=release --with-target-system-zlib=auto --enable-objc-gc=auto --enable-multiarch --disable-werror --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic --enable-offload-targets=nvptx-none=/build/gcc-10-S4I5Pr/gcc-10-10.3.0/debian/tmp-nvptx/usr,amdgcn-amdhsa=/build/gcc-10-S4I5Pr/gcc-10-10.3.0/debian/tmp-gcn/usr,hsa --without-cuda-driver --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu --with-build-config=bootstrap-lto-lean --enable-link-mutex
Thread model: posix
Supported LTO compression algorithms: zlib zstd
gcc version 10.3.0 (Ubuntu 10.3.0-1ubuntu1~20.04)
COLLECT_GCC_OPTIONS='-v' '-o' 'CMakeFiles/cmTC_f2ba8.dir/CMakeCCompilerABI.c.o' '-c' '-mtune=generic' '-march=x86-64'
/usr/lib/gcc/x86_64-linux-gnu/10/cc1 -quiet -v -imultiarch x86_64-linux-gnu /snap/clion/184/bin/cmake/linux/share/cmake-3.21/Modules/CMakeCCompilerABI.c -quiet -dumpbase CMakeCCompilerABI.c -mtune=generic -march=x86-64 -auxbase-strip CMakeFiles/cmTC_f2ba8.dir/CMakeCCompilerABI.c.o -version -fasynchronous-unwind-tables -fstack-protector-strong -Wformat -Wformat-security -fstack-clash-protection -fcf-protection -o /tmp/ccapqHEJ.s
GNU C17 (Ubuntu 10.3.0-1ubuntu1~20.04) version 10.3.0 (x86_64-linux-gnu)
compiled by GNU C version 10.3.0, GMP version 6.2.0, MPFR version 4.0.2, MPC version 1.1.0, isl version isl-0.22.1-GMP
GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
ignoring nonexistent directory "/usr/local/include/x86_64-linux-gnu"
ignoring nonexistent directory "/usr/lib/gcc/x86_64-linux-gnu/10/include-fixed"
ignoring nonexistent directory "/usr/lib/gcc/x86_64-linux-gnu/10/../../../../x86_64-linux-gnu/include"
#include "..." search starts here:
#include <...> search starts here:
/usr/lib/gcc/x86_64-linux-gnu/10/include
/usr/local/include
/usr/include/x86_64-linux-gnu
/usr/include
End of search list.
GNU C17 (Ubuntu 10.3.0-1ubuntu1~20.04) version 10.3.0 (x86_64-linux-gnu)
compiled by GNU C version 10.3.0, GMP version 6.2.0, MPFR version 4.0.2, MPC version 1.1.0, isl version isl-0.22.1-GMP
GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
Compiler executable checksum: f2dc2f7bd2244142e4cf7a4d43b693bf
COLLECT_GCC_OPTIONS='-v' '-o' 'CMakeFiles/cmTC_f2ba8.dir/CMakeCCompilerABI.c.o' '-c' '-mtune=generic' '-march=x86-64'
as -v --64 -o CMakeFiles/cmTC_f2ba8.dir/CMakeCCompilerABI.c.o /tmp/ccapqHEJ.s
GNU assembler version 2.34 (x86_64-linux-gnu) using BFD version (GNU Binutils for Ubuntu) 2.34
COMPILER_PATH=/usr/lib/gcc/x86_64-linux-gnu/10/:/usr/lib/gcc/x86_64-linux-gnu/10/:/usr/lib/gcc/x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/10/:/usr/lib/gcc/x86_64-linux-gnu/
LIBRARY_PATH=/usr/lib/gcc/x86_64-linux-gnu/10/:/usr/lib/gcc/x86_64-linux-gnu/10/../../../x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/10/../../../../lib/:/lib/x86_64-linux-gnu/:/lib/../lib/:/usr/lib/x86_64-linux-gnu/:/usr/lib/../lib/:/usr/lib/gcc/x86_64-linux-gnu/10/../../../:/lib/:/usr/lib/
COLLECT_GCC_OPTIONS='-v' '-o' 'CMakeFiles/cmTC_f2ba8.dir/CMakeCCompilerABI.c.o' '-c' '-mtune=generic' '-march=x86-64'
[2/2] Linking C executable cmTC_f2ba8
Using built-in specs.
COLLECT_GCC=/usr/bin/gcc-10
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/10/lto-wrapper
OFFLOAD_TARGET_NAMES=nvptx-none:amdgcn-amdhsa:hsa
OFFLOAD_TARGET_DEFAULT=1
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu 10.3.0-1ubuntu1~20.04' --with-bugurl=file:///usr/share/doc/gcc-10/README.Bugs --enable-languages=c,ada,c++,go,brig,d,fortran,objc,obj-c++,m2 --prefix=/usr --with-gcc-major-version-only --program-suffix=-10 --program-prefix=x86_64-linux-gnu- --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --enable-bootstrap --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-vtable-verify --enable-plugin --enable-default-pie --with-system-zlib --enable-libphobos-checking=release --with-target-system-zlib=auto --enable-objc-gc=auto --enable-multiarch --disable-werror --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic --enable-offload-targets=nvptx-none=/build/gcc-10-S4I5Pr/gcc-10-10.3.0/debian/tmp-nvptx/usr,amdgcn-amdhsa=/build/gcc-10-S4I5Pr/gcc-10-10.3.0/debian/tmp-gcn/usr,hsa --without-cuda-driver --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu --with-build-config=bootstrap-lto-lean --enable-link-mutex
Thread model: posix
Supported LTO compression algorithms: zlib zstd
gcc version 10.3.0 (Ubuntu 10.3.0-1ubuntu1~20.04)
COMPILER_PATH=/usr/lib/gcc/x86_64-linux-gnu/10/:/usr/lib/gcc/x86_64-linux-gnu/10/:/usr/lib/gcc/x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/10/:/usr/lib/gcc/x86_64-linux-gnu/
LIBRARY_PATH=/usr/lib/gcc/x86_64-linux-gnu/10/:/usr/lib/gcc/x86_64-linux-gnu/10/../../../x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/10/../../../../lib/:/lib/x86_64-linux-gnu/:/lib/../lib/:/usr/lib/x86_64-linux-gnu/:/usr/lib/../lib/:/usr/lib/gcc/x86_64-linux-gnu/10/../../../:/lib/:/usr/lib/
COLLECT_GCC_OPTIONS='-v' '-o' 'cmTC_f2ba8' '-mtune=generic' '-march=x86-64'
/usr/lib/gcc/x86_64-linux-gnu/10/collect2 -plugin /usr/lib/gcc/x86_64-linux-gnu/10/liblto_plugin.so -plugin-opt=/usr/lib/gcc/x86_64-linux-gnu/10/lto-wrapper -plugin-opt=-fresolution=/tmp/cc3bjNUZ.res -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lc -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc_s --build-id --eh-frame-hdr -m elf_x86_64 --hash-style=gnu --as-needed -dynamic-linker /lib64/ld-linux-x86-64.so.2 -pie -z now -z relro -o cmTC_f2ba8 /usr/lib/gcc/x86_64-linux-gnu/10/../../../x86_64-linux-gnu/Scrt1.o /usr/lib/gcc/x86_64-linux-gnu/10/../../../x86_64-linux-gnu/crti.o /usr/lib/gcc/x86_64-linux-gnu/10/crtbeginS.o -L/usr/lib/gcc/x86_64-linux-gnu/10 -L/usr/lib/gcc/x86_64-linux-gnu/10/../../../x86_64-linux-gnu -L/usr/lib/gcc/x86_64-linux-gnu/10/../../../../lib -L/lib/x86_64-linux-gnu -L/lib/../lib -L/usr/lib/x86_64-linux-gnu -L/usr/lib/../lib -L/usr/lib/gcc/x86_64-linux-gnu/10/../../.. CMakeFiles/cmTC_f2ba8.dir/CMakeCCompilerABI.c.o -lgcc --push-state --as-needed -lgcc_s --pop-state -lc -lgcc --push-state --as-needed -lgcc_s --pop-state /usr/lib/gcc/x86_64-linux-gnu/10/crtendS.o /usr/lib/gcc/x86_64-linux-gnu/10/../../../x86_64-linux-gnu/crtn.o
COLLECT_GCC_OPTIONS='-v' '-o' 'cmTC_f2ba8' '-mtune=generic' '-march=x86-64'
Parsed C implicit include dir info from above output: rv=done
found start of include info
found start of implicit include info
add: [/usr/lib/gcc/x86_64-linux-gnu/10/include]
add: [/usr/local/include]
add: [/usr/include/x86_64-linux-gnu]
add: [/usr/include]
end of search list found
collapse include dir [/usr/lib/gcc/x86_64-linux-gnu/10/include] ==> [/usr/lib/gcc/x86_64-linux-gnu/10/include]
collapse include dir [/usr/local/include] ==> [/usr/local/include]
collapse include dir [/usr/include/x86_64-linux-gnu] ==> [/usr/include/x86_64-linux-gnu]
collapse include dir [/usr/include] ==> [/usr/include]
implicit include dirs: [/usr/lib/gcc/x86_64-linux-gnu/10/include;/usr/local/include;/usr/include/x86_64-linux-gnu;/usr/include]
Parsed C implicit link information from above output:
link line regex: [^( *|.*[/\])(ld|CMAKE_LINK_STARTFILE-NOTFOUND|([^/\]+-)?ld|collect2)[^/\]*( |$)]
ignore line: [Change Dir: /home/tomer/Github/Public-PF/cmake-build-debug/CMakeFiles/CMakeTmp]
ignore line: []
ignore line: [Run Build Command(s):/snap/clion/184/bin/ninja/linux/ninja cmTC_f2ba8 && [1/2] Building C object CMakeFiles/cmTC_f2ba8.dir/CMakeCCompilerABI.c.o]
ignore line: [Using built-in specs.]
ignore line: [COLLECT_GCC=/usr/bin/gcc-10]
ignore line: [OFFLOAD_TARGET_NAMES=nvptx-none:amdgcn-amdhsa:hsa]
ignore line: [OFFLOAD_TARGET_DEFAULT=1]
ignore line: [Target: x86_64-linux-gnu]
ignore line: [Configured with: ../src/configure -v --with-pkgversion='Ubuntu 10.3.0-1ubuntu1~20.04' --with-bugurl=file:///usr/share/doc/gcc-10/README.Bugs --enable-languages=c ada c++ go brig d fortran objc obj-c++ m2 --prefix=/usr --with-gcc-major-version-only --program-suffix=-10 --program-prefix=x86_64-linux-gnu- --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --enable-bootstrap --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-vtable-verify --enable-plugin --enable-default-pie --with-system-zlib --enable-libphobos-checking=release --with-target-system-zlib=auto --enable-objc-gc=auto --enable-multiarch --disable-werror --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32 m64 mx32 --enable-multilib --with-tune=generic --enable-offload-targets=nvptx-none=/build/gcc-10-S4I5Pr/gcc-10-10.3.0/debian/tmp-nvptx/usr amdgcn-amdhsa=/build/gcc-10-S4I5Pr/gcc-10-10.3.0/debian/tmp-gcn/usr hsa --without-cuda-driver --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu --with-build-config=bootstrap-lto-lean --enable-link-mutex]
ignore line: [Thread model: posix]
ignore line: [Supported LTO compression algorithms: zlib zstd]
ignore line: [gcc version 10.3.0 (Ubuntu 10.3.0-1ubuntu1~20.04) ]
ignore line: [COLLECT_GCC_OPTIONS='-v' '-o' 'CMakeFiles/cmTC_f2ba8.dir/CMakeCCompilerABI.c.o' '-c' '-mtune=generic' '-march=x86-64']
ignore line: [ /usr/lib/gcc/x86_64-linux-gnu/10/cc1 -quiet -v -imultiarch x86_64-linux-gnu /snap/clion/184/bin/cmake/linux/share/cmake-3.21/Modules/CMakeCCompilerABI.c -quiet -dumpbase CMakeCCompilerABI.c -mtune=generic -march=x86-64 -auxbase-strip CMakeFiles/cmTC_f2ba8.dir/CMakeCCompilerABI.c.o -version -fasynchronous-unwind-tables -fstack-protector-strong -Wformat -Wformat-security -fstack-clash-protection -fcf-protection -o /tmp/ccapqHEJ.s]
ignore line: [GNU C17 (Ubuntu 10.3.0-1ubuntu1~20.04) version 10.3.0 (x86_64-linux-gnu)]
ignore line: [ compiled by GNU C version 10.3.0 GMP version 6.2.0 MPFR version 4.0.2 MPC version 1.1.0 isl version isl-0.22.1-GMP]
ignore line: []
ignore line: [GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072]
ignore line: [ignoring nonexistent directory "/usr/local/include/x86_64-linux-gnu"]
ignore line: [ignoring nonexistent directory "/usr/lib/gcc/x86_64-linux-gnu/10/include-fixed"]
ignore line: [ignoring nonexistent directory "/usr/lib/gcc/x86_64-linux-gnu/10/../../../../x86_64-linux-gnu/include"]
ignore line: [#include "..." search starts here:]
ignore line: [#include <...> search starts here:]
ignore line: [ /usr/lib/gcc/x86_64-linux-gnu/10/include]
ignore line: [ /usr/local/include]
ignore line: [ /usr/include/x86_64-linux-gnu]
ignore line: [ /usr/include]
ignore line: [End of search list.]
ignore line: [GNU C17 (Ubuntu 10.3.0-1ubuntu1~20.04) version 10.3.0 (x86_64-linux-gnu)]
ignore line: [ compiled by GNU C version 10.3.0 GMP version 6.2.0 MPFR version 4.0.2 MPC version 1.1.0 isl version isl-0.22.1-GMP]
ignore line: []
ignore line: [GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072]
ignore line: [Compiler executable checksum: f2dc2f7bd2244142e4cf7a4d43b693bf]
ignore line: [COLLECT_GCC_OPTIONS='-v' '-o' 'CMakeFiles/cmTC_f2ba8.dir/CMakeCCompilerABI.c.o' '-c' '-mtune=generic' '-march=x86-64']
ignore line: [ as -v --64 -o CMakeFiles/cmTC_f2ba8.dir/CMakeCCompilerABI.c.o /tmp/ccapqHEJ.s]
ignore line: [GNU assembler version 2.34 (x86_64-linux-gnu) using BFD version (GNU Binutils for Ubuntu) 2.34]
ignore line: [COMPILER_PATH=/usr/lib/gcc/x86_64-linux-gnu/10/:/usr/lib/gcc/x86_64-linux-gnu/10/:/usr/lib/gcc/x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/10/:/usr/lib/gcc/x86_64-linux-gnu/]
ignore line: [LIBRARY_PATH=/usr/lib/gcc/x86_64-linux-gnu/10/:/usr/lib/gcc/x86_64-linux-gnu/10/../../../x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/10/../../../../lib/:/lib/x86_64-linux-gnu/:/lib/../lib/:/usr/lib/x86_64-linux-gnu/:/usr/lib/../lib/:/usr/lib/gcc/x86_64-linux-gnu/10/../../../:/lib/:/usr/lib/]
ignore line: [COLLECT_GCC_OPTIONS='-v' '-o' 'CMakeFiles/cmTC_f2ba8.dir/CMakeCCompilerABI.c.o' '-c' '-mtune=generic' '-march=x86-64']
ignore line: [[2/2] Linking C executable cmTC_f2ba8]
ignore line: [Using built-in specs.]
ignore line: [COLLECT_GCC=/usr/bin/gcc-10]
ignore line: [COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/10/lto-wrapper]
ignore line: [OFFLOAD_TARGET_NAMES=nvptx-none:amdgcn-amdhsa:hsa]
ignore line: [OFFLOAD_TARGET_DEFAULT=1]
ignore line: [Target: x86_64-linux-gnu]
ignore line: [Configured with: ../src/configure -v --with-pkgversion='Ubuntu 10.3.0-1ubuntu1~20.04' --with-bugurl=file:///usr/share/doc/gcc-10/README.Bugs --enable-languages=c ada c++ go brig d fortran objc obj-c++ m2 --prefix=/usr --with-gcc-major-version-only --program-suffix=-10 --program-prefix=x86_64-linux-gnu- --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --enable-bootstrap --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-vtable-verify --enable-plugin --enable-default-pie --with-system-zlib --enable-libphobos-checking=release --with-target-system-zlib=auto --enable-objc-gc=auto --enable-multiarch --disable-werror --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32 m64 mx32 --enable-multilib --with-tune=generic --enable-offload-targets=nvptx-none=/build/gcc-10-S4I5Pr/gcc-10-10.3.0/debian/tmp-nvptx/usr amdgcn-amdhsa=/build/gcc-10-S4I5Pr/gcc-10-10.3.0/debian/tmp-gcn/usr hsa --without-cuda-driver --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu --with-build-config=bootstrap-lto-lean --enable-link-mutex]
ignore line: [Thread model: posix]
ignore line: [Supported LTO compression algorithms: zlib zstd]
ignore line: [gcc version 10.3.0 (Ubuntu 10.3.0-1ubuntu1~20.04) ]
ignore line: [COMPILER_PATH=/usr/lib/gcc/x86_64-linux-gnu/10/:/usr/lib/gcc/x86_64-linux-gnu/10/:/usr/lib/gcc/x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/10/:/usr/lib/gcc/x86_64-linux-gnu/]
ignore line: [LIBRARY_PATH=/usr/lib/gcc/x86_64-linux-gnu/10/:/usr/lib/gcc/x86_64-linux-gnu/10/../../../x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/10/../../../../lib/:/lib/x86_64-linux-gnu/:/lib/../lib/:/usr/lib/x86_64-linux-gnu/:/usr/lib/../lib/:/usr/lib/gcc/x86_64-linux-gnu/10/../../../:/lib/:/usr/lib/]
ignore line: [COLLECT_GCC_OPTIONS='-v' '-o' 'cmTC_f2ba8' '-mtune=generic' '-march=x86-64']
link line: [ /usr/lib/gcc/x86_64-linux-gnu/10/collect2 -plugin /usr/lib/gcc/x86_64-linux-gnu/10/liblto_plugin.so -plugin-opt=/usr/lib/gcc/x86_64-linux-gnu/10/lto-wrapper -plugin-opt=-fresolution=/tmp/cc3bjNUZ.res -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lc -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc_s --build-id --eh-frame-hdr -m elf_x86_64 --hash-style=gnu --as-needed -dynamic-linker /lib64/ld-linux-x86-64.so.2 -pie -z now -z relro -o cmTC_f2ba8 /usr/lib/gcc/x86_64-linux-gnu/10/../../../x86_64-linux-gnu/Scrt1.o /usr/lib/gcc/x86_64-linux-gnu/10/../../../x86_64-linux-gnu/crti.o /usr/lib/gcc/x86_64-linux-gnu/10/crtbeginS.o -L/usr/lib/gcc/x86_64-linux-gnu/10 -L/usr/lib/gcc/x86_64-linux-gnu/10/../../../x86_64-linux-gnu -L/usr/lib/gcc/x86_64-linux-gnu/10/../../../../lib -L/lib/x86_64-linux-gnu -L/lib/../lib -L/usr/lib/x86_64-linux-gnu -L/usr/lib/../lib -L/usr/lib/gcc/x86_64-linux-gnu/10/../../.. CMakeFiles/cmTC_f2ba8.dir/CMakeCCompilerABI.c.o -lgcc --push-state --as-needed -lgcc_s --pop-state -lc -lgcc --push-state --as-needed -lgcc_s --pop-state /usr/lib/gcc/x86_64-linux-gnu/10/crtendS.o /usr/lib/gcc/x86_64-linux-gnu/10/../../../x86_64-linux-gnu/crtn.o]
arg [/usr/lib/gcc/x86_64-linux-gnu/10/collect2] ==> ignore
arg [-plugin] ==> ignore
arg [/usr/lib/gcc/x86_64-linux-gnu/10/liblto_plugin.so] ==> ignore
arg [-plugin-opt=/usr/lib/gcc/x86_64-linux-gnu/10/lto-wrapper] ==> ignore
arg [-plugin-opt=-fresolution=/tmp/cc3bjNUZ.res] ==> ignore
arg [-plugin-opt=-pass-through=-lgcc] ==> ignore
arg [-plugin-opt=-pass-through=-lgcc_s] ==> ignore
arg [-plugin-opt=-pass-through=-lc] ==> ignore
arg [-plugin-opt=-pass-through=-lgcc] ==> ignore
arg [-plugin-opt=-pass-through=-lgcc_s] ==> ignore
arg [--build-id] ==> ignore
arg [--eh-frame-hdr] ==> ignore
arg [-m] ==> ignore
arg [elf_x86_64] ==> ignore
arg [--hash-style=gnu] ==> ignore
arg [--as-needed] ==> ignore
arg [-dynamic-linker] ==> ignore
arg [/lib64/ld-linux-x86-64.so.2] ==> ignore
arg [-pie] ==> ignore
arg [-znow] ==> ignore
arg [-zrelro] ==> ignore
arg [-o] ==> ignore
arg [cmTC_f2ba8] ==> ignore
arg [/usr/lib/gcc/x86_64-linux-gnu/10/../../../x86_64-linux-gnu/Scrt1.o] ==> obj [/usr/lib/gcc/x86_64-linux-gnu/10/../../../x86_64-linux-gnu/Scrt1.o]
arg [/usr/lib/gcc/x86_64-linux-gnu/10/../../../x86_64-linux-gnu/crti.o] ==> obj [/usr/lib/gcc/x86_64-linux-gnu/10/../../../x86_64-linux-gnu/crti.o]
arg [/usr/lib/gcc/x86_64-linux-gnu/10/crtbeginS.o] ==> obj [/usr/lib/gcc/x86_64-linux-gnu/10/crtbeginS.o]
arg [-L/usr/lib/gcc/x86_64-linux-gnu/10] ==> dir [/usr/lib/gcc/x86_64-linux-gnu/10]
arg [-L/usr/lib/gcc/x86_64-linux-gnu/10/../../../x86_64-linux-gnu] ==> dir [/usr/lib/gcc/x86_64-linux-gnu/10/../../../x86_64-linux-gnu]
arg [-L/usr/lib/gcc/x86_64-linux-gnu/10/../../../../lib] ==> dir [/usr/lib/gcc/x86_64-linux-gnu/10/../../../../lib]
arg [-L/lib/x86_64-linux-gnu] ==> dir [/lib/x86_64-linux-gnu]
arg [-L/lib/../lib] ==> dir [/lib/../lib]
arg [-L/usr/lib/x86_64-linux-gnu] ==> dir [/usr/lib/x86_64-linux-gnu]
arg [-L/usr/lib/../lib] ==> dir [/usr/lib/../lib]
arg [-L/usr/lib/gcc/x86_64-linux-gnu/10/../../..] ==> dir [/usr/lib/gcc/x86_64-linux-gnu/10/../../..]
arg [CMakeFiles/cmTC_f2ba8.dir/CMakeCCompilerABI.c.o] ==> ignore
arg [-lgcc] ==> lib [gcc]
arg [--push-state] ==> ignore
arg [--as-needed] ==> ignore
arg [-lgcc_s] ==> lib [gcc_s]
arg [--pop-state] ==> ignore
arg [-lc] ==> lib [c]
arg [-lgcc] ==> lib [gcc]
arg [--push-state] ==> ignore
arg [--as-needed] ==> ignore
arg [-lgcc_s] ==> lib [gcc_s]
arg [--pop-state] ==> ignore
arg [/usr/lib/gcc/x86_64-linux-gnu/10/crtendS.o] ==> obj [/usr/lib/gcc/x86_64-linux-gnu/10/crtendS.o]
arg [/usr/lib/gcc/x86_64-linux-gnu/10/../../../x86_64-linux-gnu/crtn.o] ==> obj [/usr/lib/gcc/x86_64-linux-gnu/10/../../../x86_64-linux-gnu/crtn.o]
collapse obj [/usr/lib/gcc/x86_64-linux-gnu/10/../../../x86_64-linux-gnu/Scrt1.o] ==> [/usr/lib/x86_64-linux-gnu/Scrt1.o]
collapse obj [/usr/lib/gcc/x86_64-linux-gnu/10/../../../x86_64-linux-gnu/crti.o] ==> [/usr/lib/x86_64-linux-gnu/crti.o]
collapse obj [/usr/lib/gcc/x86_64-linux-gnu/10/../../../x86_64-linux-gnu/crtn.o] ==> [/usr/lib/x86_64-linux-gnu/crtn.o]
collapse library dir [/usr/lib/gcc/x86_64-linux-gnu/10] ==> [/usr/lib/gcc/x86_64-linux-gnu/10]
collapse library dir [/usr/lib/gcc/x86_64-linux-gnu/10/../../../x86_64-linux-gnu] ==> [/usr/lib/x86_64-linux-gnu]
collapse library dir [/usr/lib/gcc/x86_64-linux-gnu/10/../../../../lib] ==> [/usr/lib]
collapse library dir [/lib/x86_64-linux-gnu] ==> [/lib/x86_64-linux-gnu]
collapse library dir [/lib/../lib] ==> [/lib]
collapse library dir [/usr/lib/x86_64-linux-gnu] ==> [/usr/lib/x86_64-linux-gnu]
collapse library dir [/usr/lib/../lib] ==> [/usr/lib]
collapse library dir [/usr/lib/gcc/x86_64-linux-gnu/10/../../..] ==> [/usr/lib]
implicit libs: [gcc;gcc_s;c;gcc;gcc_s]
implicit objs: [/usr/lib/x86_64-linux-gnu/Scrt1.o;/usr/lib/x86_64-linux-gnu/crti.o;/usr/lib/gcc/x86_64-linux-gnu/10/crtbeginS.o;/usr/lib/gcc/x86_64-linux-gnu/10/crtendS.o;/usr/lib/x86_64-linux-gnu/crtn.o]
implicit dirs: [/usr/lib/gcc/x86_64-linux-gnu/10;/usr/lib/x86_64-linux-gnu;/usr/lib;/lib/x86_64-linux-gnu;/lib]
implicit fwks: []
Detecting CXX compiler ABI info compiled with the following output:
Change Dir: /home/tomer/Github/Public-PF/cmake-build-debug/CMakeFiles/CMakeTmp
Run Build Command(s):/snap/clion/184/bin/ninja/linux/ninja cmTC_b68b5 && [1/2] Building CXX object CMakeFiles/cmTC_b68b5.dir/CMakeCXXCompilerABI.cpp.o
Using built-in specs.
COLLECT_GCC=/usr/bin/g++-10
OFFLOAD_TARGET_NAMES=nvptx-none:amdgcn-amdhsa:hsa
OFFLOAD_TARGET_DEFAULT=1
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu 10.3.0-1ubuntu1~20.04' --with-bugurl=file:///usr/share/doc/gcc-10/README.Bugs --enable-languages=c,ada,c++,go,brig,d,fortran,objc,obj-c++,m2 --prefix=/usr --with-gcc-major-version-only --program-suffix=-10 --program-prefix=x86_64-linux-gnu- --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --enable-bootstrap --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-vtable-verify --enable-plugin --enable-default-pie --with-system-zlib --enable-libphobos-checking=release --with-target-system-zlib=auto --enable-objc-gc=auto --enable-multiarch --disable-werror --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic --enable-offload-targets=nvptx-none=/build/gcc-10-S4I5Pr/gcc-10-10.3.0/debian/tmp-nvptx/usr,amdgcn-amdhsa=/build/gcc-10-S4I5Pr/gcc-10-10.3.0/debian/tmp-gcn/usr,hsa --without-cuda-driver --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu --with-build-config=bootstrap-lto-lean --enable-link-mutex
Thread model: posix
Supported LTO compression algorithms: zlib zstd
gcc version 10.3.0 (Ubuntu 10.3.0-1ubuntu1~20.04)
COLLECT_GCC_OPTIONS='-v' '-std=gnu++17' '-o' 'CMakeFiles/cmTC_b68b5.dir/CMakeCXXCompilerABI.cpp.o' '-c' '-shared-libgcc' '-mtune=generic' '-march=x86-64'
/usr/lib/gcc/x86_64-linux-gnu/10/cc1plus -quiet -v -imultiarch x86_64-linux-gnu -D_GNU_SOURCE /snap/clion/184/bin/cmake/linux/share/cmake-3.21/Modules/CMakeCXXCompilerABI.cpp -quiet -dumpbase CMakeCXXCompilerABI.cpp -mtune=generic -march=x86-64 -auxbase-strip CMakeFiles/cmTC_b68b5.dir/CMakeCXXCompilerABI.cpp.o -std=gnu++17 -version -fasynchronous-unwind-tables -fstack-protector-strong -Wformat -Wformat-security -fstack-clash-protection -fcf-protection -o /tmp/ccbVbAEB.s
GNU C++17 (Ubuntu 10.3.0-1ubuntu1~20.04) version 10.3.0 (x86_64-linux-gnu)
compiled by GNU C version 10.3.0, GMP version 6.2.0, MPFR version 4.0.2, MPC version 1.1.0, isl version isl-0.22.1-GMP
GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
ignoring duplicate directory "/usr/include/x86_64-linux-gnu/c++/10"
ignoring nonexistent directory "/usr/local/include/x86_64-linux-gnu"
ignoring nonexistent directory "/usr/lib/gcc/x86_64-linux-gnu/10/include-fixed"
ignoring nonexistent directory "/usr/lib/gcc/x86_64-linux-gnu/10/../../../../x86_64-linux-gnu/include"
#include "..." search starts here:
#include <...> search starts here:
/usr/include/c++/10
/usr/include/x86_64-linux-gnu/c++/10
/usr/include/c++/10/backward
/usr/lib/gcc/x86_64-linux-gnu/10/include
/usr/local/include
/usr/include/x86_64-linux-gnu
/usr/include
End of search list.
GNU C++17 (Ubuntu 10.3.0-1ubuntu1~20.04) version 10.3.0 (x86_64-linux-gnu)
compiled by GNU C version 10.3.0, GMP version 6.2.0, MPFR version 4.0.2, MPC version 1.1.0, isl version isl-0.22.1-GMP
GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
Compiler executable checksum: 169ee3a1708a329c07eaf03cc8dfbe6c
COLLECT_GCC_OPTIONS='-v' '-std=gnu++17' '-o' 'CMakeFiles/cmTC_b68b5.dir/CMakeCXXCompilerABI.cpp.o' '-c' '-shared-libgcc' '-mtune=generic' '-march=x86-64'
as -v --64 -o CMakeFiles/cmTC_b68b5.dir/CMakeCXXCompilerABI.cpp.o /tmp/ccbVbAEB.s
GNU assembler version 2.34 (x86_64-linux-gnu) using BFD version (GNU Binutils for Ubuntu) 2.34
COMPILER_PATH=/usr/lib/gcc/x86_64-linux-gnu/10/:/usr/lib/gcc/x86_64-linux-gnu/10/:/usr/lib/gcc/x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/10/:/usr/lib/gcc/x86_64-linux-gnu/
LIBRARY_PATH=/usr/lib/gcc/x86_64-linux-gnu/10/:/usr/lib/gcc/x86_64-linux-gnu/10/../../../x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/10/../../../../lib/:/lib/x86_64-linux-gnu/:/lib/../lib/:/usr/lib/x86_64-linux-gnu/:/usr/lib/../lib/:/usr/lib/gcc/x86_64-linux-gnu/10/../../../:/lib/:/usr/lib/
COLLECT_GCC_OPTIONS='-v' '-std=gnu++17' '-o' 'CMakeFiles/cmTC_b68b5.dir/CMakeCXXCompilerABI.cpp.o' '-c' '-shared-libgcc' '-mtune=generic' '-march=x86-64'
[2/2] Linking CXX executable cmTC_b68b5
Using built-in specs.
COLLECT_GCC=/usr/bin/g++-10
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/10/lto-wrapper
OFFLOAD_TARGET_NAMES=nvptx-none:amdgcn-amdhsa:hsa
OFFLOAD_TARGET_DEFAULT=1
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu 10.3.0-1ubuntu1~20.04' --with-bugurl=file:///usr/share/doc/gcc-10/README.Bugs --enable-languages=c,ada,c++,go,brig,d,fortran,objc,obj-c++,m2 --prefix=/usr --with-gcc-major-version-only --program-suffix=-10 --program-prefix=x86_64-linux-gnu- --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --enable-bootstrap --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-vtable-verify --enable-plugin --enable-default-pie --with-system-zlib --enable-libphobos-checking=release --with-target-system-zlib=auto --enable-objc-gc=auto --enable-multiarch --disable-werror --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic --enable-offload-targets=nvptx-none=/build/gcc-10-S4I5Pr/gcc-10-10.3.0/debian/tmp-nvptx/usr,amdgcn-amdhsa=/build/gcc-10-S4I5Pr/gcc-10-10.3.0/debian/tmp-gcn/usr,hsa --without-cuda-driver --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu --with-build-config=bootstrap-lto-lean --enable-link-mutex
Thread model: posix
Supported LTO compression algorithms: zlib zstd
gcc version 10.3.0 (Ubuntu 10.3.0-1ubuntu1~20.04)
COMPILER_PATH=/usr/lib/gcc/x86_64-linux-gnu/10/:/usr/lib/gcc/x86_64-linux-gnu/10/:/usr/lib/gcc/x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/10/:/usr/lib/gcc/x86_64-linux-gnu/
LIBRARY_PATH=/usr/lib/gcc/x86_64-linux-gnu/10/:/usr/lib/gcc/x86_64-linux-gnu/10/../../../x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/10/../../../../lib/:/lib/x86_64-linux-gnu/:/lib/../lib/:/usr/lib/x86_64-linux-gnu/:/usr/lib/../lib/:/usr/lib/gcc/x86_64-linux-gnu/10/../../../:/lib/:/usr/lib/
COLLECT_GCC_OPTIONS='-v' '-o' 'cmTC_b68b5' '-shared-libgcc' '-mtune=generic' '-march=x86-64'
/usr/lib/gcc/x86_64-linux-gnu/10/collect2 -plugin /usr/lib/gcc/x86_64-linux-gnu/10/liblto_plugin.so -plugin-opt=/usr/lib/gcc/x86_64-linux-gnu/10/lto-wrapper -plugin-opt=-fresolution=/tmp/ccmp9yeW.res -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lc -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lgcc --build-id --eh-frame-hdr -m elf_x86_64 --hash-style=gnu --as-needed -dynamic-linker /lib64/ld-linux-x86-64.so.2 -pie -z now -z relro -o cmTC_b68b5 /usr/lib/gcc/x86_64-linux-gnu/10/../../../x86_64-linux-gnu/Scrt1.o /usr/lib/gcc/x86_64-linux-gnu/10/../../../x86_64-linux-gnu/crti.o /usr/lib/gcc/x86_64-linux-gnu/10/crtbeginS.o -L/usr/lib/gcc/x86_64-linux-gnu/10 -L/usr/lib/gcc/x86_64-linux-gnu/10/../../../x86_64-linux-gnu -L/usr/lib/gcc/x86_64-linux-gnu/10/../../../../lib -L/lib/x86_64-linux-gnu -L/lib/../lib -L/usr/lib/x86_64-linux-gnu -L/usr/lib/../lib -L/usr/lib/gcc/x86_64-linux-gnu/10/../../.. CMakeFiles/cmTC_b68b5.dir/CMakeCXXCompilerABI.cpp.o -lstdc++ -lm -lgcc_s -lgcc -lc -lgcc_s -lgcc /usr/lib/gcc/x86_64-linux-gnu/10/crtendS.o /usr/lib/gcc/x86_64-linux-gnu/10/../../../x86_64-linux-gnu/crtn.o
COLLECT_GCC_OPTIONS='-v' '-o' 'cmTC_b68b5' '-shared-libgcc' '-mtune=generic' '-march=x86-64'
Parsed CXX implicit include dir info from above output: rv=done
found start of include info
found start of implicit include info
add: [/usr/include/c++/10]
add: [/usr/include/x86_64-linux-gnu/c++/10]
add: [/usr/include/c++/10/backward]
add: [/usr/lib/gcc/x86_64-linux-gnu/10/include]
add: [/usr/local/include]
add: [/usr/include/x86_64-linux-gnu]
add: [/usr/include]
end of search list found
collapse include dir [/usr/include/c++/10] ==> [/usr/include/c++/10]
collapse include dir [/usr/include/x86_64-linux-gnu/c++/10] ==> [/usr/include/x86_64-linux-gnu/c++/10]
collapse include dir [/usr/include/c++/10/backward] ==> [/usr/include/c++/10/backward]
collapse include dir [/usr/lib/gcc/x86_64-linux-gnu/10/include] ==> [/usr/lib/gcc/x86_64-linux-gnu/10/include]
collapse include dir [/usr/local/include] ==> [/usr/local/include]
collapse include dir [/usr/include/x86_64-linux-gnu] ==> [/usr/include/x86_64-linux-gnu]
collapse include dir [/usr/include] ==> [/usr/include]
implicit include dirs: [/usr/include/c++/10;/usr/include/x86_64-linux-gnu/c++/10;/usr/include/c++/10/backward;/usr/lib/gcc/x86_64-linux-gnu/10/include;/usr/local/include;/usr/include/x86_64-linux-gnu;/usr/include]
Parsed CXX implicit link information from above output:
link line regex: [^( *|.*[/\])(ld|CMAKE_LINK_STARTFILE-NOTFOUND|([^/\]+-)?ld|collect2)[^/\]*( |$)]
ignore line: [Change Dir: /home/tomer/Github/Public-PF/cmake-build-debug/CMakeFiles/CMakeTmp]
ignore line: []
ignore line: [Run Build Command(s):/snap/clion/184/bin/ninja/linux/ninja cmTC_b68b5 && [1/2] Building CXX object CMakeFiles/cmTC_b68b5.dir/CMakeCXXCompilerABI.cpp.o]
ignore line: [Using built-in specs.]
ignore line: [COLLECT_GCC=/usr/bin/g++-10]
ignore line: [OFFLOAD_TARGET_NAMES=nvptx-none:amdgcn-amdhsa:hsa]
ignore line: [OFFLOAD_TARGET_DEFAULT=1]
ignore line: [Target: x86_64-linux-gnu]
ignore line: [Configured with: ../src/configure -v --with-pkgversion='Ubuntu 10.3.0-1ubuntu1~20.04' --with-bugurl=file:///usr/share/doc/gcc-10/README.Bugs --enable-languages=c ada c++ go brig d fortran objc obj-c++ m2 --prefix=/usr --with-gcc-major-version-only --program-suffix=-10 --program-prefix=x86_64-linux-gnu- --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --enable-bootstrap --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-vtable-verify --enable-plugin --enable-default-pie --with-system-zlib --enable-libphobos-checking=release --with-target-system-zlib=auto --enable-objc-gc=auto --enable-multiarch --disable-werror --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32 m64 mx32 --enable-multilib --with-tune=generic --enable-offload-targets=nvptx-none=/build/gcc-10-S4I5Pr/gcc-10-10.3.0/debian/tmp-nvptx/usr amdgcn-amdhsa=/build/gcc-10-S4I5Pr/gcc-10-10.3.0/debian/tmp-gcn/usr hsa --without-cuda-driver --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu --with-build-config=bootstrap-lto-lean --enable-link-mutex]
ignore line: [Thread model: posix]
ignore line: [Supported LTO compression algorithms: zlib zstd]
ignore line: [gcc version 10.3.0 (Ubuntu 10.3.0-1ubuntu1~20.04) ]
ignore line: [COLLECT_GCC_OPTIONS='-v' '-std=gnu++17' '-o' 'CMakeFiles/cmTC_b68b5.dir/CMakeCXXCompilerABI.cpp.o' '-c' '-shared-libgcc' '-mtune=generic' '-march=x86-64']
ignore line: [ /usr/lib/gcc/x86_64-linux-gnu/10/cc1plus -quiet -v -imultiarch x86_64-linux-gnu -D_GNU_SOURCE /snap/clion/184/bin/cmake/linux/share/cmake-3.21/Modules/CMakeCXXCompilerABI.cpp -quiet -dumpbase CMakeCXXCompilerABI.cpp -mtune=generic -march=x86-64 -auxbase-strip CMakeFiles/cmTC_b68b5.dir/CMakeCXXCompilerABI.cpp.o -std=gnu++17 -version -fasynchronous-unwind-tables -fstack-protector-strong -Wformat -Wformat-security -fstack-clash-protection -fcf-protection -o /tmp/ccbVbAEB.s]
ignore line: [GNU C++17 (Ubuntu 10.3.0-1ubuntu1~20.04) version 10.3.0 (x86_64-linux-gnu)]
ignore line: [ compiled by GNU C version 10.3.0 GMP version 6.2.0 MPFR version 4.0.2 MPC version 1.1.0 isl version isl-0.22.1-GMP]
ignore line: []
ignore line: [GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072]
ignore line: [ignoring duplicate directory "/usr/include/x86_64-linux-gnu/c++/10"]
ignore line: [ignoring nonexistent directory "/usr/local/include/x86_64-linux-gnu"]
ignore line: [ignoring nonexistent directory "/usr/lib/gcc/x86_64-linux-gnu/10/include-fixed"]
ignore line: [ignoring nonexistent directory "/usr/lib/gcc/x86_64-linux-gnu/10/../../../../x86_64-linux-gnu/include"]
ignore line: [#include "..." search starts here:]
ignore line: [#include <...> search starts here:]
ignore line: [ /usr/include/c++/10]
ignore line: [ /usr/include/x86_64-linux-gnu/c++/10]
ignore line: [ /usr/include/c++/10/backward]
ignore line: [ /usr/lib/gcc/x86_64-linux-gnu/10/include]
ignore line: [ /usr/local/include]
ignore line: [ /usr/include/x86_64-linux-gnu]
ignore line: [ /usr/include]
ignore line: [End of search list.]
ignore line: [GNU C++17 (Ubuntu 10.3.0-1ubuntu1~20.04) version 10.3.0 (x86_64-linux-gnu)]
ignore line: [ compiled by GNU C version 10.3.0 GMP version 6.2.0 MPFR version 4.0.2 MPC version 1.1.0 isl version isl-0.22.1-GMP]
ignore line: []
ignore line: [GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072]
ignore line: [Compiler executable checksum: 169ee3a1708a329c07eaf03cc8dfbe6c]
ignore line: [COLLECT_GCC_OPTIONS='-v' '-std=gnu++17' '-o' 'CMakeFiles/cmTC_b68b5.dir/CMakeCXXCompilerABI.cpp.o' '-c' '-shared-libgcc' '-mtune=generic' '-march=x86-64']
ignore line: [ as -v --64 -o CMakeFiles/cmTC_b68b5.dir/CMakeCXXCompilerABI.cpp.o /tmp/ccbVbAEB.s]
ignore line: [GNU assembler version 2.34 (x86_64-linux-gnu) using BFD version (GNU Binutils for Ubuntu) 2.34]
ignore line: [COMPILER_PATH=/usr/lib/gcc/x86_64-linux-gnu/10/:/usr/lib/gcc/x86_64-linux-gnu/10/:/usr/lib/gcc/x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/10/:/usr/lib/gcc/x86_64-linux-gnu/]
ignore line: [LIBRARY_PATH=/usr/lib/gcc/x86_64-linux-gnu/10/:/usr/lib/gcc/x86_64-linux-gnu/10/../../../x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/10/../../../../lib/:/lib/x86_64-linux-gnu/:/lib/../lib/:/usr/lib/x86_64-linux-gnu/:/usr/lib/../lib/:/usr/lib/gcc/x86_64-linux-gnu/10/../../../:/lib/:/usr/lib/]
ignore line: [COLLECT_GCC_OPTIONS='-v' '-std=gnu++17' '-o' 'CMakeFiles/cmTC_b68b5.dir/CMakeCXXCompilerABI.cpp.o' '-c' '-shared-libgcc' '-mtune=generic' '-march=x86-64']
ignore line: [[2/2] Linking CXX executable cmTC_b68b5]
ignore line: [Using built-in specs.]
ignore line: [COLLECT_GCC=/usr/bin/g++-10]
ignore line: [COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/10/lto-wrapper]
ignore line: [OFFLOAD_TARGET_NAMES=nvptx-none:amdgcn-amdhsa:hsa]
ignore line: [OFFLOAD_TARGET_DEFAULT=1]
ignore line: [Target: x86_64-linux-gnu]
ignore line: [Configured with: ../src/configure -v --with-pkgversion='Ubuntu 10.3.0-1ubuntu1~20.04' --with-bugurl=file:///usr/share/doc/gcc-10/README.Bugs --enable-languages=c ada c++ go brig d fortran objc obj-c++ m2 --prefix=/usr --with-gcc-major-version-only --program-suffix=-10 --program-prefix=x86_64-linux-gnu- --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --enable-bootstrap --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-vtable-verify --enable-plugin --enable-default-pie --with-system-zlib --enable-libphobos-checking=release --with-target-system-zlib=auto --enable-objc-gc=auto --enable-multiarch --disable-werror --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32 m64 mx32 --enable-multilib --with-tune=generic --enable-offload-targets=nvptx-none=/build/gcc-10-S4I5Pr/gcc-10-10.3.0/debian/tmp-nvptx/usr amdgcn-amdhsa=/build/gcc-10-S4I5Pr/gcc-10-10.3.0/debian/tmp-gcn/usr hsa --without-cuda-driver --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu --with-build-config=bootstrap-lto-lean --enable-link-mutex]
ignore line: [Thread model: posix]
ignore line: [Supported LTO compression algorithms: zlib zstd]
ignore line: [gcc version 10.3.0 (Ubuntu 10.3.0-1ubuntu1~20.04) ]
ignore line: [COMPILER_PATH=/usr/lib/gcc/x86_64-linux-gnu/10/:/usr/lib/gcc/x86_64-linux-gnu/10/:/usr/lib/gcc/x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/10/:/usr/lib/gcc/x86_64-linux-gnu/]
ignore line: [LIBRARY_PATH=/usr/lib/gcc/x86_64-linux-gnu/10/:/usr/lib/gcc/x86_64-linux-gnu/10/../../../x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/10/../../../../lib/:/lib/x86_64-linux-gnu/:/lib/../lib/:/usr/lib/x86_64-linux-gnu/:/usr/lib/../lib/:/usr/lib/gcc/x86_64-linux-gnu/10/../../../:/lib/:/usr/lib/]
ignore line: [COLLECT_GCC_OPTIONS='-v' '-o' 'cmTC_b68b5' '-shared-libgcc' '-mtune=generic' '-march=x86-64']
link line: [ /usr/lib/gcc/x86_64-linux-gnu/10/collect2 -plugin /usr/lib/gcc/x86_64-linux-gnu/10/liblto_plugin.so -plugin-opt=/usr/lib/gcc/x86_64-linux-gnu/10/lto-wrapper -plugin-opt=-fresolution=/tmp/ccmp9yeW.res -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lc -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lgcc --build-id --eh-frame-hdr -m elf_x86_64 --hash-style=gnu --as-needed -dynamic-linker /lib64/ld-linux-x86-64.so.2 -pie -z now -z relro -o cmTC_b68b5 /usr/lib/gcc/x86_64-linux-gnu/10/../../../x86_64-linux-gnu/Scrt1.o /usr/lib/gcc/x86_64-linux-gnu/10/../../../x86_64-linux-gnu/crti.o /usr/lib/gcc/x86_64-linux-gnu/10/crtbeginS.o -L/usr/lib/gcc/x86_64-linux-gnu/10 -L/usr/lib/gcc/x86_64-linux-gnu/10/../../../x86_64-linux-gnu -L/usr/lib/gcc/x86_64-linux-gnu/10/../../../../lib -L/lib/x86_64-linux-gnu -L/lib/../lib -L/usr/lib/x86_64-linux-gnu -L/usr/lib/../lib -L/usr/lib/gcc/x86_64-linux-gnu/10/../../.. CMakeFiles/cmTC_b68b5.dir/CMakeCXXCompilerABI.cpp.o -lstdc++ -lm -lgcc_s -lgcc -lc -lgcc_s -lgcc /usr/lib/gcc/x86_64-linux-gnu/10/crtendS.o /usr/lib/gcc/x86_64-linux-gnu/10/../../../x86_64-linux-gnu/crtn.o]
arg [/usr/lib/gcc/x86_64-linux-gnu/10/collect2] ==> ignore
arg [-plugin] ==> ignore
arg [/usr/lib/gcc/x86_64-linux-gnu/10/liblto_plugin.so] ==> ignore
arg [-plugin-opt=/usr/lib/gcc/x86_64-linux-gnu/10/lto-wrapper] ==> ignore
arg [-plugin-opt=-fresolution=/tmp/ccmp9yeW.res] ==> ignore
arg [-plugin-opt=-pass-through=-lgcc_s] ==> ignore
arg [-plugin-opt=-pass-through=-lgcc] ==> ignore
arg [-plugin-opt=-pass-through=-lc] ==> ignore
arg [-plugin-opt=-pass-through=-lgcc_s] ==> ignore
arg [-plugin-opt=-pass-through=-lgcc] ==> ignore
arg [--build-id] ==> ignore
arg [--eh-frame-hdr] ==> ignore
arg [-m] ==> ignore
arg [elf_x86_64] ==> ignore
arg [--hash-style=gnu] ==> ignore
arg [--as-needed] ==> ignore
arg [-dynamic-linker] ==> ignore
arg [/lib64/ld-linux-x86-64.so.2] ==> ignore
arg [-pie] ==> ignore
arg [-znow] ==> ignore
arg [-zrelro] ==> ignore
arg [-o] ==> ignore
arg [cmTC_b68b5] ==> ignore
arg [/usr/lib/gcc/x86_64-linux-gnu/10/../../../x86_64-linux-gnu/Scrt1.o] ==> obj [/usr/lib/gcc/x86_64-linux-gnu/10/../../../x86_64-linux-gnu/Scrt1.o]
arg [/usr/lib/gcc/x86_64-linux-gnu/10/../../../x86_64-linux-gnu/crti.o] ==> obj [/usr/lib/gcc/x86_64-linux-gnu/10/../../../x86_64-linux-gnu/crti.o]
arg [/usr/lib/gcc/x86_64-linux-gnu/10/crtbeginS.o] ==> obj [/usr/lib/gcc/x86_64-linux-gnu/10/crtbeginS.o]
arg [-L/usr/lib/gcc/x86_64-linux-gnu/10] ==> dir [/usr/lib/gcc/x86_64-linux-gnu/10]
arg [-L/usr/lib/gcc/x86_64-linux-gnu/10/../../../x86_64-linux-gnu] ==> dir [/usr/lib/gcc/x86_64-linux-gnu/10/../../../x86_64-linux-gnu]
arg [-L/usr/lib/gcc/x86_64-linux-gnu/10/../../../../lib] ==> dir [/usr/lib/gcc/x86_64-linux-gnu/10/../../../../lib]
arg [-L/lib/x86_64-linux-gnu] ==> dir [/lib/x86_64-linux-gnu]
arg [-L/lib/../lib] ==> dir [/lib/../lib]
arg [-L/usr/lib/x86_64-linux-gnu] ==> dir [/usr/lib/x86_64-linux-gnu]
arg [-L/usr/lib/../lib] ==> dir [/usr/lib/../lib]
arg [-L/usr/lib/gcc/x86_64-linux-gnu/10/../../..] ==> dir [/usr/lib/gcc/x86_64-linux-gnu/10/../../..]
arg [CMakeFiles/cmTC_b68b5.dir/CMakeCXXCompilerABI.cpp.o] ==> ignore
arg [-lstdc++] ==> lib [stdc++]
arg [-lm] ==> lib [m]
arg [-lgcc_s] ==> lib [gcc_s]
arg [-lgcc] ==> lib [gcc]
arg [-lc] ==> lib [c]
arg [-lgcc_s] ==> lib [gcc_s]
arg [-lgcc] ==> lib [gcc]
arg [/usr/lib/gcc/x86_64-linux-gnu/10/crtendS.o] ==> obj [/usr/lib/gcc/x86_64-linux-gnu/10/crtendS.o]
arg [/usr/lib/gcc/x86_64-linux-gnu/10/../../../x86_64-linux-gnu/crtn.o] ==> obj [/usr/lib/gcc/x86_64-linux-gnu/10/../../../x86_64-linux-gnu/crtn.o]
collapse obj [/usr/lib/gcc/x86_64-linux-gnu/10/../../../x86_64-linux-gnu/Scrt1.o] ==> [/usr/lib/x86_64-linux-gnu/Scrt1.o]
collapse obj [/usr/lib/gcc/x86_64-linux-gnu/10/../../../x86_64-linux-gnu/crti.o] ==> [/usr/lib/x86_64-linux-gnu/crti.o]
collapse obj [/usr/lib/gcc/x86_64-linux-gnu/10/../../../x86_64-linux-gnu/crtn.o] ==> [/usr/lib/x86_64-linux-gnu/crtn.o]
collapse library dir [/usr/lib/gcc/x86_64-linux-gnu/10] ==> [/usr/lib/gcc/x86_64-linux-gnu/10]
collapse library dir [/usr/lib/gcc/x86_64-linux-gnu/10/../../../x86_64-linux-gnu] ==> [/usr/lib/x86_64-linux-gnu]
collapse library dir [/usr/lib/gcc/x86_64-linux-gnu/10/../../../../lib] ==> [/usr/lib]
collapse library dir [/lib/x86_64-linux-gnu] ==> [/lib/x86_64-linux-gnu]
collapse library dir [/lib/../lib] ==> [/lib]
collapse library dir [/usr/lib/x86_64-linux-gnu] ==> [/usr/lib/x86_64-linux-gnu]
collapse library dir [/usr/lib/../lib] ==> [/usr/lib]
collapse library dir [/usr/lib/gcc/x86_64-linux-gnu/10/../../..] ==> [/usr/lib]
implicit libs: [stdc++;m;gcc_s;gcc;c;gcc_s;gcc]
implicit objs: [/usr/lib/x86_64-linux-gnu/Scrt1.o;/usr/lib/x86_64-linux-gnu/crti.o;/usr/lib/gcc/x86_64-linux-gnu/10/crtbeginS.o;/usr/lib/gcc/x86_64-linux-gnu/10/crtendS.o;/usr/lib/x86_64-linux-gnu/crtn.o]
implicit dirs: [/usr/lib/gcc/x86_64-linux-gnu/10;/usr/lib/x86_64-linux-gnu;/usr/lib;/lib/x86_64-linux-gnu;/lib]
implicit fwks: []

View File

@ -0,0 +1,13 @@
/home/tomer/Github/Public-PF/cmake-build-debug/CMakeFiles/rebuild_cache.dir
/home/tomer/Github/Public-PF/cmake-build-debug/CMakeFiles/edit_cache.dir
/home/tomer/Github/Public-PF/cmake-build-debug/CMakeFiles/example.dir
/home/tomer/Github/Public-PF/cmake-build-debug/CMakeFiles/measure_fpp0.dir
/home/tomer/Github/Public-PF/cmake-build-debug/CMakeFiles/measure_perf.dir
/home/tomer/Github/Public-PF/cmake-build-debug/CMakeFiles/measure_built3.dir
/home/tomer/Github/Public-PF/cmake-build-debug/CMakeFiles/measure_built0.dir
/home/tomer/Github/Public-PF/cmake-build-debug/CMakeFiles/measure_built.dir
/home/tomer/Github/Public-PF/cmake-build-debug/CMakeFiles/measure_perf3.dir
/home/tomer/Github/Public-PF/cmake-build-debug/CMakeFiles/measure_fpp3.dir
/home/tomer/Github/Public-PF/cmake-build-debug/CMakeFiles/measure_perf0.dir
/home/tomer/Github/Public-PF/cmake-build-debug/CMakeFiles/measure_fpp.dir
/home/tomer/Github/Public-PF/cmake-build-debug/CMakeFiles/example0.dir

Binary file not shown.

View File

@ -0,0 +1,16 @@
/snap/clion/184/bin/cmake/linux/bin/cmake -DCMAKE_BUILD_TYPE=Debug -DCMAKE_MAKE_PROGRAM=/snap/clion/184/bin/ninja/linux/ninja -DCMAKE_C_COMPILER=/usr/bin/gcc-10 -DCMAKE_CXX_COMPILER=/usr/bin/g++-10 -G Ninja /home/tomer/Github/Public-PF
-- The C compiler identification is GNU 10.3.0
-- The CXX compiler identification is GNU 10.3.0
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /usr/bin/gcc-10 - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/g++-10 - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done
-- Generating done
-- Build files have been written to: /home/tomer/Github/Public-PF/cmake-build-debug

View File

@ -0,0 +1 @@
# This file is generated by cmake for dependency checking of the CMakeCache.txt file

View File

@ -0,0 +1,254 @@
# CMAKE generated file: DO NOT EDIT!
# Generated by "Ninja" Generator, CMake Version 3.21
# This file contains all the rules used to get the outputs files
# built from the input files.
# It is included in the main 'build.ninja'.
# =============================================================================
# Project: APD_ONLY
# Configurations: Debug
# =============================================================================
# =============================================================================
#############################################
# Rule for running custom commands.
rule CUSTOM_COMMAND
command = $COMMAND
description = $DESC
#############################################
# Rule for compiling CXX files.
rule CXX_COMPILER__example_Debug
depfile = $DEP_FILE
deps = gcc
command = /usr/bin/g++-10 $DEFINES $INCLUDES $FLAGS -MD -MT $out -MF $DEP_FILE -o $out -c $in
description = Building CXX object $out
#############################################
# Rule for linking CXX executable.
rule CXX_EXECUTABLE_LINKER__example_Debug
command = $PRE_LINK && /usr/bin/g++-10 $FLAGS $LINK_FLAGS $in -o $TARGET_FILE $LINK_PATH $LINK_LIBRARIES && $POST_BUILD
description = Linking CXX executable $TARGET_FILE
restat = $RESTAT
#############################################
# Rule for compiling CXX files.
rule CXX_COMPILER__measure_fpp0_Debug
depfile = $DEP_FILE
deps = gcc
command = /usr/bin/g++-10 $DEFINES $INCLUDES $FLAGS -MD -MT $out -MF $DEP_FILE -o $out -c $in
description = Building CXX object $out
#############################################
# Rule for linking CXX executable.
rule CXX_EXECUTABLE_LINKER__measure_fpp0_Debug
command = $PRE_LINK && /usr/bin/g++-10 $FLAGS $LINK_FLAGS $in -o $TARGET_FILE $LINK_PATH $LINK_LIBRARIES && $POST_BUILD
description = Linking CXX executable $TARGET_FILE
restat = $RESTAT
#############################################
# Rule for compiling CXX files.
rule CXX_COMPILER__measure_perf_Debug
depfile = $DEP_FILE
deps = gcc
command = /usr/bin/g++-10 $DEFINES $INCLUDES $FLAGS -MD -MT $out -MF $DEP_FILE -o $out -c $in
description = Building CXX object $out
#############################################
# Rule for linking CXX executable.
rule CXX_EXECUTABLE_LINKER__measure_perf_Debug
command = $PRE_LINK && /usr/bin/g++-10 $FLAGS $LINK_FLAGS $in -o $TARGET_FILE $LINK_PATH $LINK_LIBRARIES && $POST_BUILD
description = Linking CXX executable $TARGET_FILE
restat = $RESTAT
#############################################
# Rule for compiling CXX files.
rule CXX_COMPILER__measure_built3_Debug
depfile = $DEP_FILE
deps = gcc
command = /usr/bin/g++-10 $DEFINES $INCLUDES $FLAGS -MD -MT $out -MF $DEP_FILE -o $out -c $in
description = Building CXX object $out
#############################################
# Rule for linking CXX executable.
rule CXX_EXECUTABLE_LINKER__measure_built3_Debug
command = $PRE_LINK && /usr/bin/g++-10 $FLAGS $LINK_FLAGS $in -o $TARGET_FILE $LINK_PATH $LINK_LIBRARIES && $POST_BUILD
description = Linking CXX executable $TARGET_FILE
restat = $RESTAT
#############################################
# Rule for compiling CXX files.
rule CXX_COMPILER__measure_built0_Debug
depfile = $DEP_FILE
deps = gcc
command = /usr/bin/g++-10 $DEFINES $INCLUDES $FLAGS -MD -MT $out -MF $DEP_FILE -o $out -c $in
description = Building CXX object $out
#############################################
# Rule for linking CXX executable.
rule CXX_EXECUTABLE_LINKER__measure_built0_Debug
command = $PRE_LINK && /usr/bin/g++-10 $FLAGS $LINK_FLAGS $in -o $TARGET_FILE $LINK_PATH $LINK_LIBRARIES && $POST_BUILD
description = Linking CXX executable $TARGET_FILE
restat = $RESTAT
#############################################
# Rule for compiling CXX files.
rule CXX_COMPILER__measure_built_Debug
depfile = $DEP_FILE
deps = gcc
command = /usr/bin/g++-10 $DEFINES $INCLUDES $FLAGS -MD -MT $out -MF $DEP_FILE -o $out -c $in
description = Building CXX object $out
#############################################
# Rule for linking CXX executable.
rule CXX_EXECUTABLE_LINKER__measure_built_Debug
command = $PRE_LINK && /usr/bin/g++-10 $FLAGS $LINK_FLAGS $in -o $TARGET_FILE $LINK_PATH $LINK_LIBRARIES && $POST_BUILD
description = Linking CXX executable $TARGET_FILE
restat = $RESTAT
#############################################
# Rule for compiling CXX files.
rule CXX_COMPILER__measure_perf3_Debug
depfile = $DEP_FILE
deps = gcc
command = /usr/bin/g++-10 $DEFINES $INCLUDES $FLAGS -MD -MT $out -MF $DEP_FILE -o $out -c $in
description = Building CXX object $out
#############################################
# Rule for linking CXX executable.
rule CXX_EXECUTABLE_LINKER__measure_perf3_Debug
command = $PRE_LINK && /usr/bin/g++-10 $FLAGS $LINK_FLAGS $in -o $TARGET_FILE $LINK_PATH $LINK_LIBRARIES && $POST_BUILD
description = Linking CXX executable $TARGET_FILE
restat = $RESTAT
#############################################
# Rule for compiling CXX files.
rule CXX_COMPILER__measure_fpp3_Debug
depfile = $DEP_FILE
deps = gcc
command = /usr/bin/g++-10 $DEFINES $INCLUDES $FLAGS -MD -MT $out -MF $DEP_FILE -o $out -c $in
description = Building CXX object $out
#############################################
# Rule for linking CXX executable.
rule CXX_EXECUTABLE_LINKER__measure_fpp3_Debug
command = $PRE_LINK && /usr/bin/g++-10 $FLAGS $LINK_FLAGS $in -o $TARGET_FILE $LINK_PATH $LINK_LIBRARIES && $POST_BUILD
description = Linking CXX executable $TARGET_FILE
restat = $RESTAT
#############################################
# Rule for compiling CXX files.
rule CXX_COMPILER__measure_perf0_Debug
depfile = $DEP_FILE
deps = gcc
command = /usr/bin/g++-10 $DEFINES $INCLUDES $FLAGS -MD -MT $out -MF $DEP_FILE -o $out -c $in
description = Building CXX object $out
#############################################
# Rule for linking CXX executable.
rule CXX_EXECUTABLE_LINKER__measure_perf0_Debug
command = $PRE_LINK && /usr/bin/g++-10 $FLAGS $LINK_FLAGS $in -o $TARGET_FILE $LINK_PATH $LINK_LIBRARIES && $POST_BUILD
description = Linking CXX executable $TARGET_FILE
restat = $RESTAT
#############################################
# Rule for compiling CXX files.
rule CXX_COMPILER__measure_fpp_Debug
depfile = $DEP_FILE
deps = gcc
command = /usr/bin/g++-10 $DEFINES $INCLUDES $FLAGS -MD -MT $out -MF $DEP_FILE -o $out -c $in
description = Building CXX object $out
#############################################
# Rule for linking CXX executable.
rule CXX_EXECUTABLE_LINKER__measure_fpp_Debug
command = $PRE_LINK && /usr/bin/g++-10 $FLAGS $LINK_FLAGS $in -o $TARGET_FILE $LINK_PATH $LINK_LIBRARIES && $POST_BUILD
description = Linking CXX executable $TARGET_FILE
restat = $RESTAT
#############################################
# Rule for compiling CXX files.
rule CXX_COMPILER__example0_Debug
depfile = $DEP_FILE
deps = gcc
command = /usr/bin/g++-10 $DEFINES $INCLUDES $FLAGS -MD -MT $out -MF $DEP_FILE -o $out -c $in
description = Building CXX object $out
#############################################
# Rule for linking CXX executable.
rule CXX_EXECUTABLE_LINKER__example0_Debug
command = $PRE_LINK && /usr/bin/g++-10 $FLAGS $LINK_FLAGS $in -o $TARGET_FILE $LINK_PATH $LINK_LIBRARIES && $POST_BUILD
description = Linking CXX executable $TARGET_FILE
restat = $RESTAT
#############################################
# Rule for re-running cmake.
rule RERUN_CMAKE
command = /snap/clion/184/bin/cmake/linux/bin/cmake --regenerate-during-build -S/home/tomer/Github/Public-PF -B/home/tomer/Github/Public-PF/cmake-build-debug
description = Re-running CMake...
generator = 1
#############################################
# Rule for cleaning all built files.
rule CLEAN
command = /snap/clion/184/bin/ninja/linux/ninja $FILE_ARG -t clean $TARGETS
description = Cleaning all built files...
#############################################
# Rule for printing all primary targets available.
rule HELP
command = /snap/clion/184/bin/ninja/linux/ninja -t targets
description = All primary targets available:

View File

@ -0,0 +1,3 @@
Start testing: Mar 18 12:15 IST
----------------------------------------------------------
End testing: Mar 18 12:15 IST

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,54 @@
# Install script for directory: /home/tomer/Github/Public-PF
# Set the install prefix
if(NOT DEFINED CMAKE_INSTALL_PREFIX)
set(CMAKE_INSTALL_PREFIX "/usr/local")
endif()
string(REGEX REPLACE "/$" "" CMAKE_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}")
# Set the install configuration name.
if(NOT DEFINED CMAKE_INSTALL_CONFIG_NAME)
if(BUILD_TYPE)
string(REGEX REPLACE "^[^A-Za-z0-9_]+" ""
CMAKE_INSTALL_CONFIG_NAME "${BUILD_TYPE}")
else()
set(CMAKE_INSTALL_CONFIG_NAME "Debug")
endif()
message(STATUS "Install configuration: \"${CMAKE_INSTALL_CONFIG_NAME}\"")
endif()
# Set the component getting installed.
if(NOT CMAKE_INSTALL_COMPONENT)
if(COMPONENT)
message(STATUS "Install component: \"${COMPONENT}\"")
set(CMAKE_INSTALL_COMPONENT "${COMPONENT}")
else()
set(CMAKE_INSTALL_COMPONENT)
endif()
endif()
# Install shared libraries without execute permission?
if(NOT DEFINED CMAKE_INSTALL_SO_NO_EXE)
set(CMAKE_INSTALL_SO_NO_EXE "1")
endif()
# Is this installation the result of a crosscompile?
if(NOT DEFINED CMAKE_CROSSCOMPILING)
set(CMAKE_CROSSCOMPILING "FALSE")
endif()
# Set default install directory permissions.
if(NOT DEFINED CMAKE_OBJDUMP)
set(CMAKE_OBJDUMP "/usr/bin/objdump")
endif()
if(CMAKE_INSTALL_COMPONENT)
set(CMAKE_INSTALL_MANIFEST "install_manifest_${CMAKE_INSTALL_COMPONENT}.txt")
else()
set(CMAKE_INSTALL_MANIFEST "install_manifest.txt")
endif()
string(REPLACE ";" "\n" CMAKE_INSTALL_MANIFEST_CONTENT
"${CMAKE_INSTALL_MANIFEST_FILES}")
file(WRITE "/home/tomer/Github/Public-PF/cmake-build-debug/${CMAKE_INSTALL_MANIFEST}"
"${CMAKE_INSTALL_MANIFEST_CONTENT}")

View File

@ -0,0 +1,95 @@
---
Language: Cpp
# BasedOnStyle: Google
AccessModifierOffset: -1
AlignAfterOpenBracket: Align
AlignConsecutiveAssignments: false
AlignConsecutiveDeclarations: false
AlignEscapedNewlinesLeft: true
AlignOperands: true
AlignTrailingComments: true
AllowAllParametersOfDeclarationOnNextLine: true
AllowShortBlocksOnASingleLine: false
AllowShortCaseLabelsOnASingleLine: false
AllowShortFunctionsOnASingleLine: All
AllowShortIfStatementsOnASingleLine: true
AllowShortLoopsOnASingleLine: true
AlwaysBreakAfterDefinitionReturnType: None
AlwaysBreakAfterReturnType: None
AlwaysBreakBeforeMultilineStrings: true
AlwaysBreakTemplateDeclarations: true
BinPackArguments: true
BinPackParameters: true
BraceWrapping:
AfterClass: false
AfterControlStatement: false
AfterEnum: false
AfterFunction: false
AfterNamespace: false
AfterObjCDeclaration: false
AfterStruct: false
AfterUnion: false
BeforeCatch: false
BeforeElse: false
IndentBraces: false
BreakBeforeBinaryOperators: None
BreakBeforeBraces: Attach
BreakBeforeTernaryOperators: true
BreakConstructorInitializersBeforeComma: false
BreakAfterJavaFieldAnnotations: false
BreakStringLiterals: true
ColumnLimit: 80
CommentPragmas: '^ IWYU pragma:'
ConstructorInitializerAllOnOneLineOrOnePerLine: true
ConstructorInitializerIndentWidth: 4
ContinuationIndentWidth: 4
Cpp11BracedListStyle: true
DerivePointerAlignment: false
DisableFormat: false
ExperimentalAutoDetectBinPacking: false
ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH ]
IncludeCategories:
- Regex: '^<.*\.h>'
Priority: 1
- Regex: '^<.*'
Priority: 2
- Regex: '.*'
Priority: 3
IncludeIsMainRegex: '([-_](test|unittest))?$'
IndentCaseLabels: true
IndentWidth: 2
IndentWrappedFunctionNames: false
JavaScriptQuotes: Leave
JavaScriptWrapImports: true
KeepEmptyLinesAtTheStartOfBlocks: false
MacroBlockBegin: ''
MacroBlockEnd: ''
MaxEmptyLinesToKeep: 1
NamespaceIndentation: None
ObjCBlockIndentWidth: 2
ObjCSpaceAfterProperty: false
ObjCSpaceBeforeProtocolList: false
PenaltyBreakBeforeFirstCallParameter: 1
PenaltyBreakComment: 300
PenaltyBreakFirstLessLess: 120
PenaltyBreakString: 1000
PenaltyExcessCharacter: 1000000
PenaltyReturnTypeOnItsOwnLine: 200
PointerAlignment: Right
ReflowComments: true
SortIncludes: true
SpaceAfterCStyleCast: false
SpaceBeforeAssignmentOperators: true
SpaceBeforeParens: ControlStatements
SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 2
SpacesInAngles: false
SpacesInContainerLiterals: true
SpacesInCStyleCastParentheses: false
SpacesInParentheses: false
SpacesInSquareBrackets: false
Standard: Auto
TabWidth: 8
UseTab: Never
...

11
cuckoofilter/.gitignore vendored Normal file
View File

@ -0,0 +1,11 @@
#*
#*#
*#
*.*#
*.class
*.dSYM
*.la
*.lo
*.o
*.so
test

13
cuckoofilter/LICENSE Normal file
View File

@ -0,0 +1,13 @@
Copyright (C) 2013, Carnegie Mellon University and Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

43
cuckoofilter/Makefile Normal file
View File

@ -0,0 +1,43 @@
CC = g++
AR = ar
PREFIX=/usr/local
# Uncomment one of the following to switch between debug and opt mode
#OPT = -O3 -DNDEBUG
OPT = -g -ggdb
CFLAGS += --std=c++11 -fno-strict-aliasing -Wall -c -I. -I./include -I/usr/include/ -I./src/ $(OPT)
LDFLAGS+= -Wall -lpthread -lssl -lcrypto
LIBOBJECTS = \
./src/hashutil.o \
HEADERS = $(wildcard src/*.h)
ALIB = libcuckoofilter.a
TEST = test
all: $(TEST)
clean:
rm -f $(TEST) */*.o
test: example/test.o $(LIBOBJECTS)
$(CC) example/test.o $(LIBOBJECTS) $(LDFLAGS) -o $@
%.o: %.cc ${HEADERS} Makefile
$(CC) $(CFLAGS) $< -o $@
$(ALIB): $(LIBOBJECTS)
$(AR) rcs $@ $(LIBOBJECTS)
.PHONY: install
install: $(ALIB)
install -D -m 0755 $(HEADERS) -t $(DESTDIR)$(PREFIX)/include/cuckoofilter
install -D -m 0755 $< -t $(DESTDIR)$(PREFIX)/lib
.PHONY: uninstall
uninstall:
rm -f $(DESTDIR)$(PREFIX)/lib/$(ALIB)
rm -rf $(DESTDIR)$(PREFIX)/include/cuckoofilter

93
cuckoofilter/README.md Normal file
View File

@ -0,0 +1,93 @@
Cuckoo Filter
============
Overview
--------
Cuckoo filter is a Bloom filter replacement for approximated set-membership queries. While Bloom filters are well-known space-efficient data structures to serve queries like "if item x is in a set?", they do not support deletion. Their variances to enable deletion (like counting Bloom filters) usually require much more space.
Cuckoo filters provide the flexibility to add and remove items dynamically. A cuckoo filter is based on cuckoo hashing (and therefore named as cuckoo filter). It is essentially a cuckoo hash table storing each key's fingerprint. Cuckoo hash tables can be highly compact, thus a cuckoo filter could use less space than conventional Bloom filters, for applications that require low false positive rates (< 3%).
For details about the algorithm and citations please use:
["Cuckoo Filter: Practically Better Than Bloom"](http://www.cs.cmu.edu/~binfan/papers/conext14_cuckoofilter.pdf) in proceedings of ACM CoNEXT 2014 by Bin Fan, Dave Andersen and Michael Kaminsky
API
--------
A cuckoo filter supports following operations:
* `Add(item)`: insert an item to the filter
* `Contain(item)`: return if item is already in the filter. Note that this method may return false positive results like Bloom filters
* `Delete(item)`: delete the given item from the filter. Note that to use this method, it must be ensured that this item is in the filter (e.g., based on records on external storage); otherwise, a false item may be deleted.
* `Size()`: return the total number of items currently in the filter
* `SizeInBytes()`: return the filter size in bytes
Here is a simple example in C++ for the basic usage of cuckoo filter.
More examples can be found in `example/` directory.
```cpp
// Create a cuckoo filter where each item is of type size_t and
// use 12 bits for each item, with capacity of total_items
CuckooFilter<size_t, 12> filter(total_items);
// Insert item 12 to this cuckoo filter
filter.Add(12);
// Check if previously inserted items are in the filter
assert(filter.Contain(12) == cuckoofilter::Ok);
```
Repository structure
--------------------
* `src/`: the C++ header and implementation of cuckoo filter
* `example/test.cc`: an example of using cuckoo filter
* `benchmarks/`: Some benchmarks of speed, space used, and false positive rate
Build
-------
This libray depends on openssl library. Note that on MacOS 10.12, the header
files of openssl are not available by default. It may require to install openssl
and pass the path to `lib` and `include` directories to gcc, for example:
```bash
$ brew install openssl
# Replace 1.0.2j with the actual version of the openssl installed
$ export LDFLAGS="-L/usr/local/Cellar/openssl/1.0.2j/lib"
$ export CFLAGS="-I/usr/local/Cellar/openssl/1.0.2j/include"
```
To build the example (`example/test.cc`):
```bash
$ make test
```
To build the benchmarks:
```bash
$ cd benchmarks
$ make
```
Install
-------
To install the cuckoofilter library:
```bash
$ make install
```
By default, the header files will be placed in `/usr/local/include/cuckoofilter`
and the static library at `/usr/local/lib/cuckoofilter.a`.
Contributing
------------
Contributions via GitHub pull requests are welcome. Please keep the code style guided by
[Google C++ style](https://google.github.io/styleguide/cppguide.html). One can use
[clang-format](http://clang.llvm.org/docs/ClangFormat.html) with our provided
[`.clang-format`](https://github.com/efficient/cuckoofilter/blob/master/.clang-format)
in this repository to enforce the style.
Authors
-------
- Bin Fan <binfan@cs.cmu.edu>
- David G. Andersen <dga@cs.cmu.edu>
- Michael Kaminsky <michael.e.kaminsky@intel.com>

View File

@ -0,0 +1,23 @@
# Uncomment one of the following to switch between debug and opt mode
OPT = -O3 -DNDEBUG
#OPT = -g -ggdb
CXXFLAGS += -fno-strict-aliasing -Wall -std=c++11 -I. -I../src/ $(OPT) -march=core-avx2
LDFLAGS+= -Wall -lpthread -lssl -lcrypto
HEADERS = $(wildcard ../src/*.h) *.h
SRC = ../src/hashutil.cc
.PHONY: all
BINS = conext-table3.exe conext-figure5.exe bulk-insert-and-query.exe
all: $(BINS)
clean:
/bin/rm -f $(BINS)
%.exe: %.cc ${HEADERS} ${SRC} Makefile
$(CXX) $(CXXFLAGS) $< -o $@ $(SRC) $(LDFLAGS)

View File

@ -0,0 +1,255 @@
// This benchmark reports on the bulk insert and bulk query rates. It is invoked as:
//
// ./bulk-insert-and-query.exe 158000
//
// That invocation will test each probabilistic membership container type with 158000
// randomly generated items. It tests bulk Add() from empty to full and Contain() on
// filters with varying rates of expected success. For instance, at 75%, three out of
// every four values passed to Contain() were earlier Add()ed.
//
// Example output:
//
// $ for num in 55 75 85; do echo $num:; /usr/bin/time -f 'time: %e seconds' ./bulk-insert-and-query.exe ${num}00000; echo; done
// 55:
// Million Find Find Find Find Find optimal wasted
// adds/sec 0% 25% 50% 75% 100% ε bits/item bits/item space
// Cuckoo12 23.78 37.24 35.04 37.17 37.35 36.35 0.131% 18.30 9.58 91.1%
// SemiSort13 11.63 17.55 17.08 17.14 17.54 22.32 0.064% 18.30 10.62 72.4%
// Cuckoo8 35.31 49.32 50.24 49.98 48.32 50.49 2.044% 12.20 5.61 117.4%
// SemiSort9 13.99 22.23 22.78 22.13 23.16 24.06 1.207% 12.20 6.37 91.5%
// Cuckoo16 27.06 36.94 37.12 35.31 36.81 35.10 0.009% 24.40 13.46 81.4%
// SemiSort17 10.37 15.70 15.84 15.78 15.55 15.93 0.004% 24.40 14.72 65.8%
// SimdBlock8 74.22 72.34 74.23 74.34 74.69 74.32 0.508% 12.20 7.62 60.1%
// time: 14.34 seconds
//
// 75:
// Million Find Find Find Find Find optimal wasted
// adds/sec 0% 25% 50% 75% 100% ε bits/item bits/item space
// Cuckoo12 15.61 37.24 37.23 37.34 37.15 37.36 0.173% 13.42 9.18 46.2%
// SemiSort13 8.77 17.11 15.70 17.34 17.73 18.86 0.087% 13.42 10.17 31.9%
// Cuckoo8 23.46 48.81 48.14 39.48 49.28 49.65 2.806% 8.95 5.16 73.6%
// SemiSort9 11.14 23.98 20.80 23.37 24.35 21.41 1.428% 8.95 6.13 46.0%
// Cuckoo16 15.08 36.64 36.75 36.83 36.59 36.74 0.011% 17.90 13.11 36.5%
// SemiSort17 8.02 15.63 15.66 15.87 15.67 15.88 0.006% 17.90 14.02 27.6%
// SimdBlock8 73.26 74.41 74.28 70.86 72.02 70.69 2.071% 8.95 5.59 60.0%
// time: 18.06 seconds
//
// 85:
// Million Find Find Find Find Find optimal wasted
// adds/sec 0% 25% 50% 75% 100% ε bits/item bits/item space
// Cuckoo12 22.74 32.49 32.69 32.58 32.85 32.71 0.102% 23.69 9.94 138.3%
// SemiSort13 9.97 13.16 13.15 13.54 16.01 19.58 0.056% 23.69 10.80 119.4%
// Cuckoo8 30.67 36.86 36.79 37.09 36.97 36.87 1.581% 15.79 5.98 163.9%
// SemiSort9 10.96 15.49 15.37 15.40 15.18 15.63 1.047% 15.79 6.58 140.1%
// Cuckoo16 27.84 33.74 33.72 33.69 33.75 33.62 0.007% 31.58 13.80 128.8%
// SemiSort17 9.51 12.83 12.80 12.64 12.86 12.50 0.004% 31.58 14.65 115.6%
// SimdBlock8 54.84 58.37 59.73 59.13 60.11 60.12 0.144% 15.79 9.44 67.3%
// time: 19.43 seconds
//
#include <climits>
#include <iomanip>
#include <map>
#include <stdexcept>
#include <vector>
#include "cuckoofilter.h"
#include "random.h"
#include "simd-block.h"
#include "timing.h"
using namespace std;
using namespace cuckoofilter;
// The number of items sampled when determining the lookup performance
const size_t SAMPLE_SIZE = 1000 * 1000;
// The statistics gathered for each table type:
struct Statistics {
double adds_per_nano;
map<int, double> finds_per_nano; // The key is the percent of queries that were expected
// to be positive
double false_positive_probabilty;
double bits_per_item;
};
// Output for the first row of the table of results. type_width is the maximum number of
// characters of the description of any table type, and find_percent_count is the number
// of different lookup statistics gathered for each table. This function assumes the
// lookup expected positive probabiilties are evenly distributed, with the first being 0%
// and the last 100%.
string StatisticsTableHeader(int type_width, int find_percent_count) {
ostringstream os;
os << string(type_width, ' ');
os << setw(12) << right << "Million";
for (int i = 0; i < find_percent_count; ++i) {
os << setw(8) << "Find";
}
os << setw(8) << "" << setw(11) << "" << setw(11)
<< "optimal" << setw(8) << "wasted" << endl;
os << string(type_width, ' ');
os << setw(12) << right << "adds/sec";
for (int i = 0; i < find_percent_count; ++i) {
os << setw(7)
<< static_cast<int>(100 * i / static_cast<double>(find_percent_count - 1)) << '%';
}
os << setw(9) << "ε" << setw(11) << "bits/item" << setw(11)
<< "bits/item" << setw(8) << "space";
return os.str();
}
// Overloading the usual operator<< as used in "std::cout << foo", but for Statistics
template <class CharT, class Traits>
basic_ostream<CharT, Traits>& operator<<(
basic_ostream<CharT, Traits>& os, const Statistics& stats) {
constexpr double NANOS_PER_MILLION = 1000;
os << fixed << setprecision(2) << setw(12) << right
<< stats.adds_per_nano * NANOS_PER_MILLION;
for (const auto& fps : stats.finds_per_nano) {
os << setw(8) << fps.second * NANOS_PER_MILLION;
}
const auto minbits = log2(1 / stats.false_positive_probabilty);
os << setw(7) << setprecision(3) << stats.false_positive_probabilty * 100 << '%'
<< setw(11) << setprecision(2) << stats.bits_per_item << setw(11) << minbits
<< setw(7) << setprecision(1) << 100 * (stats.bits_per_item / minbits - 1) << '%';
return os;
}
template<typename Table>
struct FilterAPI {};
template <typename ItemType, size_t bits_per_item, template <size_t> class TableType>
struct FilterAPI<CuckooFilter<ItemType, bits_per_item, TableType>> {
using Table = CuckooFilter<ItemType, bits_per_item, TableType>;
static Table ConstructFromAddCount(size_t add_count) { return Table(add_count); }
static void Add(uint64_t key, Table * table) {
if (0 != table->Add(key)) {
throw logic_error("The filter is too small to hold all of the elements");
}
}
static bool Contain(uint64_t key, const Table * table) {
return (0 == table->Contain(key));
}
};
template <>
struct FilterAPI<SimdBlockFilter<>> {
using Table = SimdBlockFilter<>;
static Table ConstructFromAddCount(size_t add_count) {
Table ans(ceil(log2(add_count * 8.0 / CHAR_BIT)));
return ans;
}
static void Add(uint64_t key, Table* table) {
table->Add(key);
}
static bool Contain(uint64_t key, const Table * table) {
return table->Find(key);
}
};
template <typename Table>
Statistics FilterBenchmark(
size_t add_count, const vector<uint64_t>& to_add, const vector<uint64_t>& to_lookup) {
if (add_count > to_add.size()) {
throw out_of_range("to_add must contain at least add_count values");
}
if (SAMPLE_SIZE > to_lookup.size()) {
throw out_of_range("to_lookup must contain at least SAMPLE_SIZE values");
}
Table filter = FilterAPI<Table>::ConstructFromAddCount(add_count);
Statistics result;
// Add values until failure or until we run out of values to add:
auto start_time = NowNanos();
for (size_t added = 0; added < add_count; ++added) {
FilterAPI<Table>::Add(to_add[added], &filter);
}
result.adds_per_nano = add_count / static_cast<double>(NowNanos() - start_time);
result.bits_per_item = static_cast<double>(CHAR_BIT * filter.SizeInBytes()) / add_count;
size_t found_count = 0;
for (const double found_probability : {0.0, 0.25, 0.50, 0.75, 1.00}) {
const auto to_lookup_mixed = MixIn(&to_lookup[0], &to_lookup[SAMPLE_SIZE], &to_add[0],
&to_add[add_count], found_probability);
const auto start_time = NowNanos();
for (const auto v : to_lookup_mixed) {
found_count += FilterAPI<Table>::Contain(v, &filter);
}
const auto lookup_time = NowNanos() - start_time;
result.finds_per_nano[100 * found_probability] =
SAMPLE_SIZE / static_cast<double>(lookup_time);
if (0.0 == found_probability) {
result.false_positive_probabilty =
found_count / static_cast<double>(to_lookup_mixed.size());
}
}
return result;
}
int main(int argc, char * argv[]) {
if (argc != 2) {
cerr << "Usage: " << argv[0] << " $NUMBER" << endl;
return 1;
}
stringstream input_string(argv[1]);
size_t add_count;
input_string >> add_count;
if (input_string.fail()) {
cerr << "Invalid number: " << argv[1];
return 2;
}
const vector<uint64_t> to_add = GenerateRandom64(add_count);
const vector<uint64_t> to_lookup = GenerateRandom64(SAMPLE_SIZE);
constexpr int NAME_WIDTH = 13;
cout << StatisticsTableHeader(NAME_WIDTH, 5) << endl;
auto cf = FilterBenchmark<
CuckooFilter<uint64_t, 12 /* bits per item */, SingleTable /* not semi-sorted*/>>(
add_count, to_add, to_lookup);
cout << setw(NAME_WIDTH) << "Cuckoo12" << cf << endl;
cf = FilterBenchmark<
CuckooFilter<uint64_t, 13 /* bits per item */, PackedTable /* semi-sorted*/>>(
add_count, to_add, to_lookup);
cout << setw(NAME_WIDTH) << "SemiSort13" << cf << endl;
cf = FilterBenchmark<
CuckooFilter<uint64_t, 8 /* bits per item */, SingleTable /* not semi-sorted*/>>(
add_count, to_add, to_lookup);
cout << setw(NAME_WIDTH) << "Cuckoo8" << cf << endl;
cf = FilterBenchmark<
CuckooFilter<uint64_t, 9 /* bits per item */, PackedTable /* semi-sorted*/>>(
add_count, to_add, to_lookup);
cout << setw(NAME_WIDTH) << "SemiSort9" << cf << endl;
cf = FilterBenchmark<
CuckooFilter<uint64_t, 16 /* bits per item */, SingleTable /* not semi-sorted*/>>(
add_count, to_add, to_lookup);
cout << setw(NAME_WIDTH) << "Cuckoo16" << cf << endl;
cf = FilterBenchmark<
CuckooFilter<uint64_t, 17 /* bits per item */, PackedTable /* semi-sorted*/>>(
add_count, to_add, to_lookup);
cout << setw(NAME_WIDTH) << "SemiSort17" << cf << endl;
cf = FilterBenchmark<SimdBlockFilter<>>(add_count, to_add, to_lookup);
cout << setw(NAME_WIDTH) << "SimdBlock8" << cf << endl;
}

View File

@ -0,0 +1,84 @@
// This benchmark reproduces the CoNEXT 2014 results found in "Figure 5: Lookup
// performance when a filter achieves its capacity." It takes about two minutes to run on
// an Intel(R) Core(TM) i7-4790 CPU @ 3.60GHz.
//
// Results:
// fraction of queries on existing items/lookup throughput (million OPS)
// CF ss-CF
// 0.00% 24.79 9.37
// 25.00% 24.65 9.57
// 50.00% 24.84 9.57
// 75.00% 24.86 9.62
// 100.00% 24.89 9.96
#include <climits>
#include <iomanip>
#include <vector>
#include "cuckoofilter.h"
#include "random.h"
#include "timing.h"
using namespace std;
using namespace cuckoofilter;
// The number of items sampled when determining the lookup performance
const size_t SAMPLE_SIZE = 1000 * 1000;
// The time (in seconds) to lookup SAMPLE_SIZE keys in which 0%, 25%, 50%, 75%, and 100%
// of the keys looked up are found.
template <typename Table>
array<double, 5> CuckooBenchmark(
size_t add_count, const vector<uint64_t>& to_add, const vector<uint64_t>& to_lookup) {
Table cuckoo(add_count);
array<double, 5> result;
// Add values until failure or until we run out of values to add:
size_t added = 0;
while (added < to_add.size() && 0 == cuckoo.Add(to_add[added])) ++added;
// A value to track to prevent the compiler from optimizing out all lookups:
size_t found_count = 0;
for (const double found_percent : {0.0, 0.25, 0.50, 0.75, 1.00}) {
const auto to_lookup_mixed = MixIn(&to_lookup[0], &to_lookup[SAMPLE_SIZE], &to_add[0],
&to_add[added], found_percent);
auto start_time = NowNanos();
for (const auto v : to_lookup_mixed) found_count += (0 == cuckoo.Contain(v));
auto lookup_time = NowNanos() - start_time;
result[found_percent * 4] = lookup_time / (1000.0 * 1000.0 * 1000.0);
}
if (6 * SAMPLE_SIZE == found_count) exit(1);
return result;
}
int main() {
// Number of distinct values, used only for the constructor of CuckooFilter, which does
// not allow the caller to specify the space usage directly. The actual number of
// distinct items inserted depends on how many fit until an insert failure occurs.
size_t add_count = 127.78 * 1000 * 1000;
// Overestimate add_count so we don't run out of random data:
const size_t max_add_count = 2 * add_count;
const vector<uint64_t> to_add = GenerateRandom64(max_add_count);
const vector<uint64_t> to_lookup = GenerateRandom64(SAMPLE_SIZE);
// Calculate metrics:
const auto cf = CuckooBenchmark<
CuckooFilter<uint64_t, 12 /* bits per item */, SingleTable /* not semi-sorted*/>>(
add_count, to_add, to_lookup);
const auto sscf = CuckooBenchmark<
CuckooFilter<uint64_t, 13 /* bits per item */, PackedTable /* semi-sorted*/>>(
add_count, to_add, to_lookup);
cout << "fraction of queries on existing items/lookup throughput (million OPS) "
<< endl;
cout << setw(10) << ""
<< " " << setw(10) << right << "CF" << setw(10) << right << "ss-CF" << endl;
for (const double found_percent : {0.0, 0.25, 0.50, 0.75, 1.00}) {
cout << fixed << setprecision(2) << setw(10) << right << 100 * found_percent << "%";
cout << setw(10) << right << (SAMPLE_SIZE / cf[found_percent * 4]) / (1000 * 1000);
cout << setw(10) << right << (SAMPLE_SIZE / sscf[found_percent * 4]) / (1000 * 1000);
cout << endl;
}
}

View File

@ -0,0 +1,91 @@
// This benchmark reproduces the CoNEXT 2014 results found in "Table 3: Space efficiency
// and construction speed." It takes about two minutes to run on an Intel(R) Core(TM)
// i7-4790 CPU @ 3.60GHz.
//
// Results:
//
// metrics CF ss-CF
// # of items (million) 127.82 127.90
// bits per item 12.60 12.59
// false positive rate 0.18% 0.09%
// constr. speed (million keys/sec) 5.86 4.10
#include <climits>
#include <iomanip>
#include <vector>
#include "cuckoofilter.h"
#include "random.h"
#include "timing.h"
using namespace std;
using namespace cuckoofilter;
// The number of items sampled when determining the false positive rate
const size_t FPR_SAMPLE_SIZE = 1000 * 1000;
struct Metrics {
double add_count; // # of items (million)
double space; // bits per item
double fpr; // false positive rate (%)
double speed; // const. speed (million keys/sec)
};
template<typename Table>
Metrics CuckooBenchmark(size_t add_count, const vector<uint64_t>& input) {
Table cuckoo(add_count);
auto start_time = NowNanos();
// Insert until failure:
size_t inserted = 0;
while (inserted < input.size() && 0 == cuckoo.Add(input[inserted])) ++inserted;
auto constr_time = NowNanos() - start_time;
// Count false positives:
size_t false_positive_count = 0;
size_t absent = 0;
for (; inserted + absent < input.size() && absent < FPR_SAMPLE_SIZE; ++absent) {
false_positive_count += (0 == cuckoo.Contain(input[inserted + absent]));
}
// Calculate metrics:
const auto time = constr_time / static_cast<double>(1000 * 1000 * 1000);
Metrics result;
result.add_count = static_cast<double>(inserted) / (1000 * 1000);
result.space = static_cast<double>(CHAR_BIT * cuckoo.SizeInBytes()) / inserted;
result.fpr = (100.0 * false_positive_count) / absent;
result.speed = (inserted / time) / (1000 * 1000);
return result;
}
int main() {
// Number of distinct values, used only for the constructor of CuckooFilter, which does
// not allow the caller to specify the space usage directly. The actual number of
// distinct items inserted depends on how many fit until an insert failure occurs.
const size_t add_count = 127.78 * 1000 * 1000;
// Overestimate add_count so we don't run out of random data:
const size_t max_add_count = 2 * add_count;
const vector<uint64_t> input = GenerateRandom64(max_add_count + FPR_SAMPLE_SIZE);
// Calculate metrics:
const auto cf = CuckooBenchmark<
CuckooFilter<uint64_t, 12 /* bits per item */, SingleTable /* not semi-sorted*/>>(
add_count, input);
const auto sscf = CuckooBenchmark<
CuckooFilter<uint64_t, 13 /* bits per item */, PackedTable /* semi-sorted*/>>(
add_count, input);
cout << setw(35) << left << "metrics " << setw(10) << right << "CF" << setw(10)
<< "ss-CF" << endl
<< fixed << setprecision(2) << setw(35) << left << "# of items (million) "
<< setw(10) << right << cf.add_count << setw(10) << sscf.add_count << endl
<< setw(35) << left << "bits per item " << setw(10) << right << cf.space
<< setw(10) << sscf.space << endl
<< setw(35) << left << "false positive rate " << setw(9) << right << cf.fpr << "%"
<< setw(9) << sscf.fpr << "%" << endl
<< setw(35) << left << "constr. speed (million keys/sec) " << setw(10) << right
<< cf.speed << setw(10) << sscf.speed << endl;
}

View File

@ -0,0 +1,45 @@
// Generating random data
#pragma once
#include <algorithm>
#include <cstdint>
#include <functional>
#include <random>
#include <stdexcept>
#include <vector>
::std::vector<::std::uint64_t> GenerateRandom64(::std::size_t count) {
::std::vector<::std::uint64_t> result(count);
::std::random_device random;
// To generate random keys to lookup, this uses ::std::random_device which is slower but
// stronger than some other pseudo-random alternatives. The reason is that some of these
// alternatives (like libstdc++'s ::std::default_random, which is a linear congruential
// generator) behave non-randomly under some hash families like Dietzfelbinger's
// multiply-shift.
auto genrand = [&random]() {
return random() + (static_cast<::std::uint64_t>(random()) << 32);
};
::std::generate(result.begin(), result.end(), ::std::ref(genrand));
return result;
}
// Using two pointer ranges for sequences x and y, create a vector clone of x but for
// y_probability y's mixed in.
template <typename T>
::std::vector<T> MixIn(const T* x_begin, const T* x_end, const T* y_begin, const T* y_end,
double y_probability) {
const size_t x_size = x_end - x_begin, y_size = y_end - y_begin;
if (y_size > (1ull << 32)) throw ::std::length_error("y is too long");
::std::vector<T> result(x_begin, x_end);
::std::random_device random;
auto genrand = [&random, y_size]() {
return (static_cast<size_t>(random()) * y_size) >> 32;
};
for (size_t i = 0; i < y_probability * x_size; ++i) {
result[i] = *(y_begin + genrand());
}
::std::shuffle(result.begin(), result.end(), random);
return result;
}

View File

@ -0,0 +1,12 @@
// Timers for use in benchmarking.
#pragma once
#include <cstdint>
#include <chrono>
::std::uint64_t NowNanos() {
return ::std::chrono::duration_cast<::std::chrono::nanoseconds>(
::std::chrono::steady_clock::now().time_since_epoch())
.count();
}

View File

@ -0,0 +1,52 @@
#include "cuckoofilter.h"
#include <assert.h>
#include <math.h>
#include <iostream>
#include <vector>
using cuckoofilter::CuckooFilter;
int main(int argc, char **argv) {
size_t total_items = 1000000;
// Create a cuckoo filter where each item is of type size_t and
// use 12 bits for each item:
// CuckooFilter<size_t, 12> filter(total_items);
// To enable semi-sorting, define the storage of cuckoo filter to be
// PackedTable, accepting keys of size_t type and making 13 bits
// for each key:
// CuckooFilter<size_t, 13, cuckoofilter::PackedTable> filter(total_items);
CuckooFilter<size_t, 12> filter(total_items);
// Insert items to this cuckoo filter
size_t num_inserted = 0;
for (size_t i = 0; i < total_items; i++, num_inserted++) {
if (filter.Add(i) != cuckoofilter::Ok) {
break;
}
}
// Check if previously inserted items are in the filter, expected
// true for all items
for (size_t i = 0; i < num_inserted; i++) {
assert(filter.Contain(i) == cuckoofilter::Ok);
}
// Check non-existing items, a few false positives expected
size_t total_queries = 0;
size_t false_queries = 0;
for (size_t i = total_items; i < 2 * total_items; i++) {
if (filter.Contain(i) == cuckoofilter::Ok) {
false_queries++;
}
total_queries++;
}
// Output the measured false positive rate
std::cout << "false positive rate is "
<< 100.0 * false_queries / total_queries << "%\n";
return 0;
}

View File

@ -0,0 +1,35 @@
#ifndef CUCKOO_FILTER_BITS_H_
#define CUCKOO_FILTER_BITS_H_
namespace cuckoofilter {
// inspired from
// http://www-graphics.stanford.edu/~seander/bithacks.html#ZeroInWord
#define haszero4(x) (((x)-0x1111ULL) & (~(x)) & 0x8888ULL)
#define hasvalue4(x, n) (haszero4((x) ^ (0x1111ULL * (n))))
#define haszero8(x) (((x)-0x01010101ULL) & (~(x)) & 0x80808080ULL)
#define hasvalue8(x, n) (haszero8((x) ^ (0x01010101ULL * (n))))
#define haszero12(x) (((x)-0x001001001001ULL) & (~(x)) & 0x800800800800ULL)
#define hasvalue12(x, n) (haszero12((x) ^ (0x001001001001ULL * (n))))
#define haszero16(x) \
(((x)-0x0001000100010001ULL) & (~(x)) & 0x8000800080008000ULL)
#define hasvalue16(x, n) (haszero16((x) ^ (0x0001000100010001ULL * (n))))
inline uint64_t upperpower2(uint64_t x) {
x--;
x |= x >> 1;
x |= x >> 2;
x |= x >> 4;
x |= x >> 8;
x |= x >> 16;
x |= x >> 32;
x++;
return x;
}
} // namespace cuckoofilter
#endif // CUCKOO_FILTER_BITS_H

View File

@ -0,0 +1,267 @@
#ifndef CUCKOO_FILTER_CUCKOO_FILTER_H_
#define CUCKOO_FILTER_CUCKOO_FILTER_H_
#include <assert.h>
#include <algorithm>
#include "debug.h"
#include "hashutil.h"
#include "packedtable.h"
#include "printutil.h"
#include "singletable.h"
namespace cuckoofilter {
// status returned by a cuckoo filter operation
enum Status {
Ok = 0,
NotFound = 1,
NotEnoughSpace = 2,
NotSupported = 3,
};
// maximum number of cuckoo kicks before claiming failure
const size_t kMaxCuckooCount = 500;
// A cuckoo filter class exposes a Bloomier filter interface,
// providing methods of Add, Delete, Contain. It takes three
// template parameters:
// ItemType: the type of item you want to insert
// bits_per_item: how many bits each item is hashed into
// TableType: the storage of table, SingleTable by default, and
// PackedTable to enable semi-sorting
template <typename ItemType, size_t bits_per_item,
template <size_t> class TableType = SingleTable,
typename HashFamily = TwoIndependentMultiplyShift>
class CuckooFilter {
// Storage of items
TableType<bits_per_item> *table_;
// Number of items stored
size_t num_items_;
typedef struct {
size_t index;
uint32_t tag;
bool used;
} VictimCache;
VictimCache victim_;
HashFamily hasher_;
inline size_t IndexHash(uint32_t hv) const {
// table_->num_buckets is always a power of two, so modulo can be replaced
// with
// bitwise-and:
return hv & (table_->NumBuckets() - 1);
}
inline uint32_t TagHash(uint32_t hv) const {
uint32_t tag;
tag = hv & ((1ULL << bits_per_item) - 1);
tag += (tag == 0);
return tag;
}
inline void GenerateIndexTagHash(const ItemType &item, size_t *index,
uint32_t *tag) const {
const uint64_t hash = hasher_(item);
// const uint64_t hash = item;
*index = IndexHash(hash >> 32);
*tag = TagHash(hash);
}
inline size_t AltIndex(const size_t index, const uint32_t tag) const {
// NOTE(binfan): originally we use:
// index ^ HashUtil::BobHash((const void*) (&tag), 4)) & table_->INDEXMASK;
// now doing a quick-n-dirty way:
// 0x5bd1e995 is the hash constant from MurmurHash2
return IndexHash((uint32_t)(index ^ (tag * 0x5bd1e995)));
// uint64_t temp_index = (index ^ (tag * 0xc4ceb9fe1a85ec53L));
// return IndexHash(temp_index);
}
Status AddImpl(const size_t i, const uint32_t tag);
// load factor is the fraction of occupancy
double LoadFactor() const { return 1.0 * Size() / table_->SizeInTags(); }
double BitsPerItem() const { return 8.0 * table_->SizeInBytes() / Size(); }
public:
explicit CuckooFilter(const size_t max_num_keys)
: num_items_(0), victim_(), hasher_() {
size_t assoc = 4;
size_t num_buckets =
upperpower2(std::max<uint64_t>(1, max_num_keys / assoc));
double frac = (double)max_num_keys / num_buckets / assoc;
if (frac > 0.96) {
std::cout << "CF might fail." << std::endl;
// num_buckets <<= 1;
}
victim_.used = false;
table_ = new TableType<bits_per_item>(num_buckets);
// std::cout << "load is: " << frac << std::endl;
// std::cout << "Here!" << std::endl;
// std::cout << __LINE__ << std::endl;
}
~CuckooFilter() {
// std::cout << "CF-??? " << "Byte size is: \t" << SizeInBytes() <<
// std::endl;
delete table_;
}
// Add an item to the filter.
Status Add(const ItemType &item);
// Report if the item is inserted, with false positive rate.
Status Contain(const ItemType &item) const;
// Delete an key from the filter
Status Delete(const ItemType &item);
/* methods for providing stats */
// summary infomation
std::string Info() const;
// number of current inserted items;
size_t Size() const { return num_items_; }
// size of the filter in bytes.
size_t SizeInBytes() const { return table_->SizeInBytes(); }
size_t get_cap() const { return num_items_; }
};
template <typename ItemType, size_t bits_per_item,
template <size_t> class TableType, typename HashFamily>
Status CuckooFilter<ItemType, bits_per_item, TableType, HashFamily>::Add(
const ItemType &item) {
size_t i;
uint32_t tag;
if (victim_.used) {
#ifndef NDEBUG
std::cout << std::string(80, '=') << std::endl;
if (Contain(item) == Ok) {
std::cout << "Item was already in the set." << std::endl;
} else {
std::cout << "Item was not already in the set." << std::endl;
}
std::cout << "Info: ";
std::cout << std::string(80, '=') << std::endl;
#endif //! NDEBUG
std::cout << Info();
return NotEnoughSpace;
}
GenerateIndexTagHash(item, &i, &tag);
return AddImpl(i, tag);
}
template <typename ItemType, size_t bits_per_item,
template <size_t> class TableType, typename HashFamily>
Status CuckooFilter<ItemType, bits_per_item, TableType, HashFamily>::AddImpl(
const size_t i, const uint32_t tag) {
size_t curindex = i;
uint32_t curtag = tag;
uint32_t oldtag;
for (uint32_t count = 0; count < kMaxCuckooCount; count++) {
bool kickout = count > 0;
oldtag = 0;
if (table_->InsertTagToBucket(curindex, curtag, kickout, oldtag)) {
num_items_++;
return Ok;
}
if (kickout) {
curtag = oldtag;
}
curindex = AltIndex(curindex, curtag);
}
victim_.index = curindex;
victim_.tag = curtag;
victim_.used = true;
return Ok;
}
template <typename ItemType, size_t bits_per_item,
template <size_t> class TableType, typename HashFamily>
Status CuckooFilter<ItemType, bits_per_item, TableType, HashFamily>::Contain(
const ItemType &key) const {
bool found = false;
size_t i1, i2;
uint32_t tag;
GenerateIndexTagHash(key, &i1, &tag);
i2 = AltIndex(i1, tag);
assert(i1 == AltIndex(i2, tag));
found = victim_.used && (tag == victim_.tag) &&
(i1 == victim_.index || i2 == victim_.index);
if (found || table_->FindTagInBuckets(i1, i2, tag)) {
return Ok;
} else {
return NotFound;
}
}
template <typename ItemType, size_t bits_per_item,
template <size_t> class TableType, typename HashFamily>
Status CuckooFilter<ItemType, bits_per_item, TableType, HashFamily>::Delete(
const ItemType &key) {
size_t i1, i2;
uint32_t tag;
GenerateIndexTagHash(key, &i1, &tag);
i2 = AltIndex(i1, tag);
if (table_->DeleteTagFromBucket(i1, tag)) {
num_items_--;
goto TryEliminateVictim;
} else if (table_->DeleteTagFromBucket(i2, tag)) {
num_items_--;
goto TryEliminateVictim;
} else if (victim_.used && tag == victim_.tag &&
(i1 == victim_.index || i2 == victim_.index)) {
// num_items_--;
victim_.used = false;
return Ok;
} else {
return NotFound;
}
TryEliminateVictim:
if (victim_.used) {
victim_.used = false;
size_t i = victim_.index;
uint32_t tag = victim_.tag;
AddImpl(i, tag);
}
return Ok;
}
template <typename ItemType, size_t bits_per_item,
template <size_t> class TableType, typename HashFamily>
std::string CuckooFilter<ItemType, bits_per_item, TableType, HashFamily>::Info()
const {
std::stringstream ss;
ss << "CuckooFilter Status:\n"
<< "\t\t" << table_->Info() << "\n"
<< "\t\tKeys stored: " << Size() << "\n"
<< "\t\tLoad factor: " << LoadFactor() << "\n"
<< "\t\tHashtable size: " << (table_->SizeInBytes() >> 10) << " KB\n";
if (Size() > 0) {
ss << "\t\tbit/key: " << BitsPerItem() << "\n";
} else {
ss << "\t\tbit/key: N/A\n";
}
return ss.str();
}
} // namespace cuckoofilter
#endif // CUCKOO_FILTER_CUCKOO_FILTER_H_

View File

@ -0,0 +1,271 @@
#ifndef CUCKOO_FILTER_STABLE_CUCKOO_FILTER_STABLE_H_
#define CUCKOO_FILTER_STABLE_CUCKOO_FILTER_STABLE_H_
#include <assert.h>
#include <algorithm>
#include "debug.h"
#include "hashutil.h"
#include "packedtable.h"
#include "printutil.h"
#include "singletable.h"
namespace cuckoofilter {
inline uint32_t reduce(uint64_t hash, uint32_t n) {
// http://lemire.me/blog/2016/06/27/a-fast-alternative-to-the-modulo-reduction/
return (uint32_t)(((hash & 0xffffffffL) * n) >> 32);
}
// A stable cuckoo filter class exposes a Bloomier filter interface,
// providing methods of Add, Delete, Contain. It takes three
// template parameters:
// ItemType: the type of item you want to insert
// bits_per_item: how many bits each item is hashed into
// TableType: the storage of table, SingleTable by default, and
// PackedTable to enable semi-sorting
template <typename ItemType, size_t bits_per_item,
template <size_t> class TableType = SingleTable,
typename HashFamily = TwoIndependentMultiplyShift>
class CuckooFilterStable {
// Storage of items
TableType<bits_per_item> *table_;
size_t bucketCount;
// Number of items stored
size_t num_items_;
typedef struct {
size_t index;
uint32_t tag;
bool used;
} VictimCache;
VictimCache victim_;
HashFamily hasher_;
inline size_t IndexHash(uint32_t hv) const {
size_t x = reduce(hv, bucketCount);
return x;
}
inline uint32_t TagHash(uint32_t hv) const {
uint32_t tag;
tag = hv & ((1ULL << bits_per_item) - 1);
tag += (tag == 0);
return tag;
}
inline void GenerateIndexTagHash(const ItemType &item, size_t *index,
uint32_t *tag) const {
const uint64_t hash = hasher_(item);
// const uint64_t hash = item;
// *index = IndexHash(hash >> 32); Mistake!
*index = IndexHash((uint32_t)hash);
*tag = TagHash(hash >> 32);
}
inline size_t AltIndex(const size_t index, const uint32_t tag) const {
// NOTE(binfan): originally we use:
// index ^ HashUtil::BobHash((const void*) (&tag), 4)) & table_->INDEXMASK;
// now doing a quick-n-dirty way:
// 0x5bd1e995 is the hash constant from MurmurHash2
// return IndexHash((uint32_t)(index ^ (tag * 0x5bd1e995)));
uint64_t hash = tag * 0xc4ceb9fe1a85ec53L;
// we don't use xor; instead, we ensure bucketCount is even,
// and bucket2 = bucketCount - bucket - y,
// and if negative add the bucketCount,
// where y is 1..bucketCount - 1 and odd -
// that way, bucket2 is never the original bucket,
// and running this twice will give the original bucket, as needed
uint32_t r = (reduce(hash, bucketCount >> 1) << 1) + 1;
// this is needed because the bucket size is not always 2^n:
int32_t b2 = bucketCount - index - r;
if (b2 < 0) {
b2 += bucketCount;
}
// I tried the following alternatives (also combinations),
// but performance is the same:
// uint32_t b2 = bucketCount - index - r;
// b2 += bucketCount * (b2 >> 31);
// int32_t b2 = bucketCount - index - r;
// b2 += bucketCount & (b2 >> 31);
// int32_t b2 = r - index;
// b2 += bucketCount & (b2 >> 31);
return b2;
}
Status AddImpl(const size_t i, const uint32_t tag);
// load factor is the fraction of occupancy
double LoadFactor() const { return 1.0 * Size() / table_->SizeInTags(); }
double BitsPerItem() const { return 8.0 * table_->SizeInBytes() / Size(); }
public:
size_t get_cap() const { return num_items_; }
double get_effective_load() const {
return LoadFactor();
}
explicit CuckooFilterStable(const size_t max_num_keys)
: num_items_(0), victim_(), hasher_() {
size_t assoc = 4;
// bucket count needs to be even
constexpr double load = .94;
bucketCount = (10 + max_num_keys / load / assoc) / 2 * 2;
// std::cout << "bucketCount: " << bucketCount << std::endl;
victim_.used = false;
table_ = new TableType<bits_per_item>(bucketCount);
}
~CuckooFilterStable() { delete table_; }
// Add an item to the filter.
Status Add(const ItemType &item);
// Report if the item is inserted, with false positive rate.
Status Contain(const ItemType &item) const;
// Delete an key from the filter
Status Delete(const ItemType &item);
/* methods for providing stats */
// summary infomation
std::string Info() const;
// number of current inserted items;
size_t Size() const { return num_items_; }
// size of the filter in bytes.
size_t SizeInBytes() const { return table_->SizeInBytes(); }
};
template <typename ItemType, size_t bits_per_item,
template <size_t> class TableType, typename HashFamily>
Status CuckooFilterStable<ItemType, bits_per_item, TableType, HashFamily>::Add(
const ItemType &item) {
size_t i;
uint32_t tag;
if (victim_.used) {
return NotEnoughSpace;
}
GenerateIndexTagHash(item, &i, &tag);
return AddImpl(i, tag);
}
template <typename ItemType, size_t bits_per_item,
template <size_t> class TableType, typename HashFamily>
Status CuckooFilterStable<ItemType, bits_per_item, TableType,
HashFamily>::AddImpl(const size_t i,
const uint32_t tag) {
size_t curindex = i;
uint32_t curtag = tag;
uint32_t oldtag;
for (uint32_t count = 0; count < kMaxCuckooCount; count++) {
bool kickout = count > 0;
oldtag = 0;
if (table_->InsertTagToBucket(curindex, curtag, kickout, oldtag)) {
num_items_++;
return Ok;
}
if (kickout) {
curtag = oldtag;
}
curindex = AltIndex(curindex, curtag);
}
victim_.index = curindex;
victim_.tag = curtag;
victim_.used = true;
return Ok;
}
template <typename ItemType, size_t bits_per_item,
template <size_t> class TableType, typename HashFamily>
Status CuckooFilterStable<ItemType, bits_per_item, TableType,
HashFamily>::Contain(const ItemType &key) const {
bool found = false;
size_t i1, i2;
uint32_t tag;
GenerateIndexTagHash(key, &i1, &tag);
i2 = AltIndex(i1, tag);
assert(i1 == AltIndex(i2, tag));
found = victim_.used && (tag == victim_.tag) &&
(i1 == victim_.index || i2 == victim_.index);
if (found || table_->FindTagInBuckets(i1, i2, tag)) {
return Ok;
} else {
return NotFound;
}
}
template <typename ItemType, size_t bits_per_item,
template <size_t> class TableType, typename HashFamily>
Status CuckooFilterStable<ItemType, bits_per_item, TableType,
HashFamily>::Delete(const ItemType &key) {
size_t i1, i2;
uint32_t tag;
GenerateIndexTagHash(key, &i1, &tag);
i2 = AltIndex(i1, tag);
if (table_->DeleteTagFromBucket(i1, tag)) {
num_items_--;
goto TryEliminateVictim;
} else if (table_->DeleteTagFromBucket(i2, tag)) {
num_items_--;
goto TryEliminateVictim;
} else if (victim_.used && tag == victim_.tag &&
(i1 == victim_.index || i2 == victim_.index)) {
// num_items_--;
victim_.used = false;
return Ok;
} else {
return NotFound;
}
TryEliminateVictim:
if (victim_.used) {
victim_.used = false;
size_t i = victim_.index;
uint32_t tag = victim_.tag;
AddImpl(i, tag);
}
return Ok;
}
template <typename ItemType, size_t bits_per_item,
template <size_t> class TableType, typename HashFamily>
std::string CuckooFilterStable<ItemType, bits_per_item, TableType,
HashFamily>::Info() const {
std::stringstream ss;
ss << "CuckooFilterStable Status:\n"
<< "\t\t" << table_->Info() << "\n"
<< "\t\tKeys stored: " << Size() << "\n"
<< "\t\tLoad factor: " << LoadFactor() << "\n"
<< "\t\tHashtable size: " << (table_->SizeInBytes() >> 10) << " KB\n";
if (Size() > 0) {
ss << "\t\tbit/key: " << BitsPerItem() << "\n";
} else {
ss << "\t\tbit/key: N/A\n";
}
return ss.str();
}
} // namespace cuckoofilter
#endif // CUCKOO_FILTER_STABLE_CUCKOO_FILTER_STABLE_H_

54
cuckoofilter/src/debug.h Normal file
View File

@ -0,0 +1,54 @@
#ifndef CUCKOO_FILTER_DEBUG_H_
#define CUCKOO_FILTER_DEBUG_H_
#include <stdio.h> // for perror
namespace cuckoofilter {
#ifndef DEBUG
//#define DEBUG
#endif
#define debug_level (DEBUG_ERRS | DEBUG_CUCKOO)
#ifdef DEBUG
// extern unsigned int debug;
/*
* a combination of DEBUG_ERRS, DEBUG_CUCKOO, DEBUG_TABLE, DEBUG_ENCODE
*/
#define DPRINTF(level, ...) \
do { \
if (debug_level & (level)) fprintf(stdout, ##__VA_ARGS__); \
} while (0)
#define DEBUG_PERROR(errmsg) \
do { \
if (debug_level & DEBUG_ERRS) perror(errmsg); \
} while (0)
#else
#define DPRINTF(level, ...)
#define DEBUG_PERROR(level, ...)
#endif
/*
* The format of this should be obvious. Please add some explanatory
* text if you add a debugging value. This text will show up in
* -d list
*/
#define DEBUG_NONE 0x00 // DBTEXT: No debugging
#define DEBUG_ERRS 0x01 // DBTEXT: Verbose error reporting
#define DEBUG_CUCKOO 0x02 // DBTEXT: Messages for cuckoo hashing
#define DEBUG_TABLE 0x04 // DBTEXT: Messages for table operations
#define DEBUG_ENCODE 0x08 // DBTEXT: Messages for encoding
#define DEBUG_ALL 0xffffffff
// int set_debug(char *arg); /* Returns 0 on success, -1 on failure */
} // namespace cuckoofilter
#endif // CUCKOO_FILTER_DEBUG_H_

View File

@ -0,0 +1,782 @@
// Pulled from lookup3.c by Bob Jenkins
#include "hashutil.h"
#define rot(x, k) (((x) << (k)) | ((x) >> (32 - (k))))
#define mix(a, b, c) \
{ \
a -= c; \
a ^= rot(c, 4); \
c += b; \
b -= a; \
b ^= rot(a, 6); \
a += c; \
c -= b; \
c ^= rot(b, 8); \
b += a; \
a -= c; \
a ^= rot(c, 16); \
c += b; \
b -= a; \
b ^= rot(a, 19); \
a += c; \
c -= b; \
c ^= rot(b, 4); \
b += a; \
}
#define final(a, b, c) \
{ \
c ^= b; \
c -= rot(b, 14); \
a ^= c; \
a -= rot(c, 11); \
b ^= a; \
b -= rot(a, 25); \
c ^= b; \
c -= rot(b, 16); \
a ^= c; \
a -= rot(c, 4); \
b ^= a; \
b -= rot(a, 14); \
c ^= b; \
c -= rot(b, 24); \
}
// Assuming little endian
#define HASH_LITTLE_ENDIAN 1
#define get16bits(d) (*((const uint16_t *)(d)))
namespace cuckoofilter {
/*
hashlittle() -- hash a variable-length key into a 32-bit value
k : the key (the unaligned variable-length array of bytes)
length : the length of the key, counting by bytes
initval : can be any 4-byte value
Returns a 32-bit value. Every bit of the key affects every bit of
the return value. Two keys differing by one or two bits will have
totally different hash values.
The best hash table sizes are powers of 2. There is no need to do
mod a prime (mod is sooo slow!). If you need less than 32 bits,
use a bitmask. For example, if you need only 10 bits, do
h = (h & hashmask(10));
In which case, the hash table should have hashsize(10) elements.
If you are hashing n strings (uint8_t **)k, do it like this:
for (i=0, h=0; i<n; ++i) h = hashlittle( k[i], len[i], h);
By Bob Jenkins, 2006. bob_jenkins@burtleburtle.net. You may use this
code any way you wish, private, educational, or commercial. It's free.
Use for hash table lookup, or anything where one collision in 2^^32 is
acceptable. Do NOT use for cryptographic purposes.
*/
uint32_t HashUtil::BobHash(const std::string &s, uint32_t seed) {
return BobHash(s.data(), s.length(), seed);
}
uint32_t HashUtil::BobHash(const void *buf, size_t length, uint32_t seed) {
uint32_t a, b, c; /* internal state */
union {
const void *ptr;
size_t i;
} u; /* needed for Mac Powerbook G4 */
/* Set up the internal state */
// Is it safe to use key as the initial state setter?
a = b = c = 0xdeadbeef + ((uint32_t)length) + seed;
u.ptr = buf;
if (HASH_LITTLE_ENDIAN && ((u.i & 0x3) == 0)) {
const uint32_t *k = (const uint32_t *)buf; /* read 32-bit chunks */
/*------ all but last block: aligned reads and affect 32 bits of (a,b,c) */
while (length > 12) {
a += k[0];
b += k[1];
c += k[2];
mix(a, b, c);
length -= 12;
k += 3;
}
/*----------------------------- handle the last (probably partial) block */
/*
* "k[2]&0xffffff" actually reads beyond the end of the string, but
* then masks off the part it's not allowed to read. Because the
* string is aligned, the masked-off tail is in the same word as the
* rest of the string. Every machine with memory protection I've seen
* does it on word boundaries, so is OK with this. But VALGRIND will
* still catch it and complain. The masking trick does make the hash
* noticably faster for short strings (like English words).
*/
#ifndef VALGRIND
switch (length) {
case 12:
c += k[2];
b += k[1];
a += k[0];
break;
case 11:
c += k[2] & 0xffffff;
b += k[1];
a += k[0];
break;
case 10:
c += k[2] & 0xffff;
b += k[1];
a += k[0];
break;
case 9:
c += k[2] & 0xff;
b += k[1];
a += k[0];
break;
case 8:
b += k[1];
a += k[0];
break;
case 7:
b += k[1] & 0xffffff;
a += k[0];
break;
case 6:
b += k[1] & 0xffff;
a += k[0];
break;
case 5:
b += k[1] & 0xff;
a += k[0];
break;
case 4:
a += k[0];
break;
case 3:
a += k[0] & 0xffffff;
break;
case 2:
a += k[0] & 0xffff;
break;
case 1:
a += k[0] & 0xff;
break;
case 0:
return c; /* zero length strings require no mixing */
}
#else /* make valgrind happy */
const u_int8_t *k8;
k8 = (const u_int8_t *)k;
switch (length) {
case 12:
c += k[2];
b += k[1];
a += k[0];
break;
case 11:
c += ((uint32_t)k8[10]) << 16; /* fall through */
case 10:
c += ((uint32_t)k8[9]) << 8; /* fall through */
case 9:
c += k8[8]; /* fall through */
case 8:
b += k[1];
a += k[0];
break;
case 7:
b += ((uint32_t)k8[6]) << 16; /* fall through */
case 6:
b += ((uint32_t)k8[5]) << 8; /* fall through */
case 5:
b += k8[4]; /* fall through */
case 4:
a += k[0];
break;
case 3:
a += ((uint32_t)k8[2]) << 16; /* fall through */
case 2:
a += ((uint32_t)k8[1]) << 8; /* fall through */
case 1:
a += k8[0];
break;
case 0:
return c;
}
#endif /* !valgrind */
} else if (HASH_LITTLE_ENDIAN && ((u.i & 0x1) == 0)) {
const u_int16_t *k = (const u_int16_t *)buf; /* read 16-bit chunks */
const u_int8_t *k8;
/*--------------- all but last block: aligned reads and different mixing */
while (length > 12) {
a += k[0] + (((uint32_t)k[1]) << 16);
b += k[2] + (((uint32_t)k[3]) << 16);
c += k[4] + (((uint32_t)k[5]) << 16);
mix(a, b, c);
length -= 12;
k += 6;
}
/*----------------------------- handle the last (probably partial) block */
k8 = (const u_int8_t *)k;
switch (length) {
case 12:
c += k[4] + (((uint32_t)k[5]) << 16);
b += k[2] + (((uint32_t)k[3]) << 16);
a += k[0] + (((uint32_t)k[1]) << 16);
break;
case 11:
c += ((uint32_t)k8[10]) << 16; /* fall through */
case 10:
c += k[4];
b += k[2] + (((uint32_t)k[3]) << 16);
a += k[0] + (((uint32_t)k[1]) << 16);
break;
case 9:
c += k8[8]; /* fall through */
case 8:
b += k[2] + (((uint32_t)k[3]) << 16);
a += k[0] + (((uint32_t)k[1]) << 16);
break;
case 7:
b += ((uint32_t)k8[6]) << 16; /* fall through */
case 6:
b += k[2];
a += k[0] + (((uint32_t)k[1]) << 16);
break;
case 5:
b += k8[4]; /* fall through */
case 4:
a += k[0] + (((uint32_t)k[1]) << 16);
break;
case 3:
a += ((uint32_t)k8[2]) << 16; /* fall through */
case 2:
a += k[0];
break;
case 1:
a += k8[0];
break;
case 0:
return c; /* zero length requires no mixing */
}
} else { /* need to read the key one byte at a time */
const u_int8_t *k = (const u_int8_t *)buf;
/*--------------- all but the last block: affect some 32 bits of (a,b,c) */
while (length > 12) {
a += k[0];
a += ((uint32_t)k[1]) << 8;
a += ((uint32_t)k[2]) << 16;
a += ((uint32_t)k[3]) << 24;
b += k[4];
b += ((uint32_t)k[5]) << 8;
b += ((uint32_t)k[6]) << 16;
b += ((uint32_t)k[7]) << 24;
c += k[8];
c += ((uint32_t)k[9]) << 8;
c += ((uint32_t)k[10]) << 16;
c += ((uint32_t)k[11]) << 24;
mix(a, b, c);
length -= 12;
k += 12;
}
/*-------------------------------- last block: affect all 32 bits of (c) */
switch (length) /* all the case statements fall through */
{
case 12:
c += ((uint32_t)k[11]) << 24;
case 11:
c += ((uint32_t)k[10]) << 16;
case 10:
c += ((uint32_t)k[9]) << 8;
case 9:
c += k[8];
case 8:
b += ((uint32_t)k[7]) << 24;
case 7:
b += ((uint32_t)k[6]) << 16;
case 6:
b += ((uint32_t)k[5]) << 8;
case 5:
b += k[4];
case 4:
a += ((uint32_t)k[3]) << 24;
case 3:
a += ((uint32_t)k[2]) << 16;
case 2:
a += ((uint32_t)k[1]) << 8;
case 1:
a += k[0];
break;
case 0:
return c;
}
}
final(a, b, c);
return c;
}
/*
* hashlittle2: return 2 32-bit hash values
*
* This is identical to hashlittle(), except it returns two 32-bit hash
* values instead of just one. This is good enough for hash table
* lookup with 2^^64 buckets, or if you want a second hash if you're not
* happy with the first, or if you want a probably-unique 64-bit ID for
* the key. *pc is better mixed than *pb, so use *pc first. If you want
* a 64-bit value do something like "*pc + (((uint64_t)*pb)<<32)".
*/
void HashUtil::BobHash(const void *buf, size_t length, uint32_t *idx1,
uint32_t *idx2) {
uint32_t a, b, c; /* internal state */
union {
const void *ptr;
size_t i;
} u; /* needed for Mac Powerbook G4 */
/* Set up the internal state */
a = b = c = 0xdeadbeef + ((uint32_t)length) + *idx1;
c += *idx2;
u.ptr = buf;
if (HASH_LITTLE_ENDIAN && ((u.i & 0x3) == 0)) {
const uint32_t *k = (const uint32_t *)buf; /* read 32-bit chunks */
#ifdef VALGRIND
const uint8_t *k8;
#endif
/*------ all but last block: aligned reads and affect 32 bits of (a,b,c) */
while (length > 12) {
a += k[0];
b += k[1];
c += k[2];
mix(a, b, c);
length -= 12;
k += 3;
}
/*----------------------------- handle the last (probably partial) block */
/*
* "k[2]&0xffffff" actually reads beyond the end of the string, but
* then masks off the part it's not allowed to read. Because the
* string is aligned, the masked-off tail is in the same word as the
* rest of the string. Every machine with memory protection I've seen
* does it on word boundaries, so is OK with this. But VALGRIND will
* still catch it and complain. The masking trick does make the hash
* noticably faster for short strings (like English words).
*/
#ifndef VALGRIND
switch (length) {
case 12:
c += k[2];
b += k[1];
a += k[0];
break;
case 11:
c += k[2] & 0xffffff;
b += k[1];
a += k[0];
break;
case 10:
c += k[2] & 0xffff;
b += k[1];
a += k[0];
break;
case 9:
c += k[2] & 0xff;
b += k[1];
a += k[0];
break;
case 8:
b += k[1];
a += k[0];
break;
case 7:
b += k[1] & 0xffffff;
a += k[0];
break;
case 6:
b += k[1] & 0xffff;
a += k[0];
break;
case 5:
b += k[1] & 0xff;
a += k[0];
break;
case 4:
a += k[0];
break;
case 3:
a += k[0] & 0xffffff;
break;
case 2:
a += k[0] & 0xffff;
break;
case 1:
a += k[0] & 0xff;
break;
case 0:
*idx1 = c;
*idx2 = b;
return; /* zero length strings require no mixing */
}
#else /* make valgrind happy */
k8 = (const uint8_t *)k;
switch (length) {
case 12:
c += k[2];
b += k[1];
a += k[0];
break;
case 11:
c += ((uint32_t)k8[10]) << 16; /* fall through */
case 10:
c += ((uint32_t)k8[9]) << 8; /* fall through */
case 9:
c += k8[8]; /* fall through */
case 8:
b += k[1];
a += k[0];
break;
case 7:
b += ((uint32_t)k8[6]) << 16; /* fall through */
case 6:
b += ((uint32_t)k8[5]) << 8; /* fall through */
case 5:
b += k8[4]; /* fall through */
case 4:
a += k[0];
break;
case 3:
a += ((uint32_t)k8[2]) << 16; /* fall through */
case 2:
a += ((uint32_t)k8[1]) << 8; /* fall through */
case 1:
a += k8[0];
break;
case 0:
*idx1 = c;
*idx2 = b;
return; /* zero length strings require no mixing */
}
#endif /* !valgrind */
} else if (HASH_LITTLE_ENDIAN && ((u.i & 0x1) == 0)) {
const uint16_t *k = (const uint16_t *)buf; /* read 16-bit chunks */
const uint8_t *k8;
/*--------------- all but last block: aligned reads and different mixing */
while (length > 12) {
a += k[0] + (((uint32_t)k[1]) << 16);
b += k[2] + (((uint32_t)k[3]) << 16);
c += k[4] + (((uint32_t)k[5]) << 16);
mix(a, b, c);
length -= 12;
k += 6;
}
/*----------------------------- handle the last (probably partial) block */
k8 = (const uint8_t *)k;
switch (length) {
case 12:
c += k[4] + (((uint32_t)k[5]) << 16);
b += k[2] + (((uint32_t)k[3]) << 16);
a += k[0] + (((uint32_t)k[1]) << 16);
break;
case 11:
c += ((uint32_t)k8[10]) << 16; /* fall through */
case 10:
c += k[4];
b += k[2] + (((uint32_t)k[3]) << 16);
a += k[0] + (((uint32_t)k[1]) << 16);
break;
case 9:
c += k8[8]; /* fall through */
case 8:
b += k[2] + (((uint32_t)k[3]) << 16);
a += k[0] + (((uint32_t)k[1]) << 16);
break;
case 7:
b += ((uint32_t)k8[6]) << 16; /* fall through */
case 6:
b += k[2];
a += k[0] + (((uint32_t)k[1]) << 16);
break;
case 5:
b += k8[4]; /* fall through */
case 4:
a += k[0] + (((uint32_t)k[1]) << 16);
break;
case 3:
a += ((uint32_t)k8[2]) << 16; /* fall through */
case 2:
a += k[0];
break;
case 1:
a += k8[0];
break;
case 0:
*idx1 = c;
*idx2 = b;
return; /* zero length strings require no mixing */
}
} else { /* need to read the key one byte at a time */
const uint8_t *k = (const uint8_t *)buf;
/*--------------- all but the last block: affect some 32 bits of (a,b,c) */
while (length > 12) {
a += k[0];
a += ((uint32_t)k[1]) << 8;
a += ((uint32_t)k[2]) << 16;
a += ((uint32_t)k[3]) << 24;
b += k[4];
b += ((uint32_t)k[5]) << 8;
b += ((uint32_t)k[6]) << 16;
b += ((uint32_t)k[7]) << 24;
c += k[8];
c += ((uint32_t)k[9]) << 8;
c += ((uint32_t)k[10]) << 16;
c += ((uint32_t)k[11]) << 24;
mix(a, b, c);
length -= 12;
k += 12;
}
/*-------------------------------- last block: affect all 32 bits of (c) */
switch (length) /* all the case statements fall through */
{
case 12:
c += ((uint32_t)k[11]) << 24;
case 11:
c += ((uint32_t)k[10]) << 16;
case 10:
c += ((uint32_t)k[9]) << 8;
case 9:
c += k[8];
case 8:
b += ((uint32_t)k[7]) << 24;
case 7:
b += ((uint32_t)k[6]) << 16;
case 6:
b += ((uint32_t)k[5]) << 8;
case 5:
b += k[4];
case 4:
a += ((uint32_t)k[3]) << 24;
case 3:
a += ((uint32_t)k[2]) << 16;
case 2:
a += ((uint32_t)k[1]) << 8;
case 1:
a += k[0];
break;
case 0:
*idx1 = c;
*idx2 = b;
return; /* zero length strings require no mixing */
}
}
final(a, b, c);
*idx1 = c;
*idx2 = b;
}
void HashUtil::BobHash(const std::string &s, uint32_t *idx1, uint32_t *idx2) {
return BobHash(s.data(), s.length(), idx1, idx2);
}
//-----------------------------------------------------------------------------
// MurmurHash2, by Austin Appleby
// Note - This code makes a few assumptions about how your machine behaves -
// 1. We can read a 4-byte value from any address without crashing
// 2. sizeof(int) == 4
// And it has a few limitations -
// 1. It will not work incrementally.
// 2. It will not produce the same results on little-endian and big-endian
// machines.
// All code is released to the public domain. For business purposes,
// Murmurhash is under the MIT license.
uint32_t HashUtil::MurmurHash(const void *buf, size_t len, uint32_t seed) {
// 'm' and 'r' are mixing constants generated offline.
// They're not really 'magic', they just happen to work well.
const unsigned int m = 0x5bd1e995;
const int r = 24;
// Initialize the hash to a 'random' value
uint32_t h = seed ^ len;
// Mix 4 bytes at a time into the hash
const unsigned char *data = (const unsigned char *)buf;
while (len >= 4) {
unsigned int k = *(unsigned int *)data;
k *= m;
k ^= k >> r;
k *= m;
h *= m;
h ^= k;
data += 4;
len -= 4;
}
// Handle the last few bytes of the input array
switch (len) {
case 3:
h ^= data[2] << 16;
case 2:
h ^= data[1] << 8;
case 1:
h ^= data[0];
h *= m;
};
// Do a few final mixes of the hash to ensure the last few
// bytes are well-incorporated.
h ^= h >> 13;
h *= m;
h ^= h >> 15;
return h;
}
uint32_t HashUtil::MurmurHash(const std::string &s, uint32_t seed) {
return MurmurHash(s.data(), s.length(), seed);
}
// SuperFastHash aka Hsieh Hash, License: GPL 2.0
uint32_t HashUtil::SuperFastHash(const void *buf, size_t len) {
const char *data = (const char *)buf;
uint32_t hash = len, tmp;
int rem;
if (len == 0 || data == NULL) return 0;
rem = len & 3;
len >>= 2;
/* Main loop */
for (; len > 0; len--) {
hash += get16bits(data);
tmp = (get16bits(data + 2) << 11) ^ hash;
hash = (hash << 16) ^ tmp;
data += 2 * sizeof(uint16_t);
hash += hash >> 11;
}
/* Handle end cases */
switch (rem) {
case 3:
hash += get16bits(data);
hash ^= hash << 16;
hash ^= data[sizeof(uint16_t)] << 18;
hash += hash >> 11;
break;
case 2:
hash += get16bits(data);
hash ^= hash << 11;
hash += hash >> 17;
break;
case 1:
hash += *data;
hash ^= hash << 10;
hash += hash >> 1;
}
/* Force "avalanching" of final 127 bits */
hash ^= hash << 3;
hash += hash >> 5;
hash ^= hash << 4;
hash += hash >> 17;
hash ^= hash << 25;
hash += hash >> 6;
return hash;
}
uint32_t HashUtil::SuperFastHash(const std::string &s) {
return SuperFastHash(s.data(), s.length());
}
uint32_t HashUtil::NullHash(const void *buf, size_t length,
uint32_t shiftbytes) {
// Ensure that enough bits exist in buffer
if (length - shiftbytes < sizeof(uint32_t)) {
return 0;
}
char *data = (char *)buf;
return ((data[(length - shiftbytes - 4)] << 24) +
(data[(length - shiftbytes - 3)] << 16) +
(data[(length - shiftbytes - 2)] << 8) +
(data[(length - shiftbytes - 1)]));
}
/*
* Compatibility layer for OpenSSL < 1.1.0.
* Implemented as proposed by
* https://wiki.openssl.org/index.php/OpenSSL_1.1.0_Changes
*/
#if OPENSSL_VERSION_NUMBER < 0x10100000L
#include <string.h>
static void *OPENSSL_zalloc(size_t num) {
void *ret = OPENSSL_malloc(num);
if (ret != NULL) memset(ret, 0, num);
return ret;
}
EVP_MD_CTX *EVP_MD_CTX_new(void) {
return (EVP_MD_CTX *)OPENSSL_zalloc(sizeof(EVP_MD_CTX));
}
void EVP_MD_CTX_free(EVP_MD_CTX *ctx) {
EVP_MD_CTX_cleanup(ctx);
OPENSSL_free(ctx);
}
#endif
std::string HashUtil::MD5Hash(const char *inbuf, size_t in_length) {
EVP_MD_CTX *mdctx;
unsigned char md_value[EVP_MAX_MD_SIZE];
unsigned int md_len;
mdctx = EVP_MD_CTX_new();
EVP_DigestInit(mdctx, EVP_md5());
EVP_DigestUpdate(mdctx, (const void *)inbuf, in_length);
EVP_DigestFinal_ex(mdctx, md_value, &md_len);
EVP_MD_CTX_free(mdctx);
return std::string((char *)md_value, (size_t)md_len);
}
std::string HashUtil::SHA1Hash(const char *inbuf, size_t in_length) {
EVP_MD_CTX *mdctx;
unsigned char md_value[EVP_MAX_MD_SIZE];
unsigned int md_len;
mdctx = EVP_MD_CTX_new();
EVP_DigestInit(mdctx, EVP_sha1());
EVP_DigestUpdate(mdctx, (const void *)inbuf, in_length);
EVP_DigestFinal_ex(mdctx, md_value, &md_len);
EVP_MD_CTX_free(mdctx);
return std::string((char *)md_value, (size_t)md_len);
}
} // namespace cuckoofilter

115
cuckoofilter/src/hashutil.h Normal file
View File

@ -0,0 +1,115 @@
#ifndef CUCKOO_FILTER_HASHUTIL_H_
#define CUCKOO_FILTER_HASHUTIL_H_
#include <stdint.h>
#include <stdlib.h>
#include <sys/types.h>
#include <string>
// #include <openssl/evp.h>
#include <random>
namespace cuckoofilter {
class HashUtil {
public:
// Bob Jenkins Hash
static uint32_t BobHash(const void *buf, size_t length, uint32_t seed = 0);
static uint32_t BobHash(const std::string &s, uint32_t seed = 0);
// Bob Jenkins Hash that returns two indices in one call
// Useful for Cuckoo hashing, power of two choices, etc.
// Use idx1 before idx2, when possible. idx1 and idx2 should be initialized to
// seeds.
static void BobHash(const void *buf, size_t length, uint32_t *idx1,
uint32_t *idx2);
static void BobHash(const std::string &s, uint32_t *idx1, uint32_t *idx2);
// MurmurHash2
static uint32_t MurmurHash(const void *buf, size_t length, uint32_t seed = 0);
static uint32_t MurmurHash(const std::string &s, uint32_t seed = 0);
// SuperFastHash
static uint32_t SuperFastHash(const void *buf, size_t len);
static uint32_t SuperFastHash(const std::string &s);
// Null hash (shift and mask)
static uint32_t NullHash(const void *buf, size_t length, uint32_t shiftbytes);
// Wrappers for MD5 and SHA1 hashing using EVP
static std::string MD5Hash(const char *inbuf, size_t in_length);
static std::string SHA1Hash(const char *inbuf, size_t in_length);
private:
HashUtil();
};
// See Martin Dietzfelbinger, "Universal hashing and k-wise independent random
// variables via integer arithmetic without primes".
class TwoIndependentMultiplyShift {
unsigned __int128 multiply_, add_;
public:
TwoIndependentMultiplyShift() {
std::uint_least64_t seed;
sysrandom(&seed, sizeof(seed));
std::mt19937_64 rng(seed);
std::uniform_int_distribution<uint64_t> dist(0, UINT64_MAX);
for (auto v : {&multiply_, &add_}) {
for (size_t i = 0; i < 8; i++) {
unsigned __int128 hi = dist(rng);
unsigned __int128 lo = dist(rng);
*v ^= (hi << 64) | lo;
}
}
// ::std::random_device random;
// for (auto v : {&multiply_, &add_}) {
// *v = random();
// for (int i = 1; i <= 4; ++i) {
// *v = *v << 32;
// *v |= random();
// }
// }
}
uint64_t operator()(uint64_t key) const {
return (add_ + multiply_ * static_cast<decltype(multiply_)>(key)) >> 64;
}
inline size_t sysrandom(void *dst, size_t dstlen) {
char *buffer = reinterpret_cast<char *>(dst);
std::ifstream stream("/dev/urandom",
std::ios_base::binary | std::ios_base::in);
stream.read(buffer, dstlen);
return dstlen;
}
};
// See Patrascu and Thorup's "The Power of Simple Tabulation Hashing"
class SimpleTabulation {
uint64_t tables_[sizeof(uint64_t)][1 << CHAR_BIT];
public:
SimpleTabulation() {
::std::random_device random;
for (unsigned i = 0; i < sizeof(uint64_t); ++i) {
for (int j = 0; j < (1 << CHAR_BIT); ++j) {
tables_[i][j] = random() | ((static_cast<uint64_t>(random())) << 32);
}
}
}
uint64_t operator()(uint64_t key) const {
uint64_t result = 0;
for (unsigned i = 0; i < sizeof(key); ++i) {
result ^= tables_[i][reinterpret_cast<uint8_t *>(&key)[i]];
}
return result;
}
};
} // namespace cuckoofilter
#endif // CUCKOO_FILTER_HASHUTIL_H_

View File

@ -0,0 +1,438 @@
#ifndef CUCKOO_FILTER_PACKED_TABLE_H_
#define CUCKOO_FILTER_PACKED_TABLE_H_
#include <sstream>
#include <utility>
#include "debug.h"
#include "permencoding.h"
#include "printutil.h"
namespace cuckoofilter {
// Using Permutation encoding to save 1 bit per tag
template <size_t bits_per_tag>
class PackedTable {
static_assert(bits_per_tag == 5 || bits_per_tag == 6 || bits_per_tag == 7 ||
bits_per_tag == 8 || bits_per_tag == 9 ||
bits_per_tag == 13 || bits_per_tag == 17,
"bits_per_tag must be 5, 6, 7, 8, 9, 13, or 17");
static const size_t kDirBitsPerTag = bits_per_tag - 4;
static const size_t kBitsPerBucket = (3 + kDirBitsPerTag) * 4;
static const size_t kBytesPerBucket = (kBitsPerBucket + 7) >> 3;
static const uint32_t kDirBitsMask = ((1ULL << kDirBitsPerTag) - 1) << 4;
// using a pointer adds one more indirection
size_t len_;
size_t num_buckets_;
char *buckets_;
PermEncoding perm_;
public:
explicit PackedTable(size_t num) : num_buckets_(num) {
// NOTE(binfan): use 7 extra bytes to avoid overrun as we
// always read a uint64
len_ = kBytesPerBucket * num_buckets_ + 7;
buckets_ = new char[len_];
memset(buckets_, 0, len_);
}
~PackedTable() { delete[] buckets_; }
size_t NumBuckets() const { return num_buckets_; }
size_t SizeInTags() const { return 4 * num_buckets_; }
size_t SizeInBytes() const { return len_; }
std::string Info() const {
std::stringstream ss;
ss << "PackedHashtable with tag size: " << bits_per_tag << " bits";
ss << "\t4 packed bits(3 bits after compression) and " << kDirBitsPerTag
<< " direct bits\n";
ss << "\t\tAssociativity: 4\n";
ss << "\t\tTotal # of rows: " << num_buckets_ << "\n";
ss << "\t\ttotal # slots: " << SizeInTags() << "\n";
return ss.str();
}
void PrintBucket(const size_t i) const {
DPRINTF(DEBUG_TABLE, "PackedTable::PrintBucket %zu \n", i);
const char *p = buckets_ + kBitsPerBucket * i / 8;
std::cout << "\tbucketbits ="
<< PrintUtil::bytes_to_hex((char *)p, kBytesPerBucket + 1)
<< std::endl;
uint32_t tags[4];
ReadBucket(i, tags);
PrintTags(tags);
DPRINTF(DEBUG_TABLE, "PackedTable::PrintBucket done \n");
}
void PrintTags(uint32_t tags[4]) const {
DPRINTF(DEBUG_TABLE, "PackedTable::PrintTags \n");
uint8_t lowbits[4];
uint32_t dirbits[4];
for (size_t j = 0; j < 4; j++) {
lowbits[j] = tags[j] & 0x0f;
dirbits[j] = (tags[j] & kDirBitsMask) >> 4;
}
uint16_t codeword = perm_.encode(lowbits);
std::cout << "\tcodeword ="
<< PrintUtil::bytes_to_hex((char *)&codeword, 2) << std::endl;
for (size_t j = 0; j < 4; j++) {
std::cout << "\ttag[" << j
<< "]: " << PrintUtil::bytes_to_hex((char *)&tags[j], 4);
std::cout << " lowbits="
<< PrintUtil::bytes_to_hex((char *)&lowbits[j], 1)
<< " dirbits="
<< PrintUtil::bytes_to_hex((char *)&dirbits[j],
kDirBitsPerTag / 8 + 1)
<< std::endl;
}
DPRINTF(DEBUG_TABLE, "PackedTable::PrintTags done\n");
}
inline void SortPair(uint32_t &a, uint32_t &b) {
if ((a & 0x0f) > (b & 0x0f)) {
std::swap(a, b);
}
}
inline void SortTags(uint32_t *tags) {
SortPair(tags[0], tags[2]);
SortPair(tags[1], tags[3]);
SortPair(tags[0], tags[1]);
SortPair(tags[2], tags[3]);
SortPair(tags[1], tags[2]);
}
/* read and decode the bucket i, pass the 4 decoded tags to the 2nd arg
* bucket bits = 12 codeword bits + dir bits of tag1 + dir bits of tag2 ...
*/
inline void ReadBucket(const size_t i, uint32_t tags[4]) const {
DPRINTF(DEBUG_TABLE, "PackedTable::ReadBucket %zu \n", i);
DPRINTF(DEBUG_TABLE, "kdirbitsMask=%x\n", kDirBitsMask);
const char *p; // = buckets_ + ((kBitsPerBucket * i) >> 3);
uint16_t codeword;
uint8_t lowbits[4];
if (bits_per_tag == 5) {
// 1 dirbits per tag, 16 bits per bucket
p = buckets_ + (i * 2);
uint16_t bucketbits = *((uint16_t *)p);
codeword = bucketbits & 0x0fff;
tags[0] = ((bucketbits >> 8) & kDirBitsMask);
tags[1] = ((bucketbits >> 9) & kDirBitsMask);
tags[2] = ((bucketbits >> 10) & kDirBitsMask);
tags[3] = ((bucketbits >> 11) & kDirBitsMask);
} else if (bits_per_tag == 6) {
// 2 dirbits per tag, 20 bits per bucket
p = buckets_ + ((20 * i) >> 3);
uint32_t bucketbits = *((uint32_t *)p);
codeword = (*((uint16_t *)p) >> ((i & 1) << 2)) & 0x0fff;
tags[0] = (bucketbits >> (8 + ((i & 1) << 2))) & kDirBitsMask;
tags[1] = (bucketbits >> (10 + ((i & 1) << 2))) & kDirBitsMask;
tags[2] = (bucketbits >> (12 + ((i & 1) << 2))) & kDirBitsMask;
tags[3] = (bucketbits >> (14 + ((i & 1) << 2))) & kDirBitsMask;
} else if (bits_per_tag == 7) {
// 3 dirbits per tag, 24 bits per bucket
p = buckets_ + (i << 1) + i;
uint32_t bucketbits = *((uint32_t *)p);
codeword = *((uint16_t *)p) & 0x0fff;
tags[0] = (bucketbits >> 8) & kDirBitsMask;
tags[1] = (bucketbits >> 11) & kDirBitsMask;
tags[2] = (bucketbits >> 14) & kDirBitsMask;
tags[3] = (bucketbits >> 17) & kDirBitsMask;
} else if (bits_per_tag == 8) {
// 4 dirbits per tag, 28 bits per bucket
p = buckets_ + ((28 * i) >> 3);
uint32_t bucketbits = *((uint32_t *)p);
codeword = (*((uint16_t *)p) >> ((i & 1) << 2)) & 0x0fff;
tags[0] = (bucketbits >> (8 + ((i & 1) << 2))) & kDirBitsMask;
tags[1] = (bucketbits >> (12 + ((i & 1) << 2))) & kDirBitsMask;
tags[2] = (bucketbits >> (16 + ((i & 1) << 2))) & kDirBitsMask;
tags[3] = (bucketbits >> (20 + ((i & 1) << 2))) & kDirBitsMask;
} else if (bits_per_tag == 9) {
// 5 dirbits per tag, 32 bits per bucket
p = buckets_ + (i * 4);
uint32_t bucketbits = *((uint32_t *)p);
codeword = *((uint16_t *)p) & 0x0fff;
tags[0] = (bucketbits >> 8) & kDirBitsMask;
tags[1] = (bucketbits >> 13) & kDirBitsMask;
tags[2] = (bucketbits >> 18) & kDirBitsMask;
tags[3] = (bucketbits >> 23) & kDirBitsMask;
} else if (bits_per_tag == 13) {
// 9 dirbits per tag, 48 bits per bucket
p = buckets_ + (i * 6);
uint64_t bucketbits = *((uint64_t *)p);
codeword = *((uint16_t *)p) & 0x0fff;
tags[0] = (bucketbits >> 8) & kDirBitsMask;
tags[1] = (bucketbits >> 17) & kDirBitsMask;
tags[2] = (bucketbits >> 26) & kDirBitsMask;
tags[3] = (bucketbits >> 35) & kDirBitsMask;
} else if (bits_per_tag == 17) {
// 13 dirbits per tag, 64 bits per bucket
p = buckets_ + (i << 3);
uint64_t bucketbits = *((uint64_t *)p);
codeword = *((uint16_t *)p) & 0x0fff;
tags[0] = (bucketbits >> 8) & kDirBitsMask;
tags[1] = (bucketbits >> 21) & kDirBitsMask;
tags[2] = (bucketbits >> 34) & kDirBitsMask;
tags[3] = (bucketbits >> 47) & kDirBitsMask;
}
/* codeword is the lowest 12 bits in the bucket */
uint16_t v = perm_.dec_table[codeword];
lowbits[0] = (v & 0x000f);
lowbits[2] = ((v >> 4) & 0x000f);
lowbits[1] = ((v >> 8) & 0x000f);
lowbits[3] = ((v >> 12) & 0x000f);
tags[0] |= lowbits[0];
tags[1] |= lowbits[1];
tags[2] |= lowbits[2];
tags[3] |= lowbits[3];
if (debug_level & DEBUG_TABLE) {
PrintTags(tags);
}
DPRINTF(DEBUG_TABLE, "PackedTable::ReadBucket done \n");
}
/* Tag = 4 low bits + x high bits
* L L L L H H H H ...
*/
inline void WriteBucket(const size_t i, uint32_t tags[4], bool sort = true) {
DPRINTF(DEBUG_TABLE, "PackedTable::WriteBucket %zu \n", i);
/* first sort the tags in increasing order is arg sort = true*/
if (sort) {
DPRINTF(DEBUG_TABLE, "Sort tags\n");
SortTags(tags);
}
if (debug_level & DEBUG_TABLE) {
PrintTags(tags);
}
/* put in direct bits for each tag*/
uint8_t lowbits[4];
uint32_t highbits[4];
lowbits[0] = tags[0] & 0x0f;
lowbits[1] = tags[1] & 0x0f;
lowbits[2] = tags[2] & 0x0f;
lowbits[3] = tags[3] & 0x0f;
highbits[0] = tags[0] & 0xfffffff0;
highbits[1] = tags[1] & 0xfffffff0;
highbits[2] = tags[2] & 0xfffffff0;
highbits[3] = tags[3] & 0xfffffff0;
// note that : tags[j] = lowbits[j] | highbits[j]
uint16_t codeword = perm_.encode(lowbits);
DPRINTF(DEBUG_TABLE, "codeword=%s\n",
PrintUtil::bytes_to_hex((char *)&codeword, 2).c_str());
/* write out the bucketbits to its place*/
const char *p = buckets_ + ((kBitsPerBucket * i) >> 3);
DPRINTF(DEBUG_TABLE, "original bucketbits=%s\n",
PrintUtil::bytes_to_hex((char *)p, 8).c_str());
if (kBitsPerBucket == 16) {
// 1 dirbits per tag
*((uint16_t *)p) = codeword | (highbits[0] << 8) | (highbits[1] << 9) |
(highbits[2] << 10) | (highbits[3] << 11);
} else if (kBitsPerBucket == 20) {
// 2 dirbits per tag
if ((i & 0x0001) == 0) {
*((uint32_t *)p) &= 0xfff00000;
*((uint32_t *)p) |= codeword | (highbits[0] << 8) |
(highbits[1] << 10) | (highbits[2] << 12) |
(highbits[3] << 14);
} else {
*((uint32_t *)p) &= 0xff00000f;
*((uint32_t *)p) |= (codeword << 4) | (highbits[0] << 12) |
(highbits[1] << 14) | (highbits[2] << 16) |
(highbits[3] << 18);
}
} else if (kBitsPerBucket == 24) {
// 3 dirbits per tag
*((uint32_t *)p) &= 0xff000000;
*((uint32_t *)p) |= codeword | (highbits[0] << 8) | (highbits[1] << 11) |
(highbits[2] << 14) | (highbits[3] << 17);
} else if (kBitsPerBucket == 28) {
// 4 dirbits per tag
if ((i & 0x0001) == 0) {
*((uint32_t *)p) &= 0xf0000000;
*((uint32_t *)p) |= codeword | (highbits[0] << 8) |
(highbits[1] << 12) | (highbits[2] << 16) |
(highbits[3] << 20);
} else {
*((uint32_t *)p) &= 0x0000000f;
*((uint32_t *)p) |= (codeword << 4) | (highbits[0] << 12) |
(highbits[1] << 16) | (highbits[2] << 20) |
(highbits[3] << 24);
}
} else if (kBitsPerBucket == 32) {
// 5 dirbits per tag
*((uint32_t *)p) = codeword | (highbits[0] << 8) | (highbits[1] << 13) |
(highbits[2] << 18) | (highbits[3] << 23);
DPRINTF(DEBUG_TABLE, " new bucketbits=%s\n",
PrintUtil::bytes_to_hex((char *)p, 4).c_str());
} else if (kBitsPerBucket == 48) {
// 9 dirbits per tag
*((uint64_t *)p) &= 0xffff000000000000ULL;
*((uint64_t *)p) |= codeword | ((uint64_t)highbits[0] << 8) |
((uint64_t)highbits[1] << 17) |
((uint64_t)highbits[2] << 26) |
((uint64_t)highbits[3] << 35);
DPRINTF(DEBUG_TABLE, " new bucketbits=%s\n",
PrintUtil::bytes_to_hex((char *)p, 4).c_str());
} else if (kBitsPerBucket == 64) {
// 13 dirbits per tag
*((uint64_t *)p) = codeword | ((uint64_t)highbits[0] << 8) |
((uint64_t)highbits[1] << 21) |
((uint64_t)highbits[2] << 34) |
((uint64_t)highbits[3] << 47);
}
DPRINTF(DEBUG_TABLE, "PackedTable::WriteBucket done\n");
}
bool FindTagInBuckets(const size_t i1, const size_t i2,
const uint32_t tag) const {
// DPRINTF(DEBUG_TABLE, "PackedTable::FindTagInBucket %zu\n", i);
uint32_t tags1[4];
uint32_t tags2[4];
// disable for now
// _mm_prefetch( buckets_ + (i1 * kBitsPerBucket) / 8, _MM_HINT_NTA);
// _mm_prefetch( buckets_ + (i2 * kBitsPerBucket) / 8, _MM_HINT_NTA);
// ReadBucket(i1, tags1);
// ReadBucket(i2, tags2);
uint16_t v;
uint64_t bucketbits1 = *((uint64_t *)(buckets_ + kBitsPerBucket * i1 / 8));
uint64_t bucketbits2 = *((uint64_t *)(buckets_ + kBitsPerBucket * i2 / 8));
tags1[0] = (bucketbits1 >> 8) & kDirBitsMask;
tags1[1] = (bucketbits1 >> 17) & kDirBitsMask;
tags1[2] = (bucketbits1 >> 26) & kDirBitsMask;
tags1[3] = (bucketbits1 >> 35) & kDirBitsMask;
v = perm_.dec_table[(bucketbits1)&0x0fff];
// the order 0 2 1 3 is not a bug
tags1[0] |= (v & 0x000f);
tags1[2] |= ((v >> 4) & 0x000f);
tags1[1] |= ((v >> 8) & 0x000f);
tags1[3] |= ((v >> 12) & 0x000f);
tags2[0] = (bucketbits2 >> 8) & kDirBitsMask;
tags2[1] = (bucketbits2 >> 17) & kDirBitsMask;
tags2[2] = (bucketbits2 >> 26) & kDirBitsMask;
tags2[3] = (bucketbits2 >> 35) & kDirBitsMask;
v = perm_.dec_table[(bucketbits2)&0x0fff];
tags2[0] |= (v & 0x000f);
tags2[2] |= ((v >> 4) & 0x000f);
tags2[1] |= ((v >> 8) & 0x000f);
tags2[3] |= ((v >> 12) & 0x000f);
return (tags1[0] == tag) || (tags1[1] == tag) || (tags1[2] == tag) ||
(tags1[3] == tag) || (tags2[0] == tag) || (tags2[1] == tag) ||
(tags2[2] == tag) || (tags2[3] == tag);
}
bool FindTagInBucket(const size_t i, const uint32_t tag) const {
DPRINTF(DEBUG_TABLE, "PackedTable::FindTagInBucket %zu\n", i);
uint32_t tags[4];
ReadBucket(i, tags);
if (debug_level & DEBUG_TABLE) {
PrintTags(tags);
}
bool ret = ((tags[0] == tag) || (tags[1] == tag) || (tags[2] == tag) ||
(tags[3] == tag));
DPRINTF(DEBUG_TABLE, "PackedTable::FindTagInBucket %d \n", ret);
return ret;
}
bool DeleteTagFromBucket(const size_t i, const uint32_t tag) {
uint32_t tags[4];
ReadBucket(i, tags);
if (debug_level & DEBUG_TABLE) {
PrintTags(tags);
}
for (size_t j = 0; j < 4; j++) {
if (tags[j] == tag) {
tags[j] = 0;
WriteBucket(i, tags);
return true;
}
}
return false;
} // DeleteTagFromBucket
bool InsertTagToBucket(const size_t i, const uint32_t tag, const bool kickout,
uint32_t &oldtag) {
DPRINTF(DEBUG_TABLE, "PackedTable::InsertTagToBucket %zu \n", i);
uint32_t tags[4];
DPRINTF(DEBUG_TABLE,
"PackedTable::InsertTagToBucket read bucket to tags\n");
ReadBucket(i, tags);
if (debug_level & DEBUG_TABLE) {
PrintTags(tags);
PrintBucket(i);
}
for (size_t j = 0; j < 4; j++) {
if (tags[j] == 0) {
DPRINTF(DEBUG_TABLE,
"PackedTable::InsertTagToBucket slot %zu is empty\n", j);
tags[j] = tag;
WriteBucket(i, tags);
if (debug_level & DEBUG_TABLE) {
PrintBucket(i);
ReadBucket(i, tags);
}
DPRINTF(DEBUG_TABLE, "PackedTable::InsertTagToBucket Ok\n");
return true;
}
}
if (kickout) {
size_t r = rand() & 3;
DPRINTF(
DEBUG_TABLE,
"PackedTable::InsertTagToBucket, let's kick out a random slot %zu \n",
r);
// PrintBucket(i);
oldtag = tags[r];
tags[r] = tag;
WriteBucket(i, tags);
if (debug_level & DEBUG_TABLE) {
PrintTags(tags);
}
}
DPRINTF(DEBUG_TABLE, "PackedTable::InsertTagToBucket, insert failed \n");
return false;
}
// inline size_t NumTagsInBucket(const size_t i) {
// size_t num = 0;
// for (size_t j = 0; j < tags_per_bucket; j++ ){
// if (ReadTag(i, j) != 0) {
// num ++;
// }
// }
// return num;
// } // NumTagsInBucket
}; // PackedTable
} // namespace cuckoofilter
#endif // CUCKOO_FILTER_PACKED_TABLE_H_

View File

@ -0,0 +1,88 @@
#ifndef CUCKOO_FILTER_PERM_ENCODING_H_
#define CUCKOO_FILTER_PERM_ENCODING_H_
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream>
#include "debug.h"
namespace cuckoofilter {
class PermEncoding {
/* unpack one 2-byte number to four 4-bit numbers */
// inline void unpack(const uint16_t in, const uint8_t out[4]) const {
// (*(uint16_t *)out) = in & 0x0f0f;
// (*(uint16_t *)(out +2)) = (in >> 4) & 0x0f0f;
// }
inline void unpack(uint16_t in, uint8_t out[4]) const {
out[0] = (in & 0x000f);
out[2] = ((in >> 4) & 0x000f);
out[1] = ((in >> 8) & 0x000f);
out[3] = ((in >> 12) & 0x000f);
}
/* pack four 4-bit numbers to one 2-byte number */
inline uint16_t pack(const uint8_t in[4]) const {
uint16_t in1 = *((uint16_t *)(in)) & 0x0f0f;
uint16_t in2 = *((uint16_t *)(in + 2)) << 4;
return in1 | in2;
}
public:
PermEncoding() {
uint8_t dst[4];
uint16_t idx = 0;
memset(dec_table, 0, sizeof(dec_table));
memset(enc_table, 0, sizeof(enc_table));
gen_tables(0, 0, dst, idx);
}
~PermEncoding() {}
static const size_t N_ENTS = 3876;
uint16_t dec_table[N_ENTS];
uint16_t enc_table[1 << 16];
inline void decode(const uint16_t codeword, uint8_t lowbits[4]) const {
unpack(dec_table[codeword], lowbits);
}
inline uint16_t encode(const uint8_t lowbits[4]) const {
if (DEBUG_ENCODE & debug_level) {
printf("Perm.encode\n");
for (int i = 0; i < 4; i++) {
printf("encode lowbits[%d]=%x\n", i, lowbits[i]);
}
printf("pack(lowbits) = %x\n", pack(lowbits));
printf("enc_table[%x]=%x\n", pack(lowbits), enc_table[pack(lowbits)]);
}
return enc_table[pack(lowbits)];
}
void gen_tables(int base, int k, uint8_t dst[4], uint16_t &idx) {
for (int i = base; i < 16; i++) {
/* for fast comparison in binary_search in little-endian machine */
dst[k] = i;
if (k + 1 < 4) {
gen_tables(i, k + 1, dst, idx);
} else {
dec_table[idx] = pack(dst);
enc_table[pack(dst)] = idx;
if (DEBUG_ENCODE & debug_level) {
printf("enc_table[%04x]=%04x\t%x %x %x %x\n", pack(dst), idx, dst[0],
dst[1], dst[2], dst[3]);
}
idx++;
}
}
}
};
} // namespace cuckoofilter
#endif // CUCKOO_FILTER_PERM_ENCODING_H_

View File

@ -0,0 +1,24 @@
// #include "printutil.h"
// #include <stdio.h>
// #include <iostream>
// namespace cuckoofilter {
// std::string PrintUtil::bytes_to_hex(const char *data, size_t len) {
// std::string hexstr = "";
// static const char hexes[] = "0123456789ABCDEF ";
// for (size_t i = 0; i < len; i++) {
// unsigned char c = data[i];
// hexstr.push_back(hexes[c >> 4]);
// hexstr.push_back(hexes[c & 0xf]);
// hexstr.push_back(hexes[16]);
// }
// return hexstr;
// };
// std::string PrintUtil::bytes_to_hex(const std::string &s) {
// return bytes_to_hex((const char *)s.data(), s.size());
// };
// } // namespace cuckoofilter

View File

@ -0,0 +1,32 @@
#ifndef CUCKOO_FILTER_PRINTUTIL_H_
#define CUCKOO_FILTER_PRINTUTIL_H_
#include <string>
namespace cuckoofilter {
class PrintUtil {
public:
static std::string bytes_to_hex(const char *data, size_t len) {
std::string hexstr = "";
static const char hexes[] = "0123456789ABCDEF ";
for (size_t i = 0; i < len; i++) {
unsigned char c = data[i];
hexstr.push_back(hexes[c >> 4]);
hexstr.push_back(hexes[c & 0xf]);
hexstr.push_back(hexes[16]);
}
return hexstr;
}
static std::string bytes_to_hex(const std::string &s) {
return bytes_to_hex((const char *)s.data(), s.size());
}
private:
PrintUtil();
}; // class PrintUtil
} // namespace cuckoofilter
#endif // CUCKOO_FILTER_PRINTUTIL_H_

View File

@ -0,0 +1,488 @@
// Copied from Apache Impala (incubating), usable under the terms in the Apache License,
// Version 2.0.
// This is a block Bloom filter (from Putze et al.'s "Cache-, Hash- and Space-Efficient
// Bloom Filters") with some twists:
//
// 1. Each block is a split Bloom filter - see Section 2.1 of Broder and Mitzenmacher's
// "Network Applications of Bloom Filters: A Survey".
//
// 2. The number of bits set per Add() is contant in order to take advantage of SIMD
// instructions.
#pragma once
#include <cstdint>
#include <cstdlib>
#include <algorithm>
#include <new>
#include "hashutil.h"
using uint32_t = ::std::uint32_t;
using uint64_t = ::std::uint64_t;
__attribute__((always_inline))
inline uint32_t reduce(uint32_t hash, uint32_t n) {
// http://lemire.me/blog/2016/06/27/a-fast-alternative-to-the-modulo-reduction/
return (uint32_t) (((uint64_t) hash * n) >> 32);
}
static inline uint64_t rotl64(uint64_t n, unsigned int c) {
// assumes width is a power of 2
const unsigned int mask = (CHAR_BIT * sizeof(n) - 1);
// assert ( (c<=mask) &&"rotate by type width or more");
c &= mask;
return (n << c) | ( n >> ((-c) & mask));
}
#ifdef __AVX2__
#include <x86intrin.h>
template<typename HashFamily = ::hashing::TwoIndependentMultiplyShift>
class SimdBlockFilterFixed {
private:
// The filter is divided up into Buckets:
using Bucket = uint32_t[8];
const int bucketCount;
Bucket* directory_;
HashFamily hasher_;
public:
// Consumes at most (1 << log_heap_space) bytes on the heap:
explicit SimdBlockFilterFixed(const int bits);
~SimdBlockFilterFixed() noexcept;
void Add(const uint64_t key) noexcept;
// Add multiple items to the filter.
void AddAll(const vector<uint64_t> & data, const size_t start, const size_t end) {
return AddAll(data.data(), start,end);
}
void AddAll(const uint64_t* data, const size_t start, const size_t end);
bool Find(const uint64_t key) const noexcept;
uint64_t SizeInBytes() const { return sizeof(Bucket) * bucketCount; }
private:
// A helper function for Insert()/Find(). Turns a 32-bit hash into a 256-bit Bucket
// with 1 single 1-bit set in each 32-bit lane.
static __m256i MakeMask(const uint32_t hash) noexcept;
void ApplyBlock(uint64_t* tmp, int block, int len);
};
template<typename HashFamily>
SimdBlockFilterFixed<HashFamily>::SimdBlockFilterFixed(const int bits)
// bits / 16: fpp 0.1777%, 75.1%
// bits / 20: fpp 0.4384%, 63.4%
// bits / 22: fpp 0.6692%, 61.1%
// bits / 24: fpp 0.9765%, 59.7% <<== seems to be best (1% fpp seems important)
// bits / 26: fpp 1.3769%, 59.3%
// bits / 28: fpp 1.9197%, 60.3%
// bits / 32: fpp 3.3280%, 63.0%
: bucketCount(::std::max(1, bits / 24)),
directory_(nullptr),
hasher_() {
if (!__builtin_cpu_supports("avx2")) {
throw ::std::runtime_error("SimdBlockFilterFixed does not work without AVX2 instructions");
}
const size_t alloc_size = bucketCount * sizeof(Bucket);
const int malloc_failed =
posix_memalign(reinterpret_cast<void**>(&directory_), 64, alloc_size);
if (malloc_failed) throw ::std::bad_alloc();
memset(directory_, 0, alloc_size);
}
template<typename HashFamily>
SimdBlockFilterFixed<HashFamily>::~SimdBlockFilterFixed() noexcept {
free(directory_);
directory_ = nullptr;
}
// The SIMD reinterpret_casts technically violate C++'s strict aliasing rules. However, we
// compile with -fno-strict-aliasing.
template <typename HashFamily>
[[gnu::always_inline]] inline __m256i
SimdBlockFilterFixed<HashFamily>::MakeMask(const uint32_t hash) noexcept {
const __m256i ones = _mm256_set1_epi32(1);
// Odd contants for hashing:
const __m256i rehash = _mm256_setr_epi32(0x47b6137bU, 0x44974d91U, 0x8824ad5bU,
0xa2b7289dU, 0x705495c7U, 0x2df1424bU, 0x9efc4947U, 0x5c6bfb31U);
// Load hash into a YMM register, repeated eight times
__m256i hash_data = _mm256_set1_epi32(hash);
// Multiply-shift hashing ala Dietzfelbinger et al.: multiply 'hash' by eight different
// odd constants, then keep the 5 most significant bits from each product.
hash_data = _mm256_mullo_epi32(rehash, hash_data);
hash_data = _mm256_srli_epi32(hash_data, 27);
// Use these 5 bits to shift a single bit to a location in each 32-bit lane
return _mm256_sllv_epi32(ones, hash_data);
}
template <typename HashFamily>
[[gnu::always_inline]] inline void
SimdBlockFilterFixed<HashFamily>::Add(const uint64_t key) noexcept {
const auto hash = hasher_(key);
const uint32_t bucket_idx = reduce(rotl64(hash, 32), bucketCount);
const __m256i mask = MakeMask(hash);
__m256i* const bucket = &reinterpret_cast<__m256i*>(directory_)[bucket_idx];
_mm256_store_si256(bucket, _mm256_or_si256(*bucket, mask));
}
const int blockShift = 14;
const int blockLen = 1 << blockShift;
template<typename HashFamily>
void SimdBlockFilterFixed<HashFamily>::ApplyBlock(uint64_t* tmp, int block, int len) {
for (int i = 0; i < len; i += 2) {
uint64_t hash = tmp[(block << blockShift) + i];
uint32_t bucket_idx = tmp[(block << blockShift) + i + 1];
const __m256i mask = MakeMask(hash);
__m256i* const bucket = &reinterpret_cast<__m256i*>(directory_)[bucket_idx];
_mm256_store_si256(bucket, _mm256_or_si256(*bucket, mask));
}
}
template<typename HashFamily>
void SimdBlockFilterFixed<HashFamily>::AddAll(
const uint64_t* keys, const size_t start, const size_t end) {
int blocks = 1 + bucketCount / blockLen;
uint64_t* tmp = new uint64_t[blocks * blockLen];
int* tmpLen = new int[blocks]();
for(size_t i = start; i < end; i++) {
uint64_t key = keys[i];
uint64_t hash = hasher_(key);
uint32_t bucket_idx = reduce(rotl64(hash, 32), bucketCount);
int block = bucket_idx >> blockShift;
int len = tmpLen[block];
tmp[(block << blockShift) + len] = hash;
tmp[(block << blockShift) + len + 1] = bucket_idx;
tmpLen[block] = len + 2;
if (len + 2 == blockLen) {
ApplyBlock(tmp, block, len + 1);
tmpLen[block] = 0;
}
}
for (int block = 0; block < blocks; block++) {
ApplyBlock(tmp, block, tmpLen[block]);
}
delete[] tmp;
delete[] tmpLen;
}
template <typename HashFamily>
[[gnu::always_inline]] inline bool
SimdBlockFilterFixed<HashFamily>::Find(const uint64_t key) const noexcept {
const auto hash = hasher_(key);
const uint32_t bucket_idx = reduce(rotl64(hash, 32), bucketCount);
const __m256i mask = MakeMask(hash);
const __m256i bucket = reinterpret_cast<__m256i*>(directory_)[bucket_idx];
// We should return true if 'bucket' has a one wherever 'mask' does. _mm256_testc_si256
// takes the negation of its first argument and ands that with its second argument. In
// our case, the result is zero everywhere iff there is a one in 'bucket' wherever
// 'mask' is one. testc returns 1 if the result is 0 everywhere and returns 0 otherwise.
return _mm256_testc_si256(bucket, mask);
}
///////////////////////////////////////////////////////////////////
/// 64-byte version
///////////////////////////////////////////////////////////////////
struct mask64bytes {
__m256i first;
__m256i second;
};
typedef struct mask64bytes mask64bytes_t;
template<typename HashFamily = ::hashing::TwoIndependentMultiplyShift>
class SimdBlockFilterFixed64 {
private:
// The filter is divided up into Buckets:
using Bucket = mask64bytes_t;
const int bucketCount;
Bucket* directory_;
HashFamily hasher_;
public:
// Consumes at most (1 << log_heap_space) bytes on the heap:
explicit SimdBlockFilterFixed64(const int bits);
~SimdBlockFilterFixed64() noexcept;
void Add(const uint64_t key) noexcept;
bool Find(const uint64_t key) const noexcept;
uint64_t SizeInBytes() const { return sizeof(Bucket) * bucketCount; }
private:
static mask64bytes_t MakeMask(const uint64_t hash) noexcept;
};
template<typename HashFamily>
SimdBlockFilterFixed64<HashFamily>::SimdBlockFilterFixed64(const int bits)
: bucketCount(::std::max(1, bits / 50)),
directory_(nullptr),
hasher_() {
if (!__builtin_cpu_supports("avx2")) {
throw ::std::runtime_error("SimdBlockFilterFixed64 does not work without AVX2 instructions");
}
const size_t alloc_size = bucketCount * sizeof(Bucket);
const int malloc_failed =
posix_memalign(reinterpret_cast<void**>(&directory_), 64, alloc_size);
if (malloc_failed) throw ::std::bad_alloc();
memset(directory_, 0, alloc_size);
}
template<typename HashFamily>
SimdBlockFilterFixed64<HashFamily>::~SimdBlockFilterFixed64() noexcept {
free(directory_);
directory_ = nullptr;
}
template <typename HashFamily>
[[gnu::always_inline]] inline mask64bytes_t
SimdBlockFilterFixed64<HashFamily>::MakeMask(const uint64_t hash) noexcept {
const __m256i ones = _mm256_set1_epi64x(1);
const __m256i rehash1 = _mm256_setr_epi32(0x47b6137bU, 0x44974d91U, 0x8824ad5bU,
0xa2b7289dU, 0x705495c7U, 0x2df1424bU, 0x9efc4947U, 0x5c6bfb31U);
mask64bytes_t answer;
__m256i hash_data = _mm256_set1_epi32(hash);
__m256i h = _mm256_mullo_epi32(rehash1, hash_data);
h = _mm256_srli_epi32(h, 26);
answer.first = _mm256_unpackhi_epi32(h,_mm256_setzero_si256());
answer.first = _mm256_sllv_epi64(ones, answer.first);
answer.second = _mm256_unpacklo_epi32(h,_mm256_setzero_si256());
answer.second = _mm256_sllv_epi64(ones, answer.second);
return answer;
}
template <typename HashFamily>
[[gnu::always_inline]] inline void
SimdBlockFilterFixed64<HashFamily>::Add(const uint64_t key) noexcept {
const auto hash = hasher_(key);
const uint32_t bucket_idx = reduce(rotl64(hash, 32), bucketCount);
mask64bytes_t mask = MakeMask(hash);
mask64bytes_t* const bucket = &reinterpret_cast<mask64bytes_t*>(directory_)[bucket_idx];
bucket->first = _mm256_or_si256(mask.first, bucket->first);
bucket->second= _mm256_or_si256(mask.second, bucket->second);
}
template <typename HashFamily>
[[gnu::always_inline]] inline bool
SimdBlockFilterFixed64<HashFamily>::Find(const uint64_t key) const noexcept {
const auto hash = hasher_(key);
const uint32_t bucket_idx = reduce(rotl64(hash, 32), bucketCount);
const mask64bytes_t mask = MakeMask(hash);
const mask64bytes_t bucket = reinterpret_cast<mask64bytes_t*>(directory_)[bucket_idx];
return _mm256_testc_si256(bucket.first, mask.first) & _mm256_testc_si256(bucket.second, mask.second);
}
#endif //__AVX2__
///////////////////
// 16-byte version ARM
//////////////////
#ifdef __aarch64__
#include <arm_neon.h>
template<typename HashFamily = ::hashing::TwoIndependentMultiplyShift>
class SimdBlockFilterFixed {
private:
// The filter is divided up into Buckets:
using Bucket = uint16x8_t;
const int bucketCount;
Bucket* directory_;
HashFamily hasher_;
public:
// Consumes at most (1 << log_heap_space) bytes on the heap:
explicit SimdBlockFilterFixed(const int bits);
~SimdBlockFilterFixed() noexcept;
void Add(const uint64_t key) noexcept;
// Add multiple items to the filter.
void AddAll(const vector<uint64_t>& data, const size_t start, const size_t end) {
return AddAll(data.data(),start,end);
}
void AddAll(const uint64_t* data, const size_t start, const size_t end);
bool Find(const uint64_t key) const noexcept;
uint64_t SizeInBytes() const { return sizeof(Bucket) * bucketCount; }
private:
// A helper function for Insert()/Find(). Turns a 32-bit hash into a 256-bit Bucket
// with 1 single 1-bit set in each 32-bit lane.
static Bucket MakeMask(const uint16_t hash) noexcept;
void ApplyBlock(uint64_t* tmp, int block, int len);
};
template<typename HashFamily>
SimdBlockFilterFixed<HashFamily>::SimdBlockFilterFixed(const int bits)
: bucketCount(::std::max(1, bits / 10)),
directory_(nullptr),
hasher_() {
const size_t alloc_size = bucketCount * sizeof(Bucket);
const int malloc_failed =
posix_memalign(reinterpret_cast<void**>(&directory_), 64, alloc_size);
if (malloc_failed) throw ::std::bad_alloc();
memset(directory_, 0, alloc_size);
}
template<typename HashFamily>
SimdBlockFilterFixed<HashFamily>::~SimdBlockFilterFixed() noexcept {
free(directory_);
directory_ = nullptr;
}
template <typename HashFamily>
[[gnu::always_inline]] inline uint16x8_t
SimdBlockFilterFixed<HashFamily>::MakeMask(const uint16_t hash) noexcept {
const uint16x8_t ones = {1,1,1,1,1,1,1,1};
const uint16x8_t rehash = {0x79d8, 0xe722, 0xf2fb, 0x21ec, 0x121b, 0x2302, 0x705a, 0x6e87};
uint16x8_t hash_data = {hash,hash,hash,hash,hash,hash,hash,hash};
uint16x8_t answer = vmulq_u16(hash_data,rehash);
answer = vshrq_n_u16(answer, 12);
answer = vshlq_u16(ones, vreinterpretq_s16_u16(answer));
return answer;
}
template <typename HashFamily>
[[gnu::always_inline]] inline void
SimdBlockFilterFixed<HashFamily>::Add(const uint64_t key) noexcept {
const auto hash = hasher_(key);
const uint32_t bucket_idx = reduce(rotl64(hash, 32), bucketCount);
const uint16x8_t mask = MakeMask(hash);
uint16x8_t bucket = directory_[bucket_idx];
directory_[bucket_idx] = vorrq_u16(mask, bucket);
}
template <typename HashFamily>
[[gnu::always_inline]] inline bool
SimdBlockFilterFixed<HashFamily>::Find(const uint64_t key) const noexcept {
const auto hash = hasher_(key);
const uint32_t bucket_idx = reduce(rotl64(hash, 32), bucketCount);
const uint16x8_t mask = MakeMask(hash);
const uint16x8_t bucket = directory_[bucket_idx];
uint16x8_t an = vbicq_u16(mask, bucket);
uint64x2_t v64 = vreinterpretq_u64_u16(an);
uint32x2_t v32 = vqmovn_u64(v64);
uint64x1_t result = vreinterpret_u64_u32(v32);
return vget_lane_u64(result, 0) == 0;
}
#endif // __aarch64__
///////////////////////////////////////////////////////////////////
/// 16-byte version (not very good)
///////////////////////////////////////////////////////////////////
#ifdef __SSE4_1__
#include <smmintrin.h>
template<typename HashFamily = ::hashing::TwoIndependentMultiplyShift>
class SimdBlockFilterFixed16 {
private:
// The filter is divided up into Buckets:
using Bucket = __m128i;
const int bucketCount;
Bucket* directory_;
HashFamily hasher_;
public:
// Consumes at most (1 << log_heap_space) bytes on the heap:
explicit SimdBlockFilterFixed16(const int bits);
~SimdBlockFilterFixed16() noexcept;
void Add(const uint64_t key) noexcept;
bool Find(const uint64_t key) const noexcept;
uint64_t SizeInBytes() const { return sizeof(Bucket) * bucketCount; }
private:
static __m128i MakeMask(const uint64_t hash) noexcept;
};
template<typename HashFamily>
SimdBlockFilterFixed16<HashFamily>::SimdBlockFilterFixed16(const int bits)
: bucketCount(::std::max(1, bits / 10)),
directory_(nullptr),
hasher_() {
const size_t alloc_size = bucketCount * sizeof(Bucket);
const int malloc_failed =
posix_memalign(reinterpret_cast<void**>(&directory_), 64, alloc_size);
if (malloc_failed) throw ::std::bad_alloc();
memset(directory_, 0, alloc_size);
}
template<typename HashFamily>
SimdBlockFilterFixed16<HashFamily>::~SimdBlockFilterFixed16() noexcept {
free(directory_);
directory_ = nullptr;
}
template <typename HashFamily>
[[gnu::always_inline]] inline __m128i
SimdBlockFilterFixed16<HashFamily>::MakeMask(const uint64_t hash) noexcept {
const __m128i rehash1 = _mm_setr_epi16(0x47b5, 0x4497, 0x8823,
0xa2b7, 0x7053, 0x2df1, 0x9efc, 0x5c6b);
__m128i hash_data = _mm_set1_epi32(hash );
__m128i h = _mm_mulhi_epi16(rehash1, hash_data);
return _mm_shuffle_epi8(_mm_set_epi8(1,2,4,8,16,32,64,-128,1,2,4,8,16,32,64,-128),h);
}
template <typename HashFamily>
[[gnu::always_inline]] inline void
SimdBlockFilterFixed16<HashFamily>::Add(const uint64_t key) noexcept {
const auto hash = hasher_(key);
const uint32_t bucket_idx = reduce(rotl64(hash, 32), bucketCount);
__m128i mask = MakeMask(hash);
__m128i* const bucket = reinterpret_cast<__m128i*>(directory_) + bucket_idx;
__m128i bucketvalue = _mm_loadu_si128(bucket);
bucketvalue = _mm_or_si128(bucketvalue, mask);
_mm_storeu_si128(bucket,bucketvalue);
}
template <typename HashFamily>
[[gnu::always_inline]] inline bool
SimdBlockFilterFixed16<HashFamily>::Find(const uint64_t key) const noexcept {
const auto hash = hasher_(key);
const uint32_t bucket_idx = reduce(rotl64(hash, 32), bucketCount);
const __m128i mask = MakeMask(hash);
__m128i* const bucket = reinterpret_cast<__m128i*>(directory_) + bucket_idx;
__m128i bucketvalue = _mm_loadu_si128(bucket);
return _mm_testc_si128(bucketvalue,mask);
}
#endif // #ifdef __SSE41__

View File

@ -0,0 +1,141 @@
// // Copied from Apache Impala (incubating), usable under the terms in the Apache License,
// // Version 2.0.
// // This is a block Bloom filter (from Putze et al.'s "Cache-, Hash- and Space-Efficient
// // Bloom Filters") with some twists:
// //
// // 1. Each block is a split Bloom filter - see Section 2.1 of Broder and Mitzenmacher's
// // "Network Applications of Bloom Filters: A Survey".
// //
// // 2. The number of bits set per Add() is contant in order to take advantage of SIMD
// // instructions.
// #pragma once
// #include <cstdint>
// #include <cstdlib>
// #include <algorithm>
// #include <new>
// #include <immintrin.h>
// #include "hashutil.h"
// using uint32_t = ::std::uint32_t;
// using uint64_t = ::std::uint64_t;
// template<typename HashFamily = ::cuckoofilter::TwoIndependentMultiplyShift>
// class SimdBlockFilter {
// private:
// // The filter is divided up into Buckets:
// using Bucket = uint32_t[8];
// // log2(number of bytes in a bucket):
// static constexpr int LOG_BUCKET_BYTE_SIZE = 5;
// static_assert(
// (1 << LOG_BUCKET_BYTE_SIZE) == sizeof(Bucket) && sizeof(Bucket) == sizeof(__m256i),
// "Bucket sizing has gone awry.");
// // log_num_buckets_ is the log (base 2) of the number of buckets in the directory:
// const int log_num_buckets_;
// // directory_mask_ is (1 << log_num_buckets_) - 1. It is precomputed in the contructor
// // for efficiency reasons:
// const uint32_t directory_mask_;
// Bucket* directory_;
// HashFamily hasher_;
// public:
// // Consumes at most (1 << log_heap_space) bytes on the heap:
// explicit SimdBlockFilter(const int log_heap_space);
// SimdBlockFilter(SimdBlockFilter&& that)
// : log_num_buckets_(that.log_num_buckets_),
// directory_mask_(that.directory_mask_),
// directory_(that.directory_),
// hasher_(that.hasher_) {}
// ~SimdBlockFilter() noexcept;
// void Add(const uint64_t key) noexcept;
// bool Find(const uint64_t key) const noexcept;
// uint64_t SizeInBytes() const { return sizeof(Bucket) * (1ull << log_num_buckets_); }
// private:
// // A helper function for Insert()/Find(). Turns a 32-bit hash into a 256-bit Bucket
// // with 1 single 1-bit set in each 32-bit lane.
// static __m256i MakeMask(const uint32_t hash) noexcept;
// SimdBlockFilter(const SimdBlockFilter&) = delete;
// void operator=(const SimdBlockFilter&) = delete;
// };
// template<typename HashFamily>
// SimdBlockFilter<HashFamily>::SimdBlockFilter(const int log_heap_space)
// : // Since log_heap_space is in bytes, we need to convert it to the number of Buckets
// // we will use.
// log_num_buckets_(::std::max(1, log_heap_space - LOG_BUCKET_BYTE_SIZE)),
// // Don't use log_num_buckets_ if it will lead to undefined behavior by a shift that is
// // too large.
// directory_mask_((1ull << ::std::min(63, log_num_buckets_)) - 1),
// directory_(nullptr),
// hasher_() {
// if (!__builtin_cpu_supports("avx2")) {
// throw ::std::runtime_error("SimdBlockFilter does not work without AVX2 instructions");
// }
// const size_t alloc_size = 1ull << (log_num_buckets_ + LOG_BUCKET_BYTE_SIZE);
// const int malloc_failed =
// posix_memalign(reinterpret_cast<void**>(&directory_), 64, alloc_size);
// if (malloc_failed) throw ::std::bad_alloc();
// memset(directory_, 0, alloc_size);
// }
// template<typename HashFamily>
// SimdBlockFilter<HashFamily>::~SimdBlockFilter() noexcept {
// free(directory_);
// directory_ = nullptr;
// }
// // The SIMD reinterpret_casts technically violate C++'s strict aliasing rules. However, we
// // compile with -fno-strict-aliasing.
// template <typename HashFamily>
// [[gnu::always_inline]] inline __m256i
// SimdBlockFilter<HashFamily>::MakeMask(const uint32_t hash) noexcept {
// const __m256i ones = _mm256_set1_epi32(1);
// // Odd contants for hashing:
// const __m256i rehash = _mm256_setr_epi32(0x47b6137bU, 0x44974d91U, 0x8824ad5bU,
// 0xa2b7289dU, 0x705495c7U, 0x2df1424bU, 0x9efc4947U, 0x5c6bfb31U);
// // Load hash into a YMM register, repeated eight times
// __m256i hash_data = _mm256_set1_epi32(hash);
// // Multiply-shift hashing ala Dietzfelbinger et al.: multiply 'hash' by eight different
// // odd constants, then keep the 5 most significant bits from each product.
// hash_data = _mm256_mullo_epi32(rehash, hash_data);
// hash_data = _mm256_srli_epi32(hash_data, 27);
// // Use these 5 bits to shift a single bit to a location in each 32-bit lane
// return _mm256_sllv_epi32(ones, hash_data);
// }
// template <typename HashFamily>
// [[gnu::always_inline]] inline void
// SimdBlockFilter<HashFamily>::Add(const uint64_t key) noexcept {
// const auto hash = hasher_(key);
// const uint32_t bucket_idx = hash & directory_mask_;
// const __m256i mask = MakeMask(hash >> log_num_buckets_);
// __m256i* const bucket = &reinterpret_cast<__m256i*>(directory_)[bucket_idx];
// _mm256_store_si256(bucket, _mm256_or_si256(*bucket, mask));
// }
// template <typename HashFamily>
// [[gnu::always_inline]] inline bool
// SimdBlockFilter<HashFamily>::Find(const uint64_t key) const noexcept {
// const auto hash = hasher_(key);
// const uint32_t bucket_idx = hash & directory_mask_;
// const __m256i mask = MakeMask(hash >> log_num_buckets_);
// const __m256i bucket = reinterpret_cast<__m256i*>(directory_)[bucket_idx];
// // We should return true if 'bucket' has a one wherever 'mask' does. _mm256_testc_si256
// // takes the negation of its first argument and ands that with its second argument. In
// // our case, the result is zero everywhere iff there is a one in 'bucket' wherever
// // 'mask' is one. testc returns 1 if the result is 0 everywhere and returns 0 otherwise.
// return _mm256_testc_si256(bucket, mask);
// }

View File

@ -0,0 +1,268 @@
#ifndef CUCKOO_FILTER_SINGLE_TABLE_H_
#define CUCKOO_FILTER_SINGLE_TABLE_H_
#include <assert.h>
#include <sstream>
#include "bitsutil.h"
#include "debug.h"
#include "printutil.h"
namespace cuckoofilter {
constexpr size_t t_bits_per_tag = 12;
constexpr size_t t_tags = 4;
constexpr size_t t_bytesPerBucket = (t_bits_per_tag * t_tags + 7) >> 3;
constexpr size_t t_PaddingBuckets =
((((t_bytesPerBucket + 7) / 8) * 8) - 1) / t_bytesPerBucket;
// the most naive table implementation: one huge bit array
template <size_t bits_per_tag>
class SingleTable {
static const size_t kTagsPerBucket = 4;
static const size_t kBytesPerBucket =
(bits_per_tag * kTagsPerBucket + 7) >> 3;
static const uint32_t kTagMask = (1ULL << bits_per_tag) - 1;
// NOTE: accomodate extra buckets if necessary to avoid overrun
// as we always read a uint64
static const size_t kPaddingBuckets =
((((kBytesPerBucket + 7) / 8) * 8) - 1) / kBytesPerBucket;
struct Bucket {
char bits_[kBytesPerBucket];
} __attribute__((__packed__));
// using a pointer adds one more indirection
Bucket *buckets_;
size_t num_buckets_;
public:
explicit SingleTable(const size_t num) : num_buckets_(num) {
buckets_ = new Bucket[num_buckets_ + kPaddingBuckets];
memset(buckets_, 0, kBytesPerBucket * (num_buckets_ + kPaddingBuckets));
}
~SingleTable() { delete[] buckets_; }
size_t NumBuckets() const { return num_buckets_; }
size_t SizeInBytes() const { return kBytesPerBucket * num_buckets_; }
size_t SizeInTags() const { return kTagsPerBucket * num_buckets_; }
std::string Info() const {
std::stringstream ss;
ss << "SingleHashtable with tag size: " << bits_per_tag << " bits \n";
ss << "\t\tAssociativity: " << kTagsPerBucket << "\n";
ss << "\t\tTotal # of rows: " << num_buckets_ << "\n";
ss << "\t\tTotal # slots: " << SizeInTags() << "\n";
return ss.str();
}
// read tag from pos(i,j)
inline uint32_t ReadTag(const size_t i, const size_t j) const {
const char *p = buckets_[i].bits_;
uint32_t tag;
/* following code only works for little-endian */
if (bits_per_tag == 2) {
tag = *((uint8_t *)p) >> (j * 2);
} else if (bits_per_tag == 4) {
p += (j >> 1);
tag = *((uint8_t *)p) >> ((j & 1) << 2);
} else if (bits_per_tag == 8) {
p += j;
tag = *((uint8_t *)p);
} else if (bits_per_tag == 12) {
p += j + (j >> 1);
tag = *((uint16_t *)p) >> ((j & 1) << 2);
} else if (bits_per_tag == 16) {
p += (j << 1);
tag = *((uint16_t *)p);
} else if (bits_per_tag == 32) {
tag = ((uint32_t *)p)[j];
}
return tag & kTagMask;
}
// write tag to pos(i,j)
inline void WriteTag(const size_t i, const size_t j, const uint32_t t) {
char *p = buckets_[i].bits_;
uint32_t tag = t & kTagMask;
/* following code only works for little-endian */
if (bits_per_tag == 2) {
*((uint8_t *)p) |= tag << (2 * j);
} else if (bits_per_tag == 4) {
p += (j >> 1);
if ((j & 1) == 0) {
*((uint8_t *)p) &= 0xf0;
*((uint8_t *)p) |= tag;
} else {
*((uint8_t *)p) &= 0x0f;
*((uint8_t *)p) |= (tag << 4);
}
} else if (bits_per_tag == 8) {
((uint8_t *)p)[j] = tag;
} else if (bits_per_tag == 12) {
p += (j + (j >> 1));
if ((j & 1) == 0) {
((uint16_t *)p)[0] &= 0xf000;
((uint16_t *)p)[0] |= tag;
} else {
((uint16_t *)p)[0] &= 0x000f;
((uint16_t *)p)[0] |= (tag << 4);
}
} else if (bits_per_tag == 16) {
((uint16_t *)p)[j] = tag;
} else if (bits_per_tag == 32) {
((uint32_t *)p)[j] = tag;
}
}
inline bool FindTagInBuckets(const size_t i1, const size_t i2,
const uint32_t tag) const {
// size_t t = 0; // with 0 about 4.4 E7
// __asm__ volatile("incq %0" :: "m" (t)); // with 0 about 3.9 E7
// __asm__ volatile("incq %0" :: "m" (t)); // with 0 about 3.9 E7
// __asm__ volatile("incq %0" :: "m" (t)); // with 0 about 3.75 E7
// __asm__ volatile("incq %0" :: "m" (t)); // with 0 about 3.0 E7
// __asm__ volatile("incq %0" :: "m" (t)); // with 0 about 3.0 E7
// __asm__ volatile("incq %0" :: "m" (t)); // with 0 about 3.0 E7
// __asm__ volatile("incq %0" :: "m" (t)); // with 0 about 3.0 E7
// __asm__ volatile("incq %0" :: "m" (t)); // with 0 about 3.0 E7
// __asm__ volatile("incq %0" :: "m" (t)); // with 0 about 3.0 E7
// __asm__ volatile("incq %0" :: "m" (t)); // with 0 about 3.0 E7
// __asm__ volatile("incq %0" :: "m" (t)); // with 0 about 3.0 E7
// __asm__ volatile("incq %0" :: "m" (t)); // with 0 about 3.0 E7
// __asm__ volatile("incq %0" :: "m" (t)); // with 0 about 3.0 E7
// size_t t1 = 0, t2 = 0, t3 = 0, t4 = 0;
// __asm__ volatile("incq %0" :: "m" (t1));
// __asm__ volatile("incq %0" :: "m" (t2));
// __asm__ volatile("incq %0" :: "m" (t3));
// __asm__ volatile("incq %0" :: "m" (t4));
const char *p1 = buckets_[i1].bits_;
const char *p2 = buckets_[i2].bits_;
uint64_t v1 = *((uint64_t *)p1);
uint64_t v2 = *((uint64_t *)p2);
// caution: unaligned access & assuming little endian
if (bits_per_tag == 4 && kTagsPerBucket == 4) {
return hasvalue4(v1, tag) || hasvalue4(v2, tag);
} else if (bits_per_tag == 8 && kTagsPerBucket == 4) {
return hasvalue8(v1, tag) || hasvalue8(v2, tag);
} else if (bits_per_tag == 12 && kTagsPerBucket == 4) {
return hasvalue12(v1, tag) || hasvalue12(v2, tag);
} else if (bits_per_tag == 16 && kTagsPerBucket == 4) {
return hasvalue16(v1, tag) || hasvalue16(v2, tag);
} else {
for (size_t j = 0; j < kTagsPerBucket; j++) {
if ((ReadTag(i1, j) == tag) || (ReadTag(i2, j) == tag)) {
return true;
}
}
return false;
}
}
inline bool FindTagInBucket(const size_t i, const uint32_t tag) const {
// caution: unaligned access & assuming little endian
const char *p = buckets_[i].bits_;
uint64_t v = *(uint64_t *)p; // uint16_t may suffice
if (bits_per_tag == 4 && kTagsPerBucket == 4) {
return hasvalue4(v, tag);
} else if (bits_per_tag == 8 && kTagsPerBucket == 4) {
// const char *p = buckets_[i].bits_;
// uint64_t v = *(uint64_t *)p; // uint32_t may suffice
return hasvalue8(v, tag);
} else if (bits_per_tag == 12 && kTagsPerBucket == 4) {
// const char *p = buckets_[i].bits_;
// uint64_t v = *(uint64_t *)p;
return hasvalue12(v, tag);
} else if (bits_per_tag == 16 && kTagsPerBucket == 4) {
// const char *p = buckets_[i].bits_;
// uint64_t v = *(uint64_t *)p;
return hasvalue16(v, tag);
} else {
for (size_t j = 0; j < kTagsPerBucket; j++) {
if (ReadTag(i, j) == tag) {
return true;
}
}
return false;
}
}
inline bool DeleteTagFromBucket(const size_t i, const uint32_t tag) {
for (size_t j = 0; j < kTagsPerBucket; j++) {
if (ReadTag(i, j) == tag) {
assert(FindTagInBucket(i, tag) == true);
WriteTag(i, j, 0);
return true;
}
}
return false;
}
inline bool InsertTagToBucket(const size_t i, const uint32_t tag,
const bool kickout, uint32_t &oldtag) {
// static unsigned slot_index = 0;
for (size_t j = 0; j < kTagsPerBucket; j++) {
if (ReadTag(i, j) == 0) {
WriteTag(i, j, tag);
return true;
}
}
if (kickout) {
size_t r = rand() % kTagsPerBucket;
// size_t r = slot_index;
// slot_index = (slot_index + 1) % kTagsPerBucket;
oldtag = ReadTag(i, r);
WriteTag(i, r, tag);
}
return false;
}
inline size_t NumTagsInBucket(const size_t i) const {
size_t num = 0;
for (size_t j = 0; j < kTagsPerBucket; j++) {
if (ReadTag(i, j) != 0) {
num++;
}
}
return num;
}
inline bool FindTagIn3Buckets(const size_t i1, const size_t i2,
const size_t i3, const uint32_t tag) const {
const char *p1 = buckets_[i1].bits_;
const char *p2 = buckets_[i2].bits_;
const char *p3 = buckets_[i3].bits_;
uint64_t v1 = *((uint64_t *)p1);
uint64_t v2 = *((uint64_t *)p2);
uint64_t v3 = *((uint64_t *)p3);
// caution: unaligned access & assuming little endian
if (bits_per_tag == 4 && kTagsPerBucket == 4) {
return hasvalue4(v1, tag) || hasvalue4(v2, tag) || hasvalue4(v3, tag);
} else if (bits_per_tag == 8 && kTagsPerBucket == 4) {
return hasvalue8(v1, tag) || hasvalue8(v2, tag) || hasvalue8(v3, tag);
} else if (bits_per_tag == 12 && kTagsPerBucket == 4) {
return hasvalue12(v1, tag) || hasvalue12(v2, tag) || hasvalue12(v3, tag);
} else if (bits_per_tag == 16 && kTagsPerBucket == 4) {
return hasvalue16(v1, tag) || hasvalue16(v2, tag) || hasvalue16(v3, tag);
} else {
for (size_t j = 0; j < kTagsPerBucket; j++) {
if ((ReadTag(i1, j) == tag) || (ReadTag(i2, j) == tag)) {
return true;
}
}
return false;
}
}
};
} // namespace cuckoofilter
#endif // CUCKOO_FILTER_SINGLE_TABLE_H_

20
example.cpp Normal file
View File

@ -0,0 +1,20 @@
#include "Tests/wrappers.hpp"
int main(){
using spare = TC_shortcut; // Any incremental filter can replace TC_shortcut.
using prefixFilter = Prefix_Filter<spare>; //
size_t filter_max_capacity = 1'000'000; // Choose any size.
prefixFilter example_filter = FilterAPI<prefixFilter>::ConstructFromAddCount(filter_max_capacity);
uint64_t x1 = 0x0123'4567'89ab'cdef;
FilterAPI<prefixFilter>::Add(x1, &example_filter); // Insertions of an item x1. Insertion can be performed only one step at a time.
bool res = FilterAPI<prefixFilter>::Contain(x1, &example_filter); // Lookup of x1.
assert(res); //No false negative.
uint64_t y1 = ~0x0123'4567'89ab'cdef;
bool res2 = FilterAPI<prefixFilter>::Contain(y1, &example_filter); // Lookup of y1.
std::cout << res2 << std::endl; // Possible false positive. (Although with one item in the filter, this is highly unlikely.)
return 0;
}

289
hashutil.h Normal file
View File

@ -0,0 +1,289 @@
#ifndef HASHUTIL_H_
#define HASHUTIL_H_
#include <climits>
#include <cstring>
#include <fstream>
#include <iostream>
#include <stdint.h>
#include <stdlib.h>
#include <string>
#include <sys/types.h>
// #include "Hash_functions/BobJenkins.h"
// #include "Hash_functions/wyhash.h"
// #include "Hash_functions/xxhash64.h"
#include <assert.h>
#include <random>
#include <vector>
#include <immintrin.h>
#include <x86intrin.h>
// #include "Hash_functions/woothash.h"
namespace hashing {
inline size_t sysrandom(void *dst, size_t dstlen) {
char *buffer = reinterpret_cast<char *>(dst);
std::ifstream stream("/dev/urandom", std::ios_base::binary | std::ios_base::in);
stream.read(buffer, dstlen);
return dstlen;
}
// See Martin Dietzfelbinger, "Universal hashing and k-wise independent random
// variables via integer arithmetic without primes".
class TwoIndependentMultiplyShift {
unsigned __int128 multiply_, add_;
public:
TwoIndependentMultiplyShift() {
std::uint_least64_t seed;
sysrandom(&seed, sizeof(seed));
std::mt19937_64 rng(seed);
std::uniform_int_distribution<uint64_t> dist(0, UINT64_MAX);
for (auto v : {&multiply_, &add_}) {
for (size_t i = 0; i < 8; i++) {
unsigned __int128 hi = dist(rng);
unsigned __int128 lo = dist(rng);
*v ^= (hi << 64) | lo;
}
}
}
/* // ::std::random_device random;
// for (auto v : {&multiply_, &add_}) {
// *v = random();
// for (int i = 1; i <= 4; ++i) {
// *v = *v << 32;
// *v |= random();
// }
// }
}
//
// * @brief Construct a new Two Independent Multiply Shift object
// * Disable the randomness for debugging.
// *
// * @param seed1 Garbage
// * @param seed2 Garbage
//
// TwoIndependentMultiplyShift(unsigned __int128 seed1, unsigned __int128 seed2) {
// std::cout << "hash function is pseudo random" << std::endl;
// multiply_ = 0xaaaa'bbbb'cccc'dddd;
// multiply_ <<= 64;
// multiply_ |= 0xeeee'ffff'1111'0000;
// add_ = 0xaaaa'aaaa'bbbb'bbbb;
// add_ <<= 64;
// add_ |= 0xcccc'cccc'dddd'dddd;
// assert(multiply_ > 18446744073709551615ULL);
// assert(add_ > 18446744073709551615ULL);
// } */
inline uint64_t operator()(uint64_t key) const {
return (add_ + multiply_ * static_cast<decltype(multiply_)>(key)) >> 64;
}
inline uint32_t hash32(uint64_t key) const {
return ((uint32_t) (add_ + multiply_ * static_cast<decltype(multiply_)>(key)));
}
auto get_name() const -> std::string {
return "TwoIndependentMultiplyShift";
}
};
/**
* @brief Like others, only with redundancies, to produce more operations.
*
*/
class IdioticHash {
unsigned __int128 multiply_, add_;
unsigned __int128 multiply_2, add_2;
public:
IdioticHash() {
std::uint_least64_t seed;
sysrandom(&seed, sizeof(seed));
std::mt19937_64 rng(seed);
std::uniform_int_distribution<uint64_t> dist(0, UINT64_MAX);
for (auto v : {&multiply_, &add_}) {
for (size_t i = 0; i < 8; i++) {
unsigned __int128 hi = dist(rng);
unsigned __int128 lo = dist(rng);
*v ^= (hi << 64) | lo;
}
}
for (auto v : {&multiply_2, &add_2}) {
for (size_t i = 0; i < 8; i++) {
unsigned __int128 hi = dist(rng);
unsigned __int128 lo = dist(rng);
*v ^= (hi << 64) | lo;
}
}
}
static inline uint64_t select64(uint64_t x, int64_t j) {
assert(j < 64);
const uint64_t y = _pdep_u64(UINT64_C(1) << j, x);
return _tzcnt_u64(y);
}
inline uint64_t operator()(uint64_t key) const {
auto res1 = (add_ + multiply_ * static_cast<decltype(multiply_)>(key)) >> 64;
auto res2 = (add_2 + multiply_2 * static_cast<decltype(multiply_2)>(key)) >> 64;
size_t index = _mm_popcnt_u64(key);
size_t pos = select64(key, index / 2);
if (pos & 1)
return res1;
return res2;
}
auto get_name() const -> std::string {
return "IdioticHash";
}
};
// See Patrascu and Thorup's "The Power of Simple Tabulation Hashing"
class SimpleTabulation {
uint64_t tables_[sizeof(uint64_t)][1 << CHAR_BIT];
public:
SimpleTabulation() {
std::uint_least64_t seed;
sysrandom(&seed, sizeof(seed));
std::mt19937_64 rng(seed);
std::uniform_int_distribution<uint64_t> dist(0, UINT64_MAX);
for (unsigned i = 0; i < sizeof(uint64_t); ++i) {
for (int j = 0; j < (1 << CHAR_BIT); ++j) {
tables_[i][j] = dist(rng);
}
}
}
uint64_t operator()(uint64_t key) const {
uint64_t result = 0;
for (unsigned i = 0; i < sizeof(key); ++i) {
result ^= tables_[i][reinterpret_cast<uint8_t *>(&key)[i]];
}
return result;
}
};
class SimpleMixSplit {
public:
uint64_t seed;
SimpleMixSplit() {
std::uint_least64_t seed;
sysrandom(&seed, sizeof(seed));
std::mt19937_64 rng(seed);
std::uniform_int_distribution<uint64_t> dist(0, UINT64_MAX);
seed = dist(rng);
// seed <<= 32;
// seed |= random();
}
inline static uint64_t murmur64(uint64_t h) {
h ^= h >> 33;
h *= UINT64_C(0xff51afd7ed558ccd);
h ^= h >> 33;
h *= UINT64_C(0xc4ceb9fe1a85ec53);
h ^= h >> 33;
return h;
}
inline uint64_t operator()(uint64_t key) const {
return murmur64(key + seed);
}
};
// class my_xxhash64 {
// uint64_t seed;
// public:
// my_xxhash64() {
// seed = random();
// }
// inline uint64_t operator()(uint64_t key) const {
// return XXHash64::hash(&key, 8, seed);
// }
// auto get_name() const -> std::string {
// return "xxhash64";
// }
// };
// class my_wyhash64 {
// uint64_t seed;
// public:
// my_wyhash64() {
// seed = random();
// }
// inline uint64_t operator()(uint64_t key) const {
// return wyhash64(key, seed);
// }
// auto get_name() const -> std::string {
// return "wyhash64";
// }
// };
// class my_BobHash {
// uint64_t seed1, seed2;
// public:
// my_BobHash() {
// seed1 = random();
// seed2 = random();
// }
// inline uint64_t operator()(uint32_t s) const {
// uint32_t out1 = seed1, out2 = seed2;
// void BobHash(const void *buf, size_t length, uint32_t *idx1, uint32_t *idx2);
// BobJenkins::BobHash((void *) &s, 4, &out1, &out2);
// return ((uint64_t) out1 << 32ul) | ((uint64_t) out2);
// // return BobJenkins::BobHash((void *) &s, 4, seed);
// }
// // inline uint64_t operator()(uint64_t s) const {
// // return BobJenkins::BobHash((void *) &s, 8, seed);
// // }
// auto get_name() const -> std::string {
// return "BobHash";
// }
// };
// inline uint32_t hashint(uint32_t a) {
// a = (a + 0x7ed55d16) + (a << 12);
// a = (a ^ 0xc761c23c) ^ (a >> 19);
// a = (a + 0x165667b1) + (a << 5);
// a = (a + 0xd3a2646c) ^ (a << 9);
// a = (a + 0xfd7046c5) + (a << 3);
// a = (a ^ 0xb55a4f09) ^ (a >> 16);
// return a;
// }
// inline uint32_t hashint(uint64_t a) {
// a = (a + 0x7ed55d16) + (a << 12);
// a = (a ^ 0xc761c23c) ^ (a >> 19);
// a = (a + 0x165667b1) + (a << 5);
// a = (a + 0xd3a2646c) ^ (a << 9);
// a = (a + 0xfd7046c5) + (a << 3);
// a = (a ^ 0xb55a4f09) ^ (a >> 16);
// return a;
// }
}// namespace hashing
#endif// CUCKOO_FILTER_HASHUTIL_H_

85
main-built.cpp Normal file
View File

@ -0,0 +1,85 @@
#include "Tests/smart_tests.hpp"
void bench_to_csv();
int main() {
// constexpr int k1 = (int) ((double) 8 * 0.693147180559945 + 0.5);
// constexpr int k2 = (int) ((double) 12 * 0.693147180559945 + 0.5);
// constexpr int k3 = (int) ((double) 16 * 0.693147180559945 + 0.5);
bench_to_csv();
return 0;
}
void bench_to_csv() {
using CF8 = cuckoofilter::CuckooFilter<uint64_t, 8>;
using CF12 = cuckoofilter::CuckooFilter<uint64_t, 12>;
using CF16 = cuckoofilter::CuckooFilter<uint64_t, 16>;
// using CF32 = cuckoofilter::CuckooFilter<uint64_t, 32>;
using CF8_Flex = cuckoofilter::CuckooFilterStable<uint64_t, 8>;
using CF12_Flex = cuckoofilter::CuckooFilterStable<uint64_t, 12>;
// using CF16_Flex = cuckoofilter::CuckooFilterStable<uint64_t, 16>;
using inc4 = Prefix_Filter<SimdBlockFilterFixed<>>;
using inc6 = Prefix_Filter<CF12_Flex>;
using inc8 = Prefix_Filter<TC_shortcut>;
// using inc9 = Prefix_Filter<Impala512<>>;
using BBF = SimdBlockFilter<>;
using BBF_Fixed = SimdBlockFilterFixed<>;
using L_BF8 = bloomfilter::BloomFilter<uint64_t, 8, 0>;
using L_BF12 = bloomfilter::BloomFilter<uint64_t, 12, 0>;
using L_BF16 = bloomfilter::BloomFilter<uint64_t, 16, 0>;
using CF12_Flex = cuckoofilter::CuckooFilterStable<uint64_t, 12>;
using CF16_Flex = cuckoofilter::CuckooFilterStable<uint64_t, 16>;
constexpr size_t number_of_filters = 13;
// constexpr size_t db_speeder = 1;
constexpr size_t max_filter_capacity = ((1ULL << 28) * 94 / 100) / testSmart::db_speeder;
std::stringstream ss_array[number_of_filters];
std::string names[14] = {"Bloom-8[k=6]", "Bloom-12[k=8]", "Bloom-16[k=11]",
"CF-8", "CF-12", "CF-8-Flex", "CF-12-Flex","TC",
"PF[BBF_Fixed]", "PF[CF12-Flex]", "PF[TC]",
"BBF", "BBF_Fixed" //"Impala512"
};
for (size_t j = 0; j < number_of_filters; j++) {
ss_array[j] << names[j] << ", ";
}
for (size_t i = 0; i < testSmart::ROUNDS; i++) {
vector<u64> v_add;
size_t j = 0;
testSmart::fill_vec_smart(&v_add, max_filter_capacity);
ss_array[j++] << testSmart::bench_build_to_file22<L_BF8>(max_filter_capacity, &v_add) << ", ";
ss_array[j++] << testSmart::bench_build_to_file22<L_BF12>(max_filter_capacity, &v_add) << ", ";
ss_array[j++] << testSmart::bench_build_to_file22<L_BF16>(max_filter_capacity, &v_add) << ", ";
ss_array[j++] << testSmart::bench_build_to_file22<CF8>(max_filter_capacity, &v_add) << ", ";
ss_array[j++] << testSmart::bench_build_to_file22<CF12>(max_filter_capacity, &v_add) << ", ";
ss_array[j++] << testSmart::bench_build_to_file22<CF8_Flex>(max_filter_capacity, &v_add) << ", ";
ss_array[j++] << testSmart::bench_build_to_file22<CF12_Flex>(max_filter_capacity, &v_add) << ", ";
ss_array[j++] << testSmart::bench_build_to_file22<TC_shortcut>(max_filter_capacity, &v_add) << ", ";
ss_array[j++] << testSmart::bench_build_to_file22<inc4>(max_filter_capacity, &v_add) << ", ";
ss_array[j++] << testSmart::bench_build_to_file22<inc6>(max_filter_capacity, &v_add) << ", ";
ss_array[j++] << testSmart::bench_build_to_file22<inc8>(max_filter_capacity, &v_add) << ", ";
// ss_array[j++] << testSmart::bench_build_to_file22<inc9>(max_filter_capacity, &v_add) << ", ";
ss_array[j++] << testSmart::bench_build_to_file22<BBF>(max_filter_capacity, &v_add) << ", ";
ss_array[j++] << testSmart::bench_build_to_file22<BBF_Fixed>(max_filter_capacity, &v_add) << ", ";
// ss_array[j++] << testSmart::bench_build_to_file22<Impala512<>>(max_filter_capacity, &v_add) << ", ";
}
const std::string file_name = "../scripts/build-all.csv";
std::fstream file(file_name, std::fstream::in | std::fstream::out | std::fstream::app);
file << endl;
file << "n = " << max_filter_capacity << std::endl;
for (size_t j = 0; j < number_of_filters; j++) {
file << ss_array[j].str() << std::endl;
}
file.close();
}

71
main-fpp.cpp Normal file
View File

@ -0,0 +1,71 @@
#include "Tests/smart_tests.hpp"
void write_fpp_to_file();
int main() {
write_fpp_to_file();
return 0;
}
void write_fpp_to_file() {
using CF8 = cuckoofilter::CuckooFilter<uint64_t, 8>;
using CF12 = cuckoofilter::CuckooFilter<uint64_t, 12>;
using CF16 = cuckoofilter::CuckooFilter<uint64_t, 16>;
using CF32 = cuckoofilter::CuckooFilter<uint64_t, 32>;
using CF8_N2 = cuckoofilter::CuckooFilterStable<uint64_t, 8>;
using CF12_Flex = cuckoofilter::CuckooFilterStable<uint64_t, 12>;
using CF16_N2 = cuckoofilter::CuckooFilterStable<uint64_t, 16>;
using CF32_N2 = cuckoofilter::CuckooFilterStable<uint64_t, 32>;
using inc4 = Prefix_Filter<SimdBlockFilterFixed<>>;
using inc6 = Prefix_Filter<CF12_Flex>;
using inc8 = Prefix_Filter<TC_shortcut>;
using inc9 = Prefix_Filter<Impala512<>>;
using L_BF8 = bloomfilter::BloomFilter<uint64_t, 8, 0>;
using L_BF12 = bloomfilter::BloomFilter<uint64_t, 12, 0>;
using L_BF16 = bloomfilter::BloomFilter<uint64_t, 16, 0>;
constexpr size_t fp_capacity = ((1ULL << 28) * 94 / 100) / testSmart::db_speeder;
constexpr size_t fp_lookups = fp_capacity;
std::vector<u64> fp_v_add, fp_v_find;
testSmart::fill_vec_smart(&fp_v_add, fp_capacity);
testSmart::fill_vec_smart(&fp_v_find, fp_lookups);
std::string path = "../scripts/fpp_table.csv";
std::fstream file(path, std::fstream::in | std::fstream::out | std::fstream::app);
file << "n =, " << fp_capacity << ", Lookups =, " << fp_lookups << std::endl;
std::string header = "Filter, Size in bytes, Ratio of yes-queries bits per item (average), optimal bits per item (w.r.t. yes-queries), difference of BPI to optimal BPI, ratio of BPI to optimal BPI";
// file << "name, byte size, FPR, BPI, opt-BPI, bpi-additive-difference, bpi-ratio" << std::endl;
file << header << std::endl;
file.close();
testSmart::FPR_test<CF8>(&fp_v_add, &fp_v_find, path);
testSmart::FPR_test<CF12>(&fp_v_add, &fp_v_find, path);
testSmart::FPR_test<CF16>(&fp_v_add, &fp_v_find, path);
testSmart::FPR_test<CF8_N2>(&fp_v_add, &fp_v_find, path);
testSmart::FPR_test<CF12_Flex>(&fp_v_add, &fp_v_find, path);
testSmart::FPR_test<CF16_N2>(&fp_v_add, &fp_v_find, path);
testSmart::FPR_test<inc4>(&fp_v_add, &fp_v_find, path);
testSmart::FPR_test<inc6>(&fp_v_add, &fp_v_find, path);
testSmart::FPR_test<inc8>(&fp_v_add, &fp_v_find, path);
testSmart::FPR_test<inc9>(&fp_v_add, &fp_v_find, path);
testSmart::FPR_test<SimdBlockFilterFixed<>>(&fp_v_add, &fp_v_find, path);
testSmart::FPR_test<SimdBlockFilter<>>(&fp_v_add, &fp_v_find, path);
testSmart::FPR_test<Impala512<>>(&fp_v_add, &fp_v_find, path);
testSmart::FPR_test<L_BF8>(&fp_v_add, &fp_v_find, path);
testSmart::FPR_test<L_BF12>(&fp_v_add, &fp_v_find, path);
testSmart::FPR_test<L_BF16>(&fp_v_add, &fp_v_find, path);
testSmart::FPR_test<TC_shortcut>(&fp_v_add, &fp_v_find, path);
}

67
main-perf.cpp Normal file
View File

@ -0,0 +1,67 @@
#include "Tests/smart_tests.hpp"
void bench_cmp_np();
void temp_main();
int main() {
for (size_t i = 0; i < testSmart::ROUNDS; ++i) {
bench_cmp_np();
}
return 0;
}
void bench_cmp_np() {
// using spare_item = uint64_t;
using CF8 = cuckoofilter::CuckooFilter<uint64_t, 8>;
using CF12 = cuckoofilter::CuckooFilter<uint64_t, 12>;
using CF16 = cuckoofilter::CuckooFilter<uint64_t, 16>;
using CF8_N2 = cuckoofilter::CuckooFilterStable<uint64_t, 8>;
using CF12_Flex = cuckoofilter::CuckooFilterStable<uint64_t, 12>;
using CF16_Flex = cuckoofilter::CuckooFilterStable<uint64_t, 16>;
using inc4 = Prefix_Filter<SimdBlockFilterFixed<>>;
using inc6 = Prefix_Filter<CF12_Flex>;
using inc8 = Prefix_Filter<TC_shortcut>;
// using inc9 = Prefix_Filter<Impala512<>>;
using L_BF8 = bloomfilter::BloomFilter<uint64_t, 8, 0>;
using L_BF12 = bloomfilter::BloomFilter<uint64_t, 12, 0>;
using L_BF16 = bloomfilter::BloomFilter<uint64_t, 16, 0>;
// constexpr size_t db_speeder = 1;
constexpr size_t max_filter_capacity = ((1ULL << 28) * 94 / 100) / testSmart::db_speeder;// load is .94
constexpr size_t lookup_reps = max_filter_capacity;
constexpr size_t bench_precision = 20;
std::vector<u64> v_add, v_find;
testSmart::fill_vec_smart(&v_add, max_filter_capacity);
testSmart::fill_vec_smart(&v_find, lookup_reps);
const std::string path = "../scripts/Inputs/";
constexpr bool to_print = false;
testSmart::Bench_res_to_file_incremental_22<SimdBlockFilter<>>(max_filter_capacity, bench_precision, &v_add, &v_find, path, to_print);
testSmart::Bench_res_to_file_incremental_22<SimdBlockFilterFixed<>>(max_filter_capacity, bench_precision, &v_add, &v_find, path, to_print);
// testSmart::Bench_res_to_file_incremental_22<Impala512<>>(max_filter_capacity, bench_precision, &v_add, &v_find, path, to_print);
testSmart::Bench_res_to_file_incremental_22<CF8>(max_filter_capacity, bench_precision, &v_add, &v_find, path, to_print);
testSmart::Bench_res_to_file_incremental_22<CF12>(max_filter_capacity, bench_precision, &v_add, &v_find, path, to_print);
testSmart::Bench_res_to_file_incremental_22<CF12_Flex>(max_filter_capacity, bench_precision, &v_add, &v_find, path, to_print);
testSmart::Bench_res_to_file_incremental_22<TC_shortcut>(max_filter_capacity, bench_precision, &v_add, &v_find, path, to_print);
// testSmart::Bench_res_to_file_incremental_22<inc4>(max_filter_capacity, bench_precision, &v_add, &v_find, path, to_print);
testSmart::Bench_res_to_file_incremental_22<inc4>(max_filter_capacity, bench_precision, &v_add, &v_find, path, to_print);
testSmart::Bench_res_to_file_incremental_22<inc6>(max_filter_capacity, bench_precision, &v_add, &v_find, path, to_print);
testSmart::Bench_res_to_file_incremental_22<inc8>(max_filter_capacity, bench_precision, &v_add, &v_find, path, to_print);
// testSmart::Bench_res_to_file_incremental_22<inc9>(max_filter_capacity, bench_precision, &v_add, &v_find, path, to_print);
// testSmart::Bench_res_to_file_incremental_22<L_BF8>(max_filter_capacity, bench_precision, &v_add, &v_find, path, to_print);
// testSmart::Bench_res_to_file_incremental_22<L_BF12>(max_filter_capacity, bench_precision, &v_add, &v_find, path, to_print);
// testSmart::Bench_res_to_file_incremental_22<L_BF16>(max_filter_capacity, bench_precision, &v_add, &v_find, path, to_print);
return;
}

338
scripts/Generate-median-csv.py Executable file
View File

@ -0,0 +1,338 @@
#!/usr/bin/env python3
from Naming import name_dict, get_time
from typing import *
import matplotlib.pyplot as plt
from matplotlib.gridspec import GridSpec
# import matplotlib
# import pandas as pd
import os
import sys
# https://github.com/bendichter/brokenaxes
from brokenaxes import brokenaxes
from statistics import median
USE_AVERAGE = 0
USE_MEDIAN = 1
assert (USE_AVERAGE ^ USE_MEDIAN)
def get_lines(dir: str) -> list:
# file_name = os.path.basename(dir)
f = open(dir, "r")
lines = f.readlines()
f.close()
return lines
def find_line_index(lines: list, phrase: str) -> int:
for i in range(len(lines)):
line = lines[i].strip()
if (len(line) == 0) or (line.startswith("#")):
continue
if line.startswith(phrase):
return i
return -1
def get_filter_name_from_lines(lines):
i = find_line_index(lines, "NAME")
if (i == -1):
print(lines)
assert 0
assert i != -1
name = lines[i][5:].strip()
return name
def get_all_values_from_perf_list(lines: List[str]):
def find_all_partial_matches_in_lines(lines: List[str], pattern: str):
indexes = []
for i in range(len(lines)):
if lines[i].startswith(pattern):
indexes.append(i)
return indexes
beg_list = find_all_partial_matches_in_lines(lines, "NAME")
end_list = find_all_partial_matches_in_lines(lines, "BENCH_END")
def get_performance_list(lines: List[str]):
start_line = find_line_index(lines, "BENCH_START") + 1
end_line = find_line_index(lines, "BENCH_END") - 1 # inclusive.
performance_list = [[] for _ in range(4)]
for line in lines[start_line:end_line]:
if not (len(line.strip())):
continue
temp_list0 = line.split(",")
temp_list1 = [int(i.strip()) for i in temp_list0]
assert(len(temp_list1) == 4)
for i in range(4):
performance_list[i].append(temp_list1[i])
return performance_list
assert(len(beg_list) == len(end_list))
perfs_lists = []
for i in range(len(beg_list)):
temp_lines = lines[beg_list[i]: end_list[i] + 1]
assert temp_lines[0].startswith("NAME")
assert temp_lines[-1].startswith("BENCH")
temp_perf = get_performance_list(temp_lines)
perfs_lists.append(temp_perf)
def built_temp_list(single_perf_list: List, op: int, k: int):
"""[summary]
Args:
single_perf_list (List): [description]
op (int): [description]
k (int): [description]
Returns:
[Lists of lists]: [Each cell in the list, is ]
"""
# single_perf_list[Run][Operation][Round]
# temp_l == [Operation][Round][Run(0);Run(last)]
runs = len(single_perf_list)
assert len(single_perf_list) == runs
temp_l = [single_perf_list[i][op][k] for i in range(runs)]
return temp_l
assert len(perfs_lists[0]) == 4
operations = len(perfs_lists[0])
rounds = len(perfs_lists[0][0])
def built_raw_single_list():
fl = [[0] * rounds for _ in range(operations)]
assert operations == 4
for op in range(operations - 1):
for k in range(rounds):
temp_med = built_temp_list(perfs_lists, op, k)
fl[op][k] = temp_med
return fl
med_fl_list = built_raw_single_list()
return med_fl_list
def get_median_performance_list(lines: List[str]) -> List[List[float]]:
"""Returns a List of Lists: [operation][round(load)]
Args:
lines (List[str]): [description]
Returns:
List[List[float]]: [description]
"""
def find_all_partial_matches_in_lines(lines: List[str], pattern: str):
indexes = []
for i in range(len(lines)):
if lines[i].startswith(pattern):
indexes.append(i)
return indexes
beg_list = find_all_partial_matches_in_lines(lines, "NAME")
end_list = find_all_partial_matches_in_lines(lines, "BENCH_END")
def get_performance_list(lines: List[str]):
start_line = find_line_index(lines, "BENCH_START") + 1
end_line = find_line_index(lines, "BENCH_END") - 1 # inclusive.
performance_list = [[] for _ in range(4)]
for line in lines[start_line:end_line]:
if not (len(line.strip())):
continue
temp_list0 = line.split(",")
temp_list1 = [int(i.strip()) for i in temp_list0]
assert(len(temp_list1) == 4)
for i in range(4):
performance_list[i].append(temp_list1[i])
return performance_list
assert(len(beg_list) == len(end_list))
perfs_lists = []
for i in range(len(beg_list)):
temp_lines = lines[beg_list[i]: end_list[i] + 1]
assert temp_lines[0].startswith("NAME")
assert temp_lines[-1].startswith("BENCH")
temp_perf = get_performance_list(temp_lines)
perfs_lists.append(temp_perf)
def built_temp_list(single_perf_list: List, op: int, k: int) -> List[float]:
# single_perf_list[Run][Operation][Round]
runs = len(single_perf_list)
assert len(single_perf_list) == runs
temp_l = [single_perf_list[i][op][k] for i in range(runs)]
return temp_l
assert len(perfs_lists[0]) == 4
operations = len(perfs_lists[0])
rounds = len(perfs_lists[0][0])
def built_median_single_list() -> List[List[float]]:
fl = [[0] * rounds for _ in range(operations)]
assert operations == 4
for op in range(operations - 1):
for k in range(rounds):
temp_med = median(built_temp_list(perfs_lists, op, k))
fl[op][k] = temp_med
return fl
med_fl_list = built_median_single_list()
return med_fl_list
def get_op_divisors(lines: List[str]):
# a = find_line_index(lines, "NAME")
b = find_line_index(lines, "FILTER_MAX_CAPACITY")
c = find_line_index(lines, "NUMBER_OF_LOOKUP")
# name = lines[a].split()[1]
filter_max_cap = int(lines[b].split()[1])
lookup_reps = int(lines[c].split()[1])
return filter_max_cap, lookup_reps
def get_raw_all_data(f_list: list):
lines_list = []
names_list = []
for temp_file in f_list:
temp_lines = get_lines(temp_file)
lines_list.append(temp_lines)
names_list.append(get_filter_name_from_lines(temp_lines))
perf_lists = []
for temp_lines in lines_list:
# temp_perf == [Operation][Round][Run(0);Run(last)]
temp_perf = get_all_values_from_perf_list(temp_lines)
perf_lists.append(temp_perf)
def get_all_diviate_list(l):
def ratio(x, denom):
assert(denom != 0)
return (x-denom)/denom
t_med = median(l)
fl = [ratio(i, t_med) for i in l]
return fl
flat_div_list = []
filters_num = len(perf_lists)
operation_num = len(perf_lists[0])
rounds = len(perf_lists[0][0])
for op in range(3):
for t_filter in range(filters_num):
for t_round in range(rounds):
temp_l = perf_lists[t_filter][op][t_round]
# print(op, t_filter, t_round, end=":\t")
# print(temp_l)
# if temp_l == 0:
temp_res = get_all_diviate_list(temp_l)
flat_div_list += temp_res
# print()
return flat_div_list
def final_diver(f_list: list) -> None:
flat_diviate = get_raw_all_data(f_list)
s_fd = sorted(flat_diviate)
above_05 = [i for i in s_fd if abs(i) > 0.005]
above_1 = [i for i in s_fd if abs(i) > 0.01]
r1 = len(above_1)/len(s_fd)
r05 = len(above_05)/len(s_fd)
print(
"fraction of elements that are at most 1% away from median (in thier category) \t{:<.5f}".format(1-r1))
print(
"fraction of elements that are at most 0.5% from median (in thier category)\t{:<.5f}".format(1-r05))
print("min & max diviations:", s_fd[0], s_fd[-1])
def generate_csvs(f_list: list):
lines_list = []
names_list = []
for temp_file in f_list:
temp_lines = get_lines(temp_file)
lines_list.append(temp_lines)
names_list.append(get_filter_name_from_lines(temp_lines))
perf_lists = []
for temp_lines in lines_list:
temp_perf = []
if (USE_MEDIAN):
assert(not USE_AVERAGE)
temp_perf = get_median_performance_list(temp_lines)
elif (USE_AVERAGE):
temp_perf = get_average_performance_list(temp_lines)
else:
assert(0)
perf_lists.append(temp_perf)
filter_max_cap, lookup_reps = get_op_divisors(lines_list[0])
rounds_num = len(perf_lists[0][0])
add_step = round(filter_max_cap / rounds_num)
find_step = round(lookup_reps / rounds_num)
###########################################
ins_list = [temp_perf[0] for temp_perf in perf_lists]
uni_list = [temp_perf[1] for temp_perf in perf_lists]
yes_list = [temp_perf[2] for temp_perf in perf_lists]
###########################################
curr_time = get_time()
names = ["add-med-({:}).csv", "uni-med-({:}).csv", "yes-med-({:}).csv"]
names = [nm.format(curr_time) for nm in names]
f_add = open(names[0], "a")
f_uni = open(names[1], "a")
f_yes = open(names[2], "a")
files = [f_add, f_uni, f_yes]
lists = [ins_list, uni_list, yes_list]
filters_names = [name_dict(t) for t in names_list]
size = len(filters_names)
assert size == len(ins_list)
for op in range(len(files)):
t_file = files[op]
t_list = lists[op]
for i in range(size):
t_file.write(filters_names[i] + ",")
temp_line = str(t_list[i])[1:-1]
t_file.write(temp_line + "\n")
f_add.close()
f_uni.close()
f_yes.close()
def main_helper(path):
chosen_files = os.listdir(path)
files_list = [os.path.join(path, i)
for i in chosen_files if not i.endswith(".csv")]
files_list.sort()
final_diver(files_list)
generate_csvs(files_list)
def main():
"""
sys.argv[1] = path
"""
argc: int = len(sys.argv)
if argc == 1:
path = os.path.abspath(os.getcwd())
path = os.path.join(path, "Inputs")
assert os.path.isdir(path)
# name = "bench{:}".get_time()
main_helper(path)
elif argc == 2:
path = sys.argv[1]
# name = "bench{:}".format(get_time())
main_helper(path)
else:
print("Too many arguments where given ({:})".format(argc))
main_helper("./Inputs/")

59
scripts/Naming.py Normal file
View File

@ -0,0 +1,59 @@
from typing import *
from datetime import datetime
def get_marker_type(filter_name: str) -> str:
filter_name = filter_name.strip()
prefix_names_list = ["PF", "CF", "TC", "Bloom", "BBF", "Lem", "Impala512", "BF"]
symbols = ["o", "s", "D", "D", "^", "X", '$\star$', "D"]
default_symbol = "o"
for i in range(len(prefix_names_list)):
temp_prefix = prefix_names_list[i]
if filter_name.startswith(temp_prefix):
return symbols[i]
return default_symbol
def name_dict(filter_name: str) -> str:
filter_name = filter_name.strip()
name_dict = {
'BBF-Fixed': "BBF-Flex",
'BBF_Fixed': "BBF-Flex",
'Cuckoo-8': 'CF-8',
'Cuckoo-12': 'CF-12',
'Cuckoo-16': 'CF-16',
'CuckooStable-8': 'CF-8-Flex',
'CuckooStable-12': 'CF-12-Flex',
'CuckooStable-16': 'CF-16-Flex',
'SimdBlockFilter': "BBF",
'TCD256': "TwoChoicer-256",
'TC_V2': "TwoChoicer",
'TC-shortcut': "TC",
'TwoChoicer-dynamic': "TC-dyn",
'VQF_Wrapper': "VQF",
'inc2Choicer': "TwoChoicer",
'Prefix-Filter [ evenFilter ]': "PF[AF-2]",
'PF[BBF_Fixed]': "PF[BBF-Flex]",
'PF[BBF-Fixed]': "PF[BBF-Flex]",
'Prefix-Filter [ SimdBlockFilter ]': "PF[BBF]",
'Prefix-Filter [ Cuckoo-12 ]': 'PF[CF-12]',
'Prefix-Filter [ CuckooStable-12 ]': 'PF[CF-12-Flex]',
'PF[CF12-Flex]': 'PF[CF-12-Flex]',
'Prefix-Filter [ TC-shortcut ]': 'PF[TC]',
'Prefix-Filter [ BBF-Fixed ]': 'PF[BBF-Flex]',
'Prefix-Filter [ Impala512 ]': 'PF[Impala]',
'Bloom-8[k=6]': 'BF-8[k=6]',
'Bloom-12[k=8]': 'BF-12[k=8]',
'Bloom-16[k=11]': 'BF-16[k=11]',
'Bloom-16[k=10]': 'BF-16[k=11]'
}
if filter_name in name_dict:
return name_dict[filter_name]
else:
print(filter_name, "not in dict")
return filter_name
def get_time():
return datetime.now().strftime('%Y-%m-%d %H:%M:%S')

Some files were not shown because too many files have changed in this diff Show More