1 #ifndef LINGEN_POLYMAT_HPP_ 2 #define LINGEN_POLYMAT_HPP_ 3 4 #ifdef SELECT_MPFQ_LAYER_u64k1 5 #error "lingen_polymat does not work with binary (maybe use bblas instead -- could end up being the same interface, IDK)" 6 #endif 7 8 #include <cstddef> // for size_t, NULL 9 #include <gmp.h> // for gmp_randstate_t 10 #include "mpfq_layer.h" 11 #include "macros.h" 12 13 class matpoly; 14 15 /* This is used only for lingen. */ 16 struct polymat { 17 abdst_field ab = NULL; 18 unsigned int m = 0; 19 unsigned int n = 0; 20 private: 21 size_t size = 0; 22 size_t alloc = 0; 23 public: capacitypolymat24 inline size_t capacity() const { return alloc; } get_sizepolymat25 inline size_t get_size() const { return size; } set_sizepolymat26 void set_size(size_t s) { size = s; } 27 abvec x = NULL; 28 polymatpolymat29 polymat() : polymat(NULL, 0,0,0) {} 30 polymat(polymat const&) = delete; 31 polymat& operator=(polymat const&) = delete; 32 polymat(polymat &&); 33 polymat& operator=(polymat &&); 34 ~polymat(); 35 polymat(abdst_field ab, unsigned int m, unsigned int n, int len); 36 int check_pre_init() const; 37 void realloc(size_t newalloc); 38 void zero(); 39 #if 0 40 void swap(polymat & b); 41 #endif 42 void fill_random(unsigned int nsize, gmp_randstate_t rstate); 43 int cmp(polymat const & b); 44 45 /* {{{ access interface for polymat */ partpolymat46 inline abdst_vec part(unsigned int i, unsigned int j, unsigned int k) { 47 /* Assume row-major in all circumstances. Old code used to support 48 * various orderings, here we don't */ 49 ASSERT_ALWAYS(size); 50 return abvec_subvec(ab, x, (k*m+i)*n+j); 51 } coeffpolymat52 inline abdst_elt coeff(unsigned int i, unsigned int j, unsigned int k) { 53 return abvec_coeff_ptr(ab, part(i,j,k),0); 54 } partpolymat55 inline absrc_vec part(unsigned int i, unsigned int j, unsigned int k) const { 56 /* Assume row-major in all circumstances. Old code used to support 57 * various orderings, here we don't */ 58 ASSERT_ALWAYS(size); 59 return abvec_subvec_const(ab, (absrc_vec)x,(k*m+i)*n+j); 60 } coeffpolymat61 inline absrc_elt coeff(unsigned int i, unsigned int j, unsigned int k) const { 62 return abvec_coeff_ptr_const(ab, part(i,j,k),0); 63 } 64 /* }}} */ 65 66 void addmat( 67 unsigned int kc, 68 polymat const & a, unsigned int ka, 69 polymat const & b, unsigned int kb); 70 void submat( 71 unsigned int kc, 72 polymat const & a, unsigned int ka, 73 polymat const & b, unsigned int kb); 74 void mulmat( 75 unsigned int kc, 76 polymat const & a, unsigned int ka, 77 polymat const & b, unsigned int kb); 78 void addmulmat( 79 unsigned int kc, 80 polymat const & a, unsigned int ka, 81 polymat const & b, unsigned int kb); 82 void multiply_column_by_x(unsigned int j, unsigned int size); 83 void truncate(polymat const & src, unsigned int nsize); 84 void extract_column( 85 unsigned int jdst, unsigned int kdst, 86 polymat const & src, unsigned int jsrc, unsigned int ksrc); 87 void extract_row_fragment( 88 unsigned int i1, unsigned int j1, 89 polymat const & src, unsigned int i0, unsigned int j0, 90 unsigned int n); 91 void mul(polymat const & a, polymat const & b); 92 void addmul(polymat const & a, polymat const & b); 93 void mp(polymat const & a, polymat const & b); 94 void addmp(polymat const & a, polymat const & b); 95 96 void set_matpoly(matpoly const &); 97 void rshift(polymat const & src, unsigned int k); 98 99 }; 100 101 /* {{{ cut-off structures */ 102 /* This structure is used to decide which algorithm to use for a given 103 * input length. This essentially is a function from N*N to a finite set of 104 * choices (so far, {0,1} only). The value returned for a balanced input 105 * length x*x is: 106 * if x >= cut: 1 107 * if x < cut: 108 * if table == NULL: 109 * return 0 110 * find last (s,a) in table such that s <= x 111 * return a 112 * For unbalanced input length x*y, we compare MIN(x,y) with subdivide. 113 * At the moment there is no additional table designed to improve the 114 * choice. 115 * 116 * Cutoffs are used only by lingen-polymat.c and lingen-bigpolymat.c -- however the 117 * tuning program also uses it, so we expose it here too. 118 */ 119 /* Such a cutoff structure is used for finding which algorithm to used 120 * for: 121 * - a balanced x*x product. -> basecase(0) or karatsuba(1) 122 * - an unbalanced x*y product. -> basecase(0) or split into balanced 123 * sizes(1) 124 */ 125 126 struct polymat_cutoff_info { 127 unsigned int cut; 128 unsigned int subdivide; 129 unsigned int (*table)[2]; 130 unsigned int table_size; 131 }; 132 #ifdef __cplusplus 133 extern "C" { 134 #endif 135 void polymat_cutoff_info_init(struct polymat_cutoff_info * c); 136 void polymat_cutoff_info_clear(struct polymat_cutoff_info * c); 137 void polymat_cutoff_add_step(struct polymat_cutoff_info * c, unsigned int size, unsigned int alg); 138 void polymat_set_mul_kara_cutoff(const struct polymat_cutoff_info * new_cutoff, struct polymat_cutoff_info * old_cutoff); 139 void polymat_set_mp_kara_cutoff(const struct polymat_cutoff_info * new_cutoff, struct polymat_cutoff_info * old_cutoff); 140 #ifdef __cplusplus 141 } 142 #endif 143 /* }}} */ 144 145 #endif /* LINGEN_POLYMAT_HPP_ */ 146