Apollo 11.0
自动驾驶开放平台
libtorch_obstacle_detector.cc
浏览该文件的文档.
1/******************************************************************************
2 * Copyright 2020 The Apollo Authors. All Rights Reserved.
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
18
19#include "cyber/common/log.h"
21
22namespace apollo {
23namespace perception {
24namespace inference {
25
27
28ObstacleDetector::ObstacleDetector(const std::string &net_file,
29 const std::string &model_file,
30 const std::vector<std::string> &outputs)
31 : net_file_(net_file), model_file_(model_file), output_names_(outputs) {}
32
33ObstacleDetector::ObstacleDetector(const std::string &net_file,
34 const std::string &model_file,
35 const std::vector<std::string> &outputs,
36 const std::vector<std::string> &inputs)
37 : net_file_(net_file),
38 model_file_(model_file),
39 output_names_(outputs),
40 input_names_(inputs) {}
41
43 const std::map<std::string, std::vector<int>> &shapes) {
44 if (gpu_id_ >= 0) {
45 device_type_ = torch::kCUDA;
46 device_id_ = gpu_id_;
47 } else {
48 device_type_ = torch::kCPU;
49 }
50
51 for (const auto &name : output_names_) {
52 auto iter = shapes.find(name);
53 if (iter != shapes.end()) {
54 auto blob = std::make_shared<Blob<float>>(iter->second);
55 blobs_.emplace(name, blob);
56 }
57 }
58
59 for (const auto &name : input_names_) {
60 auto iter = shapes.find(name);
61 if (iter != shapes.end()) {
62 auto blob = std::make_shared<Blob<float>>(iter->second);
63 blobs_.emplace(name, blob);
64 }
65 }
66
67 // Load model without grad, equal to torch.no_grad()
68 // torch::NoGradGuard no_grad;
69 // Init net
70 torch::Device device(device_type_, device_id_);
71 net_ = torch::jit::load(model_file_, device);
72 net_.eval();
73
74 // run a fake inference at init time as first inference is relative slow
75 int height_ = blobs_[input_names_[0]]->shape(1);
76 int width_ = blobs_[input_names_[0]]->shape(2);
77 torch::Tensor input_feature_tensor = torch::zeros({1, 3, height_, width_});
78 std::array<float, 2> down_ratio{8.0f, 8.0f};
79 torch::Tensor tensor_downratio = torch::from_blob(down_ratio.data(), {1, 2});
80 std::array<float, 9> K{1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f};
81 torch::Tensor tensor_K = torch::from_blob(K.data(), {1, 3, 3});
82
83 std::vector<torch::jit::IValue> torch_inputs;
84 torch_inputs.push_back(input_feature_tensor.to(device));
85 torch_inputs.push_back(
86 std::make_tuple(tensor_K.to(device), tensor_downratio.to(device)));
87 auto torch_output_tensor = net_.forward(torch_inputs).toTuple()->elements();
88 if (torch_output_tensor[0].toTensor().requires_grad()) {
89 AWARN << "Require grad";
90 }
91
92 emptyCache();
93 return true;
94}
95
96std::shared_ptr<Blob<float>> ObstacleDetector::get_blob(
97 const std::string &name) {
98 auto iter = blobs_.find(name);
99 if (iter == blobs_.end()) {
100 return nullptr;
101 }
102 return iter->second;
103}
104
105bool ObstacleDetector::shape(const std::string &name, std::vector<int> *res) {
106 auto blob = get_blob(name);
107 if (blob == nullptr) {
108 return false;
109 }
110
111 *res = blob->shape();
112 return true;
113}
114
116 torch::Device device(device_type_, device_id_);
117 auto blob = blobs_[input_names_[0]];
118 auto input_K = blobs_[input_names_[1]];
119 auto input_ratio = blobs_[input_names_[2]];
120
121 torch::Tensor tensor_image = torch::from_blob(
122 blob->data()->mutable_gpu_data(),
123 {blob->shape(0), blob->shape(1), blob->shape(2), blob->shape(3)},
124 torch::kFloat32);
125 torch::Tensor tensor_K = torch::from_blob(
126 input_K->data()->mutable_cpu_data(),
127 {input_K->shape(0), input_K->shape(1), input_K->shape(2)},
128 torch::kFloat32);
129 torch::Tensor tensor_ratio = torch::from_blob(
130 input_ratio->data()->mutable_cpu_data(),
131 {input_ratio->shape(0), input_ratio->shape(1)}, torch::kFloat32);
132
133 std::vector<torch::jit::IValue> torch_inputs;
134 torch_inputs.push_back(tensor_image.to(device));
135 torch_inputs.push_back(
136 std::make_tuple(tensor_K.to(device), tensor_ratio.to(device)));
137
138 AINFO << "Start to do inference";
139 auto outputs = net_.forward(torch_inputs).toTuple()->elements();
140 AINFO << "Finished inference";
141
142 for (size_t i = 0; i < output_names_.size(); ++i) {
143 auto blob = get_blob(output_names_[i]);
144 if (blob != nullptr) {
145 torch::Tensor output_tensor = outputs[i].toTensor();
146 std::vector<int64_t> output_size_ = output_tensor.sizes().vec();
147 std::vector<int> output_size(begin(output_size_), end(output_size_));
148 blob->Reshape(output_size);
149 blob->set_gpu_data(output_tensor.data_ptr<float>());
150 }
151 }
152}
153
154} // namespace inference
155} // namespace perception
156} // namespace apollo
A wrapper around SyncedMemory holders serving as the basic computational unit for images,...
Definition blob.h:88
base::BlobPtr< float > get_blob(const std::string &name) override
ObstacleDetector(const std::string &net_file, const std::string &model_file, const std::vector< std::string > &outputs)
bool shape(const std::string &name, std::vector< int > *res)
bool Init(const std::map< std::string, std::vector< int > > &shapes) override
first check imutoantoffset saved in device
Definition readme.txt:2
#define AINFO
Definition log.h:42
#define AWARN
Definition log.h:43
class register implement
Definition arena_queue.h:37