/* Tests zn_array_mulmid_fft, for given n1, n2, modulus. If use_scale is set, zn_array_mulmid_fft() gets called with a random x (post-scaling factor), otherwise gets called with x == 1. Returns 1 on success. */ int testcase_zn_array_mulmid_fft (size_t n1, size_t n2, int use_scale, const zn_mod_t mod) { ulong* buf1 = (ulong*) malloc (sizeof (ulong) * n1); ulong* buf2 = (ulong*) malloc (sizeof (ulong) * n2); ulong* ref = (ulong*) malloc (sizeof (ulong) * (n1 - n2 + 1)); ulong* res = (ulong*) malloc (sizeof (ulong) * (n1 - n2 + 1)); // generate random polys size_t i; for (i = 0; i < n1; i++) buf1[i] = random_ulong (mod->m); for (i = 0; i < n2; i++) buf2[i] = random_ulong (mod->m); ulong x = use_scale ? random_ulong (mod->m) : 1; // compare target implementation against reference implementation ref_zn_array_mulmid (ref, buf1, n1, buf2, n2, mod); ref_zn_array_scalar_mul (ref, ref, n1 - n2 + 1, x, mod); zn_array_mulmid_fft (res, buf1, n1, buf2, n2, x, mod); ulong y = zn_array_mulmid_fft_fudge (n1, n2, mod); ref_zn_array_scalar_mul (res, res, n1 - n2 + 1, y, mod); int success = !zn_array_cmp (ref, res, n1 - n2 + 1); free (res); free (ref); free (buf2); free (buf1); return success; }
/* Tests zn_array_mul_fft_dft, for given lengths, lgT, modulus. Returns 1 on success. */ int testcase_zn_array_mul_fft_dft (size_t n1, size_t n2, unsigned lgT, const zn_mod_t mod) { ulong* buf1 = (ulong*) malloc (sizeof (ulong) * n1); ulong* buf2 = (ulong*) malloc (sizeof (ulong) * n2); ulong* ref = (ulong*) malloc (sizeof (ulong) * (n1 + n2 - 1)); ulong* res = (ulong*) malloc (sizeof (ulong) * (n1 + n2 - 1)); // generate random polys size_t i; for (i = 0; i < n1; i++) buf1[i] = random_ulong (mod->m); for (i = 0; i < n2; i++) buf2[i] = random_ulong (mod->m); // compare target implementation against reference implementation ref_zn_array_mul (ref, buf1, n1, buf2, n2, mod); zn_array_mul_fft_dft (res, buf1, n1, buf2, n2, lgT, mod); int success = !zn_array_cmp (ref, res, n1 + n2 - 1); free (res); free (ref); free (buf2); free (buf1); return success; }
/* Tests zn_array_invert() on a range of problems. */ int test_zn_array_invert (int quick) { int success = 1; int b, trial; size_t n; zn_mod_t mod; // first try a dense range of "small" problems for (b = 2; b <= ULONG_BITS && success; b++) for (n = 1; n <= 60 && success; n++) for (trial = 0; trial < (quick ? 1 : 10) && success; trial++) { zn_mod_init (mod, random_modulus (b, 0)); success = success && testcase_zn_array_invert (n, mod); zn_mod_clear (mod); } // now try a few larger random problems for (b = 2; b <= ULONG_BITS && success; b += (quick ? random_ulong (3) + 1 : 1)) for (trial = 0; trial < (quick ? 1 : 5) && success; trial++) { zn_mod_init (mod, random_modulus (b, 0)); n = random_ulong (quick ? 2000 : 10000) + 1; success = success && testcase_zn_array_invert (n, mod); zn_mod_clear (mod); } return success; }
/* tests zn_array_mul_fft() on a range of input cases */ int test_zn_array_mul_or_sqr_fft (int sqr, int quick) { int success = 1; int i, trial, use_scale; size_t n1, n2; zn_mod_t mod; // first try a dense range of "small" problems for (i = 0; i < num_test_bitsizes && success; i++) for (n2 = 1; n2 <= 50 && success; n2 += (quick ? 3 : 1)) for (n1 = n2; n1 <= 50 && (!sqr || n1 <= n2) && success; n1 += (quick ? 3 : 1)) for (use_scale = 0; use_scale <= 1 && success; use_scale++) for (trial = 0; trial < (quick ? 1 : 3) && success; trial++) { zn_mod_init (mod, random_modulus (test_bitsizes[i], 1)); success = success && testcase_zn_array_mul_fft (n1, n2, sqr, use_scale, mod); zn_mod_clear (mod); } // now try some random larger problems // and temporarily change the nussbaumer thresholds so we use that // code sometimes unsigned thresh; for (i = 0; i < num_test_bitsizes && success; i++) { unsigned b = test_bitsizes[i]; unsigned* c = sqr ? &(tuning_info[b].nuss_sqr_thresh) : &(tuning_info[b].nuss_mul_thresh); for (use_scale = 0; use_scale <= 1 && success; use_scale++) for (thresh = 2; thresh <= 8 && success; thresh += (quick ? 4 : 1)) { unsigned save_thresh = *c; *c = thresh; size_t t1 = random_ulong (quick ? 3000 : 10000) + 1; size_t t2 = sqr ? t1 : (random_ulong (quick ? 3000 : 10000) + 1); n1 = ZNP_MAX (t1, t2); n2 = ZNP_MIN (t1, t2); zn_mod_init (mod, random_modulus (b, 1)); success = success && testcase_zn_array_mul_fft (n1, n2, sqr, use_scale, mod); zn_mod_clear (mod); *c = save_thresh; } } return success; }
/* Tests zn_array_invert() for a given series length and modulus. */ int testcase_zn_array_invert (size_t n, const zn_mod_t mod) { ulong* op = (ulong*) malloc (sizeof (ulong) * n); ulong* res = (ulong*) malloc (sizeof (ulong) * n); ulong* check = (ulong*) malloc (sizeof (ulong) * (2 * n - 1)); // make up random input poly size_t i; op[0] = 1; for (i = 1; i < n; i++) op[i] = random_ulong (mod->m); // compute inverse zn_array_invert (res, op, n, mod); // multiply by original series and check we get 1 ref_zn_array_mul (check, op, n, res, n, mod); int success = (check[0] == 1); for (i = 1; i < n; i++) success = success && (check[i] == 0); free (check); free (res); free (op); return success; }
/* Consume some resources, then terminate this process in some abnormal way. */ static int NO_INLINE consume_some_resources_and_die (int seed) { consume_some_resources (); random_init (seed); int *PHYS_BASE = (int *)0xC0000000; switch (random_ulong () % 5) { case 0: *(int *) NULL = 42; case 1: return *(int *) NULL; case 2: return *PHYS_BASE; case 3: *PHYS_BASE = 42; case 4: open ((char *)PHYS_BASE); exit (-1); default: NOT_REACHED (); } return 0; }
void agent_fun(void *aux){ int i=0; while(i<5){ sema_down(&agent); long num=random_ulong()%3; if (tobaco_match==num) { sema_up(&smoker1); }else if(match_paper==num){ sema_up(&smoker2); }else if(paper_tobaco){ sema_up(&smoker3); } i++; } }
/* tests zn_array_pack() once for given n, b, k */ int testcase_zn_array_pack (size_t n, unsigned b, unsigned k) { ZNP_ASSERT (b >= 1); ZNP_ASSERT (n >= 1); int success = 1; ulong* in = (ulong*) malloc (sizeof (ulong) * n); size_t size = CEIL_DIV (n * b + k, GMP_NUMB_BITS); mp_limb_t* res = (mp_limb_t*) malloc (sizeof (mp_limb_t) * (size + 2)); mp_limb_t* ref = (mp_limb_t*) malloc (sizeof (mp_limb_t) * (size + 2)); // sentries to check buffer overflow res[0] = res[size + 1] = ref[0] = ref[size + 1] = 0x1234; // generate random data: at most b bits per input coefficient, possibly less unsigned rand_bits = (b >= ULONG_BITS) ? ULONG_BITS : b; rand_bits = random_ulong (rand_bits) + 1; ulong max = (rand_bits == ULONG_BITS) ? ((ulong)(-1)) : ((1UL << rand_bits) - 1); size_t i; for (i = 0; i < n; i++) in[i] = random_ulong (max); // run target and reference implementation zn_array_pack (res + 1, in, n, 1, b, k, 0); ref_zn_array_pack (ref + 1, in, n, b, k); // check sentries success = success && (res[0] == 0x1234); success = success && (ref[0] == 0x1234); success = success && (res[size + 1] == 0x1234); success = success && (ref[size + 1] == 0x1234); // check correct result success = success && (mpn_cmp (res + 1, ref + 1, size) == 0); free (ref); free (res); free (in); return success; }
/*! Shuffles the CNT elements in ARRAY into random order. */ static void shuffle(int *array, size_t cnt) { size_t i; for (i = 0; i < cnt; i++) { size_t j = i + random_ulong() % (cnt - i); int t = array[j]; array[j] = array[i]; array[i] = t; } }
void shuffle (void *buf_, size_t cnt, size_t size) { char *buf = buf_; size_t i; for (i = 0; i < cnt; i++) { size_t j = i + random_ulong () % (cnt - i); swap (buf + i * size, buf + j * size, size); } }
/* tests zn_array_mul_fft_dft() on a range of input cases */ int test_zn_array_mul_fft_dft (int quick) { int success = 1; int i, trial; unsigned lgT; size_t n1, n2; zn_mod_t mod; for (i = 0; i < num_test_bitsizes && success; i++) for (n2 = 1; n2 <= 30 && success; n2 += (quick ? random_ulong (2) + 1 : 1)) for (n1 = n2; n1 <= 30 && success; n1 += (quick ? random_ulong (2) + 1 : 1)) for (lgT = 0; lgT < 5 && success; lgT++) for (trial = 0; trial < (quick ? 1 : 3) && success; trial++) { zn_mod_init (mod, random_modulus (test_bitsizes[i], 1)); success = success && testcase_zn_array_mul_fft_dft (n1, n2, lgT, mod); zn_mod_clear (mod); } return success; }
/* If lgT == 0, this tests pmfvec_fft_dc. If lgT > 0, it tests pmfvec_fft_huge. */ int testcase_pmfvec_fft_dc_or_huge (unsigned lgK, unsigned lgM, unsigned lgT, ulong n, ulong z, ulong t, const zn_mod_t mod) { pmfvec_t A, B; ulong M = 1UL << lgM; ulong K = 1UL << lgK; ptrdiff_t skip = M + 1; ulong i; pmfvec_init (A, lgK, skip, lgM, mod); pmfvec_init (B, lgK, skip, lgM, mod); // create random a_i's, with zero padding for (i = z; i < K; i++) pmf_zero (A->data + i * skip, M); for (i = z; i < K; i++) A->data[i * skip] = random_ulong (2 * M); for (i = 0; i < z; i++) pmf_rand (A->data + i * skip, M, mod); // run FFT using simple iterative algorithm pmfvec_set (B, A); pmfvec_fft_basecase (B, t); // make sure truncated FFT has to deal with random crap for (i = z; i < K; i++) pmf_rand (A->data + i * skip, M, mod); // try truncated FFT if (lgT > 0) pmfvec_fft_huge (A, lgT, n, z, t); else pmfvec_fft_dc (A, n, z, t); // compare results int success = 1; for (i = 0; i < n; i++) success = success && !pmf_cmp (A->data + i * skip, B->data + i * skip, M, mod); pmfvec_clear (B); pmfvec_clear (A); return success; }
static void write_some_bytes (const char *file_name, int fd, const char *buf, size_t *ofs) { if (*ofs < FILE_SIZE) { size_t block_size = random_ulong () % (FILE_SIZE / 8) + 1; size_t ret_val; if (block_size > FILE_SIZE - *ofs) block_size = FILE_SIZE - *ofs; ret_val = write (fd, buf + *ofs, block_size); if (ret_val != block_size) fail ("write %zu bytes at offset %zu in \"%s\" returned %zu", block_size, *ofs, file_name, ret_val); *ofs += block_size; } }
/* Randomly sellects a page to evict. */ struct frame *get_frame_for_eviction() { struct hash_iterator hi; struct hash_elem e; ASSERT(lock_held_by_current_thread(&ft_lock)); // lock_acquire(&ft_lock); do { long index = random_ulong() % hash_size(&frame_table); hash_first(&hi, &frame_table); for(int i = 0; i < index; i++) hash_next(&hi); } while(!lock_try_acquire(&get_frame(hash_cur(&hi))->evicting)); struct frame *f = get_frame(hash_cur(&hi)); ASSERT(!f->page->deleting); // lock_release(&ft_lock); return f; }
/* Tests mpn_smp_kara for a range of n. */ int test_mpn_smp_kara (int quick) { int success = 1; size_t n; ulong trial; // first a dense range of small problems for (n = 2; n <= 30 && success; n++) for (trial = 0; trial < (quick ? 300 : 30000) && success; trial++) success = success && testcase_mpn_smp_kara (n); // now a few larger problems too for (trial = 0; trial < (quick ? 100 : 3000) && success; trial++) { n = random_ulong (3 * ZNP_mpn_smp_kara_thresh) + 2; success = success && testcase_mpn_smp_kara (n); } return success; }
void expand (int num, char **grammar[], char *location[], int handle) { char *word; int i, which, listStart, listEnd; which = random_ulong () % location[num][0] + 1; listStart = location[num][which]; listEnd = location[num][which + 1]; for (i = listStart; i < listEnd; i++) { word = grammar[num][i]; if (!isdigit (*word)) { if (!ispunct (*word)) hprintf (handle, " "); hprintf (handle, "%s", word); } else expand (atoi (word), grammar, location, handle); } }
void CrossBridge(int direc,int prio) { timer_sleep(((random_ulong() % 5) + 1) * 7); }
int main (int argc, char *argv[]) { if (argc != 3) fail ("huge-file: Error, usage: %s min_max_size_in_bytes niter", argv[0]); /* The minimum "max file size" we tolerate. */ long min_max_size = atol (argv[1]); int niter = atoi (argv[2]); int i; long initial_max_file_size = -1; char zeros[CHUNK_SIZE]; char out_buf[CHUNK_SIZE]; char in_buf[CHUNK_SIZE]; char tmp_buf[CHUNK_SIZE]; memset (zeros, 0, CHUNK_SIZE); random_bytes (out_buf, CHUNK_SIZE); for (i = 0; i < niter; i++) { int create_big = random_ulong () % 2; int sparse = random_ulong () % 2; //msg ("iter %i: create_big %i sparse %i", i, create_big, sparse); long bytes_written = 0; long init_size = (create_big ? min_max_size : 0); if (!create (file, init_size)) fail ("Error, could not create (\"%s\", %li)", file, init_size); int fd = open (file); if (fd < 0) fail ("Error, open (%s, 0) gave fd %i\n", file, fd); if (sparse) { /* Make the file sparse and read prior to each write. */ seek (fd, min_max_size); char c = 0; if (write (fd, &c, 1) != 1) fail ("Error, could not write file sparsely: offset %li\n", min_max_size); /* Now do a read-write sequence. Ensure every read returns nulls. */ long offset = 0; while (1) { //msg ("read-write sequence: num %i offset %li", offset/CHUNK_SIZE, offset); /* Read and verify it's nulls. */ seek (fd, offset); long n_read = read (fd, in_buf, CHUNK_SIZE); if (n_read != CHUNK_SIZE && offset+CHUNK_SIZE < min_max_size) fail ("Error, read %li instead of %i and I'm not at the end of the file\n", n_read, CHUNK_SIZE); if (memcmp (in_buf, zeros, n_read)) { printf ("Error, read something besides zeros between offset %li and %li\n", offset, offset + n_read); printf ("I expected:\n"); print_buf (zeros, n_read); printf ("I read:\n"); print_buf (in_buf, n_read); fail ("Error, see above.\n"); } /* Write data. */ seek (fd, offset); long n_written = write (fd, out_buf, CHUNK_SIZE); bytes_written += n_written; int verify_after_write = random_ulong () % 2; if (verify_after_write) { seek (fd, offset); long n_read = read (fd, tmp_buf, CHUNK_SIZE); if (n_read != n_written) fail ("Error, verifying after write, and I read %li bytes after writing %li bytes\n", n_read, n_written); long j; for (j = 0; j < n_read; j++) { if (tmp_buf[j] != out_buf[j]) fail ("Error, mismatch between write and subsequent read. Offset %li expected <%c> read <%c>\n", offset + j, out_buf[j], tmp_buf[j]); } } if (n_written != CHUNK_SIZE) break; offset += CHUNK_SIZE; } } else { /* Just write out the file until it fails. */ seek (fd, 0); long offset = 0; while (1) { //msg ("write sequence: num %li offset %li", offset/CHUNK_SIZE, offset); long n_written = write (fd, out_buf, CHUNK_SIZE); bytes_written += n_written; if (n_written != CHUNK_SIZE) break; offset += CHUNK_SIZE; } //msg ("Max file size: %li", bytes_written); } close (fd); if (!remove (file)) fail ("Error, could not delete file %s", file); if (i == 0) initial_max_file_size = bytes_written; /* Must be at least min_max_size bytes. */ if (bytes_written < min_max_size) fail ("Error, could only write %li < %li bytes", bytes_written, min_max_size); /* Should be the same number every time, whatever it is. */ if (initial_max_file_size != bytes_written) fail ("Error, on the first iteration I was able to write a total of %li bytes. On this iteration I wrote %li bytes. Why do these differ?", initial_max_file_size, bytes_written); } return 0; }
/* If lgT == 0, this tests pmfvec_ifft_dc. If lgT > 0, it tests pmfvec_ifft_huge. */ int testcase_pmfvec_ifft_dc_or_huge (unsigned lgK, unsigned lgM, unsigned lgT, ulong n, int fwd, ulong z, ulong t, const zn_mod_t mod) { pmfvec_t A, B, C; ulong M = 1UL << lgM; ulong K = 1UL << lgK; ulong x = zn_mod_reduce (K, mod); ptrdiff_t skip = M + 1; ulong i; pmfvec_init (A, lgK, skip, lgM, mod); pmfvec_init (B, lgK, skip, lgM, mod); pmfvec_init (C, lgK, skip, lgM, mod); // create random a_i's, with zero padding for (i = z; i < K; i++) pmf_zero (A->data + i * skip, M); for (i = z; i < K; i++) A->data[i * skip] = random_ulong (2 * M); for (i = 0; i < z; i++) pmf_rand (A->data + i * skip, M, mod); // run FFT pmfvec_set (B, A); pmfvec_fft (B, K, K, t); pmfvec_set (C, B); // fill in missing data, plus junk where the implied zeroes should be for (i = n; i < z; i++) { pmf_set (C->data + i * skip, A->data + i * skip, M); pmf_scalar_mul (C->data + i * skip, M, x, mod); } for (i = z; i < K; i++) pmf_rand (C->data + i * skip, M, mod); // try IFFT if (lgT > 0) pmfvec_ifft_huge (C, lgT, n, fwd, z, t); else pmfvec_ifft_dc (C, n, fwd, z, t); // compare results int success = 1; for (i = 0; i < n; i++) pmf_scalar_mul (A->data + i * skip, M, x, mod); for (i = 0; i < n; i++) success = success && !pmf_cmp (C->data + i * skip, A->data + i * skip, M, mod); if (fwd) success = success && !pmf_cmp (C->data + i * skip, B->data + i * skip, M, mod); pmfvec_clear (C); pmfvec_clear (B); pmfvec_clear (A); return success; }
/* Picks a pivot for the quicksort from the SIZE bytes in BUF. */ static unsigned char pick_pivot (unsigned char *buf, size_t size) { ASSERT (size >= 1); return buf[random_ulong () % size]; }
int test_ZmodF_mul_info_mul_fft() { int success = 1; mp_limb_t in1[1000]; mp_limb_t in2[1000]; mp_limb_t out_plain[1000]; mp_limb_t out_fft[1000]; mpz_t x; mpz_init(x); for (unsigned long n = 1; n < 300 && success; n++) { for (unsigned long depth = 1; (n*FLINT_BITS) % (1 << depth) == 0 && (depth <= FLINT_LG_BITS_PER_LIMB + 4) && success; depth++) { unsigned long input_bits = (n*FLINT_BITS) >> depth; unsigned long output_bits = 2*input_bits + 1 + depth; unsigned long target_m = ((output_bits - 1) >> FLINT_LG_BITS_PER_LIMB) + 1; for (unsigned long m = target_m - 2; m <= target_m + 3 && success; m++) { if ((m*FLINT_BITS) % (1 << depth) != 0) continue; for (unsigned long k = 0; k <= 2 && success; k++) { if (m + k < target_m) continue; if (m + k > n) continue; if (k > m) continue; #if DEBUG printf("n = %ld, depth = %ld, m = %ld, k = %ld\n", n, depth, m, k); #endif ZmodF_mul_info_t info_plain, info_fft; ZmodF_mul_info_init_plain(info_plain, n, 0); ZmodF_mul_info_init_fft(info_fft, n, depth, m, k, 0); for (unsigned long trial = 0; trial < 10 && success; trial++) { if (random_ulong(4) == 0) { // put in -1 mod p every now and then ZmodF_zero(in1, n); in1[n] = 1; } else { random_limbs(in1, n); in1[n] = 0; } if (random_ulong(4) == 0) { // put in -1 mod p every now and then ZmodF_zero(in2, n); in2[n] = 1; } else { random_limbs(in2, n); in2[n] = 0; } // test multiplication ZmodF_mul_info_mul(info_plain, out_plain, in1, in2); ZmodF_mul_info_mul(info_fft, out_fft, in1, in2); ZmodF_normalise(out_plain, n); ZmodF_normalise(out_fft, n); if (mpn_cmp(out_plain, out_fft, n+1)) success = 0; // test squaring ZmodF_mul_info_mul(info_plain, out_plain, in1, in1); ZmodF_mul_info_mul(info_fft, out_fft, in1, in1); ZmodF_normalise(out_plain, n); ZmodF_normalise(out_fft, n); if (mpn_cmp(out_plain, out_fft, n+1)) success = 0; } ZmodF_mul_info_clear(info_fft); ZmodF_mul_info_clear(info_plain); } } } } mpz_clear(x); return success; }
int test_ZmodF_mul_info_mul_threeway() { int success = 1; mp_limb_t in1[2000]; mp_limb_t in2[2000]; mp_limb_t out_plain[2000]; mp_limb_t out_threeway[2000]; mpz_t x; mpz_init(x); for (unsigned long n = 3; n < 100 && success; n += 3) { #if DEBUG printf("n = %d\n", n); #endif ZmodF_mul_info_t info_plain, info_threeway; ZmodF_mul_info_init_threeway(info_threeway, n, 0); ZmodF_mul_info_init_plain(info_plain, n, 0); for (unsigned long trial = 0; trial < 50000 && success; trial++) { if (random_ulong(4) == 0) { // put in -1 mod p every now and then ZmodF_zero(in1, n); in1[n] = 1; } else { random_limbs(in1, n); in1[n] = 0; } if (random_ulong(4) == 0) { // put in -1 mod p every now and then ZmodF_zero(in2, n); in2[n] = 1; } else { random_limbs(in2, n); in2[n] = 0; } // test multiplication ZmodF_mul_info_mul(info_plain, out_plain, in1, in2); ZmodF_mul_info_mul(info_threeway, out_threeway, in1, in2); ZmodF_normalise(out_plain, n); ZmodF_normalise(out_threeway, n); if (mpn_cmp(out_plain, out_threeway, n+1)) success = 0; // test squaring ZmodF_mul_info_mul(info_plain, out_plain, in1, in1); ZmodF_mul_info_mul(info_threeway, out_threeway, in1, in1); ZmodF_normalise(out_plain, n); ZmodF_normalise(out_threeway, n); if (mpn_cmp(out_plain, out_threeway, n+1)) success = 0; } ZmodF_mul_info_clear(info_plain); ZmodF_mul_info_clear(info_threeway); } mpz_clear(x); return success; }
int test_ZmodF_mul_info_mul_plain() { int success = 1; mp_limb_t in1[2000]; mp_limb_t in2[2000]; mp_limb_t out[2000]; mpz_t x1, x2, y, z, p; mpz_init(x1); mpz_init(x2); mpz_init(y); mpz_init(z); mpz_init(p); for (unsigned long n = 1; n < 100 && success; n++) { #if DEBUG printf("n = %d\n", n); #endif // p = B^n + 1 mpz_set_ui(p, 1); mpz_mul_2exp(p, p, n*FLINT_BITS); mpz_add_ui(p, p, 1); ZmodF_mul_info_t info; ZmodF_mul_info_init_plain(info, n, 0); for (unsigned long trial = 0; trial < 1000 && success; trial++) { if (random_ulong(4) == 0) { // put in -1 mod p every now and then ZmodF_zero(in1, n); in1[n] = 1; } else { random_limbs(in1, n); in1[n] = 0; } if (random_ulong(4) == 0) { // put in -1 mod p every now and then ZmodF_zero(in2, n); in2[n] = 1; } else { random_limbs(in2, n); in2[n] = 0; } // test multiplication mpn_to_mpz(x1, in1, n+1); mpn_to_mpz(x2, in2, n+1); mpz_mul(z, x1, x2); mpz_mod(z, z, p); ZmodF_mul_info_mul(info, out, in1, in2); ZmodF_normalise(out, n); mpn_to_mpz(y, out, n+1); if (mpz_cmp(y, z)) success = 0; // test squaring mpz_mul(z, x1, x1); mpz_mod(z, z, p); ZmodF_mul_info_mul(info, out, in1, in1); ZmodF_normalise(out, n); mpn_to_mpz(y, out, n+1); if (mpz_cmp(y, z)) success = 0; } ZmodF_mul_info_clear(info); } mpz_clear(x1); mpz_clear(x2); mpz_clear(y); mpz_clear(z); mpz_clear(p); return success; }
int test__ZmodF_mul_fft_combine() { int success = 1; mpz_t x, y, p, q, r, s, total; mpz_init(x); mpz_init(y); mpz_init(s); mpz_init(r); mpz_init(q); mpz_init(p); mpz_init(total); mp_limb_t buf[300]; for (unsigned long n = 1; n < 80 && success; n++) { for (unsigned long depth = 0; ((n*FLINT_BITS) % (1 << depth) == 0) && success; depth++) { for (unsigned long m = 1; m < n/4 && success; m++) { for (unsigned long k = 0; k < 5 && success; k++) { #if DEBUG printf("n = %ld, depth = %ld, m = %ld, k = %ld\n", n, depth, m, k); #endif ZmodF_poly_t poly; ZmodF_poly_init(poly, depth, m+k, 1); // p := B^n + 1 mpz_set_ui(p, 1); mpz_mul_2exp(p, p, n*FLINT_BITS); mpz_add_ui(p, p, 1); // q := (B^m + 1)*B^k mpz_set_ui(q, 1); mpz_mul_2exp(q, q, m*FLINT_BITS); mpz_add_ui(q, q, 1); mpz_mul_2exp(q, q, k*FLINT_BITS); // r := B^(m+k) - 1 mpz_set_ui(r, 1); mpz_mul_2exp(r, r, (m+k)*FLINT_BITS); mpz_sub_ui(r, r, 1); // s := B^(m+k)/2 mpz_set_ui(s, 1); mpz_mul_2exp(s, s, (m+k)*FLINT_BITS - 1); for (unsigned long trial = 0; trial < 20 && success; trial++) { mpz_set_ui(total, 0); for (long i = (1 << depth) - 1; i >= 0; i--) { // select random x in (0, B^(m+k)) mpz_set_ui(x, 0); while (!mpz_sgn(x)) { mpz_rrandomb(x, randstate, (m+k)*FLINT_BITS); if (random_ulong(2)) // to get high bit 0 sometimes mpz_sub(x, r, x); } // push it down to (-B^(m+k)/2, B^(m+k)/2) mpz_sub(x, x, s); // add it to running total mpz_mul_2exp(total, total, (n*FLINT_BITS) >> depth); mpz_add(total, total, x); // normalise it into [0, q), and store in polynomial mpz_mod(x, x, q); mpz_to_mpn(poly->coeffs[i], m+k+1, x); } // compare result to target function _ZmodF_mul_fft_combine(buf, poly, m, k, n); ZmodF_normalise(buf, n); mpn_to_mpz(y, buf, n+1); mpz_mod(total, total, p); if (mpz_cmp(total, y)) success = 0; } ZmodF_poly_clear(poly); } } } } mpz_clear(x); mpz_clear(y); mpz_clear(s); mpz_clear(r); mpz_clear(q); mpz_clear(p); mpz_clear(total); return success; }
double profile_mulmid (void* arg, unsigned long count) { profile_info_struct* info = (profile_info_struct*) arg; size_t n1 = info->n1; size_t n2 = info->n2; zn_mod_t mod; zn_mod_init (mod, info->m); ulong* buf1 = (ulong*) malloc (sizeof (ulong) * n1); ulong* buf2 = (ulong*) malloc (sizeof (ulong) * n2); ulong* buf3 = (ulong*) malloc (sizeof (ulong) * (n1 - n2 + 1)); // generate random inputs size_t i; for (i = 0; i < n1; i++) buf1[i] = random_ulong (info->m); for (i = 0; i < n2; i++) buf2[i] = random_ulong (info->m); void (*target)(ulong*, const ulong*, size_t, const ulong*, size_t, int, const zn_mod_t); int redc; switch (info->algo) { case ALGO_MULMID_BEST: target = zn_array_mulmid_wrapper; break; case ALGO_MULMID_FALLBACK: target = zn_array_mulmid_fallback_wrapper; break; case ALGO_MULMID_KS1: target = zn_array_mulmid_KS1; redc = 0; break; case ALGO_MULMID_KS1_REDC: target = zn_array_mulmid_KS1; redc = 1; break; case ALGO_MULMID_KS2: target = zn_array_mulmid_KS2; redc = 0; break; case ALGO_MULMID_KS2_REDC: target = zn_array_mulmid_KS2; redc = 1; break; case ALGO_MULMID_KS3: target = zn_array_mulmid_KS3; redc = 0; break; case ALGO_MULMID_KS3_REDC: target = zn_array_mulmid_KS3; redc = 1; break; case ALGO_MULMID_KS4: target = zn_array_mulmid_KS4; redc = 0; break; case ALGO_MULMID_KS4_REDC: target = zn_array_mulmid_KS4; redc = 1; break; case ALGO_MULMID_FFT: target = zn_array_mulmid_fft_wrapper; break; default: abort (); } // warm up ulong j; for (j = 0; j < count/4; j++) target (buf3, buf1, n1, buf2, n2, redc, mod); // do the actual profile cycle_count_t t0 = get_cycle_counter (); for (j = 0; j < count; j++) target (buf3, buf1, n1, buf2, n2, redc, mod); cycle_count_t t1 = get_cycle_counter (); free (buf3); free (buf2); free (buf1); zn_mod_clear (mod); return cycle_diff (t0, t1); }