[IE][VPU] Support for constant networks (#6185)

Adds support for constant networks in the Myriad plugin
This commit is contained in:
Polina Brzezinskaya 2021-07-05 10:26:34 +03:00 committed by GitHub
parent 13de29db97
commit a65828c172
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 93 additions and 60 deletions

View File

@ -27,7 +27,6 @@ IeParsedNetwork parseNetwork(const ie::CNNNetwork& network) {
out.networkOutputs = network.getOutputsInfo();
env.log->trace("Got %d inputs and %d outputs", out.networkInputs.size(), out.networkOutputs.size());
IE_ASSERT(!out.networkInputs.empty());
IE_ASSERT(!out.networkOutputs.empty());
env.log->trace("Perform topological sort");

View File

@ -7,6 +7,7 @@
#include <ie_metric_helpers.hpp>
#include <legacy/cnn_network_impl.hpp>
#include <legacy/convert_function_to_cnn_network.hpp>
#include "exec_graph_info.hpp"
#include <myriad_executable_network.h>
#include <vpu/blob_reader.hpp>
@ -25,7 +26,6 @@ namespace MyriadPlugin {
ExecutableNetwork::ExecutableNetwork(
std::shared_ptr<IMvnc> mvnc,
std::vector<DevicePtr>& devicePool,
const MyriadConfiguration& config,
const std::shared_ptr<ie::ICore> core) :
_config(config),
@ -40,10 +40,6 @@ ExecutableNetwork::ExecutableNetwork(
defaultOutput(_config.pluginLogFilePath()));
_executor = std::make_shared<MyriadExecutor>(_config.forceReset(), std::move(mvnc), logLevel, _log);
_device = _executor->openDevice(devicePool, _config);
const auto& revision = _device->revision();
_actualNumExecutors = config.compileConfig().numExecutors != -1 ? config.compileConfig().numExecutors : DefaultAllocation::numStreams(revision, config);
_supportedMetrics = {
METRIC_KEY(NETWORK_NAME),
@ -54,13 +50,19 @@ ExecutableNetwork::ExecutableNetwork(
};
}
void ExecutableNetwork::openDevice(std::vector<DevicePtr>& devicePool) {
_device = _executor->openDevice(devicePool, _config);
const auto& revision = _device->revision();
_actualNumExecutors = _config.compileConfig().numExecutors != -1 ? _config.compileConfig().numExecutors : DefaultAllocation::numStreams(revision, _config);
}
ExecutableNetwork::ExecutableNetwork(
const ie::CNNNetwork& network,
std::shared_ptr<IMvnc> mvnc,
std::vector<DevicePtr>& devicePool,
const MyriadConfiguration& config,
const std::shared_ptr<ie::ICore> core) :
ExecutableNetwork(std::move(mvnc), devicePool, config, core) {
ExecutableNetwork(std::move(mvnc), config, core) {
VPU_PROFILE(ExecutableNetwork);
const auto compilerLog = std::make_shared<Logger>(
@ -68,11 +70,9 @@ ExecutableNetwork::ExecutableNetwork(
_config.get<LogLevelOption>(),
defaultOutput(_config.compilerLogFilePath()));
if (_device == nullptr)
IE_THROW() << "No device was detected";
auto compiledGraph = compileNetwork(
network,
_device->_platform,
NC_MYRIAD_X,
_config,
compilerLog,
_core);
@ -84,12 +84,7 @@ ExecutableNetwork::ExecutableNetwork(
_inputInfo = std::move(compiledGraph->inputInfo);
_outputInfo = std::move(compiledGraph->outputInfo);
if (!_device->isBooted()) {
return;
}
const auto& networkName = network.getName();
_executor->allocateGraph(_device, _graphDesc, _graphBlob, compiledGraph->blobHeader, compiledGraph->numActiveStages, networkName, _actualNumExecutors);
if (_config.exclusiveAsyncRequests()) {
ExecutorManager *executorManager = ExecutorManager::getInstance();
_taskExecutor = executorManager->getExecutor("MYRIAD");
@ -100,6 +95,21 @@ ExecutableNetwork::ExecutableNetwork(
idStream << networkName << "_TaskExecutorGetResult" << i;
_taskExecutorGetResultIds.emplace(idStream.str());
}
if (_inputInfo.totalSize == 0) {
_isNetworkConstant = true;
const auto& nGraphFunc = network.getFunction();
const auto& sortedLayers = nGraphFunc->get_ordered_ops();
for (const auto& layer : sortedLayers) {
if (strcmp(layer->get_type_info().name, "Constant") == 0) {
const auto& constOp = std::dynamic_pointer_cast<ngraph::op::v0::Constant>(layer);
auto name = constOp->get_friendly_name();
_constDatas[name] = ie::details::shareWeights(constOp);
}
}
return;
}
openDevice(devicePool);
_executor->allocateGraph(_device, _graphDesc, _graphBlob, compiledGraph->blobHeader, compiledGraph->numActiveStages, networkName, _actualNumExecutors);
}
void ExecutableNetwork::Import(std::istream& strm, std::vector<DevicePtr> &devicePool, const MyriadConfiguration& configuration) {
@ -110,10 +120,6 @@ void ExecutableNetwork::Import(std::istream& strm, std::vector<DevicePtr> &devic
strm.seekg(currentPos, strm.beg);
strm.read(&_graphBlob[0], blobSize);
if (!_device->isBooted()) {
return;
}
std::string networkName = importedNetworkName;
BlobReader blobReader;
@ -126,9 +132,8 @@ void ExecutableNetwork::Import(std::istream& strm, std::vector<DevicePtr> &devic
_inputInfo = blobReader.getInputInfo();
_outputInfo = blobReader.getOutputInfo();
openDevice(devicePool);
_executor->allocateGraph(_device, _graphDesc, _graphBlob, blobHeader, numStages, networkName, _actualNumExecutors);
_graphMetaData.stagesMeta.resize(numStages);
for (auto &meta : _graphMetaData.stagesMeta) {
meta.stageName = meta.stageType = meta.layerName = meta.layerType = "UNKNOWN";
@ -147,9 +152,12 @@ void ExecutableNetwork::Import(std::istream& strm, std::vector<DevicePtr> &devic
}
}
ExecutableNetwork::ExecutableNetwork(std::istream& strm, std::shared_ptr<IMvnc> mvnc, std::vector<DevicePtr> &devicePool,
const MyriadConfiguration& config, const std::shared_ptr<ie::ICore> core) :
ExecutableNetwork(std::move(mvnc), devicePool, config, core) {
ExecutableNetwork::ExecutableNetwork(std::istream& strm,
std::shared_ptr<IMvnc> mvnc,
std::vector<DevicePtr> &devicePool,
const MyriadConfiguration& config,
const std::shared_ptr<ie::ICore> core) :
ExecutableNetwork(std::move(mvnc), config, core) {
VPU_PROFILE(ExecutableNetwork);
Import(strm, devicePool, config);
}
@ -160,7 +168,7 @@ ExecutableNetwork::ExecutableNetwork(
std::vector<DevicePtr>& devicePool,
const MyriadConfiguration& config,
const std::shared_ptr<ie::ICore> core) :
ExecutableNetwork(std::move(mvnc), devicePool, config, core) {
ExecutableNetwork(std::move(mvnc), config, core) {
VPU_PROFILE(ExecutableNetwork);
std::ifstream blobFile{blobFilename, std::ios::binary};
Import(blobFile, devicePool, config);

View File

@ -44,7 +44,9 @@ public:
virtual ~ExecutableNetwork() {
try {
_executor->deallocateGraph(_device, _graphDesc);
if (_device != nullptr) {
_executor->deallocateGraph(_device, _graphDesc);
}
}
catch (...) {
std::cerr << "ERROR ~ExecutableNetwork():\n"
@ -54,18 +56,19 @@ public:
ie::IInferRequestInternal::Ptr CreateInferRequestImpl(ie::InputsDataMap networkInputs,
ie::OutputsDataMap networkOutputs) override {
if (_device == nullptr || !_device->isBooted()) {
if (!_isNetworkConstant && (_device == nullptr || !_device->isBooted())) {
IE_THROW() << "Can not create infer request: there is no available devices with platform "
<< _device->_platform;
}
return std::make_shared<MyriadInferRequest>(_graphDesc, networkInputs, networkOutputs,
_inputInfo, _outputInfo,
_graphMetaData.stagesMeta, _config, _log, _executor);
_graphMetaData.stagesMeta, _config, _log, _executor,
_constDatas, _isNetworkConstant);
}
ie::IInferRequestInternal::Ptr CreateInferRequest() override {
if (_device == nullptr || !_device->isBooted()) {
if (!_isNetworkConstant && (_device == nullptr || !_device->isBooted())) {
IE_THROW() << "Can not create infer request: there is no available devices with platform "
<< _device->_platform;
}
@ -73,7 +76,7 @@ public:
auto syncRequestImpl = std::make_shared<MyriadInferRequest>(_graphDesc, _networkInputs, _networkOutputs,
_inputInfo, _outputInfo,
_graphMetaData.stagesMeta, _config, _log,
_executor);
_executor, _constDatas, _isNetworkConstant);
syncRequestImpl->setPointerToExecutableNetworkInternal(shared_from_this());
auto taskExecutorGetResult = getNextTaskExecutor();
return std::make_shared<MyriadAsyncInferRequest>(
@ -84,6 +87,16 @@ public:
model.write(_graphBlob.data(), _graphBlob.size());
}
void Export(const std::string &modelFileName) override {
std::ofstream modelFile(modelFileName, std::ios::out | std::ios::binary);
if (modelFile.is_open()) {
Export(modelFile);
} else {
IE_THROW() << "The " << modelFileName << " file can not be opened for export";
}
}
ie::Parameter GetMetric(const std::string &name) const override;
ie::CNNNetwork GetExecGraphInfo() override;
@ -98,9 +111,11 @@ private:
DevicePtr _device;
GraphMetaInfo _graphMetaData;
MyriadConfiguration _config;
bool _isNetworkConstant = false;
const std::shared_ptr<ie::ICore> _core = nullptr;
int _actualNumExecutors = 0;
std::vector<std::string> _supportedMetrics;
std::map<std::string, ie::Blob::Ptr> _constDatas;
DataInfo _inputInfo;
DataInfo _outputInfo;
@ -109,9 +124,8 @@ private:
std::queue<std::string> _taskExecutorGetResultIds;
ExecutableNetwork(std::shared_ptr<IMvnc> mvnc,
std::vector<DevicePtr> &devicePool,
const MyriadConfiguration& config,
const std::shared_ptr<ie::ICore> core);
const MyriadConfiguration& config,
const std::shared_ptr<ie::ICore> core);
ie::ITaskExecutor::Ptr getNextTaskExecutor() {
std::string id = _taskExecutorGetResultIds.front();
@ -124,6 +138,8 @@ private:
return taskExecutor;
}
void openDevice(std::vector<DevicePtr>& devicePool);
};
} // namespace MyriadPlugin

View File

@ -33,11 +33,13 @@ MyriadInferRequest::MyriadInferRequest(GraphDesc &graphDesc,
const std::vector<StageMetaInfo> &blobMetaData,
const MyriadConfig& myriadConfig,
const Logger::Ptr &log,
const MyriadExecutorPtr &executor) :
const MyriadExecutorPtr &executor,
std::map<std::string, ie::Blob::Ptr> constDatas,
bool isNetworkConstant = true) :
IInferRequestInternal(networkInputs, networkOutputs), _executor(executor),
_log(log), _stagesMetaData(blobMetaData), _config(myriadConfig),
_inputInfo(compilerInputsInfo), _outputInfo(compilerOutputsInfo),
_graphDesc(graphDesc) {
_graphDesc(graphDesc), _constDatas(constDatas), _isNetworkConstant(isNetworkConstant) {
VPU_PROFILE(MyriadInferRequest);
const auto& ioStrides = _config.compileConfig().ioStrides;
@ -83,7 +85,7 @@ MyriadInferRequest::MyriadInferRequest(GraphDesc &graphDesc,
resultBuffer.resize(compilerOutputsInfo.totalSize);
VPU_THROW_UNLESS(
!_networkOutputs.empty() && !_networkInputs.empty(),
!_networkOutputs.empty() && !(_networkInputs.empty() && !_isNetworkConstant),
"No information about network's output/input");
}
@ -93,6 +95,9 @@ void MyriadInferRequest::InferImpl() {
}
void MyriadInferRequest::InferAsync() {
if (_isNetworkConstant) {
return;
}
VPU_PROFILE(InferAsync);
// execute input pre-processing
@ -104,7 +109,7 @@ void MyriadInferRequest::InferAsync() {
auto getOffset = [&inputInfo] (const std::string& name) {
const auto offsetIt = inputInfo.offset.find(name);
IE_ASSERT(offsetIt != inputInfo.offset.end()) << "MyriadInferRequest::InferAsync()\n"
<< "Input offset [" << name << "] is not provided.";
<< "Input offset [" << name << "] is not provided.";
return offsetIt->second;
};
@ -123,9 +128,9 @@ void MyriadInferRequest::InferAsync() {
const auto byteSize = blob->byteSize();
const auto requiredSize = vpu::checked_cast<size_t>(offset) + byteSize;
IE_ASSERT(requiredSize <= inputBuffer.size()) << "MyriadInferRequest::InferAsync()\n"
<< "Input offset is too big. "
<< "Required size: " << requiredSize
<< ", Input buffer size: " << inputBuffer.size();
<< "Input offset is too big. "
<< "Required size: " << requiredSize
<< ", Input buffer size: " << inputBuffer.size();
const auto foundBlob = getNetInputInfo(name);
const auto vpuLayout = foundBlob->second->getTensorDesc().getLayout();
@ -139,9 +144,8 @@ void MyriadInferRequest::InferAsync() {
}
_executor->queueInference(_graphDesc, inputBuffer.data(),
_inputInfo.totalSize, nullptr, 0);
_inputInfo.totalSize, nullptr, 0);
}
static void copyBlobAccordingUpperBound(
const Blob::Ptr& in,
const Blob::Ptr& out) {
@ -199,10 +203,22 @@ void MyriadInferRequest::GetResult() {
const auto getVpuLayout = [&networkOutputs] (const std::string& name){
const auto foundBlob = networkOutputs.find(name);
IE_ASSERT(foundBlob != networkOutputs.end()) << "MyriadInferRequest::InferAsync()\n"
<< "Output [" << name << "] is not provided.";
<< "Output [" << name << "] is not provided.";
return foundBlob->second->getTensorDesc().getLayout();
};
if (_isNetworkConstant) {
for (const auto& output : _outputs) {
const auto& ieBlobName = output.first;
const auto& ieBlob = output.second;
IE_ASSERT(_constDatas.find(ieBlobName) != _constDatas.end()) <<
"Input [" << ieBlobName << "] is not provided.";
std::copy_n(
_constDatas[ieBlobName]->cbuffer().as<uint8_t *>(),
_constDatas[ieBlobName]->byteSize(),
ieBlob->buffer().as<uint8_t *>());
}
return;
}
// For networks with only one output
if (_outputInfo.offset.size() == 1) {
const auto& it = _outputs.begin();
@ -224,12 +240,12 @@ void MyriadInferRequest::GetResult() {
const auto resultOffset = [&](const std::string& name) {
const auto offset_it = _outputInfo.offset.find(name);
IE_ASSERT(offset_it != _outputInfo.offset.end()) << "MyriadInferRequest::InferAsync()\n"
<< "Output offset [" << name << "] error.";
<< "Output offset [" << name << "] error.";
const auto offset = vpu::checked_cast<size_t>(offset_it->second);
IE_ASSERT(offset <= resultBuffer.size()) << "MyriadInferRequest::InferAsync()\n"
<< "Input offset is too big."
<< "Required offset: " << offset
<< "Result buffer size: " << resultBuffer.size();
<< "Input offset is too big."
<< "Required offset: " << offset
<< "Result buffer size: " << resultBuffer.size();
return offset;
};

View File

@ -34,6 +34,8 @@ class MyriadInferRequest : public InferenceEngine::IInferRequestInternal {
GraphDesc _graphDesc;
std::vector<uint8_t> resultBuffer;
std::vector<uint8_t> inputBuffer;
std::map<std::string, ie::Blob::Ptr> _constDatas;
bool _isNetworkConstant;
public:
typedef std::shared_ptr<MyriadInferRequest> Ptr;
@ -46,7 +48,9 @@ public:
const std::vector<StageMetaInfo> &blobMetaData,
const MyriadConfig &myriadConfig,
const Logger::Ptr &log,
const MyriadExecutorPtr &executor);
const MyriadExecutorPtr &executor,
std::map<std::string, ie::Blob::Ptr> constDatas,
bool isNetworkConstant);
void InferImpl() override;
void InferAsync();

View File

@ -23,8 +23,6 @@ std::vector<std::string> disabledTestPatterns() {
R"(.*IEClassGetAvailableDevices.*)",
// TODO: Issue: 40473
R"(.*TopKLayerTest.*mode=min.*sort=index.*)",
// TODO: Issue: 40961
R"(.*(ConstantResultSubgraphTest).*)",
// TODO: Issue: 42828
R"(.*DSR_NonMaxSuppression.*NBoxes=(5|20|200).*)",
// TODO: Issue: 42721

View File

@ -23,15 +23,7 @@ const std::vector<SizeVector> shapes = {
};
const std::vector<Precision> precisions = {
Precision::U8,
Precision::I8,
Precision::U16,
Precision::I16,
Precision::I32,
Precision::U64,
Precision::I64,
Precision::FP32,
Precision::BOOL
Precision::FP32
};
INSTANTIATE_TEST_SUITE_P(smoke_Check, ConstantResultSubgraphTest,