Merge Request #24

Open
jerasure/gf-complete!24
Created by Yuriy Kaminskiy

Fix ARM NEON CARRY_FREE mode

Fix for jerasure/gf-complete#18 and improved unit test to ensure (more) combination of gf_w{8,16,32}{,_neon}_clm_multiply_{2,3,4} are covered.

Note: I collected prim_poly used in test from random sources without much verification; gf(2**32) coverage still incomplete, gf(2**64) and gf(2**128) coverage is not improved.

Not tested on x86 with PCLMULLDQD.

Assignee: None
Milestone: None
This can't be merged automatically, even if it could be merged you don't have the permission to do so.
This can be merged automatically but you don't have the permission to do so.
Commits (3)
1 participants
src/neon/gf_w8_neon.c
... ... @@ -52,12 +52,9 @@
52 52 * of that operation back with the result. */
53 53 #define NEON_CFM_REDUCE(v, w, result, prim_poly, initial) \
54 54 do { \
55   - if (initial) \
56   - v = vshrn_n_u16 (vreinterpretq_u16_p16(result), 8); \
57   - else \
58   - v = veor_u8 (v, vshrn_n_u16 (vreinterpretq_u16_p16(result), 8)); \
  55 + v = vshrn_n_u16 (vreinterpretq_u16_p16(result), GF_FIELD_WIDTH); \
59 56 w = vmull_p8 (prim_poly, vreinterpret_p8_u8(v)); \
60   - result = vreinterpretq_p16_u16 (veorq_u16 (vreinterpretq_u16_p16(result), vreinterpretq_u16_p16(w))); \
  57 + result = vreinterpretq_p16_u16 (veorq_u16 (vandq_u16(vdupq_n_u16(GF_FIELD_SIZE - 1), vreinterpretq_u16_p16(result)), vreinterpretq_u16_p16(w))); \
61 58 } while (0)
62 59  
63 60 static
... ...
tools/gf_methods.c
... ... @@ -37,6 +37,17 @@ static char *BREGIONS[BNREGIONS] = { "DOUBLE", "QUAD", "ALTMAP", "CAUCHY" };
37 37 #define NDIVS (2)
38 38 static char *divides[NDIVS] = { "MATRIX", "EUCLID" };
39 39  
  40 +static char *extra_poly[][3] = {
  41 + /* 8 */ [3] = { "169", "12d", /* "11d" */ NULL },
  42 + /* 16 */ [4] = { /* "1100b", */ "103dd", "1002d", NULL },
  43 + /* 32 */ [5] = { /* "100400007", */ "1000000c5", NULL },
  44 + /* ^^ TODO: add pp in 0x00020000..0x003fffff range */
  45 + /* 64 */ [6] = { /* "000000000000001b", */ NULL },
  46 + /* ^^ TODO: add pp in 0x0000000200000000..0x0001ffffffffffff range */
  47 + /* 128 */ [7] = { /* "00000000000000000000000000000087", */ NULL },
  48 + /* ^^ TODO TBD */
  49 +};
  50 +
40 51 void usage(char *s)
41 52 {
42 53 fprintf(stderr, "usage: gf_methods w -BADC -LXUMDRB\n");
... ... @@ -92,6 +103,8 @@ int main(int argc, char *argv[])
92 103 gf_t gf;
93 104 char ls[10];
94 105 char * w_str;
  106 + int wlog;
  107 + int ep, epa;
95 108  
96 109 if (argc != 4) usage(NULL);
97 110 w = atoi(argv[1]);
... ... @@ -126,121 +139,134 @@ int main(int argc, char *argv[])
126 139 *x = listing;
127 140 }
128 141  
129   - gf_argv[0] = "-";
130   - if (create_gf_from_argv(&gf, w, 1, gf_argv, 0) > 0) {
131   - printf(w_str, w);
132   - printf(" - \n");
133   - gf_free(&gf, 1);
134   - } else if (_gf_errno == GF_E_DEFAULT) {
135   - fprintf(stderr, "Unlabeled failed method: w=%d: -\n", 2);
136   - exit(1);
137   - }
  142 + for (wlog = 0; wlog < 7; wlog++)
  143 + if (w == (1<<wlog))
  144 + break;
