Skip to content
This repository has been archived by the owner on Jan 3, 2023. It is now read-only.

Add PlaidML backend #1888

Merged
merged 6 commits into from
Oct 29, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
6 changes: 6 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,8 @@ if (NGRAPH_ONNX_IMPORT_ENABLE)
option(NGRAPH_ONNXIFI_ENABLE "Enable ONNX Interface for Framework Integration" TRUE)
endif()

option(NGRAPH_PLAIDML_ENABLE "Enable the PlaidML backend" FALSE)

#-----------------------------------------------------------------------------------------------
# Installation logic...
#-----------------------------------------------------------------------------------------------
Expand Down Expand Up @@ -206,6 +208,10 @@ if (NGRAPH_CPU_ENABLE)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DNGRAPH_CPU_ENABLE")
endif()

if (NGRAPH_PLAIDML_ENABLE)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DNGRAPH_PlaidML_ENABLE")
endif()

if (NOT DEFINED NGRAPH_TBB_ENABLE)
set(NGRAPH_TBB_ENABLE ${NGRAPH_CPU_ENABLE})
endif()
Expand Down
1 change: 1 addition & 0 deletions CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
/src/ngraph/runtime/hybrid/ @sasadep
/src/ngraph/runtime/intelgpu/ @shssf
/src/ngraph/runtime/interpreter/ @rkimballn1
/src/ngraph/runtime/plaidml/ @earhart
/src/ngraph/runtime/reference/ @aprocter
/src/ngraph/type/ @diyessi
/src/ngraph/serializer.*pp @rkimballn1
Expand Down
3 changes: 2 additions & 1 deletion python/test/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@

def pytest_addoption(parser):
parser.addoption('--backend', default='INTERPRETER',
choices=['INTERPRETER', 'CPU', 'GPU', 'NNP'],
choices=['INTERPRETER', 'CPU', 'GPU', 'NNP', 'PlaidML'],
help='Select from available backends')


Expand All @@ -31,3 +31,4 @@ def pytest_configure(config):
config.cpu_skip = pytest.mark.skipif(config.getvalue('backend') == 'CPU')
config.nnp_skip = pytest.mark.skipif(config.getvalue('backend') == 'NNP')
config.interpreter_skip = pytest.mark.skipif(config.getvalue('backend') == 'INTERPRETER')
config.plaidml_skip = pytest.mark.skipif(config.getvalue('backend') == 'PlaidML')
1 change: 1 addition & 0 deletions src/ngraph/placement.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ std::string ngraph::placement_to_string(Placement placement)
case Placement::CPU: return "CPU";
case Placement::GPU: return "GPU";
case Placement::NNP: return "NNP";
case Placement::PLAIDML: return "PlaidML";
}
throw runtime_error("unhandled placement type");
}
Expand Down
1 change: 1 addition & 0 deletions src/ngraph/placement.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ namespace ngraph
CPU,
GPU,
NNP,
PLAIDML,
};

std::string placement_to_string(Placement placement);
Expand Down
2 changes: 2 additions & 0 deletions src/ngraph/runtime/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,5 @@ endif()
if (NGRAPH_GPU_ENABLE)
add_subdirectory(gpu)
endif()

add_subdirectory(plaidml)
69 changes: 69 additions & 0 deletions src/ngraph/runtime/plaidml/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
# ******************************************************************************
# Copyright 2018 Intel Corporation
#
# 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.
# ******************************************************************************

