diff --git a/paddle/framework/CMakeLists.txt b/paddle/framework/CMakeLists.txt index 984fc62aa33a7edbe355442c86f6759ec78165bf..506d0f9833e58b003a7f60173aaa23a1fed0206d 100644 --- a/paddle/framework/CMakeLists.txt +++ b/paddle/framework/CMakeLists.txt @@ -44,5 +44,5 @@ add_custom_command(TARGET framework_py_proto POST_BUILD cc_library(backward SRCS backward.cc DEPS net_op) cc_test(backward_test SRCS backward_test.cc DEPS backward recurrent_op device_context) -cc_library(executor SRCS executor.cc DEPS op_registry device_context scope framework_proto) +cc_library(executor SRCS executor.cc DEPS op_registry device scope framework_proto) cc_test(executor_test SRCS executor_test.cc DEPS executor) diff --git a/paddle/framework/executor.cc b/paddle/framework/executor.cc index ebe3259bc06ee309477c2877eaf1da19875c4a14..57e177bb0af5250bdab6a8d092a80ea7f0adc890 100644 --- a/paddle/framework/executor.cc +++ b/paddle/framework/executor.cc @@ -15,162 +15,31 @@ limitations under the License. */ #include "paddle/framework/executor.h" #include #include "paddle/framework/op_registry.h" -#include "paddle/framework/operator.h" #include "paddle/framework/scope.h" -#include "paddle/platform/device_context.h" namespace paddle { namespace framework { -class LinearListView; -class GraphView; - -// Immutable view of a ProgramDesc organized for efficient execution. -class ProgramDescView { - public: - virtual ~ProgramDescView() {} - virtual void Initialize(const ProgramDesc*) = 0; - static ProgramDescView* Create(bool is_linear); -}; - -class LinearListView : public ProgramDescView { - public: - void Initialize(const ProgramDesc*) override; - - private: - std::vector> ops_; -}; - -class GraphView : public ProgramDescView { - public: - void Initialize(const ProgramDesc*) override; -}; - -ProgramDescView* ProgramDescView::Create(bool is_linear) { - if (is_linear) { - return new LinearListView(); - } else { - return new GraphView(); - } -} - -void LinearListView::Initialize(const ProgramDesc* pdesc) { - // get a LinearView of ProgramDesc - for (auto& block_desc : pdesc->blocks()) { - for (auto& op_desc : block_desc.ops()) { - ops_.emplace_back(OpRegistry::CreateOp(op_desc)); - } +Executor::Executor(const std::vector& places) { + devices_.resize(places.size()); + for (size_t i = 0; i < places.size(); i++) { + devices_[i] = platform::GetDevice(places[i]); } } -void GraphView::Initialize(const ProgramDesc* pdesc) { - // get a GraphView of ProgramDesc -} - -struct Device { - platform::CPUDeviceContext* cpu_device_context; -#ifndef PADDLE_ONLY_CPU - platform::CUDADeviceContext* cuda_device_context; -#endif - -#ifndef PADDLE_ONLY_CPU - Device(platform::CPUDeviceContext* cpu, platform::CUDADeviceContext* gpu) - : cpu_device_context(cpu), cuda_device_context(gpu) {} -#else - explicit Device(platform::CPUDeviceContext* cpu) : cpu_device_context(cpu) {} -#endif -}; - -class ExecutorImpl : public Executor { - public: - ExecutorImpl(Scope* scope, const Device* device, const ProgramDesc* pdesc, - bool is_linear) - : scope_(scope), - device_(device), - program_desc_(pdesc), - view_(ProgramDescView::Create(is_linear)) {} - - virtual ~ExecutorImpl() { - if (view_) delete view_; - } - - void Run() override; - - void Initialize(); - - private: - Scope* scope_; - const Device* device_; - const ProgramDesc* program_desc_; - ProgramDescView* view_; -}; - -template -std::unique_ptr make_unique(Args&&... args) { - return std::unique_ptr(new T(std::forward(args)...)); -} - -platform::CPUDeviceContext* GetCPUDeviceContext( - const platform::CPUPlace& place) { - static std::unique_ptr g_cpu_device_context = - make_unique(place); - return g_cpu_device_context.get(); -} - -#ifndef PADDLE_ONLY_CPU -platform::CUDADeviceContext* GetCUDADeviceContext( - const platform::GPUPlace& place) { - static std::unique_ptr g_cuda_device_context = - make_unique(place); - return g_cuda_device_context.get(); -} -#endif - -Device* GetDevice(const platform::Place& place) { - platform::CPUPlace cpu_place; -#ifndef PADDLE_ONLY_CPU - if (platform::is_gpu_place(place)) { - platform::GPUPlace gpu_place = boost::get(place); - static std::unique_ptr g_device = make_unique( - GetCPUDeviceContext(cpu_place), GetCUDADeviceContext(gpu_place)); - return g_device.get(); - } else { - static std::unique_ptr g_device = - make_unique(GetCPUDeviceContext(cpu_place), nullptr); - return g_device.get(); - } -#else - static std::unique_ptr g_device = - make_unique(GetCPUDeviceContext(cpu_place)); - return g_device.get(); -#endif -} - -framework::Scope* GetScope() { - static std::unique_ptr g_scope = - make_unique(); - return g_scope.get(); -} - -Executor* NewLocalExecutor(const platform::Place& place, - const ProgramDesc& pdesc, bool is_linear) { - return new ExecutorImpl(GetScope(), GetDevice(place), &pdesc, is_linear); -} - -void ExecutorImpl::Run() { +void Executor::Run(const ProgramDesc& pdesc, Scope* scope, + std::vector* outputs) { // operators running - scope_->NewVar(); - device_->cpu_device_context->Wait(); + Scope& local_scope = scope->NewScope(); + local_scope.NewVar(); + for (auto device : devices_) { + device->cpu_device_context->Wait(); #ifndef PADDLE_ONLY_CPU - if (device_->cuda_device_context) { - device_->cuda_device_context->Wait(); - } + if (device->cuda_device_context) { + device->cuda_device_context->Wait(); + } #endif -} - -void ExecutorImpl::Initialize() { - // Initialize the ProgramDescView - view_->Initialize(program_desc_); + } } } // namespace framework diff --git a/paddle/framework/executor.h b/paddle/framework/executor.h index 25ef2d4d48f0f1fdbc00cfe7528a27f625cc12ee..5d6d7f37a6a66affa92cfe1d1bc89327d365107b 100644 --- a/paddle/framework/executor.h +++ b/paddle/framework/executor.h @@ -15,18 +15,22 @@ limitations under the License. */ #pragma once #include "paddle/framework/framework.pb.h" -#include "paddle/platform/place.h" +#include "paddle/framework/scope.h" +#include "paddle/framework/tensor.h" +#include "paddle/platform/device.h" namespace paddle { namespace framework { class Executor { public: - virtual ~Executor() {} - virtual void Run() = 0; -}; + explicit Executor(const std::vector& places); + ~Executor() {} + void Run(const ProgramDesc&, Scope*, std::vector*); -Executor* NewLocalExecutor(const platform::Place&, const ProgramDesc&, bool); + private: + std::vector devices_; +}; } // namespace framework } // namespace paddle diff --git a/paddle/framework/executor_test.cc b/paddle/framework/executor_test.cc index 6f8ca3876842c68515e22bb24006674ae9ae4725..51d2dfc1c326ff6dc2c2666e83fc006e5097edfc 100644 --- a/paddle/framework/executor_test.cc +++ b/paddle/framework/executor_test.cc @@ -19,9 +19,15 @@ using namespace paddle::platform; using namespace paddle::framework; TEST(Executor, Init) { + CPUPlace cpu_place1, cpu_place2; + std::vector places; + places.push_back(cpu_place1); + places.push_back(cpu_place2); + Executor* executor = new Executor(places); + ProgramDesc pdesc; - CPUPlace cpu_place; - Executor* executor = NewLocalExecutor(cpu_place, pdesc, true); - executor->Run(); + Scope s; + std::vector* outputs{nullptr}; + executor->Run(pdesc, &s, outputs); delete executor; } \ No newline at end of file diff --git a/paddle/platform/CMakeLists.txt b/paddle/platform/CMakeLists.txt index daf519b91d623d4369774dc4e37dcb7b1733666b..b581937393520ec6a47991c16c093db65a942162 100644 --- a/paddle/platform/CMakeLists.txt +++ b/paddle/platform/CMakeLists.txt @@ -23,5 +23,7 @@ cc_library(device_context SRCS device_context.cc DEPS memory buddy_allocator system_allocator memory_block meta_data meta_cache place eigen3 ${GPU_CTX_DEPS}) nv_test(device_context_test SRCS device_context_test.cc DEPS device_context gpu_info) +cc_library(device SRCS device.cc DEPS device_context) + nv_test(cudnn_helper_test SRCS cudnn_helper_test.cc DEPS dynload_cuda) nv_test(transform_test SRCS transform_test.cu DEPS paddle_memory place device_context) diff --git a/paddle/platform/device.cc b/paddle/platform/device.cc new file mode 100644 index 0000000000000000000000000000000000000000..7acd87c8c3db8f774de72251b028be10ef34770c --- /dev/null +++ b/paddle/platform/device.cc @@ -0,0 +1,59 @@ +/* Copyright (c) 2016 PaddlePaddle Authors. All Rights Reserve. + +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/platform/device.h" + +namespace paddle { +namespace platform { + +template +std::unique_ptr make_unique(Args&&... args) { + return std::unique_ptr(new T(std::forward(args)...)); +} + +CPUDeviceContext* GetCPUDeviceContext(const CPUPlace& place) { + static std::unique_ptr g_cpu_device_context = + make_unique(place); + return g_cpu_device_context.get(); +} + +#ifndef PADDLE_ONLY_CPU +CUDADeviceContext* GetCUDADeviceContext(const GPUPlace& place) { + static std::unique_ptr g_cuda_device_context = + make_unique(place); + return g_cuda_device_context.get(); +} +#endif + +Device* GetDevice(const Place& place) { + CPUPlace cpu_place; +#ifndef PADDLE_ONLY_CPU + if (is_gpu_place(place)) { + GPUPlace gpu_place = boost::get(place); + static std::unique_ptr g_device = make_unique( + GetCPUDeviceContext(cpu_place), GetCUDADeviceContext(gpu_place)); + return g_device.get(); + } else { + static std::unique_ptr g_device = + make_unique(GetCPUDeviceContext(cpu_place), nullptr); + return g_device.get(); + } +#else + static std::unique_ptr g_device = + make_unique(GetCPUDeviceContext(cpu_place)); + return g_device.get(); +#endif +} +} // namespace platform +} // namespace paddle diff --git a/paddle/platform/device.h b/paddle/platform/device.h new file mode 100644 index 0000000000000000000000000000000000000000..b1bb8073cf15dccbcb7ef20a9b412385ad666a4d --- /dev/null +++ b/paddle/platform/device.h @@ -0,0 +1,45 @@ +/* Copyright (c) 2016 PaddlePaddle Authors. All Rights Reserve. + +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 "paddle/platform/device_context.h" +#include "paddle/platform/place.h" + +namespace paddle { +namespace platform { + +struct Device { + CPUDeviceContext* cpu_device_context; +#ifndef PADDLE_ONLY_CPU + CUDADeviceContext* cuda_device_context; +#endif + +#ifndef PADDLE_ONLY_CPU + Device(CPUDeviceContext* cpu, CUDADeviceContext* gpu) + : cpu_device_context(cpu), cuda_device_context(gpu) {} +#else + explicit Device(CPUDeviceContext* cpu) : cpu_device_context(cpu) {} +#endif +}; + +CPUDeviceContext* GetCPUDeviceContext(const platform::CPUPlace& place); + +#ifndef PADDLE_ONLY_CPU +CUDADeviceContext* GetCUDADeviceContext(const platform::GPUPlace& place); +#endif + +Device* GetDevice(const platform::Place& place); +} // namespace platform +} // namespace paddle