arnaucube
arnaucube/poulpyPublic Self-hosted repository
poulpy/poulpy-backend/src/cpu_spqlios/spqlios-arithmetic/test/spqlios_coeffs_arithmetic_test.cpp
poulpy-backend/src/cpu_spqlios/spqlios-arithmetic/test/spqlios_coeffs_arithmetic_test.cppRaw
  1#include <gtest/gtest.h>
  2#include <sys/types.h>
  3
  4#include <cstdint>
  5#include <limits>
  6#include <random>
  7#include <vector>
  8
  9#include "../spqlios/coeffs/coeffs_arithmetic.h"
 10#include "test/testlib/mod_q120.h"
 11#include "testlib/negacyclic_polynomial.h"
 12#include "testlib/test_commons.h"
 13
 14/// tests of element-wise operations
 15template <typename T, typename F, typename G>
 16void test_elemw_op(F elemw_op, G poly_elemw_op) {
 17  for (uint64_t n : {1, 2, 4, 8, 16, 64, 256, 4096}) {
 18    polynomial<T> a = polynomial<T>::random(n);
 19    polynomial<T> b = polynomial<T>::random(n);
 20    polynomial<T> expect(n);
 21    polynomial<T> actual(n);
 22    // out of place
 23    expect = poly_elemw_op(a, b);
 24    elemw_op(n, actual.data(), a.data(), b.data());
 25    ASSERT_EQ(actual, expect);
 26    // in place 1
 27    actual = polynomial<T>::random(n);
 28    expect = poly_elemw_op(actual, b);
 29    elemw_op(n, actual.data(), actual.data(), b.data());
 30    ASSERT_EQ(actual, expect);
 31    // in place 2
 32    actual = polynomial<T>::random(n);
 33    expect = poly_elemw_op(a, actual);
 34    elemw_op(n, actual.data(), a.data(), actual.data());
 35    ASSERT_EQ(actual, expect);
 36    // in place 3
 37    actual = polynomial<T>::random(n);
 38    expect = poly_elemw_op(actual, actual);
 39    elemw_op(n, actual.data(), actual.data(), actual.data());
 40    ASSERT_EQ(actual, expect);
 41  }
 42}
 43
 44static polynomial<int64_t> poly_i64_add(const polynomial<int64_t>& u, polynomial<int64_t>& v) { return u + v; }
 45static polynomial<int64_t> poly_i64_sub(const polynomial<int64_t>& u, polynomial<int64_t>& v) { return u - v; }
 46TEST(coeffs_arithmetic, znx_add_i64_ref) { test_elemw_op<int64_t>(znx_add_i64_ref, poly_i64_add); }
 47TEST(coeffs_arithmetic, znx_sub_i64_ref) { test_elemw_op<int64_t>(znx_sub_i64_ref, poly_i64_sub); }
 48#ifdef __x86_64__
 49TEST(coeffs_arithmetic, znx_add_i64_avx) { test_elemw_op<int64_t>(znx_add_i64_avx, poly_i64_add); }
 50TEST(coeffs_arithmetic, znx_sub_i64_avx) { test_elemw_op<int64_t>(znx_sub_i64_avx, poly_i64_sub); }
 51#endif
 52
 53/// tests of element-wise operations
 54template <typename T, typename F, typename G>
 55void test_elemw_unary_op(F elemw_op, G poly_elemw_op) {
 56  for (uint64_t n : {1, 2, 4, 8, 16, 64, 256, 4096}) {
 57    polynomial<T> a = polynomial<T>::random(n);
 58    polynomial<T> expect(n);
 59    polynomial<T> actual(n);
 60    // out of place
 61    expect = poly_elemw_op(a);
 62    elemw_op(n, actual.data(), a.data());
 63    ASSERT_EQ(actual, expect);
 64    // in place
 65    actual = polynomial<T>::random(n);
 66    expect = poly_elemw_op(actual);
 67    elemw_op(n, actual.data(), actual.data());
 68    ASSERT_EQ(actual, expect);
 69  }
 70}
 71
 72static polynomial<int64_t> poly_i64_neg(const polynomial<int64_t>& u) { return -u; }
 73static polynomial<int64_t> poly_i64_copy(const polynomial<int64_t>& u) { return u; }
 74TEST(coeffs_arithmetic, znx_neg_i64_ref) { test_elemw_unary_op<int64_t>(znx_negate_i64_ref, poly_i64_neg); }
 75TEST(coeffs_arithmetic, znx_copy_i64_ref) { test_elemw_unary_op<int64_t>(znx_copy_i64_ref, poly_i64_copy); }
 76#ifdef __x86_64__
 77TEST(coeffs_arithmetic, znx_neg_i64_avx) { test_elemw_unary_op<int64_t>(znx_negate_i64_avx, poly_i64_neg); }
 78#endif
 79
 80/// tests of the rotations out of place
 81template <typename T, typename F>
 82void test_rotation_outplace(F rotate) {
 83  for (uint64_t n : {1, 2, 4, 8, 16, 64, 256, 4096}) {
 84    polynomial<T> poly = polynomial<T>::random(n);
 85    polynomial<T> expect(n);
 86    polynomial<T> actual(n);
 87    for (uint64_t trial = 0; trial < 10; ++trial) {
 88      int64_t p = uniform_i64_bits(32);
 89      // rotate by p
 90      for (uint64_t i = 0; i < n; ++i) {
 91        expect.set_coeff(i, poly.get_coeff(i - p));
 92      }
 93      // rotate using the function
 94      rotate(n, p, actual.data(), poly.data());
 95      ASSERT_EQ(actual, expect);
 96    }
 97  }
 98}
 99