set(SRC
plaidml_backend.cpp
plaidml_builder.cpp
plaidml_compilation_cache.cpp
plaidml_compiled_function.cpp
plaidml_compiler.cpp
plaidml_config.cpp
plaidml_convpool_formatter.cpp
plaidml_impl.cpp
plaidml_logger.cpp
plaidml_ops_arithmetic.cpp
plaidml_ops_batch_norm.cpp
plaidml_ops_comparison.cpp
plaidml_ops_concat.cpp
plaidml_ops_convert.cpp
plaidml_ops_convolution.cpp
plaidml_ops_dot.cpp
plaidml_ops_function.cpp
plaidml_ops_general.cpp
plaidml_ops_index_reduction.cpp
plaidml_ops_io.cpp
plaidml_ops_local_response_norm.cpp
plaidml_ops_logical.cpp
plaidml_ops_one_hot.cpp
plaidml_ops_pool.cpp
plaidml_ops_reduce.cpp
plaidml_ops_replace_slice.cpp
plaidml_ops_reverse.cpp
plaidml_ops_slice.cpp
plaidml_ops_softmax.cpp
plaidml_ops_transcendental.cpp
plaidml_tensor.cpp
plaidml_translate.cpp
)

if (NGRAPH_PLAIDML_ENABLE)
find_package(PlaidML CONFIG REQUIRED)
message(STATUS "PlaidML enabled")

add_library(libplaidml INTERFACE)
target_link_libraries(libplaidml INTERFACE ${PLAIDML_LIBRARIES})
install(FILES ${PLAIDML_LIBRARIES} DESTINATION ${NGRAPH_INSTALL_LIB})

