poulpy/poulpy-backend/src/cpu_spqlios/spqlios-arithmetic/test/testlib/polynomial_vector.cpp
poulpy-backend/src/cpu_spqlios/spqlios-arithmetic/test/testlib/polynomial_vector.cppRaw
1#include "polynomial_vector.h"
2
3#include <cstring>
4
5#ifdef VALGRIND_MEM_TESTS
6#include "valgrind/memcheck.h"
7#endif
8
9#define CANARY_PADDING (1024)
10#define GARBAGE_VALUE (242)
11
12znx_vec_i64_layout::znx_vec_i64_layout(uint64_t n, uint64_t size, uint64_t slice) : n(n), size(size), slice(slice) {
13 REQUIRE_DRAMATICALLY(is_pow2(n), "not a power of 2" << n);
14 REQUIRE_DRAMATICALLY(slice >= n, "slice too small" << slice << " < " << n);
15 this->region = (uint8_t*)malloc(size * slice * sizeof(int64_t) + 2 * CANARY_PADDING);
16 this->data_start = (int64_t*)(region + CANARY_PADDING);
17 // ensure that any invalid value is kind-of garbage
18 memset(region, GARBAGE_VALUE, size * slice * sizeof(int64_t) + 2 * CANARY_PADDING);
19 // mark inter-slice memory as non accessible
20#ifdef VALGRIND_MEM_TESTS
21 VALGRIND_MAKE_MEM_NOACCESS(region, CANARY_PADDING);
22 VALGRIND_MAKE_MEM_NOACCESS(region + size * slice * sizeof(int64_t) + CANARY_PADDING, CANARY_PADDING);
23 for (uint64_t i = 0; i < size; ++i) {
24 VALGRIND_MAKE_MEM_UNDEFINED(data_start + i * slice, n * sizeof(int64_t));
25 }
26 if (size != slice) {
27 for (uint64_t i = 0; i < size; ++i) {
28 VALGRIND_MAKE_MEM_NOACCESS(data_start + i * slice + n, (slice - n) * sizeof(int64_t));
29 }
30 }
31#endif
32}
33
34znx_vec_i64_layout::~znx_vec_i64_layout() { free(region); }
35
36znx_i64 znx_vec_i64_layout::get_copy_zext(uint64_t index) const {
37 if (index < size) {
38 return znx_i64(n, data_start + index * slice);
39 } else {
40 return znx_i64::zero(n);
41 }
42}
43
44znx_i64 znx_vec_i64_layout::get_copy(uint64_t index) const {
45 REQUIRE_DRAMATICALLY(index < size, "index overflow: " << index << " / " << size);
46 return znx_i64(n, data_start + index * slice);
47}
48
49void znx_vec_i64_layout::set(uint64_t index, const znx_i64& elem) {
50 REQUIRE_DRAMATICALLY(index < size, "index overflow: " << index << " / " << size);
51 REQUIRE_DRAMATICALLY(elem.nn() == n, "incompatible ring dimensions: " << elem.nn() << " / " << n);
52 elem.save_as(data_start + index * slice);
53}
54
55int64_t* znx_vec_i64_layout::data() { return data_start; }
56const int64_t* znx_vec_i64_layout::data() const { return data_start; }
57
58void znx_vec_i64_layout::fill_random(uint64_t bits) {
59 for (uint64_t i = 0; i < size; ++i) {
60 set(i, znx_i64::random_log2bound(n, bits));
61 }
62}
63__uint128_t znx_vec_i64_layout::content_hash() const {
64 test_hasher hasher;
65 for (uint64_t i = 0; i < size; ++i) {
66 hasher.update(data() + i * slice, n * sizeof(int64_t));
67 }
68 return hasher.hash();
69}