Apollo 11.0
自动驾驶开放平台
gpu_down_sample.cc
浏览该文件的文档.
1/******************************************************************************
2 * Copyright 2024 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 <algorithm>
20
23
24namespace apollo {
25namespace perception {
26namespace lidar {
27
29 std::string config_file = GetConfigFile(options.config_path, options.config_file);
31 ACHECK(cyber::common::GetProtoFromFile(config_file, &config));
32 downsample_voxel_size_x_ = config.downsample_voxel_size_x();
33 downsample_voxel_size_y_ = config.downsample_voxel_size_y();
34 downsample_voxel_size_z_ = config.downsample_voxel_size_z();
35 downsample_use_centroid = config.downsample_use_centroid();
36
37 AINFO << "GpuDownSample plugin init success.";
38 return true;
39}
40
42 base::PointF* h_point_cloud;
43 base::PointF* d_point_cloud;
44 cudaError_t err = ::cudaSuccess;
45 unsigned int flags = cudaHostAllocMapped;
46 err = cudaHostAlloc(&h_point_cloud, cloud_ptr->size() * sizeof(base::PointF), flags);
47 if (err != ::cudaSuccess) {
48 AERROR << "cudaHostAlloc returns failed";
49 }
50 err = cudaHostGetDevicePointer(&d_point_cloud, h_point_cloud, 0);
51 if (err != ::cudaSuccess) {
52 AERROR << "cudaHostGetDevicePointer returns failed";
53 }
54 for (int i = 0; i < cloud_ptr->size(); i++) {
55 h_point_cloud[i].x = cloud_ptr->at(i).x;
56 h_point_cloud[i].y = cloud_ptr->at(i).y;
57 h_point_cloud[i].z = cloud_ptr->at(i).z;
58 h_point_cloud[i].intensity = cloud_ptr->at(i).intensity;
59 }
60
61 // DownSample
62 int filtered_point_count = cloud_ptr->size();
63 if (!downSample(
64 d_point_cloud,
65 filtered_point_count,
66 downsample_voxel_size_x_,
67 downsample_voxel_size_y_,
68 downsample_voxel_size_z_,
69 downsample_use_centroid)) {
70 AERROR << "downSample is wrong!";
71 }
72 cudaDeviceSynchronize();
73
74 // After DownSample
75 cloud_ptr->resize(filtered_point_count);
76 for (int i = 0; i < filtered_point_count; i++) {
77 cloud_ptr->at(i).x = h_point_cloud[i].x;
78 cloud_ptr->at(i).y = h_point_cloud[i].y;
79 cloud_ptr->at(i).z = h_point_cloud[i].z;
80 cloud_ptr->at(i).intensity = h_point_cloud[i].intensity;
81 }
82 cudaFreeHost(h_point_cloud);
83 return true;
84}
85
86void GpuDownSample::warmUpGPU() {
87 cudaError_t err = ::cudaSuccess;
88 err = cudaSetDevice(0);
89 if (err != ::cudaSuccess) {
90 return;
91 }
92
93 err = voxel_downSample_ptr->cudaWarmUpGPU();
94 if (err != ::cudaSuccess) {
95 return;
96 }
97}
98
99int GpuDownSample::getNumberOfAvailableThreads() {
100 cudaDeviceProp prop;
101 cudaGetDeviceProperties(&prop, 0);
102
103 int threads = 0;
104 // major, minor are the major and minor revision numbers
105 // defining the device's compute capability
106 if (prop.major == 2) {
107 threads = prop.maxThreadsPerBlock / 2;
108 } else if (prop.major > 2) {
109 threads = prop.maxThreadsPerBlock;
110 } else {
111 return 0;
112 }
113
114 return threads;
115}
116
117bool GpuDownSample::downSample(
118 base::PointF* point_cloud,
119 int& point_cloud_size,
120 float resolution_x,
121 float resolution_y,
122 float resolution_z,
123 bool use_centroid_downsample) {
124 cudaError_t err = ::cudaSuccess;
125 err = cudaSetDevice(0);
126 if (err != ::cudaSuccess) {
127 return false;
128 }
129 gridParameters rgd_params;
130 hashElement* d_hashTable = NULL;
131 voxel* d_voxel = NULL;
132 bool* d_markers;
133 bool* h_markers;
134 int* count;
135 int threads = getNumberOfAvailableThreads();
136 if (threads == 0) {
137 return false;
138 }
139
140 err = voxel_downSample_ptr->cudaCalculateGridParams(
141 point_cloud, point_cloud_size, resolution_x, resolution_y, resolution_z, rgd_params);
142 if (err != ::cudaSuccess) {
143 return false;
144 }
145
146 err = cudaMalloc(reinterpret_cast<void**>(&d_hashTable), point_cloud_size * sizeof(hashElement));
147 if (err != ::cudaSuccess) {
148 return false;
149 }
150 err = cudaMalloc(reinterpret_cast<void**>(&count), sizeof(int));
151 if (err != ::cudaSuccess) {
152 return false;
153 }
154 if (use_centroid_downsample) {
155 err = cudaMalloc(reinterpret_cast<void**>(&d_voxel), point_cloud_size * sizeof(voxel));
156 if (err != ::cudaSuccess) {
157 return false;
158 }
159 }
160 err = voxel_downSample_ptr->cudaCalculateGrid(
161 threads, point_cloud, d_hashTable, point_cloud_size, rgd_params, count);
162 if (err != ::cudaSuccess) {
163 return false;
164 }
165
166 if (!use_centroid_downsample) {
167 err = cudaMalloc(reinterpret_cast<void**>(&d_markers), point_cloud_size * sizeof(bool));
168 if (err != ::cudaSuccess) {
169 return false;
170 }
171 }
172 err = voxel_downSample_ptr->cudaDownSample(
173 threads,
174 point_cloud,
175 d_markers,
176 d_hashTable,
177 d_voxel,
178 point_cloud_size,
179 rgd_params,
180 use_centroid_downsample,
181 count);
182 if (err != ::cudaSuccess) {
183 return false;
184 }
185
186 if (use_centroid_downsample) {
187 int* host_count = new int[1];
188 err = cudaMemcpy(host_count, count, sizeof(int), cudaMemcpyDeviceToHost);
189 if (err != ::cudaSuccess) {
190 return false;
191 }
192 point_cloud_size = host_count[0];
193 } else {
194 h_markers = reinterpret_cast<bool*>(malloc(point_cloud_size * sizeof(bool)));
195 err = cudaMemcpy(h_markers, d_markers, point_cloud_size * sizeof(bool), cudaMemcpyDeviceToHost);
196 if (err != ::cudaSuccess) {
197 return false;
198 }
199 int valid_size = 0;
200 for (size_t i = 0; i < point_cloud_size; i++) {
201 if (h_markers[i]) {
202 point_cloud[valid_size] = point_cloud[i];
203 valid_size += 1;
204 }
205 }
206 point_cloud_size = valid_size;
207 }
208
209 if (!use_centroid_downsample) {
210 free(h_markers);
211 }
212
213 err = cudaFree(d_hashTable);
214 d_hashTable = NULL;
215 if (err != ::cudaSuccess) {
216 return false;
217 }
218 err = cudaFree(count);
219 count = NULL;
220 if (err != ::cudaSuccess) {
221 return false;
222 }
223 if (use_centroid_downsample) {
224 err = cudaFree(d_voxel);
225 d_voxel = NULL;
226 if (err != ::cudaSuccess) {
227 return false;
228 }
229 } else {
230 err = cudaFree(d_markers);
231 d_markers = NULL;
232 if (err != ::cudaSuccess) {
233 return false;
234 }
235 }
236
237 return true;
238}
239
240} // namespace lidar
241} // namespace perception
242} // namespace apollo
bool Init(const DownSampleInitOptions &options=DownSampleInitOptions()) override
Init of GpuDownSample object
bool Process(const DownSampleOptions &options, base::PointFCloudPtr &cloud_ptr) override
filter mark area objects
cudaError_t cudaCalculateGridParams(base::PointF *d_point_cloud, int number_of_points, float resolution_X, float resolution_Y, float resolution_Z, gridParameters &out_rgd_params)
cudaError_t cudaCalculateGrid(int threads, base::PointF *d_point_cloud, hashElement *d_hashTable, int number_of_points, gridParameters rgd_params, int *count)
cudaError_t cudaDownSample(int threads, base::PointF *d_point_cloud, bool *d_markers, hashElement *d_hashTable, voxel *d_voxel, int number_of_points, gridParameters rgd_params, bool use_centroid_downsample, int *count)
#define ACHECK(cond)
Definition log.h:80
#define AERROR
Definition log.h:44
#define AINFO
Definition log.h:42
bool GetProtoFromFile(const std::string &file_name, google::protobuf::Message *message)
Parses the content of the file specified by the file_name as a representation of protobufs,...
Definition file.cc:132
Point< float > PointF
Definition point.h:56
std::shared_ptr< PointFCloud > PointFCloudPtr
std::string GetConfigFile(const std::string &config_path, const std::string &config_file)
Definition util.cc:80
class register implement
Definition arena_queue.h:37