int main() { Bulk_quote bq("0-000-111", 12.89, 10, 0.2); cout << bq.net_price(20); system("pause"); return 0; }
// single producer, many consumers void TestQueue_SPMC(unsigned iterations, unsigned threadCount, unsigned queueSize) { BlockingQueue<int> bq(queueSize); ParallelProcessor processor(threadCount); std::atomic<int64_t> result(0); processor.spawn([&bq, &result]{ int v = 0; int64_t sum = 0; while (bq.pop(v)) { sum += v; } result += sum; // std::cout << "Sum: " << sum << std::endl; }); int64_t expectedSum = 0; for (unsigned i = 0; i < iterations; ++i) { expectedSum += i; ASSERT_TRUE(bq.push(i)); } bq.close(); processor.join(); ASSERT_EQ(expectedSum, result.load()); }
TEST(BlockingQueue, CloseAndWait) { size_t queueSize = 100; BlockingQueue<int> bq(queueSize); ParallelProcessor p(4); std::atomic<size_t> itemsPopped(0); // fill the queue for (int i = 0; i < queueSize; ++i) bq.push(i); p.spawn([&bq, &itemsPopped] { int v; while (bq.pop(v)) { itemsPopped += 1; // some delay to make close() really wait std::this_thread::sleep_for(std::chrono::milliseconds(10)); } }); // check with multiple closing auto f1 = std::async(std::launch::async, [&] { bq.close(true); }); auto f2 = std::async(std::launch::async, [&] { bq.close(true); }); bq.close(true); f1.get(); f2.get(); p.join(); ASSERT_EQ(queueSize, itemsPopped.load()); }
int main() { // ex15.6 Quote q("textbook", 10.60); Bulk_quote bq("textbook", 10.60, 10, 0.3); Quote q1(q); cout << endl; Quote q2 = q; cout << endl; Bulk_quote pbq(bq); cout << endl; Bulk_quote pbq2 = bq; cout << endl; Bulk_quote pbq3 = std::move(bq); //print_total(std::cout, q, 12); //print_total(std::cout, bq, 12); //q.debug(); //bq.debug(); return 0; }
int main() { // ex15.6 Quote q("textbook", 10.60); Bulk_quote bq("textbook", 10.60, 10, 0.3); print_total(std::cout, q, 12); print_total(std::cout, bq, 12); return 0; }
TEST(BlockingQueue, AllowsMoveOnly) { BlockingQueue<std::unique_ptr<int>> bq(1); std::unique_ptr<int> v(new int(100)); ASSERT_TRUE(bq.push(std::move(v))); std::unique_ptr<int> popval; bq.pop(popval); ASSERT_EQ(*popval, 100); }
int main() { Quote q("text", 10.60); Bulk_quote bq("text", 10.60, 10, 0.3); Limit_quote lq("text", 10.60, 20, 0.3); print_total(std::cout, q, 12); print_total(std::cout, bq, 12); print_total(std::cout, lq, 21); return 0; }
TEST(BlockingQueue, Close) { BlockingQueue<int> bq(4); ParallelProcessor p(4); p.spawn([&bq] { int v; while (bq.pop(v)) ; }); bq.push(10); // enqueue 1 item bq.close(); // all threads should unblock and finish p.join(); }
int main(void) { int size; int validInput = 0; printf("BoundedQueue:\n\n"); while (!validInput) { printf("Enter desired queue size: "); validInput = promptSize(&size); if (!validInput) { printf("invalid size\n"); } } BoundedQueue bq(size); char cmd[3]; /* to hold "x\n\0" where x = command letter */ while (cmd[0] != 'q') { printf("Enter command - (e)nqueue, (d)equeue, or (q)uit: "); validInput = promptString(cmd, 3); if (!validInput) { printf("invalid\n"); continue; } int element; if (cmd[0] == 'e') { printf("Enter integer to enqueue: "); promptInt(&element); bq.enqueue(element); if (size <= 25) { printQueue(bq); printf("\n"); } } else if (cmd[0] == 'd') { printf("Dequeued integer: %d\n", bq.dequeue()); if (size <= 25) { printQueue(bq); printf("\n"); } } } return 0; }
int main() { Quote q("text", 10.60); Bulk_quote bq("text", 10.60, 10, 0.3); Limit_quote lq("text", 10.60, 20, 0.3); print_total(std::cout, q, 12); print_total(std::cout, bq, 12); print_total(std::cout, lq, 21); std::cout << "*******************************" << std::endl; print_debug(q); print_debug(bq); print_debug(lq); return 0; }
void TestQueue_MPSC(unsigned iterations, unsigned threadCount, unsigned queueSize) { BlockingQueue<int> bq(queueSize); ParallelProcessor processor(threadCount); std::atomic<unsigned> counter(0); std::atomic<int64_t> pushed(0); processor.spawn([&]{ int64_t sum = 0; for(;;) { unsigned value = counter.fetch_add(1); if (value >= iterations) break; bq.push(value); sum += value; } pushed += sum; // std::cout << "Sum: " << sum << std::endl; }); int64_t expectedSum = 0; for (unsigned i = 0; i < iterations; ++i) { int value; ASSERT_TRUE(bq.pop(value)); expectedSum += i; } ASSERT_EQ(0, bq.size()); processor.join(); ASSERT_EQ(expectedSum, pushed); }
static J<T> bp () { bq (0); }
TYPED_TEST(QuantBlasTest, TestGemmComparativeFloatQuant) { typedef typename TypeParam::Dtype Dtype; // Expect at most 5% error float percentile_eps = 0.05; std::random_device rdev; std::mt19937 rngen(rdev()); // Need to test > 64 dimension std::uniform_int_distribution<int_tp> dimsRand(1, 256); std::uniform_int_distribution<int_tp> boolRand(0, 1); std::uniform_int_distribution<int_tp> factorRand(-25, 25); std::uniform_real_distribution<float> valRand(-2.0, 2.0); for (int_tp testIdx = 0; testIdx < 25; ++testIdx) { int_tp M = dimsRand(rngen); int_tp N = dimsRand(rngen); int_tp K = dimsRand(rngen); CBLAS_TRANSPOSE trans_A = boolRand(rngen) ? CblasTrans : CblasNoTrans; CBLAS_TRANSPOSE trans_B = boolRand(rngen) ? CblasTrans : CblasNoTrans; bool has_alpha = boolRand(rngen); bool has_beta = has_alpha ? boolRand(rngen) : true; bool alpha_with_quant = boolRand(rngen) && has_alpha; bool beta_with_quant = boolRand(rngen) && has_beta; float alpha_val; float beta_val; if (has_alpha) { alpha_val = alpha_with_quant ? valRand(rngen) : float(1.0); } else { alpha_val = 0.0; } if (has_beta) { beta_val = beta_with_quant ? valRand(rngen) : float(1.0); } else { beta_val = 0.0; } vector<int_tp> A_shape(4, 1); vector<int_tp> B_shape(4, 1); vector<int_tp> C_shape(4, 1); A_shape[2] = M; A_shape[3] = K; B_shape[2] = K; B_shape[3] = N; C_shape[2] = M; C_shape[3] = N; Blob<float> A(A_shape, Caffe::GetDefaultDevice()); Blob<float> B(B_shape, Caffe::GetDefaultDevice()); Blob<float> C(C_shape, Caffe::GetDefaultDevice()); Blob<float> C_result(C_shape, Caffe::GetDefaultDevice()); Blob<Dtype> A_quant(A_shape, Caffe::GetDefaultDevice()); Blob<Dtype> B_quant(B_shape, Caffe::GetDefaultDevice()); Blob<Dtype> C_quant(C_shape, Caffe::GetDefaultDevice()); Blob<float> C_unquant(C_shape, Caffe::GetDefaultDevice()); caffe_rng_gaussian(M * K, (float)0.0, (float)0.5, A.mutable_cpu_data()); caffe_rng_gaussian(K * N, (float)0.0, (float)0.5, B.mutable_cpu_data()); caffe_rng_gaussian(M * N, (float)0.0, (float)0.5, C.mutable_cpu_data()); caffe_copy(M * N, C.cpu_data(), C_result.mutable_cpu_data()); QuantizerParameter qpm_a; QuantizerParameter qpm_b; QuantizerParameter qpm_c; QuantizerParameter qpm_alpha; QuantizerParameter qpm_beta; qpm_a.set_mode(CAFFE_QUANT_OBSERVE); qpm_b.set_mode(CAFFE_QUANT_OBSERVE); qpm_c.set_mode(CAFFE_QUANT_OBSERVE); qpm_alpha.set_mode(CAFFE_QUANT_OBSERVE); qpm_beta.set_mode(CAFFE_QUANT_OBSERVE); Quantizer<float, Dtype> aq(qpm_a); Quantizer<float, Dtype> bq(qpm_b); Quantizer<float, Dtype> cq(qpm_c); Quantizer<float, Dtype> alphaq(qpm_alpha); Quantizer<float, Dtype> betaq(qpm_beta); // Normal GEMM caffe_gemm<float>( trans_A, trans_B, M, N, K, alpha_val, A.cpu_data(), B.cpu_data(), beta_val, C_result.mutable_cpu_data()); // Observe all values that will be relevant for quantization aq.ObserveIn_cpu(M * K, A.cpu_data()); bq.ObserveIn_cpu(K * N, B.cpu_data()); cq.ObserveIn_cpu(M * N, C.cpu_data()); cq.ObserveIn_cpu(M * N, C_result.cpu_data()); alphaq.ObserveIn_cpu(1, &alpha_val); betaq.ObserveIn_cpu(1, &beta_val); // Apply observed values to the quantizer aq.update(); bq.update(); cq.update(); alphaq.update(); betaq.update(); // Quantize A, B and C aq.Forward_cpu(M * K, A.cpu_data(), A_quant.mutable_cpu_data()); bq.Forward_cpu(K * N, B.cpu_data(), B_quant.mutable_cpu_data()); cq.Forward_cpu(M * N, C.cpu_data(), C_quant.mutable_cpu_data()); Dtype alpha_val_quant = has_alpha; Dtype beta_val_quant = has_beta; // Quantize alpha if (alpha_with_quant) { alphaq.Forward_cpu(1, &alpha_val, &alpha_val_quant); } // Quantize beta if (beta_with_quant) { betaq.Forward_cpu(1, &beta_val, &beta_val_quant); } /* std::cout << "C max:" << cq.in_quantizer_values().max << std::endl; std::cout << "C min:" << cq.in_quantizer_values().min << std::endl; std::cout << "C zero:" << cq.in_quantizer_values().zero << std::endl; std::cout << "C scale:" << cq.in_quantizer_values().scale << std::endl; std::cout << "C max:" << cq.out_quantizer_values().max << std::endl; std::cout << "C min:" << cq.out_quantizer_values().min << std::endl; std::cout << "C zero:" << cq.out_quantizer_values().zero << std::endl; std::cout << "C scale:" << cq.out_quantizer_values().scale << std::endl; */ if (Caffe::mode() == Caffe::Brew::CPU) { caffe_gemm<Dtype>( trans_A, trans_B, M, N, K, alpha_val_quant, A_quant.cpu_data(), B_quant.cpu_data(), beta_val_quant, C_quant.mutable_cpu_data(), alpha_with_quant ? &(alphaq.out_quantizer_values()) : nullptr, &(aq.out_quantizer_values()), &(bq.out_quantizer_values()), beta_with_quant ? &(betaq.out_quantizer_values()) : nullptr, &(cq.out_quantizer_values())); } else { Caffe::GetDefaultDevice()->template gemm<Dtype>(trans_A, trans_B, M, N, K, alpha_val_quant, A_quant.gpu_data(), B_quant.gpu_data(), beta_val_quant, C_quant.mutable_gpu_data(), alpha_with_quant ? &(alphaq.out_quantizer_values()) : nullptr, &(aq.out_quantizer_values()), &(bq.out_quantizer_values()), beta_with_quant ? &(betaq.out_quantizer_values()) : nullptr, &(cq.out_quantizer_values())); } cq.Backward_cpu(M * N, C_quant.cpu_data(), C_unquant.mutable_cpu_data()); // print_matrix(A_quant.cpu_data(), M, K); // print_matrix(B_quant.cpu_data(), K, N); // print_matrix(C_quant.cpu_data(), M, N); // print_matrix(C_result.cpu_data(), M, N); // print_matrix(C_unquant.cpu_data(), M, N); const QuantizerValues cqv = cq.in_quantizer_values(); float eps = std::max(std::abs(cqv.get_max<float>()), std::abs(cqv.get_min<float>())) * percentile_eps; for (int_tp i = 0; i < M * N; ++i) { EXPECT_NEAR(C_unquant.cpu_data()[i], C_result.cpu_data()[i], eps); // One error is enough to abort if (fabs(C_unquant.cpu_data()[i] - C_result.cpu_data()[i]) >= eps) { break; } } } }