• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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