100TEST(coeffs_arithmetic, rnx_rotate_f64) { test_rotation_outplace<double>(rnx_rotate_f64); }
101TEST(coeffs_arithmetic, znx_rotate_i64) { test_rotation_outplace<int64_t>(znx_rotate_i64); }
102
103/// tests of the rotations out of place
104template <typename T, typename F>
105void test_rotation_inplace(F rotate) {
106  for (uint64_t n : {1, 2, 4, 8, 16, 64, 256, 4096}) {
107    polynomial<T> poly = polynomial<T>::random(n);
108    polynomial<T> expect(n);
109    for (uint64_t trial = 0; trial < 10; ++trial) {
110      polynomial<T> actual = poly;
111      int64_t p = uniform_i64_bits(32);
112      // rotate by p
113      for (uint64_t i = 0; i < n; ++i) {
114        expect.set_coeff(i, poly.get_coeff(i - p));
115      }
116      // rotate using the function
117      rotate(n, p, actual.data());
118      ASSERT_EQ(actual, expect);
119    }
120  }
121}
122
123TEST(coeffs_arithmetic, rnx_rotate_inplace_f64) { test_rotation_inplace<double>(rnx_rotate_inplace_f64); }
124
125TEST(coeffs_arithmetic, znx_rotate_inplace_i64) { test_rotation_inplace<int64_t>(znx_rotate_inplace_i64); }
126
127/// tests of the rotations out of place
128template <typename T, typename F>
129void test_mul_xp_minus_one_outplace(F rotate) {
130  for (uint64_t n : {1, 2, 4, 8, 16, 64, 256, 4096}) {
131    polynomial<T> poly = polynomial<T>::random(n);
132    polynomial<T> expect(n);
133    polynomial<T> actual(n);
134    for (uint64_t trial = 0; trial < 10; ++trial) {
135      int64_t p = uniform_i64_bits(32);
136      // rotate by p
137      for (uint64_t i = 0; i < n; ++i) {
138        expect.set_coeff(i, poly.get_coeff(i - p) - poly.get_coeff(i));
139      }
140      // rotate using the function
141      rotate(n, p, actual.data(), poly.data());
142      ASSERT_EQ(actual, expect);
143    }
144  }
145}
146
147TEST(coeffs_arithmetic, rnx_mul_xp_minus_one_f64) { test_mul_xp_minus_one_outplace<double>(rnx_mul_xp_minus_one_f64); }
148TEST(coeffs_arithmetic, znx_mul_xp_minus_one_i64) { test_mul_xp_minus_one_outplace<int64_t>(znx_mul_xp_minus_one_i64); }
149
150/// tests of the rotations out of place
151template <typename T, typename F>
152void test_mul_xp_minus_one_inplace(F rotate) {
153  for (uint64_t n : {1, 2, 4, 8, 16, 64, 256, 4096}) {
154    polynomial<T> poly = polynomial<T>::random(n);
155    polynomial<T> expect(n);
156    for (uint64_t trial = 0; trial < 10; ++trial) {
157      polynomial<T> actual = poly;
158      int64_t p = uniform_i64_bits(32);
159      // rotate by p
160      for (uint64_t i = 0; i < n; ++i) {
161        expect.set_coeff(i, poly.get_coeff(i - p) - poly.get_coeff(i));
162      }
163      // rotate using the function
164      rotate(n, p, actual.data());
165      ASSERT_EQ(actual, expect);
166    }
167  }
168}
169
170TEST(coeffs_arithmetic, rnx_mul_xp_minus_one_inplace_f64) {
171  test_mul_xp_minus_one_inplace<double>(rnx_mul_xp_minus_one_inplace_f64);
172}
173
174// TEST(coeffs_arithmetic, znx_mul_xp_minus_one_inplace_i64) {
175// test_mul_xp_minus_one_inplace<int64_t>(znx_rotate_inplace_i64); }
176/// tests of the automorphisms out of place
177template <typename T, typename F>
178void test_automorphism_outplace(F automorphism) {
179  for (uint64_t n : {1, 2, 4, 8, 16, 64, 256, 4096}) {
180    polynomial<T> poly = polynomial<T>::random(n);
181    polynomial<T> expect(n);
182    polynomial<T> actual(n);
183    for (uint64_t trial = 0; trial < 10; ++trial) {
184      int64_t p = uniform_i64_bits(32) | int64_t(1);  // make it odd
185      // automorphism p
186      for (uint64_t i = 0; i < n; ++i) {
187        expect.set_coeff(i * p, poly.get_coeff(i));
188      }
189      // rotate using the function
190      automorphism(n, p, actual.data(), poly.data());
191      ASSERT_EQ(actual, expect);
192    }
193  }
194}
195
196TEST(coeffs_arithmetic, rnx_automorphism_f64) { test_automorphism_outplace<double>(rnx_automorphism_f64); }
197TEST(coeffs_arithmetic, znx_automorphism_i64) { test_automorphism_outplace<int64_t>(znx_automorphism_i64); }
198
199/// tests of the automorphisms out of place
200template <typename T, typename F>
201void test_automorphism_inplace(F automorphism) {
202  for (uint64_t n : {1, 2, 4, 8, 16, 64, 256, 4096, 16384}) {
203    polynomial<T> poly = polynomial<T>::random(n);
204    polynomial<T> expect(n);
205    for (uint64_t trial = 0; trial < 20; ++trial) {
206      polynomial<T> actual = poly;
207      int64_t p = uniform_i64_bits(32) | int64_t(1);  // make it odd
208      // automorphism p
209      for (uint64_t i = 0; i < n; ++i) {
210        expect.set_coeff(i * p, poly.get_coeff(i));
211      }
212      automorphism(n, p, actual.data());
213      if (!(actual == expect)) {
214        std::cerr << "automorphism p: " << p << std::endl;
215        for (uint64_t i = 0; i < n; ++i) {
216          std::cerr << i << " " << actual.get_coeff(i) << " vs " << expect.get_coeff(i) << " "
217                    << (actual.get_coeff(i) == expect.get_coeff(i)) << std::endl;
218        }
219      }
220      ASSERT_EQ(actual, expect);
221    }
222  }
223}
224TEST(coeffs_arithmetic, rnx_automorphism_inplace_f64) {
225  test_automorphism_inplace<double>(rnx_automorphism_inplace_f64);
226}
227TEST(coeffs_arithmetic, znx_automorphism_inplace_i64) {
228  test_automorphism_inplace<int64_t>(znx_automorphism_inplace_i64);
229}
230
231// TODO: write a test later!
232
233/**
234 * @brief res = (X^p-1).in
235 * @param nn the ring dimension
236 * @param p must be between -2nn <= p <= 2nn
237 * @param in is a rnx/znx vector of dimension nn
238 */
239EXPORT void rnx_mul_xp_minus_one(uint64_t nn, int64_t p, double* res, const double* in);
240EXPORT void znx_mul_xp_minus_one(uint64_t nn, int64_t p, int64_t* res, const int64_t* in);
241
242// normalize with no carry in nor carry out
243template <uint8_t inplace_flag, typename F>
244void test_znx_normalize(F normalize) {
245  for (const uint64_t n : {1, 2, 4, 8, 16, 64, 256, 4096}) {
246    polynomial<int64_t> inp = znx_i64::random_log2bound(n, 62);
247    if (n >= 2) {
248      inp.set_coeff(0, -(INT64_C(1) << 62));
249      inp.set_coeff(1, (INT64_C(1) << 62));
250    }
251    for (const uint64_t base_k : {2, 3, 19, 35, 62}) {
252      polynomial<int64_t> out;
253      int64_t* inp_ptr;
254      if (inplace_flag == 1) {
255        out = polynomial<int64_t>(inp);
256        inp_ptr = out.data();
257      } else {
258        out = polynomial<int64_t>(n);
259        inp_ptr = inp.data();
260      }
261
262      znx_normalize(n, base_k, out.data(), nullptr, inp_ptr, nullptr);
263      for (uint64_t i = 0; i < n; ++i) {
264        const int64_t x = inp.get_coeff(i);
265        const int64_t y = out.get_coeff(i);
266        const int64_t y_exp = centermod(x, INT64_C(1) << base_k);
267        ASSERT_EQ(y, y_exp) << n << " " << base_k << " " << i << " " << x << " " << y;
268      }
269    }
270  }
271}
272
273TEST(coeffs_arithmetic, znx_normalize_outplace) { test_znx_normalize<0>(znx_normalize); }
274TEST(coeffs_arithmetic, znx_normalize_inplace) { test_znx_normalize<1>(znx_normalize); }
275
276// normalize with no carry in nor carry out
277template <uint8_t inplace_flag, bool has_output, typename F>
278void test_znx_normalize_cout(F normalize) {
279  static_assert(inplace_flag < 3, "either out or cout can be inplace with inp");
280  for (const uint64_t n : {1, 2, 4, 8, 16, 64, 256, 4096}) {
281    polynomial<int64_t> inp = znx_i64::random_log2bound(n, 62);
282    if (n >= 2) {
283      inp.set_coeff(0, -(INT64_C(1) << 62));
284      inp.set_coeff(1, (INT64_C(1) << 62));
285    }
286    for (const uint64_t base_k : {2, 3, 19, 35, 62}) {
287      polynomial<int64_t> out, cout;
288      int64_t* inp_ptr;
289      if (inplace_flag == 1) {
290        // out and inp are the same
291        out = polynomial<int64_t>(inp);
292        inp_ptr = out.data();
293        cout = polynomial<int64_t>(n);
294      } else if (inplace_flag == 2) {
295        // carry out and inp are the same
296        cout = polynomial<int64_t>(inp);
297        inp_ptr = cout.data();
298        out = polynomial<int64_t>(n);
299      } else {
300        // inp, out and carry out are distinct
301        out = polynomial<int64_t>(n);
302        cout = polynomial<int64_t>(n);
303        inp_ptr = inp.data();
304      }
305
306      znx_normalize(n, base_k, has_output ? out.data() : nullptr, cout.data(), inp_ptr, nullptr);
307      for (uint64_t i = 0; i < n; ++i) {
308        const int64_t x = inp.get_coeff(i);
309        const int64_t co = cout.get_coeff(i);
310        const int64_t y_exp = centermod((int64_t)x, INT64_C(1) << base_k);
311        const int64_t co_exp = (x - y_exp) >> base_k;
312        ASSERT_EQ(co, co_exp);
313
314        if (has_output) {
315          const int64_t y = out.get_coeff(i);
316          ASSERT_EQ(y, y_exp);
317        }
318      }
319    }
320  }
321}
322
323TEST(coeffs_arithmetic, znx_normalize_cout_outplace) { test_znx_normalize_cout<0, false>(znx_normalize); }
324TEST(coeffs_arithmetic, znx_normalize_out_cout_outplace) { test_znx_normalize_cout<0, true>(znx_normalize); }
325TEST(coeffs_arithmetic, znx_normalize_cout_inplace1) { test_znx_normalize_cout<1, false>(znx_normalize); }
326TEST(coeffs_arithmetic, znx_normalize_out_cout_inplace1) { test_znx_normalize_cout<1, true>(znx_normalize); }
327TEST(coeffs_arithmetic, znx_normalize_cout_inplace2) { test_znx_normalize_cout<2, false>(znx_normalize); }
328TEST(coeffs_arithmetic, znx_normalize_out_cout_inplace2) { test_znx_normalize_cout<2, true>(znx_normalize); }
329
330// normalize with no carry in nor carry out
331template <uint8_t inplace_flag, typename F>
332void test_znx_normalize_cin(F normalize) {
333  static_assert(inplace_flag < 3, "either inp or cin can be inplace with out");
334  for (const uint64_t n : {1, 2, 4, 8, 16, 64, 256, 4096}) {
335    polynomial<int64_t> inp = znx_i64::random_log2bound(n, 62);
336    if (n >= 4) {
337      inp.set_coeff(0, -(INT64_C(1) << 62));
338      inp.set_coeff(1, -(INT64_C(1) << 62));
339      inp.set_coeff(2, (INT64_C(1) << 62));
340      inp.set_coeff(3, (INT64_C(1) << 62));
341    }
342    for (const uint64_t base_k : {2, 3, 19, 35, 62}) {
343      polynomial<int64_t> cin = znx_i64::random_log2bound(n, 62);
344      if (n >= 4) {
345        inp.set_coeff(0, -(INT64_C(1) << 62));
346        inp.set_coeff(1, (INT64_C(1) << 62));
347        inp.set_coeff(0, -(INT64_C(1) << 62));
348        inp.set_coeff(1, (INT64_C(1) << 62));
349      }
350
351      polynomial<int64_t> out;
352      int64_t *inp_ptr, *cin_ptr;
353      if (inplace_flag == 1) {
354        // out and inp are the same
355        out = polynomial<int64_t>(inp);
356        inp_ptr = out.data();
357        cin_ptr = cin.data();
358      } else if (inplace_flag == 2) {
359        // out and carry in are the same
360        out = polynomial<int64_t>(cin);
361        inp_ptr = inp.data();
362        cin_ptr = out.data();
363      } else {
364        // inp, carry in and out are distinct
365        out = polynomial<int64_t>(n);
366        inp_ptr = inp.data();
367        cin_ptr = cin.data();
368      }
369
370      znx_normalize(n, base_k, out.data(), nullptr, inp_ptr, cin_ptr);
371      for (uint64_t i = 0; i < n; ++i) {
372        const int64_t x = inp.get_coeff(i);
373        const int64_t ci = cin.get_coeff(i);
374        const int64_t y = out.get_coeff(i);
375
376        const __int128_t xp = (__int128_t)x + ci;
377        const int64_t y_exp = centermod((int64_t)xp, INT64_C(1) << base_k);
378
379        ASSERT_EQ(y, y_exp) << n << " " << base_k << " " << i << " " << x << " " << y << " " << ci;
380      }
381    }
382  }
383}
384
385TEST(coeffs_arithmetic, znx_normalize_cin_outplace) { test_znx_normalize_cin<0>(znx_normalize); }
386TEST(coeffs_arithmetic, znx_normalize_cin_inplace1) { test_znx_normalize_cin<1>(znx_normalize); }
387TEST(coeffs_arithmetic, znx_normalize_cin_inplace2) { test_znx_normalize_cin<2>(znx_normalize); }
388
389// normalize with no carry in nor carry out
390template <uint8_t inplace_flag, bool has_output, typename F>
391void test_znx_normalize_cin_cout(F normalize) {
392  static_assert(inplace_flag < 7, "either inp or cin can be inplace with out");
393  for (const uint64_t n : {1, 2, 4, 8, 16, 64, 256, 4096}) {
394    polynomial<int64_t> inp = znx_i64::random_log2bound(n, 62);
395    if (n >= 4) {
396      inp.set_coeff(0, -(INT64_C(1) << 62));
397      inp.set_coeff(1, -(INT64_C(1) << 62));
398      inp.set_coeff(2, (INT64_C(1) << 62));
399      inp.set_coeff(3, (INT64_C(1) << 62));
400    }
401    for (const uint64_t base_k : {2, 3, 19, 35, 62}) {
402      polynomial<int64_t> cin = znx_i64::random_log2bound(n, 62);
403      if (n >= 4) {
404        inp.set_coeff(0, -(INT64_C(1) << 62));
405        inp.set_coeff(1, (INT64_C(1) << 62));
406        inp.set_coeff(0, -(INT64_C(1) << 62));
407        inp.set_coeff(1, (INT64_C(1) << 62));
408      }
409
410      polynomial<int64_t> out, cout;
411      int64_t *inp_ptr, *cin_ptr;
412      if (inplace_flag == 1) {
413        // out == inp
414        out = polynomial<int64_t>(inp);
415        cout = polynomial<int64_t>(n);
416        inp_ptr = out.data();
417        cin_ptr = cin.data();
418      } else if (inplace_flag == 2) {
419        // cout == inp
420        out = polynomial<int64_t>(n);
421        cout = polynomial<int64_t>(inp);
422        inp_ptr = cout.data();
423        cin_ptr = cin.data();
424      } else if (inplace_flag == 3) {
425        // out == cin
426        out = polynomial<int64_t>(cin);
427        cout = polynomial<int64_t>(n);
428        inp_ptr = inp.data();
429        cin_ptr = out.data();
430      } else if (inplace_flag == 4) {
431        // cout == cin
432        out = polynomial<int64_t>(n);
433        cout = polynomial<int64_t>(cin);
434        inp_ptr = inp.data();
435        cin_ptr = cout.data();
436      } else if (inplace_flag == 5) {
437        // out == inp, cout == cin
438        out = polynomial<int64_t>(inp);
439        cout = polynomial<int64_t>(cin);
440        inp_ptr = out.data();
441        cin_ptr = cout.data();
442      } else if (inplace_flag == 6) {
443        // out == cin, cout == inp
444        out = polynomial<int64_t>(cin);
445        cout = polynomial<int64_t>(inp);
446        inp_ptr = cout.data();
447        cin_ptr = out.data();
448      } else {
449        out = polynomial<int64_t>(n);
450        cout = polynomial<int64_t>(n);
451        inp_ptr = inp.data();
452        cin_ptr = cin.data();
453      }
454
455      znx_normalize(n, base_k, has_output ? out.data() : nullptr, cout.data(), inp_ptr, cin_ptr);
456      for (uint64_t i = 0; i < n; ++i) {
457        const int64_t x = inp.get_coeff(i);
458        const int64_t ci = cin.get_coeff(i);
459        const int64_t co = cout.get_coeff(i);
460
461        const __int128_t xp = (__int128_t)x + ci;
462        const int64_t y_exp = centermod((int64_t)xp, INT64_C(1) << base_k);
463        const int64_t co_exp = (xp - y_exp) >> base_k;
464        ASSERT_EQ(co, co_exp);
465
466        if (has_output) {
467          const int64_t y = out.get_coeff(i);
468          ASSERT_EQ(y, y_exp);
469        }
470      }
471    }
472  }
473}
474
475TEST(coeffs_arithmetic, znx_normalize_cin_cout_outplace) { test_znx_normalize_cin_cout<0, false>(znx_normalize); }
476TEST(coeffs_arithmetic, znx_normalize_out_cin_cout_outplace) { test_znx_normalize_cin_cout<0, true>(znx_normalize); }
477TEST(coeffs_arithmetic, znx_normalize_cin_cout_inplace1) { test_znx_normalize_cin_cout<1, false>(znx_normalize); }
478TEST(coeffs_arithmetic, znx_normalize_out_cin_cout_inplace1) { test_znx_normalize_cin_cout<1, true>(znx_normalize); }
479TEST(coeffs_arithmetic, znx_normalize_cin_cout_inplace2) { test_znx_normalize_cin_cout<2, false>(znx_normalize); }
480TEST(coeffs_arithmetic, znx_normalize_out_cin_cout_inplace2) { test_znx_normalize_cin_cout<2, true>(znx_normalize); }
481TEST(coeffs_arithmetic, znx_normalize_cin_cout_inplace3) { test_znx_normalize_cin_cout<3, false>(znx_normalize); }
482TEST(coeffs_arithmetic, znx_normalize_out_cin_cout_inplace3) { test_znx_normalize_cin_cout<3, true>(znx_normalize); }
483TEST(coeffs_arithmetic, znx_normalize_cin_cout_inplace4) { test_znx_normalize_cin_cout<4, false>(znx_normalize); }
484TEST(coeffs_arithmetic, znx_normalize_out_cin_cout_inplace4) { test_znx_normalize_cin_cout<4, true>(znx_normalize); }
485TEST(coeffs_arithmetic, znx_normalize_cin_cout_inplace5) { test_znx_normalize_cin_cout<5, false>(znx_normalize); }
486TEST(coeffs_arithmetic, znx_normalize_out_cin_cout_inplace5) { test_znx_normalize_cin_cout<5, true>(znx_normalize); }
487TEST(coeffs_arithmetic, znx_normalize_cin_cout_inplace6) { test_znx_normalize_cin_cout<6, false>(znx_normalize); }
488TEST(coeffs_arithmetic, znx_normalize_out_cin_cout_inplace6) { test_znx_normalize_cin_cout<6, true>(znx_normalize); }