138 145  
139   - nregions = (exhaustive) ? NREGIONS : BNREGIONS;
140   - if (!cauchy) nregions--;
141   - regions = (exhaustive) ? REGIONS : BREGIONS;
142   - mults = (exhaustive) ? MULTS : BMULTS;
143   - nmults = (exhaustive) ? NMULTS : BNMULTS;
144   -
145   -
146   - for (m = 0; m < nmults; m++) {
147   - sa = 0;
148   - gf_argv[sa++] = "-m";
149   - if (strcmp(mults[m], "GROUP44") == 0) {
150   - gf_argv[sa++] = "GROUP";
151   - gf_argv[sa++] = "4";
152   - gf_argv[sa++] = "4";
153   - } else if (strcmp(mults[m], "GROUP48") == 0) {
154   - gf_argv[sa++] = "GROUP";
155   - gf_argv[sa++] = "4";
156   - gf_argv[sa++] = "8";
157   - } else if (strcmp(mults[m], "SPLIT2") == 0) {
158   - gf_argv[sa++] = "SPLIT";
159   - sprintf(ls, "%d", w);
160   - gf_argv[sa++] = ls;
161   - gf_argv[sa++] = "2";
162   - } else if (strcmp(mults[m], "SPLIT4") == 0) {
163   - gf_argv[sa++] = "SPLIT";
164   - sprintf(ls, "%d", w);
165   - gf_argv[sa++] = ls;
166   - gf_argv[sa++] = "4";
167   - } else if (strcmp(mults[m], "SPLIT8") == 0) {
168   - gf_argv[sa++] = "SPLIT";
169   - sprintf(ls, "%d", w);
170   - gf_argv[sa++] = ls;
171   - gf_argv[sa++] = "8";
172   - } else if (strcmp(mults[m], "SPLIT16") == 0) {
173   - gf_argv[sa++] = "SPLIT";
174   - sprintf(ls, "%d", w);
175   - gf_argv[sa++] = ls;
176   - gf_argv[sa++] = "16";
177   - } else if (strcmp(mults[m], "SPLIT88") == 0) {
178   - gf_argv[sa++] = "SPLIT";
179   - gf_argv[sa++] = "8";
180   - gf_argv[sa++] = "8";
181   - } else if (strcmp(mults[m], "COMPOSITE") == 0) {
182   - gf_argv[sa++] = "COMPOSITE";
183   - gf_argv[sa++] = "2";
184   - gf_argv[sa++] = "-";
185   - } else {
186   - gf_argv[sa++] = mults[m];
  146 + ep = 0;
  147 + do {
  148 + epa = 0;
  149 + if (extra_poly[wlog][ep]) { /* NULL implies default prim_poly */
  150 + gf_argv[epa++] = "-p";
  151 + gf_argv[epa++] = extra_poly[wlog][ep];
  152 + }
  153 + gf_argv[epa+0] = "-";
  154 + if (create_gf_from_argv(&gf, w, epa + 1, gf_argv, 0) > 0) {
  155 + printf(w_str, w);
  156 + for (j = 0; j < epa + 1; j++) printf(" %s", gf_argv[j]);
  157 + printf("\n");
  158 + gf_free(&gf, 1);
  159 + } else if (_gf_errno == GF_E_DEFAULT) {
  160 + fprintf(stderr, "Unlabeled failed method: w=%d: -\n", 2);
  161 + exit(1);
187 162 }
188   - reset = sa;
189 163  
  164 + nregions = (exhaustive) ? NREGIONS : BNREGIONS;
  165 + if (!cauchy) nregions--;
  166 + regions = (exhaustive) ? REGIONS : BREGIONS;
  167 + mults = (exhaustive) ? MULTS : BMULTS;
  168 + nmults = (exhaustive) ? NMULTS : BNMULTS;
190 169  
191   - for (r = 0; r < (1 << nregions); r++) {
192   - sa = reset;
193   - for (k = 0; k < nregions; k++) {
194   - if (r & (1 << k)) {
195   - gf_argv[sa++] = "-r";
196   - gf_argv[sa++] = regions[k];
197   - }
198   - }
199   - gf_argv[sa++] = "-";
200 170  
201   - /* printf("Hmmmm. %s", gf_argv[0]);
202   - for (j = 0; j < sa; j++) printf(" %s", gf_argv[j]);
203   - printf("\n"); */
204   -
205   - if (create_gf_from_argv(&gf, w, sa, gf_argv, 0) > 0) {
206   - printf(w_str, w);
207   - for (j = 0; j < sa; j++) printf(" %s", gf_argv[j]);
208   - printf("\n");
209   - if (listing == 'X')
210   - print_methods(&gf);
211   - gf_free(&gf, 1);
212   - } else if (_gf_errno == GF_E_DEFAULT) {
213   - fprintf(stderr, "Unlabeled failed method: w=%d:", w);
214   - for (j = 0; j < sa; j++) fprintf(stderr, " %s", gf_argv[j]);
215   - fprintf(stderr, "\n");
216   - exit(1);
  171 + for (m = 0; m < nmults; m++) {
  172 + sa = epa;
  173 + gf_argv[sa++] = "-m";
  174 + if (strcmp(mults[m], "GROUP44") == 0) {
  175 + gf_argv[sa++] = "GROUP";
  176 + gf_argv[sa++] = "4";
  177 + gf_argv[sa++] = "4";
  178 + } else if (strcmp(mults[m], "GROUP48") == 0) {
  179 + gf_argv[sa++] = "GROUP";
  180 + gf_argv[sa++] = "4";
  181 + gf_argv[sa++] = "8";
  182 + } else if (strcmp(mults[m], "SPLIT2") == 0) {
  183 + gf_argv[sa++] = "SPLIT";
  184 + sprintf(ls, "%d", w);
  185 + gf_argv[sa++] = ls;
  186 + gf_argv[sa++] = "2";
  187 + } else if (strcmp(mults[m], "SPLIT4") == 0) {
  188 + gf_argv[sa++] = "SPLIT";
  189 + sprintf(ls, "%d", w);
  190 + gf_argv[sa++] = ls;
  191 + gf_argv[sa++] = "4";
  192 + } else if (strcmp(mults[m], "SPLIT8") == 0) {
  193 + gf_argv[sa++] = "SPLIT";
  194 + sprintf(ls, "%d", w);
  195 + gf_argv[sa++] = ls;
  196 + gf_argv[sa++] = "8";
  197 + } else if (strcmp(mults[m], "SPLIT16") == 0) {
  198 + gf_argv[sa++] = "SPLIT";
  199 + sprintf(ls, "%d", w);
  200 + gf_argv[sa++] = ls;
  201 + gf_argv[sa++] = "16";
  202 + } else if (strcmp(mults[m], "SPLIT88") == 0) {
  203 + gf_argv[sa++] = "SPLIT";
  204 + gf_argv[sa++] = "8";
  205 + gf_argv[sa++] = "8";
  206 + } else if (strcmp(mults[m], "COMPOSITE") == 0) {
  207 + gf_argv[sa++] = "COMPOSITE";
  208 + gf_argv[sa++] = "2";
  209 + gf_argv[sa++] = "-";
  210 + } else {
  211 + gf_argv[sa++] = mults[m];
217 212 }
218   - sa--;
219   - if (divide) {
220   - for (d = 0; d < NDIVS; d++) {
221   - gf_argv[sa++] = "-d";
222   - gf_argv[sa++] = divides[d];
223   - /* printf("w=%d:", w);
224   - for (j = 0; j < sa; j++) printf(" %s", gf_argv[j]);
225   - printf("\n"); */
226   - gf_argv[sa++] = "-";
227   - if (create_gf_from_argv(&gf, w, sa, gf_argv, 0) > 0) {
228   - printf(w_str, w);
229   - for (j = 0; j < sa; j++) printf(" %s", gf_argv[j]);
230   - printf("\n");
231   - if (listing == 'X')
232   - print_methods(&gf);
233   - gf_free(&gf, 1);
234   - } else if (_gf_errno == GF_E_DEFAULT) {
235   - fprintf(stderr, "Unlabeled failed method: w=%d:", w);
236   - for (j = 0; j < sa; j++) fprintf(stderr, " %s", gf_argv[j]);
237   - fprintf(stderr, "\n");
238   - exit(1);
239   - }
240   - sa-=3;
241   - }
  213 + reset = sa;
  214 +
  215 +
  216 + for (r = 0; r < (1 << nregions); r++) {
  217 + sa = reset;
  218 + for (k = 0; k < nregions; k++) {
  219 + if (r & (1 << k)) {
  220 + gf_argv[sa++] = "-r";
  221 + gf_argv[sa++] = regions[k];
  222 + }
  223 + }
  224 + gf_argv[sa++] = "-";
  225 +
  226 + /* printf("Hmmmm. %s", gf_argv[0]);
  227 + for (j = 0; j < sa; j++) printf(" %s", gf_argv[j]);
  228 + printf("\n"); */
  229 +
  230 + if (create_gf_from_argv(&gf, w, sa, gf_argv, 0) > 0) {
  231 + printf(w_str, w);
  232 + for (j = 0; j < sa; j++) printf(" %s", gf_argv[j]);
  233 + printf("\n");
  234 + if (listing == 'X')
  235 + print_methods(&gf);
  236 + gf_free(&gf, 1);
  237 + } else if (_gf_errno == GF_E_DEFAULT) {
  238 + fprintf(stderr, "Unlabeled failed method: w=%d:", w);
  239 + for (j = 0; j < sa; j++) fprintf(stderr, " %s", gf_argv[j]);
  240 + fprintf(stderr, "\n");
  241 + exit(1);
  242 + }
  243 + sa--;
  244 + if (divide) {
  245 + for (d = 0; d < NDIVS; d++) {
  246 + gf_argv[sa++] = "-d";
  247 + gf_argv[sa++] = divides[d];
  248 + /* printf("w=%d:", w);
  249 + for (j = 0; j < sa; j++) printf(" %s", gf_argv[j]);
  250 + printf("\n"); */
  251 + gf_argv[sa++] = "-";
  252 + if (create_gf_from_argv(&gf, w, sa, gf_argv, 0) > 0) {
  253 + printf(w_str, w);
  254 + for (j = 0; j < sa; j++) printf(" %s", gf_argv[j]);
  255 + printf("\n");
  256 + if (listing == 'X')
  257 + print_methods(&gf);
  258 + gf_free(&gf, 1);
  259 + } else if (_gf_errno == GF_E_DEFAULT) {
  260 + fprintf(stderr, "Unlabeled failed method: w=%d:", w);
  261 + for (j = 0; j < sa; j++) fprintf(stderr, " %s", gf_argv[j]);
  262 + fprintf(stderr, "\n");
  263 + exit(1);
  264 + }
  265 + sa-=3;
  266 + }
  267 + }
242 268 }
243 269 }
244   - }
  270 + } while(extra_poly[wlog][ep++]);
245 271 return 0;
246 272 }
... ...