diff --git a/lib/pari.c b/lib/pari.c index 680510e2e2f93f3bc8c282f718b77945970ad824..4f104f696bafe3eb738aac4f96f0b86fb77651c2 100644 --- a/lib/pari.c +++ b/lib/pari.c @@ -33,6 +33,8 @@ static void FpX_get_mpzx (mpzx_ptr f, GEN x); static GEN cert_get_V (mpz_t **cert, int depth); static bool primecertentryisvalid (GEN c, int i, bool type, bool verbose); static int primecertpartialisvalid (GEN c, bool type, bool verbose); +GEN cm_pari_primecertentryisvalid_worker (GEN i, GEN c, GEN type, + GEN verbose); /*****************************************************************************/ /* */ @@ -1282,6 +1284,21 @@ static bool primecertentryisvalid (GEN c, int i, bool type, bool verbose) /*****************************************************************************/ +GEN cm_pari_primecertentryisvalid_worker (GEN i, GEN c, GEN type, + GEN verbose) + /* A version of the previous function adapted to use in parfor. */ +{ + int il = itos (i); + bool typel = (itos (type) == 1); + bool verbosel = (itos (verbose) == 1); + + bool res = primecertentryisvalid (c, il, typel, verbosel); + + return stoi ((int) res); +} + +/*****************************************************************************/ + static int primecertpartialisvalid (GEN c, bool type, bool verbose) /* Check whether c is a valid partial ECPP certificate. type indicates whether the certificate is of type created by CM @@ -1292,7 +1309,7 @@ static int primecertpartialisvalid (GEN c, bool type, bool verbose) 1 means the certificate is valid and its first entry is a proven prime. */ { - int depth, val, res, i; + int depth, val, res; GEN ci, N, t, s, q; pari_sp av; @@ -1303,8 +1320,32 @@ static int primecertpartialisvalid (GEN c, bool type, bool verbose) depth = glength (c); val = 0; - for (i = 1; i <= depth; i++) - val += (primecertentryisvalid (c, i, type, verbose) ? 1 : 0); + { + /* Call primecertentryisvalid in parallel with early abort as soon + as an entry is invalid. */ + parfor_t iter; + GEN p2; + static entree functions_gp []={ + {"_cm_pari_primecertentryisvalid_worker", 0, + (void*) cm_pari_primecertentryisvalid_worker, 11, "GGGG", + "worker for primecertentryisvalid", + NULL, 0, 0, NULL}, + {NULL, 0, NULL, 0, NULL, NULL, NULL, 0, 0, NULL}}; + + pari_add_module (functions_gp); + parfor_init (&iter, gen_1, stoi (depth), + strtoclosure("_cm_pari_primecertentryisvalid_worker", 3, + c, stoi (type == true), stoi (verbose == true))); + + while ((p2 = parfor_next (&iter))) { + if (equalui (0, gel (p2, 2))) { + parfor_stop (&iter); + break; + } + else + val++; + } + } if (val != depth) return 0; @@ -1340,7 +1381,7 @@ bool cm_pari_ecpp_check (mpz_t **cert, int depth) c = cert_get_V (cert, depth); - res = (primecertpartialisvalid (c, true, true) == 1); + res = (primecertpartialisvalid (c, true, false) == 1); avma = av;