Project 'mj/mo-submit' was moved to 'mo-p/osmo'. Please update any links and bookmarks that may still have the old path.
Select Git revision
upgrade-20221029.sql
fast-array.h 2.48 KiB
#ifndef __FAST_ARRAY_H__
#define __FAST_ARRAY_H__
#include "rings.h"
#include "options.h"
template < typename Ring >
struct Mapping {
typedef typename Ring::T T;
std::vector<T> data;
Mapping() {}
Mapping(const Mapping& x) : data(x.data) {}
Mapping(size_t size = 0) : data(size, 0) {}
inline size_t size() const { return data.size(); }
inline T operator[] (size_t i) const { return data[i]; }
inline void assign(size_t i, T val) { data[i] = val; }
inline void combine(T beta, const Mapping& b) {
size_t _size = size();
for (size_t i = 0; i < _size; i++)
data[i] = Ring::plus(data[i], Ring::multiply(beta, b.data[i]));
}
};
#if OPTIMIZED_MAPPINGS
template < size_t i, size_t shift >
struct Consts {
static const uint64_t clone = (Consts<i-1, shift>::clone << shift) | 1;
static const uint64_t mask = (Consts<i-1, shift>::mask << shift) | 3;
};
template < size_t shift >
struct Consts<0, shift> {
static const uint64_t clone = 0;
static const uint64_t mask = 0;
};
template < bool isZ4 >
struct FastArray {
typedef int T;
enum { valuesPerWord = 16 };
enum { words = (MAX_EDGES + valuesPerWord - 1) / valuesPerWord };
enum { shift = 4 };
static const uint64_t clone = Consts<valuesPerWord, shift>::clone;
static const uint64_t mask = Consts<valuesPerWord, shift>::mask;
size_t size_;
uint64_t data[words];
FastArray() {}
FastArray(const FastArray& x) : size_(x.size_) {
memcpy(data, x.data, sizeof(data));
}
FastArray(size_t size = 0) : size_(size) {
assert(size <= MAX_EDGES);
memset(data, 0, sizeof(data));
}
inline size_t size() const { return size_; }
inline T operator[] (size_t i) const {
return (data[i >> 4] >> ((i & 0xF) << 2)) & 3; }
inline void assign(size_t i, T val) {
size_t w = i >> 4;
size_t off = i & 0xF;
data[w] &= ~(((uint64_t)3) << (off << 2));
data[w] |= (((uint64_t)val) << (off << 2));
}
inline void combine(T beta, const FastArray& b) {
for (size_t i = 0; i < words; i++) {
if (isZ4)
data[i] = (data[i] + ((beta * b.data[i]) & mask)) & mask;
else
data[i] = data[i] ^ ((clone * beta) & b.data[i]);
}
}
};
template <> struct Mapping< Ring::Z4<int> > : public FastArray<true> {
Mapping(const Mapping& x) : FastArray(x) {}
Mapping(size_t s = 0) : FastArray(s) {}
};
template <> struct Mapping< Ring::Z2_2<int> > : public FastArray<false> {
Mapping(const Mapping& x) : FastArray(x) {}
Mapping(size_t s = 0) : FastArray(s) {}
};
#endif
#endif