Skip to content

Commit

Permalink
Fix multiple outputs and add Split (#42)
Browse files Browse the repository at this point in the history
Fixes the problem with multiple outputs in the PlaidML plugin described in #36. Adds the Split operation with tests, which utilizes multiple outputs.
  • Loading branch information
tzerrell authored and YangleiZouIntel committed Feb 2, 2021
1 parent 4e3dc5d commit 1e9bd8a
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 2 deletions.
43 changes: 43 additions & 0 deletions inference-engine/src/plaidml_plugin/ops/split.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// Copyright (C) 2020 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//

#include "plaidml_ops.hpp"
#include "plaidml_util.hpp"

#include "ngraph/opsets/opset.hpp"
#include "ngraph/opsets/opset1.hpp"

#include "plaidml/op/op.h"

using namespace plaidml; // NOLINT[build/namespaces]

namespace PlaidMLPlugin {

static OpRegistration reg("split", [](const Context& ctx) {
auto* layer = dynamic_cast<ngraph::opset1::Split*>(ctx.layer);
IE_ASSERT(ctx.operands.size() == 2);
auto I = ctx.operands.at(0);
// operands.at(1) is unused, just read the Constant instead
auto splits = layer->get_num_splits();
auto axes = get_axis_vector_from_constant_operand(1, ctx.layer);
IE_ASSERT(axes.size() == 1);
auto axis = axes[0];

auto ndims = I.rank();
std::vector<edsl::TensorDim> I_dims(ndims);
std::vector<edsl::TensorIndex> I_idxs(ndims);
std::vector<edsl::Tensor> Os;
I.bind_dims(I_dims);
auto O_dims = I_dims;
auto split_size = I_dims[axis] / splits;
O_dims[axis] = split_size;
for (size_t i = 0; i < splits; i++) {
auto O_idxs = I_idxs;
O_idxs[axis] = I_idxs[axis] - i * split_size;
Os.push_back(plaidml::edsl::Contraction().outShape(O_dims).outAccess(O_idxs).assign(I(I_idxs)));
}
return edsl::make_tuple(Os);
});

} // namespace PlaidMLPlugin
Original file line number Diff line number Diff line change
Expand Up @@ -79,9 +79,14 @@ void PlaidMLExecutableNetwork::handleParameter(const std::shared_ptr<ngraph::Nod

void PlaidMLExecutableNetwork::handleOutput(const std::shared_ptr<ngraph::Node>& node) {
// The OV output name is the name of the node _prior_ to the result
// When there are multiple outputs, it has .# appended, where # is the output index
const auto& src_output = node->input(0).get_source_output();
tensorIONameMap_[src_output.get_node()->get_friendly_name()] =
tensorMap_.at(std::make_pair(src_output.get_node()->get_name(), src_output.get_index()));
const auto& src_node = src_output.get_node();
std::string name = src_node->get_friendly_name();
if (src_node->get_output_size() > 1) {
name += "." + std::to_string(src_output.get_index());
}
tensorIONameMap_[name] = tensorMap_.at(std::make_pair(src_node->get_name(), src_output.get_index()));
}

void PlaidMLExecutableNetwork::handleOp(const std::shared_ptr<ngraph::Node>& node) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// Copyright (C) 2020 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//

#include <vector>

#include "single_layer_tests/split.hpp"
#include "common_test_utils/test_constants.hpp"

using namespace LayerTestsDefinitions;

namespace {

const std::vector<InferenceEngine::Precision> netPrecisions = {
InferenceEngine::Precision::FP32,
// InferenceEngine::Precision::FP16
};

INSTANTIATE_TEST_CASE_P(NumSplitsCheck, SplitLayerTest,
::testing::Combine(
::testing::Values(1, 2),
::testing::Values(0, 1, 2, 3),
::testing::ValuesIn(netPrecisions),
::testing::Values(std::vector<size_t >({30, 30, 30, 30})),
::testing::Values(CommonTestUtils::DEVICE_PLAIDML)),
SplitLayerTest::getTestCaseName);
} // namespace

0 comments on commit 1e9bd8a

Please sign in to comment.