Fix GPU ID and prediction cache from pickle (#5086)
* Hack for saving GPU ID. * Declare prediction cache on GBTree. * Add a simple test. * Add `auto` option for GPU Predictor.
This commit is contained in:
@@ -29,21 +29,17 @@ TEST(GBTree, SelectTreeMethod) {
|
||||
ASSERT_EQ(tparam.updater_seq, "grow_colmaker,prune");
|
||||
gbtree.Configure({{"tree_method", "hist"}, {"num_feature", n_feat}});
|
||||
ASSERT_EQ(tparam.updater_seq, "grow_quantile_histmaker");
|
||||
ASSERT_EQ(tparam.predictor, "cpu_predictor");
|
||||
gbtree.Configure({{"booster", "dart"}, {"tree_method", "hist"},
|
||||
{"num_feature", n_feat}});
|
||||
ASSERT_EQ(tparam.updater_seq, "grow_quantile_histmaker");
|
||||
ASSERT_EQ(tparam.predictor, "cpu_predictor");
|
||||
|
||||
#ifdef XGBOOST_USE_CUDA
|
||||
generic_param.UpdateAllowUnknown(Args{{"gpu_id", "0"}});
|
||||
gbtree.Configure({{"tree_method", "gpu_hist"}, {"num_feature", n_feat}});
|
||||
ASSERT_EQ(tparam.updater_seq, "grow_gpu_hist");
|
||||
ASSERT_EQ(tparam.predictor, "gpu_predictor");
|
||||
gbtree.Configure({{"booster", "dart"}, {"tree_method", "gpu_hist"},
|
||||
{"num_feature", n_feat}});
|
||||
ASSERT_EQ(tparam.updater_seq, "grow_gpu_hist");
|
||||
ASSERT_EQ(tparam.predictor, "gpu_predictor");
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -9,8 +9,9 @@
|
||||
namespace xgboost {
|
||||
TEST(cpu_predictor, Test) {
|
||||
auto lparam = CreateEmptyGenericParam(GPUIDX);
|
||||
auto cache = std::make_shared<std::unordered_map<DMatrix*, PredictionCacheEntry>>();
|
||||
std::unique_ptr<Predictor> cpu_predictor =
|
||||
std::unique_ptr<Predictor>(Predictor::Create("cpu_predictor", &lparam));
|
||||
std::unique_ptr<Predictor>(Predictor::Create("cpu_predictor", &lparam, cache));
|
||||
|
||||
gbm::GBTreeModel model = CreateTestModel();
|
||||
|
||||
@@ -62,8 +63,10 @@ TEST(cpu_predictor, ExternalMemoryTest) {
|
||||
std::string filename = tmpdir.path + "/big.libsvm";
|
||||
std::unique_ptr<DMatrix> dmat = CreateSparsePageDMatrix(12, 64, filename);
|
||||
auto lparam = CreateEmptyGenericParam(GPUIDX);
|
||||
auto cache = std::make_shared<std::unordered_map<DMatrix*, PredictionCacheEntry>>();
|
||||
|
||||
std::unique_ptr<Predictor> cpu_predictor =
|
||||
std::unique_ptr<Predictor>(Predictor::Create("cpu_predictor", &lparam));
|
||||
std::unique_ptr<Predictor>(Predictor::Create("cpu_predictor", &lparam, cache));
|
||||
|
||||
gbm::GBTreeModel model = CreateTestModel();
|
||||
|
||||
|
||||
@@ -36,14 +36,15 @@ namespace predictor {
|
||||
TEST(gpu_predictor, Test) {
|
||||
auto cpu_lparam = CreateEmptyGenericParam(-1);
|
||||
auto gpu_lparam = CreateEmptyGenericParam(0);
|
||||
auto cache = std::make_shared<std::unordered_map<DMatrix*, PredictionCacheEntry>>();
|
||||
|
||||
std::unique_ptr<Predictor> gpu_predictor =
|
||||
std::unique_ptr<Predictor>(Predictor::Create("gpu_predictor", &gpu_lparam));
|
||||
std::unique_ptr<Predictor>(Predictor::Create("gpu_predictor", &gpu_lparam, cache));
|
||||
std::unique_ptr<Predictor> cpu_predictor =
|
||||
std::unique_ptr<Predictor>(Predictor::Create("cpu_predictor", &cpu_lparam));
|
||||
std::unique_ptr<Predictor>(Predictor::Create("cpu_predictor", &cpu_lparam, cache));
|
||||
|
||||
gpu_predictor->Configure({}, {});
|
||||
cpu_predictor->Configure({}, {});
|
||||
gpu_predictor->Configure({});
|
||||
cpu_predictor->Configure({});
|
||||
|
||||
for (size_t i = 1; i < 33; i *= 2) {
|
||||
int n_row = i, n_col = i;
|
||||
@@ -71,9 +72,10 @@ TEST(gpu_predictor, Test) {
|
||||
|
||||
TEST(gpu_predictor, ExternalMemoryTest) {
|
||||
auto lparam = CreateEmptyGenericParam(0);
|
||||
auto cache = std::make_shared<std::unordered_map<DMatrix*, PredictionCacheEntry>>();
|
||||
std::unique_ptr<Predictor> gpu_predictor =
|
||||
std::unique_ptr<Predictor>(Predictor::Create("gpu_predictor", &lparam));
|
||||
gpu_predictor->Configure({}, {});
|
||||
std::unique_ptr<Predictor>(Predictor::Create("gpu_predictor", &lparam, cache));
|
||||
gpu_predictor->Configure({});
|
||||
gbm::GBTreeModel model = CreateTestModel();
|
||||
model.param.num_feature = 3;
|
||||
const int n_classes = 3;
|
||||
|
||||
48
tests/python-gpu/test_gpu_training_continuation.py
Normal file
48
tests/python-gpu/test_gpu_training_continuation.py
Normal file
@@ -0,0 +1,48 @@
|
||||
import unittest
|
||||
import numpy as np
|
||||
import xgboost as xgb
|
||||
import json
|
||||
|
||||
rng = np.random.RandomState(1994)
|
||||
|
||||
|
||||
class TestGPUTrainingContinuation(unittest.TestCase):
|
||||
def test_training_continuation_binary(self):
|
||||
kRows = 32
|
||||
kCols = 16
|
||||
X = np.random.randn(kRows, kCols)
|
||||
y = np.random.randn(kRows)
|
||||
dtrain = xgb.DMatrix(X, y)
|
||||
params = {'tree_method': 'gpu_hist', 'max_depth': '2'}
|
||||
bst_0 = xgb.train(params, dtrain, num_boost_round=4)
|
||||
dump_0 = bst_0.get_dump(dump_format='json')
|
||||
|
||||
bst_1 = xgb.train(params, dtrain, num_boost_round=2)
|
||||
bst_1 = xgb.train(params, dtrain, num_boost_round=2, xgb_model=bst_1)
|
||||
dump_1 = bst_1.get_dump(dump_format='json')
|
||||
|
||||
def recursive_compare(obj_0, obj_1):
|
||||
if isinstance(obj_0, float):
|
||||
assert np.isclose(obj_0, obj_1)
|
||||
elif isinstance(obj_0, str):
|
||||
assert obj_0 == obj_1
|
||||
elif isinstance(obj_0, int):
|
||||
assert obj_0 == obj_1
|
||||
elif isinstance(obj_0, dict):
|
||||
keys_0 = list(obj_0.keys())
|
||||
keys_1 = list(obj_1.keys())
|
||||
values_0 = list(obj_0.values())
|
||||
values_1 = list(obj_1.values())
|
||||
for i in range(len(obj_0.items())):
|
||||
assert keys_0[i] == keys_1[i]
|
||||
if list(obj_0.keys())[i] != 'missing':
|
||||
recursive_compare(values_0[i],
|
||||
values_1[i])
|
||||
else:
|
||||
for i in range(len(obj_0)):
|
||||
recursive_compare(obj_0[i], obj_1[i])
|
||||
|
||||
for i in range(len(dump_0)):
|
||||
obj_0 = json.loads(dump_0[i])
|
||||
obj_1 = json.loads(dump_1[i])
|
||||
recursive_compare(obj_0, obj_1)
|
||||
@@ -45,9 +45,8 @@ class TestDistributedGPU(unittest.TestCase):
|
||||
assert isinstance(out['booster'], dxgb.Booster)
|
||||
assert len(out['history']['X']['rmse']) == 2
|
||||
|
||||
# FIXME(trivialfis): Re-enable this after #5003 is fixed
|
||||
# predictions = dxgb.predict(client, out, dtrain).compute()
|
||||
# assert isinstance(predictions, np.ndarray)
|
||||
predictions = dxgb.predict(client, out, dtrain).compute()
|
||||
assert isinstance(predictions, np.ndarray)
|
||||
|
||||
@pytest.mark.skipif(**tm.no_dask())
|
||||
@pytest.mark.skipif(**tm.no_dask_cuda())
|
||||
|
||||
Reference in New Issue
Block a user