poulpy/poulpy-backend/src/cpu_spqlios/spqlios-arithmetic/spqlios/arithmetic/zn_api.c
poulpy-backend/src/cpu_spqlios/spqlios-arithmetic/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_prepare_dblptr = default_zn32_vmp_prepare_dblptr_ref;
20 module->vtable.zn32_vmp_prepare_row = default_zn32_vmp_prepare_row_ref;
21 module->vtable.zn32_vmp_apply_i8 = default_zn32_vmp_apply_i8_ref;
22 module->vtable.zn32_vmp_apply_i16 = default_zn32_vmp_apply_i16_ref;
23 module->vtable.zn32_vmp_apply_i32 = default_zn32_vmp_apply_i32_ref;
24 module->vtable.dbl_to_tn32 = dbl_to_tn32_ref;
25 module->vtable.tn32_to_dbl = tn32_to_dbl_ref;
26 module->vtable.dbl_round_to_i32 = dbl_round_to_i32_ref;
27 module->vtable.i32_to_dbl = i32_to_dbl_ref;
28 module->vtable.dbl_round_to_i64 = dbl_round_to_i64_ref;
29 module->vtable.i64_to_dbl = i64_to_dbl_ref;
30
31 // Add optimized function pointers here
32 if (CPU_SUPPORTS("avx")) {
33 module->vtable.zn32_vmp_apply_i8 = default_zn32_vmp_apply_i8_avx;
34 module->vtable.zn32_vmp_apply_i16 = default_zn32_vmp_apply_i16_avx;
35 module->vtable.zn32_vmp_apply_i32 = default_zn32_vmp_apply_i32_avx;
36 }
37}
38
39void init_z_module_info(MOD_Z* module, //
40 Z_MODULE_TYPE mtype) {
41 memset(module, 0, sizeof(MOD_Z));
42 module->mtype = mtype;
43 switch (mtype) {
44 case DEFAULT:
45 default_init_z_module_precomp(module);
46 default_init_z_module_vtable(module);
47 break;
48 default:
49 NOT_SUPPORTED(); // unknown mtype
50 }
51}
52
53void finalize_z_module_info(MOD_Z* module) {
54 if (module->custom) module->custom_deleter(module->custom);
55 switch (module->mtype) {
56 case DEFAULT:
57 default_finalize_z_module_precomp(module);
58 // fft64_finalize_rnx_module_vtable(module); // nothing to finalize
59 break;
60 default:
61 NOT_SUPPORTED(); // unknown mtype
62 }
63}
64
65EXPORT MOD_Z* new_z_module_info(Z_MODULE_TYPE mtype) {
66 MOD_Z* res = (MOD_Z*)malloc(sizeof(MOD_Z));
67 init_z_module_info(res, mtype);
68 return res;
69}
70
71EXPORT void delete_z_module_info(MOD_Z* module_info) {
72 finalize_z_module_info(module_info);
73 free(module_info);
74}
75
76//////////////// wrappers //////////////////
77
78/** @brief sets res = gadget_decompose(a) (int8_t* output) */
79EXPORT void i8_approxdecomp_from_tndbl(const MOD_Z* module, // N
80 const TNDBL_APPROXDECOMP_GADGET* gadget, // gadget
81 int8_t* res, uint64_t res_size, // res (in general, size ell.a_size)
82 const double* a, uint64_t a_size) { // a
83 module->vtable.i8_approxdecomp_from_tndbl(module, gadget, res, res_size, a, a_size);
84}
85
86/** @brief sets res = gadget_decompose(a) (int16_t* output) */
87EXPORT void i16_approxdecomp_from_tndbl(const MOD_Z* module, // N
88 const TNDBL_APPROXDECOMP_GADGET* gadget, // gadget
89 int16_t* res, uint64_t res_size, // res (in general, size ell.a_size)
90 const double* a, uint64_t a_size) { // a
91 module->vtable.i16_approxdecomp_from_tndbl(module, gadget, res, res_size, a, a_size);
92}
93/** @brief sets res = gadget_decompose(a) (int32_t* output) */
94EXPORT void i32_approxdecomp_from_tndbl(const MOD_Z* module, // N
95 const TNDBL_APPROXDECOMP_GADGET* gadget, // gadget
96 int32_t* res, uint64_t res_size, // res (in general, size ell.a_size)
97 const double* a, uint64_t a_size) { // a
98 module->vtable.i32_approxdecomp_from_tndbl(module, gadget, res, res_size, a, a_size);
99}
100
101/** @brief prepares a vmp matrix (contiguous row-major version) */
102EXPORT void zn32_vmp_prepare_contiguous(const MOD_Z* module,
103 ZN32_VMP_PMAT* pmat, // output
104 const int32_t* mat, uint64_t nrows, uint64_t ncols) { // a
105 module->vtable.zn32_vmp_prepare_contiguous(module, pmat, mat, nrows, ncols);
106}
107
108/** @brief prepares a vmp matrix (mat[row]+col*N points to the item) */
109EXPORT void zn32_vmp_prepare_dblptr(const MOD_Z* module,
110 ZN32_VMP_PMAT* pmat, // output
111 const int32_t** mat, uint64_t nrows, uint64_t ncols) { // a
112 module->vtable.zn32_vmp_prepare_dblptr(module, pmat, mat, nrows, ncols);
113}
114
115/** @brief prepares the ith-row of a vmp matrix with nrows and ncols */
116EXPORT void zn32_vmp_prepare_row(const MOD_Z* module,
117 ZN32_VMP_PMAT* pmat, // output
118 const int32_t* row, uint64_t row_i, uint64_t nrows, uint64_t ncols) { // a
119 module->vtable.zn32_vmp_prepare_row(module, pmat, row, row_i, nrows, ncols);
120}
121
122/** @brief applies a vmp product (int32_t* input) */
123EXPORT void zn32_vmp_apply_i32(const MOD_Z* module, int32_t* res, uint64_t res_size, const int32_t* a, uint64_t a_size,
124 const ZN32_VMP_PMAT* pmat, uint64_t nrows, uint64_t ncols) {
125 module->vtable.zn32_vmp_apply_i32(module, res, res_size, a, a_size, pmat, nrows, ncols);
126}
127/** @brief applies a vmp product (int16_t* input) */
128EXPORT void zn32_vmp_apply_i16(const MOD_Z* module, int32_t* res, uint64_t res_size, const int16_t* a, uint64_t a_size,
129 const ZN32_VMP_PMAT* pmat, uint64_t nrows, uint64_t ncols) {
130 module->vtable.zn32_vmp_apply_i16(module, res, res_size, a, a_size, pmat, nrows, ncols);
131}
132
133/** @brief applies a vmp product (int8_t* input) */
134EXPORT void zn32_vmp_apply_i8(const MOD_Z* module, int32_t* res, uint64_t res_size, const int8_t* a, uint64_t a_size,
135 const ZN32_VMP_PMAT* pmat, uint64_t nrows, uint64_t ncols) {
136 module->vtable.zn32_vmp_apply_i8(module, res, res_size, a, a_size, pmat, nrows, ncols);
137}
138
139/** reduction mod 1, output in torus32 space */
140EXPORT void dbl_to_tn32(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_to_tn32(module, res, res_size, a, a_size);
145}
146
147/** real centerlift mod 1, output in double space */
148EXPORT void tn32_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.tn32_to_dbl(module, res, res_size, a, a_size);
153}
154
155/** round to the nearest int, output in i32 space */
156EXPORT void dbl_round_to_i32(const MOD_Z* module, //
157 int32_t* res, uint64_t res_size, // res
158 const double* a, uint64_t a_size // a
159) {
160 module->vtable.dbl_round_to_i32(module, res, res_size, a, a_size);
161}
162
163/** small int (int32 space) to double */
164EXPORT void i32_to_dbl(const MOD_Z* module, //
165 double* res, uint64_t res_size, // res
166 const int32_t* a, uint64_t a_size // a
167) {
168 module->vtable.i32_to_dbl(module, res, res_size, a, a_size);
169}
170
171/** round to the nearest int, output in int64 space */
172EXPORT void dbl_round_to_i64(const MOD_Z* module, //
173 int64_t* res, uint64_t res_size, // res
174 const double* a, uint64_t a_size // a
175) {
176 module->vtable.dbl_round_to_i64(module, res, res_size, a, a_size);
177}
178
179/** small int (int64 space, <= 2^50) to double */
180EXPORT void i64_to_dbl(const MOD_Z* module, //
181 double* res, uint64_t res_size, // res
182 const int64_t* a, uint64_t a_size // a
183) {
184 module->vtable.i64_to_dbl(module, res, res_size, a, a_size);
185}