From 0134460a9535802cac9f8953a144bee53926a4e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Radek=20Hu=C5=A1ek?= <PitelVonSacek@gmail.com> Date: Wed, 9 Dec 2015 18:48:05 +0100 Subject: [PATCH] Add optimized versions of Mapping class Optimized versions are off by default --- Makefile | 2 +- compileTimeOptions.h | 14 ++++++++ fast-array.h | 82 ++++++++++++++++++++++++++++++++++++++++---- group-connectivity.h | 4 +-- 4 files changed, 93 insertions(+), 9 deletions(-) diff --git a/Makefile b/Makefile index 302acb9..27bc003 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ default: groupConnectivity.so clean_obj -groupConnectivity.so: groupConnectivity.pyx group-connectivity.h setup.py compileTimeOptions.h rings.h parmap.py +groupConnectivity.so: groupConnectivity.pyx group-connectivity.h setup.py compileTimeOptions.h rings.h fast-array.h parmap.py python setup.py build_ext cp build/lib*/groupConnectivity.so . diff --git a/compileTimeOptions.h b/compileTimeOptions.h index 6b47bc0..18f3a51 100644 --- a/compileTimeOptions.h +++ b/compileTimeOptions.h @@ -11,5 +11,19 @@ #pragma message "SAVE_MEMORY off" #endif + +#ifndef OPTIMIZED_MAPPINGS +#define OPTIMIZED_MAPPINGS 0 +#endif +#if OPTIMIZED_MAPPINGS +#pragma message "OPTIMIZED_MAPPINGS ON" +#else +#pragma message "OPTIMIZED_MAPPINGS off" +#endif + +#ifndef MAX_EDGES +#define MAX_EDGES 48 +#endif + #endif diff --git a/fast-array.h b/fast-array.h index b9e0090..9132595 100644 --- a/fast-array.h +++ b/fast-array.h @@ -1,29 +1,99 @@ #ifndef __FAST_ARRAY_H__ #define __FAST_ARRAY_H__ -template < typename Ring, size_t maxSize = 0 > +#include "rings.h" + +template < typename Ring > struct Mapping { typedef typename Ring::T T; std::vector<T> data; Mapping() {} - template < typename X > - Mapping(X x) : data(x.data) {} + Mapping(const Mapping& x) : data(x.data) {} - Mapping(size_t size = 0, T val = 0) : data(size, val) {} + 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; } - Mapping& combine(T beta, const Mapping& b) { + 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])); - return *this; } }; + +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]); + } + } +}; + +#if OPTIMIZED_MAPPINGS +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 diff --git a/group-connectivity.h b/group-connectivity.h index f127f81..1ac5ae1 100644 --- a/group-connectivity.h +++ b/group-connectivity.h @@ -65,7 +65,7 @@ struct Tester : public AbstractTester { classEdges.push_back(e - 1); for (const auto& elemCycle : elementaryCycles) { - nonClassEdges.push_back(std::make_pair(elemCycle[0] - 1, Mapping(edges, 0))); + nonClassEdges.push_back(std::make_pair(elemCycle[0] - 1, Mapping(edges))); Mapping &map = nonClassEdges.back().second; for (auto edge : elemCycle) { @@ -121,7 +121,7 @@ struct Tester : public AbstractTester { virtual bool run() { - Mapping forb(edges, 0); + Mapping forb(edges); for (size_t i = 0; i < numForb; i++) #if SAVE_MEMORY -- GitLab