zero copy

Signed-off-by: zhupuxu <zhupuxu@huawei.com>
This commit is contained in:
zhupuxu 2021-03-10 16:22:47 +08:00
parent d490b3ad0b
commit 3cc573b5b8
4 changed files with 205 additions and 10 deletions

View File

@ -102,7 +102,7 @@ Status ModelProcess::ConstructTensors(const std::vector<AclTensorInfo> &acl_tens
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]);
auto ret = aclrtMemcpy((*tensor_list)[i].MutableData(), (*tensor_list)[i].DataSize(),
acl_tensor_list[i].device_data, acl_tensor_list[i].buffer_size, kind);
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;
@ -164,7 +164,8 @@ Status ModelProcess::InitInputsBuffer() {
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, buffer_size, data_type, shape, 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;
@ -246,7 +247,8 @@ Status ModelProcess::InitOutputsBuffer() {
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, buffer_size, data_type, shape, 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;
@ -381,17 +383,23 @@ Status ModelProcess::CheckAndInitInput(const std::vector<MSTensor> &inputs) {
}
// copy inputs
for (size_t i = 0; i < input_infos_.size(); ++i) {
const auto &info = input_infos_[i];
auto &info = input_infos_[i];
auto input = inputs[i];
const void *data = input.MutableData();
void *data = input.MutableData();
void *input_buffer = nullptr;
if (!is_run_on_device_) {
ret = aclrtMemcpy(info.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;
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;
}
input_buffer = info.device_data;
} else {
input_buffer = const_cast<void *>(data);
}

View File

@ -27,6 +27,7 @@
namespace mindspore {
struct AclTensorInfo {
void *cur_device_data;
void *device_data;
size_t buffer_size;
aclDataType data_type;

View File

@ -0,0 +1,27 @@
aipp_op {
aipp_mode: static
input_format : YUV420SP_U8
csc_switch : true
rbuv_swap_switch : false
matrix_r0c0 : 256
matrix_r0c1 : 0
matrix_r0c2 : 359
matrix_r1c0 : 256
matrix_r1c1 : -88
matrix_r1c2 : -183
matrix_r2c0 : 256
matrix_r2c1 : 454
matrix_r2c2 : 0
input_bias_0 : 0
input_bias_1 : 128
input_bias_2 : 128
mean_chn_0 : 124
mean_chn_1 : 116
mean_chn_2 : 102
min_chn_0 : 0.0
min_chn_1 : 0.0
min_chn_2 : 0.0
var_reci_chn_0 : 0.017125
var_reci_chn_1 : 0.017507
var_reci_chn_2 : 0.017429
}

View File

@ -0,0 +1,159 @@
/**
* 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 <sys/stat.h>
#include <string>
#include <vector>
#include <fstream>
#include <iostream>
#include "common/common_test.h"
#include "include/api/types.h"
#include "minddata/dataset/include/execute.h"
#include "minddata/dataset/include/transforms.h"
#include "minddata/dataset/include/vision.h"
#ifdef ENABLE_ACL
#include "minddata/dataset/include/vision_ascend.h"
#endif
#include "minddata/dataset/kernels/tensor_op.h"
#include "include/api/model.h"
#include "include/api/serialization.h"
#include "include/api/context.h"
using namespace mindspore;
using namespace mindspore::dataset;
using namespace mindspore::dataset::vision;
class TestZeroCopy : public ST::Common {
public:
TestZeroCopy() {}
};
constexpr auto resnet_file = "/home/workspace/mindspore_dataset/mindir/resnet50/resnet50_imagenet.mindir";
constexpr auto image_path = "/home/workspace/mindspore_dataset/imagenet/imagenet_original/val/n01440764/";
constexpr auto aipp_path = "./data/dataset/aipp_resnet50.cfg";
size_t GetMax(mindspore::MSTensor data);
std::string RealPath(std::string_view path);
DIR *OpenDir(std::string_view dir_name);
std::vector<std::string> GetAllFiles(std::string_view dir_name);
TEST_F(TestZeroCopy, TestMindIR) {
#ifdef ENABLE_ACL
// Set context
mindspore::GlobalContext::SetGlobalDeviceTarget(mindspore::kDeviceTypeAscend310);
mindspore::GlobalContext::SetGlobalDeviceID(0);
auto model_context = std::make_shared<ModelContext>();
ModelContext::SetInsertOpConfigPath(model_context,aipp_path);
// Define model
auto graph = mindspore::Serialization::LoadModel(resnet_file, mindspore::ModelType::kMindIR);
mindspore::Model resnet50(mindspore::GraphCell(graph),model_context);
// Build model
ASSERT_TRUE(resnet50.Build() == kSuccess);
// Get model info
std::vector<mindspore::MSTensor> model_inputs =resnet50.GetInputs();
ASSERT_EQ(model_inputs.size(), 1);
// Define transform operations
std::shared_ptr<TensorTransform> decode(new vision::Decode());
std::shared_ptr<TensorTransform> resize(new vision::Resize({256}));
std::shared_ptr<TensorTransform> center_crop(new vision::CenterCrop({224,224}));
mindspore::dataset::Execute Transform({decode,resize,center_crop},MapTargetDevice::kAscend310);
size_t count=0;
// Read images
std::vector<std::string> images =GetAllFiles(image_path);
for(const auto &image_file:images){
// prepare input
std::vector<mindspore::MSTensor> inputs;
std::vector<mindspore::MSTensor> outputs;
std::shared_ptr<mindspore::dataset::Tensor> de_tensor;
mindspore::dataset::Tensor::CreateFromFile(image_file, &de_tensor);
auto image = mindspore::MSTensor(std::make_shared<mindspore::dataset::DETensor>(de_tensor));
// Apply transform on images
Status rc = Transform(image, &image);
ASSERT_TRUE(rc == kSuccess);
inputs.push_back(image);
// infer
ASSERT_TRUE(resnet50.Predict(inputs, &outputs)==kSuccess);
if(GetMax(outputs[0])==0){
++count;
}
Transform.DeviceMemoryRelease();
}
ASSERT_GE(static_cast<double>(count)/images.size()*100.0, 20.0);
#endif
}
size_t GetMax(mindspore::MSTensor data) {
float max_value = -1;
size_t max_idx = 0;
const float *p = reinterpret_cast<const float *>(data.MutableData());
for (size_t i = 0; i < data.DataSize() / sizeof(float); ++i) {
if (p[i] > max_value) {
max_value = p[i];
max_idx = i;
}
}
return max_idx;
}
std::string RealPath(std::string_view path) {
char real_path_mem[PATH_MAX] = {0};
char *real_path_ret = realpath(path.data(), real_path_mem);
if (real_path_ret == nullptr) {
return "";
}
return std::string(real_path_mem);
}
DIR *OpenDir(std::string_view dir_name) {
// check the parameter !
if (dir_name.empty()) {
return nullptr;
}
std::string real_path = RealPath(dir_name);
// check if dir_name is a valid dir
struct stat s;
lstat(real_path.c_str(), &s);
if (!S_ISDIR(s.st_mode)) {
return nullptr;
}
DIR *dir;
dir = opendir(real_path.c_str());
if (dir == nullptr) {
return nullptr;
}
return dir;
}
std::vector<std::string> GetAllFiles(std::string_view dir_name) {
struct dirent *filename;
DIR *dir = OpenDir(dir_name);
if (dir == nullptr) {
return {};
}
/* read all the files in the dir ~ */
std::vector<std::string> res;
while ((filename = readdir(dir)) != nullptr) {
std::string d_name = std::string(filename->d_name);
// get rid of "." and ".."
if (d_name == "." || d_name == ".." || filename->d_type != DT_REG)
continue;
res.emplace_back(std::string(dir_name) + "/" + filename->d_name);
}
std::sort(res.begin(), res.end());
return res;
}