br_status factor_rewriter::mk_eq(expr * arg1, expr * arg2, expr_ref & result) { if (!a().is_real(arg1) && !m_arith.is_int(arg1)) { return BR_FAILED; } mk_adds(arg1, arg2); mk_muls(); if (m_muls.empty()) { result = m().mk_true(); return BR_DONE; } if (!extract_factors()) { TRACE("factor_rewriter", tout << mk_pp(arg1, m()) << " = " << mk_pp(arg2, m()) << "\n";);
//----------------------- NFS ENTRY POINT ------------------------------------// void nfs(fact_obj_t *fobj) { //expect the input in fobj->nfs_obj.gmp_n char *input; msieve_obj *obj = NULL; char *nfs_args = NULL; // unused as yet enum cpu_type cpu = yafu_get_cpu_type(); mp_t mpN; factor_list_t factor_list; uint32 flags = 0; nfs_job_t job; uint32 relations_needed = 1; uint32 last_specialq = 0; struct timeval stop; // stop time of this job struct timeval start; // start time of this job struct timeval bstop; // stop time of sieving batch struct timeval bstart; // start time of sieving batch TIME_DIFF * difference; double t_time; uint32 pre_batch_rels = 0; char tmpstr[GSTR_MAXSIZE]; int process_done; enum nfs_state_e nfs_state; // initialize some job parameters memset(&job, 0, sizeof(nfs_job_t)); obj_ptr = NULL; //below a certain amount, revert to SIQS if (gmp_base10(fobj->nfs_obj.gmp_n) < fobj->nfs_obj.min_digits) { mpz_set(fobj->qs_obj.gmp_n, fobj->nfs_obj.gmp_n); SIQS(fobj); mpz_set(fobj->nfs_obj.gmp_n, fobj->qs_obj.gmp_n); return; } if (mpz_probab_prime_p(fobj->nfs_obj.gmp_n, NUM_WITNESSES)) { add_to_factor_list(fobj, fobj->nfs_obj.gmp_n); if (VFLAG >= 0) gmp_printf("PRP%d = %Zd\n", gmp_base10(fobj->nfs_obj.gmp_n), fobj->nfs_obj.gmp_n); logprint_oc(fobj->flogname, "a", "PRP%d = %s\n", gmp_base10(fobj->nfs_obj.gmp_n), mpz_conv2str(&gstr1.s, 10, fobj->nfs_obj.gmp_n)); mpz_set_ui(fobj->nfs_obj.gmp_n, 1); return; } if (mpz_perfect_square_p(fobj->nfs_obj.gmp_n)) { mpz_sqrt(fobj->nfs_obj.gmp_n, fobj->nfs_obj.gmp_n); add_to_factor_list(fobj, fobj->nfs_obj.gmp_n); logprint_oc(fobj->flogname, "a", "prp%d = %s\n", gmp_base10(fobj->nfs_obj.gmp_n), mpz_conv2str(&gstr1.s, 10, fobj->nfs_obj.gmp_n)); add_to_factor_list(fobj, fobj->nfs_obj.gmp_n); logprint_oc(fobj->flogname, "a", "prp%d = %s\n", gmp_base10(fobj->nfs_obj.gmp_n), mpz_conv2str(&gstr1.s, 10, fobj->nfs_obj.gmp_n)); mpz_set_ui(fobj->nfs_obj.gmp_n, 1); return; } if (mpz_perfect_power_p(fobj->nfs_obj.gmp_n)) { FILE *flog; uint32 j; if (VFLAG > 0) printf("input is a perfect power\n"); factor_perfect_power(fobj, fobj->nfs_obj.gmp_n); flog = fopen(fobj->flogname, "a"); if (flog == NULL) { printf("fopen error: %s\n", strerror(errno)); printf("could not open %s for appending\n", fobj->flogname); exit(1); } logprint(flog,"input is a perfect power\n"); for (j=0; j<fobj->num_factors; j++) { uint32 k; for (k=0; k<fobj->fobj_factors[j].count; k++) { logprint(flog,"prp%d = %s\n",gmp_base10(fobj->fobj_factors[j].factor), mpz_conv2str(&gstr1.s, 10, fobj->fobj_factors[j].factor)); } } fclose(flog); return; } if (fobj->nfs_obj.filearg[0] != '\0') { if (VFLAG > 0) printf("test: starting trial sieving\n"); trial_sieve(fobj); return; } //initialize the flag to watch for interrupts, and set the //pointer to the function to call if we see a user interrupt NFS_ABORT = 0; signal(SIGINT,nfsexit); //start a counter for the whole job gettimeofday(&start, NULL); //nfs state machine: input = (char *)malloc(GSTR_MAXSIZE * sizeof(char)); nfs_state = NFS_STATE_INIT; process_done = 0; while (!process_done) { switch (nfs_state) { case NFS_STATE_INIT: // write the input bigint as a string input = mpz_conv2str(&input, 10, fobj->nfs_obj.gmp_n); // create an msieve_obj // this will initialize the savefile to the outputfile name provided obj = msieve_obj_new(input, flags, fobj->nfs_obj.outputfile, fobj->nfs_obj.logfile, fobj->nfs_obj.fbfile, g_rand.low, g_rand.hi, (uint32)0, cpu, (uint32)L1CACHE, (uint32)L2CACHE, (uint32)THREADS, (uint32)0, nfs_args); fobj->nfs_obj.mobj = obj; // initialize these before checking existing files. If poly // select is resumed they will be changed by check_existing_files. job.last_leading_coeff = 0; job.poly_time = 0; job.use_max_rels = 0; job.snfs = NULL; // determine what to do next based on the state of various files. // this will set job.current_rels if it finds any nfs_state = check_existing_files(fobj, &last_specialq, &job); // before we get started, check to make sure we can find ggnfs sievers // if we are going to be doing sieving if (check_for_sievers(fobj, 1) == 1) nfs_state = NFS_STATE_DONE; if (VFLAG >= 0 && nfs_state != NFS_STATE_DONE) gmp_printf("nfs: commencing nfs on c%d: %Zd\n", gmp_base10(fobj->nfs_obj.gmp_n), fobj->nfs_obj.gmp_n); if (nfs_state != NFS_STATE_DONE) logprint_oc(fobj->flogname, "a", "nfs: commencing nfs on c%d: %s\n", gmp_base10(fobj->nfs_obj.gmp_n), mpz_conv2str(&gstr1.s, 10, fobj->nfs_obj.gmp_n)); // convert input to msieve bigint notation and initialize a list of factors gmp2mp_t(fobj->nfs_obj.gmp_n,&mpN); factor_list_init(&factor_list); if (fobj->nfs_obj.rangeq > 0) job.qrange = ceil((double)fobj->nfs_obj.rangeq / (double)THREADS); break; case NFS_STATE_POLY: if ((fobj->nfs_obj.nfs_phases == NFS_DEFAULT_PHASES) || (fobj->nfs_obj.nfs_phases & NFS_PHASE_POLY)) { // always check snfs forms (it is fast) snfs_choose_poly(fobj, &job); if( job.snfs == NULL ) { // either we never were doing snfs, or snfs form detect failed. // if the latter then bail with an error because the user // explicitly wants to run snfs... if (fobj->nfs_obj.snfs) { printf("nfs: failed to find snfs polynomial!\n"); exit(-1); } // init job.poly for gnfs job.poly = (mpz_polys_t*)malloc(sizeof(mpz_polys_t)); if (job.poly == NULL) { printf("nfs: couldn't allocate memory!\n"); exit(-1); } mpz_polys_init(job.poly); job.poly->rat.degree = 1; // maybe way off in the future this isn't true // assume gnfs for now job.poly->side = ALGEBRAIC_SPQ; do_msieve_polyselect(fobj, obj, &job, &mpN, &factor_list); } else { fobj->nfs_obj.snfs = 1; mpz_set(fobj->nfs_obj.gmp_n, job.snfs->n); } } nfs_state = NFS_STATE_SIEVE; break; case NFS_STATE_SIEVE: pre_batch_rels = job.current_rels; gettimeofday(&bstart, NULL); // sieve if the user has requested to (or by default). else, // set the done sieving flag. this will prevent some infinite loops, // for instance if we only want to post-process, but filtering // doesn't produce a matrix. if we don't want to sieve in that case, // then we're done. if (((fobj->nfs_obj.nfs_phases == NFS_DEFAULT_PHASES) || (fobj->nfs_obj.nfs_phases & NFS_PHASE_SIEVE)) && !(fobj->nfs_obj.nfs_phases & NFS_DONE_SIEVING)) do_sieving(fobj, &job); else fobj->nfs_obj.nfs_phases |= NFS_DONE_SIEVING; // if this has been previously marked, then go ahead and exit. if (fobj->nfs_obj.nfs_phases & NFS_DONE_SIEVING) process_done = 1; // if user specified -ns with a fixed start and range, // then mark that we're done sieving. if (fobj->nfs_obj.rangeq > 0) { // we're done sieving the requested range, but there may be // more phases to check, so don't exit yet fobj->nfs_obj.nfs_phases |= NFS_DONE_SIEVING; } // then move on to the next phase nfs_state = NFS_STATE_FILTCHECK; break; case NFS_STATE_FILTER: // if we've flagged not to do filtering, then assume we have // enough relations and move on to linear algebra if ((fobj->nfs_obj.nfs_phases == NFS_DEFAULT_PHASES) || (fobj->nfs_obj.nfs_phases & NFS_PHASE_FILTER)) relations_needed = do_msieve_filtering(fobj, obj, &job); else relations_needed = 0; if (relations_needed == 0) nfs_state = NFS_STATE_LINALG; else { // if we filtered, but didn't produce a matrix, raise the target // min rels by a few percent. this will prevent too frequent // filtering attempts while allowing the q_batch size to remain small. if (job.current_rels > job.min_rels) job.min_rels = job.current_rels * fobj->nfs_obj.filter_min_rels_nudge; else job.min_rels *= fobj->nfs_obj.filter_min_rels_nudge; if (VFLAG > 0) printf("nfs: raising min_rels by %1.2f percent to %u\n", 100*(fobj->nfs_obj.filter_min_rels_nudge-1), job.min_rels); nfs_state = NFS_STATE_SIEVE; } break; case NFS_STATE_LINALG: if ((fobj->nfs_obj.nfs_phases == NFS_DEFAULT_PHASES) || (fobj->nfs_obj.nfs_phases & NFS_PHASE_LA) || (fobj->nfs_obj.nfs_phases & NFS_PHASE_LA_RESUME)) { // msieve: build matrix flags = 0; flags = flags | MSIEVE_FLAG_USE_LOGFILE; if (VFLAG > 0) flags = flags | MSIEVE_FLAG_LOG_TO_STDOUT; flags = flags | MSIEVE_FLAG_NFS_LA; // add restart flag if requested if (fobj->nfs_obj.nfs_phases & NFS_PHASE_LA_RESUME) flags |= MSIEVE_FLAG_NFS_LA_RESTART; obj->flags = flags; if (VFLAG >= 0) printf("nfs: commencing msieve linear algebra\n"); logprint_oc(fobj->flogname, "a", "nfs: commencing msieve linear algebra\n"); // use a different number of threads for the LA, if requested if (LATHREADS > 0) { msieve_obj_free(obj); obj = msieve_obj_new(input, flags, fobj->nfs_obj.outputfile, fobj->nfs_obj.logfile, fobj->nfs_obj.fbfile, g_rand.low, g_rand.hi, (uint32)0, cpu, (uint32)L1CACHE, (uint32)L2CACHE, (uint32)LATHREADS, (uint32)0, nfs_args); } // try this hack - store a pointer to the msieve obj so that // we can change a flag on abort in order to interrupt the LA. obj_ptr = obj; nfs_solve_linear_system(obj, fobj->nfs_obj.gmp_n); if (obj_ptr->flags & MSIEVE_FLAG_STOP_SIEVING) nfs_state = NFS_STATE_DONE; else { // check for a .dat.deps file. if we don't have one, assume // its because the job was way oversieved and only trivial // dependencies were found. try again from filtering with // 20% less relations. FILE *t; sprintf(tmpstr, "%s.dep", fobj->nfs_obj.outputfile); if ((t = fopen(tmpstr, "r")) == NULL) { if (job.use_max_rels > 0) { // we've already tried again with an attempted fix to the trivial // dependencies problem, so either that wasn't the problem or // it didn't work. either way, give up. printf("nfs: no dependency file retry failed\n"); fobj->flags |= FACTOR_INTERRUPT; nfs_state = NFS_STATE_DONE; } else { // this should be sufficient to produce a matrix, but not too much // to trigger the assumed failure mode. if (job.min_rels == 0) { // if min_rels is not set, then we need to parse the .job file to compute it. parse_job_file(fobj, &job); nfs_set_min_rels(&job); } job.use_max_rels = job.min_rels * 1.5; printf("nfs: no dependency file found - trying again with %u relations\n", job.use_max_rels); nfs_state = NFS_STATE_FILTER; } } else { fclose(t); nfs_state = NFS_STATE_SQRT; } } // set the msieve threads back to where it was if we used // a different amount for linalg if (LATHREADS > 0) { msieve_obj_free(obj); obj = msieve_obj_new(input, flags, fobj->nfs_obj.outputfile, fobj->nfs_obj.logfile, fobj->nfs_obj.fbfile, g_rand.low, g_rand.hi, (uint32)0, cpu, (uint32)L1CACHE, (uint32)L2CACHE, (uint32)THREADS, (uint32)0, nfs_args); } obj_ptr = NULL; } else // not doing linalg nfs_state = NFS_STATE_SQRT; break; case NFS_STATE_SQRT: if ((fobj->nfs_obj.nfs_phases == NFS_DEFAULT_PHASES) || (fobj->nfs_obj.nfs_phases & NFS_PHASE_SQRT)) { uint32 retcode; // msieve: find factors flags = 0; flags = flags | MSIEVE_FLAG_USE_LOGFILE; if (VFLAG > 0) flags = flags | MSIEVE_FLAG_LOG_TO_STDOUT; flags = flags | MSIEVE_FLAG_NFS_SQRT; obj->flags = flags; if (VFLAG >= 0) printf("nfs: commencing msieve sqrt\n"); logprint_oc(fobj->flogname, "a", "nfs: commencing msieve sqrt\n"); // try this hack - store a pointer to the msieve obj so that // we can change a flag on abort in order to interrupt the sqrt. obj_ptr = obj; retcode = nfs_find_factors(obj, fobj->nfs_obj.gmp_n, &factor_list); obj_ptr = NULL; if (retcode) { extract_factors(&factor_list,fobj); if (mpz_cmp_ui(fobj->nfs_obj.gmp_n, 1) == 0) nfs_state = NFS_STATE_CLEANUP; //completely factored, clean up everything else nfs_state = NFS_STATE_DONE; //not factored completely, keep files and stop } else { if (VFLAG >= 0) { printf("nfs: failed to find factors... possibly no dependencies found\n"); printf("nfs: continuing with sieving\n"); } logprint_oc(fobj->flogname, "a", "nfs: failed to find factors... " "possibly no dependencies found\n" "nfs: continuing with sieving\n"); nfs_state = NFS_STATE_SIEVE; } } else nfs_state = NFS_STATE_DONE; //not factored completely, keep files and stop break; case NFS_STATE_CLEANUP: remove(fobj->nfs_obj.outputfile); remove(fobj->nfs_obj.fbfile); sprintf(tmpstr, "%s.p",fobj->nfs_obj.outputfile); remove(tmpstr); sprintf(tmpstr, "%s.br",fobj->nfs_obj.outputfile); remove(tmpstr); sprintf(tmpstr, "%s.cyc",fobj->nfs_obj.outputfile); remove(tmpstr); sprintf(tmpstr, "%s.dep",fobj->nfs_obj.outputfile); remove(tmpstr); sprintf(tmpstr, "%s.hc",fobj->nfs_obj.outputfile); remove(tmpstr); sprintf(tmpstr, "%s.mat",fobj->nfs_obj.outputfile); remove(tmpstr); sprintf(tmpstr, "%s.lp",fobj->nfs_obj.outputfile); remove(tmpstr); sprintf(tmpstr, "%s.d",fobj->nfs_obj.outputfile); remove(tmpstr); sprintf(tmpstr, "%s.mat.chk",fobj->nfs_obj.outputfile); remove(tmpstr); gettimeofday(&stop, NULL); difference = my_difftime (&start, &stop); t_time = ((double)difference->secs + (double)difference->usecs / 1000000); free(difference); if (VFLAG >= 0) printf("NFS elapsed time = %6.4f seconds.\n",t_time); logprint_oc(fobj->flogname, "a", "NFS elapsed time = %6.4f seconds.\n",t_time); logprint_oc(fobj->flogname, "a", "\n"); logprint_oc(fobj->flogname, "a", "\n"); // free stuff nfs_state = NFS_STATE_DONE; break; case NFS_STATE_DONE: process_done = 1; break; case NFS_STATE_FILTCHECK: if (job.current_rels >= job.min_rels) { if (VFLAG > 0) printf("nfs: found %u relations, need at least %u, proceeding with filtering ...\n", job.current_rels, job.min_rels); nfs_state = NFS_STATE_FILTER; } else { // compute eta by dividing how many rels we have left to find // by the average time per relation. we have average time // per relation because we've saved the time it took to do // the last batch of sieving and we know how many relations we // found in that batch. uint32 est_time; gettimeofday(&bstop, NULL); difference = my_difftime (&bstart, &bstop); t_time = ((double)difference->secs + (double)difference->usecs / 1000000); free(difference); est_time = (uint32)((job.min_rels - job.current_rels) * (t_time / (job.current_rels - pre_batch_rels))); // if the user doesn't want to sieve, then we can't make progress. if ((fobj->nfs_obj.nfs_phases == NFS_DEFAULT_PHASES) || (fobj->nfs_obj.nfs_phases & NFS_PHASE_SIEVE)) { if (VFLAG > 0) printf("nfs: found %u relations, need at least %u " "(filtering ETA: %uh %um), continuing with sieving ...\n", // uh... um... hmm... idk *shrug* job.current_rels, job.min_rels, est_time / 3600, (est_time % 3600) / 60); nfs_state = NFS_STATE_SIEVE; } else { if (VFLAG > 0) printf("nfs: found %u relations, need at least %u " "(filtering ETA: %uh %um), sieving not selected, finishing ...\n", job.current_rels, job.min_rels, est_time / 3600, (est_time % 3600) / 60); nfs_state = NFS_STATE_DONE; } } break; case NFS_STATE_STARTNEW: nfs_state = NFS_STATE_POLY; // create a new directory for this job //#ifdef _WIN32 // sprintf(tmpstr, "%s\%s", fobj->nfs_obj.ggnfs_dir, // mpz_conv2str(&gstr1.s, 10, fobj->nfs_obj.gmp_n)); // mkdir(tmpstr); //#else // sprintf(tmpstr, "%s/%s", fobj->nfs_obj.ggnfs_dir, // mpz_conv2str(&gstr1.s, 10, fobj->nfs_obj.gmp_n)); // mkdir(tmpstr, S_IRWXU); //#endif // point msieve and ggnfs to the new directory //#ifdef _WIN32 // sprintf(fobj->nfs_obj.outputfile, "%s\%s", // tmpstr, fobj->nfs_obj.outputfile); // sprintf(fobj->nfs_obj.logfile, "%s\%s", // tmpstr, fobj->nfs_obj.logfile); // sprintf(fobj->nfs_obj.fbfile, "%s\%s", // tmpstr, fobj->nfs_obj.fbfile); //#else // sprintf(fobj->nfs_obj.outputfile, "%s%s", // tmpstr, fobj->nfs_obj.outputfile); // sprintf(fobj->nfs_obj.logfile, "%s%s", // tmpstr, fobj->nfs_obj.logfile); // sprintf(fobj->nfs_obj.fbfile, "%s%s", // tmpstr, fobj->nfs_obj.fbfile); // //#endif // // msieve_obj_free(fobj->nfs_obj.mobj); // obj = msieve_obj_new(input, flags, fobj->nfs_obj.outputfile, fobj->nfs_obj.logfile, // fobj->nfs_obj.fbfile, g_rand.low, g_rand.hi, (uint32)0, nfs_lower, nfs_upper, cpu, // (uint32)L1CACHE, (uint32)L2CACHE, (uint32)THREADS, (uint32)0, (uint32)0, 0.0); // fobj->nfs_obj.mobj = obj; // // printf("output: %s\n", fobj->nfs_obj.mobj->savefile.name); // printf("log: %s\n", fobj->nfs_obj.mobj->logfile_name); // printf("fb: %s\n", fobj->nfs_obj.mobj->nfs_fbfile_name); break; // should really be "resume_job", since we do more than just resume sieving... case NFS_STATE_RESUMESIEVE: // last_specialq == 0 if: // 1) user specifies -R and -ns with params // 2) user specifies post processing steps only // 3) user wants to resume sieving (either with a solo -ns or no arguements) // but no data file or special-q was found // 4) -R was not specified (but then we won't be in this state, we'll be in DONE) // last_specialq > 1 if: // 5) user wants to resume sieving (either with a solo -ns or no arguements) // and a data file and special-q was found // 6) it contains poly->time info (in which case we'll be in NFS_STATE_RESUMEPOLY) strcpy(tmpstr, ""); if ((last_specialq == 0) && ((fobj->nfs_obj.nfs_phases == NFS_DEFAULT_PHASES) || (fobj->nfs_obj.nfs_phases & NFS_PHASE_SIEVE))) { // this if-block catches cases 1 and 3 from above uint32 missing_params = parse_job_file(fobj, &job); // set min_rels. get_ggnfs_params(fobj, &job); fill_job_file(fobj, &job, missing_params); // if any ggnfs params are missing, fill them // this means the user can provide an SNFS poly or external GNFS poly, // but let YAFU choose the other params // this won't override any params in the file. if (fobj->nfs_obj.startq > 0) { job.startq = fobj->nfs_obj.startq; sprintf(tmpstr, "nfs: resuming with sieving at user specified special-q %u\n", job.startq); } else { // this is a guess, may be completely wrong job.startq = (job.poly->side == RATIONAL_SPQ ? job.rlim : job.alim) / 2; sprintf(tmpstr, "nfs: continuing with sieving - could not determine " "last special q; using default startq\n"); } // next step is sieving nfs_state = NFS_STATE_SIEVE; } else if ((last_specialq == 0) && ((fobj->nfs_obj.nfs_phases & NFS_PHASE_FILTER) || (fobj->nfs_obj.nfs_phases & NFS_PHASE_LA) || (fobj->nfs_obj.nfs_phases & NFS_PHASE_LA_RESUME) || (fobj->nfs_obj.nfs_phases & NFS_PHASE_SQRT))) { // this if-block catches case 2 from above // with these options we don't check for the last special-q, so this isn't // really a new factorization if ((fobj->nfs_obj.nfs_phases & NFS_PHASE_FILTER)) { nfs_state = NFS_STATE_FILTCHECK; sprintf(tmpstr, "nfs: resuming with filtering\n"); } else if ((fobj->nfs_obj.nfs_phases & NFS_PHASE_LA) || (fobj->nfs_obj.nfs_phases & NFS_PHASE_LA_RESUME)) { nfs_state = NFS_STATE_LINALG; sprintf(tmpstr, "nfs: resuming with linear algebra\n"); } else if (fobj->nfs_obj.nfs_phases & NFS_PHASE_SQRT) { nfs_state = NFS_STATE_SQRT; sprintf(tmpstr, "nfs: resuming with sqrt\n"); } } else // data file already exists { // this if-block catches case 5 from above (void) parse_job_file(fobj, &job); // set min_rels. get_ggnfs_params(fobj, &job); if (fobj->nfs_obj.startq > 0) { // user wants to resume sieving. // i don't believe this case is ever executed... // because if startq is > 0, then last_specialq will be 0... job.startq = fobj->nfs_obj.startq; nfs_state = NFS_STATE_SIEVE; } else { job.startq = last_specialq; // we found some relations - find the appropriate state // given user input if ((fobj->nfs_obj.nfs_phases == NFS_DEFAULT_PHASES) || (fobj->nfs_obj.nfs_phases & NFS_PHASE_FILTER)) { nfs_state = NFS_STATE_FILTCHECK; sprintf(tmpstr, "nfs: resuming with filtering\n"); } else if (fobj->nfs_obj.nfs_phases & NFS_PHASE_SIEVE) { nfs_state = NFS_STATE_SIEVE; sprintf(tmpstr, "nfs: resuming with sieving at special-q = %u\n", last_specialq); } else if ((fobj->nfs_obj.nfs_phases & NFS_PHASE_LA) || (fobj->nfs_obj.nfs_phases & NFS_PHASE_LA_RESUME)) { nfs_state = NFS_STATE_LINALG; sprintf(tmpstr, "nfs: resuming with linear algebra\n"); } else if (fobj->nfs_obj.nfs_phases & NFS_PHASE_SQRT) { nfs_state = NFS_STATE_SQRT; sprintf(tmpstr, "nfs: resuming with sqrt\n"); } } } if (VFLAG >= 0) printf("%s", tmpstr); logprint_oc(fobj->flogname, "a", "%s", tmpstr); // if there is a job file and the user has specified -np, print // this warning. if (fobj->nfs_obj.nfs_phases & NFS_PHASE_POLY) { printf("WARNING: .job file exists! If you really want to redo poly selection," " delete the .job file.\n"); // non ideal solution to infinite loop in factor() if we return without factors // (should return error code instead) NFS_ABORT = 1; process_done = 1; } break; case NFS_STATE_RESUMEPOLY: if (VFLAG > 1) printf("nfs: resuming poly select\n"); fobj->nfs_obj.polystart = job.last_leading_coeff; nfs_state = NFS_STATE_POLY; break; default: printf("unknown state, bailing\n"); // non ideal solution to infinite loop in factor() if we return without factors // (should return error code instead) NFS_ABORT = 1; break; } //after every state, check elasped time against a specified timeout value gettimeofday(&stop, NULL); difference = my_difftime (&start, &stop); t_time = ((double)difference->secs + (double)difference->usecs / 1000000); free(difference); if ((fobj->nfs_obj.timeout > 0) && (t_time > (double)fobj->nfs_obj.timeout)) { if (VFLAG >= 0) printf("NFS timeout after %6.4f seconds.\n",t_time); logprint_oc(fobj->flogname, "a", "NFS timeout after %6.4f seconds.\n",t_time); process_done = 1; } if (NFS_ABORT) { print_factors(fobj); exit(1); } } //reset signal handler to default (no handler). signal(SIGINT,NULL); if (obj != NULL) msieve_obj_free(obj); free(input); if( job.snfs ) { snfs_clear(job.snfs); free(job.snfs); } else if( job.poly ) { mpz_polys_free(job.poly); free(job.poly); } return; }