END_TEST START_TEST(test_ck_assert_uint_ge) { unsigned int x = 2; unsigned int y = 3; ck_assert_uint_ge(y, x); ck_assert_uint_ge(y, x); ck_assert_uint_ge(x, y); #define LINENO_ck_assert_uint_ge _STR(__LINE__) }
static unsigned char *gen_random_data(size_t minlen, size_t maxlen, size_t *outlen) { unsigned char *result; unsigned long rval; size_t rlen; int res; ck_assert_uint_ge(maxlen, minlen); res = RAND_pseudo_bytes((unsigned char *)&rval, sizeof(rval)); ck_assert(res == 0 || res == 1); rlen = minlen + (rval % (maxlen - minlen + 1)); result = malloc(rlen); ck_assert(result != NULL); res = RAND_pseudo_bytes(result, rlen); ck_assert(res == 0 || res == 1); *outlen = rlen; return result; }
END_TEST START_TEST(test_all_backends_fail) { size_t item_count = 10; const unsigned char keydata[] = "342f48a2c3a152a0fe39df4f2bca34d3c6c56e57797f0da682a6154ef7b674e3" "9c131c0c70442f94b865a5e0e030b48f4f51969fb80d5251fd67023c9982d3ab" "1ffd27717200ccb3c92882b10a04129422d5b71ddfaf24daf9fb5ee9cdfa2ef0"; size_t val_len; const unsigned char *val; pid_t mc_pid0, mc_pid1; int mc_port0 = ot_start_memcached(NULL, &mc_pid0); int mc_port1 = ot_start_memcached(NULL, &mc_pid1); char strbuf[100]; sprintf(strbuf, "127.0.0.1:%d,127.0.0.1:%d", mc_port0, mc_port1); omcache_t *oc = ot_init_omcache(0, LOG_INFO); ck_omcache_ok(omcache_set_servers(oc, strbuf)); ck_omcache_ok(omcache_set_dead_timeout(oc, 1000)); ck_omcache_ok(omcache_set_connect_timeout(oc, 2000)); ck_omcache_ok(omcache_set_reconnect_timeout(oc, 3000)); // send noops to both servers and write a bunch of values to them to make // sure we're connected to both servers and ketama picks both servers ck_omcache_ok(omcache_noop(oc, 0, 1000)); ck_omcache_ok(omcache_noop(oc, 1, 1000)); for (size_t i = 0; i < item_count; i ++) ck_omcache(omcache_set(oc, keydata + i, 100, keydata + i, 100, 0, 0, 0, 0), OMCACHE_BUFFERED); ck_omcache_ok(omcache_io(oc, NULL, NULL, NULL, NULL, 5000)); for (size_t i = 0; i < item_count; i ++) { ck_omcache_ok(omcache_get(oc, keydata + i, 100, &val, &val_len, NULL, NULL, 3000)); ck_assert_uint_eq(val_len, 100); ck_assert_int_eq(memcmp(val, keydata + i, 100), 0); } // suspend memcaches kill(mc_pid0, SIGSTOP); kill(mc_pid1, SIGSTOP); usleep(100000); // allow 0.1 for SIGSTOPs to be delivered // now try to read the values for (size_t i = 0; i < item_count; i ++) { int ret = omcache_get(oc, keydata + i, 100, &val, &val_len, NULL, NULL, 3000); ck_assert_int_ne(ret, OMCACHE_OK); } // sleep over timeouts again and try again sleep(3); // resume one memcache kill(mc_pid0, SIGCONT); // now try to read the values again, some of these will fail because we're // not yet fully connected to mc_pid0 and mc_pid1 is still down size_t found = 0; for (size_t i = 0; i < item_count; i ++) { int ret = omcache_get(oc, keydata + i, 100, &val, &val_len, NULL, NULL, 3000); if (ret == OMCACHE_OK) { ck_assert_uint_eq(val_len, 100); ck_assert_int_eq(memcmp(val, keydata + i, 100), 0); found ++; } else { usleep(1000); } } ck_assert_uint_ge(found, 1); // we should've found something // resume the other memcache kill(mc_pid1, SIGCONT); // sleep over timeouts again sleep(3); // try to read the values yet again, some of these will fail because we're // not yet fully connected after resuming mc_pid1 found = 0; for (size_t i = 0; i < item_count; i ++) { int ret = omcache_get(oc, keydata + i, 100, &val, &val_len, NULL, NULL, 3000); if (ret == OMCACHE_OK) { ck_assert_uint_eq(val_len, 100); ck_assert_int_eq(memcmp(val, keydata + i, 100), 0); found ++; } else { usleep(1000); } } ck_assert_uint_ge(found, item_count / 2 + 1); // we should've found more than half // sleep over timeouts again sleep(3); // try to read the values a final time, now we should have everything for (size_t i = 0; i < item_count; i ++) { ck_omcache_ok(omcache_get(oc, keydata + i, 100, &val, &val_len, NULL, NULL, 3000)); ck_assert_uint_eq(val_len, 100); ck_assert_int_eq(memcmp(val, keydata + i, 100), 0); } omcache_free(oc); }
}END_TEST /** * Integer Factorization test */ START_TEST(test_integerfactorization){ ga_factor_list fl; uint64_t n; /** * Attempt exact factorization for 2^64-1, no k-smoothness constraint. * Expected PASS with 3*5*17*257*641*65537*6700417 */ n = 18446744073709551615ULL; ck_assert_int_ne (gaIFactorize(n, 0, 0, &fl), 0); ck_assert_int_eq (gaIFLGetFactorPower(&fl, 3ULL), 1); ck_assert_int_eq (gaIFLGetFactorPower(&fl, 5ULL), 1); ck_assert_int_eq (gaIFLGetFactorPower(&fl, 17ULL), 1); ck_assert_int_eq (gaIFLGetFactorPower(&fl, 257ULL), 1); ck_assert_int_eq (gaIFLGetFactorPower(&fl, 641ULL), 1); ck_assert_int_eq (gaIFLGetFactorPower(&fl, 65537ULL), 1); ck_assert_int_eq (gaIFLGetFactorPower(&fl, 6700417ULL), 1); ck_assert_uint_eq(gaIFLGetProduct(&fl), n); /** * Attempt exact factorization for 2^64-1, 4096-smooth constraint. * Expected FAIL, because 2^64-1 possesses prime factors in excess of 4096. */ n = 18446744073709551615ULL; ck_assert_int_eq (gaIFactorize(n, 0, 4096, &fl), 0); /** * Attempt approximate factorization for 2^64-1, no k-smoothness constraint. * Unlimited growth permitted. * Expected PASS, since 2^64-1 rounds up to 2^64 and 2^64 trivially factorizes. */ n = 18446744073709551615ULL; ck_assert_int_ne (gaIFactorize(n, -1, 0, &fl), 0); ck_assert_int_eq (gaIFLGetFactorPower(&fl, 2ULL), 64); ck_assert_uint_eq(gaIFLGetGreatestFactor(&fl), 2); ck_assert_int_ne (gaIFLIsOverflowed(&fl), 0); /** * Attempt exact factorization for 2196095973992233039, no k-smoothness constraint. * 2196095973992233039 is a large, highly non-smooth number, with three enormous * factors. * Expected PASS *very quickly*, since it factorizes as 1299817*1299821*1299827 */ n = 2196095973992233039ULL; ck_assert_int_ne (gaIFactorize(n, 0, 0, &fl), 0); ck_assert_int_eq (gaIFLGetFactorPower(&fl, 1299817ULL), 1); ck_assert_int_eq (gaIFLGetFactorPower(&fl, 1299821ULL), 1); ck_assert_int_eq (gaIFLGetFactorPower(&fl, 1299827ULL), 1); ck_assert_uint_eq(gaIFLGetGreatestFactor(&fl), 1299827); ck_assert_uint_eq(gaIFLGetProduct(&fl), n); /** * Attempt approximate factorization for 2196095973992233039, 16-smooth constraint. * 2196095973992233039 is a large, highly non-smooth number, with three enormous * factors. It is not 64-smooth, so code paths that attempt approximate * factorization within the growth limits (.005%) are exercised. * * Expected PASS *relatively quickly*. */ n = 2196095973992233039ULL; ck_assert_int_ne (gaIFactorize(n, n*1.00005, 16, &fl), 0); ck_assert_uint_ge(gaIFLGetProduct(&fl), n); ck_assert_uint_le(gaIFLGetProduct(&fl), n*1.00005); /** * Attempt exact factorization of 7438473388800000000, 5-smooth constraint. * It is a large, 5-smooth number. This should exercise the 5-smooth * factorization path. */ n = 7438473388800000000ULL; ck_assert_int_ne (gaIFactorize(n, 0, 5, &fl), 0); ck_assert_int_eq (gaIFLGetFactorPower(&fl, 2ULL), 14); ck_assert_int_eq (gaIFLGetFactorPower(&fl, 3ULL), 19); ck_assert_int_eq (gaIFLGetFactorPower(&fl, 5ULL), 8); ck_assert_uint_eq(gaIFLGetGreatestFactor(&fl), 5); ck_assert_uint_eq(gaIFLGetProduct(&fl), n); /** * Attempt approximate factorization of 7438473388799999997, 2-smooth constraint. * It is a large, non-smooth number. This should exercise the optimal 2-smooth * factorizer in spite of the available, unlimited slack. */ n = 7438473388799999997ULL; ck_assert_int_ne (gaIFactorize(n, -1, 2, &fl), 0); ck_assert_int_eq (gaIFLGetFactorPower(&fl, 2ULL), 63); ck_assert_int_eq (gaIFLGetFactorPower(&fl, 3ULL), 0); ck_assert_int_eq (gaIFLGetFactorPower(&fl, 5ULL), 0); ck_assert_uint_eq(gaIFLGetGreatestFactor(&fl), 2); ck_assert_uint_eq(gaIFLGetProduct(&fl), 9223372036854775808ULL); /** * Attempt approximate factorization of 7438473388799999997, 3-smooth constraint. * It is a large, non-smooth number. This should exercise the optimal 3-smooth * factorizer in spite of the available, unlimited slack. */ n = 7438473388799999997ULL; ck_assert_int_ne (gaIFactorize(n, -1, 3, &fl), 0); ck_assert_int_eq (gaIFLGetFactorPower(&fl, 2ULL), 31); ck_assert_int_eq (gaIFLGetFactorPower(&fl, 3ULL), 20); ck_assert_int_eq (gaIFLGetFactorPower(&fl, 5ULL), 0); ck_assert_uint_eq(gaIFLGetGreatestFactor(&fl), 3); ck_assert_uint_eq(gaIFLGetProduct(&fl), 7487812485248974848ULL); /** * Attempt approximate factorization of 7438473388799999997, 5-smooth constraint. * It is a large, non-smooth number, but 3 integers above it is a 5-smooth * integer, 7438473388800000000. This should exercise the optimal 5-smooth * factorizer in spite of the available, unlimited slack. */ n = 7438473388799999997ULL; ck_assert_int_ne (gaIFactorize(n, -1, 5, &fl), 0); ck_assert_int_eq (gaIFLGetFactorPower(&fl, 2ULL), 14); ck_assert_int_eq (gaIFLGetFactorPower(&fl, 3ULL), 19); ck_assert_int_eq (gaIFLGetFactorPower(&fl, 5ULL), 8); ck_assert_uint_eq(gaIFLGetGreatestFactor(&fl), 5); ck_assert_uint_eq(gaIFLGetProduct(&fl), 7438473388800000000ULL); /** * Toughest challenge: Attempt very tight approximate factorization of * 9876543210987654321 with .01% slack and 43-smooth constraint. * * This forces a bypass of the optimal 5-smooth factorizers and heavily * exercises the nextI:, subfactorize:, primetest: and newX jumps and * calculations. * * Expected PASS, "reasonably fast". */ n = 9876543210987654321ULL; ck_assert_int_ne (gaIFactorize(n, n*1.0001, 43, &fl), 0); ck_assert_uint_ge(gaIFLGetProduct(&fl), n); ck_assert_uint_le(gaIFLGetProduct(&fl), n*1.0001); ck_assert_uint_le(gaIFLGetGreatestFactor(&fl), 43); }END_TEST
}END_TEST START_TEST(test_scheduler){ /* We use here the CUDA limits of a CC 3.0 GPU as an example. */ uint64_t maxBTot = 1024, maxBInd[] = { 1024, 1024, 64}, maxGTot = 0xFFFFFFFF, maxGInd[] = {2147483647, 65535, 65535}, warpSize = 32; int warpAxis; uint64_t dims[3]; ga_factor_list factBS[3], factGS[3], factCS[3]; unsigned long long intbBS[3], intbGS[3], intbCS[3]; unsigned long long intaBS[3], intaGS[3], intaCS[3]; /** * NOTE: If you want to view befores-and-afters of scheduling, #define PRINT * to something non-0. */ #define PRINT 0 /** * * Testcase: (895,1147,923) job, warpSize on axis 0. * */ { warpAxis = 0; dims[0] = 895; dims[1] = 1141; dims[2] = 923; dims[warpAxis] = (dims[warpAxis]+warpSize-1) / warpSize; /** * Factorization job must be successful. */ ck_assert(gaIFactorize(warpAxis==0?warpSize:1, 0, maxBInd[0], factBS+0)); ck_assert(gaIFactorize(warpAxis==1?warpSize:1, 0, maxBInd[1], factBS+1)); ck_assert(gaIFactorize(warpAxis==2?warpSize:1, 0, maxBInd[2], factBS+2)); ck_assert(gaIFactorize( 1, 0, maxBInd[0], factGS+0)); ck_assert(gaIFactorize( 1, 0, maxBInd[1], factGS+1)); ck_assert(gaIFactorize( 1, 0, maxBInd[2], factGS+2)); ck_assert(gaIFactorize( dims[0], dims[0]*1.1, maxBInd[0], factCS+0)); ck_assert(gaIFactorize( dims[1], dims[1]*1.1, maxBInd[1], factCS+1)); ck_assert(gaIFactorize( dims[2], dims[2]*1.1, maxBInd[2], factCS+2)); intbBS[0] = gaIFLGetProduct(factBS+0); intbBS[1] = gaIFLGetProduct(factBS+1); intbBS[2] = gaIFLGetProduct(factBS+2); intbGS[0] = gaIFLGetProduct(factGS+0); intbGS[1] = gaIFLGetProduct(factGS+1); intbGS[2] = gaIFLGetProduct(factGS+2); intbCS[0] = gaIFLGetProduct(factCS+0); intbCS[1] = gaIFLGetProduct(factCS+1); intbCS[2] = gaIFLGetProduct(factCS+2); /** * Ensure that factorization only *increases* the size of the problem. */ ck_assert_uint_ge(intbCS[0], dims[0]); ck_assert_uint_ge(intbCS[1], dims[1]); ck_assert_uint_ge(intbCS[2], dims[2]); /** * Run scheduler. */ #if PRINT printf("Before:\n"); printf("BS: (%6llu, %6llu, %6llu)\n", intbBS[0], intbBS[1], intbBS[2]); printf("GS: (%6llu, %6llu, %6llu)\n", intbGS[0], intbGS[1], intbGS[2]); printf("CS: (%6llu, %6llu, %6llu)\n", intbCS[0], intbCS[1], intbCS[2]); #endif gaIFLSchedule(3, maxBTot, maxBInd, maxGTot, maxGInd, factBS, factGS, factCS); intaBS[0] = gaIFLGetProduct(factBS+0); intaBS[1] = gaIFLGetProduct(factBS+1); intaBS[2] = gaIFLGetProduct(factBS+2); intaGS[0] = gaIFLGetProduct(factGS+0); intaGS[1] = gaIFLGetProduct(factGS+1); intaGS[2] = gaIFLGetProduct(factGS+2); intaCS[0] = gaIFLGetProduct(factCS+0); intaCS[1] = gaIFLGetProduct(factCS+1); intaCS[2] = gaIFLGetProduct(factCS+2); #if PRINT printf("After:\n"); printf("BS: (%6llu, %6llu, %6llu)\n", intaBS[0], intaBS[1], intaBS[2]); printf("GS: (%6llu, %6llu, %6llu)\n", intaGS[0], intaGS[1], intaGS[2]); printf("CS: (%6llu, %6llu, %6llu)\n", intaCS[0], intaCS[1], intaCS[2]); #endif /** * Scheduling is only about moving factors between block/grid/chunk factor * lists. Therefore, the three dimensions must not have changed size. */ ck_assert_uint_eq(intbBS[0]*intbGS[0]*intbCS[0], intaBS[0]*intaGS[0]*intaCS[0]); ck_assert_uint_eq(intbBS[1]*intbGS[1]*intbCS[1], intaBS[1]*intaGS[1]*intaCS[1]); ck_assert_uint_eq(intbBS[2]*intbGS[2]*intbCS[2], intaBS[2]*intaGS[2]*intaCS[2]); /** * Verify that the individual limits and global limits on threads in a * block and blocks in a grid are met. */ ck_assert_uint_le(intaBS[0], maxBInd[0]); ck_assert_uint_le(intaBS[1], maxBInd[1]); ck_assert_uint_le(intaBS[2], maxBInd[2]); ck_assert_uint_le(intaGS[0], maxGInd[0]); ck_assert_uint_le(intaGS[1], maxGInd[1]); ck_assert_uint_le(intaGS[2], maxGInd[2]); ck_assert_uint_le(intaBS[0]*intaBS[1]*intaBS[2], maxBTot); ck_assert_uint_le(intaGS[0]*intaGS[1]*intaGS[2], maxGTot); } /** * * Testcase: (1,1,121632959) job, warpSize on axis 2. * */ { warpAxis = 2; dims[0] = 1; dims[1] = 1; dims[2] = 121632959; dims[warpAxis] = (dims[warpAxis]+warpSize-1) / warpSize; /** * Factorization job must be successful. */ ck_assert(gaIFactorize(warpAxis==0?warpSize:1, 0, maxBInd[0], factBS+0)); ck_assert(gaIFactorize(warpAxis==1?warpSize:1, 0, maxBInd[1], factBS+1)); ck_assert(gaIFactorize(warpAxis==2?warpSize:1, 0, maxBInd[2], factBS+2)); ck_assert(gaIFactorize( 1, 0, maxBInd[0], factGS+0)); ck_assert(gaIFactorize( 1, 0, maxBInd[1], factGS+1)); ck_assert(gaIFactorize( 1, 0, maxBInd[2], factGS+2)); ck_assert(gaIFactorize( dims[0], dims[0]*1.1, maxBInd[0], factCS+0)); ck_assert(gaIFactorize( dims[1], dims[1]*1.1, maxBInd[1], factCS+1)); ck_assert(gaIFactorize( dims[2], dims[2]*1.1, maxBInd[2], factCS+2)); intbBS[0] = gaIFLGetProduct(factBS+0); intbBS[1] = gaIFLGetProduct(factBS+1); intbBS[2] = gaIFLGetProduct(factBS+2); intbGS[0] = gaIFLGetProduct(factGS+0); intbGS[1] = gaIFLGetProduct(factGS+1); intbGS[2] = gaIFLGetProduct(factGS+2); intbCS[0] = gaIFLGetProduct(factCS+0); intbCS[1] = gaIFLGetProduct(factCS+1); intbCS[2] = gaIFLGetProduct(factCS+2); /** * Ensure that factorization only *increases* the size of the problem. */ ck_assert_uint_ge(intbCS[0], dims[0]); ck_assert_uint_ge(intbCS[1], dims[1]); ck_assert_uint_ge(intbCS[2], dims[2]); /** * Run scheduler. */ #if PRINT printf("Before:\n"); printf("BS: (%6llu, %6llu, %6llu)\n", intbBS[0], intbBS[1], intbBS[2]); printf("GS: (%6llu, %6llu, %6llu)\n", intbGS[0], intbGS[1], intbGS[2]); printf("CS: (%6llu, %6llu, %6llu)\n", intbCS[0], intbCS[1], intbCS[2]); #endif gaIFLSchedule(3, maxBTot, maxBInd, maxGTot, maxGInd, factBS, factGS, factCS); intaBS[0] = gaIFLGetProduct(factBS+0); intaBS[1] = gaIFLGetProduct(factBS+1); intaBS[2] = gaIFLGetProduct(factBS+2); intaGS[0] = gaIFLGetProduct(factGS+0); intaGS[1] = gaIFLGetProduct(factGS+1); intaGS[2] = gaIFLGetProduct(factGS+2); intaCS[0] = gaIFLGetProduct(factCS+0); intaCS[1] = gaIFLGetProduct(factCS+1); intaCS[2] = gaIFLGetProduct(factCS+2); #if PRINT printf("After:\n"); printf("BS: (%6llu, %6llu, %6llu)\n", intaBS[0], intaBS[1], intaBS[2]); printf("GS: (%6llu, %6llu, %6llu)\n", intaGS[0], intaGS[1], intaGS[2]); printf("CS: (%6llu, %6llu, %6llu)\n", intaCS[0], intaCS[1], intaCS[2]); #endif /** * Scheduling is only about moving factors between block/grid/chunk factor * lists. Therefore, the three dimensions must not have changed size. */ ck_assert_uint_eq(intbBS[0]*intbGS[0]*intbCS[0], intaBS[0]*intaGS[0]*intaCS[0]); ck_assert_uint_eq(intbBS[1]*intbGS[1]*intbCS[1], intaBS[1]*intaGS[1]*intaCS[1]); ck_assert_uint_eq(intbBS[2]*intbGS[2]*intbCS[2], intaBS[2]*intaGS[2]*intaCS[2]); /** * Verify that the individual limits and global limits on threads in a * block and blocks in a grid are met. */ ck_assert_uint_le(intaBS[0], maxBInd[0]); ck_assert_uint_le(intaBS[1], maxBInd[1]); ck_assert_uint_le(intaBS[2], maxBInd[2]); ck_assert_uint_le(intaGS[0], maxGInd[0]); ck_assert_uint_le(intaGS[1], maxGInd[1]); ck_assert_uint_le(intaGS[2], maxGInd[2]); ck_assert_uint_le(intaBS[0]*intaBS[1]*intaBS[2], maxBTot); ck_assert_uint_le(intaGS[0]*intaGS[1]*intaGS[2], maxGTot); } }END_TEST