src/snark patches for windows build

This commit is contained in:
DeckerSU
2018-04-20 03:32:45 +03:00
parent 0a4ffaff30
commit 5a83e4fc3f
66 changed files with 637 additions and 475 deletions

View File

@@ -66,14 +66,14 @@ merkle_tree<HashT>::merkle_tree(const size_t depth,
assert(log2(contents_as_vector.size()) <= depth);
for (size_t address = 0; address < contents_as_vector.size(); ++address)
{
const size_t idx = address + (1ul<<depth) - 1;
const size_t idx = address + (UINT64_C(1)<<depth) - 1;
values[idx] = contents_as_vector[address];
hashes[idx] = contents_as_vector[address];
hashes[idx].resize(digest_size);
}
size_t idx_begin = (1ul<<depth) - 1;
size_t idx_end = contents_as_vector.size() + ((1ul<<depth) - 1);
size_t idx_begin = (UINT64_C(1)<<depth) - 1;
size_t idx_end = contents_as_vector.size() + ((UINT64_C(1)<<depth) - 1);
for (int layer = depth; layer > 0; --layer)
{
@@ -100,13 +100,13 @@ merkle_tree<HashT>::merkle_tree(const size_t depth,
if (!contents.empty())
{
assert(contents.rbegin()->first < 1ul<<depth);
assert(contents.rbegin()->first < UINT64_C(1)<<depth);
for (auto it = contents.begin(); it != contents.end(); ++it)
{
const size_t address = it->first;
const bit_vector value = it->second;
const size_t idx = address + (1ul<<depth) - 1;
const size_t idx = address + (UINT64_C(1)<<depth) - 1;
values[address] = value;
hashes[idx] = value;
@@ -167,7 +167,7 @@ void merkle_tree<HashT>::set_value(const size_t address,
const bit_vector &value)
{
assert(log2(address) <= depth);
size_t idx = address + (1ul<<depth) - 1;
size_t idx = address + (UINT64_C(1)<<depth) - 1;
assert(value.size() == value_size);
values[address] = value;
@@ -201,7 +201,7 @@ typename HashT::merkle_authentication_path_type merkle_tree<HashT>::get_path(con
{
typename HashT::merkle_authentication_path_type result(depth);
assert(log2(address) <= depth);
size_t idx = address + (1ul<<depth) - 1;
size_t idx = address + (UINT64_C(1)<<depth) - 1;
for (size_t layer = depth; layer > 0; --layer)
{
@@ -209,7 +209,7 @@ typename HashT::merkle_authentication_path_type merkle_tree<HashT>::get_path(con
auto it = hashes.find(sibling_idx);
if (layer == depth)
{
auto it2 = values.find(sibling_idx - ((1ul<<depth) - 1));
auto it2 = values.find(sibling_idx - ((UINT64_C(1)<<depth) - 1));
result[layer-1] = (it2 == values.end() ? bit_vector(value_size, false) : it2->second);
result[layer-1].resize(digest_size);
}
@@ -227,7 +227,7 @@ typename HashT::merkle_authentication_path_type merkle_tree<HashT>::get_path(con
template<typename HashT>
void merkle_tree<HashT>::dump() const
{
for (size_t i = 0; i < 1ul<<depth; ++i)
for (size_t i = 0; i < UINT64_C(1)<<depth; ++i)
{
auto it = values.find(i);
printf("[%zu] -> ", i);

View File

@@ -32,9 +32,9 @@ std::istream& operator>>(std::istream &in, sparse_vector<T> &v);
template<typename T>
struct sparse_vector {
std::vector<size_t> indices;
std::vector<uint64_t> indices;
std::vector<T> values;
size_t domain_size_ = 0;
uint64_t domain_size_ = 0;
sparse_vector() = default;
sparse_vector(const sparse_vector<T> &other) = default;
@@ -44,7 +44,7 @@ struct sparse_vector {
sparse_vector<T>& operator=(const sparse_vector<T> &other) = default;
sparse_vector<T>& operator=(sparse_vector<T> &&other) = default;
T operator[](const size_t idx) const;
T operator[](const uint64_t idx) const;
bool operator==(const sparse_vector<T> &other) const;
bool operator==(const std::vector<T> &other) const;
@@ -52,15 +52,15 @@ struct sparse_vector {
bool is_valid() const;
bool empty() const;
size_t domain_size() const; // return domain_size_
size_t size() const; // return the number of indices (representing the number of non-zero entries)
size_t size_in_bits() const; // return the number bits needed to store the sparse vector
uint64_t domain_size() const; // return domain_size_
uint64_t size() const; // return the number of indices (representing the number of non-zero entries)
uint64_t size_in_bits() const; // return the number bits needed to store the sparse vector
/* return a pair consisting of the accumulated value and the sparse vector of non-accumulated values */
/* return a pair consisting of the accumulated value and the sparse vector of non-accumuated values */
template<typename FieldT>
std::pair<T, sparse_vector<T> > accumulate(const typename std::vector<FieldT>::const_iterator &it_begin,
const typename std::vector<FieldT>::const_iterator &it_end,
const size_t offset) const;
const uint64_t offset) const;
friend std::ostream& operator<< <T>(std::ostream &out, const sparse_vector<T> &v);
friend std::istream& operator>> <T>(std::istream &in, sparse_vector<T> &v);

View File

@@ -29,7 +29,7 @@ sparse_vector<T>::sparse_vector(std::vector<T> &&v) :
}
template<typename T>
T sparse_vector<T>::operator[](const size_t idx) const
T sparse_vector<T>::operator[](const uint64_t idx) const
{
auto it = std::lower_bound(indices.begin(), indices.end(), idx);
return (it != indices.end() && *it == idx) ? values[it - indices.begin()] : T();
@@ -43,7 +43,7 @@ bool sparse_vector<T>::operator==(const sparse_vector<T> &other) const
return false;
}
size_t this_pos = 0, other_pos = 0;
uint64_t this_pos = 0, other_pos = 0;
while (this_pos < this->indices.size() && other_pos < other.indices.size())
{
if (this->indices[this_pos] == other.indices[other_pos])
@@ -103,8 +103,8 @@ bool sparse_vector<T>::operator==(const std::vector<T> &other) const
return false;
}
size_t j = 0;
for (size_t i = 0; i < other.size(); ++i)
uint64_t j = 0;
for (uint64_t i = 0; i < other.size(); ++i)
{
if (this->indices[j] == i)
{
@@ -134,7 +134,7 @@ bool sparse_vector<T>::is_valid() const
return false;
}
for (size_t i = 0; i + 1 < indices.size(); ++i)
for (uint64_t i = 0; i + 1 < indices.size(); ++i)
{
if (indices[i] >= indices[i+1])
{
@@ -157,42 +157,42 @@ bool sparse_vector<T>::empty() const
}
template<typename T>
size_t sparse_vector<T>::domain_size() const
uint64_t sparse_vector<T>::domain_size() const
{
return domain_size_;
}
template<typename T>
size_t sparse_vector<T>::size() const
uint64_t sparse_vector<T>::size() const
{
return indices.size();
}
template<typename T>
size_t sparse_vector<T>::size_in_bits() const
uint64_t sparse_vector<T>::size_in_bits() const
{
return indices.size() * (sizeof(size_t) * 8 + T::size_in_bits());
return indices.size() * (sizeof(uint64_t) * 8 + T::size_in_bits());
}
template<typename T>
template<typename FieldT>
std::pair<T, sparse_vector<T> > sparse_vector<T>::accumulate(const typename std::vector<FieldT>::const_iterator &it_begin,
const typename std::vector<FieldT>::const_iterator &it_end,
const size_t offset) const
const uint64_t offset) const
{
// TODO: does not really belong here.
const size_t chunks = 1;
const uint64_t chunks = 1;
const bool use_multiexp = true;
T accumulated_value = T::zero();
sparse_vector<T> resulting_vector;
resulting_vector.domain_size_ = domain_size_;
const size_t range_len = it_end - it_begin;
const uint64_t range_len = it_end - it_begin;
bool in_block = false;
size_t first_pos = -1, last_pos = -1; // g++ -flto emits unitialized warning, even though in_block guards for such cases.
uint64_t first_pos = -1, last_pos = -1; // g++ -flto emits unitialized warning, even though in_block guards for such cases.
for (size_t i = 0; i < indices.size(); ++i)
for (uint64_t i = 0; i < indices.size(); ++i)
{
const bool matching_pos = (offset <= indices[i] && indices[i] < offset + range_len);
// printf("i = %zu, pos[i] = %zu, offset = %zu, w_size = %zu\n", i, indices[i], offset, w_size);
@@ -265,7 +265,7 @@ std::ostream& operator<<(std::ostream& out, const sparse_vector<T> &v)
{
out << v.domain_size_ << "\n";
out << v.indices.size() << "\n";
for (const size_t& i : v.indices)
for (const uint64_t& i : v.indices)
{
out << i << "\n";
}
@@ -285,11 +285,11 @@ std::istream& operator>>(std::istream& in, sparse_vector<T> &v)
in >> v.domain_size_;
consume_newline(in);
size_t s;
uint64_t s;
in >> s;
consume_newline(in);
v.indices.resize(s);
for (size_t i = 0; i < s; ++i)
for (uint64_t i = 0; i < s; ++i)
{
in >> v.indices[i];
consume_newline(in);
@@ -300,7 +300,7 @@ std::istream& operator>>(std::istream& in, sparse_vector<T> &v)
consume_newline(in);
v.values.reserve(s);
for (size_t i = 0; i < s; ++i)
for (uint64_t i = 0; i < s; ++i)
{
T t;
in >> t;

View File

@@ -26,27 +26,44 @@
#include <proc/readproc.h>
#endif
#ifdef __MACH__ // required to build on MacOS
#include <time.h>
#include <sys/time.h>
#include <mach/clock.h>
#include <mach/mach.h>
#endif
namespace libsnark {
long long get_nsec_time()
int64_t get_nsec_time()
{
auto timepoint = std::chrono::high_resolution_clock::now();
return std::chrono::duration_cast<std::chrono::nanoseconds>(timepoint.time_since_epoch()).count();
}
/* Return total CPU time consumed by all threads of the process, in nanoseconds. */
long long get_nsec_cpu_time()
/* Return total CPU time consumsed by all threads of the process, in nanoseconds. */
int64_t get_nsec_cpu_time()
{
::timespec ts;
#ifdef __MACH__
clock_serv_t cclock;
mach_timespec_t mts;
host_get_clock_service(mach_host_self(), CALENDAR_CLOCK, &cclock);
clock_get_time(cclock, &mts);
mach_port_deallocate(mach_task_self(), cclock);
ts.tv_sec = mts.tv_sec;
ts.tv_nsec = mts.tv_nsec;
#else
if ( ::clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &ts) )
throw ::std::runtime_error("clock_gettime(CLOCK_PROCESS_CPUTIME_ID) failed");
// If we expected this to work, don't silently ignore failures, because that would hide the problem and incur an unnecessarily system-call overhead. So if we ever observe this exception, we should probably add a suitable #ifdef .
//TODO: clock_gettime(CLOCK_PROCESS_CPUTIME_ID) is not supported by native Windows. What about Cygwin? Should we #ifdef on CLOCK_PROCESS_CPUTIME_ID or on __linux__?
#endif
return ts.tv_sec * 1000000000ll + ts.tv_nsec;
}
long long start_time, last_time;
long long start_cpu_time, last_cpu_time;
int64_t start_time, last_time;
int64_t start_cpu_time, last_cpu_time;
void start_profiling()
{
@@ -57,20 +74,20 @@ void start_profiling()
}
std::map<std::string, size_t> invocation_counts;
std::map<std::string, long long> enter_times;
std::map<std::string, long long> last_times;
std::map<std::string, long long> cumulative_times;
std::map<std::string, int64_t> enter_times;
std::map<std::string, int64_t> last_times;
std::map<std::string, int64_t> cumulative_times;
//TODO: Instead of analogous maps for time and cpu_time, use a single struct-valued map
std::map<std::string, long long> enter_cpu_times;
std::map<std::string, long long> last_cpu_times;
std::map<std::pair<std::string, std::string>, long long> op_counts;
std::map<std::pair<std::string, std::string>, long long> cumulative_op_counts; // ((msg, data_point), value)
std::map<std::string, int64_t> enter_cpu_times;
std::map<std::string, int64_t> last_cpu_times;
std::map<std::pair<std::string, std::string>, int64_t> op_counts;
std::map<std::pair<std::string, std::string>, int64_t> cumulative_op_counts; // ((msg, data_point), value)
// TODO: Convert op_counts and cumulative_op_counts from pair to structs
size_t indentation = 0;
std::vector<std::string> block_names;
std::list<std::pair<std::string, long long*> > op_data_points = {
std::list<std::pair<std::string, int64_t*> > op_data_points = {
#ifdef PROFILE_OP_COUNTS
std::make_pair("Fradd", &Fr<default_ec_pp>::add_cnt),
std::make_pair("Frsub", &Fr<default_ec_pp>::sub_cnt),
@@ -98,7 +115,7 @@ void clear_profiling_counters()
cumulative_times.clear();
}
void print_cumulative_time_entry(const std::string &key, const long long factor)
void print_cumulative_time_entry(const std::string &key, const int64_t factor)
{
const double total_ms = (cumulative_times.at(key) * 1e-6);
const size_t cnt = invocation_counts.at(key);
@@ -106,7 +123,7 @@ void print_cumulative_time_entry(const std::string &key, const long long factor)
printf(" %-45s: %12.5fms = %lld * %0.5fms (%zu invocations, %0.5fms = %lld * %0.5fms per invocation)\n", key.c_str(), total_ms, factor, total_ms/factor, cnt, avg_ms, factor, avg_ms/factor);
}
void print_cumulative_times(const long long factor)
void print_cumulative_times(const int64_t factor)
{
printf("Dumping times:\n");
for (auto& kv : cumulative_times)
@@ -155,7 +172,7 @@ void print_op_profiling(const std::string &msg)
printf("(opcounts) = (");
bool first = true;
for (std::pair<std::string, long long*> p : op_data_points)
for (std::pair<std::string, int64_t*> p : op_data_points)
{
if (!first)
{
@@ -171,14 +188,14 @@ void print_op_profiling(const std::string &msg)
#endif
}
static void print_times_from_last_and_start(long long now, long long last,
long long cpu_now, long long cpu_last)
static void print_times_from_last_and_start(int64_t now, int64_t last,
int64_t cpu_now, int64_t cpu_last)
{
long long time_from_start = now - start_time;
long long time_from_last = now - last;
int64_t time_from_start = now - start_time;
int64_t time_from_last = now - last;
long long cpu_time_from_start = cpu_now - start_cpu_time;
long long cpu_time_from_last = cpu_now - cpu_last;
int64_t cpu_time_from_start = cpu_now - start_cpu_time;
int64_t cpu_time_from_last = cpu_now - cpu_last;
if (time_from_last != 0) {
double parallelism_from_last = 1.0 * cpu_time_from_last / time_from_last;
@@ -199,8 +216,8 @@ void print_time(const char* msg)
return;
}
long long now = get_nsec_time();
long long cpu_now = get_nsec_cpu_time();
int64_t now = get_nsec_time();
int64_t cpu_now = get_nsec_cpu_time();
printf("%-35s\t", msg);
print_times_from_last_and_start(now, last_time, cpu_now, last_cpu_time);
@@ -231,7 +248,7 @@ void print_indent()
void op_profiling_enter(const std::string &msg)
{
for (std::pair<std::string, long long*> p : op_data_points)
for (std::pair<std::string, int64_t*> p : op_data_points)
{
op_counts[std::make_pair(msg, p.first)] = *(p.second);
}
@@ -245,9 +262,9 @@ void enter_block(const std::string &msg, const bool indent)
}
block_names.emplace_back(msg);
long long t = get_nsec_time();
int64_t t = get_nsec_time();
enter_times[msg] = t;
long long cpu_t = get_nsec_cpu_time();
int64_t cpu_t = get_nsec_cpu_time();
enter_cpu_times[msg] = cpu_t;
if (inhibit_profiling_info)
@@ -288,15 +305,15 @@ void leave_block(const std::string &msg, const bool indent)
++invocation_counts[msg];
long long t = get_nsec_time();
int64_t t = get_nsec_time();
last_times[msg] = (t - enter_times[msg]);
cumulative_times[msg] += (t - enter_times[msg]);
long long cpu_t = get_nsec_cpu_time();
int64_t cpu_t = get_nsec_cpu_time();
last_cpu_times[msg] = (cpu_t - enter_cpu_times[msg]);
#ifdef PROFILE_OP_COUNTS
for (std::pair<std::string, long long*> p : op_data_points)
for (std::pair<std::string, int64_t*> p : op_data_points)
{
cumulative_op_counts[std::make_pair(msg, p.first)] += *(p.second)-op_counts[std::make_pair(msg, p.first)];
}

View File

@@ -22,7 +22,7 @@
namespace libsnark {
void start_profiling();
long long get_nsec_time();
int64_t get_nsec_time();
void print_time(const char* msg);
void print_header(const char* msg);
@@ -31,13 +31,13 @@ void print_indent();
extern bool inhibit_profiling_info;
extern bool inhibit_profiling_counters;
extern std::map<std::string, size_t> invocation_counts;
extern std::map<std::string, long long> last_times;
extern std::map<std::string, long long> cumulative_times;
extern std::map<std::string, int64_t> last_times;
extern std::map<std::string, int64_t> cumulative_times;
void clear_profiling_counters();
void print_cumulative_time_entry(const std::string &key, const long long factor=1);
void print_cumulative_times(const long long factor=1);
void print_cumulative_time_entry(const std::string &key, const int64_t factor=1);
void print_cumulative_times(const int64_t factor=1);
void print_cumulative_op_counts(const bool only_fq=false);
void enter_block(const std::string &msg, const bool indent=true);

View File

@@ -22,7 +22,7 @@ namespace libsnark {
/*
* @todo
* The serialization is fragile. Should be rewritten using a standard, portable-format
* The serialization is fragile. Shoud be rewritten using a standard, portable-format
* library like boost::serialize.
*
* However, for now the following conventions are used within the code.

View File

@@ -17,6 +17,7 @@
#include <cassert>
#include <sstream>
#include "common/utils.hpp"
#include "common/assert_except.hpp"
namespace libsnark {
@@ -69,7 +70,7 @@ T reserialize(const T &obj)
ss << obj;
T tmp;
ss >> tmp;
assert(obj == tmp);
assert_except(obj == tmp);
return tmp;
}

View File

@@ -15,11 +15,11 @@
namespace libsnark {
size_t log2(size_t n)
uint64_t log2(uint64_t n)
/* returns ceil(log2(n)), so 1ul<<log2(n) is the smallest power of 2,
that is not less than n. */
{
size_t r = ((n & (n-1)) == 0 ? 0 : 1); // add 1 if n is not power of 2
uint64_t r = ((n & (n-1)) == 0 ? 0 : 1); // add 1 if n is not power of 2
while (n > 1)
{
@@ -30,10 +30,10 @@ size_t log2(size_t n)
return r;
}
size_t bitreverse(size_t n, const size_t l)
uint64_t bitreverse(uint64_t n, const uint64_t l)
{
size_t r = 0;
for (size_t k = 0; k < l; ++k)
uint64_t r = 0;
for (uint64_t k = 0; k < l; ++k)
{
r = (r << 1) | (n & 1);
n >>= 1;
@@ -41,20 +41,20 @@ size_t bitreverse(size_t n, const size_t l)
return r;
}
bit_vector int_list_to_bits(const std::initializer_list<unsigned long> &l, const size_t wordsize)
bit_vector int_list_to_bits(const std::initializer_list<uint64_t> &l, const size_t wordsize)
{
bit_vector res(wordsize*l.size());
for (size_t i = 0; i < l.size(); ++i)
for (uint64_t i = 0; i < l.size(); ++i)
{
for (size_t j = 0; j < wordsize; ++j)
for (uint64_t j = 0; j < wordsize; ++j)
{
res[i*wordsize + j] = (*(l.begin()+i) & (1ul<<(wordsize-1-j)));
res[i*wordsize + j] = (*(l.begin()+i) & (UINT64_C(1)<<(wordsize-1-j)));
}
}
return res;
}
long long div_ceil(long long x, long long y)
int64_t div_ceil(int64_t x, int64_t y)
{
return (x + (y-1)) / y;
}
@@ -68,7 +68,7 @@ bool is_little_endian()
std::string FORMAT(const std::string &prefix, const char* format, ...)
{
const static size_t MAX_FMT = 256;
const static uint64_t MAX_FMT = 256;
char buf[MAX_FMT];
va_list args;
va_start(args, format);
@@ -81,7 +81,7 @@ std::string FORMAT(const std::string &prefix, const char* format, ...)
void serialize_bit_vector(std::ostream &out, const bit_vector &v)
{
out << v.size() << "\n";
for (size_t i = 0; i < v.size(); ++i)
for (uint64_t i = 0; i < v.size(); ++i)
{
out << v[i] << "\n";
}
@@ -89,10 +89,10 @@ void serialize_bit_vector(std::ostream &out, const bit_vector &v)
void deserialize_bit_vector(std::istream &in, bit_vector &v)
{
size_t size;
uint64_t size;
in >> size;
v.resize(size);
for (size_t i = 0; i < size; ++i)
for (uint64_t i = 0; i < size; ++i)
{
bool b;
in >> b;

View File

@@ -21,13 +21,13 @@ namespace libsnark {
typedef std::vector<bool> bit_vector;
/// returns ceil(log2(n)), so 1ul<<log2(n) is the smallest power of 2, that is not less than n
size_t log2(size_t n);
uint64_t log2(uint64_t n);
inline size_t exp2(size_t k) { return 1ul << k; }
inline uint64_t exp2(uint64_t k) { return 1ull << k; }
size_t bitreverse(size_t n, const size_t l);
bit_vector int_list_to_bits(const std::initializer_list<unsigned long> &l, const size_t wordsize);
long long div_ceil(long long x, long long y);
uint64_t bitreverse(uint64_t n, const uint64_t l);
bit_vector int_list_to_bits(const std::initializer_list<uint64_t> &l, const uint64_t wordsize);
int64_t div_ceil(int64_t x, int64_t y);
bool is_little_endian();
@@ -46,8 +46,13 @@ void UNUSED(Types&&...) {}
void serialize_bit_vector(std::ostream &out, const bit_vector &v);
void deserialize_bit_vector(std::istream &in, bit_vector &v);
#ifdef __APPLE__
template<typename T>
size_t size_in_bits(const std::vector<T> &v);
unsigned long size_in_bits(const std::vector<T> &v);
#else
template<typename T>
uint64_t size_in_bits(const std::vector<T> &v);
#endif
#define ARRAY_SIZE(arr) (sizeof(arr)/sizeof(arr[0]))

View File

@@ -12,11 +12,19 @@
namespace libsnark {
#ifdef __APPLE__
template<typename T>
unsigned long size_in_bits(const std::vector<T> &v)
{
return v.size() * T::size_in_bits();
}
#else
template<typename T>
size_t size_in_bits(const std::vector<T> &v)
{
return v.size() * T::size_in_bits();
}
#endif
} // libsnark