예제 #1
0
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__)
}
예제 #2
0
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;
}
예제 #3
0
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