From 797c6ac94c3442f350bfecfc9bcdd1c0365df541 Mon Sep 17 00:00:00 2001 From: Vincent Neiger Date: Thu, 26 Mar 2026 15:50:07 +0100 Subject: [PATCH 1/4] add profile files for some main nmod mat functions --- .../profile/p-charpoly_minpoly.c | 167 ++++++++++++++++ .../src/nmod_mat_extra/profile/p-inv.c | 152 ++++++++++++++ .../src/nmod_mat_extra/profile/p-lu.c | 169 ++++++++++++++++ .../src/nmod_mat_extra/profile/p-mul.c | 188 ++++++++++++++++++ .../src/nmod_mat_extra/profile/p-solve.c | 162 +++++++++++++++ 5 files changed, 838 insertions(+) create mode 100644 flint-extras/src/nmod_mat_extra/profile/p-charpoly_minpoly.c create mode 100644 flint-extras/src/nmod_mat_extra/profile/p-inv.c create mode 100644 flint-extras/src/nmod_mat_extra/profile/p-lu.c create mode 100644 flint-extras/src/nmod_mat_extra/profile/p-mul.c create mode 100644 flint-extras/src/nmod_mat_extra/profile/p-solve.c diff --git a/flint-extras/src/nmod_mat_extra/profile/p-charpoly_minpoly.c b/flint-extras/src/nmod_mat_extra/profile/p-charpoly_minpoly.c new file mode 100644 index 00000000..4012df33 --- /dev/null +++ b/flint-extras/src/nmod_mat_extra/profile/p-charpoly_minpoly.c @@ -0,0 +1,167 @@ +#include +#include // for atoi + +#include +#include +#include +#include +#include + +#define MEASURE_SAMPLE 0 + +/* for charpoly/minpoly of dim x dim */ +typedef struct { + slong dim; + slong modn; +} time_args; + +#define TIME_CPMP(fun) \ +void time_##fun(time_args targs, flint_rand_t state) \ +{ \ + const slong dim = targs.dim; \ + const slong modn = targs.modn; \ + \ + nmod_mat_t mat; \ + nmod_mat_init(mat, dim, dim, modn); \ + nmod_mat_rand(mat, state); \ + nmod_poly_t pol; \ + nmod_poly_init(pol, modn); \ + \ + double FLINT_SET_BUT_UNUSED(tcpu), twall; \ + \ + TIMEIT_START; \ + fun(pol, mat); \ + TIMEIT_STOP_VALUES(tcpu, twall); \ + \ + flint_printf("%.2e", twall); \ + \ + nmod_poly_clear(pol); \ + nmod_mat_clear(mat); \ +} + +#define SAMPLE_CPMP(fun) \ +void sample_##fun(void * arg, ulong count) \ +{ \ + time_args * targs = (time_args *) arg; \ + const slong dim = targs->dim; \ + const slong modn = targs->modn; \ + \ + FLINT_TEST_INIT(state); \ + \ + nmod_mat_t mat; \ + nmod_mat_init(mat, dim, dim, modn); \ + nmod_mat_rand(mat, state); \ + nmod_poly_t pol; \ + nmod_poly_init(pol, modn); \ + for (ulong i = 0; i < count; i++) \ + { \ + nmod_mat_t tmp; \ + nmod_mat_init(tmp, dim, dim, modn); \ + for (slong k = 0; k < dim*dim; k++) \ + tmp->entries[k] = mat->entries[k]; \ + prof_start(); \ + fun(pol, mat); \ + prof_stop(); \ + nmod_mat_clear(tmp); \ + } \ + \ + nmod_poly_clear(pol); \ + nmod_mat_clear(mat); \ + FLINT_TEST_CLEAR(state); \ +} + +TIME_CPMP(nmod_mat_charpoly) +TIME_CPMP(nmod_mat_charpoly_danilevsky) +TIME_CPMP(nmod_mat_charpoly_berkowitz) +TIME_CPMP(nmod_mat_minpoly) + +SAMPLE_CPMP(nmod_mat_charpoly) +SAMPLE_CPMP(nmod_mat_charpoly_danilevsky) +SAMPLE_CPMP(nmod_mat_charpoly_berkowitz) +SAMPLE_CPMP(nmod_mat_minpoly) + +/*-------------------------*/ +/* main */ +/*-------------------------*/ +int main(int argc, char ** argv) +{ + flint_rand_t state; + flint_rand_init(state); + flint_rand_set_seed(state, time(NULL), time(NULL)+129384125L); + + // bench functions + const slong nfuns = 4; + typedef void (*timefun) (time_args, flint_rand_t); + const timefun funs[] = { + time_nmod_mat_minpoly, // 0 + time_nmod_mat_charpoly, // 1 + time_nmod_mat_charpoly_danilevsky, // 2 + time_nmod_mat_charpoly_berkowitz, // 3 + }; + + typedef void (*samplefun) (void*, ulong); + const samplefun sfuns[] = { + sample_nmod_mat_minpoly, // 0 + sample_nmod_mat_charpoly, // 1 + sample_nmod_mat_charpoly_danilevsky, // 2 + sample_nmod_mat_charpoly_berkowitz, // 3 + }; + + const char * description[] = { + "#0 --> nmod_mat_minpoly ", + "#1 --> nmod_mat_charpoly ", + "#2 --> nmod_mat_charpoly_danilevsky ", + "#3 --> nmod_mat_charpoly_berkowitz ", + }; + + if (argc == 1) // show usage + { + flint_printf("Usage: `%s [nbits] [fun] [dim]`\n", argv[0]); + flint_printf(" No argument shows this help.\n"); + flint_printf(" - nbits: number of bits, in (0..63], for the randomly-chosen modulus\n"); + flint_printf(" - fun: id number of the timed function (see below),\n"); + flint_printf(" - dim: matrix dimension\n"); + flint_printf("\nAvailable functions:\n"); + for (slong j = 0; j < nfuns; j++) + flint_printf(" %s\n", description[j]); + + return 0; + } + + /* flint_printf("#warmup...\n"); */ + for (slong i = 0; i < 3; i++) + { + time_args targs = { + i*100, + n_nextprime(17 + (UWORD(1) << (i*17)), 0) + }; + double min, max; + prof_repeat(&min, &max, sfuns[0], &targs); + } + /* flint_printf("\n\n"); */ + + if (argc == 4) + { + const slong b = atoi(argv[1]); + const slong ifun = atoi(argv[2]); + const slong dim = atoi(argv[3]); + flint_printf("bits fun dim \n"); + + ulong n = n_nextprime(UWORD(1) << (b-1), 1); + + flint_printf("%-4ld %-3ld %-6ld", b, ifun, dim); + time_args targs = {dim, n}; + +#if MEASURE_SAMPLE + double min, max; + prof_repeat(&min, &max, sfuns[ifun], &targs); + flint_printf("%.2e", min/1000000); +#else + funs[ifun](targs, state); +#endif + flint_printf("\n"); + } + + flint_rand_clear(state); + return 0; +} diff --git a/flint-extras/src/nmod_mat_extra/profile/p-inv.c b/flint-extras/src/nmod_mat_extra/profile/p-inv.c new file mode 100644 index 00000000..98483bee --- /dev/null +++ b/flint-extras/src/nmod_mat_extra/profile/p-inv.c @@ -0,0 +1,152 @@ +#include +#include // for atoi + +#include +#include +#include +#include +#include + +#define MEASURE_SAMPLE 0 + +/* for inversion of dim x dim */ +typedef struct { + slong dim; + slong modn; +} time_args; + +#define TIME_INV(fun) \ +void time_##fun(time_args targs, flint_rand_t state) \ +{ \ + const slong dim = targs.dim; \ + const slong modn = targs.modn; \ + \ + nmod_mat_t mat; \ + nmod_mat_t imat; \ + nmod_mat_init(mat, dim, dim, modn); \ + nmod_mat_init(imat, dim, dim, modn); \ + nmod_mat_rand(mat, state); \ + \ + double FLINT_SET_BUT_UNUSED(tcpu), twall; \ + \ + TIMEIT_START; \ + fun(imat, mat); \ + TIMEIT_STOP_VALUES(tcpu, twall); \ + \ + flint_printf("%.2e", twall); \ + \ + nmod_mat_clear(mat); \ + nmod_mat_clear(imat); \ +} + +#define SAMPLE_INV(fun) \ +void sample_##fun(void * arg, ulong count) \ +{ \ + time_args * targs = (time_args *) arg; \ + const slong dim = targs->dim; \ + const slong modn = targs->modn; \ + \ + FLINT_TEST_INIT(state); \ + \ + nmod_mat_t mat; \ + nmod_mat_t imat; \ + nmod_mat_init(mat, dim, dim, modn); \ + nmod_mat_init(imat, dim, dim, modn); \ + nmod_mat_rand(mat, state); \ + for (ulong i = 0; i < count; i++) \ + { \ + nmod_mat_t tmp; \ + nmod_mat_init(tmp, dim, dim, modn); \ + for (slong k = 0; k < dim*dim; k++) \ + tmp->entries[k] = mat->entries[k]; \ + prof_start(); \ + fun(imat, mat); \ + prof_stop(); \ + nmod_mat_clear(tmp); \ + } \ + \ + nmod_mat_clear(mat); \ + nmod_mat_clear(imat); \ + FLINT_TEST_CLEAR(state); \ +} + +TIME_INV(nmod_mat_inv) + +SAMPLE_INV(nmod_mat_inv) + +/*-------------------------*/ +/* main */ +/*-------------------------*/ +int main(int argc, char ** argv) +{ + flint_rand_t state; + flint_rand_init(state); + flint_rand_set_seed(state, time(NULL), time(NULL)+129384125L); + + // bench functions + const slong nfuns = 4; + typedef void (*timefun) (time_args, flint_rand_t); + const timefun funs[] = { + time_nmod_mat_inv, // 0 + }; + + typedef void (*samplefun) (void*, ulong); + const samplefun sfuns[] = { + sample_nmod_mat_inv, // 0 + }; + + const char * description[] = { + "#0 --> nmod_mat_inv ", + }; + + if (argc == 1) // show usage + { + flint_printf("Usage: `%s [nbits] [fun] [dim]`\n", argv[0]); + flint_printf(" No argument shows this help.\n"); + flint_printf(" - nbits: number of bits, in (0..63], for the randomly-chosen modulus\n"); + flint_printf(" - fun: id number of the timed function (see below),\n"); + flint_printf(" - dim: matrix dimension\n"); + flint_printf("\nAvailable functions:\n"); + for (slong j = 0; j < nfuns; j++) + flint_printf(" %s\n", description[j]); + + return 0; + } + + /* flint_printf("#warmup...\n"); */ + for (slong i = 0; i < 3; i++) + { + time_args targs = { + i*100, + n_nextprime(17 + (UWORD(1) << (i*17)), 0) + }; + double min, max; + prof_repeat(&min, &max, sfuns[0], &targs); + } + /* flint_printf("\n\n"); */ + + if (argc == 4) + { + const slong b = atoi(argv[1]); + const slong ifun = atoi(argv[2]); + const slong dim = atoi(argv[3]); + flint_printf("bits fun dim \n"); + + ulong n = n_nextprime(UWORD(1) << (b-1), 1); + + flint_printf("%-4ld %-3ld %-6ld", b, ifun, dim); + time_args targs = {dim, n}; + +#if MEASURE_SAMPLE + double min, max; + prof_repeat(&min, &max, sfuns[ifun], &targs); + flint_printf("%.2e", min/1000000); +#else + funs[ifun](targs, state); +#endif + flint_printf("\n"); + } + + flint_rand_clear(state); + return 0; +} diff --git a/flint-extras/src/nmod_mat_extra/profile/p-lu.c b/flint-extras/src/nmod_mat_extra/profile/p-lu.c new file mode 100644 index 00000000..155ef48f --- /dev/null +++ b/flint-extras/src/nmod_mat_extra/profile/p-lu.c @@ -0,0 +1,169 @@ +#include +#include // for atoi + +#include +#include +#include +#include + +#define MEASURE_SAMPLE 0 + +/* for LU of dim1 x dim2 */ +typedef struct { + slong dim1; + slong dim2; + slong modn; +} time_args; + +#define TIME_LU(fun) \ +void time_##fun(time_args targs, flint_rand_t state) \ +{ \ + const slong dim1 = targs.dim1; \ + const slong dim2 = targs.dim2; \ + const slong modn = targs.modn; \ + \ + nmod_mat_t mat; \ + nmod_mat_init(mat, dim1, dim2, modn); \ + nmod_mat_rand(mat, state); \ + slong * P = FLINT_ARRAY_ALLOC(dim1, slong); \ + \ + double FLINT_SET_BUT_UNUSED(tcpu), twall; \ + \ + TIMEIT_START; \ + fun(P, mat, 0); \ + TIMEIT_STOP_VALUES(tcpu, twall); \ + \ + flint_printf("%.2e", twall); \ + \ + flint_free(P); \ + nmod_mat_clear(mat); \ +} + +#define SAMPLE_LU(fun) \ +void sample_##fun(void * arg, ulong count) \ +{ \ + time_args * targs = (time_args *) arg; \ + const slong dim1 = targs->dim1; \ + const slong dim2 = targs->dim2; \ + const slong modn = targs->modn; \ + \ + FLINT_TEST_INIT(state); \ + \ + nmod_mat_t mat; \ + nmod_mat_init(mat, dim1, dim2, modn); \ + nmod_mat_rand(mat, state); \ + slong * P = FLINT_ARRAY_ALLOC(dim1, slong); \ + for (ulong i = 0; i < count; i++) \ + { \ + nmod_mat_t tmp; \ + nmod_mat_init(tmp, dim1, dim2, modn); \ + for (slong k = 0; k < dim1*dim2; k++) \ + tmp->entries[k] = mat->entries[k]; \ + prof_start(); \ + fun(P, mat, 0); \ + prof_stop(); \ + nmod_mat_clear(tmp); \ + } \ + \ + flint_free(P); \ + nmod_mat_clear(mat); \ + FLINT_TEST_CLEAR(state); \ +} + +TIME_LU(nmod_mat_lu) +TIME_LU(nmod_mat_lu_classical) +TIME_LU(nmod_mat_lu_classical_delayed) +TIME_LU(nmod_mat_lu_recursive) + +SAMPLE_LU(nmod_mat_lu) +SAMPLE_LU(nmod_mat_lu_classical) +SAMPLE_LU(nmod_mat_lu_classical_delayed) +SAMPLE_LU(nmod_mat_lu_recursive) + +/*-------------------------*/ +/* main */ +/*-------------------------*/ +int main(int argc, char ** argv) +{ + flint_rand_t state; + flint_rand_init(state); + flint_rand_set_seed(state, time(NULL), time(NULL)+129384125L); + + // bench functions + const slong nfuns = 4; + typedef void (*timefun) (time_args, flint_rand_t); + const timefun funs[] = { + time_nmod_mat_lu, // 0 + time_nmod_mat_lu_classical, // 1 + time_nmod_mat_lu_classical_delayed, // 2 + time_nmod_mat_lu_recursive, // 3 + }; + + typedef void (*samplefun) (void*, ulong); + const samplefun sfuns[] = { + sample_nmod_mat_lu, // 0 + sample_nmod_mat_lu_classical, // 1 + sample_nmod_mat_lu_classical_delayed, // 2 + sample_nmod_mat_lu_recursive, // 3 + }; + + const char * description[] = { + "#0 --> nmod_mat_lu ", + "#1 --> nmod_mat_lu_classical ", + "#2 --> nmod_mat_lu_classical_delayed ", + "#3 --> nmod_mat_lu_recursive ", + }; + + if (argc == 1) // show usage + { + flint_printf("Usage: `%s [nbits] [fun] [dim1] [dim2]`\n", argv[0]); + flint_printf(" No argument shows this help.\n"); + flint_printf(" - nbits: number of bits, in (0..63], for the randomly-chosen modulus\n"); + flint_printf(" - fun: id number of the timed function (see below),\n"); + flint_printf(" - dim1, dim2: matrix dimensions\n"); + flint_printf("\nAvailable functions:\n"); + for (slong j = 0; j < nfuns; j++) + flint_printf(" %s\n", description[j]); + + return 0; + } + + /* flint_printf("#warmup...\n"); */ + for (slong i = 0; i < 3; i++) + { + time_args targs = { + i*100, + i*100, + n_nextprime(17 + (UWORD(1) << (i*17)), 0) + }; + double min, max; + prof_repeat(&min, &max, sfuns[0], &targs); + } + /* flint_printf("\n\n"); */ + + if (argc == 5) + { + const slong b = atoi(argv[1]); + const slong ifun = atoi(argv[2]); + const slong dim1 = atoi(argv[3]); + const slong dim2 = atoi(argv[4]); + flint_printf("bits fun dim1 dim2 \n"); + + ulong n = n_nextprime(UWORD(1) << (b-1), 1); + + flint_printf("%-4ld %-3ld %-6ld%-6ld", b, ifun, dim1, dim2); + time_args targs = {dim1, dim2, n}; + +#if MEASURE_SAMPLE + double min, max; + prof_repeat(&min, &max, sfuns[ifun], &targs); + flint_printf("%.2e", min/1000000); +#else + funs[ifun](targs, state); +#endif + flint_printf("\n"); + } + + flint_rand_clear(state); + return 0; +} diff --git a/flint-extras/src/nmod_mat_extra/profile/p-mul.c b/flint-extras/src/nmod_mat_extra/profile/p-mul.c new file mode 100644 index 00000000..051f1ca1 --- /dev/null +++ b/flint-extras/src/nmod_mat_extra/profile/p-mul.c @@ -0,0 +1,188 @@ +#include // for atoi + +#include +#include +#include +#include + +#define MEASURE_SAMPLE 0 + +/* for multiplying dim1 x dim2 x dim3 */ +typedef struct { + slong dim1; + slong dim2; + slong dim3; + slong modn; +} time_args; + +#define TIME_MUL(fun) \ +void time_##fun(time_args targs, flint_rand_t state) \ +{ \ + const slong dim1 = targs.dim1; \ + const slong dim2 = targs.dim2; \ + const slong dim3 = targs.dim3; \ + const slong modn = targs.modn; \ + \ + nmod_mat_t mat1; \ + nmod_mat_t mat2; \ + nmod_mat_t prod; \ + nmod_mat_init(mat1, dim1, dim2, modn); \ + nmod_mat_init(mat2, dim2, dim3, modn); \ + nmod_mat_init(prod, dim1, dim3, modn); \ + nmod_mat_rand(mat1, state); \ + nmod_mat_rand(mat2, state); \ + \ + double FLINT_SET_BUT_UNUSED(tcpu), twall; \ + \ + TIMEIT_START; \ + fun(prod, mat1, mat2); \ + TIMEIT_STOP_VALUES(tcpu, twall); \ + \ + flint_printf("%.2e", twall); \ + \ + nmod_mat_clear(mat1); \ + nmod_mat_clear(mat2); \ + nmod_mat_clear(prod); \ +} + +#define SAMPLE_MUL(fun) \ +void sample_##fun(void * arg, ulong count) \ +{ \ + time_args * targs = (time_args *) arg; \ + const slong dim1 = targs->dim1; \ + const slong dim2 = targs->dim2; \ + const slong dim3 = targs->dim3; \ + const slong modn = targs->modn; \ + \ + FLINT_TEST_INIT(state); \ + \ + nmod_mat_t mat1; \ + nmod_mat_t mat2; \ + nmod_mat_t prod; \ + nmod_mat_init(mat1, dim1, dim2, modn); \ + nmod_mat_init(mat2, dim2, dim3, modn); \ + nmod_mat_rand(mat1, state); \ + nmod_mat_rand(mat2, state); \ + for (ulong i = 0; i < count; i++) \ + { \ + nmod_mat_t tmp1; \ + nmod_mat_t tmp2; \ + nmod_mat_init(tmp1, dim1, dim2, modn); \ + nmod_mat_init(tmp2, dim2, dim3, modn); \ + nmod_mat_init(prod, dim1, dim3, modn); \ + for (slong k = 0; k < dim1*dim2; k++) \ + tmp1->entries[k] = mat1->entries[k]; \ + for (slong k = 0; k < dim2*dim3; k++) \ + tmp2->entries[k] = mat2->entries[k]; \ + prof_start(); \ + fun(prod, tmp1, tmp2); \ + prof_stop(); \ + nmod_mat_clear(prod); \ + nmod_mat_clear(tmp1); \ + nmod_mat_clear(tmp2); \ + } \ + \ + nmod_mat_clear(mat1); \ + nmod_mat_clear(mat2); \ + FLINT_TEST_CLEAR(state); \ +} + +TIME_MUL(nmod_mat_mul) +TIME_MUL(nmod_mat_mul_classical) +TIME_MUL(nmod_mat_mul_classical_threaded) +TIME_MUL(nmod_mat_mul_blas) +TIME_MUL(nmod_mat_mul_strassen) + +SAMPLE_MUL(nmod_mat_mul) +SAMPLE_MUL(nmod_mat_mul_classical) +SAMPLE_MUL(nmod_mat_mul_classical_threaded) +SAMPLE_MUL(nmod_mat_mul_blas) +SAMPLE_MUL(nmod_mat_mul_strassen) + +/*-------------------------*/ +/* main */ +/*-------------------------*/ +int main(int argc, char ** argv) +{ + flint_rand_t state; + flint_rand_init(state); + flint_rand_set_seed(state, time(NULL), time(NULL)+129384125L); + + // bench functions + const slong nfuns = 5; + typedef void (*timefun) (time_args, flint_rand_t); + const timefun funs[] = { + time_nmod_mat_mul, // 0 + time_nmod_mat_mul_classical, // 1 + time_nmod_mat_mul_classical_threaded, // 2 + time_nmod_mat_mul_blas, // 3 + time_nmod_mat_mul_strassen, // 4 + }; + + typedef void (*samplefun) (void*, ulong); + const samplefun sfuns[] = { + sample_nmod_mat_mul, // 0 + sample_nmod_mat_mul_classical, // 1 + sample_nmod_mat_mul_classical_threaded, // 2 + sample_nmod_mat_mul_blas, // 3 + sample_nmod_mat_mul_strassen, // 4 + }; + + const char * description[] = { + "#0 --> nmod_mat_mul ", + "#1 --> nmod_mat_mul_classical ", + "#2 --> nmod_mat_mul_classical_threaded ", + "#3 --> nmod_mat_mul_blas ", + "#4 --> nmod_mat_mul_strassen ", + }; + + if (argc == 1) // show usage + { + flint_printf("Usage: `%s [nbits] [fun] [dim1] [dim2] [dim3]`\n", argv[0]); + flint_printf(" No argument shows this help.\n"); + flint_printf(" - nbits: number of bits, in (0..63], for the randomly-chosen modulus\n"); + flint_printf(" - fun: id number of the timed function (see below),\n"); + flint_printf(" - dim1, dim2, dim3: matrix dimensions\n"); + flint_printf("\nAvailable functions:\n"); + for (slong j = 0; j < nfuns; j++) + flint_printf(" %s\n", description[j]); + + return 0; + } + + /* flint_printf("#warmup...\n"); */ + for (slong i = 0; i < 3; i++) + { + time_args targs = {i*100, i*100, i*100, 17 + (UWORD(1) << (i*17))}; + double min, max; + prof_repeat(&min, &max, sfuns[0], &targs); + } + /* flint_printf("\n\n"); */ + + if (argc == 6) + { + const slong b = atoi(argv[1]); + const slong ifun = atoi(argv[2]); + const slong dim1 = atoi(argv[3]); + const slong dim2 = atoi(argv[4]); + const slong dim3 = atoi(argv[5]); + flint_printf("bits fun dim1 dim2 dim3 \n"); + + ulong n = n_nextprime(UWORD(1) << (b-1), 1); + + flint_printf("%-4ld %-3ld %-6ld%-6ld%-6ld", b, ifun, dim1, dim2, dim3); + time_args targs = {dim1, dim2, dim3, n}; + +#if MEASURE_SAMPLE + double min, max; + prof_repeat(&min, &max, sfuns[ifun], &targs); + flint_printf("%.2e", min/1000000); +#else + funs[ifun](targs, state); +#endif + flint_printf("\n"); + } + + flint_rand_clear(state); + return 0; +} diff --git a/flint-extras/src/nmod_mat_extra/profile/p-solve.c b/flint-extras/src/nmod_mat_extra/profile/p-solve.c new file mode 100644 index 00000000..d5651643 --- /dev/null +++ b/flint-extras/src/nmod_mat_extra/profile/p-solve.c @@ -0,0 +1,162 @@ +#include +#include // for atoi + +#include +#include +#include +#include + +#define MEASURE_SAMPLE 0 + +/* for solve of dim1 x dim1 and dim1 x dim2 */ +typedef struct { + slong dim1; + slong dim2; + slong modn; +} time_args; + +#define TIME_SOLVE(fun) \ +void time_##fun(time_args targs, flint_rand_t state) \ +{ \ + const slong dim1 = targs.dim1; \ + const slong dim2 = targs.dim2; \ + const slong modn = targs.modn; \ + \ + nmod_mat_t mat; \ + nmod_mat_t rhs; \ + nmod_mat_t res; \ + nmod_mat_init(mat, dim1, dim1, modn); \ + nmod_mat_init(rhs, dim1, dim2, modn); \ + nmod_mat_init(res, dim1, dim2, modn); \ + nmod_mat_rand(mat, state); \ + \ + double FLINT_SET_BUT_UNUSED(tcpu), twall; \ + \ + TIMEIT_START; \ + fun(res, mat, rhs); \ + TIMEIT_STOP_VALUES(tcpu, twall); \ + \ + flint_printf("%.2e", twall); \ + \ + nmod_mat_clear(mat); \ + nmod_mat_clear(rhs); \ + nmod_mat_clear(res); \ +} + +#define SAMPLE_SOLVE(fun) \ +void sample_##fun(void * arg, ulong count) \ +{ \ + time_args * targs = (time_args *) arg; \ + const slong dim1 = targs->dim1; \ + const slong dim2 = targs->dim2; \ + const slong modn = targs->modn; \ + \ + FLINT_TEST_INIT(state); \ + \ + nmod_mat_t mat; \ + nmod_mat_t rhs; \ + nmod_mat_t res; \ + nmod_mat_init(mat, dim1, dim1, modn); \ + nmod_mat_init(rhs, dim1, dim2, modn); \ + nmod_mat_init(res, dim1, dim2, modn); \ + nmod_mat_rand(mat, state); \ + for (ulong i = 0; i < count; i++) \ + { \ + nmod_mat_t tmp; \ + nmod_mat_init(tmp, dim1, dim1, modn); \ + for (slong k = 0; k < dim1*dim1; k++) \ + tmp->entries[k] = mat->entries[k]; \ + prof_start(); \ + fun(res, mat, rhs); \ + prof_stop(); \ + nmod_mat_clear(tmp); \ + } \ + \ + nmod_mat_clear(mat); \ + nmod_mat_clear(rhs); \ + nmod_mat_clear(res); \ + FLINT_TEST_CLEAR(state); \ +} + +TIME_SOLVE(nmod_mat_solve) + +SAMPLE_SOLVE(nmod_mat_solve) + +/*-------------------------*/ +/* main */ +/*-------------------------*/ +int main(int argc, char ** argv) +{ + flint_rand_t state; + flint_rand_init(state); + flint_rand_set_seed(state, time(NULL), time(NULL)+129384125L); + + // bench functions + const slong nfuns = 4; + typedef void (*timefun) (time_args, flint_rand_t); + const timefun funs[] = { + time_nmod_mat_solve, // 0 + }; + + typedef void (*samplefun) (void*, ulong); + const samplefun sfuns[] = { + sample_nmod_mat_solve, // 0 + }; + + const char * description[] = { + "#0 --> nmod_mat_solve ", + }; + + if (argc == 1) // show usage + { + flint_printf("Usage: `%s [nbits] [fun] [dim1] [dim2]`\n", argv[0]); + flint_printf(" No argument shows this help.\n"); + flint_printf(" - nbits: number of bits, in (0..63], for the randomly-chosen modulus\n"); + flint_printf(" - fun: id number of the timed function (see below),\n"); + flint_printf(" - dim1, dim2: matrix dimensions, solving dim1 x dim1 with rhs of dimensions dim1 x dim2\n"); + flint_printf("\nAvailable functions:\n"); + for (slong j = 0; j < nfuns; j++) + flint_printf(" %s\n", description[j]); + + return 0; + } + + /* flint_printf("#warmup...\n"); */ + for (slong i = 0; i < 3; i++) + { + time_args targs = { + i*100, + i*100, + n_nextprime(17 + (UWORD(1) << (i*17)), 0) + }; + double min, max; + prof_repeat(&min, &max, sfuns[0], &targs); + } + /* flint_printf("\n\n"); */ + + if (argc == 5) + { + const slong b = atoi(argv[1]); + const slong ifun = atoi(argv[2]); + const slong dim1 = atoi(argv[3]); + const slong dim2 = atoi(argv[4]); + flint_printf("bits fun dim1 dim2 \n"); + + ulong n = n_nextprime(UWORD(1) << (b-1), 1); + + flint_printf("%-4ld %-3ld %-6ld%-6ld", b, ifun, dim1, dim2); + time_args targs = {dim1, dim2, n}; + +#if MEASURE_SAMPLE + double min, max; + prof_repeat(&min, &max, sfuns[ifun], &targs); + flint_printf("%.2e", min/1000000); +#else + funs[ifun](targs, state); +#endif + flint_printf("\n"); + } + + flint_rand_clear(state); + return 0; +} From 6589d6e7f04501b56c457954db9d67aba9ae1218 Mon Sep 17 00:00:00 2001 From: Vincent Neiger Date: Thu, 26 Mar 2026 16:14:29 +0100 Subject: [PATCH 2/4] profile nmod poly mul --- .../src/nmod_poly_extra/nmod_poly_rand.c | 3 - .../src/nmod_poly_extra/profile/p-mul.c | 188 ++++++++++++++++++ 2 files changed, 188 insertions(+), 3 deletions(-) create mode 100644 flint-extras/src/nmod_poly_extra/profile/p-mul.c diff --git a/flint-extras/src/nmod_poly_extra/nmod_poly_rand.c b/flint-extras/src/nmod_poly_extra/nmod_poly_rand.c index 57ba6017..f3cc86f0 100644 --- a/flint-extras/src/nmod_poly_extra/nmod_poly_rand.c +++ b/flint-extras/src/nmod_poly_extra/nmod_poly_rand.c @@ -37,6 +37,3 @@ void nmod_poly_rand_monic(nmod_poly_t pol, pol->length = len; } } - -/* -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -// vim:sts=4:sw=4:ts=4:et:sr:cino=>s,f0,{0,g0,(0,\:0,t0,+0,=s diff --git a/flint-extras/src/nmod_poly_extra/profile/p-mul.c b/flint-extras/src/nmod_poly_extra/profile/p-mul.c new file mode 100644 index 00000000..416ff819 --- /dev/null +++ b/flint-extras/src/nmod_poly_extra/profile/p-mul.c @@ -0,0 +1,188 @@ +#include +#include // for atoi + +#include +#include +#include +#include +#include "nmod_poly_extra.h" + +#define MEASURE_SAMPLE 0 + +/* for multiplication in length len1 x len2 */ +typedef struct { + slong len1; + slong len2; + slong modn; +} time_args; + +#define TIME_MUL(fun) \ +void time_##fun(time_args targs, flint_rand_t state) \ +{ \ + const slong len1 = targs.len1; \ + const slong len2 = targs.len2; \ + const slong modn = targs.modn; \ + \ + nmod_poly_t pol1; \ + nmod_poly_t pol2; \ + nmod_poly_t prod; \ + nmod_poly_init(pol1, modn); \ + nmod_poly_init(pol2, modn); \ + nmod_poly_init(prod, modn); \ + nmod_poly_rand(pol1, state, len1); \ + nmod_poly_rand(pol2, state, len2); \ + \ + double FLINT_SET_BUT_UNUSED(tcpu), twall; \ + \ + TIMEIT_START; \ + fun(prod, pol1, pol2); \ + TIMEIT_STOP_VALUES(tcpu, twall); \ + \ + flint_printf("%.2e", twall); \ + \ + nmod_poly_clear(pol1); \ + nmod_poly_clear(pol2); \ + nmod_poly_clear(prod); \ +} + +#define SAMPLE_MUL(fun) \ +void sample_##fun(void * arg, ulong count) \ +{ \ + time_args * targs = (time_args *) arg; \ + const slong len1 = targs->len1; \ + const slong len2 = targs->len2; \ + const slong modn = targs->modn; \ + \ + FLINT_TEST_INIT(state); \ + \ + nmod_poly_t pol1; \ + nmod_poly_t pol2; \ + nmod_poly_t prod; \ + nmod_poly_init(pol1, modn); \ + nmod_poly_init(pol2, modn); \ + nmod_poly_init(prod, modn); \ + nmod_poly_rand(pol1, state, len1); \ + nmod_poly_rand(pol2, state, len2); \ + for (ulong i = 0; i < count; i++) \ + { \ + nmod_poly_t tmp1; \ + nmod_poly_t tmp2; \ + nmod_poly_init(tmp1, modn); \ + nmod_poly_init(tmp2, modn); \ + nmod_poly_set(tmp1, pol1); \ + nmod_poly_set(tmp2, pol2); \ + prof_start(); \ + fun(prod, tmp1, tmp2); \ + prof_stop(); \ + nmod_poly_clear(tmp1); \ + nmod_poly_clear(tmp2); \ + } \ + \ + nmod_poly_clear(pol1); \ + nmod_poly_clear(pol2); \ + nmod_poly_clear(prod); \ + FLINT_TEST_CLEAR(state); \ +} + +TIME_MUL(nmod_poly_mul) +TIME_MUL(nmod_poly_mul_classical) +TIME_MUL(nmod_poly_mul_KS) +TIME_MUL(nmod_poly_mul_KS2) +TIME_MUL(nmod_poly_mul_KS4) + +SAMPLE_MUL(nmod_poly_mul) +SAMPLE_MUL(nmod_poly_mul_classical) +SAMPLE_MUL(nmod_poly_mul_KS) +SAMPLE_MUL(nmod_poly_mul_KS2) +SAMPLE_MUL(nmod_poly_mul_KS4) + +/*-------------------------*/ +/* main */ +/*-------------------------*/ +int main(int argc, char ** argv) +{ + flint_rand_t state; + flint_rand_init(state); + flint_rand_set_seed(state, time(NULL), time(NULL)+129384125L); + + // bench functions + const slong nfuns = 5; + typedef void (*timefun) (time_args, flint_rand_t); + const timefun funs[] = { + time_nmod_poly_mul, // 0 + time_nmod_poly_mul_classical, // 1 + time_nmod_poly_mul_KS, // 2 + time_nmod_poly_mul_KS2, // 3 + time_nmod_poly_mul_KS4, // 4 + }; + + typedef void (*samplefun) (void*, ulong); + const samplefun sfuns[] = { + sample_nmod_poly_mul, // 0 + sample_nmod_poly_mul_classical, // 1 + sample_nmod_poly_mul_KS, // 2 + sample_nmod_poly_mul_KS2, // 3 + sample_nmod_poly_mul_KS4, // 4 + }; + + const char * description[] = { + "#0 --> nmod_poly_mul ", + "#1 --> nmod_poly_mul_classical ", + "#2 --> nmod_poly_mul_KS ", + "#3 --> nmod_poly_mul_KS2 ", + "#4 --> nmod_poly_mul_KS4 ", + }; + + if (argc == 1) // show usage + { + flint_printf("Usage: `%s [nbits] [fun] [len1] [len2]`\n", argv[0]); + flint_printf(" No argument shows this help.\n"); + flint_printf(" - nbits: number of bits, in (0..63], for the randomly-chosen modulus\n"); + flint_printf(" - fun: id number of the timed function (see below),\n"); + flint_printf(" - len1, len2: length of polynomials to be multiplied\n"); + flint_printf("\nAvailable functions:\n"); + for (slong j = 0; j < nfuns; j++) + flint_printf(" %s\n", description[j]); + + return 0; + } + + /* flint_printf("#warmup...\n"); */ + for (slong i = 0; i < 3; i++) + { + time_args targs = { + i*100, + i*100, + n_nextprime(17 + (UWORD(1) << (i*17)), 0) + }; + double min, max; + prof_repeat(&min, &max, sfuns[0], &targs); + } + /* flint_printf("\n\n"); */ + + if (argc == 5) + { + const slong b = atoi(argv[1]); + const slong ifun = atoi(argv[2]); + const slong len1 = atoi(argv[3]); + const slong len2 = atoi(argv[4]); + flint_printf("bits fun len1 len2 \n"); + + ulong n = n_nextprime(UWORD(1) << (b-1), 1); + + flint_printf("%-4ld %-3ld %-10ld%-10ld", b, ifun, len1, len2); + time_args targs = {len1, len2, n}; + +#if MEASURE_SAMPLE + double min, max; + prof_repeat(&min, &max, sfuns[ifun], &targs); + flint_printf("%.2e", min/1000000); +#else + funs[ifun](targs, state); +#endif + flint_printf("\n"); + } + + flint_rand_clear(state); + return 0; +} From dd19623df15702f55d68d127dc475f8dbb9d1a5a Mon Sep 17 00:00:00 2001 From: Vincent Neiger Date: Thu, 26 Mar 2026 16:25:48 +0100 Subject: [PATCH 3/4] profile nmod poly divrem --- .../src/nmod_poly_extra/profile/p-divrem.c | 179 ++++++++++++++++++ 1 file changed, 179 insertions(+) create mode 100644 flint-extras/src/nmod_poly_extra/profile/p-divrem.c diff --git a/flint-extras/src/nmod_poly_extra/profile/p-divrem.c b/flint-extras/src/nmod_poly_extra/profile/p-divrem.c new file mode 100644 index 00000000..1c96e74c --- /dev/null +++ b/flint-extras/src/nmod_poly_extra/profile/p-divrem.c @@ -0,0 +1,179 @@ +#include +#include // for atoi + +#include +#include +#include +#include +#include "nmod_poly_extra.h" + +#define MEASURE_SAMPLE 0 + +/* for divrem for lengths len1 and len2 */ +typedef struct { + slong len1; + slong len2; + slong modn; +} time_args; + +#define TIME_DIV(fun) \ +void time_##fun(time_args targs, flint_rand_t state) \ +{ \ + const slong len1 = targs.len1; \ + const slong len2 = targs.len2; \ + const slong modn = targs.modn; \ + \ + nmod_poly_t pol1; \ + nmod_poly_t pol2; \ + nmod_poly_init(pol1, modn); \ + nmod_poly_init(pol2, modn); \ + nmod_poly_rand(pol1, state, len1); \ + nmod_poly_rand(pol2, state, len2); \ + nmod_poly_t quo; \ + nmod_poly_t rem; \ + nmod_poly_init(quo, modn); \ + nmod_poly_init(rem, modn); \ + \ + double FLINT_SET_BUT_UNUSED(tcpu), twall; \ + \ + TIMEIT_START; \ + fun(quo, rem, pol1, pol2); \ + TIMEIT_STOP_VALUES(tcpu, twall); \ + \ + flint_printf("%.2e", twall); \ + \ + nmod_poly_clear(pol1); \ + nmod_poly_clear(pol2); \ + nmod_poly_clear(quo); \ + nmod_poly_clear(rem); \ +} + +#define SAMPLE_DIV(fun) \ +void sample_##fun(void * arg, ulong count) \ +{ \ + time_args * targs = (time_args *) arg; \ + const slong len1 = targs->len1; \ + const slong len2 = targs->len2; \ + const slong modn = targs->modn; \ + \ + FLINT_TEST_INIT(state); \ + \ + nmod_poly_t pol1; \ + nmod_poly_t pol2; \ + nmod_poly_init(pol1, modn); \ + nmod_poly_init(pol2, modn); \ + nmod_poly_rand(pol1, state, len1); \ + nmod_poly_rand(pol2, state, len2); \ + nmod_poly_t quo; \ + nmod_poly_t rem; \ + nmod_poly_init(quo, modn); \ + nmod_poly_init(rem, modn); \ + for (ulong i = 0; i < count; i++) \ + { \ + nmod_poly_t tmp1; \ + nmod_poly_t tmp2; \ + nmod_poly_init(tmp1, modn); \ + nmod_poly_init(tmp2, modn); \ + nmod_poly_set(tmp1, pol1); \ + nmod_poly_set(tmp2, pol2); \ + prof_start(); \ + fun(quo, rem, tmp1, tmp2); \ + prof_stop(); \ + nmod_poly_clear(tmp1); \ + nmod_poly_clear(tmp2); \ + } \ + \ + nmod_poly_clear(pol1); \ + nmod_poly_clear(pol2); \ + nmod_poly_clear(quo); \ + nmod_poly_clear(rem); \ + FLINT_TEST_CLEAR(state); \ +} + +TIME_DIV(nmod_poly_divrem) +TIME_DIV(nmod_poly_divrem_basecase) + +SAMPLE_DIV(nmod_poly_divrem) +SAMPLE_DIV(nmod_poly_divrem_basecase) + +/*-------------------------*/ +/* main */ +/*-------------------------*/ +int main(int argc, char ** argv) +{ + flint_rand_t state; + flint_rand_init(state); + flint_rand_set_seed(state, time(NULL), time(NULL)+129384125L); + + // bench functions + const slong nfuns = 2; + typedef void (*timefun) (time_args, flint_rand_t); + const timefun funs[] = { + time_nmod_poly_divrem, // 0 + time_nmod_poly_divrem_basecase, // 1 + }; + + typedef void (*samplefun) (void*, ulong); + const samplefun sfuns[] = { + sample_nmod_poly_divrem, // 0 + sample_nmod_poly_divrem_basecase, // 1 + }; + + const char * description[] = { + "#0 --> nmod_poly_divrem ", + "#1 --> nmod_poly_divrem_basecase ", + }; + + if (argc == 1) // show usage + { + flint_printf("Usage: `%s [nbits] [fun] [len1] [len2]`\n", argv[0]); + flint_printf(" No argument shows this help.\n"); + flint_printf(" - nbits: number of bits, in (0..63], for the randomly-chosen modulus\n"); + flint_printf(" - fun: id number of the timed function (see below),\n"); + flint_printf(" - len1, len2: length of polynomials\n"); + flint_printf("\nAvailable functions:\n"); + for (slong j = 0; j < nfuns; j++) + flint_printf(" %s\n", description[j]); + + return 0; + } + + /* flint_printf("#warmup...\n"); */ + for (slong i = 0; i < 3; i++) + { + time_args targs = { + (i+1)*100, + (i+1)*100, + n_nextprime(17 + (UWORD(1) << (i*17)), 0) + }; + double min, max; + prof_repeat(&min, &max, sfuns[0], &targs); + } + /* flint_printf("\n\n"); */ + + if (argc == 5) + { + const slong b = atoi(argv[1]); + const slong ifun = atoi(argv[2]); + const slong len1 = atoi(argv[3]); + const slong len2 = atoi(argv[4]); + flint_printf("bits fun len1 len2 \n"); + + ulong n = n_nextprime(UWORD(1) << (b-1), 1); + + flint_printf("%-4ld %-3ld %-10ld%-10ld", b, ifun, len1, len2); + time_args targs = {len1, len2, n}; + +#if MEASURE_SAMPLE + double min, max; + prof_repeat(&min, &max, sfuns[ifun], &targs); + flint_printf("%.2e", min/1000000); +#else + funs[ifun](targs, state); +#endif + flint_printf("\n"); + } + + flint_rand_clear(state); + return 0; +} From 1ba6b6a5e084012cfdc1013f95ba2df247bfae38 Mon Sep 17 00:00:00 2001 From: Vincent Neiger Date: Thu, 26 Mar 2026 16:36:14 +0100 Subject: [PATCH 4/4] profile nmod poly xgcd --- .../src/nmod_poly_extra/profile/p-xgcd.c | 190 ++++++++++++++++++ 1 file changed, 190 insertions(+) create mode 100644 flint-extras/src/nmod_poly_extra/profile/p-xgcd.c diff --git a/flint-extras/src/nmod_poly_extra/profile/p-xgcd.c b/flint-extras/src/nmod_poly_extra/profile/p-xgcd.c new file mode 100644 index 00000000..3843be5d --- /dev/null +++ b/flint-extras/src/nmod_poly_extra/profile/p-xgcd.c @@ -0,0 +1,190 @@ +#include +#include // for atoi + +#include +#include +#include +#include +#include "nmod_poly_extra.h" + +#define MEASURE_SAMPLE 0 + +/* for xgcd for lengths len1 and len2 */ +typedef struct { + slong len1; + slong len2; + slong modn; +} time_args; + +#define TIME_XGCD(fun) \ +void time_##fun(time_args targs, flint_rand_t state) \ +{ \ + const slong len1 = targs.len1; \ + const slong len2 = targs.len2; \ + const slong modn = targs.modn; \ + \ + nmod_poly_t pol1; \ + nmod_poly_t pol2; \ + nmod_poly_init(pol1, modn); \ + nmod_poly_init(pol2, modn); \ + nmod_poly_rand(pol1, state, len1); \ + nmod_poly_rand(pol2, state, len2); \ + nmod_poly_t u; \ + nmod_poly_t v; \ + nmod_poly_t g; \ + nmod_poly_init(u, modn); \ + nmod_poly_init(v, modn); \ + nmod_poly_init(g, modn); \ + \ + double FLINT_SET_BUT_UNUSED(tcpu), twall; \ + \ + TIMEIT_START; \ + fun(g, u, v, pol1, pol2); \ + TIMEIT_STOP_VALUES(tcpu, twall); \ + \ + flint_printf("%.2e", twall); \ + \ + nmod_poly_clear(pol1); \ + nmod_poly_clear(pol2); \ + nmod_poly_clear(u); \ + nmod_poly_clear(v); \ + nmod_poly_clear(g); \ +} + +#define SAMPLE_XGCD(fun) \ +void sample_##fun(void * arg, ulong count) \ +{ \ + time_args * targs = (time_args *) arg; \ + const slong len1 = targs->len1; \ + const slong len2 = targs->len2; \ + const slong modn = targs->modn; \ + \ + FLINT_TEST_INIT(state); \ + \ + nmod_poly_t pol1; \ + nmod_poly_t pol2; \ + nmod_poly_init(pol1, modn); \ + nmod_poly_init(pol2, modn); \ + nmod_poly_rand(pol1, state, len1); \ + nmod_poly_rand(pol2, state, len2); \ + nmod_poly_t u; \ + nmod_poly_t v; \ + nmod_poly_t g; \ + nmod_poly_init(u, modn); \ + nmod_poly_init(v, modn); \ + nmod_poly_init(g, modn); \ + for (ulong i = 0; i < count; i++) \ + { \ + nmod_poly_t tmp1; \ + nmod_poly_t tmp2; \ + nmod_poly_init(tmp1, modn); \ + nmod_poly_init(tmp2, modn); \ + nmod_poly_set(tmp1, pol1); \ + nmod_poly_set(tmp2, pol2); \ + prof_start(); \ + fun(g, u, v, tmp1, tmp2); \ + prof_stop(); \ + nmod_poly_clear(tmp1); \ + nmod_poly_clear(tmp2); \ + } \ + \ + nmod_poly_clear(pol1); \ + nmod_poly_clear(pol2); \ + nmod_poly_clear(u); \ + nmod_poly_clear(v); \ + nmod_poly_clear(g); \ + FLINT_TEST_CLEAR(state); \ +} + +TIME_XGCD(nmod_poly_xgcd) +TIME_XGCD(nmod_poly_xgcd_hgcd) +TIME_XGCD(nmod_poly_xgcd_euclidean) + +SAMPLE_XGCD(nmod_poly_xgcd) +SAMPLE_XGCD(nmod_poly_xgcd_hgcd) +SAMPLE_XGCD(nmod_poly_xgcd_euclidean) + +/*-------------------------*/ +/* main */ +/*-------------------------*/ +int main(int argc, char ** argv) +{ + flint_rand_t state; + flint_rand_init(state); + flint_rand_set_seed(state, time(NULL), time(NULL)+129384125L); + + // bench functions + const slong nfuns = 2; + typedef void (*timefun) (time_args, flint_rand_t); + const timefun funs[] = { + time_nmod_poly_xgcd, // 0 + time_nmod_poly_xgcd_hgcd, // 1 + time_nmod_poly_xgcd_euclidean, // 2 + }; + + typedef void (*samplefun) (void*, ulong); + const samplefun sfuns[] = { + sample_nmod_poly_xgcd, // 0 + sample_nmod_poly_xgcd_hgcd, // 1 + sample_nmod_poly_xgcd_euclidean, // 2 + }; + + const char * description[] = { + "#0 --> nmod_poly_xgcd ", + "#1 --> nmod_poly_xgcd_hgcd ", + "#2 --> nmod_poly_xgcd_euclidean ", + }; + + if (argc == 1) // show usage + { + flint_printf("Usage: `%s [nbits] [fun] [len1] [len2]`\n", argv[0]); + flint_printf(" No argument shows this help.\n"); + flint_printf(" - nbits: number of bits, in (0..63], for the randomly-chosen modulus\n"); + flint_printf(" - fun: id number of the timed function (see below),\n"); + flint_printf(" - len1, len2: length of polynomials\n"); + flint_printf("\nAvailable functions:\n"); + for (slong j = 0; j < nfuns; j++) + flint_printf(" %s\n", description[j]); + + return 0; + } + + /* flint_printf("#warmup...\n"); */ + for (slong i = 0; i < 3; i++) + { + time_args targs = { + (i+1)*100, + (i+1)*100, + n_nextprime(17 + (UWORD(1) << (i*17)), 0) + }; + double min, max; + prof_repeat(&min, &max, sfuns[0], &targs); + } + /* flint_printf("\n\n"); */ + + if (argc == 5) + { + const slong b = atoi(argv[1]); + const slong ifun = atoi(argv[2]); + const slong len1 = atoi(argv[3]); + const slong len2 = atoi(argv[4]); + flint_printf("bits fun len1 len2 \n"); + + ulong n = n_nextprime(UWORD(1) << (b-1), 1); + + flint_printf("%-4ld %-3ld %-10ld%-10ld", b, ifun, len1, len2); + time_args targs = {len1, len2, n}; + +#if MEASURE_SAMPLE + double min, max; + prof_repeat(&min, &max, sfuns[ifun], &targs); + flint_printf("%.2e", min/1000000); +#else + funs[ifun](targs, state); +#endif + flint_printf("\n"); + } + + flint_rand_clear(state); + return 0; +}