add_library(plaidml_backend SHARED ${SRC})
set_target_properties(plaidml_backend PROPERTIES VERSION ${NGRAPH_VERSION} SOVERSION ${NGRAPH_API_VERSION})
target_include_directories(plaidml_backend SYSTEM PUBLIC ${PLAIDML_INCLUDE_DIRS})
target_link_libraries(plaidml_backend PUBLIC ngraph libplaidml)
set_target_properties(plaidml_backend PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${NGRAPH_BUILD_DIR}")
install(TARGETS plaidml_backend LIBRARY DESTINATION ${NGRAPH_INSTALL_LIB})
else()
message(STATUS "PlaidML not enabled")
endif()

95 changes: 95 additions & 0 deletions src/ngraph/runtime/plaidml/plaidml_backend.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
//*****************************************************************************
// Copyright 2017-2018 Intel Corporation
//
// 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 "ngraph/runtime/plaidml/plaidml_backend.hpp"
#include "ngraph/node.hpp"
#include "ngraph/runtime/plaidml/plaidml_compiled_function.hpp"
#include "ngraph/runtime/plaidml/plaidml_tensor.hpp"
#include "ngraph/util.hpp"

namespace vp = vertexai::plaidml;

ngraph::runtime::plaidml::PlaidML_Backend::PlaidML_Backend(const char* configuration_string)
: m_config{parse_config_string(configuration_string)}
, m_compiler{&m_config}
{
}

std::shared_ptr<ngraph::runtime::Tensor> ngraph::runtime::plaidml::PlaidML_Backend::create_tensor(
const ngraph::element::Type& element_type, const ngraph::Shape& shape)
{
return std::make_shared<PlaidML_Tensor>(&m_config, element_type, shape, "direct_data", nullptr);
}

std::shared_ptr<ngraph::runtime::Tensor> ngraph::runtime::plaidml::PlaidML_Backend::create_tensor(
const ngraph::element::Type& element_type, const Shape& shape, void* memory_pointer)
{
return std::make_shared<PlaidML_Tensor>(
&m_config, element_type, shape, "direct_data", memory_pointer);
}

bool ngraph::runtime::plaidml::PlaidML_Backend::compile(std::shared_ptr<Function> func)
{
m_cache.compile(func, &m_compiler);
return true;
}

bool ngraph::runtime::plaidml::PlaidML_Backend::call(
std::shared_ptr<Function> func,
const std::vector<std::shared_ptr<runtime::Tensor>>& outputs,
const std::vector<std::shared_ptr<runtime::Tensor>>& inputs)
{
auto cfunc = m_cache.try_lookup(func);
if (!cfunc)
{
cfunc = m_compiler.compile(func);
}
cfunc->schedule_invocation(inputs, outputs);
return true;
}

void ngraph::runtime::plaidml::PlaidML_Backend::remove_compiled_function(
std::shared_ptr<Function> func)
{
m_cache.forget(func);
}

void ngraph::runtime::plaidml::PlaidML_Backend::save(std::shared_ptr<Function> func,
const std::string& filename,
plaidml_file_format format)
{
auto cfunc = m_cache.try_lookup(func);
if (!cfunc)
{
cfunc = m_compiler.compile(func);
}
cfunc->save(filename, format);
}

extern "C" const char* get_ngraph_version_string()
{
return NGRAPH_VERSION;
}

extern "C" ngraph::runtime::Backend* new_backend(const char* configuration_string)
{
return new ngraph::runtime::plaidml::PlaidML_Backend{configuration_string};
}

extern "C" void delete_backend(ngraph::runtime::Backend* backend)
{
delete backend;
}
65 changes: 65 additions & 0 deletions src/ngraph/runtime/plaidml/plaidml_backend.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
//*****************************************************************************
// Copyright 2017-2018 Intel Corporation
//
// 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 <plaidml/plaidml++.h>

#include "ngraph/runtime/backend.hpp"
#include "ngraph/runtime/plaidml/plaidml_compilation_cache.hpp"
#include "ngraph/runtime/plaidml/plaidml_compiler.hpp"
#include "ngraph/runtime/plaidml/plaidml_config.hpp"

namespace ngraph
{
namespace runtime
{
namespace plaidml
{
class PlaidML_Backend;
}
}
}

// Implements the runtime::Backend interface for the PlaidML nGraph backend.
class ngraph::runtime::plaidml::PlaidML_Backend final : public runtime::Backend
{
public:
PlaidML_Backend(const char* configuration_string);
~PlaidML_Backend() final {}
std::shared_ptr<ngraph::runtime::Tensor>
create_tensor(const ngraph::element::Type& element_type, const Shape& shape) final;

std::shared_ptr<ngraph::runtime::Tensor> create_tensor(
const ngraph::element::Type& element_type, const Shape& shape, void* memory_pointer) final;

bool compile(std::shared_ptr<Function> func) final;

bool call(std::shared_ptr<Function> func,
const std::vector<std::shared_ptr<runtime::Tensor>>& outputs,
const std::vector<std::shared_ptr<runtime::Tensor>>& inputs) final;

void remove_compiled_function(std::shared_ptr<Function> func) final;

void save(std::shared_ptr<Function> func,
const std::string& filename,
plaidml_file_format format);

private:
Config m_config;
Compiler m_compiler;
CompilationCache m_cache;
};
72 changes: 72 additions & 0 deletions src/ngraph/runtime/plaidml/plaidml_build.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
//*****************************************************************************
// Copyright 2017-2018 Intel Corporation
//
// 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 <plaidml/plaidml++.h>

#include <string>
#include <unordered_map>

#include "ngraph/function.hpp"
#include "ngraph/runtime/plaidml/plaidml_config.hpp"
#include "ngraph/runtime/tensor.hpp"

namespace ngraph
{
namespace runtime
{
namespace plaidml
{
struct Build;
class Compiler;
struct TensorInfo;

enum class TensorContents
{
DATA = 0,
LOGICAL = 1
};
}
}
}

// Holds information about a particular tensor.
struct ngraph::runtime::plaidml::TensorInfo final
{
TensorInfo(vertexai::plaidml::variable _var, TensorContents _contents)
: var{std::move(_var)}
, contents{_contents}
{
}

vertexai::plaidml::variable var;
TensorContents contents;
};

// Holds the intermediate state of a function compilation.
struct ngraph::runtime::plaidml::Build final
{
Config* config = nullptr;
Compiler* compiler = nullptr;
std::shared_ptr<Function> func;
std::unordered_map<descriptor::Tensor*, std::string> input_names;
std::unordered_map<descriptor::Tensor*, std::string> output_names;
vertexai::plaidml::compose composer;
std::unordered_map<descriptor::Tensor*, TensorInfo> bindings;
bool io_dim_override = false;
std::size_t io_dim_override_count = 0;
};