From 4a1f7bd21fc45d6051fe3d20da0c44b498daad2e Mon Sep 17 00:00:00 2001 From: qijun Date: Mon, 31 Jul 2017 17:10:17 +0800 Subject: [PATCH] add gpu python op test --- paddle/framework/detail/tensor-inl.h | 8 ++- paddle/platform/enforce.h | 12 ++-- paddle/pybind/pybind.cc | 33 +++++++--- .../paddle/v2/framework/tests/op_test_util.py | 62 ++++++++++--------- .../paddle/v2/framework/tests/test_fc_op.py | 2 +- 5 files changed, 70 insertions(+), 47 deletions(-) diff --git a/paddle/framework/detail/tensor-inl.h b/paddle/framework/detail/tensor-inl.h index e7ff09dd5c9..9e8983e1fde 100644 --- a/paddle/framework/detail/tensor-inl.h +++ b/paddle/framework/detail/tensor-inl.h @@ -13,7 +13,7 @@ See the License for the specific language governing permissions and limitations under the License. */ #pragma once - +#include #include "paddle/memory/memcpy.h" namespace paddle { @@ -62,9 +62,11 @@ inline T* Tensor::mutable_data(platform::Place place) { if (platform::is_cpu_place(place)) { holder_.reset(new PlaceholderImpl( boost::get(place), size)); + } else if (platform::is_gpu_place(place)) { +#ifdef PADDLE_ONLY_CPU + PADDLE_THROW("'GPUPlace' is not supported in CPU only device."); } -#ifndef PADDLE_ONLY_CPU - else if (platform::is_gpu_place(place)) { +#else holder_.reset(new PlaceholderImpl( boost::get(place), size)); } diff --git a/paddle/platform/enforce.h b/paddle/platform/enforce.h index fd4adbd9dec..0b90d26b5ea 100644 --- a/paddle/platform/enforce.h +++ b/paddle/platform/enforce.h @@ -132,12 +132,12 @@ inline void throw_on_error(T e) { throw_on_error(e, ""); } -#define PADDLE_THROW(...) \ - do { \ - throw ::paddle::platform::EnforceNotMet( \ - std::make_exception_ptr( \ - std::runtime_error(string::Sprintf(__VA_ARGS__))), \ - __FILE__, __LINE__); \ +#define PADDLE_THROW(...) \ + do { \ + throw ::paddle::platform::EnforceNotMet( \ + std::make_exception_ptr( \ + std::runtime_error(paddle::string::Sprintf(__VA_ARGS__))), \ + __FILE__, __LINE__); \ } while (0) #define PADDLE_ENFORCE(...) \ diff --git a/paddle/pybind/pybind.cc b/paddle/pybind/pybind.cc index 7ef62c27c38..548277235ee 100644 --- a/paddle/pybind/pybind.cc +++ b/paddle/pybind/pybind.cc @@ -56,6 +56,14 @@ static size_t UniqueIntegerGenerator() { return generator.fetch_add(1); } +bool IsCompileGPU() { +#ifdef PADDLE_ONLY_CPU + return false; +#else + return true; +#endif +} + PYBIND11_PLUGIN(core) { py::module m("core", "C++ core of PaddlePaddle"); @@ -148,18 +156,23 @@ All parameter, weight, gradient are variables in Paddle. .def("temp", pd::OperatorBase::TMP_VAR_NAME); py::class_(m, "DeviceContext") - .def_static("cpu_context", - []() -> paddle::platform::DeviceContext* { - return new paddle::platform::CPUDeviceContext(); - }) -#ifndef PADDLE_ONLY_CPU - .def_static("gpu_context", - [](paddle::platform::GPUPlace& place) + .def_static("create", + [](paddle::platform::CPUPlace& place) -> paddle::platform::DeviceContext* { - return new paddle::platform::CUDADeviceContext(place); + return new paddle::platform::CPUDeviceContext(); }) + .def_static( + "create", + [](paddle::platform::GPUPlace& place) + -> paddle::platform::DeviceContext* { +#ifdef PADDLE_ONLY_CPU + PADDLE_THROW("'GPUPlace' is not supported in CPU only device."); + +#else + return new paddle::platform::CUDADeviceContext(place); #endif - ; // NOLINT + }); + py::class_(m, "GPUPlace").def(py::init()); py::class_(m, "CPUPlace").def(py::init<>()); @@ -198,5 +211,7 @@ All parameter, weight, gradient are variables in Paddle. m.def("unique_integer", UniqueIntegerGenerator); + m.def("is_compile_gpu", IsCompileGPU); + return m.ptr(); } diff --git a/python/paddle/v2/framework/tests/op_test_util.py b/python/paddle/v2/framework/tests/op_test_util.py index 35ee9555850..a858b32bf1f 100644 --- a/python/paddle/v2/framework/tests/op_test_util.py +++ b/python/paddle/v2/framework/tests/op_test_util.py @@ -25,42 +25,48 @@ class OpTestMeta(type): self.assertIsNotNone(func) scope = core.Scope(None) - place = core.CPUPlace() + kwargs = dict() - for in_name in func.all_input_args: - if hasattr(self, in_name): - kwargs[in_name] = in_name - var = scope.create_var(in_name).get_tensor() - arr = getattr(self, in_name) - var.set_dims(arr.shape) - var.set(arr, place) - else: - kwargs[in_name] = "@EMPTY@" + places = [] + places.append(core.CPUPlace()) + if core.is_compile_gpu(): + places.append(core.GPUPlace(0)) + + for place in places: + for in_name in func.all_input_args: + if hasattr(self, in_name): + kwargs[in_name] = in_name + var = scope.create_var(in_name).get_tensor() + arr = getattr(self, in_name) + var.set_dims(arr.shape) + var.set(arr, place) + else: + kwargs[in_name] = "@EMPTY@" - for out_name in func.all_output_args: - if hasattr(self, out_name): - kwargs[out_name] = out_name - scope.create_var(out_name).get_tensor() + for out_name in func.all_output_args: + if hasattr(self, out_name): + kwargs[out_name] = out_name + scope.create_var(out_name).get_tensor() - for attr_name in func.all_attr_args: - if hasattr(self, attr_name): - kwargs[attr_name] = getattr(self, attr_name) + for attr_name in func.all_attr_args: + if hasattr(self, attr_name): + kwargs[attr_name] = getattr(self, attr_name) - op = func(**kwargs) + op = func(**kwargs) - op.infer_shape(scope) + op.infer_shape(scope) - ctx = core.DeviceContext.cpu_context() - op.run(scope, ctx) + ctx = core.DeviceContext.create(place) + op.run(scope, ctx) - for out_name in func.all_output_args: - actual = numpy.array(scope.get_var(out_name).get_tensor()) - expect = getattr(self, out_name) - # TODO(qijun) The default decimal is 7, but numpy.dot and eigen.mul - # has some diff, and could not pass unittest. So I set decimal 3 here. - # And I will check this in future. - numpy.testing.assert_almost_equal(actual, expect, decimal=3) + for out_name in func.all_output_args: + actual = numpy.array(scope.get_var(out_name).get_tensor()) + expect = getattr(self, out_name) + # TODO(qijun) The default decimal is 7, but numpy.dot and eigen.mul + # has some diff, and could not pass unittest. So I set decimal 3 here. + # And I will check this in future. + numpy.testing.assert_almost_equal(actual, expect, decimal=3) obj.test_all = test_all return obj diff --git a/python/paddle/v2/framework/tests/test_fc_op.py b/python/paddle/v2/framework/tests/test_fc_op.py index d5fd590892f..f274f66c24c 100644 --- a/python/paddle/v2/framework/tests/test_fc_op.py +++ b/python/paddle/v2/framework/tests/test_fc_op.py @@ -33,7 +33,7 @@ class TestFc(unittest.TestCase): op.infer_shape(scope) self.assertEqual([1000, 100], tensor.shape()) - ctx = core.DeviceContext.cpu_context() + ctx = core.DeviceContext.create(place) op.run(scope, ctx) -- GitLab