Added NBG support

Signed-off-by: xiang.zhang <xiang.zhang@verisilicon.com>
This commit is contained in:
xiang.zhang 2021-02-19 17:53:24 +08:00 committed by Kainan Cha
parent c5e16157a6
commit 9d44b4477b
14 changed files with 305 additions and 33 deletions

View File

@ -49,3 +49,16 @@ cc_binary(
],
)
##############################################################################
# unit test
##############################################################################
cc_test (
name = "unit_test",
copts = ["-std=c++14", "-Werror"],
srcs = glob(["src/tim/vx/*_test.cc"]),
deps = [
"@gtest//:gtest",
"@gtest//:gtest_main",
":tim-vx_interface",
]
)

View File

@ -2,6 +2,9 @@ workspace(name = "TIM_VX")
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
##############################################################################
# Toolchains
##############################################################################
http_archive(
name = "aarch64_A311D",
build_file = "@//prebuilt-sdk/x86_64_linux:BUILD",
@ -19,3 +22,17 @@ local_repository(
load("@TOOLCHAINS//:toolchains.bzl", "init_toolchains")
init_toolchains()
##############################################################################
#Third party repositories
##############################################################################
http_archive(
name = "gtest",
sha256 = "ff7a82736e158c077e76188232eac77913a15dac0b22508c390ab3f88e6d6d86",
strip_prefix = "googletest-b6cd405286ed8635ece71c72f118e659f4ade3fb",
urls = [
"https://storage.googleapis.com/mirror.tensorflow.org/github.com/google/googletest/archive/b6cd405286ed8635ece71c72f118e659f4ade3fb.zip",
"https://github.com/google/googletest/archive/b6cd405286ed8635ece71c72f118e659f4ade3fb.zip",
],
)

View File

@ -26,11 +26,11 @@
#include <memory>
#include "tim/vx/graph.h"
namespace tim {
namespace vx {
class Graph;
class Context {
public:
virtual ~Context() {}
@ -41,4 +41,4 @@ class Context {
} // namespace vx
} // namespace tim
#endif /* TIM_VX_CONTEXT_H_ */
#endif /* TIM_VX_CONTEXT_H_ */

View File

@ -27,11 +27,12 @@
#include <memory>
#include <vector>
#include "tim/vx/tensor.h"
namespace tim {
namespace vx {
class Tensor;
class TensorSpec;
class Graph {
public:
virtual ~Graph() {}
@ -46,7 +47,9 @@ class Graph {
/// Freeze graph
virtual bool Compile() = 0;
/// Process the compiled graph
/// Compile to BinaryGraph
virtual bool CompileToBinary(void* buf, size_t* size) = 0;
virtual bool Run() = 0;
template <typename OpType, typename... Params>

View File

@ -39,4 +39,4 @@ class L2Normalization : public Operation {
} // namespace ops
} // namespace vx
} // namespace tim
#endif
#endif

41
include/tim/vx/ops/nbg.h Normal file
View File

@ -0,0 +1,41 @@
/****************************************************************************
*
* Copyright (c) 2020 Vivante Corporation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
*****************************************************************************/
#ifndef TIM_VX_OPS_NBG_H_
#define TIM_VX_OPS_NBG_H_
#include "tim/vx/operation.h"
namespace tim {
namespace vx {
namespace ops {
class NBG : public Operation {
public:
NBG(Graph* graph, const char* binary, size_t input_count, size_t output_count);
};
} // namespace ops
} // namespace vx
} // namespace tim
#endif

View File

@ -90,6 +90,13 @@ struct TensorSpec {
this->quantization_ = quantization;
}
TensorSpec(const TensorSpec& other) {
this->datatype_ = other.datatype_;
this->shape_ = other.shape_;
this->attr_ = other.attr_;
this->quantization_ = other.quantization_;
}
TensorSpec& SetDataType(DataType datatype) {
this->datatype_ = datatype;
return *this;
@ -138,4 +145,4 @@ class Tensor {
} // namespace vx
} // namespace tim
#endif /* TIM_VX_TENSOR_H_ */
#endif /* TIM_VX_TENSOR_H_ */

View File

@ -48,6 +48,5 @@ std::shared_ptr<Context> Context::Create() {
std::shared_ptr<Graph> ContextImpl::CreateGraph() {
return std::make_shared<GraphImpl>(this);
}
} // namespace vx
} // namespace tim

View File

@ -34,8 +34,8 @@ class ContextImpl : public Context {
ContextImpl();
~ContextImpl();
vsi_nn_context_t context();
std::shared_ptr<Graph> CreateGraph();
std::shared_ptr<Graph> CreateGraph() override;
protected:
vsi_nn_context_t context_;
};

View File

@ -0,0 +1,32 @@
/****************************************************************************
*
* Copyright (c) 2020 Vivante Corporation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
*****************************************************************************/
#include "tim/vx/context.h"
#include "gtest/gtest.h"
TEST(Context, create) {
auto ctx0 = tim::vx::Context::Create();
{auto ctx0 = tim::vx::Context::Create();}
auto ctx1 = tim::vx::Context::Create();
// EXPECT_TRUE(0);
}

View File

@ -28,7 +28,10 @@
#include "context_private.h"
#include "graph_private.h"
#include "tensor_private.h"
#include "operation_private.h"
#include "tim/vx/context.h"
#include "tim/vx/ops/nbg.h"
#include "vsi_nn_pub.h"
namespace tim {
@ -37,8 +40,7 @@ namespace vx {
GraphImpl::GraphImpl(ContextImpl* context)
: context_(context),
graph_(vsi_nn_CreateGraph(context_->context(), 0, 0)),
tensor_placeholder_(nullptr),
compiled_(false) {}
tensor_placeholder_(nullptr) {}
GraphImpl::~GraphImpl() { vsi_nn_ReleaseGraph(&graph_); }
@ -70,20 +72,40 @@ std::shared_ptr<Tensor> GraphImpl::CreateTensorPlaceHolder() {
}
bool GraphImpl::Compile() {
compiled_ = true;
bool status = true;
vsi_nn_SetGraphInputs(graph_, inputs_.data(), inputs_.size());
vsi_nn_SetGraphOutputs(graph_, outputs_.data(), outputs_.size());
std::call_once(setio_once_, [&status, this]() {
status = (vsi_nn_SetGraphInputs(this->graph_, this->inputs_.data(), this->inputs_.size()) &&
vsi_nn_SetGraphOutputs(this->graph_, this->outputs_.data(), this->outputs_.size()));
});
return (VSI_SUCCESS == vsi_nn_SetupGraph(graph_, true) &&
VSI_SUCCESS == vsi_nn_VerifyGraph(graph_));
std::call_once(setup_once_, [&status, this](){
status = (VSI_SUCCESS == vsi_nn_SetupGraph(this->graph_, true));
});
std::call_once(verify_graph_once_, [&status, this]() {
status = (VSI_SUCCESS == vsi_nn_VerifyGraph(this->graph_));
});
return status;
}
bool GraphImpl::CompileToBinary(void* buf, size_t* size) {
bool status = true;
std::call_once(setio_once_, [&status, this]() {
status = (vsi_nn_SetGraphInputs(this->graph_, this->inputs_.data(), this->inputs_.size()) &&
vsi_nn_SetGraphOutputs(this->graph_,this->outputs_.data(), this->outputs_.size()));
});
std::call_once(setup_once_, [&status, this](){
status = (VSI_SUCCESS == vsi_nn_SetupGraph(this->graph_, true));
});
return ((status) && (VSI_SUCCESS == vsi_nn_GenerateNBG(graph_, buf, size)));
}
bool GraphImpl::Run() {
if (!compiled_ && !Compile()) {
return false;
}
return (VSI_SUCCESS == vsi_nn_RunGraph(graph_));
return ((Compile()) && (VSI_SUCCESS == vsi_nn_RunGraph(graph_)));
}
} // namespace vx

View File

@ -23,10 +23,15 @@
*****************************************************************************/
#ifndef TIM_VX_GRAPH_PRIVATE_H_
#define TIM_VX_GRAPH_PRIVATE_H_
#include <vector>
#include "context_private.h"
#include "tim/vx/graph.h"
#include <vector>
#include <mutex>
#include <utility>
#include "tim/vx/tensor.h"
#include "context_private.h"
#include "vsi_nn_pub.h"
namespace tim {
@ -39,22 +44,25 @@ class GraphImpl : public Graph {
/// Return the low-level graph object
vsi_nn_graph_t* graph();
void AddInput(vsi_nn_tensor_id_t id);
void AddOutput(vsi_nn_tensor_id_t id);
/// Implement parents' virtual functions
std::shared_ptr<Tensor> CreateTensor(const TensorSpec& spec,
const void* data = nullptr);
std::shared_ptr<Tensor> CreateTensorPlaceHolder();
bool Compile();
bool Run();
std::shared_ptr<Tensor> CreateTensor(const TensorSpec& spec,
const void* data = nullptr) override;
std::shared_ptr<Tensor> CreateTensorPlaceHolder() override;
bool Compile() override;
bool CompileToBinary(void* buf, size_t* size) override;
bool Run() override;
protected:
ContextImpl* context_;
vsi_nn_graph_t* graph_;
std::shared_ptr<Tensor> tensor_placeholder_;
bool compiled_;
std::once_flag setio_once_;
std::once_flag setup_once_;
std::once_flag verify_graph_once_;
std::vector<vsi_nn_tensor_id_t> inputs_;
std::vector<vsi_nn_tensor_id_t> outputs_;
};

92
src/tim/vx/graph_test.cc Normal file
View File

@ -0,0 +1,92 @@
/****************************************************************************
*
* Copyright (c) 2020 Vivante Corporation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
*****************************************************************************/
#include "tim/vx/context.h"
#include "tim/vx/graph.h"
#include "tim/vx/ops/elementwise.h"
#include "tim/vx/ops/nbg.h"
#include "gtest/gtest.h"
#include <vector>
TEST(graph, gen_binary_graph_with_empty_graph) {
auto ctx = tim::vx::Context::Create();
auto graph = ctx->CreateGraph();
size_t bin_size = -1;
EXPECT_FALSE(graph->CompileToBinary(nullptr, &bin_size)) << "Can not generate binary graph if it is empty";
}
TEST(graph, gen_binary_graph_with_simple_add) {
auto ctx = tim::vx::Context::Create();
auto graph = ctx->CreateGraph();
tim::vx::ShapeType io_shape({1,1,1,1});
tim::vx::TensorSpec input_spec(tim::vx::DataType::FLOAT32, io_shape, tim::vx::TensorAttribute::INPUT);
tim::vx::TensorSpec output_spec(tim::vx::DataType::FLOAT32, io_shape, tim::vx::TensorAttribute::OUTPUT);
auto input_t0 = graph->CreateTensor(input_spec);
auto input_t1 = graph->CreateTensor(input_spec);
auto output_t = graph->CreateTensor(output_spec);
float in = 1.0f;
float expected_out = 2.0f;
EXPECT_TRUE(input_t0->CopyDataToTensor(&in, sizeof(in)));
EXPECT_TRUE(input_t1->CopyDataToTensor(&in, sizeof(in)));
auto add = graph->CreateOperation<tim::vx::ops::Add>();
(*add).BindInputs({input_t0, input_t1}).BindOutputs({output_t});
size_t bin_size = -1;
EXPECT_TRUE(graph->CompileToBinary(nullptr, &bin_size));
EXPECT_NE(bin_size, -1);
std::vector<char> nbg_buf(bin_size);
EXPECT_TRUE(graph->CompileToBinary(nbg_buf.data(), &bin_size));
// binary graph compilation doesn't impact current graph's execution
EXPECT_TRUE(graph->Run());
float output = 0.0f;
EXPECT_TRUE(output_t->CopyDataFromTensor(&output));
EXPECT_EQ(output, expected_out);
auto nbg_graph = ctx->CreateGraph();
auto nbg_in0 = nbg_graph->CreateTensor(input_spec);
auto nbg_in1 = nbg_graph->CreateTensor(input_spec);
auto nbg_out = nbg_graph->CreateTensor(output_spec);
EXPECT_TRUE(nbg_in0->CopyDataToTensor(&in, sizeof(in)));
EXPECT_TRUE(nbg_in1->CopyDataToTensor(&in, sizeof(in)));
auto nbg_node = nbg_graph->CreateOperation<tim::vx::ops::NBG>(
(nbg_buf.data()), /*num_of_input*/ 2,
/*num_of_output*/ 1);
(*nbg_node).BindInputs({nbg_in0, nbg_in1}).BindOutputs({output_t});
EXPECT_TRUE(nbg_graph->Compile());
EXPECT_TRUE(nbg_graph->Run());
output=0.0f;
EXPECT_TRUE(nbg_out->CopyDataFromTensor(&output));
EXPECT_EQ(output, expected_out);
}

38
src/tim/vx/ops/nbg.cc Normal file
View File

@ -0,0 +1,38 @@
/****************************************************************************
*
* Copyright (c) 2020 Vivante Corporation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
*****************************************************************************/
#include "tim/vx/ops/nbg.h"
#include "operation_private.h"
#include "vsi_nn_pub.h"
namespace tim {
namespace vx {
namespace ops {
NBG::NBG(Graph* graph, const char* binary, size_t input_count, size_t output_count) : Operation(graph, VSI_NN_OP_NBG, input_count, output_count) {
this->impl()->node()->nn_param.nbg.url = binary;
this->impl()->node()->nn_param.nbg.type = VSI_NN_NBG_POINTER;
}
} // namespace ops
} // namespace vx
} // namespace tim