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}