1 /**
2 * Copyright 2021 Huawei Technologies Co., Ltd
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 #include <sys/stat.h>
17 #include <string>
18 #include <vector>
19 #include <fstream>
20 #include <iostream>
21 #include <sys/time.h>
22 #include "common/common_test.h"
23 #include "include/api/types.h"
24 #include "minddata/dataset/include/dataset/execute.h"
25 #include "minddata/dataset/include/dataset/transforms.h"
26 #include "minddata/dataset/include/dataset/vision.h"
27 #ifdef ENABLE_ACL
28 #include "minddata/dataset/include/dataset/vision_ascend.h"
29 #endif
30 #include "minddata/dataset/kernels/tensor_op.h"
31 #include "include/api/model.h"
32 #include "include/api/serialization.h"
33 #include "include/api/context.h"
34
35 using namespace mindspore;
36 using namespace mindspore::dataset;
37 using namespace mindspore::dataset::vision;
38
39 class TestZeroCopy : public ST::Common {
40 public:
TestZeroCopy()41 TestZeroCopy() {}
42 };
43
44 typedef timeval TimeValue;
45 constexpr auto resnet_file = "/home/workspace/mindspore_dataset/mindir/resnet50/resnet50_imagenet.mindir";
46 constexpr auto image_path = "/home/workspace/mindspore_dataset/imagenet/imagenet_original/val/n01440764/";
47 constexpr auto aipp_path = "./data/dataset/aipp_resnet50.cfg";
48 constexpr uint64_t kUSecondInSecond = 1000000;
49 constexpr uint64_t run_nums = 10;
50
51 size_t GetMax(mindspore::MSTensor data);
52 std::string RealPath(std::string_view path);
53 DIR *OpenDir(std::string_view dir_name);
54 std::vector<std::string> GetAllFiles(std::string_view dir_name);
55
TEST_F(TestZeroCopy,TestMindIR)56 TEST_F(TestZeroCopy, TestMindIR) {
57 #ifdef ENABLE_ACL
58 // Set context
59 auto context = ContextAutoSet();
60 ASSERT_TRUE(context != nullptr);
61 ASSERT_TRUE(context->MutableDeviceInfo().size() == 1);
62 auto ascend310_info = context->MutableDeviceInfo()[0]->Cast<Ascend310DeviceInfo>();
63 ASSERT_TRUE(ascend310_info != nullptr);
64 ascend310_info->SetInsertOpConfigPath(aipp_path);
65 auto device_id = ascend310_info->GetDeviceID();
66 // Define model
67 Graph graph;
68 ASSERT_TRUE(Serialization::Load(resnet_file, ModelType::kMindIR, &graph) == kSuccess);
69 Model resnet50;
70 ASSERT_TRUE(resnet50.Build(GraphCell(graph), context) == kSuccess);
71 // Get model info
72 std::vector<mindspore::MSTensor> model_inputs = resnet50.GetInputs();
73 ASSERT_EQ(model_inputs.size(), 1);
74 // Define transform operations
75 std::shared_ptr<TensorTransform> decode(new vision::Decode());
76 std::shared_ptr<TensorTransform> resize(new vision::Resize({256}));
77 std::shared_ptr<TensorTransform> center_crop(new vision::CenterCrop({224, 224}));
78 mindspore::dataset::Execute Transform({decode, resize, center_crop}, MapTargetDevice::kAscend310, device_id);
79 size_t count = 0;
80 // Read images
81 std::vector<std::string> images = GetAllFiles(image_path);
82 for (const auto &image_file : images) {
83 // prepare input
84 std::vector<mindspore::MSTensor> inputs;
85 std::vector<mindspore::MSTensor> outputs;
86 std::shared_ptr<mindspore::dataset::Tensor> de_tensor;
87 mindspore::dataset::Tensor::CreateFromFile(image_file, &de_tensor);
88 auto image = mindspore::MSTensor(std::make_shared<mindspore::dataset::DETensor>(de_tensor));
89 // Apply transform on images
90 Status rc = Transform(image, &image);
91 ASSERT_TRUE(rc == kSuccess);
92 inputs.push_back(image);
93 // infer
94 ASSERT_TRUE(resnet50.Predict(inputs, &outputs) == kSuccess);
95 if (GetMax(outputs[0]) == 0) {
96 ++count;
97 }
98 Transform.DeviceMemoryRelease();
99 }
100 ASSERT_GE(static_cast<double>(count) / images.size() * 100.0, 20.0);
101 #endif
102 }
103
TEST_F(TestZeroCopy,TestDeviceTensor)104 TEST_F(TestZeroCopy, TestDeviceTensor) {
105 #ifdef ENABLE_ACL
106 // Set context
107 auto context = ContextAutoSet();
108 ASSERT_TRUE(context != nullptr);
109 ASSERT_TRUE(context->MutableDeviceInfo().size() == 1);
110 auto ascend310_info = context->MutableDeviceInfo()[0]->Cast<Ascend310DeviceInfo>();
111 ASSERT_TRUE(ascend310_info != nullptr);
112 ascend310_info->SetInsertOpConfigPath(aipp_path);
113 auto device_id = ascend310_info->GetDeviceID();
114 // Define model
115 Graph graph;
116 ASSERT_TRUE(Serialization::Load(resnet_file, ModelType::kMindIR, &graph) == kSuccess);
117 Model resnet50;
118 ASSERT_TRUE(resnet50.Build(GraphCell(graph), context) == kSuccess);
119 // Get model info
120 std::vector<mindspore::MSTensor> model_inputs = resnet50.GetInputs();
121 ASSERT_EQ(model_inputs.size(), 1);
122 // Define transform operations
123 std::shared_ptr<TensorTransform> decode(new vision::Decode());
124 std::shared_ptr<TensorTransform> resize(new vision::Resize({256}));
125 std::shared_ptr<TensorTransform> center_crop(new vision::CenterCrop({224, 224}));
126 mindspore::dataset::Execute Transform({decode, resize, center_crop}, MapTargetDevice::kAscend310, device_id);
127 // Read images
128 std::vector<std::string> images = GetAllFiles(image_path);
129 uint64_t cost = 0, device_cost = 0;
130 for (const auto &image_file : images) {
131 // prepare input
132 std::vector<mindspore::MSTensor> inputs;
133 std::vector<mindspore::MSTensor> outputs;
134 std::shared_ptr<mindspore::dataset::Tensor> de_tensor;
135 mindspore::dataset::Tensor::CreateFromFile(image_file, &de_tensor);
136 auto image = mindspore::MSTensor(std::make_shared<mindspore::dataset::DETensor>(de_tensor));
137 // Apply transform on images
138 Status rc = Transform(image, &image);
139 ASSERT_TRUE(rc == kSuccess);
140 MSTensor *device_tensor =
141 MSTensor::CreateDevTensor(image.Name(), image.DataType(), image.Shape(),
142 image.MutableData(), image.DataSize());
143 MSTensor *tensor =
144 MSTensor::CreateTensor(image.Name(), image.DataType(), image.Shape(),
145 image.Data().get(), image.DataSize());
146 inputs.push_back(*tensor);
147 // infer
148 TimeValue start_time, end_time;
149 (void)gettimeofday(&start_time, nullptr);
150 for (size_t i = 0; i < run_nums; ++i) {
151 ASSERT_TRUE(resnet50.Predict(inputs, &outputs) == kSuccess);
152 }
153 (void)gettimeofday(&end_time, nullptr);
154 cost +=
155 (kUSecondInSecond * static_cast<uint64_t>(end_time.tv_sec) + static_cast<uint64_t>(end_time.tv_usec)) -
156 (kUSecondInSecond * static_cast<uint64_t>(start_time.tv_sec) + static_cast<uint64_t>(start_time.tv_usec));
157 // clear inputs
158 inputs.clear();
159 start_time = (TimeValue){0};
160 end_time = (TimeValue){0};
161 inputs.push_back(*device_tensor);
162
163 // infer with device tensor
164 (void)gettimeofday(&start_time, nullptr);
165 for (size_t i = 0; i < run_nums; ++i) {
166 ASSERT_TRUE(resnet50.Predict(inputs, &outputs) == kSuccess);
167 }
168 (void)gettimeofday(&end_time, nullptr);
169 device_cost +=
170 (kUSecondInSecond * static_cast<uint64_t>(end_time.tv_sec) + static_cast<uint64_t>(end_time.tv_usec)) -
171 (kUSecondInSecond * static_cast<uint64_t>(start_time.tv_sec) + static_cast<uint64_t>(start_time.tv_usec));
172 Transform.DeviceMemoryRelease();
173 }
174 ASSERT_GE(cost, device_cost);
175 #endif
176 }
177
GetMax(mindspore::MSTensor data)178 size_t GetMax(mindspore::MSTensor data) {
179 float max_value = -1;
180 size_t max_idx = 0;
181 const float *p = reinterpret_cast<const float *>(data.MutableData());
182 for (size_t i = 0; i < data.DataSize() / sizeof(float); ++i) {
183 if (p[i] > max_value) {
184 max_value = p[i];
185 max_idx = i;
186 }
187 }
188 return max_idx;
189 }
190
RealPath(std::string_view path)191 std::string RealPath(std::string_view path) {
192 char real_path_mem[PATH_MAX] = {0};
193 char *real_path_ret = realpath(path.data(), real_path_mem);
194 if (real_path_ret == nullptr) {
195 return "";
196 }
197 return std::string(real_path_mem);
198 }
199
OpenDir(std::string_view dir_name)200 DIR *OpenDir(std::string_view dir_name) {
201 // check the parameter !
202 if (dir_name.empty()) {
203 return nullptr;
204 }
205 std::string real_path = RealPath(dir_name);
206
207 // check if dir_name is a valid dir
208 struct stat s;
209 lstat(real_path.c_str(), &s);
210 if (!S_ISDIR(s.st_mode)) {
211 return nullptr;
212 }
213
214 DIR *dir;
215 dir = opendir(real_path.c_str());
216 if (dir == nullptr) {
217 return nullptr;
218 }
219 return dir;
220 }
221
GetAllFiles(std::string_view dir_name)222 std::vector<std::string> GetAllFiles(std::string_view dir_name) {
223 struct dirent *filename;
224 DIR *dir = OpenDir(dir_name);
225 if (dir == nullptr) {
226 return {};
227 }
228 /* read all the files in the dir ~ */
229 std::vector<std::string> res;
230 while ((filename = readdir(dir)) != nullptr) {
231 std::string d_name = std::string(filename->d_name);
232 // get rid of "." and ".."
233 if (d_name == "." || d_name == ".." || filename->d_type != DT_REG) continue;
234 res.emplace_back(std::string(dir_name) + "/" + filename->d_name);
235 }
236
237 std::sort(res.begin(), res.end());
238 return res;
239 }
240