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: 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 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 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 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 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 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 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