1 #include "gtest/gtest.h" 2 #include "gmock/gmock.h" 17 using namespace ::testing;
26 membuf(
char* begin,
char* end) { this->setg(begin, begin, end); }
31 std::vector<float> floats;
34 while (std::getline(data, line)) floats.push_back((
float)atof(line.c_str()));
38 std::vector<float>
read_floats(
unsigned char* data,
unsigned int len)
40 membuf mb((
char*)data, (
char*)(data + len));
47 std::ifstream data(filename);
59 #define TEST_DATA(input, filename) \ 61 if (!strcmp(input, #filename)) \ 63 td.model = filename##_model; \ 64 td.model_len = filename##_model_len; \ 65 td.pred = filename##_pred; \ 66 td.pred_len = filename##_pred_len; \ 75 TEST_DATA(model_filename, regression_data_1);
76 TEST_DATA(model_filename, regression_data_2);
77 TEST_DATA(model_filename, regression_data_3);
78 TEST_DATA(model_filename, regression_data_3);
79 TEST_DATA(model_filename, regression_data_4);
80 TEST_DATA(model_filename, regression_data_5);
81 TEST_DATA(model_filename, regression_data_6);
82 TEST_DATA(model_filename, regression_data_7);
83 TEST_DATA(model_filename, regression_data_no_constant);
84 TEST_DATA(model_filename, regression_data_ignore_linear);
85 TEST_DATA(model_filename, multiclass_data_4);
86 TEST_DATA(model_filename, cb_data_epsilon_0_skype_jb);
97 const char* model_filename,
const char* data_filename,
const char* prediction_reference_filename)
99 std::vector<float> preds;
108 if (!strcmp(data_filename,
"regression_data_1.txt"))
121 preds.push_back(score);
124 else if (!strcmp(data_filename,
"regression_data_2.txt"))
139 preds.push_back(score);
142 else if (!strcmp(data_filename,
"regression_data_3.txt"))
159 preds.push_back(score);
162 else if (!strcmp(data_filename,
"regression_data_4.txt"))
187 preds.push_back(score);
190 else if (!strcmp(data_filename,
"regression_data_7.txt"))
207 preds.push_back(score);
211 FAIL() <<
"Unknown data file: " << data_filename;
216 EXPECT_THAT(preds, Pointwise(FloatNearPointwise(1e-5
f), preds_expected));
248 run_predict_in_memory<sparse_parameters>(
249 GetParam().model_filename, GetParam().data_filename, GetParam().prediction_reference_filename);
251 run_predict_in_memory<dense_parameters>(
252 GetParam().model_filename, GetParam().data_filename, GetParam().prediction_reference_filename);
257 std::vector<PredictParam> fixtures;
262 {
"regression_data_no_constant",
"regression_data_1.txt",
"regression_data_no-constant.pred",
264 {
"regression_data_ignore_linear",
"regression_data_2.txt",
"regression_data_ignore_linear.pred",
272 for (
int i = 0; i <
sizeof(predict_params) /
sizeof(
PredictParam); i++)
276 fixtures.push_back(p);
283 fixtures.push_back(p);
311 const char* model_file = (
const char*)GetParam().model;
312 size_t model_file_size = (size_t)GetParam().model_len;
314 auto& undetectable_offsets = GetParam().undetectable_offsets;
316 for (
size_t end = 0; end < model_file_size - 1; ++end)
319 if (undetectable_offsets.find(end) != undetectable_offsets.end())
327 EXPECT_NE(
S_VW_PREDICT_OK, vw.
load(&model_file[0], end)) <<
"partial model read until " << end <<
" didn't throw";
332 EXPECT_NE(
S_VW_PREDICT_OK, vw.
load(&model_file[0], end)) <<
"partial model read until " << end <<
" didn't throw";
348 TEST(VowpalWabbitSlim, multiclass_data_4)
354 std::vector<float> out_scores;
376 std::vector<float> preds_expected = {0.901038f, 0.46983f, 0.0386223f};
379 EXPECT_THAT(out_scores, Pointwise(FloatNearPointwise(1e-5
f), preds_expected));
383 std::vector<int> ranking_expected, std::vector<float> pdf_expected)
402 const int min_delay_actions = 10;
404 for (
int i = 0; i < min_delay_actions; i++)
411 std::vector<float> pdfs;
412 std::vector<int> rankings;
413 int result = vw.
predict(
"eid", features, actions, min_delay_actions, pdfs, rankings);
416 EXPECT_EQ(result, 0);
417 EXPECT_THAT(pdfs, Pointwise(FloatNearPointwise(1e-5
f), pdf_expected));
418 EXPECT_THAT(rankings, ranking_expected);
421 TEST(VowpalWabbitSlim, interaction_num_bits_bug)
423 std::ifstream input(
"data/Delay_Margin_AudioNetworkPCR_all_cb_FF8.model", std::ios::in | std::ios::binary);
424 input.seekg(0, std::ios::end);
425 auto length = input.tellg();
426 input.seekg(0, std::ios::beg);
427 std::unique_ptr<char> buffer_ptr(
new char[length]);
428 input.read(buffer_ptr.get(),
433 int result = vw.
load(buffer_ptr.get(), length);
434 EXPECT_EQ(result, 0);
442 bOa.push_feature_string(
"CallTypeP2P", 1.
f);
443 bOa.push_feature_string(
"PlatformAndroid", 1.
f);
444 bOa.push_feature_string(
"MediaTypeVideo", 1.
f);
446 const int MINDELAYACTIONS = 10;
449 for (
int i = 0; i < MINDELAYACTIONS; i++)
456 std::string uuidString(
"EventId_0");
458 std::vector<float> pdfs;
459 std::vector<int> rankings;
461 result = vw.
predict(uuidString.c_str(), features, actions, MINDELAYACTIONS, pdfs, rankings);
462 EXPECT_EQ(result, 0);
463 EXPECT_EQ(rankings[0], 3);
466 TEST(VowpalWabbitSlim, cb_data_epsilon_0_skype_jb)
469 std::vector<float> pdf_expected = {1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
472 std::vector<int> ranking_expected = {1, 0, 2, 3, 4, 5, 7, 6, 8, 9};
476 ranking_expected = {1, 0, 2, 3, 4, 5, 6, 8, 7, 9};
480 ranking_expected = {1, 2, 0, 3, 4, 5, 6, 7, 8, 9};
484 ranking_expected = {1, 3, 2, 0, 4, 6, 5, 8, 7, 9};
488 ranking_expected = {3, 1, 0, 2, 5, 4, 7, 6, 8, 9};
492 ranking_expected = {2, 4, 6, 1, 0, 5, 3, 7, 8, 9};
496 ranking_expected = {2, 4, 6, 1, 3, 5, 0, 7, 8, 9};
500 ranking_expected = {2, 5, 4, 3, 6, 1, 0, 7, 8, 9};
504 ranking_expected = {0, 1, 4, 2, 6, 3, 8, 7, 5, 9};
508 ranking_expected = {0, 1, 4, 2, 7, 3, 6, 8, 5, 9};
572 std::vector<float> pdf_expected = GetParam().pdf_expected;
573 std::vector<float> histogram(pdf_expected.size() * pdf_expected.size());
578 std::vector<int> ranking;
582 size_t rep = GetParam().replications;
583 for (
size_t i = 0; i < rep; i++)
585 std::vector<float> pdf;
590 ASSERT_EQ(pdf_expected.size(), ranking.size());
591 for (
size_t i = 0; i < ranking.size(); i++) histogram[i * ranking.size() + ranking[i]]++;
594 for (
auto& d : histogram) d /= rep;
596 #ifdef VW_SLIM_TEST_DEBUG 607 EXPECT_THAT(histogram, Pointwise(FloatNearPointwise(1e-2
f), GetParam().ranking_pdf_expected));
611 {
"CB Epsilon Greedy",
"cb_data_5", 10000, {0.1f, 0.1f, 0.8f},
622 {
"CB Softmax",
"cb_data_6", 1000, {0.329f, 0.333f, 0.337f},
624 0.328f, 0.354f, 0.316f,
625 0.000f, 0.644f, 0.354f,
626 0.671f, 0.000f, 0.328f,
628 {
"CB Bag",
"cb_data_7", 5, {0.0f, 0.0f, 1.0f},
634 {
"CB Bag Epsilon Greedy",
"cb_data_8", 10000, {0.09f, 0.09f, 0.82f},
636 0.091f, 0.086f, 0.82f,
637 0.00f, 0.91f, 0.086f,
645 template <
typename W>
659 std::vector<float> scores;
660 std::vector<int> ranking;
674 std::vector<float> scores;
675 std::vector<int> ranking;
690 size_t num_bytes_to_corrupt = 10;
692 for (
size_t i = 0; i < 100; i++)
695 for (
size_t j = 0; j < num_bytes_to_corrupt; j++)
698 size_t random_idx = (size_t)(rand * model_copy.size());
702 model_copy[random_idx] = (char)rand;
704 ASSERT_NE(0, vw.
load((
const char*)&model_copy[0], model_copy.size()));
712 TEST(ColdStartModel, action_set_not_reordered)
714 std::ifstream input(
"data/cold_start.model", std::ios::in | std::ios::binary);
715 input.seekg(0, std::ios::end);
716 auto length = input.tellg();
717 input.seekg(0, std::ios::beg);
718 std::unique_ptr<char> buffer_ptr(
new char[length]);
719 input.read(buffer_ptr.get(), length);
723 int result = vw.
load(buffer_ptr.get(), length);
724 EXPECT_EQ(result, 0);
731 const int NUM_ACTIONS = 5;
732 std::array<safe_example_predict, NUM_ACTIONS> actions;
733 for (
int i = 0; i < actions.size(); i++)
739 std::string uuidString(
"EventId_0");
741 std::vector<float> pdfs;
742 std::vector<int> rankings;
744 result = vw.
predict(uuidString.c_str(), features, actions.data(), NUM_ACTIONS, pdfs, rankings);
746 EXPECT_GT(pdfs[0], 0.8);
747 EXPECT_GT(pdfs[0], pdfs[1]);
748 EXPECT_THAT(rankings, ElementsAre(0, 1, 2, 3, 4));
void push_feature(feature_index feature_idx, feature_value value)
#define E_VW_PREDICT_ERR_NOT_A_CB_MODEL
unsigned int regression_data_1_model_len
bool is_cb_explore_adf()
True if the model describes a contextual bandit (cb) model using action dependent features (afd) ...
PredictParamWeightType weight_type
CBPredictParam cb_predict_params[]
unsigned char regression_data_6_model[]
Vowpal Wabbit slim predictor. Supports: regression, multi-class classification and contextual bandits...
const char * model_filename
INSTANTIATE_TYPED_TEST_SUITE_P(VowpalWabbitSlim, VwSlimTest, WeightParameters)
TYPED_TEST_SUITE_P(VwSlimTest)
the core definition of a set of features.
const char * data_filename
unsigned int regression_data_6_model_len
InvalidModelParam invalid_model_param[]
std::vector< float > pdf_expected
void run_predict_in_memory(const char *model_filename, const char *data_filename, const char *prediction_reference_filename)
void cb_data_epsilon_0_skype_jb_test_runner(int call_type, int modality, int network_type, int platform, std::vector< int > ranking_expected, std::vector< float > pdf_expected)
INSTANTIATE_TEST_SUITE_P(VowpalWabbitSlim, PredictTest, ::testing::ValuesIn(GenerateTestParams()))
membuf(char *begin, char *end)
const char * prediction_reference_filename
void generate_cb_data_5(safe_example_predict &shared, safe_example_predict *ex)
int load(const char *model, size_t length)
Reads the Vowpal Wabbit model from the supplied buffer (produced using vw -f <modelname>) ...
REGISTER_TYPED_TEST_SUITE_P(VwSlimTest, model_not_loaded, model_reduction_mismatch, model_corrupted)
const char * model_filename
unsigned char namespace_index
std::vector< float > ranking_pdf_expected
unsigned char regression_data_1_model[]
uint32_t feature_index_num_bits()
#define E_VW_PREDICT_ERR_NO_A_CSOAA_MODEL
TYPED_TEST_P(VwSlimTest, model_not_loaded)
void push_feature_string(char *feature_idx, feature_value value)
std::vector< PredictParam > GenerateTestParams()
test_data get_test_data(const char *model_filename)
#define E_VW_PREDICT_ERR_NO_MODEL_LOADED
TEST(VowpalWabbitSlim, multiclass_data_4)
::std::ostream & operator<<(::std::ostream &os, const PredictParam ¶m)
#define TEST_DATA(input, filename)
PredictParamWeightType weight_type
std::string generate_string_seed(size_t i)
::testing::Types< sparse_parameters, dense_parameters > WeightParameters
std::set< size_t > undetectable_offsets
int predict(example_predict &ex, float &score)
Predicts a score (as in regression) for the provided example.
std::vector< float > read_floats(std::istream &data)
float uniform_random_merand48(uint64_t initial)