!40257 [MS][Lite]introduce extendrt for cloud inference

Merge pull request !40257 from zhaizhiqiang/master
This commit is contained in:
i-robot 2022-09-06 12:11:26 +00:00 committed by Gitee
commit 2f7531af8f
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
74 changed files with 625 additions and 4892 deletions

View File

@ -36,6 +36,7 @@ enum DeviceType {
};
class Allocator;
class AbstractDelegate;
class Delegate;
class DeviceInfoContext;
@ -46,37 +47,37 @@ class MS_API Context {
Context();
~Context() = default;
/// \brief Set the number of threads at runtime. Only valid for Lite.
/// \brief Set the number of threads at runtime.
///
/// \param[in] thread_num the number of threads at runtime.
void SetThreadNum(int32_t thread_num);
/// \brief Get the current thread number setting. Only valid for Lite.
/// \brief Get the current thread number setting.
///
/// \return The current thread number setting.
int32_t GetThreadNum() const;
/// \brief Set the parallel number of operators at runtime. Only valid for Lite.
/// \brief Set the parallel number of operators at runtime.
///
/// \param[in] parallel_num the parallel number of operators at runtime.
void SetInterOpParallelNum(int32_t parallel_num);
/// \brief Get the current operators parallel number setting. Only valid for Lite.
/// \brief Get the current operators parallel number setting.
///
/// \return The current operators parallel number setting.
int32_t GetInterOpParallelNum() const;
/// \brief Set the thread affinity to CPU cores. Only valid for Lite.
/// \brief Set the thread affinity to CPU cores.
///
/// \param[in] mode: 0: no affinities, 1: big cores first, 2: little cores first
void SetThreadAffinity(int mode);
/// \brief Get the thread affinity of CPU cores. Only valid for Lite.
/// \brief Get the thread affinity of CPU cores.
///
/// \return Thread affinity to CPU cores. 0: no affinities, 1: big cores first, 2: little cores first
int GetThreadAffinityMode() const;
/// \brief Set the thread lists to CPU cores. Only valid for Lite.
/// \brief Set the thread lists to CPU cores.
///
/// \note If core_list and mode are set by SetThreadAffinity at the same time, the core_list is effective, but the
/// mode is not effective.
@ -84,29 +85,35 @@ class MS_API Context {
/// \param[in] core_list: a vector of thread core lists.
void SetThreadAffinity(const std::vector<int> &core_list);
/// \brief Get the thread lists of CPU cores. Only valid for Lite.
/// \brief Get the thread lists of CPU cores.
///
/// \return core_list: a vector of thread core lists.
std::vector<int32_t> GetThreadAffinityCoreList() const;
/// \brief Set the status whether to perform model inference or training in parallel. Only valid for Lite.
/// \brief Set the status whether to perform model inference or training in parallel.
///
/// \param[in] is_parallel: true, parallel; false, not in parallel.
void SetEnableParallel(bool is_parallel);
/// \brief Get the status whether to perform model inference or training in parallel. Only valid for Lite.
/// \brief Get the status whether to perform model inference or training in parallel.
///
/// \return Bool value that indicates whether in parallel.
bool GetEnableParallel() const;
/// \brief Set Delegate to access third-party AI framework. Only valid for Lite.
/// \brief Set Delegate to access third-party AI framework.
///
/// \param[in] delegate the custom delegate.
void set_delegate(const std::shared_ptr<AbstractDelegate> &delegate);
// deprecated
void SetDelegate(const std::shared_ptr<Delegate> &delegate);
/// \brief Get the delegate of the third-party AI framework. Only valid for Lite.
/// \brief Get the delegate of the third-party AI framework.
///
/// \return Pointer to the custom delegate.
std::shared_ptr<AbstractDelegate> get_delegate() const;
// deprecated
std::shared_ptr<Delegate> GetDelegate() const;
/// \brief Set quant model to run as float model in multi device.

View File

@ -22,7 +22,7 @@
#include <memory>
#include "schema/model_generated.h"
#include "include/api/kernel.h"
#include "include/api/status.h"
#include "include/api/delegate_api.h"
namespace mindspore {
typedef enum {
@ -36,6 +36,7 @@ using KernelIter = std::vector<kernel::Kernel *>::iterator;
template <class T>
class MS_API DelegateModel {
public:
DelegateModel() = default;
/// \brief Constructor of MindSpore Lite DelegateModel.
DelegateModel(std::vector<kernel::Kernel *> *kernels, const std::vector<MSTensor> &inputs,
const std::vector<MSTensor> &outputs, const std::map<kernel::Kernel *, const T *> &primitives,
@ -107,14 +108,14 @@ class MS_API DelegateModel {
SchemaVersion version_;
};
class MS_API Delegate {
// lite delegate use kernel::Kernel as graph node.
using LiteDelegateGraph = DelegateModel<schema::Primitive>;
class Delegate : public IDelegate<LiteDelegateGraph, kernel::Kernel, kernel::Kernel> {
public:
/// \brief Constructor of MindSpore Lite Delegate.
Delegate() = default;
/// \brief Destructor of MindSpore Lite Delegate.
Delegate(const std::vector<mindspore::MSTensor> &inputs, const std::vector<mindspore::MSTensor> &outputs)
: IDelegate<LiteDelegateGraph, kernel::Kernel, kernel::Kernel>(inputs, outputs) {}
virtual ~Delegate() = default;
/// \brief Init delegate.
///
/// \note Init will be called in Model::Build.
@ -122,12 +123,26 @@ class MS_API Delegate {
/// \return Status. If Status is kLiteNotSupport, the program will return to the MindSpore Lite inner inference.
virtual Status Init() = 0;
/// \brief Build delegate graph for MindSpore Lite model.
std::shared_ptr<kernel::Kernel> CreateKernel(const std::shared_ptr<kernel::Kernel> &node) override {
// return node as kernel since they are same one.
return node;
}
bool IsDelegateNode(const std::shared_ptr<kernel::Kernel> &node) override { return false; }
/// \brief Replace the nodes in model with delegate nodes, delegate will create kernels by its delegate nodes.
///
/// \param[in] graph The graph to be built.
void ReplaceNodes(const std::shared_ptr<LiteDelegateGraph> &graph) override {}
/// \brief Build delegate graph for MindSpore model.
///
/// \note Build will be called in Model::Build.
///
/// \param[in] model Define the delegate model to be built.
virtual Status Build(DelegateModel<schema::Primitive> *model) = 0;
///
/// \note deprecated, use ReplaceNodes and CreateKernel to build delegate model.
virtual Status Build(LiteDelegateGraph *model) = 0;
};
class MS_API CoreMLDelegate : public Delegate {
@ -147,7 +162,7 @@ class MS_API CoreMLDelegate : public Delegate {
/// \note Build will be called in Model::Build.
///
/// \param[in] model Define the delegate model to be built.
Status Build(DelegateModel<schema::Primitive> *model) override;
Status Build(LiteDelegateGraph *model) override;
protected:
std::shared_ptr<Delegate> impl_;

View File

@ -0,0 +1,75 @@
/**
* Copyright 2022 Huawei Technologies Co., Ltd
*
* 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 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.
*/
#ifndef MINDSPORE_INCLUDE_API_DELEGATE_API_H
#define MINDSPORE_INCLUDE_API_DELEGATE_API_H
#include <map>
#include <vector>
#include <memory>
#include "include/api/status.h"
#include "include/api/types.h"
namespace mindspore {
class AbstractDelegate {
public:
AbstractDelegate() = default;
AbstractDelegate(const std::vector<mindspore::MSTensor> &inputs, const std::vector<mindspore::MSTensor> &outputs)
: inputs_(inputs), outputs_(outputs) {}
virtual ~AbstractDelegate() = default;
/// \brief Get the input tensors of DelegateModel.
///
/// \return The input tensor vector of DelegateModel.
const std::vector<mindspore::MSTensor> &inputs() { return this->inputs_; }
/// \brief Get the output tensors of DelegateModel.
///
/// \return The ioutput tensor vector of DelegateModel.
const std::vector<mindspore::MSTensor> &outputs() { return this->outputs_; }
protected:
std::vector<mindspore::MSTensor> inputs_;
std::vector<mindspore::MSTensor> outputs_;
};
template <typename Graph, typename Node, typename Kernel>
class IDelegate : public AbstractDelegate {
public:
IDelegate() = default;
IDelegate(const std::vector<mindspore::MSTensor> &inputs, const std::vector<mindspore::MSTensor> &outputs)
: AbstractDelegate(inputs, outputs) {}
virtual ~IDelegate() = default;
/// \brief Replace the nodes in model with delegate nodes, delegate will create kernels by its delegate nodes.
///
/// \param[in] graph The graph to be built.
virtual void ReplaceNodes(const std::shared_ptr<Graph> &graph) = 0;
/// \brief Check if this node is belong to this delegate.
///
/// \param[in] node The node need to be checked.
///
/// \return True if the node is belong to this delegate, otherwise return false.
virtual bool IsDelegateNode(const std::shared_ptr<Node> &node) = 0;
/// \brief Create a delegate kernel if the node is a delegate node.
///
/// \param[in] node Define the delegate model to be built.
///
/// \return The delegate kernel, if the node is not a delegate node, return nullptr.
virtual std::shared_ptr<Kernel> CreateKernel(const std::shared_ptr<Node> &node) = 0;
};
} // namespace mindspore
#endif // MINDSPORE_INCLUDE_API_DELEGATE_API_H

View File

@ -14,8 +14,8 @@
* limitations under the License.
*/
#ifndef MINDSPORE_INCLUDE_API_KERNEL_H
#define MINDSPORE_INCLUDE_API_KERNEL_H
#ifndef MINDSPORE_LITE_INCLUDE_KERNEL_H
#define MINDSPORE_LITE_INCLUDE_KERNEL_H
#include <vector>
#include <string>
#include <utility>
@ -23,75 +23,18 @@
#include "schema/model_generated.h"
#include "include/api/types.h"
#include "include/api/context.h"
#include "include/api/kernel_api.h"
namespace mindspore::kernel {
/// \brief The Kernel class is used to define a MindSpore Kernel.
class MS_API Kernel {
class MS_API Kernel : public IKernel<schema::Primitive> {
public:
Kernel() = default;
/// \brief Constructor.
///
/// \param[in] inputs define the input tensors for kernel.
/// \param[in] outputs define the output tensors for kernel.
/// \param[in] primitive define the primitive of kernel generated by flatbuffers.
/// \param[in] ctx define the context for kernel.
Kernel(const std::vector<mindspore::MSTensor> &inputs, const std::vector<mindspore::MSTensor> &outputs,
const schema::Primitive *primitive, const mindspore::Context *ctx)
: context_(ctx), inputs_(std::move(inputs)), outputs_(std::move(outputs)), primitive_(primitive) {
: IKernel<schema::Primitive>(inputs, outputs, primitive, ctx) {
Initialize();
}
/// \brief Destructor.
virtual ~Kernel() = default;
/// \brief prepare for executing kernel.
///
/// \return result code.
virtual int Prepare() = 0;
/// \brief execute the kernel.
///
/// \return result code.
virtual int Execute() = 0;
/// \brief resize the kernel input shape, memory need to refresh.
///
/// \return result code.
virtual int ReSize() = 0;
/// \brief set kernel's input tensors.
///
/// \param[in] in_tensors define the input tensors.
virtual void set_inputs(const std::vector<mindspore::MSTensor> &in_tensors) { this->inputs_ = in_tensors; }
/// \brief set kernel's input tensor.
///
/// \param[in] in_tensor define the input tensor.
/// \param[in] index define the index of the input tensor.
virtual void set_input(mindspore::MSTensor in_tensor, int index) { this->inputs_[index] = in_tensor; }
/// \brief set kernel's output tensors.
///
/// \param[in] out_tensors define the output tensors.
virtual void set_outputs(const std::vector<mindspore::MSTensor> &out_tensors) { this->outputs_ = out_tensors; }
/// \brief set kernel's output tensor.
///
/// \param[in] out_tensor define the output tensor.
/// \param[in] index define the index of the output tensor.
virtual void set_output(mindspore::MSTensor out_tensor, int index) { this->outputs_[index] = out_tensor; }
/// \brief obtain kernel's input tensors.
///
/// \return input tensors.
virtual const std::vector<mindspore::MSTensor> &inputs() { return this->inputs_; }
/// \brief obtain kernel's output tensors.
///
/// \return output tensors.
virtual const std::vector<mindspore::MSTensor> &outputs() { return this->outputs_; }
/// \brief obtain kernel's name.
///
/// \return kernel's name.
std::string name() const { return this->name_; }
/// \brief set kernel's name.
///
/// \param[in] name define the kernel's name.
void set_name(const std::string &name) { this->name_ = name; }
/// \brief obtain kernel's context.
///
/// \return kernel's context.
const mindspore::Context *context() const { return this->context_; }
/// \brief obtain kernel's type.
///
/// \return kernel's type.
@ -101,61 +44,13 @@ class MS_API Kernel {
/// \return kernel's quant type.
virtual schema::QuantType quant_type() const { return quant_type_; }
/// \brief obtain the primitive of kernel generated by flatbuffers.
///
/// \return the primitive of kernel generated by flatbuffers.
const schema::Primitive *primitive() const { return this->primitive_; }
/// \brief get kernel's attribute.
///
/// \param[in] key define the kernel's attribute key.
std::string GetAttr(const std::string &key) const {
auto iter = attrs_.find(key);
if (iter != attrs_.end()) {
return iter->second;
}
return "";
}
/// \brief set kernel's config.
///
/// \param[in] config define the kernel's config.
void SetConfig(const std::map<std::string, std::map<std::string, std::string>> *config) {
config_ = config;
}
/// \brief set kernel's config.
///
/// \param[in] section define the section of the kernel's config.
std::map<std::string, std::string> GetConfig(const std::string &section) const {
if (config_ == nullptr) {
return std::map<std::string, std::string>();
}
auto iter = config_->find(section);
if (iter != config_->end()) {
return iter->second;
}
return std::map<std::string, std::string>();
}
protected:
void Initialize();
protected:
/// \brief set kernel's attribute
///
/// \param[in] key define the kernel's attribute key.
/// \param[in] value define the kernel's attribute value.
void SetAttr(const std::string &key, const std::string &value) { attrs_[key] = value; }
std::string name_;
const mindspore::Context *context_ = nullptr;
std::vector<mindspore::MSTensor> inputs_;
std::vector<mindspore::MSTensor> outputs_;
schema::PrimitiveType type_ = schema::PrimitiveType_NONE;
const schema::Primitive *primitive_ = nullptr;
std::map<std::string, std::string> attrs_;
const std::map<std::string, std::map<std::string, std::string>> *config_;
schema::QuantType quant_type_ = schema::QuantType_QUANT_NONE;
private:
void Initialize();
};
} // namespace mindspore::kernel
#endif // MINDSPORE_INCLUDE_API_KERNEL_H
#endif // MINDSPORE_LITE_INCLUDE_KERNEL_H

143
include/api/kernel_api.h Normal file
View File

@ -0,0 +1,143 @@
/**
* Copyright 2022 Huawei Technologies Co., Ltd
*
* 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.
*/
#ifndef MINDSPORE_INCLUDE_API_KERNEL_API_H
#define MINDSPORE_INCLUDE_API_KERNEL_API_H
#include <vector>
#include <string>
#include <utility>
#include <map>
#include "include/api/types.h"
namespace mindspore {
class Context;
namespace kernel {
/// \brief The Kernel class is used to define a MindSpore Kernel.
template <typename Primitive>
class MS_API IKernel {
public:
IKernel() = default;
/// \brief Constructor.
///
/// \param[in] inputs define the input tensors for kernel.
/// \param[in] outputs define the output tensors for kernel.
/// \param[in] primitive define the primitive of kernel.
/// \param[in] ctx define the context for kernel.
IKernel(const std::vector<mindspore::MSTensor> &inputs, const std::vector<mindspore::MSTensor> &outputs,
const Primitive *primitive, const mindspore::Context *ctx)
: context_(ctx), inputs_(std::move(inputs)), outputs_(std::move(outputs)), primitive_(primitive) {}
/// \brief Destructor.
virtual ~IKernel() = default;
/// \brief prepare for executing kernel.
///
/// \return result code.
virtual int Prepare() = 0;
/// \brief execute the kernel.
///
/// \return result code.
virtual int Execute() = 0;
/// \brief resize the kernel input shape, memory need to refresh.
///
/// \return result code.
virtual int ReSize() = 0;
/// \brief set kernel's input tensors.
///
/// \param[in] in_tensors define the input tensors.
virtual void set_inputs(const std::vector<mindspore::MSTensor> &in_tensors) { this->inputs_ = in_tensors; }
/// \brief set kernel's input tensor.
///
/// \param[in] in_tensor define the input tensor.
/// \param[in] index define the index of the input tensor.
virtual void set_input(mindspore::MSTensor in_tensor, int index) { this->inputs_[index] = in_tensor; }
/// \brief set kernel's output tensors.
///
/// \param[in] out_tensors define the output tensors.
virtual void set_outputs(const std::vector<mindspore::MSTensor> &out_tensors) { this->outputs_ = out_tensors; }
/// \brief set kernel's output tensor.
///
/// \param[in] out_tensor define the output tensor.
/// \param[in] index define the index of the output tensor.
virtual void set_output(mindspore::MSTensor out_tensor, int index) { this->outputs_[index] = out_tensor; }
/// \brief obtain kernel's input tensors.
///
/// \return input tensors.
virtual const std::vector<mindspore::MSTensor> &inputs() { return this->inputs_; }
/// \brief obtain kernel's output tensors.
///
/// \return output tensors.
virtual const std::vector<mindspore::MSTensor> &outputs() { return this->outputs_; }
/// \brief obtain kernel's name.
///
/// \return kernel's name.
std::string name() const { return this->name_; }
/// \brief set kernel's name.
///
/// \param[in] name define the kernel's name.
void set_name(const std::string &name) { this->name_ = name; }
/// \brief obtain kernel's context.
///
/// \return kernel's context.
const mindspore::Context *context() const { return this->context_; }
///
/// \return the primitive of kernel generated by flatbuffers.
const Primitive *primitive() const { return this->primitive_; }
/// \brief get kernel's attribute.
///
/// \param[in] key define the kernel's attribute key.
std::string GetAttr(const std::string &key) const {
auto iter = attrs_.find(key);
if (iter != attrs_.end()) {
return iter->second;
}
return "";
}
/// \brief set kernel's config.
///
/// \param[in] config define the kernel's config.
void SetConfig(const std::map<std::string, std::map<std::string, std::string>> *config) { config_ = config; }
/// \brief set kernel's config.
///
/// \param[in] section define the section of the kernel's config.
std::map<std::string, std::string> GetConfig(const std::string &section) const {
if (config_ == nullptr) {
return std::map<std::string, std::string>();
}
auto iter = config_->find(section);
if (iter != config_->end()) {
return iter->second;
}
return std::map<std::string, std::string>();
}
protected:
/// \brief set kernel's attribute
///
/// \param[in] key define the kernel's attribute key.
/// \param[in] value define the kernel's attribute value.
void SetAttr(const std::string &key, const std::string &value) { attrs_[key] = value; }
std::string name_;
const mindspore::Context *context_ = nullptr;
std::vector<mindspore::MSTensor> inputs_;
std::vector<mindspore::MSTensor> outputs_;
const Primitive *primitive_ = nullptr;
std::map<std::string, std::string> attrs_;
const std::map<std::string, std::map<std::string, std::string>> *config_;
};
} // namespace kernel
} // namespace mindspore
#endif // MINDSPORE_INCLUDE_API_KERNEL_API_H

View File

@ -48,7 +48,7 @@ class MS_API Model {
Model(const Model &) = delete;
void operator=(const Model &) = delete;
/// \brief Build a model from model buffer so that it can run on a device. Only valid for Lite.
/// \brief Build a model from model buffer so that it can run on a device.
///
/// \param[in] model_data Define the buffer read from a model file.
/// \param[in] data_size Define bytes number of model buffer.
@ -60,7 +60,7 @@ class MS_API Model {
Status Build(const void *model_data, size_t data_size, ModelType model_type,
const std::shared_ptr<Context> &model_context = nullptr);
/// \brief Load and build a model from model buffer so that it can run on a device. Only valid for Lite.
/// \brief Load and build a model from model buffer so that it can run on a device.
///
/// \param[in] model_path Define the model path.
/// \param[in] model_type Define The type of model file. Options: ModelType::kMindIR, ModelType::kOM. Only
@ -71,7 +71,7 @@ class MS_API Model {
inline Status Build(const std::string &model_path, ModelType model_type,
const std::shared_ptr<Context> &model_context = nullptr);
/// \brief Build a model from model buffer so that it can run on a device. Only valid for Lite.
/// \brief Build a model from model buffer so that it can run on a device.
///
/// \param[in] model_data Define the buffer read from a model file.
/// \param[in] data_size Define bytes number of model buffer.
@ -87,7 +87,7 @@ class MS_API Model {
const std::shared_ptr<Context> &model_context, const Key &dec_key, const std::string &dec_mode,
const std::string &cropto_lib_path);
/// \brief Load and build a model from model buffer so that it can run on a device. Only valid for Lite.
/// \brief Load and build a model from model buffer so that it can run on a device.
///
/// \param[in] model_path Define the model path.
/// \param[in] model_type Define The type of model file. Options: ModelType::kMindIR, ModelType::kOM. Only

View File

@ -85,7 +85,7 @@ class MS_API ModelParallelRunner {
ModelParallelRunner() = default;
~ModelParallelRunner() = default;
/// \brief build a model parallel runner from model path so that it can run on a device. Only valid for Lite.
/// \brief build a model parallel runner from model path so that it can run on a device.
///
/// \param[in] model_path Define the model path.
/// \param[in] runner_config Define the config used to store options during model pool init.
@ -93,7 +93,7 @@ class MS_API ModelParallelRunner {
/// \return Status.
inline Status Init(const std::string &model_path, const std::shared_ptr<RunnerConfig> &runner_config = nullptr);
/// \brief build a model parallel runner from model buffer so that it can run on a device. Only valid for Lite.
/// \brief build a model parallel runner from model buffer so that it can run on a device.
///
/// \param[in] model_data Define the buffer read from a model file.
/// \param[in] data_size Define bytes number of model buffer.

View File

@ -215,42 +215,42 @@ class MS_API MSTensor {
/// \return The boolean value that indicates whether the MSTensor not equals tensor.
bool operator!=(const MSTensor &tensor) const;
/// \brief Set the shape of for the MSTensor. Only valid for Lite.
/// \brief Set the shape of for the MSTensor.
///
/// \param[in] shape Shape of the MSTensor, a vector of int64_t.
void SetShape(const std::vector<int64_t> &shape);
/// \brief Set the data type for the MSTensor. Only valid for Lite.
/// \brief Set the data type for the MSTensor.
///
/// \param[in] data_type The data type of the MSTensor.
void SetDataType(enum DataType data_type);
/// \brief Set the name for the MSTensor. Only valid for Lite.
/// \brief Set the name for the MSTensor.
///
/// \param[in] name The name of the MSTensor.
inline void SetTensorName(const std::string &name);
/// \brief Set the Allocator for the MSTensor. Only valid for Lite.
/// \brief Set the Allocator for the MSTensor.
///
/// \param[in] allocator A pointer to Allocator.
void SetAllocator(std::shared_ptr<Allocator> allocator);
/// \brief Obtain the Allocator of the MSTensor. Only valid for Lite.
/// \brief Obtain the Allocator of the MSTensor.
///
/// \return A pointer to Allocator.
std::shared_ptr<Allocator> allocator() const;
/// \brief Set the format for the MSTensor. Only valid for Lite.
/// \brief Set the format for the MSTensor.
///
/// \param[in] format The format of the MSTensor.
void SetFormat(mindspore::Format format);
/// \brief Obtain the format of the MSTensor. Only valid for Lite.
/// \brief Obtain the format of the MSTensor.
///
/// \return The format of the MSTensor.
mindspore::Format format() const;
/// \brief Set the data for the MSTensor. Only valid for Lite.
/// \brief Set the data for the MSTensor.
///
/// \note Deprecated, this interface will be removed in the next iteration
///
@ -274,12 +274,12 @@ class MS_API MSTensor {
/// \return A pointer to the device data of the MSTensor.
void *GetDeviceData();
/// \brief Get the quantization parameters of the MSTensor. Only valid for Lite.
/// \brief Get the quantization parameters of the MSTensor.
///
/// \return The quantization parameters of the MSTensor.
std::vector<QuantParam> QuantParams() const;
/// \brief Set the quantization parameters for the MSTensor. Only valid for Lite.
/// \brief Set the quantization parameters for the MSTensor.
///
/// \param[in] quant_params The quantization parameters of the MSTensor.
void SetQuantParams(std::vector<QuantParam> quant_params);

View File

@ -45,12 +45,12 @@ typedef struct MSCallBackParamC {
typedef bool (*MSKernelCallBackC)(const MSTensorHandleArray inputs, const MSTensorHandleArray outputs,
const MSCallBackParamC kernel_Info);
/// \brief Create a model object. Only valid for Lite.
/// \brief Create a model object.
///
/// \return Model object handle.
MS_API MSModelHandle MSModelCreate();
/// \brief Destroy the model object. Only valid for Lite.
/// \brief Destroy the model object.
///
/// \param[in] model Model object handle address.
MS_API void MSModelDestroy(MSModelHandle *model);
@ -62,7 +62,7 @@ MS_API void MSModelDestroy(MSModelHandle *model);
/// \param[in] workspace_size Define the workspace size.
MS_API void MSModelSetWorkspace(MSModelHandle model, void *workspace, size_t workspace_size);
/// \brief Build the model from model file buffer so that it can run on a device. Only valid for Lite.
/// \brief Build the model from model file buffer so that it can run on a device.
///
/// \param[in] model Model object handle.
/// \param[in] model_data Define the buffer read from a model file.
@ -74,7 +74,7 @@ MS_API void MSModelSetWorkspace(MSModelHandle model, void *workspace, size_t wor
MS_API MSStatus MSModelBuild(MSModelHandle model, const void *model_data, size_t data_size, MSModelType model_type,
const MSContextHandle model_context);
/// \brief Load and build the model from model path so that it can run on a device. Only valid for Lite.
/// \brief Load and build the model from model path so that it can run on a device.
///
/// \param[in] model Model object handle.
/// \param[in] model_path Define the model file path.

View File

@ -54,7 +54,7 @@ public class ModelParallelRunner {
}
/**
* Build a model runner from model path so that it can run on a device. Only valid for Lite.
* Build a model runner from model path so that it can run on a device.
*
* @param modelPath the model path.
* @param runnerConfig the RunnerConfig Object.
@ -69,7 +69,7 @@ public class ModelParallelRunner {
}
/**
* Build a model runner from model path so that it can run on a device. Only valid for Lite.
* Build a model runner from model path so that it can run on a device.
*
* @param modelPath the model path.
* @return init status.
@ -83,7 +83,7 @@ public class ModelParallelRunner {
}
/**
* Build a model runner from model path so that it can run on a device. Only valid for Lite.
* Build a model runner from model path so that it can run on a device.
*
* @param inputs inputs A vector where model inputs are arranged in sequence.
* @param outputs outputs Which is a pointer to a vector. The model outputs are filled in the container in sequence.

View File

@ -128,7 +128,7 @@ public class MSContext {
}
/**
* set the number of threads at runtime. Only valid for Lite.
* set the number of threads at runtime.
* If you haven't init context before, it will do nothing.
*
* @param threadNum the number of threads at runtime.
@ -142,7 +142,7 @@ public class MSContext {
}
/**
* get the current thread number setting. Only valid for Lite.
* get the current thread number setting.
* If you haven't init context, it will return {@value ERROR_VALUE}.
*
* @return The current thread number setting.
@ -158,7 +158,7 @@ public class MSContext {
}
/**
* set the parallel number of operators at runtime. Only valid for Lite.
* set the parallel number of operators at runtime.
* If you haven't init context before, it will do nothing.
*
* @param parallelNum parallelNum the parallel number of operators at runtime.
@ -172,7 +172,7 @@ public class MSContext {
}
/**
* get the current operators parallel number setting. Only valid for Lite.
* get the current operators parallel number setting.
* If you haven't init context, it will return {@value ERROR_VALUE}.
*
* @return The current operators parallel number setting.
@ -188,7 +188,7 @@ public class MSContext {
}
/**
* set the thread affinity to CPU cores. Only valid for Lite.
* set the thread affinity to CPU cores.
* If you haven't init context before, it will do nothing.
*
* @param mode: 0: no affinities, 1: big cores first, 2: little cores first
@ -203,7 +203,7 @@ public class MSContext {
/**
* get the thread affinity of CPU cores. Only valid for Lite.
* get the thread affinity of CPU cores.
* If you haven't init context, it will return {@value ERROR_VALUE}.
*
* @return Thread affinity to CPU cores. 0: no affinities, 1: big cores first, 2: little cores first
@ -219,7 +219,7 @@ public class MSContext {
}
/**
* set the thread lists to CPU cores. Only valid for Lite.
* set the thread lists to CPU cores.
* If coreList and mode are set by setThreadAffinity at the same time, the coreList is effective, but the
* mode is not effective.
* If you haven't init context before, it will do nothing.
@ -240,7 +240,7 @@ public class MSContext {
}
/**
* get the thread lists of CPU cores. Only valid for Lite.
* get the thread lists of CPU cores.
* If you haven't init context, it will return {@value ERROR_VALUE}.
*
* @return An {@code ArrayList<Integer>} of thread core lists.
@ -257,7 +257,7 @@ public class MSContext {
}
/**
* set the status whether to perform model inference or training in parallel. Only valid for Lite.
* set the status whether to perform model inference or training in parallel.
* If you haven't init context before, it will do nothing.
*
* @param isParallel: true, parallel; false, not in parallel.
@ -271,7 +271,7 @@ public class MSContext {
}
/**
* get the status whether to perform model inference or training in parallel. Only valid for Lite.
* get the status whether to perform model inference or training in parallel.
* If you haven't init context, it will also return false.
*
* @return boolean value that indicates whether in parallel.

View File

@ -38,25 +38,24 @@ if(MSLITE_ENABLE_CLOUD_FUSION_INFERENCE)
${CMAKE_CURRENT_SOURCE_DIR}/../litert/pack_weight_manager.cc
${CMAKE_CURRENT_SOURCE_DIR}/dynamic_mem_allocator.cc
${CMAKE_CURRENT_SOURCE_DIR}/dynamic_mem_manager.cc
${CMAKE_CURRENT_SOURCE_DIR}/subgraph_kernel.cc
${CMAKE_CURRENT_SOURCE_DIR}/numa_adapter.cc
${CMAKE_CURRENT_SOURCE_DIR}/kernel/cpu/less_test_kernel_mod.cc
${CMAKE_CURRENT_SOURCE_DIR}/kernel/cpu/transpose_kernel_mod.cc
${CMAKE_CURRENT_SOURCE_DIR}/infer_session.cc
${CMAKE_CURRENT_SOURCE_DIR}/single_op_session.cc
${CMAKE_CURRENT_SOURCE_DIR}/session/single_op_session.cc
${CMAKE_CURRENT_SOURCE_DIR}/infer_device_address.cc
${CMAKE_CURRENT_SOURCE_DIR}/utils/kernel_build_utils.cc
${CMAKE_CURRENT_SOURCE_DIR}/utils/kernel_graph_utils.cc
${CMAKE_CURRENT_SOURCE_DIR}/utils/tensor_utils.cc
${CMAKE_CURRENT_SOURCE_DIR}/utils/runtime_utils.cc
${CMAKE_CURRENT_SOURCE_DIR}/delegate/graph_executor/delegate.cc
${CMAKE_CURRENT_SOURCE_DIR}/session/delegate_session.cc
${CMAKE_CURRENT_SOURCE_DIR}/session/graph_executor_session.cc
${CMAKE_CURRENT_SOURCE_DIR}/session/factory.cc
${CMAKE_CURRENT_SOURCE_DIR}/delegate/factory.cc
${CMAKE_CURRENT_SOURCE_DIR}/delegate/graph_executor/factory.cc
${CMAKE_CURRENT_SOURCE_DIR}/delegate/plugin/tensorrt_executor_plugin.cc
${CMAKE_CURRENT_SOURCE_DIR}/delegate/tensorrt/distribution/distribution_base.cc
${CMAKE_CURRENT_SOURCE_DIR}/session/lite_infer_session.cc
${CMAKE_CURRENT_SOURCE_DIR}/delegate_graph_executor.cc
)
# when cpu kernel is need
#if(NOT MSLITE_ENABLE_ACL)

View File

@ -1,60 +0,0 @@
/**
* Copyright 2020 Huawei Technologies Co., Ltd
*
* 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 "extendrt/acl/acl_env_guard.h"
#include "utils/log_adapter.h"
#include "acl/acl.h"
namespace mindspore {
std::weak_ptr<AclEnvGuard> AclEnvGuard::global_acl_env_;
std::mutex AclEnvGuard::global_acl_env_mutex_;
AclEnvGuard::AclEnvGuard() {
errno_ = aclInit(nullptr);
if (errno_ != ACL_ERROR_NONE && errno_ != ACL_ERROR_REPEAT_INITIALIZE) {
MS_LOG(ERROR) << "Execute aclInit Failed";
return;
}
MS_LOG(INFO) << "Acl init success";
}
AclEnvGuard::~AclEnvGuard() {
errno_ = aclFinalize();
if (errno_ != ACL_ERROR_NONE && errno_ != ACL_ERROR_REPEAT_FINALIZE) {
MS_LOG(ERROR) << "Finalize acl failed";
}
MS_LOG(INFO) << "Acl finalize success";
}
std::shared_ptr<AclEnvGuard> AclEnvGuard::GetAclEnv() {
std::shared_ptr<AclEnvGuard> acl_env;
std::lock_guard<std::mutex> lock(global_acl_env_mutex_);
acl_env = global_acl_env_.lock();
if (acl_env != nullptr) {
MS_LOG(INFO) << "Acl has been initialized, skip.";
} else {
acl_env = std::make_shared<AclEnvGuard>();
aclError ret = acl_env->GetErrno();
if (ret != ACL_ERROR_NONE && ret != ACL_ERROR_REPEAT_INITIALIZE) {
MS_LOG(ERROR) << "Execute aclInit Failed";
return nullptr;
}
global_acl_env_ = acl_env;
MS_LOG(INFO) << "Acl init success";
}
return acl_env;
}
} // namespace mindspore

View File

@ -1,37 +0,0 @@
/**
* Copyright 2020 Huawei Technologies Co., Ltd
*
* 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.
*/
#ifndef MINDSPORE_LITE_SRC_EXTENDRT_CXX_API_GRAPH_ACL_ACL_ENV_GUARD_H_
#define MINDSPORE_LITE_SRC_EXTENDRT_CXX_API_GRAPH_ACL_ACL_ENV_GUARD_H_
#include <memory>
#include <mutex>
#include "acl/acl_base.h"
namespace mindspore {
class __attribute__((visibility("default"))) AclEnvGuard {
public:
explicit AclEnvGuard();
~AclEnvGuard();
aclError GetErrno() const { return errno_; }
static std::shared_ptr<AclEnvGuard> GetAclEnv();
private:
static std::weak_ptr<AclEnvGuard> global_acl_env_;
static std::mutex global_acl_env_mutex_;
aclError errno_;
};
} // namespace mindspore
#endif // MINDSPORE_LITE_SRC_EXTENDRT_CXX_API_GRAPH_ACL_ACL_ENV_GUARD_H_

View File

@ -1,323 +0,0 @@
/**
* Copyright 2020 Huawei Technologies Co., Ltd
*
* 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 "extendrt/acl/acl_infer.h"
#include "include/api/context.h"
#include "extendrt/acl/model_converter.h"
#include "utils/log_adapter.h"
#include "mindspore/core/utils/convert_utils_base.h"
#include "extendrt/acl/acl_utils.h"
namespace mindspore {
AclInferExecutor::AclInferExecutor()
: init_flag_(false),
load_flag_(false),
device_type_("AscendCL"),
device_id_(0),
context_(nullptr),
acl_env_(nullptr) {}
AclInferExecutor::~AclInferExecutor() {
try {
(void)FinalizeEnv();
} catch (const std::exception &e) {
MS_LOG(ERROR) << "AclInferExecutor destructor run failed, error message : " << e.what();
} catch (...) {
MS_LOG(ERROR) << "AclInferExecutor destructor run failed, unknown error occurred.";
}
}
Status AclInferExecutor::Run(const std::vector<MSTensor> &inputs, std::vector<MSTensor> *outputs) {
MS_EXCEPTION_IF_NULL(outputs);
Status ret = Load(IntToUint(device_id_));
if (ret != kSuccess) {
MS_LOG(ERROR) << "Prepare model resource failed.";
return ret;
}
return model_process_.PredictFromHost(inputs, outputs);
}
std::vector<MSTensor> AclInferExecutor::GetInputs() {
Status ret = Load(IntToUint(device_id_));
if (ret != kSuccess) {
MS_LOG(ERROR) << "Prepare model resource failed.";
return {};
}
return model_process_.GetInputs();
}
std::vector<MSTensor> AclInferExecutor::GetOutputs() {
Status ret = Load(IntToUint(device_id_));
if (ret != kSuccess) {
MS_LOG(ERROR) << "Prepare model resource failed.";
return {};
}
return model_process_.GetOutputs();
}
Status AclInferExecutor::LoadAclModel(const Buffer om_data) {
MS_LOG(INFO) << "Start load acl model.";
// acl load model
uint32_t acl_model_id;
auto acl_ret = aclmdlLoadFromMem(om_data.Data(), om_data.DataSize(), &acl_model_id);
if (acl_ret != ACL_ERROR_NONE) {
MS_LOG(ERROR) << "Call aclmdlLoadFromMem failed.";
return kMCDeviceError;
}
// acl init model resource
model_process_.set_model_id(acl_model_id);
Status ret = model_process_.PreInitModelResource();
if (ret != kSuccess) {
(void)aclmdlUnload(acl_model_id);
MS_LOG(ERROR) << "Pre init model resource failed.";
return ret;
}
MS_LOG(INFO) << "Load acl model success.";
return kSuccess;
}
Status AclInferExecutor::InitEnv() {
if (init_flag_) {
return kSuccess;
}
acl_env_ = AclEnvGuard::GetAclEnv();
if (acl_env_ == nullptr) {
MS_LOG(ERROR) << "Acl init failed.";
return kMCDeviceError;
}
aclError ret = aclrtSetDevice(device_id_);
if (ret != ACL_ERROR_NONE) {
MS_LOG(EXCEPTION) << "Device " << device_id_ << " call aclrtSetDevice failed, ret[" << static_cast<int>(ret) << "]";
}
MS_LOG(INFO) << "Open device " << device_id_ << " success";
ret = aclrtCreateContext(&context_, device_id_);
if (ret != ACL_ERROR_NONE) {
MS_LOG(ERROR) << "Acl create context failed";
return kMCDeviceError;
}
MS_LOG(INFO) << "Create context success";
aclrtRunMode run_mode;
ret = aclrtGetRunMode(&run_mode);
if (ret != ACL_ERROR_NONE) {
MS_LOG(ERROR) << "Acl get run mode failed";
return kMCDeviceError;
}
bool is_device = (run_mode == ACL_DEVICE);
model_process_.SetIsDevice(is_device);
MS_LOG(INFO) << "Get run mode success is device input/output " << is_device;
MS_LOG(INFO) << "Init acl success, device id " << device_id_;
init_flag_ = true;
return kSuccess;
}
Status AclInferExecutor::FinalizeEnv() {
if (!init_flag_) {
return kSuccess;
}
aclError rt_ret = aclrtSetCurrentContext(context_);
if (rt_ret != ACL_ERROR_NONE) {
MS_LOG(ERROR) << "Set the ascend device context failed";
return kMCDeviceError;
}
Status ret = model_process_.UnLoad();
if (ret != kSuccess) {
MS_LOG(ERROR) << "Unload model inner failed.";
return ret;
}
if (context_ != nullptr) {
rt_ret = aclrtDestroyContext(context_);
if (rt_ret != ACL_ERROR_NONE) {
MS_LOG(ERROR) << "Destroy context failed";
}
context_ = nullptr;
}
MS_LOG(INFO) << "End to destroy context";
rt_ret = aclrtResetDevice(device_id_);
if (rt_ret != ACL_ERROR_NONE) {
MS_LOG(ERROR) << "Reset device " << device_id_ << " failed";
}
MS_LOG(INFO) << "End to reset device " << device_id_;
init_flag_ = false;
return kSuccess;
}
Status AclInferExecutor::Build() {
MS_LOG(INFO) << "Start build model.";
MS_EXCEPTION_IF_NULL(graph_);
if (graph_cell_ != nullptr) {
MS_LOG(INFO) << "This model has been built, skip.";
return kSuccess;
}
std::shared_ptr<AclModelOptions> options = std::make_shared<AclModelOptions>(model_context_);
MS_EXCEPTION_IF_NULL(options);
if (graph_cell_ == nullptr && graph_->ModelType() == ModelType::kOM) {
MS_LOG(INFO) << "Load om model and all build options will be ignored.";
graph_cell_ = std::make_shared<GraphCell>(graph_);
MS_EXCEPTION_IF_NULL(graph_cell_);
auto ret = graph_cell_->Load(options->GetDeviceID());
if (ret != kSuccess) {
MS_LOG(ERROR) << "Load failed.";
return ret;
}
options_ = std::move(options);
return kSuccess;
}
std::string options_key = options->GenAclOptionsKey();
std::shared_ptr<Graph> graph;
if (auto iter = dynamic_size_graph_map_.find(options_key); iter != dynamic_size_graph_map_.end()) {
MS_LOG(INFO) << "This options has been built, read cache.";
graph = iter->second;
} else {
auto func_graph = ModelImpl::GetFuncGraph();
MS_EXCEPTION_IF_NULL(func_graph);
auto inputs = func_graph->parameters();
std::vector<std::string> input_names;
for (auto node : inputs) {
auto para = node->cast<ParameterPtr>();
MS_EXCEPTION_IF_NULL(para);
std::string name = para->name();
for (auto pos = name.find(':'); pos != std::string::npos; pos = name.find(':')) {
name = name.substr(0, pos) + "_" + name.substr(pos + 1);
MS_LOG(INFO) << name;
}
para->set_name(name);
input_names.push_back(name);
}
options->RenameInput(input_names);
MS_EXCEPTION_IF_NULL(func_graph);
model_converter_.set_options(options);
auto om_data = model_converter_.LoadMindIR(func_graph);
if (om_data.Data() == nullptr || om_data.DataSize() == 0) {
MS_LOG(ERROR) << "Load MindIR failed.";
return kMCFailed;
}
graph = std::make_shared<Graph>(std::make_shared<Graph::GraphData>(om_data, ModelType::kOM));
dynamic_size_graph_map_[options_key] = graph;
}
MS_EXCEPTION_IF_NULL(graph);
auto graph_cell = std::make_shared<GraphCell>(graph);
MS_EXCEPTION_IF_NULL(graph_cell);
auto ret = graph_cell->Load(options->GetDeviceID());
if (ret != kSuccess) {
MS_LOG(ERROR) << "Load failed.";
return ret;
}
// save result
graph_cell_ = graph_cell;
options_ = std::move(options);
MS_LOG(INFO) << "Build model success.";
return kSuccess;
}
Status AclInferExecutor::Load(uint32_t device_id) {
// check graph type
if (graph_->ModelType() != ModelType::kOM) {
Status ret = ConvertToOM();
if (ret != kSuccess) {
MS_LOG(ERROR) << "Load Failed.";
return ret;
}
}
const auto &graph_data = GraphImpl::MutableGraphData();
MS_EXCEPTION_IF_NULL(graph_data);
auto om_data = graph_data->GetOMData();
// init
device_id_ = UintToInt(device_id);
Status ret = InitEnv();
if (ret != kSuccess) {
MS_LOG(ERROR) << "InitEnv failed.";
return ret;
}
// load model
if (!load_flag_) {
ret = LoadAclModel(om_data);
if (ret != kSuccess) {
MS_LOG(ERROR) << "Load acl model failed.";
return ret;
}
load_flag_ = true;
}
aclError rt_ret = aclrtSetCurrentContext(context_);
if (rt_ret != ACL_ERROR_NONE) {
MS_LOG(ERROR) << "Set the ascend device context failed";
return kMCDeviceError;
}
return kSuccess;
}
Status AclInferExecutor::ConvertToOM() {
MS_LOG(INFO) << "Start convert to om model.";
if (graph_ == nullptr) {
MS_LOG(ERROR) << "Invalid graph_ is null.";
return kMCFailed;
}
auto &graph_data = GraphImpl::MutableGraphData();
MS_EXCEPTION_IF_NULL(graph_data);
if (graph_->ModelType() == ModelType::kOM) {
MS_LOG(INFO) << "This model has been built, skip.";
return kSuccess;
} else if (graph_->ModelType() == ModelType::kMindIR) {
auto func_graph = graph_data->GetFuncGraph();
MS_EXCEPTION_IF_NULL(func_graph);
ModelConverter model_converter;
Buffer om_data = model_converter.LoadMindIR(func_graph);
if (om_data.Data() == nullptr || om_data.DataSize() == 0) {
MS_LOG(ERROR) << "Convert MindIR to OM failed.";
return kMCFailed;
}
graph_data = std::make_shared<Graph::GraphData>(om_data, ModelType::kOM);
MS_LOG(INFO) << "Convert MindIR to OM success.";
return kSuccess;
}
MS_LOG(ERROR) << "Unsupported ModelType " << graph_->ModelType();
return kMCFailed;
}
bool AclInferExecutor::CheckDeviceSupport(mindspore::DeviceType device_type) {
// for Ascend, only support kAscend and kAscend310
if (device_type != kAscend && device_type != kAscend310) {
return false;
}
return IsAscendNo910Soc();
}
} // namespace mindspore

View File

@ -1,56 +0,0 @@
/**
* Copyright 2020 Huawei Technologies Co., Ltd
*
* 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.
*/
#ifndef MINDSPORE_LITE_SRC_EXTENDRT_CXX_API_GRAPH_ACL_ACL_GRAPH_IMPL_H_
#define MINDSPORE_LITE_SRC_EXTENDRT_CXX_API_GRAPH_ACL_ACL_GRAPH_IMPL_H_
#include <functional>
#include <map>
#include <string>
#include <vector>
#include <memory>
#include <utility>
#include "include/api/graph.h"
#include "extendrt/acl/model_process.h"
#include "extendrt/acl/acl_env_guard.h"
#include "extendrt/cxx_api/graph/graph_impl.h"
#include "extendrt/graph_executor.h"
namespace mindspore {
class AclInferExecutor : public GraphExecutor {
public:
AclInferExecutor();
~AclInferExecutor() override;
Status Execute(const ExecutePlan &plan, const std::vector<MSTensor> &inputs, std::vector<MSTensor> *outputs) override;
protected:
bool CheckDeviceSupport(mindspore::DeviceType device_type) override;
Status Load(uint32_t device_id);
Status InitEnv();
Status FinalizeEnv();
Status CheckModelInputs(const std::vector<tensor::TensorPtr> &inputs) const;
bool init_flag_;
bool load_flag_;
std::string device_type_;
int32_t device_id_;
aclrtContext context_;
std::shared_ptr<AclEnvGuard> acl_env_;
ModelProcess model_process_;
};
} // namespace mindspore
#endif // MINDSPORE_LITE_SRC_EXTENDRT_CXX_API_GRAPH_ACL_ACL_GRAPH_IMPL_H_

View File

@ -1,267 +0,0 @@
/**
* Copyright 2021 Huawei Technologies Co., Ltd
*
* 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 "extendrt/acl/acl_model_multi.h"
#include <vector>
#include <utility>
#include <map>
#include <string>
#include <algorithm>
#include <numeric>
#include <deque>
#include <functional>
#include "extendrt/factory.h"
#include "acl/acl_rt.h"
#include "mindspore/core/load_mindir/infer_mindir.h"
#include "extendrt/acl/acl_vm/ms_tensor_ref.h"
#include "extendrt/acl/acl_vm/acl_vm.h"
namespace mindspore {
API_FACTORY_REG(ModelImpl, AclModelMulti);
namespace {
std::map<DataType, size_t> kDtypeMap = {
{DataType::kNumberTypeBool, sizeof(bool)}, {DataType::kNumberTypeInt8, sizeof(int8_t)},
{DataType::kNumberTypeInt16, sizeof(int16_t)}, {DataType::kNumberTypeInt32, sizeof(int32_t)},
{DataType::kNumberTypeInt64, sizeof(int64_t)}, {DataType::kNumberTypeFloat16, sizeof(float16)},
{DataType::kNumberTypeFloat32, sizeof(float)}, {DataType::kNumberTypeFloat64, sizeof(double)},
{DataType::kNumberTypeUInt8, sizeof(uint8_t)}, {DataType::kNumberTypeUInt16, sizeof(uint16_t)},
{DataType::kNumberTypeUInt32, sizeof(uint32_t)}, {DataType::kNumberTypeUInt64, sizeof(uint64_t)}};
std::shared_ptr<compile::MsBackend> CreateBackend(const std::shared_ptr<AclModelOptions> &options) {
MS_EXCEPTION_IF_NULL(options);
return std::make_shared<AclBackend>(kMsConvert, kDavinciMultiGraphInferenceDevice, options);
}
bool HasMultiGraph(const FuncGraphPtr &fg) {
MS_EXCEPTION_IF_NULL(fg);
std::vector<AnfNodePtr> all_nodes = TopoSort(fg->get_return());
for (const auto &node : all_nodes) {
MS_EXCEPTION_IF_NULL(node);
if (IsValueNode<FuncGraph>(node)) {
MS_LOG(INFO) << fg->ToString() << " has FuncGraph node " << node->DebugString() << " is multi graph.";
return true;
}
}
return false;
}
} // namespace
Status AclModelMulti::Build() {
if (!is_multi_graph_.has_value()) {
is_multi_graph_ = ModelImpl::GetFuncGraph() == nullptr ? false : HasMultiGraph(ModelImpl::GetFuncGraph());
}
if (!is_multi_graph_.value()) {
return AclInferSession::Build();
}
if (vm_ != nullptr) {
MS_LOG(INFO) << "Multi graph model has been built, skip.";
return kSuccess;
}
MS_LOG(INFO) << "Start build multi graph model.";
// perpare func graph
auto manager = MakeManager();
manager->AddFuncGraph(ModelImpl::GetFuncGraph());
ModelImpl::GetFuncGraph()->set_manager(manager);
// set inputs
SetInputs();
// infer mindir
abstract::AbstractBasePtrList broaded_args;
auto fg = ModelImpl::GetFuncGraph();
MS_EXCEPTION_IF_NULL(fg);
const auto &inputs = fg->get_inputs();
(void)std::transform(inputs.begin(), inputs.end(), std::back_inserter(broaded_args),
[](const AnfNodePtr &n) -> AbstractBasePtr {
MS_EXCEPTION_IF_NULL(n);
auto abstract = n->abstract();
MS_EXCEPTION_IF_NULL(abstract);
if (abstract->GetValueTrack() != kAnyValue) {
return abstract->Broaden();
}
return abstract;
});
try {
(void)InferMindir(ModelImpl::GetFuncGraph(), broaded_args);
} catch (const std::runtime_error &e) {
MS_LOG(ERROR) << "Infer mindir for sub graph failed: " << e.what();
return kMCFailed;
}
// set output
SetOutput();
// create vm
auto backend = CreateBackend(std::make_shared<AclModelOptions>(model_context_));
auto context_ptr = MsContext::GetInstance();
MS_EXCEPTION_IF_NULL(context_ptr);
backend->set_is_multi_graph_sink(false);
context_ptr->set_param<std::string>(MS_CTX_DEVICE_TARGET, kDavinciMultiGraphInferenceDevice);
context_ptr->set_param<bool>(MS_CTX_IS_MULTI_GRAPH_SINK, false);
context_ptr->set_param<bool>(MS_CTX_ENABLE_LOOP_SINK, false);
auto compile = std::make_shared<AclCompileGraphs>(backend, compile::GetMsNonlinearOps());
vm_ = compile->CompileAndLink(ModelImpl::GetFuncGraph());
backend_ = std::move(backend);
MS_LOG(INFO) << "Build multi graph model success.";
return kSuccess;
}
Status AclModelMulti::Predict(const std::vector<MSTensor> &inputs, std::vector<MSTensor> *outputs) {
if (!is_multi_graph_.has_value()) {
is_multi_graph_ = ModelImpl::GetFuncGraph() == nullptr ? false : HasMultiGraph(ModelImpl::GetFuncGraph());
}
if (!is_multi_graph_.value()) {
return AclInferSession::Predict(inputs, outputs);
}
auto ret = Build();
if (ret != kSuccess) {
MS_LOG(ERROR) << "Build multi-graph model as default options failed.";
return ret;
}
MS_LOG(INFO) << "Start predict multi graph model.";
MS_EXCEPTION_IF_NULL(vm_);
MS_EXCEPTION_IF_NULL(outputs);
try {
(*outputs) = MSTensorRef::Convert(vm_->Eval(MSTensorRef::Convert(inputs)));
} catch (const std::exception &ex) {
MS_LOG(ERROR) << "Predict Failed, error: " << ex.what();
return kMCFailed;
}
if (inputs_.empty()) {
inputs_ = inputs;
} else {
if (inputs.size() != inputs_.size()) {
MS_LOG(ERROR) << "Input Size is wrong.";
return kMCFailed;
}
for (size_t i = 0; i < inputs_.size(); ++i) {
auto input_tensor = MSTensor::CreateTensor(inputs_[i].Name(), inputs_[i].DataType(), inputs_[i].Shape(),
inputs[i].Data().get(), inputs[i].DataSize());
inputs_[i] = (*input_tensor);
MSTensor::DestroyTensorPtr(input_tensor);
}
}
outputs_ = *outputs;
MS_LOG(INFO) << "Predict multi graph model success.";
return kSuccess;
}
void AclModelMulti::SetInputs() {
if (inputs_.empty()) {
auto fg = ModelImpl::GetFuncGraph();
MS_EXCEPTION_IF_NULL(fg);
const auto &inputs = fg->get_inputs();
for (const auto &in : inputs) {
auto input_param = std::dynamic_pointer_cast<Parameter>(in);
MS_EXCEPTION_IF_NULL(input_param);
auto input_abs = input_param->abstract();
MS_EXCEPTION_IF_NULL(input_abs);
auto tensor_abs = input_abs->cast<abstract::AbstractTensorPtr>();
if (tensor_abs == nullptr) {
MS_LOG(EXCEPTION) << "The graph input type is not a tensor. input args info:" << input_abs->ToString();
}
auto shape_ptr = tensor_abs->BuildShape();
MS_EXCEPTION_IF_NULL(shape_ptr);
auto tensor_shape = shape_ptr->cast<abstract::ShapePtr>();
MS_EXCEPTION_IF_NULL(tensor_shape);
auto elem = tensor_abs->element();
MS_EXCEPTION_IF_NULL(elem);
auto type_id = elem->BuildType()->type_id();
auto tensor = std::make_shared<tensor::Tensor>(type_id, tensor_shape->shape());
std::vector<int64_t> shape = tensor->shape_c();
auto input_tensor = MSTensor::CreateTensor(input_param->name(), static_cast<DataType>(tensor->data_type_c()),
shape, nullptr, tensor->Size());
inputs_.emplace_back(*input_tensor);
MSTensor::DestroyTensorPtr(input_tensor);
}
} else {
MS_LOG(DEBUG) << "inputs_ has been set.";
}
}
void AclModelMulti::SetOutput() {
if (outputs_.empty()) {
auto fg = ModelImpl::GetFuncGraph();
MS_EXCEPTION_IF_NULL(fg);
const auto output = fg->output();
MS_EXCEPTION_IF_NULL(output);
auto abs = output->abstract();
MS_EXCEPTION_IF_NULL(abs);
// DataType
DataType type_id;
if (abs->isa<abstract::AbstractTensor>()) {
auto abs_tensor = abs->cast<abstract::AbstractTensorPtr>();
auto ele = abs_tensor->element();
MS_EXCEPTION_IF_NULL(ele);
MS_EXCEPTION_IF_NULL(ele->GetTypeTrack());
type_id = static_cast<DataType>(ele->GetTypeTrack()->type_id());
} else {
MS_EXCEPTION_IF_NULL(abs->GetTypeTrack());
type_id = static_cast<DataType>(abs->GetTypeTrack()->type_id());
}
// Shape
auto shape_track = abs->GetShapeTrack();
MS_EXCEPTION_IF_NULL(shape_track);
std::vector<int64_t> shape = {};
if (shape_track->isa<abstract::Shape>()) {
auto shapeptr = shape_track->cast<abstract::ShapePtr>();
shape = static_cast<std::vector<int64_t>>(shapeptr->shape());
}
// Size
size_t ato_size = 0;
if (kDtypeMap.find(type_id) != kDtypeMap.end()) {
ato_size = kDtypeMap[type_id];
}
int64_t ele_num = std::accumulate(shape.begin(), shape.end(), 1, std::multiplies<int64_t>());
size_t size = ato_size * LongToSize(ele_num);
// create tensor
auto output_tensor = MSTensor::CreateTensor("", type_id, shape, nullptr, size);
outputs_.emplace_back(*output_tensor);
MSTensor::DestroyTensorPtr(output_tensor);
} else {
MS_LOG(DEBUG) << "outputs_ has been set.";
}
}
std::vector<MSTensor> AclModelMulti::GetInputs() {
if (!is_multi_graph_.has_value()) {
is_multi_graph_ = ModelImpl::GetFuncGraph() == nullptr ? false : HasMultiGraph(ModelImpl::GetFuncGraph());
}
if (!is_multi_graph_.value()) {
return AclInferSession::GetInputs();
}
return inputs_;
}
std::vector<MSTensor> AclModelMulti::GetOutputs() {
if (!is_multi_graph_.has_value()) {
is_multi_graph_ = ModelImpl::GetFuncGraph() == nullptr ? false : HasMultiGraph(ModelImpl::GetFuncGraph());
}
if (!is_multi_graph_.value()) {
return AclInferSession::GetOutputs();
}
return outputs_;
}
} // namespace mindspore

View File

@ -1,54 +0,0 @@
/**
* Copyright 2021 Huawei Technologies Co., Ltd
*
* 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.
*/
#ifndef MINDSPORE_LITE_SRC_EXTENDRT_CXX_API_MODEL_ACL_ACL_MODEL_MULTI_H_
#define MINDSPORE_LITE_SRC_EXTENDRT_CXX_API_MODEL_ACL_ACL_MODEL_MULTI_H_
#include "extendrt/acl/acl_model.h"
#include <memory>
#include <optional>
#include <vector>
#include <string>
#include <map>
namespace mindspore {
namespace compile {
class MsBackend;
class FinalVM;
} // namespace compile
class AclModelMulti : public AclInferSession {
public:
AclModelMulti() : AclInferSession(), is_multi_graph_(std::nullopt) {}
~AclModelMulti() = default;
Status Build() override;
Status Predict(const std::vector<MSTensor> &inputs, std::vector<MSTensor> *outputs) override;
std::vector<MSTensor> GetInputs() override;
std::vector<MSTensor> GetOutputs() override;
private:
void SetInputs();
void SetOutput();
std::optional<bool> is_multi_graph_;
std::shared_ptr<compile::MsBackend> backend_;
std::shared_ptr<compile::FinalVM> vm_;
std::vector<MSTensor> inputs_ = {};
std::vector<MSTensor> outputs_ = {};
};
} // namespace mindspore
#endif // MINDSPORE_LITE_SRC_EXTENDRT_CXX_API_MODEL_ACL_ACL_MODEL_MULTI_H_

View File

@ -1,163 +0,0 @@
/**
* Copyright 2020 Huawei Technologies Co., Ltd
*
* 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 "extendrt/acl/acl_model_options.h"
#include <set>
#include <memory>
#include "utils/log_adapter.h"
#include "external/ge/ge_api_types.h"
#include "acl/acl_base.h"
namespace mindspore {
static const std::map<DataType, std::string> kSupportedDtypeOptionMap = {{DataType::kNumberTypeFloat16, "FP16"},
{DataType::kNumberTypeFloat32, "FP32"},
{DataType::kNumberTypeUInt8, "UINT8"}};
AclModelOptions::AclModelOptions(const std::shared_ptr<Context> &context) {
if (context == nullptr) {
return;
}
auto &device_infos = context->MutableDeviceInfo();
if (device_infos.size() != 1) {
return;
}
auto ascend_info = device_infos[0]->Cast<AscendDeviceInfo>();
if (ascend_info == nullptr) {
return;
}
insert_op_cfg_path_ = ascend_info->GetInsertOpConfigPath();
input_format_ = ascend_info->GetInputFormat();
input_shape_map_ = ascend_info->GetInputShapeMap();
auto out_type = ascend_info->GetOutputType();
auto iter = kSupportedDtypeOptionMap.find(out_type);
if (out_type == DataType::kTypeUnknown) {
// do nothing
} else if (iter == kSupportedDtypeOptionMap.end()) {
MS_LOG(INFO) << "Unsupported output type " << out_type << ", use FP32 as default.";
} else {
output_type_ = iter->second;
}
dynamic_batch_size_ = ascend_info->GetDynamicBatchSize();
dynamic_image_size_ = ascend_info->GetDynamicImageSize();
precision_mode_ = ascend_info->GetPrecisionMode();
op_select_impl_mode_ = ascend_info->GetOpSelectImplMode();
fusion_switch_cfg_path_ = ascend_info->GetFusionSwitchConfigPath();
device_id_ = ascend_info->GetDeviceID();
buffer_optimize_mode_ = ascend_info->GetBufferOptimizeMode();
#ifndef SUPPORT_SD3403_DAVINCI
const char *soc_name = aclrtGetSocName();
if (soc_name == nullptr) {
MS_LOG(WARNING) << "Get soc version failed.";
return;
}
soc_version_ = soc_name;
#else
soc_version = "OPTG";
#endif
}
void AclModelOptions::RenameInput(const std::vector<std::string> &input_names) {
if (input_names.size() != input_shape_map_.size()) {
MS_LOG(INFO) << "Inputs count not match";
return;
}
input_shape_ = "";
for (size_t i = 0; i < input_shape_map_.size(); i++) {
if (input_shape_map_.find(i) == input_shape_map_.end()) {
MS_LOG(WARNING) << "Not find the key: " << i;
return;
}
std::string s;
for (size_t j = 0; j < input_shape_map_[i].size(); j++) {
s += std::to_string(input_shape_map_[i][j]) + ",";
}
input_shape_ += input_names[i] + ":" + s.substr(0, s.size() - 1) + ";";
}
input_shape_ = input_shape_.substr(0, input_shape_.size() - 1);
MS_LOG(INFO) << "input name is " << input_shape_;
}
std::tuple<std::map<std::string, std::string>, std::map<std::string, std::string>> AclModelOptions::GenAclOptions()
const {
const std::map<std::string const *, std::string> init_options_map = {
{&op_select_impl_mode_, ge::ir_option::OP_SELECT_IMPL_MODE},
{&soc_version_, ge::ir_option::SOC_VERSION},
{&fusion_switch_cfg_path_, ge::ir_option::FUSION_SWITCH_FILE},
{&buffer_optimize_mode_, ge::ir_option::BUFFER_OPTIMIZE}};
const std::map<std::string const *, std::string> build_options_map = {
{&insert_op_cfg_path_, ge::ir_option::INSERT_OP_FILE},
{&input_format_, ge::ir_option::INPUT_FORMAT},
{&input_shape_, ge::ir_option::INPUT_SHAPE},
{&output_type_, ge::ir_option::OUTPUT_TYPE},
{&precision_mode_, ge::ir_option::PRECISION_MODE},
{&dynamic_batch_size_, ge::ir_option::DYNAMIC_BATCH_SIZE},
{&dynamic_image_size_, ge::ir_option::DYNAMIC_IMAGE_SIZE}};
const std::set<std::string> first_graph_options = {
ge::ir_option::INSERT_OP_FILE,
ge::ir_option::INPUT_FORMAT,
ge::ir_option::INPUT_SHAPE,
};
const std::set<std::string> multi_graph_unsupported_options = {ge::ir_option::OUTPUT_TYPE};
std::map<std::string, std::string> init_options;
std::map<std::string, std::string> build_options;
for (auto [ms_option, acl_option_key] : init_options_map) {
if (ms_option == nullptr || ms_option->empty()) {
continue;
}
MS_LOG(INFO) << "Option " << acl_option_key << " : " << *ms_option;
init_options.emplace(acl_option_key, *ms_option);
}
for (auto [ms_option, acl_option_key] : build_options_map) {
if (ms_option == nullptr || ms_option->empty()) {
continue;
}
MS_LOG(INFO) << "Option " << acl_option_key << " : " << *ms_option;
build_options.emplace(acl_option_key, *ms_option);
}
// first_graph_flag has value means being multi graph mode
if (first_graph_flag_.has_value()) {
for (const auto &option : multi_graph_unsupported_options) {
build_options.erase(option);
}
// non-input graph
if (!first_graph_flag_) {
for (const auto &option : first_graph_options) {
build_options.erase(option);
}
}
}
return {init_options, build_options};
}
std::string AclModelOptions::GenAclOptionsKey() const {
auto [init_options, build_options] = GenAclOptions();
std::string key_str;
for (auto &[key, value] : init_options) {
key_str += key + "^" + value + "^^";
}
for (auto &[key, value] : build_options) {
key_str += key + "^" + value + "^^";
}
return key_str;
}
} // namespace mindspore

View File

@ -1,64 +0,0 @@
/**
* Copyright 2020 Huawei Technologies Co., Ltd
*
* 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.
*/
#ifndef MINDSPORE_LITE_EXTENDRT_SESSION_ACL_OPTION_PARSER_H
#define MINDSPORE_LITE_EXTENDRT_SESSION_ACL_OPTION_PARSER_H
#include <vector>
#include <string>
#include <map>
#include <tuple>
#include <memory>
#include <optional>
#include "include/api/types.h"
#include "include/api/status.h"
#include "include/api/context.h"
namespace mindspore {
class MS_API AclModelOptions {
public:
explicit AclModelOptions(const std::shared_ptr<Context> &context);
~AclModelOptions() = default;
std::string GenAclOptionsKey() const;
uint32_t GetDeviceID() const { return device_id_; }
void RenameInput(const std::vector<std::string> &);
// return tuple<init_options, build_options>
std::tuple<std::map<std::string, std::string>, std::map<std::string, std::string>> GenAclOptions() const;
void SetFirstGraph(bool is_first_graph) noexcept { first_graph_flag_ = is_first_graph; }
void SetOmFilePath(const std::string &file_path) noexcept { om_file_path_ = file_path; }
std::string GetOmFilePath() const { return om_file_path_; }
private:
std::string output_node_; // todo: at convert.cc::BuildGraph(), no atc options
// build options
std::string insert_op_cfg_path_;
std::string input_format_;
std::string input_shape_;
std::string output_type_;
std::string precision_mode_;
std::string op_select_impl_mode_;
std::string fusion_switch_cfg_path_;
std::string soc_version_ = "Ascend310";
std::string dynamic_batch_size_;
std::string dynamic_image_size_;
std::string buffer_optimize_mode_;
std::map<int, std::vector<int>> input_shape_map_;
// other options
uint32_t device_id_;
std::optional<bool> first_graph_flag_;
std::string om_file_path_;
};
} // namespace mindspore
#endif // MINDSPORE_LITE_SRC_EXTENDRT_CXX_API_MODEL_ACL_ACL_MODEL_OPTIONS_H_

View File

@ -1,45 +0,0 @@
/**
* Copyright 2021 Huawei Technologies Co., Ltd
*
* 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.
*/
#ifndef MINDSPORE_LITE_SRC_EXTENDRT_CXX_API_ACL_UTILS_H_
#define MINDSPORE_LITE_SRC_EXTENDRT_CXX_API_ACL_UTILS_H_
#include <string>
#include "acl/acl_base.h"
namespace mindspore {
static inline bool IsAscend910Soc() {
const char *soc_name_c = aclrtGetSocName();
if (soc_name_c == nullptr) {
return false;
}
std::string soc_name(soc_name_c);
if (soc_name.find("910") == std::string::npos) {
return false;
}
return true;
}
static inline bool IsAscendNo910Soc() {
const char *soc_name_c = aclrtGetSocName();
if (soc_name_c == nullptr) {
return false;
}
std::string soc_name(soc_name_c);
if (soc_name.find("910") != std::string::npos) {
return false;
}
return true;
}
} // namespace mindspore
#endif // MINDSPORE_LITE_SRC_EXTENDRT_CXX_API_ACL_UTILS_H_

View File

@ -1,154 +0,0 @@
/**
* Copyright 2021 Huawei Technologies Co., Ltd
*
* 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 "extendrt/acl/acl_vm/acl_multi_graph_session.h"
#include <memory>
#include <deque>
#include <vector>
#include "backend/common/session/session_factory.h"
#include "backend/common/optimizer/optimizer.h"
#include "plugin/device/ascend/optimizer/enhancer/add_placeholder_for_dynamic_rnn.h"
#include "extendrt/acl/model_converter.h"
#include "extendrt/acl/acl_model_options.h"
#include "extendrt/acl/acl_vm/ms_tensor_ref.h"
#include "extendrt/cxx_api/graph/graph_data.h"
namespace mindspore::session {
void MultiGraphAclSession::Init(uint32_t device_id) { InitExecutor(kDavinciMultiGraphInferenceDevice, device_id); }
GraphId MultiGraphAclSession::CompileGraphImpl(const AnfNodePtrList &lst, const AnfNodePtrList &outputs) {
class FirstGraphModeGuard {
public:
explicit FirstGraphModeGuard(const std::shared_ptr<AclModelOptions> &options) : options_(options) {
if (options_ != nullptr) {
options_->SetFirstGraph(true);
}
}
~FirstGraphModeGuard() {
if (options_ != nullptr) {
options_->SetFirstGraph(false);
}
}
private:
std::shared_ptr<AclModelOptions> options_;
};
MS_LOG(INFO) << "Start MultiGraph Compile.";
// construct kernel graph
auto kernel_graph = SessionBasic::ConstructKernelGraph(lst, outputs, device::DeviceType::kUnknown, false);
MS_EXCEPTION_IF_NULL(kernel_graph);
auto optimizer = std::make_shared<opt::GraphOptimizer>();
auto pm = std::make_shared<opt::PassManager>("310_multi_graph_pm");
pm->AddPass(std::make_shared<opt::InsertPlaceholderForDynamicRNN>());
optimizer->AddPassManager(pm);
(void)optimizer->Optimize(kernel_graph);
kernel_graph->SetExecOrderByDefault();
// concert to om data
ModelConverter model_converter_;
model_converter_.set_options(options_);
FirstGraphModeGuard guard(options_);
auto om_data = model_converter_.LoadMindIR(kernel_graph);
if (om_data.Data() == nullptr || om_data.DataSize() == 0) {
MS_LOG(ERROR) << "Load MindIR failed.";
return kMCFailed;
}
// load
std::shared_ptr<Graph> graph = std::make_shared<Graph>(std::make_shared<Graph::GraphData>(om_data, ModelType::kOM));
MS_EXCEPTION_IF_NULL(graph);
auto graph_cell = GraphCell(graph);
auto ret = graph_cell.Load(options_->GetDeviceID());
if (ret != kSuccess) {
MS_LOG(EXCEPTION) << "Load failed.";
}
graphs_[kernel_graph->graph_id()] = graph_cell;
kernel_graphs_[kernel_graph->graph_id()] = kernel_graph;
MS_LOG(INFO) << "Multi graph compile success, graph id " << kernel_graph->graph_id();
return kernel_graph->graph_id();
}
void MultiGraphAclSession::RunGraph(GraphId graph_id, const std::vector<MSTensor> &inputs, VectorRef *outputs) {
MS_EXCEPTION_IF_NULL(outputs);
MS_LOG(INFO) << "Start run graph " << graph_id;
auto iter = graphs_.find(graph_id);
if (iter == graphs_.end()) {
MS_LOG(EXCEPTION) << "Graph id " << graph_id << " not found.";
}
std::vector<MSTensor> out_tensors;
auto ret = iter->second.Run(inputs, &out_tensors);
if (ret != kSuccess) {
MS_LOG(EXCEPTION) << "Graph id " << graph_id << " run failed.";
}
std::deque<MSTensor> out_tensors_deque(out_tensors.begin(), out_tensors.end());
(*outputs) = ConstructOutputRef(graph_id, &out_tensors_deque);
}
VectorRef MultiGraphAclSession::ConstructOutputRef(GraphId graph_id, std::deque<MSTensor> *out_tensors) {
MS_EXCEPTION_IF_NULL(out_tensors);
VectorRef outs;
auto out_nodes = kernel_graphs_[graph_id]->outputs();
for (auto &out : out_nodes) {
auto item_with_index = common::AnfAlgo::VisitKernelWithReturnType(
out, 0, false, std::vector<PrimitivePtr>{prim::kPrimMakeTuple, prim::kPrimUpdateState, prim::kPrimStateSetItem});
auto &anf_node = item_with_index.first;
if (common::AnfAlgo::CheckPrimitiveType(anf_node, prim::kPrimMakeTuple)) {
auto cnode = anf_node->cast<CNodePtr>();
MS_EXCEPTION_IF_NULL(cnode);
outs.emplace_back(ConstructOutputRefByTupleNode(cnode, out_tensors));
} else if (AnfUtils::IsRealKernel(anf_node)) {
if (out_tensors->empty()) {
MS_LOG(EXCEPTION) << "Can not find MSTensor for output node " << out->DebugString()
<< ", visited: " << anf_node->DebugString();
}
outs.emplace_back(MSTensorRef(out_tensors->front()));
out_tensors->pop_front();
}
}
if (!out_tensors->empty()) {
MS_LOG(EXCEPTION) << "Number of output size " << outs.size() << " but " << out_tensors->size()
<< " MSTensor remained.";
}
return outs;
}
VectorRef MultiGraphAclSession::ConstructOutputRefByTupleNode(const CNodePtr &tuple_node,
std::deque<MSTensor> *out_tensors) {
MS_EXCEPTION_IF_NULL(out_tensors);
VectorRef outs;
for (size_t i = 1; i < tuple_node->inputs().size(); ++i) {
auto item_with_index = common::AnfAlgo::VisitKernelWithReturnType(
tuple_node->input(i), 0, false,
std::vector<PrimitivePtr>{prim::kPrimMakeTuple, prim::kPrimUpdateState, prim::kPrimStateSetItem});
auto &anf_node = item_with_index.first;
if (common::AnfAlgo::CheckPrimitiveType(anf_node, prim::kPrimMakeTuple)) {
auto cnode = anf_node->cast<CNodePtr>();
MS_EXCEPTION_IF_NULL(cnode);
outs.emplace_back(ConstructOutputRefByTupleNode(cnode, out_tensors));
} else if (AnfUtils::IsRealKernel(anf_node)) {
if (out_tensors->empty()) {
MS_LOG(EXCEPTION) << "Can not find MSTensor for output node " << tuple_node->input(i)->DebugString()
<< ", visited: " << anf_node->DebugString();
}
outs.emplace_back(MSTensorRef(out_tensors->front()));
out_tensors->pop_front();
}
}
return outs;
}
MS_REG_SESSION(kDavinciMultiGraphInferenceDevice, MultiGraphAclSession);
} // namespace mindspore::session

View File

@ -1,49 +0,0 @@
/**
* Copyright 2021 Huawei Technologies Co., Ltd
*
* 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.
*/
#ifndef MINDSPORE_LITE_SRC_EXTENDRT_CXX_API_MODEL_ACL_ACL_VM_ACL_MULTI_GRAPH_SESSION_H_
#define MINDSPORE_LITE_SRC_EXTENDRT_CXX_API_MODEL_ACL_ACL_VM_ACL_MULTI_GRAPH_SESSION_H_
#include <deque>
#include <vector>
#include <map>
#include <memory>
#include "include/api/types.h"
#include "include/api/cell.h"
#include "backend/common/session/session_basic.h"
namespace mindspore {
class AclModelOptions;
namespace session {
class MultiGraphAclSession : public session::SessionBasic {
public:
MultiGraphAclSession() = default;
~MultiGraphAclSession() override = default;
void Init(uint32_t device_id) override;
GraphId CompileGraphImpl(const AnfNodePtrList &lst, const AnfNodePtrList &outputs) override;
void RunGraph(GraphId graph_id, const std::vector<MSTensor> &inputs, VectorRef *outputs);
void SetOptions(const std::shared_ptr<AclModelOptions> &options) { options_ = options; }
private:
VectorRef ConstructOutputRef(GraphId graph_id, std::deque<MSTensor> *out_tensors);
VectorRef ConstructOutputRefByTupleNode(const CNodePtr &tuple_node, std::deque<MSTensor> *out_tensors);
std::map<GraphId, GraphCell> graphs_ = {};
std::map<GraphId, KernelGraphPtr> kernel_graphs_ = {};
std::shared_ptr<AclModelOptions> options_ = nullptr;
};
} // namespace session
} // namespace mindspore
#endif // MINDSPORE_LITE_SRC_EXTENDRT_CXX_API_MODEL_ACL_ACL_VM_ACL_MULTI_GRAPH_SESSION_H_

View File

@ -1,295 +0,0 @@
/**
* Copyright 2021 Huawei Technologies Co., Ltd
*
* 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 "extendrt/acl/acl_vm/acl_vm.h"
#include <memory>
#include <string>
#include <vector>
#include "extendrt/acl/acl_model_options.h"
#include "extendrt/acl/acl_vm/acl_multi_graph_session.h"
#include "utils/trace_base.h"
namespace mindspore {
namespace {
inline bool IsMonadNode(const AnfNodePtr &node) {
if (IsPrimitiveCNode(node, prim::kPrimStateSetItem) || IsPrimitiveCNode(node, prim::kPrimUpdateState)) {
return true;
}
if (HasAbstractMonad(node)) {
return true;
}
return false;
}
} // namespace
AclBackend::AclBackend(const std::string &name, const std::string &target,
const std::shared_ptr<AclModelOptions> &options)
: MsBackend(name, target, options->GetDeviceID()) {
auto session = std::dynamic_pointer_cast<session::MultiGraphAclSession>(MsBackend::target_sess_);
MS_EXCEPTION_IF_NULL(session);
session->SetOptions(options);
}
VectorRef AclBackend::MsRunGraph(const GraphId &g, const VectorRef &args, const std::string &target) {
std::vector<MSTensor> inputs;
for (const auto &arg : args) {
if (!utils::isa<MSTensorRef>(arg)) {
MS_LOG(EXCEPTION) << "Invalid item " << arg.ToString();
}
auto wrapper = utils::cast<MSTensorRef>(arg);
inputs.emplace_back(wrapper.GetTensor());
}
VectorRef outputs;
MS_EXCEPTION_IF_NULL(target_sess_);
auto exec_sess = std::dynamic_pointer_cast<session::MultiGraphAclSession>(target_sess_);
MS_EXCEPTION_IF_NULL(exec_sess);
exec_sess->RunGraph(g, inputs, &outputs);
return outputs;
}
bool AclBackend::GetCond(const BaseRef &c, bool *value) {
MS_EXCEPTION_IF_NULL(value);
if (!utils::isa<MSTensorRef>(c)) {
MS_LOG(ERROR) << "Invalid item " << c.ToString() << " must be a MSTensorRef.";
return false;
}
auto wrapper = utils::cast<MSTensorRef>(c);
if (wrapper.GetTensor().DataType() != DataType::kNumberTypeBool) {
MS_LOG(ERROR) << "Invalid data type " << wrapper.GetTensor().DataType() << " must be bool.";
return false;
}
auto data = wrapper.GetTensor().Data();
if (data == nullptr) {
return false;
}
(*value) = *reinterpret_cast<const bool *>(data.get());
return true;
}
bool AclBackend::GetIndex(const BaseRef &c, int64_t *value) {
MS_EXCEPTION_IF_NULL(value);
if (!utils::isa<MSTensorRef>(c)) {
MS_LOG(ERROR) << "Invalid item " << c.ToString() << " must be a MSTensorRef.";
return false;
}
auto wrapper = utils::cast<MSTensorRef>(c);
if (wrapper.GetTensor().DataType() == DataType::kNumberTypeInt32) {
auto data = wrapper.GetTensor().Data();
if (data == nullptr) {
return false;
}
auto value_int32 = *reinterpret_cast<const int32_t *>(data.get());
(*value) = static_cast<int64_t>(value_int32);
return true;
} else if (wrapper.GetTensor().DataType() == DataType::kNumberTypeInt64) {
auto data = wrapper.GetTensor().Data();
if (data == nullptr) {
return false;
}
(*value) = *reinterpret_cast<const int64_t *>(data.get());
return true;
} else {
MS_LOG(ERROR) << "Index must be Int type.";
return false;
}
}
AclCompileGraph::AclCompileGraph(const std::shared_ptr<compile::MsBackend> &backend,
const std::vector<PrimitivePtr> &cut_list)
: CompileGraph(backend, cut_list) {}
void AclCompileGraph::AddInst(const compile::Instruction &inst, const MSTensorRef &arg) {
VectorRef args;
args.push_back(arg);
compile::CompileGraph::AddInst(inst, args);
}
int64_t AclCompileGraph::Ref(const AnfNodePtr &node) {
MS_EXCEPTION_IF_NULL(node);
MS_LOG(DEBUG) << "Start Ref node " << node->DebugString(true) << " height_: " << height_;
if (slots_.count(node) == 0 && node->isa<ValueNode>()) {
if (IsValueNode<FuncGraph>(node)) {
MS_LOG(DEBUG) << "Push graph.";
compile::CompileGraph::AddInst(compile::Instruction::kGraph, GetValueNode(node));
} else {
MS_LOG(DEBUG) << "Push.";
if (IsValueNode<Primitive>(node)) {
MS_LOG(EXCEPTION) << "must not be primitive in here NodeInfo: " << trace::GetDebugInfo(node->debug_info());
} else if (IsValueNode<tensor::Tensor>(node)) {
auto tensor_node = std::dynamic_pointer_cast<tensor::Tensor>(node->cast<ValueNodePtr>()->value());
MS_EXCEPTION_IF_NULL(tensor_node);
std::string name = "";
std::vector<int64_t> shape = tensor_node->shape_c();
DataType type = static_cast<DataType>(tensor_node->data_type_c());
auto mstensor_node = MSTensor::CreateRefTensor(name, type, shape, tensor_node->data_c(), tensor_node->Size());
MSTensorRef mstensor_ref(*mstensor_node);
AddInst(compile::Instruction::kPush, mstensor_ref);
MSTensor::DestroyTensorPtr(mstensor_node);
} else {
compile::CompileGraph::AddInst(compile::Instruction::kPush, GetValueNode(node));
}
}
Push(node);
} else if (auto const_parameter = dyn_cast<Parameter>(node);
slots_.count(node) == 0 && const_parameter != nullptr && const_parameter->has_default()) {
auto value = const_parameter->default_param();
MS_EXCEPTION_IF_NULL(value);
if (value->isa<tensor::Tensor>()) {
auto tensor_node = std::dynamic_pointer_cast<tensor::Tensor>(value);
MS_EXCEPTION_IF_NULL(tensor_node);
std::vector<int64_t> shape = tensor_node->shape_c();
DataType type = static_cast<DataType>(tensor_node->data_type_c());
auto mstensor_node =
MSTensor::CreateRefTensor(const_parameter->name(), type, shape, tensor_node->data_c(), tensor_node->Size());
MSTensorRef mstensor_ref(*mstensor_node);
AddInst(compile::Instruction::kPush, mstensor_ref);
MSTensor::DestroyTensorPtr(mstensor_node);
} else {
compile::CompileGraph::AddInst(compile::Instruction::kPush, value);
}
Push(node);
}
MS_LOG(DEBUG) << "End Ref node end height_: " << height_ << ", slots: " << slots_[node]
<< ", return: " << slots_[node] - height_;
return slots_[node] - height_;
}
void AclCompileGraph::AddExternal(const compile::LinConvertResult &result) {
VectorRef args;
args.push_back(result.run);
args.push_back(result.simu_run);
size_t size = result.inputs.size();
for (size_t i = 0; i < size; ++i) {
const auto &input = result.inputs[i];
MS_EXCEPTION_IF_NULL(input);
if (auto parameter = dyn_cast<Parameter>(input); parameter != nullptr && parameter->has_default()) {
MS_LOG(DEBUG) << parameter->DebugString() << " has default value, will not be pushed as inputs.";
continue;
}
if (IsMonadNode(input)) {
MS_LOG(DEBUG) << input->DebugString() << " is monad node, will not be pushed as inputs.";
continue;
}
args.emplace_back(Ref(input));
}
compile::CompileGraph::AddInst(compile::Instruction::kExternal, args);
size_t out_count = 0;
for (auto &out : result.outputs) {
if (IsMonadNode(out)) {
continue;
}
++out_count;
Push(out);
}
MS_LOG(DEBUG) << "Args size " << args.size() << " out size " << out_count;
}
void AclCompileGraph::AddInput(const AnfNodePtr &node) {
MS_EXCEPTION_IF_NULL(node);
if (IsMonadNode(node)) {
return;
}
if (slots_.count(node) == 0) {
MS_LOG(DEBUG) << "Input node is null " << node->DebugString(true);
(void)Ref(node);
return;
}
compile::CompileGraph::AddInst(compile::Instruction::kInput, Ref(node));
set_height(height_ + 1);
}
void AclCompileGraph::AddPartial(const CNodePtr &node) {
MS_EXCEPTION_IF_NULL(node);
auto inputs = node->inputs();
VectorRef args;
if (inputs.size() <= 1) {
MS_LOG(EXCEPTION) << "The node:" << node->DebugString() << "do not have two input.";
}
auto fn = inputs[1];
if (!IsValueNode<FuncGraph>(fn)) {
MS_LOG(EXCEPTION) << "The type of 1st input of node must be FuncGraph";
}
for (size_t i = 1; i < inputs.size(); i++) {
if (IsMonadNode(inputs[i])) {
continue;
}
args.emplace_back(Ref(inputs[i]));
}
compile::CompileGraph::AddInst(compile::Instruction::kPartial, args);
}
int64_t AclCompileGraph::AddCall(const FuncGraphPtr &graph, const CNodePtr &node) {
MS_EXCEPTION_IF_NULL(graph);
MS_EXCEPTION_IF_NULL(node);
auto inputs = node->inputs();
AnfNodePtr fn = inputs[0];
(void)Ref(fn);
size_t size = inputs.size();
size_t non_monad_size = size;
for (size_t i = size - 1; i > 0; --i) {
if (IsMonadNode(inputs[i])) {
--non_monad_size;
continue;
}
AddInput(inputs[i]);
}
if (node == graph->output()) {
AddTailCall(fn, non_monad_size);
return RET_BREAK;
}
MS_LOG(DEBUG) << "Call:" << Ref(fn) << ", " << height_ << ", " << (non_monad_size - 1);
compile::CompileGraph::AddInst(compile::Instruction::kCall, Ref(fn));
Ret(static_cast<int64_t>(non_monad_size - 1));
for (size_t i = size - 1; i > 0; i--) {
const auto iter = slots_.find(inputs[i]);
if (iter != slots_.end() && iter->second >= height_) {
slots_.erase(inputs[i]);
}
}
return RET_SUCCESS;
}
void AclCompileGraph::PushParameters(const FuncGraphPtr &func_graph) {
MS_EXCEPTION_IF_NULL(func_graph);
std::vector<AnfNodePtr> parameters = func_graph->parameters();
for (size_t i = parameters.size(); i != 0; i--) {
MS_EXCEPTION_IF_NULL(parameters[i - 1]);
auto param = parameters[i - 1]->cast<ParameterPtr>();
MS_EXCEPTION_IF_NULL(param);
if (param->has_default()) {
MS_LOG(DEBUG) << "Parameter " << (i - 1) << ": " << param->DebugString() << " has default value, skip.";
continue;
}
if (IsMonadNode(param)) {
MS_LOG(DEBUG) << "Parameter " << (i - 1) << ": " << param->DebugString() << " has monad type, skip.";
continue;
}
Push(param);
MS_LOG(DEBUG) << "Push parameter " << (i - 1) << ": " << param->DebugString();
}
}
AclCompileGraphs::AclCompileGraphs(const std::shared_ptr<compile::MsBackend> &backend,
const std::vector<PrimitivePtr> &cut_list)
: CompileGraphs(backend, cut_list) {
MS_EXCEPTION_IF_NULL(backend);
MS_LOG(DEBUG) << "Start vm: " << backend->name();
transform_ = std::make_shared<AclCompileGraph>(backend, cut_list);
Reset();
}
} // namespace mindspore

View File

@ -1,62 +0,0 @@
/**
* Copyright 2021 Huawei Technologies Co., Ltd
*
* 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.
*/
#ifndef MINDSPORE_LITE_SRC_EXTENDRT_CXX_API_MODEL_ACL_ACL_VM_ACL_VM_H_
#define MINDSPORE_LITE_SRC_EXTENDRT_CXX_API_MODEL_ACL_ACL_VM_ACL_VM_H_
#include <vector>
#include <memory>
#include <string>
#include "backend/graph_compiler/transform.h"
#include "backend/graph_compiler/backend.h"
#include "extendrt/acl/acl_vm/ms_tensor_ref.h"
namespace mindspore {
class AclModelOptions;
class AclBackend : public compile::MsBackend {
public:
AclBackend(const std::string &name, const std::string &target, const std::shared_ptr<AclModelOptions> &options);
~AclBackend() override = default;
VectorRef MsRunGraph(const GraphId &g, const VectorRef &args, const std::string &target) override;
bool GetCond(const BaseRef &c, bool *value) override;
bool GetIndex(const BaseRef &c, int64_t *value) override;
};
class AclCompileGraph : public compile::CompileGraph {
public:
explicit AclCompileGraph(const std::shared_ptr<compile::MsBackend> &backend,
const std::vector<PrimitivePtr> &cut_list);
~AclCompileGraph() override = default;
int64_t Ref(const AnfNodePtr &node) override;
void AddExternal(const compile::LinConvertResult &result) override;
void AddInput(const AnfNodePtr &node) override;
void AddPartial(const CNodePtr &node) override;
int64_t AddCall(const FuncGraphPtr &graph, const CNodePtr &node) override;
void PushParameters(const FuncGraphPtr &func_graph) override;
private:
void AddInst(const compile::Instruction &inst, const MSTensorRef &arg);
};
class AclCompileGraphs : public compile::CompileGraphs {
public:
explicit AclCompileGraphs(const std::shared_ptr<compile::MsBackend> &backend,
const std::vector<PrimitivePtr> &cut_list);
~AclCompileGraphs() override = default;
};
} // namespace mindspore
#endif // MINDSPORE_LITE_SRC_EXTENDRT_CXX_API_MODEL_ACL_ACL_VM_ACL_VM_H_

View File

@ -1,78 +0,0 @@
/**
* Copyright 2021 Huawei Technologies Co., Ltd
*
* 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 "extendrt/acl/acl_vm/ms_tensor_ref.h"
#include <algorithm>
namespace mindspore {
VectorRef MSTensorRef::Convert(const std::vector<MSTensor> &tensors) {
VectorRef res;
(void)std::transform(tensors.begin(), tensors.end(), std::back_inserter(res),
[](const MSTensor &t) { return MSTensorRef(t); });
return res;
}
std::vector<MSTensor> MSTensorRef::Convert(const BaseRef &args) {
std::vector<MSTensor> res;
if (utils::isa<VectorRef>(args)) {
VectorRef args_vec = utils::cast<VectorRef>(args);
res = ConvertTuple(args_vec);
} else if (utils::isa<MSTensorRef>(args)) {
auto wrapper = utils::cast<MSTensorRef>(args);
res.push_back(wrapper.ms_tensor_);
} else {
MS_LOG(EXCEPTION) << "Invalid BaseRef " << args.ToString() << " must be MSTensorRef or VectorRef{MSTensorRef...}";
}
return res;
}
std::shared_ptr<Base> MSTensorRef::copy() const {
MSTensor *tensor = ms_tensor_.Clone();
auto res = std::make_shared<MSTensorRef>(static_cast<const MSTensor &>(*tensor));
MSTensor::DestroyTensorPtr(tensor);
return res;
}
bool MSTensorRef::operator==(const BaseRef &other) const {
if (!utils::isa<MSTensorRef>(other)) {
return false;
}
auto other_ms_tensor = utils::cast<MSTensorRef>(other).ms_tensor_;
auto this_ms_tensor = ms_tensor_;
return (this_ms_tensor.Name() == other_ms_tensor.Name()) && (this_ms_tensor.Shape() == other_ms_tensor.Shape()) &&
(this_ms_tensor.MutableData() == other_ms_tensor.MutableData()) &&
(this_ms_tensor.DataSize() == other_ms_tensor.DataSize()) &&
(this_ms_tensor.DataType() == other_ms_tensor.DataType());
}
std::vector<MSTensor> MSTensorRef::ConvertTuple(const VectorRef &args) {
std::vector<MSTensor> outs;
for (size_t i = 0; i < args.size(); ++i) {
const auto &item = args[i];
if (utils::isa<VectorRef>(item)) {
VectorRef args_vec = utils::cast<VectorRef>(args);
auto ret = ConvertTuple(args_vec);
(void)outs.insert(outs.end(), ret.begin(), ret.end());
} else if (utils::isa<MSTensorRef>(item)) {
auto wrapper = utils::cast<MSTensorRef>(item);
outs.push_back(wrapper.ms_tensor_);
} else {
MS_LOG(EXCEPTION) << "Invalid BaseRef " << args.ToString() << " must be MSTensorRef or VectorRef{MSTensorRef...}";
}
}
return outs;
}
} // namespace mindspore

View File

@ -1,49 +0,0 @@
/**
* Copyright 2021 Huawei Technologies Co., Ltd
*
* 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.
*/
#ifndef MINDSPORE_LITE_SRC_EXTENDRT_CXX_API_MODEL_ACL_ACL_VM_MS_TENSOR_REF_H_
#define MINDSPORE_LITE_SRC_EXTENDRT_CXX_API_MODEL_ACL_ACL_VM_MS_TENSOR_REF_H_
#include <memory>
#include <string>
#include <vector>
#include "include/api/types.h"
#include "mindspore/core/base/base_ref.h"
namespace mindspore {
class MSTensorRef : public BaseRef {
public:
MS_DECLARE_PARENT(MSTensorRef, BaseRef);
static VectorRef Convert(const std::vector<MSTensor> &tensors);
static std::vector<MSTensor> Convert(const BaseRef &args);
explicit MSTensorRef(const MSTensor &tensor) : ms_tensor_(tensor) {}
~MSTensorRef() override = default;
const MSTensor &GetTensor() const { return ms_tensor_; }
std::shared_ptr<Base> copy() const override;
uint32_t type() const override { return tid(); }
std::string ToString() const override { return ms_tensor_.Name(); }
bool operator==(const BaseRef &other) const override;
private:
static std::vector<MSTensor> ConvertTuple(const VectorRef &args);
MSTensor ms_tensor_;
};
} // namespace mindspore
#endif // MINDSPORE_LITE_SRC_EXTENDRT_CXX_API_MODEL_ACL_ACL_VM_MS_TENSOR_REF_H_

View File

@ -1,256 +0,0 @@
/**
* Copyright 2020 Huawei Technologies Co., Ltd
*
* 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 "extendrt/acl/model_converter.h"
#include <memory>
#include "include/transform/graph_ir/convert.h"
#include "include/transform/graph_ir/graph_runner.h"
#include "mindspore/core/utils/ms_context.h"
#include "include/api/serialization.h"
#include "graph/model.h"
#include "extendrt/acl/model_converter_utils/multi_process.h"
namespace mindspore {
namespace {
transform::TensorOrderMap GetParams(const FuncGraphPtr &anf_graph) {
transform::TensorOrderMap res;
for (auto &anf_node : anf_graph->parameters()) {
MS_EXCEPTION_IF_NULL(anf_node);
auto para = anf_node->cast<ParameterPtr>();
MS_EXCEPTION_IF_NULL(para);
if (para->has_default()) {
auto value = para->default_param();
MS_EXCEPTION_IF_NULL(value);
auto tensor = value->cast<std::shared_ptr<tensor::Tensor>>();
res.emplace(para->name(), tensor);
MS_LOG(INFO) << "Parameter " << para->name() << " has default value.";
}
}
return res;
}
bool CreateSessionAndGraphRunner() {
std::shared_ptr<ge::Session> sess = transform::DfGraphManager::GetInstance().GetGeSession();
if (sess == nullptr) {
transform::SessionOptions options;
options["ge.trainFlag"] = "0";
options["ge.enablePrintOpPass"] = "0";
sess = transform::GraphRunner::NewSession(options);
transform::DfGraphManager::GetInstance().SetGeSession(sess);
}
transform::GraphRunnerOptions options;
options.sess_ptr = sess;
auto graph_runner = std::make_shared<transform::GraphRunner>(options);
if (graph_runner == nullptr) {
MS_LOG(ERROR) << "Create new graph runner failed";
return false;
} else {
transform::DfGraphManager::GetInstance().SetGraphRunner(graph_runner);
}
return true;
}
} // namespace
transform::DfGraphPtr ModelConverter::ConvertFuncGraphToAIR(const FuncGraphPtr &anf_graph) {
MS_EXCEPTION_IF_NULL(anf_graph);
transform::DfGraphConvertor converter(anf_graph);
std::string net_id = "0";
std::string init_graph = "init_subgraph." + net_id;
std::string checkpoint_name = "save." + net_id;
converter.set_training(false);
(void)converter.ConvertAllNode().InitParam(GetParams(anf_graph)).BuildGraph();
(void)converter.GenerateCheckpointGraph();
if (converter.ErrCode() != 0) {
transform::DfGraphManager::GetInstance().ClearGraph();
MS_LOG(ERROR) << "Convert df graph failed, err:" << converter.ErrCode();
return nullptr;
}
(void)transform::DfGraphManager::GetInstance().AddGraph(anf_graph->ToString(), converter.GetComputeGraph());
(void)transform::DfGraphManager::GetInstance().AddGraph(init_graph, converter.GetInitGraph());
(void)transform::DfGraphManager::GetInstance().AddGraph(BROADCAST_GRAPH_NAME, converter.GetBroadcastGraph());
transform::Status ret =
transform::DfGraphManager::GetInstance().AddGraph(checkpoint_name, converter.GetSaveCheckpointGraph());
if (ret == transform::Status::SUCCESS) {
transform::DfGraphManager::GetInstance().SetAnfGraph(checkpoint_name, anf_graph);
}
(void)setenv("GE_TRAIN", "0", 1);
if (!CreateSessionAndGraphRunner()) {
MS_LOG(ERROR) << "Create GE Session or GraphRunner failed.";
return nullptr;
}
auto wrap_ptr = transform::DfGraphManager::GetInstance().GetGraphByName(anf_graph->ToString());
if (wrap_ptr == nullptr) {
MS_LOG(ERROR) << "Get graph form DfGraphManager failed!";
return nullptr;
}
transform::DfGraphPtr &ge_graph = wrap_ptr->graph_ptr_;
if (ge_graph == nullptr) {
MS_LOG(ERROR) << "The export graph is null";
return nullptr;
}
return ge_graph;
}
Buffer ModelConverter::BuildAirModel(const transform::DfGraphPtr &graph,
const std::map<std::string, std::string> &init_options,
const std::map<std::string, std::string> &build_options) {
ge::ModelBufferData model;
auto ret = ge::aclgrphBuildInitialize(init_options);
if (ret != ge::SUCCESS) {
MS_LOG(ERROR) << "Call aclgrphBuildInitialize fail.";
return Buffer();
}
ret = ge::aclgrphBuildModel(*graph, build_options, model);
if (ret != ge::SUCCESS) {
MS_LOG(ERROR) << "Call aclgrphBuildModel fail.";
return Buffer();
}
if (SaveModel(model) != kSuccess) {
MS_LOG(ERROR) << "Save model failed.";
return Buffer();
}
ge::aclgrphBuildFinalize();
return Buffer(model.data.get(), model.length);
}
Status ModelConverter::SaveModel(const ge::ModelBufferData &model) {
#ifdef BUILD_LITE
std::string file_path;
auto option = options_.lock();
if (option != nullptr) {
file_path = option->GetOmFilePath();
}
if (file_path.empty()) {
MS_LOG(INFO) << "File path is empty, there is no need to save model";
return kSuccess;
}
MS_LOG(INFO) << "Om file path: " << file_path;
auto ret = ge::aclgrphSaveModel(file_path, model);
if (ret != ge::SUCCESS) {
MS_LOG(ERROR) << "Call aclgrphSaveModel fail.";
return kMCFailed;
}
#endif
return kSuccess;
}
Buffer ModelConverter::LoadMindIR(const FuncGraphPtr &func_graph) {
MultiProcess multi_process;
Buffer buffer_ret;
auto parent_process = [&func_graph, &buffer_ret, this](MultiProcess *multi_process) -> Status {
MS_EXCEPTION_IF_NULL(multi_process);
auto df_graph = ConvertFuncGraphToAIR(func_graph);
if (df_graph == nullptr) {
MS_LOG(ERROR) << "Convert FuncGraph to AscendIR failed.";
return kMCFailed;
}
ge::Model model;
ge::Buffer model_data;
model.SetGraph(*df_graph);
auto ge_ret = model.Save(model_data);
if (ge_ret != ge::SUCCESS) {
MS_LOG(ERROR) << "Save ge model to buffer failed.";
return kMCFailed;
}
// send original model to child
auto status = multi_process->SendMsg(model_data.data(), model_data.size());
if (status != kSuccess) {
MS_LOG_ERROR << "Send original model to child process failed";
return status;
}
// receive convert model result from child
CreateBufferCall call = [&buffer_ret](size_t msg_len) -> uint8_t * {
(void)buffer_ret.ResizeData(msg_len);
return reinterpret_cast<uint8_t *>(buffer_ret.MutableData());
};
status = multi_process->ReceiveMsg(call);
if (status != kSuccess) {
MS_LOG_ERROR << "Receive result model from child process failed";
return status;
}
return kSuccess;
};
auto child_process = [this](MultiProcess *multi_process) -> Status {
MS_EXCEPTION_IF_NULL(multi_process);
// receive original model from parent
Buffer model;
CreateBufferCall call = [&model](size_t msg_len) -> uint8_t * {
(void)model.ResizeData(msg_len);
return reinterpret_cast<uint8_t *>(model.MutableData());
};
auto status = multi_process->ReceiveMsg(call);
if (status != kSuccess) {
MS_LOG_ERROR << "Receive original model from parent process failed";
return status;
}
Buffer model_result = LoadAscendIRInner(model);
if (model_result.DataSize() == 0) {
MS_LOG_ERROR << "Convert model from MindIR to OM failed";
return kMCFailed;
}
// send result model to parent
status = multi_process->SendMsg(model_result.Data(), model_result.DataSize());
if (status != kSuccess) {
MS_LOG_ERROR << "Send result model to parent process failed";
return status;
}
return kSuccess;
};
auto status = multi_process.MainProcess(parent_process, child_process);
if (status != kSuccess) {
MS_LOG_ERROR << "Convert MindIR model to OM model failed";
} else {
MS_LOG_INFO << "Convert MindIR model to OM model success";
}
return buffer_ret;
}
Buffer ModelConverter::LoadAscendIRInner(const Buffer &model_data) {
ge::Model load_model = ge::Model("loadmodel", "version2");
ge::Status ret =
ge::Model::Load(reinterpret_cast<const uint8_t *>(model_data.Data()), model_data.DataSize(), load_model);
if (ret != ge::GRAPH_SUCCESS) {
MS_LOG(ERROR) << "Load AscendIR failed, ret = " << ret;
return Buffer();
}
transform::DfGraphPtr df_graph = std::make_shared<transform::DfGraph>(load_model.GetGraph());
if (df_graph == nullptr) {
MS_LOG(ERROR) << "Convert FuncGraph to AscendIR failed.";
return Buffer();
}
std::map<std::string, std::string> init_options;
std::map<std::string, std::string> build_options;
auto option = options_.lock();
if (option != nullptr) {
std::tie(init_options, build_options) = option->GenAclOptions();
}
return BuildAirModel(df_graph, init_options, build_options);
}
} // namespace mindspore

View File

@ -1,50 +0,0 @@
/**
* Copyright 2020 Huawei Technologies Co., Ltd
*
* 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.
*/
#ifndef MINDSPORE_LITE_SRC_EXTENDRT_CXX_API_MODEL_ACL_MODEL_CONVERTER_H_
#define MINDSPORE_LITE_SRC_EXTENDRT_CXX_API_MODEL_ACL_MODEL_CONVERTER_H_
#include <vector>
#include <string>
#include <map>
#include <memory>
#include "include/api/types.h"
#include "include/api/status.h"
#include "mindspore/core/ir/func_graph.h"
#include "include/transform/graph_ir/types.h"
#include "external/ge/ge_ir_build.h"
#include "extendrt/acl/acl_model_options.h"
namespace mindspore {
class MS_API ModelConverter {
public:
ModelConverter() : options_() {}
~ModelConverter() = default;
Buffer LoadMindIR(const FuncGraphPtr &func_graph);
void set_options(const std::weak_ptr<AclModelOptions> &options) { options_ = options; }
Status SaveModel(const ge::ModelBufferData &model);
private:
transform::DfGraphPtr ConvertFuncGraphToAIR(const FuncGraphPtr &anf_graph);
Buffer BuildAirModel(const transform::DfGraphPtr &graph, const std::map<std::string, std::string> &init_options,
const std::map<std::string, std::string> &build_options);
Buffer LoadAscendIRInner(const Buffer &model_data);
std::weak_ptr<AclModelOptions> options_;
};
} // namespace mindspore
#endif // MINDSPORE_LITE_SRC_EXTENDRT_CXX_API_MODEL_ACL_MODEL_CONVERTER_H_

View File

@ -1,246 +0,0 @@
/**
* Copyright 2020 Huawei Technologies Co., Ltd
*
* 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 "extendrt/acl/model_converter_utils/multi_process.h"
#include <unistd.h>
#include <sys/wait.h>
#include <algorithm>
#include <vector>
#include <thread>
#include "mindspore/core/utils/log_adapter.h"
#include "extendrt/acl/model_converter_utils/shared_memory.h"
namespace mindspore {
namespace {
constexpr uint64_t kSharedMemorySize = 100ull << 20; // 100 MB
constexpr timespec kOneMillisecond = {
0, // 0 seconds
1 * 1000L * 1000L, // And 1 ms
};
constexpr timespec kOneHundredMilliseconds = {
0, // 0 seconds
100 * 1000L * 1000L, // And 100 ms
};
} // namespace
MultiProcess::MultiProcess() = default;
MultiProcess::~MultiProcess() = default;
Status MultiProcess::MainProcess(const ProcessFuncCall &parent_process, const ProcessFuncCall &child_process) {
MS_EXCEPTION_IF_NULL(parent_process);
MS_EXCEPTION_IF_NULL(child_process);
Status ret;
memory_size_ = kSharedMemorySize; // 100 MB
SharedMemory shared_memory;
ret = shared_memory.Create(memory_size_);
if (ret != kSuccess) {
MS_LOG_ERROR << "Create shared memory failed";
return ret;
}
pid_t pid = fork();
if (pid < 0) {
shared_memory.Destroy();
MS_LOG_ERROR << "Fork process to convert model failed";
return kMEFailed;
}
ret = shared_memory.Attach();
if (ret != kSuccess) {
MS_LOG_ERROR << "Process attach shared memory failed, pid " << pid;
return ret;
}
shmat_addr_ = shared_memory.GetSharedMemoryAddr();
if (shmat_addr_ == nullptr) {
MS_LOG_ERROR << "Get shared memory failed";
return ret;
}
constexpr size_t kMsgStructNum = 2;
shmat_data_addr_ = shmat_addr_ + sizeof(MessageFlag) * kMsgStructNum;
shmat_data_max_size_ =
memory_size_ - (reinterpret_cast<uintptr_t>(shmat_data_addr_) - reinterpret_cast<uintptr_t>(shmat_addr_));
MS_LOG_INFO << "Shm addr " << (uintptr_t)shmat_addr_;
if (pid == 0) {
ChildProcess(child_process);
shared_memory.Detach();
MS_LOG_INFO << "Model converter: child process sleep waiting for exit signal.";
while (1) {
// waiting for signal
}
} else { // parent process
ret = ParentProcess(parent_process);
shared_memory.Detach();
MS_LOG_INFO << "Model converter: parent process kills child of fork.";
(void)kill(pid, SIGKILL);
constexpr uint32_t kMaxLoopCount = 5;
bool child_exited = false;
for (uint32_t i = 0; i < kMaxLoopCount; ++i) {
int status;
if (waitpid(pid, &status, WNOHANG) == pid) {
MS_LOG(INFO) << "Child process " << pid << " exits success.";
child_exited = true;
break;
}
(void)sleep(1);
}
if (!child_exited) {
MS_LOG(WARNING) << "Child process " << pid << " has been killed but waitpid failed.";
}
shared_memory.Destroy();
}
return ret;
}
Status MultiProcess::ParentProcess(const ProcessFuncCall &parent_process) {
auto parent_msg = reinterpret_cast<MessageFlag *>(shmat_addr_);
auto child_msg = reinterpret_cast<MessageFlag *>(shmat_addr_ + sizeof(MessageFlag));
send_msg_ = parent_msg;
receive_msg_ = child_msg;
std::thread heartbeat_thread(MultiProcess::HeartbeatThreadFunc, this);
Status ret;
try {
ret = parent_process(this);
if (ret != kSuccess) {
MS_LOG_ERROR << "Parent process process failed";
}
} catch (const std::runtime_error &ex) {
MS_LOG_ERROR << "Catch parent process runtime error: " << ex.what();
ret = kMEFailed;
}
stopped_ = true;
send_msg_->stop = 1;
heartbeat_thread.join();
return ret;
}
void MultiProcess::ChildProcess(const ProcessFuncCall &child_process) {
auto parent_msg = reinterpret_cast<MessageFlag *>(shmat_addr_);
auto child_msg = reinterpret_cast<MessageFlag *>(shmat_addr_ + sizeof(MessageFlag));
send_msg_ = child_msg;
receive_msg_ = parent_msg;
std::thread heartbeat_thread(MultiProcess::HeartbeatThreadFunc, this);
try {
MS_EXCEPTION_IF_NULL(child_process);
auto ret = child_process(this);
if (ret != kSuccess) {
MS_LOG_ERROR << "Child process process failed";
}
} catch (const std::runtime_error &ex) {
MS_LOG_ERROR << "Catch child process runtime error: " << ex.what();
}
stopped_ = true;
send_msg_->stop = 1;
heartbeat_thread.join();
}
Status MultiProcess::SendMsg(const void *buffer, uint64_t msg_len) {
MS_EXCEPTION_IF_NULL(buffer);
MS_LOG_INFO << "Start to send message to peer process, msg len " << msg_len;
send_msg_->msg_total_len = msg_len;
uint64_t cur_offset = 0;
while (msg_len > cur_offset) {
uint64_t sub_msg_len = std::min(msg_len - cur_offset, shmat_data_max_size_);
if (sub_msg_len == 0) {
MS_LOG(ERROR) << "Invalid message len " << sub_msg_len;
return kMEFailed;
}
auto ret =
memcpy_s(shmat_data_addr_, shmat_data_max_size_, static_cast<const uint8_t *>(buffer) + cur_offset, sub_msg_len);
if (ret != EOK) {
MS_LOG(ERROR) << "memcpy_s failed, ret = " << ret;
return kMEFailed;
}
cur_offset += sub_msg_len;
send_msg_->msg_len = sub_msg_len;
send_msg_->read_finish_flag = 0;
send_msg_->read_ready_flag = 1;
MS_LOG_INFO << "Send start " << cur_offset << ", msg len " << sub_msg_len << ", total len " << msg_len;
while (!send_msg_->read_finish_flag && !peer_stopped_) {
(void)nanosleep(&kOneMillisecond, nullptr); // 1ms
}
if (peer_stopped_) {
if (!send_msg_->read_finish_flag) {
return kMEFailed;
}
break;
}
MS_LOG_INFO << "Send end " << cur_offset << ", msg len " << sub_msg_len << ", total len " << msg_len;
}
MS_LOG_INFO << "End to send message to peer process, msg len " << msg_len;
return kSuccess;
}
Status MultiProcess::ReceiveMsg(const CreateBufferCall &create_buffer_call) {
uint64_t cur_offset = 0;
uint8_t *msg_buffer = nullptr;
uint64_t msg_len = 0;
do {
MS_LOG_INFO << "Receive start from " << cur_offset;
while (!receive_msg_->read_ready_flag && !peer_stopped_) {
(void)nanosleep(&kOneMillisecond, nullptr); // 1ms
}
if (peer_stopped_) {
return kMEFailed;
}
if (msg_buffer == nullptr) {
msg_len = receive_msg_->msg_total_len;
msg_buffer = create_buffer_call(msg_len);
}
MS_EXCEPTION_IF_NULL(msg_buffer);
auto ret = memcpy_s(msg_buffer + cur_offset, msg_len - cur_offset, shmat_data_addr_, receive_msg_->msg_len);
if (ret != EOK) {
MS_LOG(INFO) << "memcpy_s failed, ret = " << ret;
return kMEFailed;
}
cur_offset += receive_msg_->msg_len;
receive_msg_->read_ready_flag = 0;
receive_msg_->read_finish_flag = 1;
MS_LOG_INFO << "Receive end, current length " << cur_offset << ", total length " << msg_len << std::endl;
} while (msg_len > cur_offset);
return kSuccess;
}
void MultiProcess::HeartbeatThreadFunc(MultiProcess *multi_process) { multi_process->HeartbeatThreadFuncInner(); }
void MultiProcess::HeartbeatThreadFuncInner() {
constexpr uint64_t kOvertime = 1024;
uint64_t last_beat_cnt = 0;
uint64_t repeat_cnt = 0;
while (!stopped_) {
if (receive_msg_->stop) {
peer_stopped_ = true;
MS_LOG_WARNING << "Peer stopped";
break;
}
uint64_t heartbeat_gap = receive_msg_->heartbeat - last_beat_cnt;
if (heartbeat_gap > 0 && heartbeat_gap < kOvertime) {
last_beat_cnt = receive_msg_->heartbeat;
repeat_cnt = 0;
} else {
repeat_cnt++;
if (repeat_cnt > 30) { // 30*100ms = 3s no reply
peer_stopped_ = true;
MS_LOG_WARNING << "Peer stopped";
break;
}
}
send_msg_->heartbeat += 1;
(void)nanosleep(&kOneHundredMilliseconds, nullptr); // sleep 100 ms
}
}
} // namespace mindspore

View File

@ -1,62 +0,0 @@
/**
* Copyright 2020 Huawei Technologies Co., Ltd
*
* 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.
*/
#ifndef MINDSPORE_LITE_SRC_EXTENDRT_CXX_API_MODEL_MODEL_CONVERTER_UTILS_MULTI_PROCESS_H_
#define MINDSPORE_LITE_SRC_EXTENDRT_CXX_API_MODEL_MODEL_CONVERTER_UTILS_MULTI_PROCESS_H_
#include <iostream>
#include <functional>
#include "include/api/status.h"
namespace mindspore {
struct MessageFlag {
uint64_t heartbeat = 0;
uint64_t stop = false;
uint64_t msg_len = 0;
uint64_t msg_total_len = 0;
uint64_t read_ready_flag = false;
uint64_t read_finish_flag = false;
};
class MultiProcess;
using ProcessFuncCall = std::function<Status(MultiProcess *multi_process)>;
using CreateBufferCall = std::function<uint8_t *(size_t msg_len)>;
class MultiProcess {
public:
MultiProcess();
~MultiProcess();
Status MainProcess(const ProcessFuncCall &parent_process, const ProcessFuncCall &child_process);
Status SendMsg(const void *buffer, uint64_t msg_len);
Status ReceiveMsg(const CreateBufferCall &create_buffer_call);
private:
uint8_t *shmat_addr_ = nullptr;
uint8_t *shmat_data_addr_ = nullptr;
uint64_t shmat_data_max_size_ = 0;
uint64_t memory_size_ = 0;
bool peer_stopped_ = false;
bool stopped_ = false;
MessageFlag *send_msg_ = nullptr;
MessageFlag *receive_msg_ = nullptr;
static void HeartbeatThreadFunc(MultiProcess *multi_process);
void HeartbeatThreadFuncInner();
Status ParentProcess(const ProcessFuncCall &parent_process);
void ChildProcess(const ProcessFuncCall &child_process);
};
} // namespace mindspore
#endif // MINDSPORE_LITE_SRC_EXTENDRT_CXX_API_MODEL_MODEL_CONVERTER_UTILS_MULTI_PROCESS_H_

View File

@ -1,65 +0,0 @@
/**
* Copyright 2020 Huawei Technologies Co., Ltd
*
* 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 "extendrt/acl/model_converter_utils/shared_memory.h"
#include <sys/shm.h>
#include <sys/stat.h>
#include <string>
#include "mindspore/core/utils/log_adapter.h"
namespace mindspore {
Status SharedMemory::Create(uint64_t memory_size) {
auto access_mode = S_IRUSR | S_IWUSR | S_IROTH | S_IWOTH | S_IRGRP | S_IWGRP;
shm_id_ = shmget(IPC_PRIVATE, memory_size, IPC_CREAT | IPC_EXCL | access_mode);
if (shm_id_ == -1) {
MS_LOG_ERROR << "Shared memory creation failed. Errno " + std::to_string(errno);
return kMCFailed;
}
MS_LOG_INFO << "shmget success, shm id " << shm_id_;
return kSuccess;
}
Status SharedMemory::Attach() {
void *shmat_addr = shmat(shm_id_, nullptr, 0);
if (shmat_addr == reinterpret_cast<void *>(-1)) {
MS_LOG_ERROR << "Shared memory attach failed. Errno " + std::to_string(errno);
return kMCFailed;
}
shmat_addr_ = reinterpret_cast<uint8_t *>(shmat_addr);
return kSuccess;
}
void SharedMemory::Detach() {
if (shmat_addr_ != nullptr) {
auto err = shmdt(shmat_addr_);
if (err == -1) {
MS_LOG_ERROR << "Shared memory detach failed. Errno " + std::to_string(errno);
return;
}
}
shmat_addr_ = nullptr;
}
void SharedMemory::Destroy() {
// Remove the shared memory and never mind about the return code.
auto err = shmctl(shm_id_, IPC_RMID, nullptr);
if (err == -1) {
std::string errMsg = "Unable to remove shared memory with id " + std::to_string(shm_id_);
errMsg += ". Errno :" + std::to_string(errno);
errMsg += "\nPlesae remove it manually using ipcrm -m command";
MS_LOG_ERROR << errMsg;
}
}
} // namespace mindspore

View File

@ -1,37 +0,0 @@
/**
* Copyright 2020 Huawei Technologies Co., Ltd
*
* 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.
*/
#ifndef MINDSPORE_LITE_SRC_EXTENDRT_CXX_API_MODEL_MODEL_CONVERTER_UTILS_SHARED_MEMORY_H_
#define MINDSPORE_LITE_SRC_EXTENDRT_CXX_API_MODEL_MODEL_CONVERTER_UTILS_SHARED_MEMORY_H_
#include <iostream>
#include "include/api/status.h"
namespace mindspore {
class SharedMemory {
public:
Status Create(uint64_t memory_size);
Status Attach();
void Detach();
void Destroy();
private:
friend class MultiProcess;
uint8_t *GetSharedMemoryAddr() { return shmat_addr_; }
int shm_id_ = -1;
uint8_t *shmat_addr_ = nullptr;
};
} // namespace mindspore
#endif // MINDSPORE_LITE_SRC_EXTENDRT_CXX_API_MODEL_MODEL_CONVERTER_UTILS_SHARED_MEMORY_H_

View File

@ -1,531 +0,0 @@
/**
* Copyright 2020 Huawei Technologies Co., Ltd
*
* 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 "extendrt/acl/model_process.h"
#include <sys/time.h>
#include <algorithm>
#include <map>
#include "include/common/utils/utils.h"
#include "mindspore/core/utils/convert_utils_base.h"
namespace mindspore {
static DataType TransToApiType(aclDataType data_type) {
static const std::map<aclDataType, enum DataType> data_type_map = {
{ACL_FLOAT16, DataType::kNumberTypeFloat16}, {ACL_FLOAT, DataType::kNumberTypeFloat32},
{ACL_DOUBLE, DataType::kNumberTypeFloat64}, {ACL_INT8, DataType::kNumberTypeInt8},
{ACL_INT16, DataType::kNumberTypeInt16}, {ACL_INT32, DataType::kNumberTypeInt32},
{ACL_INT64, DataType::kNumberTypeInt64}, {ACL_UINT8, DataType::kNumberTypeUInt8},
{ACL_UINT16, DataType::kNumberTypeUInt16}, {ACL_UINT32, DataType::kNumberTypeUInt32},
{ACL_UINT64, DataType::kNumberTypeUInt64}, {ACL_BOOL, DataType::kNumberTypeBool},
};
auto it = data_type_map.find(data_type);
if (it == data_type_map.end()) {
return DataType::kTypeUnknown;
} else {
return it->second;
}
}
template <class T>
inline static void ClearIfNotNull(T *vec) {
if (vec != nullptr) {
vec->clear();
}
}
template <class T, class U = std::vector<T>>
inline static void PushbackIfNotNull(U *vec, T &&item) {
if (vec != nullptr) {
vec->emplace_back(item);
}
}
static void ConstructTensorDesc(const std::vector<AclTensorInfo> &acl_tensor_list, std::vector<std::string> *names,
std::vector<std::vector<int64_t>> *shapes, std::vector<enum DataType> *data_types,
std::vector<size_t> *mem_sizes) {
ClearIfNotNull(names);
ClearIfNotNull(shapes);
ClearIfNotNull(data_types);
ClearIfNotNull(mem_sizes);
for (size_t i = 0; i < acl_tensor_list.size(); ++i) {
const auto &info = acl_tensor_list[i];
PushbackIfNotNull(names, info.name);
PushbackIfNotNull(shapes, info.dims);
PushbackIfNotNull(data_types, TransToApiType(info.data_type));
PushbackIfNotNull(mem_sizes, info.buffer_size);
}
}
static std::string ShapeToString(const std::vector<int64_t> &shape) {
std::string result = "[";
for (size_t i = 0; i < shape.size(); ++i) {
result += std::to_string(shape[i]);
if (i + 1 < shape.size()) {
result += ", ";
}
}
result += "]";
return result;
}
Status ModelProcess::ConstructTensors(const std::vector<AclTensorInfo> &acl_tensor_list,
std::vector<MSTensor> *tensor_list) {
MS_EXCEPTION_IF_NULL(tensor_list);
std::vector<std::string> names;
std::vector<std::vector<int64_t>> shapes;
std::vector<enum DataType> data_types;
std::vector<size_t> mem_sizes;
ConstructTensorDesc(acl_tensor_list, &names, &shapes, &data_types, &mem_sizes);
tensor_list->clear();
if (names.size() != acl_tensor_list.size() || shapes.size() != acl_tensor_list.size() ||
data_types.size() != acl_tensor_list.size() || mem_sizes.size() != acl_tensor_list.size()) {
MS_LOG(ERROR) << "Inner error, size do not match: names size " << names.size() << " shapes size " << shapes.size()
<< " data types size " << data_types.size() << " mem sizes size " << mem_sizes.size()
<< " acl_tensor_list size " << acl_tensor_list.size();
return kMCFailed;
}
aclrtMemcpyKind kind = is_run_on_device_ ? ACL_MEMCPY_HOST_TO_HOST : ACL_MEMCPY_DEVICE_TO_HOST;
for (size_t i = 0; i < acl_tensor_list.size(); ++i) {
tensor_list->emplace_back(names[i], data_types[i], shapes[i], nullptr, mem_sizes[i]);
if (acl_tensor_list[i].cur_device_data == nullptr) {
// when run on device, cur_device_data is nullptr before first execute
continue;
}
auto ret = aclrtMemcpy((*tensor_list)[i].MutableData(), (*tensor_list)[i].DataSize(),
acl_tensor_list[i].cur_device_data, acl_tensor_list[i].buffer_size, kind);
if (ret != ACL_ERROR_NONE) {
MS_LOG(ERROR) << "Memcpy input " << i << " from " << (is_run_on_device_ ? "host" : "device")
<< " to host failed, memory size " << acl_tensor_list[i].buffer_size;
return kMCFailed;
}
}
return kSuccess;
}
Status ModelProcess::PreInitModelResource() {
model_desc_ = aclmdlCreateDesc();
aclError acl_ret = aclmdlGetDesc(model_desc_, model_id_);
if (acl_ret != ACL_ERROR_NONE) {
MS_LOG(ERROR) << "Read model desc failed";
return kMCDeviceError;
}
Status ret = InitInputsBuffer();
if (ret != kSuccess) {
MS_LOG(ERROR) << "Create input buffer failed";
return ret;
}
ret = InitOutputsBuffer();
if (ret != kSuccess) {
MS_LOG(ERROR) << "Create output buffer failed";
return ret;
}
return kSuccess;
}
Status ModelProcess::InitInputsBuffer() {
aclError ret;
size_t input_size = aclmdlGetNumInputs(model_desc_);
MS_LOG(INFO) << "input_size = " << input_size;
for (size_t i = 0; i < input_size; ++i) {
auto buffer_size = aclmdlGetInputSizeByIndex(model_desc_, i);
void *data_mem_buffer = nullptr;
if (!is_run_on_device_) { // need to copy input/output to/from device
ret = aclrtMalloc(&data_mem_buffer, buffer_size, ACL_MEM_MALLOC_NORMAL_ONLY);
if (ret != ACL_ERROR_NONE) {
MS_LOG(ERROR) << "Malloc device input buffer failed , input size " << buffer_size;
return kMCDeviceError;
}
}
aclmdlIODims dims;
ret = aclmdlGetInputDims(model_desc_, i, &dims);
if (ret != ACL_ERROR_NONE) {
MS_LOG(ERROR) << "Get input shape failed";
if (!is_run_on_device_) {
(void)aclrtFree(data_mem_buffer);
}
return kMCDeviceError;
}
aclDataType data_type = aclmdlGetInputDataType(model_desc_, i);
std::vector<int64_t> shape(dims.dims, dims.dims + dims.dimCount);
const char *input_name_char = aclmdlGetInputNameByIndex(model_desc_, i);
std::string input_name = (input_name_char != nullptr) ? input_name_char : std::string();
if (input_name.empty()) {
MS_LOG(WARNING) << "Get name of input " << i << " failed.";
}
MS_LOG(INFO) << "Name of input " << i << " is " << input_name;
input_infos_.emplace_back(
AclTensorInfo{data_mem_buffer, data_mem_buffer, buffer_size, data_type, shape, input_name});
}
MS_LOG(INFO) << "Create model inputs success";
return kSuccess;
}
Status ModelProcess::CreateDataBuffer(void **data_mem_buffer, size_t buffer_size, aclmdlDataset *dataset) const {
MS_EXCEPTION_IF_NULL(data_mem_buffer);
aclError ret;
auto free_data_buffer = [this](void *dataMemBuffer) {
if (!is_run_on_device_) {
(void)aclrtFree(dataMemBuffer);
} else {
(void)aclrtFreeHost(dataMemBuffer);
}
};
if (!is_run_on_device_) {
ret = aclrtMalloc(data_mem_buffer, buffer_size, ACL_MEM_MALLOC_NORMAL_ONLY);
if (ret != ACL_ERROR_NONE) {
MS_LOG(ERROR) << "Malloc device buffer failed , buffer size " << buffer_size;
return kMCDeviceError;
}
} else {
ret = aclrtMallocHost(data_mem_buffer, buffer_size);
if (ret != ACL_ERROR_NONE) {
MS_LOG(ERROR) << "Malloc device buffer failed , buffer size " << buffer_size;
return kMCDeviceError;
}
}
auto data_buffer = aclCreateDataBuffer(*data_mem_buffer, buffer_size);
if (data_buffer == nullptr) {
MS_LOG(ERROR) << "Create Data Buffer failed";
free_data_buffer(*data_mem_buffer);
return kMCDeviceError;
}
ret = aclmdlAddDatasetBuffer(dataset, data_buffer);
if (ret != ACL_ERROR_NONE) {
MS_LOG(ERROR) << "add data buffer failed";
free_data_buffer(*data_mem_buffer);
(void)aclDestroyDataBuffer(data_buffer);
return kMCDeviceError;
}
return kSuccess;
}
Status ModelProcess::InitOutputsBuffer() {
aclError ret;
outputs_ = aclmdlCreateDataset();
if (outputs_ == nullptr) {
MS_LOG(ERROR) << "Create input dataset failed";
return kMCDeviceError;
}
size_t output_size = aclmdlGetNumOutputs(model_desc_);
MS_LOG(INFO) << "output_size = " << output_size;
for (size_t i = 0; i < output_size; ++i) {
auto buffer_size = aclmdlGetOutputSizeByIndex(model_desc_, i);
void *data_mem_buffer = nullptr;
if (CreateDataBuffer(&data_mem_buffer, buffer_size, outputs_) != kSuccess) {
MS_LOG(ERROR) << "add output data buffer failed, buffer size " << buffer_size;
return kMCDeviceError;
}
aclmdlIODims dims;
ret = aclmdlGetOutputDims(model_desc_, i, &dims);
if (ret != ACL_ERROR_NONE) {
MS_LOG(ERROR) << "Get input shape failed";
if (!is_run_on_device_) {
(void)aclrtFree(data_mem_buffer);
} else {
(void)aclrtFreeHost(data_mem_buffer);
}
return kMCDeviceError;
}
aclDataType data_type = aclmdlGetOutputDataType(model_desc_, i);
std::vector<int64_t> shape(dims.dims, dims.dims + dims.dimCount);
const char *output_name_char = aclmdlGetOutputNameByIndex(model_desc_, i);
std::string output_name = (output_name_char != nullptr) ? output_name_char : std::string();
if (output_name.empty()) {
MS_LOG(WARNING) << "Get name of output " << i << " failed.";
}
MS_LOG(INFO) << "Name of input " << i << " is " << output_name;
output_infos_.emplace_back(
AclTensorInfo{data_mem_buffer, data_mem_buffer, buffer_size, data_type, shape, output_name});
}
MS_LOG(INFO) << "Create model output success";
return kSuccess;
}
void ModelProcess::DestroyInputsDataset() {
if (inputs_ == nullptr) {
return;
}
for (size_t i = 0; i < aclmdlGetDatasetNumBuffers(inputs_); i++) {
auto dataBuffer = aclmdlGetDatasetBuffer(inputs_, i);
(void)aclDestroyDataBuffer(dataBuffer);
}
(void)aclmdlDestroyDataset(inputs_);
inputs_ = nullptr;
}
void ModelProcess::DestroyInputsDataMem() {
if (!is_run_on_device_) {
for (const auto &item : input_infos_) {
(void)aclrtFree(item.device_data);
}
}
input_infos_.clear();
}
void ModelProcess::DestroyInputsBuffer() {
DestroyInputsDataMem();
DestroyInputsDataset();
}
void ModelProcess::DestroyOutputsBuffer() {
for (const auto &item : output_infos_) {
if (!is_run_on_device_) {
(void)aclrtFree(item.device_data);
} else {
(void)aclrtFreeHost(item.device_data);
}
}
output_infos_.clear();
if (outputs_ == nullptr) {
return;
}
for (size_t i = 0; i < aclmdlGetDatasetNumBuffers(outputs_); i++) {
auto dataBuffer = aclmdlGetDatasetBuffer(outputs_, i);
(void)aclDestroyDataBuffer(dataBuffer);
}
(void)aclmdlDestroyDataset(outputs_);
outputs_ = nullptr;
}
Status ModelProcess::UnLoad() {
auto ret = aclmdlUnload(model_id_);
if (ret != ACL_ERROR_NONE) {
MS_LOG(ERROR) << "Unload model failed";
return kMCDeviceError;
}
if (model_desc_ != nullptr) {
ret = aclmdlDestroyDesc(model_desc_);
if (ret != ACL_ERROR_NONE) {
MS_LOG(ERROR) << "Unload model failed";
return kMCDeviceError;
}
model_desc_ = nullptr;
}
DestroyInputsBuffer();
DestroyOutputsBuffer();
MS_LOG(INFO) << "End unload model " << model_id_;
return kSuccess;
}
size_t ModelProcess::GetDynamicDims(const std::vector<AclTensorInfo> &inputs) {
size_t max_num = 0;
for (auto input : inputs) {
size_t cur_num = std::count(input.dims.begin(), input.dims.end(), -1);
if (cur_num > max_num) {
max_num = cur_num;
}
}
return max_num;
}
Status ModelProcess::SetBatchSize(const std::vector<MSTensor> &inputs) {
size_t index;
aclError ret;
for (size_t i = 0; i < inputs.size(); i++) {
input_infos_[i].buffer_size = inputs[i].DataSize();
}
auto *p = reinterpret_cast<const float *>(inputs[inputs.size() - 1].Data().get());
MS_EXCEPTION_IF_NULL(p);
size_t dynamicBatchSize = FloatToSize(p[0]);
ret = aclmdlGetInputIndexByName(model_desc_, ACL_DYNAMIC_TENSOR_NAME, &index);
if (ret != ACL_ERROR_NONE) {
MS_LOG(ERROR) << "get index failed";
return kMCDeviceError;
}
ret = aclmdlSetDynamicBatchSize(model_id_, inputs_, index, dynamicBatchSize);
if (ret != ACL_ERROR_NONE) {
MS_LOG(ERROR) << "dynamic batch set failed, modelId is " << model_id_;
return kMCDeviceError;
}
return kSuccess;
}
Status ModelProcess::CheckAndInitInput(const std::vector<MSTensor> &inputs) {
aclError ret;
inputs_ = aclmdlCreateDataset();
constexpr size_t dynamic_batch_size = 1;
constexpr size_t dynamic_image_size = 2;
size_t dynamic_nums = GetDynamicDims(input_infos_);
// check inputs
if (inputs.size() != input_infos_.size()) {
MS_LOG(ERROR) << "Inputs count not match, required count " << input_infos_.size() << ", given count "
<< inputs.size();
return kMCInvalidInput;
}
if (dynamic_nums == 0) {
for (size_t i = 0; i < input_infos_.size(); ++i) {
if (inputs[i].Shape() != input_infos_[i].dims) {
MS_LOG(INFO) << "Note: input " << i << " shape not match, required " << ShapeToString(input_infos_[i].dims)
<< ", given " << ShapeToString(inputs[i].Shape());
}
if (inputs[i].DataType() != TransToApiType(input_infos_[i].data_type)) {
MS_LOG(INFO) << "Note: input " << i << " data type not match, required "
<< TransToApiType(input_infos_[i].data_type) << ", given " << inputs[i].DataType();
}
if (inputs[i].DataSize() != input_infos_[i].buffer_size) {
MS_LOG(ERROR) << "Input " << i << " data size not match, required size " << input_infos_[i].buffer_size
<< ", given count " << inputs[i].DataSize();
return kMCInvalidInput;
}
}
}
// copy inputs
for (size_t i = 0; i < input_infos_.size(); ++i) {
auto &info = input_infos_[i];
auto input = inputs[i];
void *data = input.MutableData();
void *input_buffer = nullptr;
if (!is_run_on_device_) {
if (input.IsDevice()) {
info.cur_device_data = data;
input_buffer = info.cur_device_data;
} else {
info.cur_device_data = info.device_data;
ret = aclrtMemcpy(info.cur_device_data, info.buffer_size, data, input.DataSize(), ACL_MEMCPY_HOST_TO_DEVICE);
if (ret != ACL_ERROR_NONE) {
MS_LOG(ERROR) << "Acl memcpy input " << i << " data to device failed, buffer size " << input.DataSize();
return kMCDeviceError;
}
input_buffer = info.cur_device_data;
}
} else {
input_buffer = data;
}
auto data_buffer = aclCreateDataBuffer(input_buffer, info.buffer_size);
if (data_buffer == nullptr) {
MS_LOG(ERROR) << "Create Data Buffer failed";
return kMCDeviceError;
}
ret = aclmdlAddDatasetBuffer(inputs_, data_buffer);
if (ret != ACL_ERROR_NONE) {
MS_LOG(ERROR) << "add data buffer failed";
(void)aclDestroyDataBuffer(data_buffer);
return kMCDeviceError;
}
}
if (dynamic_nums == dynamic_batch_size) {
if (SetBatchSize(inputs) != kSuccess) {
MS_LOG(ERROR) << "failed to convert dynamic batch size";
return kMCDeviceError;
}
if (ResetOutputSize() != kSuccess) {
MS_LOG(ERROR) << "reset output size failed";
return kMCDeviceError;
}
} else if (dynamic_nums == dynamic_image_size) {
MS_LOG(ERROR) << "only dynamic batch size is supported";
return kMCInvalidInput;
}
return kSuccess;
}
Status ModelProcess::ResetOutputSize() {
aclDataType output_type;
aclError ret;
size_t output_size = aclmdlGetNumOutputs(model_desc_);
for (size_t index = 0; index < output_size; index++) {
int64_t dims = 1;
struct aclmdlIODims output_dims;
ret = aclmdlGetCurOutputDims(model_desc_, index, &output_dims);
if (ret != ACL_ERROR_NONE) {
MS_LOG(ERROR) << "get output dim error.";
return kMCDeviceError;
}
for (size_t i = 0; i < output_dims.dimCount; i++) {
dims *= output_dims.dims[i];
}
output_type = aclmdlGetOutputDataType(model_desc_, index);
output_infos_[index].buffer_size = LongToSize(dims) * aclDataTypeSize(output_type);
}
return kSuccess;
}
Status ModelProcess::PredictFromHost(const std::vector<MSTensor> &inputs, std::vector<MSTensor> *outputs) {
MS_EXCEPTION_IF_NULL(outputs);
aclError acl_ret;
Status ret = CheckAndInitInput(inputs);
if (ret != kSuccess) {
MS_LOG(ERROR) << "check or init input failed";
DestroyInputsDataset();
return ret; // forward status error
}
struct timeval start_time;
struct timeval end_time;
(void)gettimeofday(&start_time, nullptr);
acl_ret = aclmdlExecute(model_id_, inputs_, outputs_);
(void)gettimeofday(&end_time, nullptr);
constexpr uint64_t kUSecondInSecond = 1000000;
uint64_t cost =
(kUSecondInSecond * static_cast<uint64_t>(end_time.tv_sec) + static_cast<uint64_t>(end_time.tv_usec)) -
(kUSecondInSecond * static_cast<uint64_t>(start_time.tv_sec) + static_cast<uint64_t>(start_time.tv_usec));
MS_LOG(INFO) << "Model execute in " << cost << " us";
DestroyInputsDataset();
if (acl_ret != ACL_ERROR_NONE) {
MS_LOG(ERROR) << "Execute Model Failed";
return kMCDeviceError;
}
ret = BuildOutputs(outputs);
if (ret != kSuccess) {
MS_LOG(ERROR) << "Build outputs failed";
return ret;
}
MS_LOG(INFO) << "Execute model success";
return kSuccess;
}
Status ModelProcess::BuildOutputs(std::vector<MSTensor> *outputs) {
MS_EXCEPTION_IF_NULL(outputs);
// copy outputs
outputs->clear();
auto inner_outputs = GetOutputs();
if (inner_outputs.size() != output_infos_.size()) {
MS_LOG(ERROR) << "Invalid inner outputs size " << inner_outputs.size() << " do not match device output infos size "
<< output_infos_.size();
return kMCFailed;
}
(*outputs) = inner_outputs;
return kSuccess;
}
std::vector<MSTensor> ModelProcess::GetInputs() {
Status ret = ConstructTensors(input_infos_, &input_tensors_);
if (ret != kSuccess) {
MS_LOG(ERROR) << "ConstructTensors failed.";
input_tensors_.clear();
}
return input_tensors_;
}
std::vector<MSTensor> ModelProcess::GetOutputs() {
Status ret = ConstructTensors(output_infos_, &output_tensors_);
if (ret != kSuccess) {
MS_LOG(ERROR) << "ConstructTensors failed.";
output_tensors_.clear();
}
return output_tensors_;
}
} // namespace mindspore

View File

@ -1,89 +0,0 @@
/**
* Copyright 2020 Huawei Technologies Co., Ltd
*
* 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.
*/
#ifndef MINDSPORE_LITE_SRC_EXTENDRT_CXX_API_GRAPH_ACL_MODEL_PROCESS_H_
#define MINDSPORE_LITE_SRC_EXTENDRT_CXX_API_GRAPH_ACL_MODEL_PROCESS_H_
#include <vector>
#include <string>
#include <map>
#include "acl/acl.h"
#include "acl/acl_mdl.h"
#include "acl/acl_rt.h"
#include "include/api/status.h"
#include "include/api/types.h"
namespace mindspore {
struct AclTensorInfo {
void *cur_device_data;
void *device_data;
size_t buffer_size;
aclDataType data_type;
std::vector<int64_t> dims;
std::string name;
};
class ModelProcess {
public:
ModelProcess()
: model_id_(0xffffffff),
is_run_on_device_(false),
model_desc_(nullptr),
inputs_(nullptr),
outputs_(nullptr),
input_infos_(),
output_infos_() {}
~ModelProcess() {}
Status UnLoad();
Status PredictFromHost(const std::vector<MSTensor> &inputs, std::vector<MSTensor> *outputs);
Status PreInitModelResource();
std::vector<MSTensor> GetInputs();
std::vector<MSTensor> GetOutputs();
// override this method to avoid request/reply data copy
void SetIsDevice(bool is_device) { is_run_on_device_ = is_device; }
void set_model_id(uint32_t model_id) { model_id_ = model_id; }
uint32_t model_id() const { return model_id_; }
private:
Status CreateDataBuffer(void **data_mem_buffer, size_t buffer_size, aclmdlDataset *dataset) const;
Status CheckAndInitInput(const std::vector<MSTensor> &inputs);
Status ConstructTensors(const std::vector<AclTensorInfo> &acl_tensor_list, std::vector<MSTensor> *tensor_list);
Status BuildOutputs(std::vector<MSTensor> *outputs);
Status SetBatchSize(const std::vector<MSTensor> &inputs);
Status InitInputsBuffer();
Status InitOutputsBuffer();
Status ResetOutputSize();
void DestroyInputsDataset();
void DestroyInputsDataMem();
void DestroyInputsBuffer();
void DestroyOutputsBuffer();
uint32_t model_id_;
// if run one device(AICPU), there is no need to alloc device memory and copy inputs to(/outputs from) device
bool is_run_on_device_;
aclmdlDesc *model_desc_;
aclmdlDataset *inputs_;
aclmdlDataset *outputs_;
std::vector<AclTensorInfo> input_infos_;
std::vector<AclTensorInfo> output_infos_;
std::vector<MSTensor> input_tensors_;
std::vector<MSTensor> output_tensors_;
size_t GetDynamicDims(const std::vector<AclTensorInfo> &);
};
} // namespace mindspore
#endif // MINDSPORE_LITE_SRC_EXTENDRT_CXX_API_GRAPH_ACL_MODEL_PROCESS_H_

View File

@ -1,455 +0,0 @@
/**
* Copyright 2020 Huawei Technologies Co., Ltd
*
* 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 "extendrt/ascend/ascend_infer.h"
#include <algorithm>
#include "include/api/context.h"
#include "extendrt/factory.h"
#include "extendrt/acl/acl_utils.h"
#include "utils/log_adapter.h"
#include "runtime/device/context_extends.h"
#include "mindspore/core/base/base_ref_utils.h"
#include "backend/common/session/session_factory.h"
#include "backend/common/session/executor_manager.h"
#include "runtime/device/kernel_runtime_manager.h"
#include "runtime/dev.h"
#include "frontend/parallel/strategy_checkpoint/parallel_strategy_checkpoint.h"
#include "include/common/utils/python_adapter.h"
namespace mindspore {
namespace {
constexpr auto kHcclEnable = "MS_ENABLE_HCCL";
constexpr auto kHcclGroupFile = "PARA_GROUP_FILE";
void InitHccl() {
auto ms_context = MsContext::GetInstance();
MS_EXCEPTION_IF_NULL(ms_context);
mindspore::python_adapter::set_python_env_flag(true);
uint32_t device_id = ms_context->get_param<uint32_t>(MS_CTX_DEVICE_ID);
if (ms_context->backend_policy() == "ms") {
auto runtime_instance = device::KernelRuntimeManager::Instance().GetKernelRuntime(kAscendDevice, device_id);
MS_EXCEPTION_IF_NULL(runtime_instance);
#ifndef ENABLE_SECURITY
runtime_instance->PreInit();
#endif
(void)context::OpenTsd(ms_context);
if (!runtime_instance->Init()) {
MS_LOG(EXCEPTION) << "Runtime init failed.";
}
} else {
(void)context::OpenTsd(ms_context);
}
}
bool CreateGroupsByCkptFile(const std::string &file) {
parallel::GroupInfoMap group_info_map;
if (parallel::StrategyCheckpoint::GetInstance().LoadGroupInfo(file, &group_info_map) != parallel::SUCCESS) {
return false;
}
for (const auto &[group_name, rank_ids] : group_info_map) {
if (!CommManager::GetInstance().CreateGroupSync(group_name, rank_ids)) {
MS_LOG(ERROR) << "Create group " << group_name << " rank ids " << rank_ids << " failed.";
return false;
}
}
MS_LOG(INFO) << "Create groups by checkpoint file success";
return true;
}
} // namespace
AscendInferExecutor::AscendInferExecutor()
: session_impl_(nullptr),
graph_id_(0),
device_type_("Ascend"),
device_id_(0),
context_(nullptr),
inputs_info_(),
outputs_info_(),
input_names_(),
output_names_(),
load_flag_(false) {}
AscendInferExecutor::~AscendInferExecutor() {}
Status AscendInferExecutor::InitEnv() {
MS_LOG(INFO) << "Start to init env.";
env_guard_ = MsEnvGuard::GetEnv(device_id_);
if (env_guard_ == nullptr) {
MS_LOG(ERROR) << "Env init failed.";
return kMCDeviceError;
}
session_impl_ = session::SessionFactory::Get().Create(kDavinciInferenceDevice);
if (session_impl_ == nullptr) {
MS_LOG(ERROR) << "Session create failed!, please make sure target device:" << kDavinciInferenceDevice
<< " is available.";
return kMCFailed;
}
session_impl_->Init(device_id_);
MS_LOG(INFO) << "InitEnv success.";
return kSuccess;
}
Status AscendInferExecutor::CompileGraph(const std::shared_ptr<FuncGraph> &funcGraphPtr) {
MS_ASSERT(session_impl_ != nullptr);
try {
graph_id_ = session_impl_->CompileGraph(NOT_NULL(funcGraphPtr));
return kSuccess;
} catch (std::exception &e) {
MS_LOG(ERROR) << "CompileGraph failed: " << e.what();
return kMCFailed;
}
}
std::vector<tensor::TensorPtr> AscendInferExecutor::RunGraph(const std::vector<tensor::TensorPtr> &inputs) {
try {
VectorRef outputs;
session_impl_->RunGraph(graph_id_, inputs, &outputs);
return TransformVectorRefToMultiTensor(outputs);
} catch (std::exception &e) {
MS_LOG(ERROR) << "RunGraph failed: " << e.what();
return std::vector<tensor::TensorPtr>();
}
}
Status AscendInferExecutor::CheckModelInputs(const std::vector<tensor::TensorPtr> &inputs) const {
MS_ASSERT(session_impl_ != nullptr);
std::string error_msg;
if (!session_impl_->CheckModelInputs(graph_id_, inputs, &error_msg)) {
return Status(kMCInvalidInput, error_msg);
}
return kSuccess;
}
Status AscendInferExecutor::ExecuteModel(const std::vector<MSTensor> &request, std::vector<MSTensor> *reply) {
MS_EXCEPTION_IF_NULL(reply);
if (context_ == nullptr) {
MS_LOG(ERROR) << "rtCtx is nullptr";
return kMCDeviceError;
}
rtError_t rt_ret = rtCtxSetCurrent(context_);
if (rt_ret != RT_ERROR_NONE) {
MS_LOG(ERROR) << "Set Ascend rtCtx failed";
return kMCDeviceError;
}
vector<tensor::TensorPtr> inputs;
for (size_t i = 0; i < request.size(); i++) {
auto item = request[i];
auto input = inputs_info_[i];
if (input->Size() != item.DataSize()) {
MS_LOG(ERROR) << "Input " << i << " data size " << item.DataSize() << " not match model input data size "
<< input->Size();
return kMCInvalidInput;
}
auto ret = memcpy_s(input->data_c(), input->Size(), item.MutableData(), item.DataSize());
if (ret != EOK) {
MS_LOG(ERROR) << "MSTensor copy failed";
return kMCFailed;
}
inputs.push_back(input);
}
last_inputs_ = inputs;
std::vector<tensor::TensorPtr> outputs = RunGraph(inputs);
if (outputs.empty()) {
MS_LOG(ERROR) << "Execute Model Failed";
return kMCFailed;
}
last_outputs_ = outputs;
reply->clear();
*reply = GetOutputs();
return kSuccess;
}
std::vector<MSTensor> AscendInferExecutor::GetInputs() {
if (!load_flag_) {
Status ret = Load(device_id_);
if (ret != kSuccess) {
MS_LOG(ERROR) << "PrepareModel failed.";
return {};
}
}
std::vector<MSTensor> result(inputs_info_.size());
for (size_t i = 0; i < inputs_info_.size(); ++i) {
auto &tensor = inputs_info_[i];
void *data = nullptr;
size_t data_size = tensor->Size();
if (i < last_inputs_.size()) {
data = last_inputs_[i]->data_c();
data_size = last_inputs_[i]->Size();
}
result[i] =
MSTensor(input_names_[i], static_cast<enum DataType>(tensor->data_type()), tensor->shape(), data, data_size);
}
return result;
}
std::vector<MSTensor> AscendInferExecutor::GetOutputs() {
if (!load_flag_) {
Status ret = Load(device_id_);
if (ret != kSuccess) {
MS_LOG(ERROR) << "PrepareModel failed.";
return {};
}
}
std::vector<MSTensor> result(outputs_info_.size());
for (size_t i = 0; i < outputs_info_.size(); ++i) {
auto &tensor = outputs_info_[i];
void *data = nullptr;
size_t data_size = tensor->Size();
if (i < last_outputs_.size()) {
data = last_outputs_[i]->data_c();
data_size = last_outputs_[i]->Size();
}
result[i] =
MSTensor(output_names_[i], static_cast<enum DataType>(tensor->data_type()), tensor->shape(), data, data_size);
}
return result;
}
Status AscendInferExecutor::Load(uint32_t device_id) {
// check graph type
if (graph_->ModelType() != ModelType::kMindIR) {
MS_LOG(ERROR) << "Unsupported model type " << graph_->ModelType();
return kMCInvalidInput;
}
const auto &graph_data = GraphImpl::MutableGraphData();
MS_EXCEPTION_IF_NULL(graph_data);
auto func_graph = graph_data->GetFuncGraph();
// init
device_id_ = device_id;
Status ret = InitEnv();
if (ret != kSuccess) {
MS_LOG(ERROR) << "InitEnv failed.";
return ret;
}
// load model
if (!load_flag_) {
ret = CompileGraph(func_graph);
if (ret != kSuccess) {
MS_LOG(ERROR) << "Compile graph model failed";
return ret;
}
MS_EXCEPTION_IF_NULL(session_impl_);
session_impl_->GetModelInputsInfo(graph_id_, &inputs_info_, &input_names_);
session_impl_->GetModelOutputsInfo(graph_id_, &outputs_info_, &output_names_);
if (inputs_info_.size() != input_names_.size()) {
MS_LOG_ERROR << "Get model inputs info failed";
return kMCInvalidInput;
}
if (outputs_info_.size() != output_names_.size()) {
MS_LOG_ERROR << "Get model outputs info failed";
return kMCInvalidInput;
}
// save d context
rtError_t rt_ret = rtCtxGetCurrent(&context_);
if (rt_ret != RT_ERROR_NONE || context_ == nullptr) {
MS_LOG(ERROR) << "the ascend device context is null";
return kMCDeviceError;
}
MS_LOG(INFO) << "Load model success";
load_flag_ = true;
}
rtError_t rt_ret = rtCtxSetCurrent(context_);
if (rt_ret != RT_ERROR_NONE) {
MS_LOG(ERROR) << "Set the ascend device context failed";
return kMCDeviceError;
}
return kSuccess;
}
Status AscendInferExecutor::Run(const std::vector<MSTensor> &inputs, std::vector<MSTensor> *outputs) {
MS_EXCEPTION_IF_NULL(outputs);
if (!load_flag_) {
Status ret = Load(device_id_);
if (ret != kSuccess) {
MS_LOG(ERROR) << "PrepareModel failed.";
return ret;
}
}
if (inputs.size() != inputs_info_.size()) {
MS_LOG(ERROR) << "inputs count not match, required count " << inputs_info_.size() << ", given count "
<< inputs.size();
return kMCInvalidInput;
}
for (size_t i = 0; i < inputs_info_.size(); ++i) {
if (inputs[i].DataSize() != inputs_info_[i]->Size()) {
MS_LOG(ERROR) << "input " << i << " data size not match, required size " << inputs_info_[i]->Size()
<< ", given count " << inputs[i].DataSize();
return kMCInvalidInput;
}
}
Status ret = ExecuteModel(inputs, outputs);
if (ret != kSuccess) {
MS_LOG(ERROR) << "Execute Model Failed";
return ret;
}
if (outputs_info_.size() != outputs->size()) {
MS_LOG(ERROR) << "Predict output size " << outputs->size() << " not match output size got from model info "
<< outputs_info_.size();
return kMCFailed;
}
return kSuccess;
}
AscendInferExecutor::MsEnvGuard::MsEnvGuard(uint32_t device_id) {
MS_LOG(INFO) << "Start to init device " << device_id;
device_id_ = device_id;
RegAllOp();
auto ms_context = MsContext::GetInstance();
if (ms_context == nullptr) {
MS_LOG(ERROR) << "Get Context failed!";
errno_ = kMCFailed;
return;
}
auto env_hccl_mode = common::GetEnv(kHcclEnable);
if (!env_hccl_mode.empty() && env_hccl_mode != std::to_string(0)) {
MS_LOG(INFO) << "Enable hccl parallel mode.";
ms_context->set_param<bool>(MS_CTX_ENABLE_HCCL, true);
}
ms_context->set_param<int>(MS_CTX_EXECUTION_MODE, kGraphMode);
ms_context->set_param<uint32_t>(MS_CTX_DEVICE_ID, device_id_);
ms_context->set_param<std::string>(MS_CTX_DEVICE_TARGET, kAscendDevice);
ms_context->set_param<bool>(MS_CTX_IS_MULTI_GRAPH_SINK, true);
if (ms_context->get_param<bool>(MS_CTX_ENABLE_HCCL)) {
InitHccl();
auto para_group_file = common::GetEnv(kHcclGroupFile);
if (para_group_file.empty()) {
MS_LOG(INFO) << "Cannot get Env " << kHcclGroupFile << ", skip.";
} else {
MS_LOG(INFO) << "Get env " << kHcclGroupFile << " success: " << para_group_file;
if (!CreateGroupsByCkptFile(para_group_file)) {
MS_LOG(ERROR) << "CreateGroupsByCkptFile failed.";
errno_ = kMCFailed;
return;
}
}
} else {
auto ret = rtSetDevice(static_cast<int32_t>(device_id_));
if (ret != RT_ERROR_NONE) {
MS_LOG(EXCEPTION) << "Device " << device_id_ << " call rtSetDevice failed, ret[" << static_cast<int>(ret) << "]";
}
}
MS_LOG(INFO) << "Device " << device_id << " init env success.";
errno_ = kSuccess;
}
AscendInferExecutor::MsEnvGuard::~MsEnvGuard() {
MS_LOG(INFO) << "Start finalize device " << device_id_;
session::ExecutorManager::Instance().Clear();
device::KernelRuntimeManager::Instance().ClearRuntimeResource();
auto ms_context = MsContext::GetInstance();
if (ms_context == nullptr) {
MS_LOG(ERROR) << "Get Context failed!";
return;
}
if (ms_context->get_param<bool>(MS_CTX_ENABLE_HCCL)) {
PythonEnvGuard guard;
if (!context::CloseTsd(ms_context)) {
MS_LOG(ERROR) << "CloseTsd failed!";
return;
}
} else {
auto ret = rtDeviceReset(static_cast<int32_t>(device_id_));
if (ret != RT_ERROR_NONE) {
MS_LOG(ERROR) << "Device " << device_id_ << " call rtDeviceReset failed, ret[" << static_cast<int>(ret) << "]";
return;
}
}
MS_LOG(INFO) << "End finalize device " << device_id_;
}
std::shared_ptr<AscendInferExecutor::MsEnvGuard> AscendInferExecutor::MsEnvGuard::GetEnv(uint32_t device_id) {
std::shared_ptr<MsEnvGuard> acl_env;
std::lock_guard<std::mutex> lock(global_ms_env_mutex_);
auto iter = global_ms_env_.find(device_id);
if (iter != global_ms_env_.end()) {
acl_env = iter->second.lock();
}
if (acl_env != nullptr) {
MS_LOG(INFO) << "Env has been initialized, skip.";
return acl_env;
}
acl_env = std::make_shared<MsEnvGuard>(device_id);
if (acl_env->GetErrno() != kSuccess) {
MS_LOG(ERROR) << "Init ascend env Failed";
return nullptr;
}
global_ms_env_.emplace(device_id, acl_env);
MS_LOG(INFO) << "Env init success";
return acl_env;
}
bool AscendInferExecutor::CheckDeviceSupport(mindspore::DeviceType device_type) {
// for Ascend, only support kAscend and kAscend910
if (device_type != kAscend && device_type != kAscend910) {
return false;
}
return IsAscend910Soc();
}
std::map<uint32_t, std::weak_ptr<AscendInferExecutor::MsEnvGuard>> AscendInferExecutor::MsEnvGuard::global_ms_env_;
std::mutex AscendInferExecutor::MsEnvGuard::global_ms_env_mutex_;
PythonEnvGuard::PythonEnvGuard() {
origin_init_status_ = PythonIsInited();
InitPython();
}
PythonEnvGuard::~PythonEnvGuard() {
// finalize when init by this
if (!origin_init_status_) {
FinalizePython();
}
}
bool PythonEnvGuard::PythonIsInited() const { return Py_IsInitialized() != 0; }
void PythonEnvGuard::InitPython() const {
if (!PythonIsInited()) {
Py_Initialize();
}
}
void PythonEnvGuard::FinalizePython() const {
if (PythonIsInited()) {
Py_Finalize();
}
}
} // namespace mindspore

View File

@ -1,87 +0,0 @@
/**
* Copyright 2020 Huawei Technologies Co., Ltd
*
* 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.
*/
#ifndef MINDSPORE_LITE_SRC_EXTENDRT_ASCEND_INFER_EXECUTOR_H_
#define MINDSPORE_LITE_SRC_EXTENDRT_ASCEND_INFER_EXECUTOR_H_
#include <functional>
#include <map>
#include <string>
#include <vector>
#include <memory>
#include <utility>
#include "include/api/status.h"
#include "include/api/graph.h"
#include "extendrt/graph_executor.h"
#include "runtime/context.h"
namespace mindspore {
class AscendInferExecutor : public GraphExecutor {
public:
AscendInferExecutor();
~AscendInferExecutor() override;
Status Execute(const ExecutePlan &plan, const std::vector<MSTensor> &inputs, std::vector<MSTensor> *outputs) override;
protected:
bool CheckDeviceSupport(mindspore::DeviceType device_type) override;
Status Load(uint32_t device_id);
Status InitEnv();
Status FinalizeEnv();
Status CheckModelInputs(const std::vector<tensor::TensorPtr> &inputs) const;
private:
uint32_t graph_id_;
std::string device_type_;
uint32_t device_id_;
rtContext_t context_;
std::vector<tensor::TensorPtr> inputs_info_;
std::vector<tensor::TensorPtr> outputs_info_;
std::vector<tensor::TensorPtr> last_inputs_;
std::vector<tensor::TensorPtr> last_outputs_;
std::vector<std::string> input_names_;
std::vector<std::string> output_names_;
bool load_flag_;
std::shared_ptr<MsEnvGuard> env_guard_;
};
class AscendInferSession::MsEnvGuard {
public:
explicit MsEnvGuard(uint32_t device_id);
~MsEnvGuard();
Status GetErrno() const { return errno_; }
static std::shared_ptr<MsEnvGuard> GetEnv(uint32_t device_id);
private:
static std::map<uint32_t, std::weak_ptr<MsEnvGuard>> global_ms_env_;
static std::mutex global_ms_env_mutex_;
Status errno_;
uint32_t device_id_;
};
class PythonEnvGuard {
public:
PythonEnvGuard();
~PythonEnvGuard();
private:
bool PythonIsInited() const;
void InitPython() const;
void FinalizePython() const;
bool origin_init_status_;
};
} // namespace mindspore
#endif // MINDSPORE_LITE_SRC_EXTENDRT_CXX_API_GRAPH_ASCEND_ASCEND_GRAPH_IMPL_H_

View File

@ -22,6 +22,7 @@
#include "src/litert/inner_allocator.h"
#include "src/common/log_adapter.h"
#include "src/extendrt/delegate/tensorrt/distribution/distribution_base.h"
#include "src/extendrt/delegate_graph_executor.h"
namespace mindspore {
constexpr auto kModelOptionCpuEnableFP16 = "mindspore.option.cpu.enable_fp16";
@ -171,15 +172,15 @@ std::vector<int32_t> Context::GetThreadAffinityCoreList() const {
return data_->affinity_core_list_;
}
void Context::SetDelegate(const std::shared_ptr<Delegate> &delegate) {
void Context::set_delegate(const std::shared_ptr<AbstractDelegate> &delegate) {
if (data_ == nullptr) {
MS_LOG(ERROR) << "Invalid context.";
return;
}
data_->delegate = delegate;
data_->delegate = std::dynamic_pointer_cast<GraphSinkDelegate>(delegate);
}
std::shared_ptr<Delegate> Context::GetDelegate() const {
std::shared_ptr<AbstractDelegate> Context::get_delegate() const {
if (data_ == nullptr) {
MS_LOG(ERROR) << "Invalid context.";
return nullptr;
@ -187,6 +188,12 @@ std::shared_ptr<Delegate> Context::GetDelegate() const {
return data_->delegate;
}
// deprecated
void Context::SetDelegate(const std::shared_ptr<Delegate> &delegate) { MS_LOG(ERROR) << "Invalid delegate."; }
// deprecated
std::shared_ptr<Delegate> Context::GetDelegate() const { return nullptr; }
void Context::SetMultiModalHW(bool float_mode) {
if (data_ == nullptr) {
MS_LOG(ERROR) << "Invalid context.";

View File

@ -27,6 +27,7 @@
#include <experimental/any>
#endif
#include "include/api/context.h"
#include "include/api/delegate_api.h"
namespace mindspore {
struct Context::Data {
@ -42,7 +43,7 @@ struct Context::Data {
int32_t thread_num = 0; // defaults are automatically adjusted based on computer performance
bool enable_parallel_ = false;
std::vector<int32_t> affinity_core_list_;
std::shared_ptr<Delegate> delegate = nullptr;
std::shared_ptr<AbstractDelegate> delegate = nullptr;
bool float_mode = false;
};

View File

@ -16,7 +16,6 @@
#ifndef MINDSPORE_LITE_SRC_RUNTIME_DELEGATE_DELEGATE_UTILS_H_
#define MINDSPORE_LITE_SRC_RUNTIME_DELEGATE_DELEGATE_UTILS_H_
#include <vector>
#include "include/api/delegate.h"
#include "src/common/log_adapter.h"
#include "include/errorcode.h"
#include "core/base/base.h"

View File

@ -20,14 +20,15 @@
#include <string>
#include <memory>
#include "include/api/delegate.h"
#include "utils/hash_map.h"
#include "extendrt/delegate/graph_executor/factory.h"
#include "extendrt/delegate/graph_executor/type.h"
#include "runtime/hardware/device_context.h"
#include "src/extendrt/delegate_graph_executor.h"
#include "include/api/context.h"
namespace mindspore {
typedef std::shared_ptr<Delegate> (*DelegateCreator)(const std::shared_ptr<mindspore::DelegateConfig> &config);
using mindspore::device::GraphExecutor;
// TODO(zhaizhiqiang): Wrap graph executor as delegate.
// typedef std::shared_ptr<GraphSinkDelegate> (*DelegateCreator)(const std::shared_ptr<Context> &);
typedef std::shared_ptr<GraphExecutor> (*DelegateCreator)(const std::shared_ptr<Context> &);
class MS_API DelegateRegistry {
public:
DelegateRegistry() = default;
@ -46,10 +47,10 @@ class MS_API DelegateRegistry {
it->second[provider] = creator;
}
std::shared_ptr<Delegate> GetDelegate(const mindspore::DeviceType &device_type, const std::string &provider,
const std::shared_ptr<mindspore::DelegateConfig> &config) {
std::shared_ptr<GraphExecutor> GetDelegate(const mindspore::DeviceType &device_type, const std::string &provider,
const std::shared_ptr<Context> &ctx) {
// first find graph executor delegate
auto graph_executor_delegate = GraphExecutorRegistry::GetInstance().GetDelegate(device_type, provider, config);
auto graph_executor_delegate = DelegateRegistry::GetInstance().GetDelegate(device_type, provider, ctx);
if (graph_executor_delegate != nullptr) {
return graph_executor_delegate;
}
@ -63,7 +64,7 @@ class MS_API DelegateRegistry {
if (creator_it == it->second.end()) {
return nullptr;
}
return creator_it->second(config);
return creator_it->second(ctx);
}
private:

View File

@ -1,24 +0,0 @@
/**
* Copyright 2019-2021 Huawei Technologies Co., Ltd
*
* 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 <memory>
#include "extendrt/delegate/graph_executor/delegate.h"
namespace mindspore {
Status GraphExecutorDelegate::Init() { return kSuccess; }
Status GraphExecutorDelegate::Build(DelegateModel<schema::Primitive> *model) { return kSuccess; }
} // namespace mindspore

View File

@ -1,47 +0,0 @@
/**
* Copyright 2019-2021 Huawei Technologies Co., Ltd
*
* 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.
*/
#ifndef MINDSPORE_LITE_SRC_EXTENDRT_DELEGATE_GRAPH_EXECUTOR_DELEGATE_H_
#define MINDSPORE_LITE_SRC_EXTENDRT_DELEGATE_GRAPH_EXECUTOR_DELEGATE_H_
#include <memory>
#include "include/api/delegate.h"
#include "extendrt/session/lite_graph_executor.h"
namespace mindspore {
class GraphExecutorDelegate : public Delegate {
public:
GraphExecutorDelegate() = default;
explicit GraphExecutorDelegate(std::shared_ptr<mindspore::LiteGraphExecutor> graph_executor)
: graph_executor_(graph_executor) {}
virtual ~GraphExecutorDelegate() = default;
virtual Status Init();
virtual Status Build(DelegateModel<schema::Primitive> *model);
std::shared_ptr<mindspore::LiteGraphExecutor> GetGraphExecutor() { return graph_executor_; }
void SetGraphExecutor(std::shared_ptr<mindspore::LiteGraphExecutor> graph_executor) {
graph_executor_ = graph_executor;
}
private:
std::shared_ptr<mindspore::LiteGraphExecutor> graph_executor_;
};
} // namespace mindspore
#endif // MINDSPORE_LITE_SRC_EXTENDRT_DELEGATE_GRAPH_EXECUTOR_DELEGATE_H_

View File

@ -1,23 +0,0 @@
/**
* Copyright 2019-2021 Huawei Technologies Co., Ltd
*
* 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 "extendrt/delegate/graph_executor/factory.h"
namespace mindspore {
GraphExecutorRegistry &GraphExecutorRegistry::GetInstance() {
static GraphExecutorRegistry instance;
return instance;
}
} // namespace mindspore

View File

@ -1,93 +0,0 @@
/**
* Copyright 2019-2021 Huawei Technologies Co., Ltd
*
* 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.
*/
#ifndef MINDSPORE_LITE_SRC_EXTENDRT_DELEGATE_GRAPH_EXECUTOR_FACTORY_H_
#define MINDSPORE_LITE_SRC_EXTENDRT_DELEGATE_GRAPH_EXECUTOR_FACTORY_H_
#include <functional>
#include <string>
#include <memory>
#include "extendrt/delegate/graph_executor/delegate.h"
#include "extendrt/delegate/graph_executor/type.h"
#include "utils/hash_map.h"
namespace mindspore {
typedef std::shared_ptr<LiteGraphExecutor> (*GraphExecutorCreator)(
const std::shared_ptr<mindspore::DelegateConfig> &config);
class MS_API GraphExecutorRegistry {
public:
GraphExecutorRegistry() = default;
virtual ~GraphExecutorRegistry() = default;
static GraphExecutorRegistry &GetInstance();
void RegGraphExecutor(const mindspore::DeviceType &device_type, const std::string &provider,
GraphExecutorCreator creator) {
auto it = creator_map_.find(device_type);
if (it == creator_map_.end()) {
HashMap<std::string, GraphExecutorCreator> map;
map[provider] = creator;
creator_map_[device_type] = map;
return;
}
it->second[provider] = creator;
}
std::shared_ptr<LiteGraphExecutor> GetGraphExecutor(const mindspore::DeviceType &device_type,
const std::string &provider,
const std::shared_ptr<mindspore::DelegateConfig> &config) {
auto it = creator_map_.find(device_type);
if (it == creator_map_.end()) {
return nullptr;
}
auto creator_it = it->second.find(provider);
if (creator_it == it->second.end()) {
return nullptr;
}
return creator_it->second(config);
}
std::shared_ptr<GraphExecutorDelegate> GetDelegate(const mindspore::DeviceType &device_type,
const std::string &provider,
const std::shared_ptr<mindspore::DelegateConfig> &config) {
auto graph_executor = GetGraphExecutor(device_type, provider, config);
if (graph_executor == nullptr) {
return nullptr;
}
auto delegate = std::make_shared<mindspore::GraphExecutorDelegate>();
delegate->SetGraphExecutor(graph_executor);
return delegate;
}
private:
mindspore::HashMap<DeviceType, mindspore::HashMap<std::string, GraphExecutorCreator>> creator_map_;
};
class GraphExecutorRegistrar {
public:
GraphExecutorRegistrar(const mindspore::DeviceType &device_type, const std::string &provider,
GraphExecutorCreator creator) {
GraphExecutorRegistry::GetInstance().RegGraphExecutor(device_type, provider, creator);
}
~GraphExecutorRegistrar() = default;
};
#define REG_GRAPH_EXECUTOR(device_type, provider, creator) \
static GraphExecutorRegistrar g_##device_type##provider##GraphExecutor(device_type, provider, creator);
} // namespace mindspore
#endif // MINDSPORE_LITE_SRC_EXTENDRT_DELEGATE_GRAPH_EXECUTOR_FACTORY_H_

View File

@ -28,7 +28,7 @@
#include "extendrt/delegate/graph_executor/litert/converters.h"
#include "extendrt/delegate/graph_executor/litert/graph_executor.h"
#include "extendrt/delegate/graph_executor/factory.h"
#include "extendrt/delegate/factory.h"
#include "tools/common/meta_graph_serializer.h"
#include "extendrt/utils/tensor_utils.h"
@ -285,11 +285,9 @@ std::shared_ptr<lite::LiteSession> LiteRTGraphExecutor::CreateLiteSession(lite::
return session;
}
static std::shared_ptr<LiteGraphExecutor> LiteRTGraphExecutorCreator(
const std::shared_ptr<mindspore::DelegateConfig> &config) {
MS_EXCEPTION_IF_NULL(config);
return std::make_shared<LiteRTGraphExecutor>(config->GetContext());
static std::shared_ptr<device::GraphExecutor> LiteRTGraphExecutorCreator(const std::shared_ptr<Context> &ctx) {
return std::make_shared<LiteRTGraphExecutor>(ctx);
}
REG_GRAPH_EXECUTOR(kCPU, litert_provider, LiteRTGraphExecutorCreator);
REG_DELEGATE(kCPU, litert_provider, LiteRTGraphExecutorCreator);
} // namespace mindspore

View File

@ -1,32 +0,0 @@
/**
* Copyright 2019-2021 Huawei Technologies Co., Ltd
*
* 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.
*/
#ifndef MINDSPORE_LITE_EXTENDRT_DELEGATE_GRAPH_EXECUTOR_TYPE_H_
#define MINDSPORE_LITE_EXTENDRT_DELEGATE_GRAPH_EXECUTOR_TYPE_H_
#include <memory>
#include <vector>
#include "extendrt/delegate/type.h"
namespace mindspore {
class GraphExecutorConfig : public DelegateConfig {
public:
GraphExecutorConfig() = default;
explicit GraphExecutorConfig(const std::shared_ptr<Context> &context) : DelegateConfig(context) {}
~GraphExecutorConfig() = default;
};
} // namespace mindspore
#endif // MINDSPORE_LITE_EXTENDRT_DELEGATE_GRAPH_EXECUTOR_TYPE_H_

View File

@ -24,7 +24,6 @@
#include <utility>
#include "ccsrc/kernel/kernel.h"
#include "src/extendrt/delegate/delegate_utils.h"
#include "src/extendrt/delegate/graph_executor/factory.h"
#include "ccsrc/kernel/common_utils.h"
#include "ccsrc/backend/common/optimizer/helper.h"
#include "ccsrc/include/common/utils/convert_utils.h"
@ -705,13 +704,11 @@ std::vector<tensor::Tensor> TensorRTExecutor::GetOutputInfos(const FuncGraphPtr
return tensors;
}
static std::shared_ptr<LiteGraphExecutor> TensorRTGraphExecutorCreator(
const std::shared_ptr<mindspore::DelegateConfig> &config) {
MS_EXCEPTION_IF_NULL(config);
auto executor = std::make_shared<TensorRTExecutor>(config->GetContext());
static std::shared_ptr<device::GraphExecutor> TensorRTGraphExecutorCreator(const std::shared_ptr<Context> &ctx) {
auto executor = std::make_shared<TensorRTExecutor>(ctx);
executor->Init();
return executor;
}
REG_GRAPH_EXECUTOR(kGPU, tensorrt_provider, TensorRTGraphExecutorCreator);
REG_DELEGATE(kGPU, tensorrt_provider, TensorRTGraphExecutorCreator);
} // namespace mindspore::lite

View File

@ -22,7 +22,6 @@
#include <memory>
#include <set>
#include <map>
#include "include/api/delegate.h"
#include "src/extendrt/delegate/tensorrt/tensorrt_subgraph.h"
#include "src/extendrt/delegate/parameter_cache/embedding_cache_manager.h"
#include "include/api/kernel.h"
@ -30,7 +29,7 @@
#include "src/common/log_adapter.h"
#include "include/api/context.h"
#include "core/base/base.h"
#include "extendrt/delegate/factory.h"
#include "extendrt/session/lite_graph_executor.h"
#include "ccsrc/backend/common/session/kernel_graph.h"

View File

@ -1,39 +0,0 @@
/**
* Copyright 2019-2021 Huawei Technologies Co., Ltd
*
* 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.
*/
#ifndef MINDSPORE_LITE_EXTENDRT_DELEGATE_TYPE_H_
#define MINDSPORE_LITE_EXTENDRT_DELEGATE_TYPE_H_
#include <memory>
#include <vector>
#include "include/api/context.h"
namespace mindspore {
class DelegateConfig {
public:
DelegateConfig() = default;
explicit DelegateConfig(const std::shared_ptr<Context> &context) : context_(context) {}
virtual ~DelegateConfig() = default;
// void SetContext(const std::shared_ptr<Context> &context) { context_ = context; }
const std::shared_ptr<Context> &GetContext() { return context_; }
protected:
const std::shared_ptr<Context> context_;
};
} // namespace mindspore
#endif // MINDSPORE_LITE_EXTENDRT_DELEGATE_TYPE_H_

View File

@ -0,0 +1,57 @@
/**
* Copyright 2022 Huawei Technologies Co., Ltd
*
* 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 "src/extendrt/delegate_graph_executor.h"
#include <set>
#include <memory>
#include "src/extendrt/subgraph_kernel.h"
#include "tools/common/func_graph_subgraph.h"
#include "ops/fusion/partial_fusion.h"
namespace mindspore {
// Graph sink delegate, the whole FuncGraph as a node to execute.
void GraphSinkDelegate::ReplaceNodes(const std::shared_ptr<FuncGraph> &graph) {
sink_graph_ = graph;
// replace the whole graph to a partial node.
lite::SubGraph helper(graph);
auto nodes = graph->order_list();
std::set<CNodePtr> cnodeset;
for (auto it = nodes.begin(); it != nodes.end(); it++) {
cnodeset.emplace(*it);
}
helper.Reset(cnodeset);
helper.ApplySubGraph();
return;
}
bool GraphSinkDelegate::IsDelegateNode(const std::shared_ptr<CNode> &node) {
auto partial_prim = std::make_shared<mindspore::ops::PartialFusion>();
if (!IsPrimitiveCNode(node, partial_prim->GetPrim())) {
return false;
}
auto graph = GetCNodeFuncGraph(node);
if (graph.get() == sink_graph_.get()) {
return true;
}
return false;
}
std::shared_ptr<kernel::KernelMod> GraphExecutorDelegate::CreateKernel(const std::shared_ptr<CNode> &node) {
if (!IsDelegateNode(node)) {
return nullptr;
}
auto kernel = std::make_shared<kernel::SubgraphKernel>(sink_graph_, executor_);
return kernel;
}
} // namespace mindspore

View File

@ -0,0 +1,55 @@
/**
* Copyright 2022 Huawei Technologies Co., Ltd
*
* 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.
*/
#ifndef MINDSPORE_LITE_EXTENDRT_DELEGATE_GRAPH_EXECUTOR_H_
#define MINDSPORE_LITE_EXTENDRT_DELEGATE_GRAPH_EXECUTOR_H_
#include <vector>
#include <memory>
#include "include/api/delegate_api.h"
#include "ir/func_graph.h"
#include "ir/anf.h"
#include "runtime/hardware/device_context.h"
#include "tools/common/func_graph_subgraph.h"
#include "kernel/kernel.h"
namespace mindspore {
// Graph sink delegate, the whole FuncGraph as a node to execute.
class GraphSinkDelegate : public IDelegate<FuncGraph, CNode, kernel::KernelMod> {
public:
GraphSinkDelegate(const std::vector<mindspore::MSTensor> &inputs, const std::vector<mindspore::MSTensor> &outputs)
: IDelegate<FuncGraph, CNode, kernel::KernelMod>(inputs, outputs) {}
virtual ~GraphSinkDelegate() = default;
void ReplaceNodes(const std::shared_ptr<FuncGraph> &graph) override;
bool IsDelegateNode(const std::shared_ptr<CNode> &node) override;
protected:
FuncGraphPtr sink_graph_;
};
// wrap graph executor as delegate
class GraphExecutorDelegate : public GraphSinkDelegate {
public:
explicit GraphExecutorDelegate(const std::vector<mindspore::MSTensor> &inputs,
const std::vector<mindspore::MSTensor> &outputs,
std::shared_ptr<device::GraphExecutor> executor)
: GraphSinkDelegate(inputs, outputs), executor_(executor) {}
virtual ~GraphExecutorDelegate() = default;
std::shared_ptr<kernel::KernelMod> CreateKernel(const std::shared_ptr<CNode> &node) override;
private:
const std::shared_ptr<device::GraphExecutor> executor_;
};
} // namespace mindspore
#endif

View File

@ -1,269 +0,0 @@
/**
* Copyright 2021 Huawei Technologies Co., Ltd
*
* 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 "extendrt/gpu/gpu_infer.h"
#include <algorithm>
#include "include/api/context.h"
#include "extendrt/factory.h"
#include "extendrt/cxx_api/akg_kernel_register.h"
#include "utils/log_adapter.h"
#include "mindspore/core/base/base_ref_utils.h"
#include "backend/common/session/session_factory.h"
#include "backend/common/session/executor_manager.h"
#include "runtime/device/kernel_runtime_manager.h"
#include "plugin/device/gpu/hal/device/cuda_driver.h"
namespace mindspore {
GPUInferExecutor::GPUInferExecutor()
: session_impl_(nullptr),
graph_id_(0),
device_id_(0),
inputs_info_(),
outputs_info_(),
input_names_(),
output_names_(),
init_flag_(false),
load_flag_(false),
set_device_id_flag_(false) {}
Status GPUInferExecutor::InitEnv() {
if (init_flag_) {
MS_LOG(WARNING) << "Initialized again, return success.";
return kSuccess;
}
auto ms_context = MsContext::GetInstance();
if (ms_context == nullptr) {
MS_LOG(ERROR) << "Get Context failed!";
return kMCFailed;
}
ms_context->set_param<int>(MS_CTX_EXECUTION_MODE, kGraphMode);
ms_context->set_param<uint32_t>(MS_CTX_DEVICE_ID, device_id_);
ms_context->set_param<std::string>(MS_CTX_DEVICE_TARGET, kGPUDevice);
// Set device id for sync data to host as cudaSetDevice is thread level config.
bool ret = device::gpu::CudaDriver::SetDevice(UintToInt(device_id_));
if (!ret) {
MS_LOG(ERROR) << "Failed to set device id:" << device_id_;
return kMCDeviceError;
}
auto &device_infos = graph_context_->MutableDeviceInfo();
if (device_infos.size() != 1) {
return kMCDeviceError;
}
auto gpu_info = device_infos[0]->Cast<GPUDeviceInfo>();
if (gpu_info == nullptr) {
return kMCDeviceError;
}
ms_context->set_param<bool>(MS_CTX_ENABLE_INFER_OPT, true);
ms_context->set_param<std::string>(MS_CTX_INFER_PRECISION_MODE, gpu_info->GetPrecisionMode());
session_impl_ = session::SessionFactory::Get().Create(kGpuInferenceDevice);
if (session_impl_ == nullptr) {
MS_LOG(ERROR) << "Session create failed!, please make sure target device:" << kGpuInferenceDevice
<< " is available.";
return kMCFailed;
}
session_impl_->Init(device_id_);
init_flag_ = true;
return kSuccess;
}
Status GPUInferExecutor::FinalizeEnv() {
if (!init_flag_) {
MS_LOG(WARNING) << "Never initialize before, return success";
return kSuccess;
}
MS_LOG_INFO << "Start finalize env";
session::ExecutorManager::Instance().Clear();
device::KernelRuntimeManager::Instance().ClearRuntimeResource();
init_flag_ = false;
MS_LOG(INFO) << "End finalize env";
return kSuccess;
}
Status GPUInferExecutor::Load(uint32_t device_id) {
// check graph type
if (graph_->ModelType() != ModelType::kMindIR) {
MS_LOG(ERROR) << "Unsupported model type " << graph_->ModelType();
return kMCInvalidInput;
}
const auto &graph_data = GraphImpl::MutableGraphData();
MS_EXCEPTION_IF_NULL(graph_data);
auto func_graph = graph_data->GetFuncGraph();
// init
device_id_ = device_id;
Status ret = InitEnv();
if (ret != kSuccess) {
MS_LOG(ERROR) << "InitEnv failed.";
return kMCDeviceError;
}
ret = CompileGraph(func_graph);
if (ret != kSuccess) {
MS_LOG(ERROR) << "Compile graph model failed";
return kMCFailed;
}
MS_EXCEPTION_IF_NULL(session_impl_);
session_impl_->GetModelInputsInfo(graph_id_, &inputs_info_, &input_names_);
session_impl_->GetModelOutputsInfo(graph_id_, &outputs_info_, &output_names_);
if (inputs_info_.empty() || inputs_info_.size() != input_names_.size()) {
MS_LOG_ERROR << "Get model inputs info failed";
return kMCInvalidInput;
}
if (outputs_info_.empty() || outputs_info_.size() != output_names_.size()) {
MS_LOG_ERROR << "Get model outputs info failed";
return kMCInvalidInput;
}
load_flag_ = true;
return kSuccess;
}
Status GPUInferExecutor::ExecuteModel(const std::vector<MSTensor> &request, std::vector<MSTensor> *reply) {
MS_EXCEPTION_IF_NULL(reply);
vector<tensor::TensorPtr> inputs;
for (size_t i = 0; i < request.size(); i++) {
auto &item = request[i];
auto input = inputs_info_[i];
if (input->Size() != item.DataSize()) {
MS_LOG(ERROR) << "Input " << i << " data size " << item.DataSize() << " not match model input data size "
<< input->Size();
return kMCInvalidInput;
}
auto ret = memcpy_s(input->data_c(), input->Size(), item.Data().get(), item.DataSize());
if (ret != kSuccess) {
MS_LOG(ERROR) << "Tensor copy failed";
return kMCFailed;
}
inputs.push_back(input);
}
last_inputs_ = inputs;
std::vector<tensor::TensorPtr> outputs = RunGraph(inputs);
if (outputs.empty()) {
MS_LOG(ERROR) << "Execute Model Failed";
return kMCFailed;
}
last_outputs_ = outputs;
reply->clear();
*reply = GetOutputs();
return kSuccess;
}
Status GPUInferExecutor::Run(const std::vector<MSTensor> &inputs, std::vector<MSTensor> *outputs) {
MS_EXCEPTION_IF_NULL(outputs);
if (!load_flag_) {
Status ret = Load(device_id_);
if (ret != kSuccess) {
MS_LOG(ERROR) << "PrepareModel failed.";
return ret;
}
}
// The `Load()` and `Run()` running in two threads. `Run()` always running in same thread.
// It should set device id once.
if (!set_device_id_flag_) {
bool ret = device::gpu::CudaDriver::SetDevice(UintToInt(device_id_));
if (!ret) {
MS_LOG(ERROR) << "Failed to set device id:" << device_id_;
return kMCDeviceError;
}
set_device_id_flag_ = true;
}
if (inputs.size() != inputs_info_.size()) {
MS_LOG(ERROR) << "inputs count not match, required count " << inputs_info_.size() << ", given count "
<< inputs.size();
return kMCInvalidInput;
}
for (size_t i = 0; i < inputs_info_.size(); ++i) {
if (inputs[i].DataSize() != inputs_info_[i]->Size()) {
MS_LOG(ERROR) << "input " << i << " data size not match, required size " << inputs_info_[i]->Size()
<< ", given count " << inputs[i].DataSize();
return kMCInvalidInput;
}
}
if (ExecuteModel(inputs, outputs) != kSuccess) {
MS_LOG(ERROR) << "Execute Model Failed";
return kMCFailed;
}
if (outputs_info_.size() != outputs->size()) {
MS_LOG(ERROR) << "Predict output size " << outputs->size() << " not match output size got from model info "
<< outputs_info_.size();
return kMCFailed;
}
return kSuccess;
}
std::vector<MSTensor> GPUInferExecutor::GetInputs() {
if (!load_flag_) {
Status ret = Load(device_id_);
if (ret != kSuccess) {
MS_LOG(ERROR) << "PrepareModel failed.";
return {};
}
}
std::vector<MSTensor> result(inputs_info_.size());
for (size_t i = 0; i < inputs_info_.size(); ++i) {
auto &tensor = inputs_info_[i];
void *data = nullptr;
size_t data_size = tensor->Size();
if (i < last_inputs_.size()) {
data = last_inputs_[i]->data_c();
data_size = last_inputs_[i]->Size();
}
result[i] =
MSTensor(input_names_[i], static_cast<enum DataType>(tensor->data_type()), tensor->shape(), data, data_size);
}
return result;
}
std::vector<MSTensor> GPUInferExecutor::GetOutputs() {
if (!load_flag_) {
Status ret = Load(device_id_);
if (ret != kSuccess) {
MS_LOG(ERROR) << "PrepareModel failed.";
return {};
}
}
std::vector<MSTensor> result(outputs_info_.size());
for (size_t i = 0; i < outputs_info_.size(); ++i) {
auto &tensor = outputs_info_[i];
void *data = nullptr;
size_t data_size = tensor->Size();
if (i < last_outputs_.size()) {
if (last_outputs_[i]->NeedSyncDeviceToHost()) {
last_outputs_[i]->data_sync(false);
}
data = last_outputs_[i]->data_c();
data_size = last_outputs_[i]->Size();
}
result[i] =
MSTensor(output_names_[i], static_cast<enum DataType>(tensor->data_type()), tensor->shape(), data, data_size);
}
return result;
}
bool GPUInferExecutor::CheckDeviceSupport(mindspore::DeviceType device_type) { return device_type == kGPU; }
} // namespace mindspore

View File

@ -1,59 +0,0 @@
/**
* Copyright 2021 Huawei Technologies Co., Ltd
*
* 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.
*/
#ifndef MINDSPORE_LITE_SRC_EXTENDRT_GPU_INFER_EXECUTOR_H_
#define MINDSPORE_LITE_SRC_EXTENDRT_GPU_INFER_EXECUTOR_H_
#include <string>
#include <vector>
#include <utility>
#include <memory>
#include "include/api/status.h"
#include "include/api/graph.h"
#include "ir/anf.h"
#include "extendrt/graph_executor.h"
namespace mindspore {
class GPUInferExecutor : public GraphExecutor {
public:
GPUInferSession();
~GPUInferSession() override = default;
Status Execute(const ExecutePlan &plan, const std::vector<MSTensor> &inputs, std::vector<MSTensor> *outputs) override;
protected:
bool CheckDeviceSupport(mindspore::DeviceType device_type) override;
Status Load(uint32_t device_id);
Status InitEnv();
Status FinalizeEnv();
Status CheckModelInputs(const std::vector<tensor::TensorPtr> &inputs) const;
private:
uint32_t graph_id_;
std::string device_type_;
uint32_t device_id_;
std::vector<tensor::TensorPtr> inputs_info_;
std::vector<tensor::TensorPtr> outputs_info_;
std::vector<tensor::TensorPtr> last_inputs_;
std::vector<tensor::TensorPtr> last_outputs_;
std::vector<std::string> input_names_;
std::vector<std::string> output_names_;
bool init_flag_;
bool load_flag_;
bool set_device_id_flag_;
// tensor-rt
uint32_t batch_size_;
uint32_t workspace_size_;
};
} // namespace mindspore
#endif // MINDSPORE_LITE_SRC_EXTENDRT_GPU_INFER_EXECUTOR_H_

View File

@ -28,7 +28,7 @@ ExcutionPlan GraphCompiler::Compile(FuncGraphPtr func_graph) {
}
CompileResult result = LinkSegments();
return scheduler.Schedule(result);
return Schedule(result);
}
GraphId GraphCompiler::CompileSegment(const GraphSegmentPtr &segment) {
// Generate kernel graph.

View File

@ -13,8 +13,8 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef MINDSPORE_LITE_EXTENDRT_GRAPH_COMPILER_H
#define MINDSPORE_LITE_EXTENDRT_GRAPH_COMPILER_H
#ifndef MINDSPORE_LITE_EXTENDRT_GRAPH_COMPILER_H_
#define MINDSPORE_LITE_EXTENDRT_GRAPH_COMPILER_H_
#include <string>
#include <memory>
#include <map>
@ -34,10 +34,10 @@ struct CompileResult {
GraphId root_;
std::vector<GraphId> control_nodes_;
std::vector<KernelGraphPtr> graphs_;
// dependency ?
};
struct KernelInfo {
KernelPtr kernel_;
bool isSubgraphKernel;
std::vector<int64_t> inputs_;
std::vector<int64_t> outputs_;
};

View File

@ -1,39 +0,0 @@
/**
* Copyright 2019-2021 Huawei Technologies Co., Ltd
*
* 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.
*/
#ifndef MINDSPORE_LITE_EXTENDRT_GRAPH_EXECUTOR_H
#define MINDSPORE_LITE_EXTENDRT_GRAPH_EXECUTOR_H
#include <string>
#include <memory>
#include <map>
#include <vector>
#include "include/api/context.h"
#include "include/api/model.h"
#include "include/api/graph.h"
#include "include/api/status.h"
#include "include/common/utils/utils.h"
#include "ir/func_graph.h"
namespace mindspore {
namespace infer {
class GraphExecutor : public std::enable_shared_from_this<GraphExecutor> {
public:
GraphExecutor() = default;
GraphExecutor(const std::string &device_name, uint32_t device_id);
Status Execute(const ExecutePlan &plan, const std::vector<MSTensor> &inputs, std::vector<MSTensor> *outputs);
};
} // namespace infer
} // namespace mindspore
#endif

View File

@ -15,7 +15,7 @@
*/
#include "extendrt/infer_session.h"
#include "extendrt/single_op_session.h"
#include "extendrt/session/single_op_session.h"
#include "plugin/factory/ms_factory.h"
#include "kernel/common_utils.h"
// #include "backend/common/session/session_basic.h"
@ -25,7 +25,6 @@
#include "include/common/utils/anfalgo.h"
#include "backend/common/session/anf_runtime_algorithm.h"
#include "extendrt/delegate/factory.h"
#include "extendrt/delegate/graph_executor/factory.h"
#include "extendrt/session/factory.h"
#include "extendrt/delegate/plugin/tensorrt_executor_plugin.h"
@ -33,19 +32,17 @@ namespace mindspore {
static const std::vector<PrimitivePtr> ms_infer_cut_list = {prim::kPrimReturn, prim::kPrimPartial,
prim::kPrimSwitch, prim::kPrimMakeTuple,
prim::kPrimBpropCut, prim::kPrimSwitchLayer};
static bool is_infer_single_op = false;
static bool is_use_lite_session = true;
static bool is_infer_single_op = true;
static bool is_use_lite_session = false;
// static bool is_use_tensorrt_delegate = true;
class DefaultInferSession : public InferSession {
public:
DefaultInferSession() = default;
explicit DefaultInferSession(const std::shared_ptr<Context> &context) {}
virtual ~DefaultInferSession() = default;
Status Init(const std::shared_ptr<Context> context) override;
Status Init(const std::shared_ptr<Context> &context) override;
Status CompileGraph(FuncGraphPtr graph, const void *data = nullptr, size_t size = 0) override;
Status RunGraph() override;
Status RunGraph(const std::vector<tensor::Tensor> &inputs, std::vector<tensor::Tensor> *outputs) override;
Status Resize(const std::vector<tensor::Tensor> &inputs, const std::vector<std::vector<int64_t>> &dims) override;
std::vector<MutableTensorImplPtr> GetOutputs() override;
std::vector<MutableTensorImplPtr> GetInputs() override;
std::vector<std::string> GetOutputNames() override;
@ -59,7 +56,7 @@ class DefaultInferSession : public InferSession {
std::vector<KernelGraphPtr> kernel_graphs_;
};
Status DefaultInferSession::Init(const std::shared_ptr<Context> context) {
Status DefaultInferSession::Init(const std::shared_ptr<Context> &context) {
MS_LOG(INFO) << "DefaultInferSession::Init";
kernel_graph_utils_ = std::make_shared<mindspore::KernelGraphUtils>();
partition_ = std::make_shared<compile::GraphPartition>(ms_infer_cut_list, "ms");
@ -70,25 +67,20 @@ Status DefaultInferSession::CompileGraph(FuncGraphPtr graph, const void *data, s
return kSuccess;
}
Status DefaultInferSession::RunGraph() { return kSuccess; }
Status DefaultInferSession::RunGraph(const std::vector<tensor::Tensor> &inputs, std::vector<tensor::Tensor> *outputs) {
return kSuccess;
}
Status DefaultInferSession::Resize(const std::vector<tensor::Tensor> &inputs,
const std::vector<std::vector<int64_t>> &dims) {
return kSuccess;
}
std::vector<MutableTensorImplPtr> DefaultInferSession::GetOutputs() { return {}; }
std::vector<MutableTensorImplPtr> DefaultInferSession::GetInputs() { return {}; }
std::vector<std::string> DefaultInferSession::GetOutputNames() { return std::vector<std::string>(); }
std::vector<std::string> DefaultInferSession::GetInputNames() { return std::vector<std::string>(); }
MutableTensorImplPtr DefaultInferSession::GetOutputByTensorName(const std::string &tensorName) { return nullptr; }
MutableTensorImplPtr DefaultInferSession::GetInputByTensorName(const std::string &name) { return nullptr; }
std::shared_ptr<InferSession> InferSession::CreateSession(const std::shared_ptr<Context> context) {
std::shared_ptr<InferSession> InferSession::CreateSession(const std::shared_ptr<Context> &context) {
HandleGPUContext(context);
auto config = SelectSessionArg(context);
MS_LOG(DEBUG) << "Session type " << static_cast<int64_t>(config.type_);
return SessionRegistry::GetInstance().GetSession(config.type_, config);
auto session_type = SelectSession(context);
MS_LOG(DEBUG) << "Session type " << static_cast<int64_t>(session_type);
return SessionRegistry::GetInstance().GetSession(session_type, context);
}
void InferSession::HandleGPUContext(const std::shared_ptr<Context> &context) {
@ -116,50 +108,34 @@ void InferSession::HandleGPUContext(const std::shared_ptr<Context> &context) {
}
}
SessionConfig InferSession::SelectSessionArg(const std::shared_ptr<Context> &context) {
SessionConfig config;
config.context_ = context;
SessionType InferSession::SelectSession(const std::shared_ptr<Context> &context) {
if (context != nullptr) {
if (context->GetDelegate() != nullptr) {
config.delegates_.emplace_back(context->GetDelegate());
}
auto delegate_config = std::make_shared<mindspore::DelegateConfig>(context);
auto &device_contexts = context->MutableDeviceInfo();
for (auto device_context : device_contexts) {
MS_EXCEPTION_IF_NULL(device_context);
if (device_context->GetDeviceType() == kAscend) {
config.type_ = kSingleOpSession;
return config;
return kSingleOpSession;
}
// get graph executor delegate
auto delegate = mindspore::DelegateRegistry::GetInstance().GetDelegate(
device_context->GetDeviceType(), device_context->GetProvider(), delegate_config);
if (delegate == nullptr) {
continue;
// if (device_context->GetDeviceType() == kGPU && is_use_tensorrt_delegate) {
if (device_context->GetDeviceType() == kGPU) {
return kDelegateSession;
}
config.delegates_.emplace_back(delegate);
}
}
if (!config.delegates_.empty()) {
// create delegate session object
config.type_ = kDelegateSession;
return config;
}
if (is_infer_single_op) {
config.type_ = kSingleOpSession;
return config;
return kSingleOpSession;
}
if (is_use_lite_session) {
config.type_ = kLiteInferSession;
return config;
return kLiteInferSession;
}
config.type_ = kDefaultSession;
return config;
return kDefaultSession;
}
static std::shared_ptr<InferSession> DefaultSessionCreator(const SessionConfig &config) {
return std::make_shared<DefaultInferSession>();
static std::shared_ptr<InferSession> DefaultSessionCreator(const std::shared_ptr<Context> &ctx) {
auto session = std::make_shared<DefaultInferSession>(ctx);
session->Init(ctx);
return session;
}
REG_SESSION(kDefaultSession, DefaultSessionCreator);
} // namespace mindspore

View File

@ -34,13 +34,14 @@ namespace mindspore {
class InferSession : public std::enable_shared_from_this<InferSession> {
public:
virtual ~InferSession() = default;
static std::shared_ptr<InferSession> CreateSession(const std::shared_ptr<Context> context);
static SessionConfig SelectSessionArg(const std::shared_ptr<Context> &context);
virtual Status Init(const std::shared_ptr<Context> context) = 0;
static std::shared_ptr<InferSession> CreateSession(const std::shared_ptr<Context> &context);
static SessionType SelectSession(const std::shared_ptr<Context> &context);
virtual Status Init(const std::shared_ptr<Context> &context) = 0;
virtual Status CompileGraph(FuncGraphPtr graph, const void *data = nullptr, size_t size = 0) = 0;
virtual Status RunGraph() = 0;
virtual Status RunGraph(const std::vector<tensor::Tensor> &inputs, std::vector<tensor::Tensor> *outputs) = 0;
virtual Status Resize(const std::vector<tensor::Tensor> &inputs, const std::vector<std::vector<int64_t>> &dims) = 0;
virtual Status Resize(const std::vector<tensor::Tensor> &inputs, const std::vector<std::vector<int64_t>> &dims) {
return kSuccess;
}
virtual std::vector<MutableTensorImplPtr> GetOutputs() = 0;
virtual std::vector<MutableTensorImplPtr> GetInputs() = 0;
@ -53,6 +54,6 @@ class InferSession : public std::enable_shared_from_this<InferSession> {
FuncGraphPtr graph_;
compile::GraphPartitionPtr partition_;
static void HandleGPUContext(const std::shared_ptr<Context> &context);
};
}; // namespace mindspore
} // namespace mindspore
#endif

View File

@ -14,49 +14,58 @@
* limitations under the License.
*/
#include "extendrt/session/delegate_session.h"
#include <vector>
#include <string>
#include <memory>
#include "extendrt/session/delegate_session.h"
#include "extendrt/session/graph_executor_session.h"
#include "extendrt/utils/tensor_utils.h"
#include "src/extendrt/utils/kernel_build_utils.h"
#include "extendrt/delegate/factory.h"
#include "extendrt/session/factory.h"
#include "extendrt/delegate/graph_executor/delegate.h"
namespace mindspore {
Status DelegateSession::Init(const std::shared_ptr<Context> context) { return kSuccess; }
Status DelegateSession::CompileGraph(FuncGraphPtr graph, const void *data, size_t size) { return kSuccess; }
Status DelegateSession::RunGraph() { return kSuccess; }
Status DelegateSession::RunGraph(const std::vector<tensor::Tensor> &inputs, std::vector<tensor::Tensor> *outputs) {
Status GraphSinkSession::Init(const std::shared_ptr<Context> &context) {
MS_LOG(INFO) << "GraphSinkSession::Init";
kernel_graph_utils_ = std::make_shared<mindspore::KernelGraphUtils>();
return kSuccess;
}
Status DelegateSession::Resize(const std::vector<tensor::Tensor> &inputs,
const std::vector<std::vector<int64_t>> &dims) {
Status GraphSinkSession::CompileGraph(FuncGraphPtr graph, const void *data, size_t size) {
MS_LOG(INFO) << "GraphSinkSession::CompileGraph";
std::vector<KernelGraphPtr> all_out_graph;
kernel_graph_ = kernel_graph_utils_->ConstructKernelGraph(graph, &all_out_graph, mindspore::device::DeviceType::kCPU);
MS_EXCEPTION_IF_NULL(kernel_graph_);
auto &kernel_nodes = kernel_graph_->execution_order();
for (const auto &kernel_node : kernel_nodes) {
mindspore::infer::SetKernelInfo(kernel_node);
}
if (graph_executor_->CompileGraph(kernel_graph_, options_)) {
kernel_graph_utils_->GetModelInputsInfo(kernel_graph_->graph_id(), &inputs_, &input_names_);
kernel_graph_utils_->GetModelOutputsInfo(kernel_graph_->graph_id(), &outputs_, &output_names_);
return kSuccess;
}
return kCoreFailed;
}
Status GraphSinkSession::RunGraph(const std::vector<tensor::Tensor> &inputs, std::vector<tensor::Tensor> *outputs) {
return kSuccess;
}
std::vector<MutableTensorImplPtr> DelegateSession::GetOutputs() { return {}; }
std::vector<MutableTensorImplPtr> DelegateSession::GetInputs() { return {}; }
std::vector<std::string> DelegateSession::GetOutputNames() { return std::vector<std::string>(); }
std::vector<std::string> DelegateSession::GetInputNames() { return std::vector<std::string>(); }
MutableTensorImplPtr DelegateSession::GetOutputByTensorName(const std::string &tensorName) { return nullptr; }
MutableTensorImplPtr DelegateSession::GetInputByTensorName(const std::string &name) { return nullptr; }
static std::shared_ptr<InferSession> DelegateSessionCreator(const SessionConfig &config) {
auto delegates = config.delegates_;
if (delegates.size() > 1) {
MS_LOG(ERROR) << "Not support multi delegates context";
std::vector<MutableTensorImplPtr> GraphSinkSession::GetOutputs() { return {}; }
std::vector<MutableTensorImplPtr> GraphSinkSession::GetInputs() { return {}; }
std::vector<std::string> GraphSinkSession::GetOutputNames() { return std::vector<std::string>(); }
std::vector<std::string> GraphSinkSession::GetInputNames() { return std::vector<std::string>(); }
MutableTensorImplPtr GraphSinkSession::GetOutputByTensorName(const std::string &tensorName) { return nullptr; }
MutableTensorImplPtr GraphSinkSession::GetInputByTensorName(const std::string &name) { return nullptr; }
static std::shared_ptr<InferSession> DelegateSessionCreator(const std::shared_ptr<Context> &ctx) {
auto &device_contexts = ctx->MutableDeviceInfo();
if (device_contexts.empty()) {
return nullptr;
}
auto delegate = delegates.front();
auto device_type = device_contexts.at(0)->GetDeviceType();
auto provider = device_contexts.at(0)->GetProvider();
auto graph_executor_delegate = std::reinterpret_pointer_cast<GraphExecutorDelegate>(delegate);
if (graph_executor_delegate != nullptr) {
return std::make_shared<GraphExecutorSession>(graph_executor_delegate->GetGraphExecutor());
}
return std::make_shared<DelegateSession>(delegate);
auto delegate = DelegateRegistry::GetInstance().GetDelegate(device_type, provider, ctx);
auto session = std::make_shared<GraphSinkSession>(delegate);
session->Init(ctx);
return session;
}
REG_SESSION(kDelegateSession, DelegateSessionCreator);
} // namespace mindspore

View File

@ -17,24 +17,25 @@
#define MINDSPORE_LITE_EXTENDRT_SESSION_DELEGATE_SESSION_H_
#include <vector>
#include <memory>
#include <string>
#include <memory>
#include <map>
#include "extendrt/infer_session.h"
#include "runtime/hardware/device_context.h"
#include "extendrt/utils/kernel_graph_utils.h"
namespace mindspore {
class DelegateSession : public InferSession {
// TODO(zhaizhiqiang): use GraphSinkDelegateSession instead of GraphSinkSession in future.
// class GraphSinkDelegateSession
class GraphSinkSession : public InferSession {
public:
DelegateSession() = default;
explicit DelegateSession(std::shared_ptr<mindspore::Delegate> delegate) : delegate_(delegate) {}
virtual ~DelegateSession() = default;
GraphSinkSession() = default;
explicit GraphSinkSession(const std::shared_ptr<device::GraphExecutor> &executor) : graph_executor_(executor) {}
virtual ~GraphSinkSession() = default;
Status Init(const std::shared_ptr<Context> context) override;
Status Init(const std::shared_ptr<Context> &context) override;
Status CompileGraph(FuncGraphPtr graph, const void *data = nullptr, size_t size = 0) override;
Status RunGraph() override;
Status RunGraph(const std::vector<tensor::Tensor> &inputs, std::vector<tensor::Tensor> *outputs) override;
Status Resize(const std::vector<tensor::Tensor> &inputs, const std::vector<std::vector<int64_t>> &dims) override;
std::vector<MutableTensorImplPtr> GetOutputs() override;
std::vector<MutableTensorImplPtr> GetInputs() override;
std::vector<std::string> GetOutputNames() override;
@ -43,7 +44,14 @@ class DelegateSession : public InferSession {
MutableTensorImplPtr GetInputByTensorName(const std::string &name) override;
private:
std::shared_ptr<mindspore::Delegate> delegate_;
std::shared_ptr<device::GraphExecutor> graph_executor_;
std::map<string, string> options_;
KernelGraphUtilsPtr kernel_graph_utils_;
KernelGraphPtr kernel_graph_;
std::vector<tensor::TensorPtr> inputs_;
std::vector<std::string> input_names_;
std::vector<tensor::TensorPtr> outputs_;
std::vector<std::string> output_names_;
};
} // namespace mindspore

View File

@ -26,17 +26,18 @@ SessionRegistry &SessionRegistry::GetInstance() {
return instance;
}
void SessionRegistry::RegSession(const mindspore::SessionType &session_type,
std::function<std::shared_ptr<InferSession>(const SessionConfig &)> creator) {
void SessionRegistry::RegSession(
const mindspore::SessionType &session_type,
const std::function<std::shared_ptr<InferSession>(const std::shared_ptr<Context> &)> &creator) {
session_map_[session_type] = creator;
}
std::shared_ptr<InferSession> SessionRegistry::GetSession(const mindspore::SessionType &session_type,
const SessionConfig &config) {
const std::shared_ptr<Context> &ctx) {
auto it = session_map_.find(session_type);
if (it == session_map_.end()) {
return nullptr;
}
return it->second(config);
return it->second(ctx);
}
} // namespace mindspore

View File

@ -21,7 +21,7 @@
#include "extendrt/session/type.h"
#include "extendrt/infer_session.h"
#include "include/api/context.h"
namespace mindspore {
class SessionRegistry {
public:
@ -31,18 +31,20 @@ class SessionRegistry {
static SessionRegistry &GetInstance();
void RegSession(const mindspore::SessionType &session_type,
std::function<std::shared_ptr<InferSession>(const SessionConfig &)> creator);
const std::function<std::shared_ptr<InferSession>(const std::shared_ptr<Context> &)> &creator);
std::shared_ptr<InferSession> GetSession(const mindspore::SessionType &session_type, const SessionConfig &config);
std::shared_ptr<InferSession> GetSession(const mindspore::SessionType &session_type,
const std::shared_ptr<Context> &);
private:
mindspore::HashMap<SessionType, std::function<std::shared_ptr<InferSession>(const SessionConfig &)>> session_map_;
mindspore::HashMap<SessionType, std::function<std::shared_ptr<InferSession>(const std::shared_ptr<Context> &)>>
session_map_;
};
class SessionRegistrar {
public:
SessionRegistrar(const mindspore::SessionType &session_type,
std::function<std::shared_ptr<InferSession>(const SessionConfig &)> creator) {
const std::function<std::shared_ptr<InferSession>(const std::shared_ptr<Context> &)> &creator) {
SessionRegistry::GetInstance().RegSession(session_type, creator);
}
~SessionRegistrar() = default;

View File

@ -1,187 +0,0 @@
/**
* Copyright 2019-2021 Huawei Technologies Co., Ltd
*
* 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 <vector>
#include <string>
#include <memory>
#include "extendrt/session/graph_executor_session.h"
#include "src/extendrt/utils/kernel_build_utils.h"
#include "extendrt/utils/tensor_default_impl.h"
#include "extendrt/utils/tensor_utils.h"
#include "extendrt/delegate/graph_executor/litert/graph_executor.h"
namespace mindspore {
Status GraphExecutorSession::Init(const std::shared_ptr<Context> context) {
MS_LOG(INFO) << "GraphExecutorSession::Init";
kernel_graph_utils_ = std::make_shared<mindspore::KernelGraphUtils>();
return kSuccess;
}
Status GraphExecutorSession::CompileGraph(FuncGraphPtr graph, const void *data, size_t size) {
MS_LOG(INFO) << "GraphExecutorSession::CompileGraph";
func_graph_ = graph;
std::vector<KernelGraphPtr> all_out_graph;
kernel_graph_ = kernel_graph_utils_->ConstructKernelGraph(graph, &all_out_graph, mindspore::device::DeviceType::kCPU);
MS_EXCEPTION_IF_NULL(kernel_graph_);
auto &kernel_nodes = kernel_graph_->execution_order();
for (const auto &kernel_node : kernel_nodes) {
mindspore::infer::SetKernelInfo(kernel_node);
}
bool ret = true;
if (is_use_kernel_graph_) {
if (!graph_executor_->CompileGraph(kernel_graph_, options_)) {
is_use_kernel_graph_ = false;
ret = graph_executor_->CompileGraph(func_graph_, options_);
}
} else {
ret = graph_executor_->CompileGraph(func_graph_, options_);
}
if (!ret) {
MS_LOG(ERROR) << "GraphExecutorSession::CompileGraph compile graph failed";
return kCoreFailed;
}
return InitGraphInputsOutputs();
}
Status GraphExecutorSession::InitGraphInputsOutputs() {
std::vector<tensor::TensorPtr> graph_inputs, graph_outputs;
kernel_graph_utils_->GetModelInputsInfo(kernel_graph_->graph_id(), &graph_inputs, &input_names_);
kernel_graph_utils_->GetModelOutputsInfo(kernel_graph_->graph_id(), &graph_outputs, &output_names_);
if (graph_inputs.size() != input_names_.size()) {
MS_LOG(ERROR) << "Graph input size " << graph_inputs.size() << " != input names size " << input_names_.size();
return kCoreFailed;
}
if (graph_outputs.size() != output_names_.size()) {
MS_LOG(ERROR) << "Graph output size " << graph_outputs.size() << " != output names size " << output_names_.size();
return kCoreFailed;
}
inputs_.clear();
auto new_inputs = graph_executor_->GetInputInfos(kernel_graph_);
if (new_inputs.empty()) {
for (size_t i = 0; i < input_names_.size(); i++) {
auto &input = graph_inputs[i];
auto data_type = static_cast<enum DataType>(input->data_type());
auto impl = std::make_shared<TensorDefaultImpl>(input_names_[i], data_type, input->shape_c());
inputs_.push_back(impl);
}
} else {
if (new_inputs.size() != input_names_.size()) {
MS_LOG(ERROR) << "Input count " << new_inputs.size() << " get from executor != input names count "
<< input_names_.size();
return kCoreFailed;
}
for (size_t i = 0; i < input_names_.size(); i++) {
auto &input = new_inputs[i];
auto data_type = static_cast<enum DataType>(input.data_type());
auto impl = std::make_shared<TensorDefaultImpl>(input_names_[i], data_type, input.shape_c());
inputs_.push_back(impl);
}
}
outputs_.clear();
auto new_outputs = graph_executor_->GetOutputInfos(kernel_graph_);
if (new_outputs.empty()) {
for (size_t i = 0; i < output_names_.size(); i++) {
auto &output = graph_outputs[i];
auto data_type = static_cast<enum DataType>(output->data_type());
auto impl = std::make_shared<TensorDefaultImpl>(output_names_[i], data_type, output->shape_c());
outputs_.push_back(impl);
}
} else {
if (new_outputs.size() != output_names_.size()) {
MS_LOG(ERROR) << "Output count " << new_outputs.size() << " get from executor != output names count "
<< output_names_.size();
return kCoreFailed;
}
for (size_t i = 0; i < output_names_.size(); i++) {
auto &output = new_outputs[i];
auto data_type = static_cast<enum DataType>(output.data_type());
auto impl = std::make_shared<TensorDefaultImpl>(output_names_[i], data_type, output.shape_c());
outputs_.push_back(impl);
}
}
return kSuccess;
}
Status GraphExecutorSession::RunGraph() { return kSuccess; }
Status GraphExecutorSession::RunGraph(const std::vector<tensor::Tensor> &inputs, std::vector<tensor::Tensor> *outputs) {
MS_LOG(INFO) << "GraphExecutorSession::RunGraph";
MS_EXCEPTION_IF_NULL(graph_executor_);
MS_EXCEPTION_IF_NULL(outputs);
bool ret = true;
if (is_use_kernel_graph_) {
ret = graph_executor_->RunGraph(kernel_graph_, inputs, outputs, options_);
} else {
ret = graph_executor_->RunGraph(func_graph_, inputs, outputs, options_);
}
if (!ret) {
MS_LOG(ERROR) << "GraphExecutorSession::RunGraph run graph failed";
return kCoreFailed;
}
return kSuccess;
}
Status GraphExecutorSession::Resize(const std::vector<tensor::Tensor> &inputs,
const std::vector<std::vector<int64_t>> &new_shapes) {
MS_LOG(INFO) << "GraphExecutorSession::Resize";
MS_EXCEPTION_IF_NULL(graph_executor_);
auto ret = graph_executor_->Resize(kernel_graph_, inputs, new_shapes);
if (!ret) {
return kCoreFailed;
}
auto new_outputs = graph_executor_->GetOutputInfos(kernel_graph_);
if (new_outputs.empty()) {
return kSuccess;
}
if (new_outputs.size() != outputs_.size()) {
MS_LOG(ERROR) << "Output count " << new_outputs.size() << " get from executor != last output count "
<< outputs_.size();
return kCoreFailed;
}
for (size_t i = 0; i < new_shapes.size(); i++) {
auto &input_shape = new_shapes[i];
inputs_[i]->SetShape(input_shape);
inputs_[i]->SetData(nullptr, false); // reset data
}
for (size_t i = 0; i < outputs_.size(); i++) {
auto &output = new_outputs[i];
outputs_[i]->SetShape(output.shape_c());
outputs_[i]->SetData(nullptr, false); // reset data
}
return kSuccess;
}
std::vector<MutableTensorImplPtr> GraphExecutorSession::GetOutputs() { return outputs_; }
std::vector<MutableTensorImplPtr> GraphExecutorSession::GetInputs() { return inputs_; }
std::vector<std::string> GraphExecutorSession::GetOutputNames() { return output_names_; }
std::vector<std::string> GraphExecutorSession::GetInputNames() { return input_names_; }
MutableTensorImplPtr GraphExecutorSession::GetOutputByTensorName(const std::string &tensorName) {
for (size_t i = 0; i < output_names_.size(); i++) {
if (output_names_[i] == tensorName) {
return outputs_[i];
}
}
return nullptr;
}
MutableTensorImplPtr GraphExecutorSession::GetInputByTensorName(const std::string &name) {
for (size_t i = 0; i < input_names_.size(); i++) {
if (input_names_[i] == name) {
return inputs_[i];
}
}
return nullptr;
}
} // namespace mindspore

View File

@ -1,65 +0,0 @@
/**
* Copyright 2019-2021 Huawei Technologies Co., Ltd
*
* 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.
*/
#ifndef MINDSPORE_LITE_EXTENDRT_SESSION_GRAPH_EXECUTOR_SESSION_H_
#define MINDSPORE_LITE_EXTENDRT_SESSION_GRAPH_EXECUTOR_SESSION_H_
#include <vector>
#include <string>
#include <memory>
#include <map>
#include "extendrt/session/delegate_session.h"
#include "extendrt/session/lite_graph_executor.h"
#include "extendrt/utils/kernel_graph_utils.h"
namespace mindspore {
class GraphExecutorSession : public DelegateSession {
public:
GraphExecutorSession() = default;
explicit GraphExecutorSession(std::shared_ptr<mindspore::LiteGraphExecutor> graph_executor)
: graph_executor_(graph_executor) {}
virtual ~GraphExecutorSession() = default;
Status Init(const std::shared_ptr<Context> context) override;
Status CompileGraph(FuncGraphPtr graph, const void *data = nullptr, size_t size = 0) override;
Status RunGraph() override;
Status RunGraph(const std::vector<tensor::Tensor> &inputs, std::vector<tensor::Tensor> *outputs) override;
Status Resize(const std::vector<tensor::Tensor> &inputs, const std::vector<std::vector<int64_t>> &dims) override;
std::vector<MutableTensorImplPtr> GetOutputs() override;
std::vector<MutableTensorImplPtr> GetInputs() override;
std::vector<std::string> GetOutputNames() override;
std::vector<std::string> GetInputNames() override;
MutableTensorImplPtr GetOutputByTensorName(const std::string &tensorName) override;
MutableTensorImplPtr GetInputByTensorName(const std::string &name) override;
private:
std::shared_ptr<mindspore::LiteGraphExecutor> graph_executor_;
std::map<std::string, std::string> options_;
bool is_use_kernel_graph_ = true;
KernelGraphUtilsPtr kernel_graph_utils_;
KernelGraphPtr kernel_graph_;
FuncGraphPtr func_graph_;
std::vector<MutableTensorImplPtr> inputs_;
std::vector<std::string> input_names_;
std::vector<MutableTensorImplPtr> outputs_;
std::vector<std::string> output_names_;
Status InitGraphInputsOutputs();
};
} // namespace mindspore
#endif // MINDSPORE_LITE_EXTENDRT_SESSION_GRAPH_EXECUTOR_SESSION_H_

View File

@ -29,7 +29,7 @@
namespace mindspore {
const size_t tensor_max_size = 0x1000000;
Status LiteInferSession::Init(const std::shared_ptr<Context> context) {
Status LiteInferSession::Init(const std::shared_ptr<Context> &context) {
MS_LOG(INFO) << "SingleOpInferSession::Init";
context_ = context;
lite_session_ = CreateLiteSession(ContextUtils::Convert(context_.get()));
@ -125,10 +125,6 @@ std::vector<int32_t> LiteInferSession::TruncateShape(const std::vector<int64_t>
return truncated_shape;
}
Status LiteInferSession::RunGraph() {
auto ret = lite_session_->RunGraph();
return static_cast<StatusCode>(ret);
}
Status LiteInferSession::RunGraph(const std::vector<tensor::Tensor> &inputs, std::vector<tensor::Tensor> *outputs) {
MS_LOG(INFO) << "SingleOpInferSession::RunGraph with input and outputs";
MS_EXCEPTION_IF_NULL(outputs);
@ -186,7 +182,7 @@ Status LiteInferSession::RunGraph(const std::vector<tensor::Tensor> &inputs, std
}
}
}
auto ret = RunGraph();
auto ret = static_cast<StatusCode>(lite_session_->RunGraph());
ResetTensorData(old_data, input_tensors);
if (ret != kSuccess) {
MS_LOG(ERROR) << "Run graph failed.";
@ -202,10 +198,6 @@ Status LiteInferSession::RunGraph(const std::vector<tensor::Tensor> &inputs, std
*outputs = TensorUtils::MSTensorToTensor(res);
return kSuccess;
}
Status LiteInferSession::Resize(const std::vector<tensor::Tensor> &inputs,
const std::vector<std::vector<int64_t>> &dims) {
return kSuccess;
}
std::vector<MutableTensorImplPtr> LiteInferSession::GetOutputs() {
auto outputs = lite_session_->GetOutputs();
@ -302,8 +294,10 @@ std::vector<tensor::TensorPtr> LiteInferSession::ConvertToTensors(
return tensors;
}
static std::shared_ptr<InferSession> LiteInferSessionCreator(const SessionConfig &config) {
return std::make_shared<LiteInferSession>(config.context_);
static std::shared_ptr<InferSession> LiteInferSessionCreator(const std::shared_ptr<Context> &ctx) {
auto session = std::make_shared<LiteInferSession>();
session->Init(ctx);
return session;
}
REG_SESSION(kLiteInferSession, LiteInferSessionCreator);
} // namespace mindspore

View File

@ -27,14 +27,11 @@ namespace mindspore {
class LiteInferSession : public InferSession {
public:
LiteInferSession() = default;
explicit LiteInferSession(const std::shared_ptr<Context> context) : context_(context) {}
explicit LiteInferSession(const std::shared_ptr<Context> &context) : context_(context) {}
virtual ~LiteInferSession() = default;
Status Init(const std::shared_ptr<Context> context) override;
Status Init(const std::shared_ptr<Context> &context) override;
Status CompileGraph(FuncGraphPtr graph, const void *data = nullptr, size_t size = 0) override;
Status RunGraph() override;
Status RunGraph(const std::vector<tensor::Tensor> &inputs, std::vector<tensor::Tensor> *outputs) override;
Status Resize(const std::vector<tensor::Tensor> &inputs, const std::vector<std::vector<int64_t>> &dims) override;
std::vector<MutableTensorImplPtr> GetOutputs() override;
std::vector<MutableTensorImplPtr> GetInputs() override;
std::vector<std::string> GetOutputNames() override;

View File

@ -1,5 +1,5 @@
/**
* Copyright 2019-2021 Huawei Technologies Co., Ltd
* Copyright 2019-2021 uawei Technologies Co., Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -19,7 +19,7 @@
#include <string>
#include <vector>
#include "src/extendrt/single_op_session.h"
#include "src/extendrt/session/single_op_session.h"
#include "src/extendrt/infer_device_address.h"
#include "plugin/factory/ms_factory.h"
@ -53,7 +53,7 @@ Status SingleOpInferSession::AscendInit(const std::shared_ptr<Context> &context)
return kSuccess;
}
Status SingleOpInferSession::Init(const std::shared_ptr<Context> context) {
Status SingleOpInferSession::Init(const std::shared_ptr<Context> &context) {
MS_LOG(INFO) << "SingleOpInferSession::Init";
MS_EXCEPTION_IF_NULL(context);
kernel_graph_utils_ = std::make_shared<mindspore::KernelGraphUtils>();
@ -158,7 +158,6 @@ Status SingleOpInferSession::CompileGraph(FuncGraphPtr graph, const void *data,
return kSuccess;
}
Status SingleOpInferSession::RunGraph() { return kSuccess; }
Status SingleOpInferSession::RunGraph(const std::vector<tensor::Tensor> &inputs, std::vector<tensor::Tensor> *outputs) {
MS_LOG(INFO) << "SingleOpInferSession::RunGraph with input and outputs";
MS_EXCEPTION_IF_NULL(kernel_graph_);
@ -244,27 +243,6 @@ Status SingleOpInferSession::ResizeGraphInputs(const std::vector<tensor::Tensor>
graph_input->set_abstract(abstract);
}
return kSuccess;
} // namespace mindspore
Status SingleOpInferSession::Resize(const std::vector<tensor::Tensor> &inputs,
const std::vector<std::vector<int64_t>> &dims) {
if (ResizeGraphInputs(inputs, dims) != kSuccess) {
MS_LOG(EXCEPTION) << "Resize graph input error. ";
}
auto &kernel_nodes = kernel_graph_->execution_order();
for (const auto &kernel_node : kernel_nodes) {
std::string kernel_name = common::AnfAlgo::GetCNodeName(kernel_node);
MS_LOG(INFO) << "SingleOpInferSession::Resize " << kernel_name;
auto kernel_mod = AnfAlgo::GetKernelMod(kernel_node);
if (kernel_mod == nullptr) {
MS_LOG(EXCEPTION) << "Kernel mod is nullptr, kernel name: " << kernel_name;
}
auto args = kernel::AbstractArgsFromCNode(kernel_node);
if (kernel_mod->Resize(args.op, args.inputs, args.outputs) != kSuccess) {
MS_LOG(EXCEPTION) << "Kernel mod resize failed, kernel name: " << kernel_name;
}
}
return kSuccess;
}
std::vector<MutableTensorImplPtr> SingleOpInferSession::GetOutputs() { return outputs_; }
std::vector<MutableTensorImplPtr> SingleOpInferSession::GetInputs() { return inputs_; }
@ -295,8 +273,10 @@ MutableTensorImplPtr SingleOpInferSession::GetInputByTensorName(const std::strin
return nullptr;
}
static std::shared_ptr<InferSession> SingleOpSessionCreator(const SessionConfig &config) {
return std::make_shared<SingleOpInferSession>();
static std::shared_ptr<InferSession> SingleOpSessionCreator(const std::shared_ptr<Context> &ctx) {
auto session = std::make_shared<SingleOpInferSession>();
session->Init(ctx);
return session;
}
REG_SESSION(kSingleOpSession, SingleOpSessionCreator);
} // namespace mindspore

View File

@ -19,7 +19,6 @@
#include <string>
#include <memory>
#include <vector>
#include "src/extendrt/infer_session.h"
#include "extendrt/utils/kernel_graph_utils.h"
@ -28,13 +27,10 @@ class SingleOpInferSession : public InferSession {
public:
SingleOpInferSession() = default;
virtual ~SingleOpInferSession() = default;
Status Init(const std::shared_ptr<Context> context) override;
Status Init(const std::shared_ptr<Context> &context) override;
Status AscendInit(const std::shared_ptr<Context> &context);
Status CompileGraph(FuncGraphPtr graph, const void *data = nullptr, size_t size = 0) override;
Status RunGraph() override;
Status RunGraph(const std::vector<tensor::Tensor> &inputs, std::vector<tensor::Tensor> *outputs) override;
Status Resize(const std::vector<tensor::Tensor> &inputs, const std::vector<std::vector<int64_t>> &dims) override;
std::vector<MutableTensorImplPtr> GetOutputs() override;
std::vector<MutableTensorImplPtr> GetInputs() override;
std::vector<std::string> GetOutputNames() override;

View File

@ -19,15 +19,7 @@
#include <memory>
#include <vector>
#include "include/api/delegate.h"
namespace mindspore {
enum SessionType { kDefaultSession = 0, kSingleOpSession, kLiteInferSession, kDelegateSession, kNoneSession };
struct SessionConfig {
SessionType type_;
std::shared_ptr<Context> context_;
std::vector<std::shared_ptr<Delegate>> delegates_;
};
} // namespace mindspore
#endif // MINDSPORE_LITE_EXTENDRT_SESSION_TYPE_H_

View File

@ -1,5 +1,5 @@
/**
* Copyright 2019-2021 Huawei Technologies Co., Ltd
* Copyright 2022 Huawei Technologies Co., Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -13,10 +13,25 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "extendrt/subgraph_kernel.h"
namespace mindspore::infer {
#include "src/extendrt/subgraph_kernel.h"
namespace mindspore::kernel {
bool SubgraphKernel::Launch(const std::vector<AddressPtr> &inputs, const std::vector<AddressPtr> &workspace,
const std::vector<AddressPtr> &outputs, void *stream_ptr) {
// TODO(zhaizhiqiang): Construct input/output tensor::Tensor for graph executor.
std::vector<tensor::Tensor> in;
std::vector<tensor::Tensor> out;
std::map<string, string> compile_options;
executor_->RunGraph(subgraph_, in, &out, compile_options);
return true;
}
} // namespace mindspore::infer
bool SubgraphKernel::Init(const BaseOperatorPtr &opdef, const std::vector<KernelTensorPtr> &inputs,
const std::vector<KernelTensorPtr> &outputs) {
std::map<string, string> compile_options;
return executor_->CompileGraph(subgraph_, compile_options);
}
int SubgraphKernel::Resize(const BaseOperatorPtr &base_operator, const std::vector<KernelTensorPtr> &inputs,
const std::vector<KernelTensorPtr> &outputs,
const std::map<uint32_t, tensor::TensorPtr> &inputsOnHost) {
return 0;
}
} // namespace mindspore::kernel

View File

@ -1,5 +1,5 @@
/**
* Copyright 2019-2021 Huawei Technologies Co., Ltd
* Copyright 2022 Huawei Technologies Co., Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -19,22 +19,28 @@
#include <memory>
#include <map>
#include <vector>
#include "include/api/context.h"
#include "include/api/model.h"
#include "include/api/graph.h"
#include "include/api/status.h"
#include "include/common/utils/utils.h"
#include "kernel/kernel.h"
#include "ir/func_graph.h"
#include "ccsrc/kernel/kernel.h"
struct KernelInfo;
class SubGraphKernel : public KernelMod {
#include "runtime/hardware/device_context.h"
namespace mindspore::kernel {
class SubgraphKernel : public KernelMod {
public:
SubGraphKernel() = default;
virtual ~SubGraphKernel() = default;
SubgraphKernel(FuncGraphPtr subgraph, std::shared_ptr<device::GraphExecutor> executor)
: subgraph_(subgraph), executor_(executor) {}
virtual ~SubgraphKernel() = default;
bool Init(const BaseOperatorPtr & /* base_operator */, const std::vector<KernelTensorPtr> & /* inputs */,
const std::vector<KernelTensorPtr> & /* outputs */) override;
int Resize(const BaseOperatorPtr &base_operator, const std::vector<KernelTensorPtr> &inputs,
const std::vector<KernelTensorPtr> &outputs,
const std::map<uint32_t, tensor::TensorPtr> &inputsOnHost) override;
bool Launch(const std::vector<AddressPtr> &inputs, const std::vector<AddressPtr> &workspace,
const std::vector<AddressPtr> &outputs, void *stream_ptr) override;
protected:
std::vector<KernelInfo> kernels_;
FuncGraphPtr subgraph_;
std::shared_ptr<device::GraphExecutor> executor_;
};
} // namespace mindspore::kernel
#endif

View File

@ -158,6 +158,23 @@ std::vector<int32_t> Context::GetThreadAffinityCoreList() const {
return data_->affinity_core_list_;
}
void Context::set_delegate(const std::shared_ptr<AbstractDelegate> &delegate) {
// if (data_ == nullptr) {
// MS_LOG(ERROR) << "Invalid context.";
// return;
// }
// data_->delegate = std::dynamic_pointer_cast<Delegate>(delegate);
}
std::shared_ptr<AbstractDelegate> Context::get_delegate() const {
if (data_ == nullptr) {
MS_LOG(ERROR) << "Invalid context.";
return nullptr;
}
return data_->delegate;
}
// deprecated
void Context::SetDelegate(const std::shared_ptr<Delegate> &delegate) {
if (data_ == nullptr) {
MS_LOG(ERROR) << "Invalid context.";
@ -166,6 +183,7 @@ void Context::SetDelegate(const std::shared_ptr<Delegate> &delegate) {
data_->delegate = delegate;
}
// deprecated
std::shared_ptr<Delegate> Context::GetDelegate() const {
if (data_ == nullptr) {
MS_LOG(ERROR) << "Invalid context.";

View File

@ -27,6 +27,7 @@
#include <experimental/any>
#endif
#include "include/api/context.h"
#include "include/api/delegate.h"
namespace mindspore {
struct Context::Data {