/* * GF-Complete: A Comprehensive Open Source Library for Galois Field Arithmetic * James S. Plank, Ethan L. Miller, Kevin M. Greenan, * Benjamin A. Arnold, John A. Burnum, Adam W. Disney, Allen C. McBride. * * gf_methods.c * * Lists supported methods (incomplete w.r.t. GROUP and COMPOSITE) */ #include #include #include #include #include "gf_complete.h" #include "gf_method.h" #include "gf_int.h" #define BNMULTS (8) static char *BMULTS[BNMULTS] = { "CARRY_FREE", "GROUP48", "TABLE", "LOG", "SPLIT4", "SPLIT8", "SPLIT88", "COMPOSITE" }; #define NMULTS (17) static char *MULTS[NMULTS] = { "SHIFT", "CARRY_FREE", "CARRY_FREE_GK", "GROUP44", "GROUP48", "BYTWO_p", "BYTWO_b", "TABLE", "LOG", "LOG_ZERO", "LOG_ZERO_EXT", "SPLIT2", "SPLIT4", "SPLIT8", "SPLIT16", "SPLIT88", "COMPOSITE" }; /* Make sure CAUCHY is last */ #define NREGIONS (7) static char *REGIONS[NREGIONS] = { "DOUBLE", "QUAD", "LAZY", "SIMD", "NOSIMD", "ALTMAP", "CAUCHY" }; #define BNREGIONS (4) static char *BREGIONS[BNREGIONS] = { "DOUBLE", "QUAD", "ALTMAP", "CAUCHY" }; #define NDIVS (2) static char *divides[NDIVS] = { "MATRIX", "EUCLID" }; void usage(char *s) { fprintf(stderr, "usage: gf_methods w -BADC -LUMDRB\n"); fprintf(stderr, "\n"); fprintf(stderr, " w can be 1-32, 64, 128\n"); fprintf(stderr, "\n"); fprintf(stderr, " -B lists basic methods that are useful\n"); fprintf(stderr, " -A does a nearly exhaustive listing\n"); fprintf(stderr, " -D adds EUCLID and MATRIX division\n"); fprintf(stderr, " -C adds CAUCHY when possible\n"); fprintf(stderr, " Combinations are fine.\n"); fprintf(stderr, "\n"); fprintf(stderr, " -L Simply lists methods\n"); fprintf(stderr, " -U Produces calls to gf_unit\n"); fprintf(stderr, " -M Produces calls to time_tool.sh for single multiplications\n"); fprintf(stderr, " -D Produces calls to time_tool.sh for single divisions\n"); fprintf(stderr, " -R Produces calls to time_tool.sh for region multiplications\n"); fprintf(stderr, " -B Produces calls to time_tool.sh for the fastest region multiplications\n"); fprintf(stderr, " Cannot combine L, U, T.\n"); if (s != NULL) { fprintf(stderr, "\n"); fprintf(stderr, "%s\n", s); } exit(1); } int main(int argc, char *argv[]) { int m, r, d, w, i, sa, j, k, reset, ok; int nregions; int nmults; char **regions; char **mults; int exhaustive = 0; int divide = 0; int cauchy = 0; int listing; char *gf_argv[50], *x; gf_t gf; char ls[10]; char * w_str; if (argc != 4) usage(NULL); w = atoi(argv[1]); ok = (w >= 1 && w <= 32); if (w == 64) ok = 1; if (w == 128) ok = 1; if (!ok) usage("Bad w"); if (argv[2][0] != '-' || argv[3][0] != '-' || strlen(argv[2]) == 1 || strlen(argv[3]) != 2) { usage(NULL); } for (i = 1; argv[2][i] != '\0'; i++) { switch(argv[2][i]) { case 'B': exhaustive = 0; break; case 'A': exhaustive = 1; break; case 'D': divide = 1; break; case 'C': cauchy = 1; break; default: usage("Bad -BADC"); } } if (strchr("LUMDRB", argv[3][1]) == NULL) { usage("Bad -LUMDRB"); } listing = argv[3][1]; if (listing == 'U') { w_str = "../test/gf_unit %d A -1"; } else if (listing == 'L') { w_str = "w=%d:"; } else { w_str = strdup("sh time_tool.sh X %d"); x = strchr(w_str, 'X'); *x = listing; } gf_argv[0] = "-"; if (create_gf_from_argv(&gf, w, 1, gf_argv, 0) > 0) { printf(w_str, w); printf(" - \n"); gf_free(&gf, 1); } else if (_gf_errno == GF_E_DEFAULT) { fprintf(stderr, "Unlabeled failed method: w=%d: -\n", 2); exit(1); } nregions = (exhaustive) ? NREGIONS : BNREGIONS; if (!cauchy) nregions--; regions = (exhaustive) ? REGIONS : BREGIONS; mults = (exhaustive) ? MULTS : BMULTS; nmults = (exhaustive) ? NMULTS : BNMULTS; for (m = 0; m < nmults; m++) { sa = 0; gf_argv[sa++] = "-m"; if (strcmp(mults[m], "GROUP44") == 0) { gf_argv[sa++] = "GROUP"; gf_argv[sa++] = "4"; gf_argv[sa++] = "4"; } else if (strcmp(mults[m], "GROUP48") == 0) { gf_argv[sa++] = "GROUP"; gf_argv[sa++] = "4"; gf_argv[sa++] = "8"; } else if (strcmp(mults[m], "SPLIT2") == 0) { gf_argv[sa++] = "SPLIT"; sprintf(ls, "%d", w); gf_argv[sa++] = ls; gf_argv[sa++] = "2"; } else if (strcmp(mults[m], "SPLIT4") == 0) { gf_argv[sa++] = "SPLIT"; sprintf(ls, "%d", w); gf_argv[sa++] = ls; gf_argv[sa++] = "4"; } else if (strcmp(mults[m], "SPLIT8") == 0) { gf_argv[sa++] = "SPLIT"; sprintf(ls, "%d", w); gf_argv[sa++] = ls; gf_argv[sa++] = "8"; } else if (strcmp(mults[m], "SPLIT16") == 0) { gf_argv[sa++] = "SPLIT"; sprintf(ls, "%d", w); gf_argv[sa++] = ls; gf_argv[sa++] = "16"; } else if (strcmp(mults[m], "SPLIT88") == 0) { gf_argv[sa++] = "SPLIT"; gf_argv[sa++] = "8"; gf_argv[sa++] = "8"; } else if (strcmp(mults[m], "COMPOSITE") == 0) { gf_argv[sa++] = "COMPOSITE"; gf_argv[sa++] = "2"; gf_argv[sa++] = "-"; } else { gf_argv[sa++] = mults[m]; } reset = sa; for (r = 0; r < (1 << nregions); r++) { sa = reset; for (k = 0; k < nregions; k++) { if (r & (1 << k)) { gf_argv[sa++] = "-r"; gf_argv[sa++] = regions[k]; } } gf_argv[sa++] = "-"; /* printf("Hmmmm. %s", gf_argv[0]); for (j = 0; j < sa; j++) printf(" %s", gf_argv[j]); printf("\n"); */ if (create_gf_from_argv(&gf, w, sa, gf_argv, 0) > 0) { printf(w_str, w); for (j = 0; j < sa; j++) printf(" %s", gf_argv[j]); printf("\n"); gf_free(&gf, 1); } else if (_gf_errno == GF_E_DEFAULT) { fprintf(stderr, "Unlabeled failed method: w=%d:", w); for (j = 0; j < sa; j++) fprintf(stderr, " %s", gf_argv[j]); fprintf(stderr, "\n"); exit(1); } sa--; if (divide) { for (d = 0; d < NDIVS; d++) { gf_argv[sa++] = "-d"; gf_argv[sa++] = divides[d]; /* printf("w=%d:", w); for (j = 0; j < sa; j++) printf(" %s", gf_argv[j]); printf("\n"); */ gf_argv[sa++] = "-"; if (create_gf_from_argv(&gf, w, sa, gf_argv, 0) > 0) { printf(w_str, w); for (j = 0; j < sa; j++) printf(" %s", gf_argv[j]); printf("\n"); gf_free(&gf, 1); } else if (_gf_errno == GF_E_DEFAULT) { fprintf(stderr, "Unlabeled failed method: w=%d:", w); for (j = 0; j < sa; j++) fprintf(stderr, " %s", gf_argv[j]); fprintf(stderr, "\n"); exit(1); } sa-=3; } } } } return 0; }