未验证 提交 8305c2be 编写于 作者: J Jiabin Yang 提交者: GitHub

support eager switch system (#38170)

* support eager switch system

* polish code
上级 092839d6
cc_library(tensor_utils SRCS tensor_utils.cc DEPS pten pten_api autograd_meta grad_node_info accumulation_node) cc_library(tensor_utils SRCS tensor_utils.cc DEPS pten pten_api autograd_meta grad_node_info accumulation_node)
cc_library(hook_utils SRCS hook_utils.cc DEPS pten tensor_utils autograd_meta grad_node_info utils accumulation_node) cc_library(hook_utils SRCS hook_utils.cc DEPS pten tensor_utils autograd_meta grad_node_info utils accumulation_node)
cc_library(global_utils SRCS global_utils.cc DEPS place) cc_library(global_utils SRCS global_utils.cc DEPS place tracer)
...@@ -17,7 +17,7 @@ ...@@ -17,7 +17,7 @@
#include <atomic> #include <atomic>
#include <memory> #include <memory>
#include "paddle/fluid/platform/place.h" #include "paddle/fluid/imperative/tracer.h"
namespace egr { namespace egr {
...@@ -34,29 +34,49 @@ class UniqueNameGenerator { ...@@ -34,29 +34,49 @@ class UniqueNameGenerator {
}; };
// Global // Global
// TODO(jiabin): Now we are using imperative tracer, move it here when we
// deprecate imperative.
class Controller { class Controller {
public: public:
static Controller& Instance() { return *controller_; } static Controller& Instance() { return *controller_; }
const paddle::platform::Place& GetExpectedPlace() const { paddle::platform::Place GetExpectedPlace() const {
return *expected_place_.get(); return tracer_->ExpectedPlace();
} }
void SetExpectedPlace(const paddle::platform::Place& place) { void SetExpectedPlace(const paddle::platform::Place& place) {
expected_place_ = std::make_shared<paddle::platform::Place>(place); tracer_->SetExpectedPlace(place);
}
void SetAMPLevel(paddle::imperative::AmpLevel level) {
tracer_->SetAmpLevel(level);
} }
void SetAMPLevel(int level) { amp_level_ = level; } paddle::imperative::AmpLevel GetAMPLevel() const {
int GetAMPLevel() const { return amp_level_; } return tracer_->GetAmpLevel();
bool HasGrad() const { return has_grad_; } }
bool HasGrad() const { return tracer_->HasGrad(); }
void SetHasGrad(bool has_grad) { tracer_->SetHasGrad(has_grad); }
std::string GenerateUniqueName(std::string key = "eager_tmp") { std::string GenerateUniqueName(std::string key = "eager_tmp") {
return generator_->Generate(key); return tracer_->GenerateUniqueName(key);
}
const std::shared_ptr<paddle::imperative::Tracer>& GetCurrentTracer() {
return tracer_;
} }
void SetCurrentTracer(
const std::shared_ptr<paddle::imperative::Tracer>& tracer) {
tracer_ = tracer;
VLOG(6) << "Set current tracer: " << tracer_;
}
bool InEagerMode() const { return in_eager_mode_; }
void SetInEagerMode(bool in_eager_mode) { in_eager_mode_ = in_eager_mode; }
private: private:
Controller() = default; Controller() = default;
static Controller* controller_; static Controller* controller_;
std::shared_ptr<paddle::platform::Place> expected_place_ = nullptr; std::shared_ptr<paddle::imperative::Tracer> tracer_{
int amp_level_ = 0; new paddle::imperative::Tracer()};
bool has_grad_ = true; // TODO(jiabin): remove when we don't need imperative.
std::unique_ptr<UniqueNameGenerator> generator_{new UniqueNameGenerator()}; bool in_eager_mode_{false};
DISABLE_COPY_AND_ASSIGN(Controller); DISABLE_COPY_AND_ASSIGN(Controller);
}; };
......
...@@ -117,7 +117,7 @@ static inline std::shared_ptr<egr::EagerTensor> CastToType( ...@@ -117,7 +117,7 @@ static inline std::shared_ptr<egr::EagerTensor> CastToType(
NameTensorMap outs = {{"Out", {out}}}; NameTensorMap outs = {{"Out", {out}}};
{ {
AutoCastGuard guard(0); AutoCastGuard guard(paddle::imperative::AmpLevel::O0);
paddle::framework::AttributeMap default_attrs; paddle::framework::AttributeMap default_attrs;
RunOp("cast", ins, outs, std::move(attrs), {}, &default_attrs, true); RunOp("cast", ins, outs, std::move(attrs), {}, &default_attrs, true);
} }
......
...@@ -22,18 +22,11 @@ ...@@ -22,18 +22,11 @@
#include "paddle/fluid/eager/api/utils/global_utils.h" #include "paddle/fluid/eager/api/utils/global_utils.h"
#include "paddle/fluid/eager/eager_tensor.h" #include "paddle/fluid/eager/eager_tensor.h"
#include "paddle/fluid/eager/legacy/type_def.h" #include "paddle/fluid/eager/legacy/type_def.h"
#include "paddle/fluid/imperative/amp_auto_cast.h"
namespace egr { namespace egr {
namespace legacy { namespace legacy {
// NOTE(zhiqiu): only O1 and O2 are valid now
enum class AmpLevel {
O0 = 0, // fp32
O1, // amp, mixed fp32-fp16
O2, // almost fp16
O3, // fp16
};
class AmpOperators { class AmpOperators {
public: public:
~AmpOperators(); ~AmpOperators();
...@@ -69,7 +62,7 @@ std::ostream& operator<<(std::ostream& os, AmpOperators& ops); ...@@ -69,7 +62,7 @@ std::ostream& operator<<(std::ostream& os, AmpOperators& ops);
// NOTE(zhiqiu): AutoCastGuard is used for RAII. // NOTE(zhiqiu): AutoCastGuard is used for RAII.
class AutoCastGuard { class AutoCastGuard {
public: public:
explicit AutoCastGuard(int guard_level) { explicit AutoCastGuard(paddle::imperative::AmpLevel guard_level) {
pre_amp_level_ = Controller::Instance().GetAMPLevel(); pre_amp_level_ = Controller::Instance().GetAMPLevel();
if (pre_amp_level_ != guard_level) { if (pre_amp_level_ != guard_level) {
...@@ -84,7 +77,7 @@ class AutoCastGuard { ...@@ -84,7 +77,7 @@ class AutoCastGuard {
AutoCastGuard& operator=(const AutoCastGuard& guard) = delete; AutoCastGuard& operator=(const AutoCastGuard& guard) = delete;
private: private:
int pre_amp_level_; paddle::imperative::AmpLevel pre_amp_level_;
}; };
NameTensorMap AutoCastInputs(const std::string& op_type, NameTensorMap AutoCastInputs(const std::string& op_type,
......
...@@ -131,10 +131,10 @@ void RunOp(const std::string& type, const NameTensorMap& ins, ...@@ -131,10 +131,10 @@ void RunOp(const std::string& type, const NameTensorMap& ins,
auto amp_level = egr::Controller::Instance().GetAMPLevel(); auto amp_level = egr::Controller::Instance().GetAMPLevel();
NameTensorMap new_ins = ins; NameTensorMap new_ins = ins;
if (amp_level == 1) { if (amp_level == paddle::imperative::AmpLevel::O1) {
VLOG(5) << "Auto mixed precision run operator: " << type; VLOG(5) << "Auto mixed precision run operator: " << type;
new_ins = AutoCastInputs(type, ins); new_ins = AutoCastInputs(type, ins);
} else if (amp_level == 2) { } else if (amp_level == paddle::imperative::AmpLevel::O2) {
VLOG(5) << "Pure fp16 run operator: " << type; VLOG(5) << "Pure fp16 run operator: " << type;
new_ins = CastPureFp16Inputs(type, ins); new_ins = CastPureFp16Inputs(type, ins);
} }
......
...@@ -2,7 +2,7 @@ set(PYBIND_DEPS pybind python proto_desc memory executor fleet_wrapper box_wrapp ...@@ -2,7 +2,7 @@ set(PYBIND_DEPS pybind python proto_desc memory executor fleet_wrapper box_wrapp
feed_fetch_method pass generate_pass pass_builder parallel_executor profiler layer tracer engine scope_pool feed_fetch_method pass generate_pass pass_builder parallel_executor profiler layer tracer engine scope_pool
analysis_predictor imperative_profiler imperative_flag save_load_util dlpack_tensor device_context analysis_predictor imperative_profiler imperative_flag save_load_util dlpack_tensor device_context
gloo_wrapper infer_io_utils heter_wrapper generator op_version_registry ps_gpu_wrapper custom_operator gloo_wrapper infer_io_utils heter_wrapper generator op_version_registry ps_gpu_wrapper custom_operator
cost_model cuda_graph_with_memory_pool fleet_executor) cost_model cuda_graph_with_memory_pool fleet_executor global_utils)
if (WITH_PSCORE) if (WITH_PSCORE)
set(PYBIND_DEPS ${PYBIND_DEPS} ps_service) set(PYBIND_DEPS ${PYBIND_DEPS} ps_service)
......
...@@ -37,18 +37,17 @@ namespace py = ::pybind11; ...@@ -37,18 +37,17 @@ namespace py = ::pybind11;
PyTypeObject* p_eager_tensor_type; PyTypeObject* p_eager_tensor_type;
PyObject* eagertensor_new(PyTypeObject* type, PyObject* args, PyObject* EagerTensorNew(PyTypeObject* type, PyObject* args, PyObject* kwargs) {
PyObject* kwargs) {
PyObject* obj = type->tp_alloc(type, 0); PyObject* obj = type->tp_alloc(type, 0);
if (obj) { if (obj) {
auto v = reinterpret_cast<EagerTensorObject*>(obj); auto v = reinterpret_cast<EagerTensorObject*>(obj);
new (&(v->eagertensor)) egr::EagerTensor(); new (&(v->eager_tensor)) egr::EagerTensor();
} }
return obj; return obj;
} }
static void eagertensor_dealloc(EagerTensorObject* self) { static void eagertensor_dealloc(EagerTensorObject* self) {
self->eagertensor.~EagerTensor(); self->eager_tensor.~EagerTensor();
Py_TYPE(self)->tp_free(reinterpret_cast<PyObject*>(self)); Py_TYPE(self)->tp_free(reinterpret_cast<PyObject*>(self));
} }
...@@ -94,7 +93,7 @@ PyTypeObject eager_tensor_type = { ...@@ -94,7 +93,7 @@ PyTypeObject eager_tensor_type = {
0, /* tp_dictoffset */ 0, /* tp_dictoffset */
0, /* tp_init */ 0, /* tp_init */
0, /* tp_alloc */ 0, /* tp_alloc */
eagertensor_new, /* tp_new */ EagerTensorNew, /* tp_new */
0, /* tp_free */ 0, /* tp_free */
0, /* tp_is_gc */ 0, /* tp_is_gc */
0, /* tp_bases */ 0, /* tp_bases */
......
...@@ -90,13 +90,20 @@ static PyObject* eager_api_set_expected_place(PyObject* self, PyObject* args, ...@@ -90,13 +90,20 @@ static PyObject* eager_api_set_expected_place(PyObject* self, PyObject* args,
EAGER_CATCH_AND_THROW_RETURN_NULL EAGER_CATCH_AND_THROW_RETURN_NULL
} }
static PyObject* eager_api_get_expected_place(PyObject* self, PyObject* args,
PyObject* kwargs) {
EAGER_TRY
return ToPyObject(egr::Controller::Instance().GetExpectedPlace());
EAGER_CATCH_AND_THROW_RETURN_NULL
}
static PyObject* eager_api_scale(PyObject* self, PyObject* args, static PyObject* eager_api_scale(PyObject* self, PyObject* args,
PyObject* kwargs) { PyObject* kwargs) {
EAGER_TRY EAGER_TRY
// TODO(jiabin): Sync Tensor and Variable here when we support // TODO(jiabin): Sync Tensor and Variable here when we support
egr::EagerTensor ret = egr::EagerTensor ret =
egr::scale(reinterpret_cast<EagerTensorObject*>(PyTuple_GET_ITEM(args, 0)) egr::scale(reinterpret_cast<EagerTensorObject*>(PyTuple_GET_ITEM(args, 0))
->eagertensor, ->eager_tensor,
CastPyArg2AttrFloat(PyTuple_GET_ITEM(args, 1), 1), CastPyArg2AttrFloat(PyTuple_GET_ITEM(args, 1), 1),
CastPyArg2AttrFloat(PyTuple_GET_ITEM(args, 2), 2), CastPyArg2AttrFloat(PyTuple_GET_ITEM(args, 2), 2),
CastPyArg2AttrBoolean(PyTuple_GET_ITEM(args, 3), 3), CastPyArg2AttrBoolean(PyTuple_GET_ITEM(args, 3), 3),
...@@ -128,10 +135,10 @@ static PyObject* eager_api_numpy_to_tensor(PyObject* numpy_data, ...@@ -128,10 +135,10 @@ static PyObject* eager_api_numpy_to_tensor(PyObject* numpy_data,
PyObject* obj = p_eager_tensor_type->tp_alloc(p_eager_tensor_type, 0); PyObject* obj = p_eager_tensor_type->tp_alloc(p_eager_tensor_type, 0);
if (obj) { if (obj) {
auto v = reinterpret_cast<EagerTensorObject*>(obj); auto v = reinterpret_cast<EagerTensorObject*>(obj);
new (&(v->eagertensor)) egr::EagerTensor(); new (&(v->eager_tensor)) egr::EagerTensor();
v->eagertensor.set_impl(densetensor); v->eager_tensor.set_impl(densetensor);
v->eagertensor.set_name(egr::Controller::Instance().GenerateUniqueName()); v->eager_tensor.set_name(egr::Controller::Instance().GenerateUniqueName());
auto meta = egr::EagerUtils::autograd_meta(&(v->eagertensor)); auto meta = egr::EagerUtils::autograd_meta(&(v->eager_tensor));
meta->SetStopGradient(stop_gradient); meta->SetStopGradient(stop_gradient);
// Created tensor will be leaf tensor // Created tensor will be leaf tensor
...@@ -204,6 +211,9 @@ PyMethodDef variable_functions[] = { ...@@ -204,6 +211,9 @@ PyMethodDef variable_functions[] = {
{"_set_expected_place", {"_set_expected_place",
(PyCFunction)(void (*)(void))eager_api_set_expected_place, (PyCFunction)(void (*)(void))eager_api_set_expected_place,
METH_VARARGS | METH_KEYWORDS, NULL}, METH_VARARGS | METH_KEYWORDS, NULL},
{"_get_expected_place",
(PyCFunction)(void (*)(void))eager_api_get_expected_place,
METH_VARARGS | METH_KEYWORDS, NULL},
{"retain_grad_for_tensor", {"retain_grad_for_tensor",
(PyCFunction)(void (*)(void))eager_api_retain_grad_for_tensor, (PyCFunction)(void (*)(void))eager_api_retain_grad_for_tensor,
METH_VARARGS | METH_KEYWORDS, NULL}, METH_VARARGS | METH_KEYWORDS, NULL},
......
...@@ -36,15 +36,14 @@ extern PyTypeObject* pEagerTensorType; ...@@ -36,15 +36,14 @@ extern PyTypeObject* pEagerTensorType;
static PyObject* eager_tensor_method_numpy(EagerTensorObject* self, static PyObject* eager_tensor_method_numpy(EagerTensorObject* self,
PyObject* args, PyObject* kwargs) { PyObject* args, PyObject* kwargs) {
EAGER_TRY EAGER_SYNC_TRY
self->eagertensor.SyncToTensor(); if (!self->eager_tensor.initialized()) {
if (!self->eagertensor.initialized()) {
Py_INCREF(Py_None); Py_INCREF(Py_None);
return Py_None; return Py_None;
} }
auto tensor_dims = self->eagertensor.shape(); auto tensor_dims = self->eager_tensor.shape();
auto numpy_dtype = TensorDtype2NumpyDtype(self->eagertensor.type()); auto numpy_dtype = TensorDtype2NumpyDtype(self->eager_tensor.type());
auto sizeof_dtype = pten::DataTypeSize(self->eagertensor.type()); auto sizeof_dtype = pten::DataTypeSize(self->eager_tensor.type());
Py_intptr_t py_dims[paddle::framework::DDim::kMaxRank]; Py_intptr_t py_dims[paddle::framework::DDim::kMaxRank];
Py_intptr_t py_strides[paddle::framework::DDim::kMaxRank]; Py_intptr_t py_strides[paddle::framework::DDim::kMaxRank];
size_t numel = 1; size_t numel = 1;
...@@ -61,18 +60,18 @@ static PyObject* eager_tensor_method_numpy(EagerTensorObject* self, ...@@ -61,18 +60,18 @@ static PyObject* eager_tensor_method_numpy(EagerTensorObject* self,
pybind11::detail::npy_api::NPY_ARRAY_WRITEABLE_, pybind11::detail::npy_api::NPY_ARRAY_WRITEABLE_,
nullptr); nullptr);
if (self->eagertensor.is_cpu()) { if (self->eager_tensor.is_cpu()) {
auto dense_tensor = auto dense_tensor =
std::dynamic_pointer_cast<pten::DenseTensor>(self->eagertensor.impl()); std::dynamic_pointer_cast<pten::DenseTensor>(self->eager_tensor.impl());
platform::CPUPlace place; platform::CPUPlace place;
// deep copy // deep copy
paddle::memory::Copy(place, reinterpret_cast<void*>( paddle::memory::Copy(place, reinterpret_cast<void*>(
pybind11::detail::array_proxy(array)->data), pybind11::detail::array_proxy(array)->data),
place, dense_tensor->data(), sizeof_dtype * numel); place, dense_tensor->data(), sizeof_dtype * numel);
#if defined(PADDLE_WITH_CUDA) #if defined(PADDLE_WITH_CUDA)
} else if (self->eagertensor.is_cuda()) { } else if (self->eager_tensor.is_cuda()) {
auto dense_tensor = auto dense_tensor =
std::dynamic_pointer_cast<pten::DenseTensor>(self->eagertensor.impl()); std::dynamic_pointer_cast<pten::DenseTensor>(self->eager_tensor.impl());
paddle::platform::GpuMemcpySync( paddle::platform::GpuMemcpySync(
pybind11::detail::array_proxy(array)->data, dense_tensor->data(), pybind11::detail::array_proxy(array)->data, dense_tensor->data(),
...@@ -93,11 +92,8 @@ static PyObject* eager_tensor_method_numpy(EagerTensorObject* self, ...@@ -93,11 +92,8 @@ static PyObject* eager_tensor_method_numpy(EagerTensorObject* self,
static PyObject* eager_tensor_method_is_initialized(EagerTensorObject* self, static PyObject* eager_tensor_method_is_initialized(EagerTensorObject* self,
PyObject* args, PyObject* args,
PyObject* kwargs) { PyObject* kwargs) {
EAGER_TRY EAGER_SYNC_TRY
if (self->eagertensor.Var().IsInitialized()) { return ToPyObject(self->eager_tensor.initialized());
self->eagertensor.SyncToTensor();
}
return ToPyObject(self->eagertensor.initialized());
EAGER_CATCH_AND_THROW_RETURN_NULL EAGER_CATCH_AND_THROW_RETURN_NULL
} }
......
...@@ -36,44 +36,39 @@ extern PyTypeObject* p_eager_tensor_type; ...@@ -36,44 +36,39 @@ extern PyTypeObject* p_eager_tensor_type;
PyObject* eager_tensor_properties_get_name(EagerTensorObject* self, PyObject* eager_tensor_properties_get_name(EagerTensorObject* self,
void* closure) { void* closure) {
EAGER_TRY EAGER_SYNC_TRY
self->eagertensor.SyncToTensor(); return ToPyObject(self->eager_tensor.name());
return ToPyObject(self->eagertensor.name());
EAGER_CATCH_AND_THROW_RETURN_NULL EAGER_CATCH_AND_THROW_RETURN_NULL
} }
int eager_tensor_properties_set_name(EagerTensorObject* self, PyObject* value, int eager_tensor_properties_set_name(EagerTensorObject* self, PyObject* value,
void* closure) { void* closure) {
EAGER_TRY EAGER_SYNC_TRY
self->eagertensor.SyncToTensor(); self->eager_tensor.set_name(CastPyArg2AttrString(value, 0));
self->eagertensor.set_name(CastPyArg2AttrString(value, 0));
return 0; return 0;
EAGER_CATCH_AND_THROW_RETURN_ZERO EAGER_CATCH_AND_THROW_RETURN_ZERO
} }
PyObject* eager_tensor_properties_get_stop_gradient(EagerTensorObject* self, PyObject* eager_tensor_properties_get_stop_gradient(EagerTensorObject* self,
void* closure) { void* closure) {
EAGER_TRY EAGER_SYNC_TRY
self->eagertensor.SyncToTensor(); auto meta = egr::EagerUtils::autograd_meta(&self->eager_tensor);
auto meta = egr::EagerUtils::autograd_meta(&self->eagertensor);
return ToPyObject(meta->StopGradient()); return ToPyObject(meta->StopGradient());
EAGER_CATCH_AND_THROW_RETURN_NULL EAGER_CATCH_AND_THROW_RETURN_NULL
} }
PyObject* eager_tensor_properties_get_grad(EagerTensorObject* self, PyObject* eager_tensor_properties_get_grad(EagerTensorObject* self,
void* closure) { void* closure) {
EAGER_TRY EAGER_SYNC_TRY
self->eagertensor.SyncToTensor(); auto meta = egr::EagerUtils::unsafe_autograd_meta(self->eager_tensor);
auto meta = egr::EagerUtils::unsafe_autograd_meta(self->eagertensor);
return ToPyObject(meta->Grad()); return ToPyObject(meta->Grad());
EAGER_CATCH_AND_THROW_RETURN_NULL EAGER_CATCH_AND_THROW_RETURN_NULL
} }
int eager_tensor_properties_set_stop_gradient(EagerTensorObject* self, int eager_tensor_properties_set_stop_gradient(EagerTensorObject* self,
PyObject* value, void* closure) { PyObject* value, void* closure) {
EAGER_TRY EAGER_SYNC_TRY
self->eagertensor.SyncToTensor(); auto meta = egr::EagerUtils::autograd_meta(&self->eager_tensor);
auto meta = egr::EagerUtils::autograd_meta(&self->eagertensor);
meta->SetStopGradient(CastPyArg2AttrBoolean(value, 0)); meta->SetStopGradient(CastPyArg2AttrBoolean(value, 0));
return 0; return 0;
EAGER_CATCH_AND_THROW_RETURN_ZERO EAGER_CATCH_AND_THROW_RETURN_ZERO
...@@ -81,18 +76,16 @@ int eager_tensor_properties_set_stop_gradient(EagerTensorObject* self, ...@@ -81,18 +76,16 @@ int eager_tensor_properties_set_stop_gradient(EagerTensorObject* self,
PyObject* eager_tensor_properties_get_persistable(EagerTensorObject* self, PyObject* eager_tensor_properties_get_persistable(EagerTensorObject* self,
void* closure) { void* closure) {
EAGER_TRY EAGER_SYNC_TRY
self->eagertensor.SyncToTensor(); auto meta = egr::EagerUtils::autograd_meta(&self->eager_tensor);
auto meta = egr::EagerUtils::autograd_meta(&self->eagertensor);
return ToPyObject(meta->Persistable()); return ToPyObject(meta->Persistable());
EAGER_CATCH_AND_THROW_RETURN_NULL EAGER_CATCH_AND_THROW_RETURN_NULL
} }
int eager_tensor_properties_set_persistable(EagerTensorObject* self, int eager_tensor_properties_set_persistable(EagerTensorObject* self,
PyObject* value, void* closure) { PyObject* value, void* closure) {
EAGER_TRY EAGER_SYNC_TRY
self->eagertensor.SyncToTensor(); auto meta = egr::EagerUtils::autograd_meta(&self->eager_tensor);
auto meta = egr::EagerUtils::autograd_meta(&self->eagertensor);
meta->SetPersistable(CastPyArg2AttrBoolean(value, 0)); meta->SetPersistable(CastPyArg2AttrBoolean(value, 0));
return 0; return 0;
EAGER_CATCH_AND_THROW_RETURN_ZERO EAGER_CATCH_AND_THROW_RETURN_ZERO
...@@ -100,9 +93,8 @@ int eager_tensor_properties_set_persistable(EagerTensorObject* self, ...@@ -100,9 +93,8 @@ int eager_tensor_properties_set_persistable(EagerTensorObject* self,
PyObject* eager_tensor_properties_get_shape(EagerTensorObject* self, PyObject* eager_tensor_properties_get_shape(EagerTensorObject* self,
void* closure) { void* closure) {
EAGER_TRY EAGER_SYNC_TRY
self->eagertensor.SyncToTensor(); auto ddim = self->eager_tensor.shape();
auto ddim = self->eagertensor.shape();
std::vector<int64_t> value; std::vector<int64_t> value;
size_t rank = static_cast<size_t>(ddim.size()); size_t rank = static_cast<size_t>(ddim.size());
value.resize(rank); value.resize(rank);
...@@ -116,27 +108,24 @@ PyObject* eager_tensor_properties_get_shape(EagerTensorObject* self, ...@@ -116,27 +108,24 @@ PyObject* eager_tensor_properties_get_shape(EagerTensorObject* self,
PyObject* eager_tensor_properties_get_place(EagerTensorObject* self, PyObject* eager_tensor_properties_get_place(EagerTensorObject* self,
void* closure) { void* closure) {
EAGER_TRY EAGER_SYNC_TRY
self->eagertensor.SyncToTensor(); return ToPyObject(self->eager_tensor.place());
return ToPyObject(self->eagertensor.place());
EAGER_CATCH_AND_THROW_RETURN_NULL EAGER_CATCH_AND_THROW_RETURN_NULL
} }
PyObject* eager_tensor_properties_get_place_str(EagerTensorObject* self, PyObject* eager_tensor_properties_get_place_str(EagerTensorObject* self,
void* closure) { void* closure) {
EAGER_TRY EAGER_SYNC_TRY
self->eagertensor.SyncToTensor();
std::stringstream ostr; std::stringstream ostr;
ostr << self->eagertensor.place(); ostr << self->eager_tensor.place();
return ToPyObject(ostr.str()); return ToPyObject(ostr.str());
EAGER_CATCH_AND_THROW_RETURN_NULL EAGER_CATCH_AND_THROW_RETURN_NULL
} }
PyObject* eager_tensor_properties_get_dtype(EagerTensorObject* self, PyObject* eager_tensor_properties_get_dtype(EagerTensorObject* self,
void* closure) { void* closure) {
EAGER_TRY EAGER_SYNC_TRY
self->eagertensor.SyncToTensor(); return ToPyObject(pten::TransToProtoVarType(self->eager_tensor.type()));
return ToPyObject(pten::DataType2String(self->eagertensor.type()));
EAGER_CATCH_AND_THROW_RETURN_NULL EAGER_CATCH_AND_THROW_RETURN_NULL
} }
......
...@@ -33,6 +33,7 @@ namespace pybind { ...@@ -33,6 +33,7 @@ namespace pybind {
extern PyTypeObject* p_eager_tensor_type; extern PyTypeObject* p_eager_tensor_type;
extern PyTypeObject* g_vartype_pytype;
extern PyTypeObject* g_place_pytype; extern PyTypeObject* g_place_pytype;
extern PyTypeObject* g_cudaplace_pytype; extern PyTypeObject* g_cudaplace_pytype;
extern PyTypeObject* g_cpuplace_pytype; extern PyTypeObject* g_cpuplace_pytype;
...@@ -174,7 +175,7 @@ std::string CastPyArg2AttrString(PyObject* obj, ssize_t arg_pos) { ...@@ -174,7 +175,7 @@ std::string CastPyArg2AttrString(PyObject* obj, ssize_t arg_pos) {
egr::EagerTensor CastPyArg2EagerTensor(PyObject* obj, ssize_t arg_pos) { egr::EagerTensor CastPyArg2EagerTensor(PyObject* obj, ssize_t arg_pos) {
if (PyObject_IsInstance(obj, if (PyObject_IsInstance(obj,
reinterpret_cast<PyObject*>(p_eager_tensor_type))) { reinterpret_cast<PyObject*>(p_eager_tensor_type))) {
return reinterpret_cast<EagerTensorObject*>(obj)->eagertensor; return reinterpret_cast<EagerTensorObject*>(obj)->eager_tensor;
} else { } else {
PADDLE_THROW(platform::errors::InvalidArgument( PADDLE_THROW(platform::errors::InvalidArgument(
"argument (position %d) must be " "argument (position %d) must be "
...@@ -194,7 +195,7 @@ std::vector<egr::EagerTensor> CastPyArg2VectorOfEagerTensor(PyObject* obj, ...@@ -194,7 +195,7 @@ std::vector<egr::EagerTensor> CastPyArg2VectorOfEagerTensor(PyObject* obj,
if (PyObject_IsInstance( if (PyObject_IsInstance(
item, reinterpret_cast<PyObject*>(p_eager_tensor_type))) { item, reinterpret_cast<PyObject*>(p_eager_tensor_type))) {
result.emplace_back( result.emplace_back(
reinterpret_cast<EagerTensorObject*>(item)->eagertensor); reinterpret_cast<EagerTensorObject*>(item)->eager_tensor);
} else { } else {
PADDLE_THROW(platform::errors::InvalidArgument( PADDLE_THROW(platform::errors::InvalidArgument(
"argument (position %d) must be " "argument (position %d) must be "
...@@ -211,7 +212,7 @@ std::vector<egr::EagerTensor> CastPyArg2VectorOfEagerTensor(PyObject* obj, ...@@ -211,7 +212,7 @@ std::vector<egr::EagerTensor> CastPyArg2VectorOfEagerTensor(PyObject* obj,
if (PyObject_IsInstance( if (PyObject_IsInstance(
item, reinterpret_cast<PyObject*>(p_eager_tensor_type))) { item, reinterpret_cast<PyObject*>(p_eager_tensor_type))) {
result.emplace_back( result.emplace_back(
reinterpret_cast<EagerTensorObject*>(item)->eagertensor); reinterpret_cast<EagerTensorObject*>(item)->eager_tensor);
} else { } else {
PADDLE_THROW(platform::errors::InvalidArgument( PADDLE_THROW(platform::errors::InvalidArgument(
"argument (position %d) must be " "argument (position %d) must be "
...@@ -258,6 +259,22 @@ platform::Place CastPyArg2Place(PyObject* obj, ssize_t arg_pos) { ...@@ -258,6 +259,22 @@ platform::Place CastPyArg2Place(PyObject* obj, ssize_t arg_pos) {
return place; return place;
} }
paddle::framework::proto::VarType::Type CastPyArg2ProtoType(PyObject* obj,
ssize_t arg_pos) {
paddle::framework::proto::VarType::Type dtype;
if (PyObject_IsInstance(obj, reinterpret_cast<PyObject*>(g_vartype_pytype))) {
dtype =
::pybind11::handle(obj).cast<paddle::framework::proto::VarType::Type>();
} else {
PADDLE_THROW(platform::errors::InvalidArgument(
"argument (position %d) must be "
"one of core.VarDesc.VarType, "
"but got %s",
arg_pos + 1, reinterpret_cast<PyTypeObject*>(obj->ob_type)->tp_name));
}
return dtype;
}
PyObject* ToPyObject(bool value) { PyObject* ToPyObject(bool value) {
if (value) { if (value) {
Py_INCREF(Py_True); Py_INCREF(Py_True);
...@@ -286,8 +303,8 @@ PyObject* ToPyObject(const egr::EagerTensor& value) { ...@@ -286,8 +303,8 @@ PyObject* ToPyObject(const egr::EagerTensor& value) {
PyObject* obj = p_eager_tensor_type->tp_alloc(p_eager_tensor_type, 0); PyObject* obj = p_eager_tensor_type->tp_alloc(p_eager_tensor_type, 0);
if (obj) { if (obj) {
auto v = reinterpret_cast<EagerTensorObject*>(obj); auto v = reinterpret_cast<EagerTensorObject*>(obj);
new (&(v->eagertensor)) egr::EagerTensor(); new (&(v->eager_tensor)) egr::EagerTensor();
v->eagertensor = value; v->eager_tensor = value;
} else { } else {
PADDLE_THROW(platform::errors::Fatal( PADDLE_THROW(platform::errors::Fatal(
"tp_alloc return null, can not new a PyObject.")); "tp_alloc return null, can not new a PyObject."));
...@@ -352,8 +369,8 @@ PyObject* ToPyObject(const std::vector<egr::EagerTensor>& value) { ...@@ -352,8 +369,8 @@ PyObject* ToPyObject(const std::vector<egr::EagerTensor>& value) {
PyObject* obj = p_eager_tensor_type->tp_alloc(p_eager_tensor_type, 0); PyObject* obj = p_eager_tensor_type->tp_alloc(p_eager_tensor_type, 0);
if (obj) { if (obj) {
auto v = reinterpret_cast<EagerTensorObject*>(obj); auto v = reinterpret_cast<EagerTensorObject*>(obj);
new (&(v->eagertensor)) egr::EagerTensor(); new (&(v->eager_tensor)) egr::EagerTensor();
v->eagertensor = value[i]; v->eager_tensor = value[i];
} else { } else {
PADDLE_THROW(platform::errors::Fatal( PADDLE_THROW(platform::errors::Fatal(
"tp_alloc return null, can not new a PyObject.")); "tp_alloc return null, can not new a PyObject."));
...@@ -370,6 +387,12 @@ PyObject* ToPyObject(const platform::Place& value) { ...@@ -370,6 +387,12 @@ PyObject* ToPyObject(const platform::Place& value) {
return obj.ptr(); return obj.ptr();
} }
PyObject* ToPyObject(const paddle::framework::proto::VarType::Type& dtype) {
auto obj = ::pybind11::cast(dtype);
obj.inc_ref();
return obj.ptr();
}
PyObject* ToPyObject(const void* value) { PyObject* ToPyObject(const void* value) {
if (value == nullptr) { if (value == nullptr) {
Py_INCREF(Py_None); Py_INCREF(Py_None);
...@@ -399,7 +422,7 @@ egr::EagerTensor GetEagerTensorFromArgs(const std::string& op_type, ...@@ -399,7 +422,7 @@ egr::EagerTensor GetEagerTensorFromArgs(const std::string& op_type,
return emptytensor; return emptytensor;
} }
return reinterpret_cast<EagerTensorObject*>(obj)->eagertensor; return reinterpret_cast<EagerTensorObject*>(obj)->eager_tensor;
} }
std::vector<egr::EagerTensor> GetEagerTensorListFromArgs( std::vector<egr::EagerTensor> GetEagerTensorListFromArgs(
...@@ -430,7 +453,7 @@ std::vector<egr::EagerTensor> GetEagerTensorListFromArgs( ...@@ -430,7 +453,7 @@ std::vector<egr::EagerTensor> GetEagerTensorListFromArgs(
for (Py_ssize_t i = 0; i < len; i++) { for (Py_ssize_t i = 0; i < len; i++) {
result.emplace_back( result.emplace_back(
reinterpret_cast<EagerTensorObject*>(PyList_GetItem(list, i)) reinterpret_cast<EagerTensorObject*>(PyList_GetItem(list, i))
->eagertensor); ->eager_tensor);
} }
} else if (PyTuple_Check(list)) { } else if (PyTuple_Check(list)) {
Py_ssize_t len = PyTuple_Size(list); Py_ssize_t len = PyTuple_Size(list);
...@@ -443,7 +466,7 @@ std::vector<egr::EagerTensor> GetEagerTensorListFromArgs( ...@@ -443,7 +466,7 @@ std::vector<egr::EagerTensor> GetEagerTensorListFromArgs(
for (Py_ssize_t i = 0; i < len; i++) { for (Py_ssize_t i = 0; i < len; i++) {
result.emplace_back( result.emplace_back(
reinterpret_cast<EagerTensorObject*>(PyTuple_GetItem(list, i)) reinterpret_cast<EagerTensorObject*>(PyTuple_GetItem(list, i))
->eagertensor); ->eager_tensor);
} }
} else { } else {
PADDLE_THROW(platform::errors::InvalidArgument( PADDLE_THROW(platform::errors::InvalidArgument(
......
...@@ -18,7 +18,7 @@ namespace paddle { ...@@ -18,7 +18,7 @@ namespace paddle {
namespace pybind { namespace pybind {
typedef struct { typedef struct {
PyObject_HEAD egr::EagerTensor eagertensor; PyObject_HEAD egr::EagerTensor eager_tensor;
} EagerTensorObject; } EagerTensorObject;
int TensorDtype2NumpyDtype(pten::DataType dtype); int TensorDtype2NumpyDtype(pten::DataType dtype);
...@@ -35,7 +35,8 @@ egr::EagerTensor CastPyArg2EagerTensor(PyObject* obj, ssize_t arg_pos); ...@@ -35,7 +35,8 @@ egr::EagerTensor CastPyArg2EagerTensor(PyObject* obj, ssize_t arg_pos);
std::vector<egr::EagerTensor> CastPyArg2VectorOfEagerTensor(PyObject* obj, std::vector<egr::EagerTensor> CastPyArg2VectorOfEagerTensor(PyObject* obj,
ssize_t arg_pos); ssize_t arg_pos);
platform::Place CastPyArg2Place(PyObject* obj, ssize_t arg_pos); platform::Place CastPyArg2Place(PyObject* obj, ssize_t arg_pos);
framework::proto::VarType::Type CastPyArg2ProtoType(PyObject* obj,
ssize_t arg_pos);
PyObject* ToPyObject(int value); PyObject* ToPyObject(int value);
PyObject* ToPyObject(bool value); PyObject* ToPyObject(bool value);
PyObject* ToPyObject(int64_t value); PyObject* ToPyObject(int64_t value);
...@@ -51,6 +52,7 @@ PyObject* ToPyObject(const std::vector<float>& value); ...@@ -51,6 +52,7 @@ PyObject* ToPyObject(const std::vector<float>& value);
PyObject* ToPyObject(const std::vector<double>& value); PyObject* ToPyObject(const std::vector<double>& value);
PyObject* ToPyObject(const std::vector<egr::EagerTensor>& value); PyObject* ToPyObject(const std::vector<egr::EagerTensor>& value);
PyObject* ToPyObject(const platform::Place& value); PyObject* ToPyObject(const platform::Place& value);
PyObject* ToPyObject(const paddle::framework::proto::VarType::Type& dtype);
PyObject* ToPyObject(const void* value); PyObject* ToPyObject(const void* value);
template <typename Tuple, size_t N> template <typename Tuple, size_t N>
......
...@@ -19,6 +19,12 @@ limitations under the License. */ ...@@ -19,6 +19,12 @@ limitations under the License. */
#include "pybind11/pybind11.h" #include "pybind11/pybind11.h"
#define EAGER_TRY try { #define EAGER_TRY try {
#define EAGER_SYNC_TRY \
try { \
if (self->eager_tensor.Var().IsInitialized()) { \
self->eager_tensor.SyncToTensor(); \
}
#define EAGER_CATCH_AND_THROW_RETURN_NULL \ #define EAGER_CATCH_AND_THROW_RETURN_NULL \
} \ } \
catch (...) { \ catch (...) { \
......
...@@ -29,6 +29,7 @@ limitations under the License. */ ...@@ -29,6 +29,7 @@ limitations under the License. */
#include <utility> #include <utility>
#include <vector> #include <vector>
#include "paddle/fluid/eager/api/all.h"
#include "paddle/fluid/framework/scope_guard.h" #include "paddle/fluid/framework/scope_guard.h"
#include "paddle/fluid/imperative/all_reduce.h" #include "paddle/fluid/imperative/all_reduce.h"
#include "paddle/fluid/imperative/amp_auto_cast.h" #include "paddle/fluid/imperative/amp_auto_cast.h"
...@@ -868,9 +869,18 @@ void BindImperative(py::module *m_ptr) { ...@@ -868,9 +869,18 @@ void BindImperative(py::module *m_ptr) {
m.def("_dygraph_debug_level", []() { return imperative::GetDebugLevel(); }); m.def("_dygraph_debug_level", []() { return imperative::GetDebugLevel(); });
m.def("_switch_tracer", m.def("_switch_tracer",
[](const std::shared_ptr<imperative::Tracer> &tracer) { [](const std::shared_ptr<imperative::Tracer> &tracer) {
if (egr::Controller::Instance().InEagerMode()) {
egr::Controller::Instance().SetCurrentTracer(tracer);
} else {
imperative::SetCurrentTracer(tracer); imperative::SetCurrentTracer(tracer);
}
}); });
m.def("_enable_eager_mode",
[]() { egr::Controller::Instance().SetInEagerMode(true); });
m.def("_disable_eager_mode",
[]() { egr::Controller::Instance().SetInEagerMode(false); });
m.def("_in_eager_mode",
[]() { return egr::Controller::Instance().InEagerMode(); });
py::class_<imperative::VarBase, std::shared_ptr<imperative::VarBase>> varbase( py::class_<imperative::VarBase, std::shared_ptr<imperative::VarBase>> varbase(
m, "VarBase", R"DOC()DOC"); m, "VarBase", R"DOC()DOC");
g_varbase_pytype = (PyTypeObject *)varbase.ptr(); // NOLINT g_varbase_pytype = (PyTypeObject *)varbase.ptr(); // NOLINT
......
...@@ -268,6 +268,9 @@ if avx_supported(): ...@@ -268,6 +268,9 @@ if avx_supported():
from .core_avx import _is_dygraph_debug_enabled from .core_avx import _is_dygraph_debug_enabled
from .core_avx import _dygraph_debug_level from .core_avx import _dygraph_debug_level
from .core_avx import _switch_tracer from .core_avx import _switch_tracer
from .core_avx import _disable_eager_mode
from .core_avx import _enable_eager_mode
from .core_avx import _in_eager_mode
from .core_avx import _set_paddle_lib_path from .core_avx import _set_paddle_lib_path
from .core_avx import _create_loaded_parameter from .core_avx import _create_loaded_parameter
from .core_avx import _cuda_synchronize from .core_avx import _cuda_synchronize
...@@ -321,6 +324,9 @@ if load_noavx: ...@@ -321,6 +324,9 @@ if load_noavx:
from .core_noavx import _is_dygraph_debug_enabled from .core_noavx import _is_dygraph_debug_enabled
from .core_noavx import _dygraph_debug_level from .core_noavx import _dygraph_debug_level
from .core_noavx import _switch_tracer from .core_noavx import _switch_tracer
from .core_noavx import _disable_eager_mode
from .core_noavx import _enable_eager_mode
from .core_noavx import _in_eager_mode
from .core_noavx import _set_paddle_lib_path from .core_noavx import _set_paddle_lib_path
from .core_noavx import _create_loaded_parameter from .core_noavx import _create_loaded_parameter
from .core_noavx import _cuda_synchronize from .core_noavx import _cuda_synchronize
......
...@@ -46,8 +46,6 @@ __all__ = [ ...@@ -46,8 +46,6 @@ __all__ = [
'Program', 'Program',
'default_startup_program', 'default_startup_program',
'default_main_program', 'default_main_program',
'eager_guard',
'in_eager_mode',
'program_guard', 'program_guard',
'name_scope', 'name_scope',
'cuda_places', 'cuda_places',
...@@ -79,46 +77,20 @@ _current_device = None ...@@ -79,46 +77,20 @@ _current_device = None
global_prog_seed = 0 global_prog_seed = 0
_current_pipeline_stage = None _current_pipeline_stage = None
_global_flags_ = core.globals() _global_flags_ = core.globals()
_eager_mode_ = False core._disable_eager_mode()
@signature_safe_contextmanager @signature_safe_contextmanager
def eager_mode_place_guard(place): def _test_eager_guard():
if place is not None: core._enable_eager_mode()
expected_place = _get_paddle_place(place)
else:
expected_place = _current_expected_place()
global _global_expected_place_
tmp_place = _global_expected_place_
_global_expected_place_ = expected_place
_set_expected_place(expected_place)
try:
yield
finally:
_global_expected_place_ = tmp_place
_set_expected_place(tmp_place)
@signature_safe_contextmanager
def eager_guard(place=None):
global _eager_mode_
_eager_mode_ = True
_C_ops.switch_to_eager_ops() _C_ops.switch_to_eager_ops()
try: try:
with eager_mode_place_guard(place):
yield yield
finally: finally:
_eager_mode_ = False core._disable_eager_mode()
_C_ops.switch_to_core_ops() _C_ops.switch_to_core_ops()
def in_eager_mode():
return _eager_mode_
def require_version(min_version, max_version=None): def require_version(min_version, max_version=None):
""" """
Check if the installed version of PaddlePaddle is in [min_version, max_version], Check if the installed version of PaddlePaddle is in [min_version, max_version],
...@@ -256,6 +228,10 @@ def in_dygraph_mode(): ...@@ -256,6 +228,10 @@ def in_dygraph_mode():
return _dygraph_tracer_ is not None return _dygraph_tracer_ is not None
def _in_eager_mode():
return core._in_eager_mode() and in_dygraph_mode()
def _dygraph_not_support_(func): def _dygraph_not_support_(func):
def __impl__(*args, **kwargs): def __impl__(*args, **kwargs):
assert not in_dygraph_mode( assert not in_dygraph_mode(
...@@ -382,9 +358,8 @@ def _set_dygraph_tracer_expected_place(place): ...@@ -382,9 +358,8 @@ def _set_dygraph_tracer_expected_place(place):
def _set_expected_place(place): def _set_expected_place(place):
global _global_expected_place_ global _global_expected_place_
_global_expected_place_ = place _global_expected_place_ = place
if in_eager_mode(): if _in_eager_mode():
return core.eager._set_expected_place(place) return core.eager._set_expected_place(place)
else:
_set_dygraph_tracer_expected_place(place) _set_dygraph_tracer_expected_place(place)
...@@ -6441,14 +6416,17 @@ def _dygraph_place_guard(place): ...@@ -6441,14 +6416,17 @@ def _dygraph_place_guard(place):
global _global_expected_place_ global _global_expected_place_
tmp_place = _global_expected_place_ tmp_place = _global_expected_place_
_global_expected_place_ = place _global_expected_place_ = place
if _in_eager_mode():
core.eager._set_expected_place(place)
_set_dygraph_tracer_expected_place(place) _set_dygraph_tracer_expected_place(place)
try: try:
yield yield
finally: finally:
_global_expected_place_ = tmp_place _global_expected_place_ = tmp_place
_set_dygraph_tracer_expected_place(tmp_place) if _in_eager_mode():
core.eager._set_expected_place(_global_expected_place_)
_set_dygraph_tracer_expected_place(_global_expected_place_)
def switch_device(device): def switch_device(device):
......
...@@ -16,13 +16,13 @@ import paddle.fluid.core as core ...@@ -16,13 +16,13 @@ import paddle.fluid.core as core
import paddle.fluid.eager.eager_tensor_patch_methods as eager_tensor_patch_methods import paddle.fluid.eager.eager_tensor_patch_methods as eager_tensor_patch_methods
import paddle import paddle
import numpy as np import numpy as np
from paddle.fluid import eager_guard from paddle.fluid.framework import _test_eager_guard
import unittest import unittest
class EagerOpAPIGenerateTestCase(unittest.TestCase): class EagerOpAPIGenerateTestCase(unittest.TestCase):
def test_elementwise_add(self): def test_elementwise_add(self):
with eager_guard(): with _test_eager_guard():
paddle.set_device("cpu") paddle.set_device("cpu")
np_x = np.ones([4, 16, 16, 32]).astype('float32') np_x = np.ones([4, 16, 16, 32]).astype('float32')
np_y = np.ones([4, 16, 16, 32]).astype('float32') np_y = np.ones([4, 16, 16, 32]).astype('float32')
...@@ -35,7 +35,7 @@ class EagerOpAPIGenerateTestCase(unittest.TestCase): ...@@ -35,7 +35,7 @@ class EagerOpAPIGenerateTestCase(unittest.TestCase):
self.assertTrue(np.array_equal(out_arr, out_arr_expected)) self.assertTrue(np.array_equal(out_arr, out_arr_expected))
def test_sum(self): def test_sum(self):
with eager_guard(): with _test_eager_guard():
x_data = np.array( x_data = np.array(
[[0.2, 0.3, 0.5, 0.9], [0.1, 0.2, 0.6, 0.7]]).astype('float32') [[0.2, 0.3, 0.5, 0.9], [0.1, 0.2, 0.6, 0.7]]).astype('float32')
x = paddle.to_tensor(x_data, 'float32') x = paddle.to_tensor(x_data, 'float32')
...@@ -45,7 +45,7 @@ class EagerOpAPIGenerateTestCase(unittest.TestCase): ...@@ -45,7 +45,7 @@ class EagerOpAPIGenerateTestCase(unittest.TestCase):
self.assertTrue(np.array_equal(out_arr, out_arr_expected)) self.assertTrue(np.array_equal(out_arr, out_arr_expected))
def test_mm(self): def test_mm(self):
with eager_guard(): with _test_eager_guard():
np_input = np.random.random([16, 32]).astype('float32') np_input = np.random.random([16, 32]).astype('float32')
np_mat2 = np.random.random([32, 32]).astype('float32') np_mat2 = np.random.random([32, 32]).astype('float32')
input = paddle.to_tensor(np_input) input = paddle.to_tensor(np_input)
...@@ -56,7 +56,7 @@ class EagerOpAPIGenerateTestCase(unittest.TestCase): ...@@ -56,7 +56,7 @@ class EagerOpAPIGenerateTestCase(unittest.TestCase):
self.assertTrue(np.allclose(out_arr, out_arr_expected)) self.assertTrue(np.allclose(out_arr, out_arr_expected))
def test_sigmoid(self): def test_sigmoid(self):
with eager_guard(): with _test_eager_guard():
np_x = np.array([-0.4, -0.2, 0.1, 0.3]).astype('float32') np_x = np.array([-0.4, -0.2, 0.1, 0.3]).astype('float32')
x = paddle.to_tensor(np_x) x = paddle.to_tensor(np_x)
out = paddle.nn.functional.sigmoid(x) out = paddle.nn.functional.sigmoid(x)
......
...@@ -16,13 +16,14 @@ import paddle.fluid.core as core ...@@ -16,13 +16,14 @@ import paddle.fluid.core as core
import paddle.fluid.eager.eager_tensor_patch_methods as eager_tensor_patch_methods import paddle.fluid.eager.eager_tensor_patch_methods as eager_tensor_patch_methods
import paddle import paddle
import numpy as np import numpy as np
from paddle.fluid import eager_guard from paddle.fluid.framework import _test_eager_guard
from paddle.fluid.data_feeder import convert_dtype
import unittest import unittest
class EagerScaleTestCase(unittest.TestCase): class EagerScaleTestCase(unittest.TestCase):
def test_scale_base(self): def test_scale_base(self):
with eager_guard(): with _test_eager_guard():
paddle.set_device("cpu") paddle.set_device("cpu")
arr = np.ones([4, 16, 16, 32]).astype('float32') arr = np.ones([4, 16, 16, 32]).astype('float32')
tensor = paddle.to_tensor(arr, 'float32', core.CPUPlace()) tensor = paddle.to_tensor(arr, 'float32', core.CPUPlace())
...@@ -35,7 +36,7 @@ class EagerScaleTestCase(unittest.TestCase): ...@@ -35,7 +36,7 @@ class EagerScaleTestCase(unittest.TestCase):
self.assertEqual(tensor.stop_gradient, True) self.assertEqual(tensor.stop_gradient, True)
def test_retain_grad_and_run_backward(self): def test_retain_grad_and_run_backward(self):
with eager_guard(): with _test_eager_guard():
paddle.set_device("cpu") paddle.set_device("cpu")
input_data = np.ones([4, 16, 16, 32]).astype('float32') input_data = np.ones([4, 16, 16, 32]).astype('float32')
...@@ -55,33 +56,38 @@ class EagerScaleTestCase(unittest.TestCase): ...@@ -55,33 +56,38 @@ class EagerScaleTestCase(unittest.TestCase):
class EagerDtypeTestCase(unittest.TestCase): class EagerDtypeTestCase(unittest.TestCase):
def check_to_tesnsor_and_numpy(self, dtype): def check_to_tesnsor_and_numpy(self, dtype, proto_dtype):
with eager_guard(): with _test_eager_guard():
arr = np.random.random([4, 16, 16, 32]).astype(dtype) arr = np.random.random([4, 16, 16, 32]).astype(dtype)
tensor = paddle.to_tensor(arr, dtype) tensor = paddle.to_tensor(arr, dtype)
self.assertEqual(tensor.dtype, dtype) self.assertEqual(tensor.dtype, proto_dtype)
self.assertTrue(np.array_equal(arr, tensor.numpy())) self.assertTrue(np.array_equal(arr, tensor.numpy()))
def test_dtype_base(self): def test_dtype_base(self):
self.check_to_tesnsor_and_numpy('bool') print("Test_dtype")
self.check_to_tesnsor_and_numpy('int8') self.check_to_tesnsor_and_numpy('bool', core.VarDesc.VarType.BOOL)
self.check_to_tesnsor_and_numpy('uint8') self.check_to_tesnsor_and_numpy('int8', core.VarDesc.VarType.INT8)
self.check_to_tesnsor_and_numpy('int16') self.check_to_tesnsor_and_numpy('uint8', core.VarDesc.VarType.UINT8)
self.check_to_tesnsor_and_numpy('int32') self.check_to_tesnsor_and_numpy('int16', core.VarDesc.VarType.INT16)
self.check_to_tesnsor_and_numpy('int64') self.check_to_tesnsor_and_numpy('int32', core.VarDesc.VarType.INT32)
self.check_to_tesnsor_and_numpy('float16') self.check_to_tesnsor_and_numpy('int64', core.VarDesc.VarType.INT64)
self.check_to_tesnsor_and_numpy('float32') self.check_to_tesnsor_and_numpy('float16', core.VarDesc.VarType.FP16)
self.check_to_tesnsor_and_numpy('float64') self.check_to_tesnsor_and_numpy('float32', core.VarDesc.VarType.FP32)
self.check_to_tesnsor_and_numpy('complex64') self.check_to_tesnsor_and_numpy('float64', core.VarDesc.VarType.FP64)
self.check_to_tesnsor_and_numpy('complex128') self.check_to_tesnsor_and_numpy('complex64',
core.VarDesc.VarType.COMPLEX64)
self.check_to_tesnsor_and_numpy('complex128',
core.VarDesc.VarType.COMPLEX128)
class EagerTensorPropertiesTestCase(unittest.TestCase): class EagerTensorPropertiesTestCase(unittest.TestCase):
def test_properties(self): def test_properties(self):
with eager_guard(): print("Test_properties")
with _test_eager_guard():
paddle.set_device("cpu") paddle.set_device("cpu")
arr = np.ones([4, 16, 16, 32]).astype('float32') arr = np.ones([4, 16, 16, 32]).astype('float32')
tensor = paddle.to_tensor(arr, 'float32', core.CPUPlace()) tensor = paddle.to_tensor(arr, core.VarDesc.VarType.FP32,
core.CPUPlace())
self.assertEqual(tensor.shape, [4, 16, 16, 32]) self.assertEqual(tensor.shape, [4, 16, 16, 32])
tensor.name = 'tensor_name_test' tensor.name = 'tensor_name_test'
self.assertEqual(tensor.name, 'tensor_name_test') self.assertEqual(tensor.name, 'tensor_name_test')
...@@ -98,6 +104,25 @@ class EagerTensorPropertiesTestCase(unittest.TestCase): ...@@ -98,6 +104,25 @@ class EagerTensorPropertiesTestCase(unittest.TestCase):
tensor.stop_gradient = True tensor.stop_gradient = True
self.assertEqual(tensor.stop_gradient, True) self.assertEqual(tensor.stop_gradient, True)
def test_global_properties(self):
print("Test_global_properties")
self.assertFalse(core._in_eager_mode())
with _test_eager_guard():
self.assertTrue(core._in_eager_mode())
self.assertFalse(core._in_eager_mode())
def test_place_guard(self):
core._enable_eager_mode()
if core.is_compiled_with_cuda():
paddle.set_device("gpu:0")
with paddle.fluid.framework._dygraph_place_guard(core.CPUPlace()):
self.assertTrue(core.eager._get_expected_place().is_cpu_place())
else:
paddle.set_device("cpu")
with paddle.fluid.framework._dygraph_place_guard(core.CPUPlace()):
self.assertTrue(core.eager._get_expected_place().is_cpu_place())
core._disable_eager_mode()
if __name__ == "__main__": if __name__ == "__main__":
unittest.main() unittest.main()
...@@ -31,7 +31,7 @@ from ..fluid.framework import convert_np_dtype_to_dtype_, in_dygraph_mode, _varb ...@@ -31,7 +31,7 @@ from ..fluid.framework import convert_np_dtype_to_dtype_, in_dygraph_mode, _varb
from ..fluid.layers import linspace # noqa: F401 from ..fluid.layers import linspace # noqa: F401
import paddle import paddle
from paddle import _C_ops from paddle import _C_ops
from ..fluid.framework import in_eager_mode from ..fluid.framework import _in_eager_mode
__all__ = [] __all__ = []
...@@ -116,7 +116,7 @@ def to_tensor(data, dtype=None, place=None, stop_gradient=True): ...@@ -116,7 +116,7 @@ def to_tensor(data, dtype=None, place=None, stop_gradient=True):
) != _current_expected_place()._get_device_id(): ) != _current_expected_place()._get_device_id():
place = _current_expected_place() place = _current_expected_place()
if in_eager_mode(): if _in_eager_mode():
if dtype is None: if dtype is None:
dtype = paddle.get_default_dtype() dtype = paddle.get_default_dtype()
return core.eager.to_tensor(data, return core.eager.to_tensor(data,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册