From 689feb4b09c9d711ec9fdf2b9951fa16a2dbb270 Mon Sep 17 00:00:00 2001 From: jianghaicheng Date: Fri, 6 Aug 2021 10:18:52 +0800 Subject: [PATCH] ipu device manage (#20) * ipu device manage Co-authored-by: Han Co-authored-by: jianghaicheng --- paddle/fluid/framework/ipu/CMakeLists.txt | 3 +- paddle/fluid/framework/ipu/device.cc | 48 ++++++++++ paddle/fluid/framework/ipu/device.h | 44 ++++++++++ paddle/fluid/framework/ipu/ipu_backend.cc | 88 +++++++++++++++++-- paddle/fluid/framework/ipu/ipu_backend.h | 11 ++- paddle/fluid/framework/ipu/ipu_utils.cc | 18 +++- paddle/fluid/framework/ipu/ipu_utils.h | 9 +- .../ir/ipu/ipu_graph_builder_pass.cc | 2 +- .../ir/ipu/optimizer_extract_pass.cc | 2 +- paddle/fluid/operators/ipu_runtime_op.h | 8 +- paddle/fluid/platform/CMakeLists.txt | 4 +- paddle/fluid/platform/device_context.cc | 18 ++-- paddle/fluid/platform/device_context.h | 20 +++-- paddle/fluid/platform/ipu_info.cc | 40 ++------- paddle/fluid/platform/ipu_info.h | 2 - paddle/fluid/pybind/pybind.cc | 16 ++-- python/paddle/__init__.py | 1 + python/paddle/device.py | 2 +- .../tests/unittests/ipu/ipu_place_test.py | 70 +++++---------- .../tests/unittests/ipu/ipu_simple_add.py | 2 +- 20 files changed, 273 insertions(+), 135 deletions(-) create mode 100644 paddle/fluid/framework/ipu/device.cc create mode 100644 paddle/fluid/framework/ipu/device.h diff --git a/paddle/fluid/framework/ipu/CMakeLists.txt b/paddle/fluid/framework/ipu/CMakeLists.txt index 9cf9fcce54f67..e2abbc236784e 100644 --- a/paddle/fluid/framework/ipu/CMakeLists.txt +++ b/paddle/fluid/framework/ipu/CMakeLists.txt @@ -5,6 +5,7 @@ set(POPART_CANONICALIZATION_HANDLERS_SRC cc_library(popart_canonicalization_utils SRCS popart_canonicalization_utils.cc ${POPART_CANONICALIZATION_HANDLERS_SRC} DEPS framework_proto enforce) +cc_library(ipu_device SRCS device.cc DEPS enforce popart) cc_library(ipu_utils SRCS ipu_utils.cc DEPS memory framework_proto popart) cc_library(ipu_build_strategy SRCS ipu_build_strategy.cc DEPS popart graph framework_proto enforce) -cc_library(ipu_backend SRCS ipu_backend.cc DEPS popart graph framework_proto enforce ipu_utils ipu_build_strategy) +cc_library(ipu_backend SRCS ipu_backend.cc DEPS popart graph framework_proto enforce ipu_utils ipu_build_strategy ipu_device graph_helper) diff --git a/paddle/fluid/framework/ipu/device.cc b/paddle/fluid/framework/ipu/device.cc new file mode 100644 index 0000000000000..8d65d95b1cdf2 --- /dev/null +++ b/paddle/fluid/framework/ipu/device.cc @@ -0,0 +1,48 @@ +/* Copyright (c) 2021 PaddlePaddle Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. */ + +#include "paddle/fluid/framework/ipu/device.h" + +namespace paddle { +namespace framework { +namespace ipu { + +Device::Device(const popart::DeviceInfo& device_info) + : id_(device_info.getId()), is_attached_(device_info.isAttached()) { + popart::DeviceType popart_device_type = device_info.getType(); + switch (popart_device_type) { + case popart::DeviceType::IpuModel: + device_type_ = DeviceType::IpuModel; + break; + case popart::DeviceType::Cpu: + device_type_ = DeviceType::Cpu; + break; + case popart::DeviceType::Ipu: + device_type_ = DeviceType::Ipu; + break; + case popart::DeviceType::OfflineIpu: + device_type_ = DeviceType::OfflineIpu; + break; + case popart::DeviceType::Sim: + device_type_ = DeviceType::Sim; + break; + default: + PADDLE_THROW(platform::errors::InvalidArgument( + "popart::DeviceType:Unsupported type %d", popart_device_type)); + } +} + +} // namespace ipu +} // namespace framework +} // namespace paddle diff --git a/paddle/fluid/framework/ipu/device.h b/paddle/fluid/framework/ipu/device.h new file mode 100644 index 0000000000000..0cf2a663ee399 --- /dev/null +++ b/paddle/fluid/framework/ipu/device.h @@ -0,0 +1,44 @@ +/* Copyright (c) 2021 PaddlePaddle Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. */ + +#pragma once + +#include +#include "paddle/fluid/platform/enforce.h" + +namespace paddle { +namespace framework { +namespace ipu { + +enum class DeviceType { IpuModel = 0, Cpu, Ipu, OfflineIpu, Sim }; + +class Device { + public: + Device() {} + explicit Device(const popart::DeviceInfo& device_info); + + int getId() const { return id_; } + bool isAttached() const { return is_attached_; } + DeviceType getType() const { return device_type_; } + + private: + int id_; + bool is_attached_; + DeviceType device_type_; + /* TODO:: Add more elements in the future */ +}; + +} // namespace ipu +} // namespace framework +} // namespace paddle diff --git a/paddle/fluid/framework/ipu/ipu_backend.cc b/paddle/fluid/framework/ipu/ipu_backend.cc index d6b63bcbe452b..ee8719110fae0 100644 --- a/paddle/fluid/framework/ipu/ipu_backend.cc +++ b/paddle/fluid/framework/ipu/ipu_backend.cc @@ -28,17 +28,16 @@ limitations under the License. */ #include #include -#include "paddle/fluid/framework/feed_fetch_type.h" #include "paddle/fluid/framework/framework.pb.h" #include "paddle/fluid/framework/ipu/ipu_utils.h" #include "paddle/fluid/framework/ir/graph.h" #include "paddle/fluid/framework/ir/graph_helper.h" #include "paddle/fluid/framework/ir/node.h" -#include "paddle/fluid/framework/lod_tensor.h" #include "paddle/fluid/platform/enforce.h" namespace paddle { namespace framework { +namespace ipu { std::shared_ptr IpuBackend::instance_ = nullptr; @@ -127,11 +126,10 @@ void IpuBackend::Prepare() { } auto dataFlow = popart::DataFlow(1, anchor_ids); - std::map deviceOpts{{"numIPUs", "1"}}; - auto ipuModelDevice = - popart::DeviceManager::createDeviceManager().createIpuModelDevice( - deviceOpts); - // or acquireAvailableDevice(); + PADDLE_ENFORCE_NOT_NULL( + curr_device_, + platform::errors::Unavailable("IPU device isn't attached, please call " + "IpuBackend::AttachDevice(id) first.")); if (ipu_build_strategy_ != nullptr && ipu_build_strategy_->is_training_) { VLOG(1) << "Creating TrainingSession from Onnx Model..."; @@ -142,11 +140,11 @@ void IpuBackend::Prepare() { paddle::platform::errors::InvalidArgument( "loss_id = %s doesn't exist in popart graph.", optimizer_.loss_)); session_ = popart::TrainingSession::createFromOnnxModel( - proto, dataFlow, it->second, *popart_optimizer, ipuModelDevice); + proto, dataFlow, it->second, *popart_optimizer, curr_device_); } else { VLOG(1) << "Creating InferenceSession from Onnx Model..."; session_ = popart::InferenceSession::createFromOnnxModel(proto, dataFlow, - ipuModelDevice); + curr_device_); } VLOG(1) << "Creating session from Onnx Model...done"; @@ -308,5 +306,77 @@ void IpuBackend::LowerBody(const ir::Graph* graph) { } } +size_t IpuBackend::GetNumDevices() { + // IpuModel + bool ipu_model = GetBoolEnv("POPLAR_IPUMODEL"); + if (ipu_model) return 1; + // Real dev + size_t num_devices = + popart::DeviceManager::createDeviceManager().enumerateDevices().size(); + PADDLE_ENFORCE_GT( + num_devices, 0, + platform::errors::Unavailable( + "Do not found any IPU devices, please make " + "sure Poplar sdk is enabled or enable ENV \"POPLAR_IPUMODEL=1\"")); + return num_devices; +} + +std::vector IpuBackend::GetDeviceIds() { + bool ipu_model = GetBoolEnv("POPLAR_IPUMODEL"); + if (ipu_model) { + return {0}; + } + std::vector device_ids; + auto devices = + popart::DeviceManager::createDeviceManager().enumerateDevices(); + PADDLE_ENFORCE_GT( + devices.size(), 0, + platform::errors::Unavailable("Do not found any IPU devices, please make " + "sure Poplar sdk is enabled.")); + + for (auto device : devices) { + device_ids.push_back(device->getId()); + } + + return device_ids; +} + +Device IpuBackend::GetDevice(int id) { + bool ipu_model = GetBoolEnv("POPLAR_IPUMODEL"); + if (ipu_model) { + std::map deviceOpts{{"numIPUs", "1 "}}; + curr_device_ = + popart::DeviceManager::createDeviceManager().createIpuModelDevice( + deviceOpts); + Device device(*curr_device_.get()); + return device; + } + size_t num_devices = GetNumDevices(); + if (id < 0 || id >= num_devices) { + PADDLE_THROW(platform::errors::InvalidArgument( + "device id %d is invalid, number devices is %d", id, num_devices)); + } + std::shared_ptr popart_device_info = + popart::DeviceManager::createDeviceManager().getDevice( + popart::SyncPattern::Full, id); + Device device(*popart_device_info.get()); + return device; +} + +void IpuBackend::AttachDevice(int id) { + bool ipu_model = GetBoolEnv("POPLAR_IPUMODEL"); + if (ipu_model) { + return; + } + curr_device_ = + popart::DeviceManager::createDeviceManager().acquireDeviceById(id); + PADDLE_ENFORCE_NOT_NULL( + curr_device_, + platform::errors::Unavailable("Can't attach IPU device id = %d.", id)); +} + +bool IpuBackend::DeviceIsAttached() { return curr_device_ != nullptr; } + +} // namespace ipu } // namespace framework } // namespace paddle diff --git a/paddle/fluid/framework/ipu/ipu_backend.h b/paddle/fluid/framework/ipu/ipu_backend.h index 3cdf909b9ad24..3a128f3c3925d 100644 --- a/paddle/fluid/framework/ipu/ipu_backend.h +++ b/paddle/fluid/framework/ipu/ipu_backend.h @@ -32,17 +32,17 @@ limitations under the License. */ #include "paddle/fluid/framework/feed_fetch_type.h" #include "paddle/fluid/framework/ipu/ipu_build_strategy.h" +#include "paddle/fluid/framework/ipu/device.h" #include "paddle/fluid/framework/ir/graph.h" -#include "paddle/fluid/framework/lod_tensor.h" #include "paddle/fluid/framework/scope.h" #include "paddle/fluid/framework/tensor.h" #include "paddle/fluid/platform/enforce.h" namespace paddle { namespace framework { +namespace ipu { using ipu::IpuBuildStrategy; - struct Optimizer { std::string type_; std::string loss_; @@ -89,6 +89,11 @@ class IpuBackend { void SetIpuBuildStrategy(const IpuBuildStrategy &strategy) { ipu_build_strategy_ = &strategy; } + size_t GetNumDevices(); + std::vector GetDeviceIds(); + Device GetDevice(int id); + void AttachDevice(int id); + bool DeviceIsAttached(); static std::shared_ptr GetInstance() { if (NULL == instance_) { @@ -115,9 +120,11 @@ class IpuBackend { std::unique_ptr builder_; std::unique_ptr session_; + std::shared_ptr curr_device_; static std::shared_ptr instance_; }; +} // namespace ipu } // namespace framework } // namespace paddle diff --git a/paddle/fluid/framework/ipu/ipu_utils.cc b/paddle/fluid/framework/ipu/ipu_utils.cc index 760e860184776..029adb690beff 100644 --- a/paddle/fluid/framework/ipu/ipu_utils.cc +++ b/paddle/fluid/framework/ipu/ipu_utils.cc @@ -16,6 +16,7 @@ limitations under the License. */ namespace paddle { namespace framework { +namespace ipu { popart::DataType VarType2PopartType(proto::VarType::Type type) { switch (type) { @@ -46,6 +47,19 @@ popart::DataType VarType2PopartType(proto::VarType::Type type) { "Unsupported Paddle var type.")); } } - +// count num should > 0 +bool GetBoolEnv(std::string str) { + char *str_val = getenv(str.c_str()); + if (str_val == NULL) { + return false; + } else { + bool val = false; + if (strcmp(str_val, "1") == 0 || strcmp(str_val, "true") == 0 || + strcmp(str_val, "True") == 0 || strcmp(str_val, "TRUE") == 0) + val = true; + return val; + } +} +} // namespace ipu } // namespace framework -} // namespace paddle \ No newline at end of file +} // namespace paddle diff --git a/paddle/fluid/framework/ipu/ipu_utils.h b/paddle/fluid/framework/ipu/ipu_utils.h index 12da7bb5487b7..c8f4785763cac 100644 --- a/paddle/fluid/framework/ipu/ipu_utils.h +++ b/paddle/fluid/framework/ipu/ipu_utils.h @@ -24,11 +24,13 @@ limitations under the License. */ namespace paddle { namespace framework { +namespace ipu { popart::DataType VarType2PopartType(proto::VarType::Type type); +bool GetBoolEnv(std::string str); template -std::unique_ptr> Tensor2IArray(Tensor &tensor) { +std::unique_ptr> Tensor2IArray(const Tensor &tensor) { auto dtype = VarType2PopartType(tensor.type()); auto shape = std::vector(); for (size_t i = 0; i < tensor.dims().size(); ++i) { @@ -42,7 +44,7 @@ std::unique_ptr> Tensor2IArray(Tensor &tensor) { template std::unique_ptr> LoDTensor2IArray( - LoDTensor &lod_tensor) { + LoDTensor const &lod_tensor) { if (lod_tensor.lod().size() == 0) { return Tensor2IArray(lod_tensor); } else { @@ -51,5 +53,6 @@ std::unique_ptr> LoDTensor2IArray( } } +} // namespace ipu } // namespace framework -} // namespace paddle \ No newline at end of file +} // namespace paddle diff --git a/paddle/fluid/framework/ir/ipu/ipu_graph_builder_pass.cc b/paddle/fluid/framework/ir/ipu/ipu_graph_builder_pass.cc index ca98904eac445..6061a1b4a03c4 100644 --- a/paddle/fluid/framework/ir/ipu/ipu_graph_builder_pass.cc +++ b/paddle/fluid/framework/ir/ipu/ipu_graph_builder_pass.cc @@ -49,7 +49,7 @@ void IpuGraphBuilderPass::ApplyImpl(ir::Graph* graph) const { std::vector fetch_list; fetch_list = Get>("fetch_list"); - std::shared_ptr ipu_backend = IpuBackend::GetInstance(); + std::shared_ptr ipu_backend = ipu::IpuBackend::GetInstance(); ipu_backend->Compile(graph, feed_list, fetch_list); diff --git a/paddle/fluid/framework/ir/ipu/optimizer_extract_pass.cc b/paddle/fluid/framework/ir/ipu/optimizer_extract_pass.cc index b06b411dc3fe6..6090ff9797b40 100644 --- a/paddle/fluid/framework/ir/ipu/optimizer_extract_pass.cc +++ b/paddle/fluid/framework/ir/ipu/optimizer_extract_pass.cc @@ -29,7 +29,7 @@ void IpuOptimizerExtractPass::ApplyImpl(ir::Graph* graph) const { VLOG(10) << "Raw Graph: "; VLOG(10) << DebugString(graph); - auto ipu_backend = paddle::framework::IpuBackend::GetInstance(); + auto ipu_backend = paddle::framework::ipu::IpuBackend::GetInstance(); for (auto* node : graph->Nodes()) { if (node->IsOp() && node->Op()) { diff --git a/paddle/fluid/operators/ipu_runtime_op.h b/paddle/fluid/operators/ipu_runtime_op.h index 08718ae315601..6721141acddf5 100644 --- a/paddle/fluid/operators/ipu_runtime_op.h +++ b/paddle/fluid/operators/ipu_runtime_op.h @@ -30,7 +30,13 @@ class IpuRuntimeKernel : public framework::OpKernel { public: void Compute(const framework::ExecutionContext& ctx) const override { #ifdef PADDLE_WITH_IPU - auto ipu_backend = paddle::framework::IpuBackend::GetInstance(); + auto ipu_backend = framework::ipu::IpuBackend::GetInstance(); + if (!ipu_backend->DeviceIsAttached()) { + const platform::IPUDeviceContext& ipu_ctx = + reinterpret_cast( + ctx.device_context()); + ipu_backend->AttachDevice(ipu_ctx.DeviceId()); + } VLOG(4) << "IpuRuntime Kernel, begin to run graph"; auto inputs = ctx.MultiInput("FeedList"); auto outputs = ctx.MultiOutput("FetchList"); diff --git a/paddle/fluid/platform/CMakeLists.txt b/paddle/fluid/platform/CMakeLists.txt index cab37ce28301a..fdc694b79f8ab 100644 --- a/paddle/fluid/platform/CMakeLists.txt +++ b/paddle/fluid/platform/CMakeLists.txt @@ -62,8 +62,8 @@ IF(WITH_GPU) nv_library(gpu_info SRCS gpu_info.cc DEPS gflags glog enforce monitor dynload_cuda) ENDIF() IF(WITH_IPU) - set(IPU_CTX_DEPS popart) - cc_library(ipu_info SRCS ipu_info.cc DEPS popart) + set(IPU_CTX_DEPS ipu_backend) + cc_library(ipu_info SRCS ipu_info.cc DEPS ipu_backend) ELSE() set(IPU_CTX_DEPS) ENDIF(WITH_IPU) diff --git a/paddle/fluid/platform/device_context.cc b/paddle/fluid/platform/device_context.cc index 0428fdffef1f5..8eb733f050e52 100644 --- a/paddle/fluid/platform/device_context.cc +++ b/paddle/fluid/platform/device_context.cc @@ -16,6 +16,9 @@ limitations under the License. */ #include "paddle/fluid/memory/allocation/cuda_device_context_allocator.h" #include "paddle/fluid/platform/cuda_device_guard.h" #endif +#ifdef PADDLE_WITH_IPU +#include "paddle/fluid/framework/ipu/ipu_backend.h" +#endif #include "glog/logging.h" #include "paddle/fluid/platform/profiler.h" @@ -181,20 +184,11 @@ Eigen::DefaultDevice* CPUDeviceContext::eigen_device() const { Place CPUDeviceContext::GetPlace() const { return place_; } #ifdef PADDLE_WITH_IPU -IPUDeviceContext::IPUDeviceContext() { - std::map deviceOpts{{"numIPUs", "1"}}; - gc_devices_ = - popart::DeviceManager::createDeviceManager().createIpuModelDevice( - deviceOpts); -} - // TODO(Cheng) get current device IPUDeviceContext::IPUDeviceContext(IPUPlace place) : place_(place) { - //...... - // std::map deviceOpts{{"numIPUs", "1"}}; - // gc_devices_ = - // popart::DeviceManager::createDeviceManager().createIpuModelDevice( - // deviceOpts); + int id = place.GetDeviceId(); + std::shared_ptr ipu_backend = framework::ipu::IpuBackend::GetInstance(); + device_ = ipu_backend->GetDevice(id); } Place IPUDeviceContext::GetPlace() const { return place_; } diff --git a/paddle/fluid/platform/device_context.h b/paddle/fluid/platform/device_context.h index d17a53146abc7..7261b8df30705 100644 --- a/paddle/fluid/platform/device_context.h +++ b/paddle/fluid/platform/device_context.h @@ -60,11 +60,10 @@ limitations under the License. */ #ifdef PADDLE_WITH_ASCEND_CL #include "paddle/fluid/platform/stream/npu_stream.h" #endif -#include "unsupported/Eigen/CXX11/Tensor" - #ifdef PADDLE_WITH_IPU -#include +#include "paddle/fluid/framework/ipu/device.h" #endif +#include "unsupported/Eigen/CXX11/Tensor" namespace Eigen { struct DefaultDevice; @@ -143,18 +142,21 @@ struct DefaultDeviceContextType { // Graphcore IPU #ifdef PADDLE_WITH_IPU class IPUDeviceContext : public DeviceContext { -public: - IPUDeviceContext(); + public: + IPUDeviceContext() = delete; explicit IPUDeviceContext(IPUPlace place); virtual ~IPUDeviceContext(); - Eigen::DefaultDevice* eigen_device() const{ return nullptr; } + Eigen::DefaultDevice* eigen_device() const { return nullptr; } Place GetPlace() const override; - /*! \brief Wait for all operations completion in the stream. */ + /*! \brief Wait for all operations completion in the stream. */ void Wait() const override; + int DeviceId() const { + return device_.getId(); + } -private: + private: IPUPlace place_; - std::shared_ptr gc_devices_; + framework::ipu::Device device_; }; template <> struct DefaultDeviceContextType { diff --git a/paddle/fluid/platform/ipu_info.cc b/paddle/fluid/platform/ipu_info.cc index c5bcd888a2921..bbcec5ba178a4 100644 --- a/paddle/fluid/platform/ipu_info.cc +++ b/paddle/fluid/platform/ipu_info.cc @@ -10,51 +10,21 @@ See the License for the specific language governing permissions and limitations under the License. */ #include "paddle/fluid/platform/ipu_info.h" +#include "paddle/fluid/framework/ipu/ipu_backend.h" namespace paddle { namespace platform { -std::vector> GetIPUDevices() { - char *p; - bool use_cpu_model = false; - if ((p = getenv("TF_POPLAR_FLAGS"))) { - if (strcmp(p, "--use_cpu_model") == 0) { - use_cpu_model = true; - } - } - std::vector> devices; - if (use_cpu_model) { - auto dm = popart::DeviceManager::createDeviceManager(); - devices = dm.enumerateDevices(); - } else { - std::map deviceOpts{{"numIPUs", "1"}}; - auto ipuModelDevice = - popart::DeviceManager::createDeviceManager().createIpuModelDevice( - deviceOpts); - devices.push_back(ipuModelDevice); - } - return devices; -} //! Get a list of device ids from environment variable or use all. std::vector GetSelectedIPUDevices() { - std::vector devices_ids; - auto devices = GetIPUDevices(); - for (auto dev : devices) { - devices_ids.push_back(dev->getId()); - } - return devices_ids; + std::shared_ptr ipu_backend = framework::ipu::IpuBackend::GetInstance(); + return ipu_backend->GetDeviceIds(); } //! Get the total number of IPU devices in system. int GetIPUDeviceCount() { - auto devices = GetIPUDevices(); - if (devices.empty()) { - LOG(ERROR) - << "\nNo IPU detected in the system: are you sure the gc-driver is " - "enabled ?"; - return 0; - } - return devices.size(); + std::shared_ptr ipu_backend = framework::ipu::IpuBackend::GetInstance(); + return ipu_backend->GetNumDevices(); } } // namespace platform } // namespace paddle diff --git a/paddle/fluid/platform/ipu_info.h b/paddle/fluid/platform/ipu_info.h index 1b1e70a174e58..3d032eeb4bfc1 100644 --- a/paddle/fluid/platform/ipu_info.h +++ b/paddle/fluid/platform/ipu_info.h @@ -12,13 +12,11 @@ limitations under the License. */ #ifdef PADDLE_WITH_IPU #include -#include #include #include "glog/logging.h" namespace paddle { namespace platform { -std::vector> GetIPUDevices(); std::vector GetSelectedIPUDevices(); int GetIPUDeviceCount(); } // namespace platform diff --git a/paddle/fluid/pybind/pybind.cc b/paddle/fluid/pybind/pybind.cc index e6c3c0ab78c2a..fbfb1808bb5d7 100644 --- a/paddle/fluid/pybind/pybind.cc +++ b/paddle/fluid/pybind/pybind.cc @@ -2331,6 +2331,10 @@ All parameter, weight, gradient are variables in Paddle. }); #endif +#ifdef PADDLE_WITH_IPU + m.def("get_ipu_device_count", platform::GetIPUDeviceCount); +#endif + py::enum_(m, "TracerOption", py::arithmetic()) .value("kDefault", platform::TracerOption::kDefault) .value("kOpDetail", platform::TracerOption::kOpDetail) @@ -3204,19 +3208,19 @@ All parameter, weight, gradient are variables in Paddle. .def("device_count", &ParallelExecutor::DeviceCount); #ifdef PADDLE_WITH_IPU - py::class_>( + py::class_>( m, "IpuBackend") - .def(py::init(&IpuBackend::GetInstance)) - .def("set_scope", &IpuBackend::SetScope) - .def("set_ipu_build_strategy", &IpuBackend::SetIpuBuildStrategy); + .def(py::init(&ipu::IpuBackend::GetInstance)) + .def("set_scope", &ipu::IpuBackend::SetScope) + .def("set_ipu_build_strategy", &ipu::IpuBackend::SetIpuBuildStrategy); // TODO(xiaobingw): maybe refactor at future py::class_(m, "IpuBuildStrategy") .def(py::init()) .def_property( "is_training", - [](const IpuBuildStrategy &self) { return self.is_training_; }, - [](IpuBuildStrategy &self, bool is_training) { + [](const ipu::IpuBuildStrategy &self) { return self.is_training_; }, + [](ipu::IpuBuildStrategy &self, bool is_training) { self.is_training_ = is_training; }); #endif diff --git a/python/paddle/__init__.py b/python/paddle/__init__.py index 8801ca89768f5..ed280b0a7a320 100755 --- a/python/paddle/__init__.py +++ b/python/paddle/__init__.py @@ -262,6 +262,7 @@ from .fluid.framework import is_compiled_with_rocm # noqa: F401 from .device import is_compiled_with_xpu # noqa: F401 from .device import is_compiled_with_npu # noqa: F401 +from .device import is_compiled_with_ipu # noqa: F401 from .device import XPUPlace # noqa: F401 from .fluid.dygraph.base import enable_dygraph as disable_static # noqa: F401 diff --git a/python/paddle/device.py b/python/paddle/device.py index 6384b03bef7cd..bcc08c5cd8130 100644 --- a/python/paddle/device.py +++ b/python/paddle/device.py @@ -68,7 +68,7 @@ def is_compiled_with_ipu(): .. code-block:: python import paddle - support_npu = paddle.is_compiled_with_ipu() + support_ipu = paddle.is_compiled_with_ipu() """ return core.is_compiled_with_ipu() diff --git a/python/paddle/fluid/tests/unittests/ipu/ipu_place_test.py b/python/paddle/fluid/tests/unittests/ipu/ipu_place_test.py index 95732a199af84..7bf0a35fa9eef 100644 --- a/python/paddle/fluid/tests/unittests/ipu/ipu_place_test.py +++ b/python/paddle/fluid/tests/unittests/ipu/ipu_place_test.py @@ -1,10 +1,10 @@ -# Copyright (c) 2018 PaddlePaddle Authors. All Rights Reserved. +# Copyright (c) 2021 PaddlePaddle Authors. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # -# http://www.apache.org/licenses/LICENSE-2.0 +# http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, @@ -12,53 +12,29 @@ # See the License for the specific language governing permissions and # limitations under the License. -"""simple test for ipu_place. +from __future__ import print_function -Args: - place (IPUPlace The place where the op runs. -Returns: - None. -""" - -import paddle import numpy as np -import os -import paddle.fluid.layers as layers -import faulthandler; - -faulthandler.enable() -os.environ['TF_POPLAR_FLAGS']="--use_cpu_model”" +import unittest +import sys +sys.path.append("..") +import paddle +import paddle.fluid as fluid -# 飞桨2.X默认模式为动态图,需要开启静态图模式 paddle.enable_static() -# 编译期:调用飞桨的API编写Python程序,如下述代码中定义了一个含conv2d的网络,并使用Adam优化器优化参数。 -a = paddle.static.data(name='a', shape=[1], dtype='float32') -b = paddle.static.data(name='b', shape=[1], dtype='float32') -c = a + b -# paddle.assign_value(a,b,c) -# 运行期:先运行一次startup program初始化网络参数,然后调用飞桨的Executor和CompiledProgram API运行网络。 -place = paddle.IPUPlace(0) # 使用何种设备运行网络,IPUPlace表示使用IPU运行,IUDAPlace表示使用IPU运行 - -# x = paddle.ones([2,2]) -# y = paddle.ones([2,2]) -# input = paddle.ones([2,2]) -# out = paddle.gctest( input=input, x=x, y=y, beta=0.5, alpha=5.0 ) -# print("output values is ",out,x) - -# d = paddle.gctest(input =a,x=a, y=b) - -executor = paddle.static.Executor(place) # 创建执行器 -# executor.run(paddle.static.default_startup_program()) # 运行startup program进行参数初始化 - -prog = paddle.static.default_main_program() -print(prog._to_readable_code()) - -# 再使用CompiledProgram编译网络,准备执行。 -# compiled_program = paddle.static.CompiledProgram(paddle.static.default_main_program()) - -result = executor.run(prog, feed={'a': np.array([100], dtype=np.float32), 'b': np.array([200], dtype=np.float32)}, fetch_list=[c]) -print("result = {}".format(result)) - -# 关闭静态图模式 -paddle.disable_static() +@unittest.skipIf(not paddle.is_compiled_with_ipu(), + "core is not compiled with IPU") +class TestIpuPlace(unittest.TestCase): + def test_ipu_place(self): + num_devices = fluid.core.get_ipu_device_count() + self.assertGreater(num_devices, 0) + + for i in range(num_devices): + place = paddle.IPUPlace(i) + p = fluid.core.Place() + p.set_place(place) + self.assertTrue(p.is_ipu_place()) + +if __name__ == '__main__': + unittest.main() diff --git a/python/paddle/fluid/tests/unittests/ipu/ipu_simple_add.py b/python/paddle/fluid/tests/unittests/ipu/ipu_simple_add.py index b8e1adad876f9..032005bc1d824 100644 --- a/python/paddle/fluid/tests/unittests/ipu/ipu_simple_add.py +++ b/python/paddle/fluid/tests/unittests/ipu/ipu_simple_add.py @@ -24,7 +24,7 @@ b = paddle.static.data(name='b', shape=[1], dtype='float32') c = a + b -place = paddle.CPUPlace() +place = paddle.IPUPlace(0) executor = paddle.static.Executor(place) print("------------------------")