arnaucube
arnaucube/poulpyPublic Self-hosted repository
poulpy/spqlios/lib/spqlios/arithmetic/zn_api.c
spqlios/lib/spqlios/arithmetic/zn_api.cRaw
  1#include <string.h>
  2
  3#include "zn_arithmetic_private.h"
  4
  5void default_init_z_module_precomp(MOD_Z* module) {
  6  // Add here initialization of items that are in the precomp
  7}
  8
  9void default_finalize_z_module_precomp(MOD_Z* module) {
 10  // Add here deleters for items that are in the precomp
 11}
 12
 13void default_init_z_module_vtable(MOD_Z* module) {
 14  // Add function pointers here
 15  module->vtable.i8_approxdecomp_from_tndbl = default_i8_approxdecomp_from_tndbl_ref;
 16  module->vtable.i16_approxdecomp_from_tndbl = default_i16_approxdecomp_from_tndbl_ref;
 17  module->vtable.i32_approxdecomp_from_tndbl = default_i32_approxdecomp_from_tndbl_ref;
 18  module->vtable.zn32_vmp_prepare_contiguous = default_zn32_vmp_prepare_contiguous_ref;
 19  module->vtable.zn32_vmp_apply_i8 = default_zn32_vmp_apply_i8_ref;
 20  module->vtable.zn32_vmp_apply_i16 = default_zn32_vmp_apply_i16_ref;
 21  module->vtable.zn32_vmp_apply_i32 = default_zn32_vmp_apply_i32_ref;
 22  module->vtable.dbl_to_tn32 = dbl_to_tn32_ref;
 23  module->vtable.tn32_to_dbl = tn32_to_dbl_ref;
 24  module->vtable.dbl_round_to_i32 = dbl_round_to_i32_ref;
 25  module->vtable.i32_to_dbl = i32_to_dbl_ref;
 26  module->vtable.dbl_round_to_i64 = dbl_round_to_i64_ref;
 27  module->vtable.i64_to_dbl = i64_to_dbl_ref;
 28
 29  // Add optimized function pointers here
 30  if (CPU_SUPPORTS("avx")) {
 31    module->vtable.zn32_vmp_apply_i8 = default_zn32_vmp_apply_i8_avx;
 32    module->vtable.zn32_vmp_apply_i16 = default_zn32_vmp_apply_i16_avx;
 33    module->vtable.zn32_vmp_apply_i32 = default_zn32_vmp_apply_i32_avx;
 34  }
 35}
 36
 37void init_z_module_info(MOD_Z* module,  //
 38                        Z_MODULE_TYPE mtype) {
 39  memset(module, 0, sizeof(MOD_Z));
 40  module->mtype = mtype;
 41  switch (mtype) {
 42    case DEFAULT:
 43      default_init_z_module_precomp(module);
 44      default_init_z_module_vtable(module);
 45      break;
 46    default:
 47      NOT_SUPPORTED();  // unknown mtype
 48  }
 49}
 50
 51void finalize_z_module_info(MOD_Z* module) {
 52  if (module->custom) module->custom_deleter(module->custom);
 53  switch (module->mtype) {
 54    case DEFAULT:
 55      default_finalize_z_module_precomp(module);
 56      // fft64_finalize_rnx_module_vtable(module); // nothing to finalize
 57      break;
 58    default:
 59      NOT_SUPPORTED();  // unknown mtype
 60  }
 61}
 62
 63EXPORT MOD_Z* new_z_module_info(Z_MODULE_TYPE mtype) {
 64  MOD_Z* res = (MOD_Z*)malloc(sizeof(MOD_Z));
 65  init_z_module_info(res, mtype);
 66  return res;
 67}
 68
 69EXPORT void delete_z_module_info(MOD_Z* module_info) {
 70  finalize_z_module_info(module_info);
 71  free(module_info);
 72}
 73
 74//////////////// wrappers //////////////////
 75
 76/** @brief sets res = gadget_decompose(a) (int8_t* output) */
 77EXPORT void i8_approxdecomp_from_tndbl(const MOD_Z* module,                      // N
 78                                       const TNDBL_APPROXDECOMP_GADGET* gadget,  // gadget
 79                                       int8_t* res, uint64_t res_size,           // res (in general, size ell.a_size)
 80                                       const double* a, uint64_t a_size) {       // a
 81  module->vtable.i8_approxdecomp_from_tndbl(module, gadget, res, res_size, a, a_size);
 82}
 83
 84/** @brief sets res = gadget_decompose(a) (int16_t* output) */
 85EXPORT void i16_approxdecomp_from_tndbl(const MOD_Z* module,                      // N
 86                                        const TNDBL_APPROXDECOMP_GADGET* gadget,  // gadget
 87                                        int16_t* res, uint64_t res_size,          // res (in general, size ell.a_size)
 88                                        const double* a, uint64_t a_size) {       // a
 89  module->vtable.i16_approxdecomp_from_tndbl(module, gadget, res, res_size, a, a_size);
 90}
 91/** @brief sets res = gadget_decompose(a) (int32_t* output) */
 92EXPORT void i32_approxdecomp_from_tndbl(const MOD_Z* module,                      // N
 93                                        const TNDBL_APPROXDECOMP_GADGET* gadget,  // gadget
 94                                        int32_t* res, uint64_t res_size,          // res (in general, size ell.a_size)
 95                                        const double* a, uint64_t a_size) {       // a
 96  module->vtable.i32_approxdecomp_from_tndbl(module, gadget, res, res_size, a, a_size);
 97}
 98
 99EXPORT void zn32_vmp_prepare_contiguous(  //
100    const MOD_Z* module,
101    ZN32_VMP_PMAT* pmat,                                   // output
102    const int32_t* mat, uint64_t nrows, uint64_t ncols) {  // a
103  module->vtable.zn32_vmp_prepare_contiguous(module, pmat, mat, nrows, ncols);
104}
105
106/** @brief applies a vmp product (int32_t* input) */
107EXPORT void zn32_vmp_apply_i32(const MOD_Z* module, int32_t* res, uint64_t res_size, const int32_t* a, uint64_t a_size,
108                               const ZN32_VMP_PMAT* pmat, uint64_t nrows, uint64_t ncols) {
109  module->vtable.zn32_vmp_apply_i32(module, res, res_size, a, a_size, pmat, nrows, ncols);
110}
111/** @brief applies a vmp product (int16_t* input) */
112EXPORT void zn32_vmp_apply_i16(const MOD_Z* module, int32_t* res, uint64_t res_size, const int16_t* a, uint64_t a_size,
113                               const ZN32_VMP_PMAT* pmat, uint64_t nrows, uint64_t ncols) {
114  module->vtable.zn32_vmp_apply_i16(module, res, res_size, a, a_size, pmat, nrows, ncols);
115}
116
117/** @brief applies a vmp product (int8_t* input) */
118EXPORT void zn32_vmp_apply_i8(const MOD_Z* module, int32_t* res, uint64_t res_size, const int8_t* a, uint64_t a_size,
119                              const ZN32_VMP_PMAT* pmat, uint64_t nrows, uint64_t ncols) {
120  module->vtable.zn32_vmp_apply_i8(module, res, res_size, a, a_size, pmat, nrows, ncols);
121}
122
123/** reduction mod 1, output in torus32 space */
124EXPORT void dbl_to_tn32(const MOD_Z* module,              //
125                        int32_t* res, uint64_t res_size,  // res
126                        const double* a, uint64_t a_size  // a
127) {
128  module->vtable.dbl_to_tn32(module, res, res_size, a, a_size);
129}
130
131/** real centerlift mod 1, output in double space */
132EXPORT void tn32_to_dbl(const MOD_Z* module,               //
133                        double* res, uint64_t res_size,    // res
134                        const int32_t* a, uint64_t a_size  // a
135) {
136  module->vtable.tn32_to_dbl(module, res, res_size, a, a_size);
137}
138
139/** round to the nearest int, output in i32 space */
140EXPORT void dbl_round_to_i32(const MOD_Z* module,              //
141                             int32_t* res, uint64_t res_size,  // res
142                             const double* a, uint64_t a_size  // a
143) {
144  module->vtable.dbl_round_to_i32(module, res, res_size, a, a_size);
145}
146
147/** small int (int32 space) to double */
148EXPORT void i32_to_dbl(const MOD_Z* module,               //
149                       double* res, uint64_t res_size,    // res
150                       const int32_t* a, uint64_t a_size  // a
151) {
152  module->vtable.i32_to_dbl(module, res, res_size, a, a_size);
153}
154
155/** round to the nearest int, output in int64 space */
156EXPORT void dbl_round_to_i64(const MOD_Z* module,              //
157                             int64_t* res, uint64_t res_size,  // res
158                             const double* a, uint64_t a_size  // a
159) {
160  module->vtable.dbl_round_to_i64(module, res, res_size, a, a_size);
161}
162
163/** small int (int64 space, <= 2^50) to double */
164EXPORT void i64_to_dbl(const MOD_Z* module,               //
165                       double* res, uint64_t res_size,    // res
166                       const int64_t* a, uint64_t a_size  // a
167) {
168  module->vtable.i64_to_dbl(module, res, res_size, a, a_size);
169}