-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy pathbev_pool_cuda.cu
More file actions
180 lines (162 loc) · 7.55 KB
/
Copy pathbev_pool_cuda.cu
File metadata and controls
180 lines (162 loc) · 7.55 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
#include <stdio.h>
#include <stdlib.h>
/*
Function: pillar pooling
Args:
b : batch size
d : depth of the feature map
h : height of pooled feature map
w : width of pooled feature map
n : number of input points
c : number of channels
n_intervals : number of unique points
x : input features, FloatTensor[n, c]
geom_feats : input coordinates, IntTensor[n, 4]
interval_lengths : starting position for pooled point, IntTensor[n_intervals]
interval_starts : how many points in each pooled point, IntTensor[n_intervals]
out : output features, FloatTensor[b, d, h, w, c]
*/
__global__ void bev_pool_kernel(int b, int d, int h, int w, int n, int c, int n_intervals,
const float *__restrict__ x,
const int *__restrict__ geom_feats,
const int *__restrict__ interval_starts,
const int *__restrict__ interval_lengths,
float *__restrict__ out)
{
int idx = blockIdx.x * blockDim.x + threadIdx.x;
int index = idx / c;
int cur_c = idx % c;
if (index >= n_intervals)
return;
int interval_start = interval_starts[index];
int interval_length = interval_lengths[index];
const int *cur_geom_feats = geom_feats + (interval_start + interval_length - 1) * 4;
const float *cur_x = x + interval_start * c + cur_c;
float *cur_out = out + cur_geom_feats[3] * d * h * w * c +
cur_geom_feats[2] * h * w * c + cur_geom_feats[0] * w * c +
cur_geom_feats[1] * c + cur_c;
float psum = 0;
for (int i = 0; i < interval_length; i++)
{
psum += cur_x[i * c];
}
*cur_out = psum;
}
/*
Function: pillar pooling backward
Args:
b : batch size
d : depth of the feature map
h : height of pooled feature map
w : width of pooled feature map
n : number of input points
c : number of channels
n_intervals : number of unique points
out_grad : gradient of the BEV fmap from top, FloatTensor[b, d, h, w, c]
geom_feats : input coordinates, IntTensor[n, 4]
interval_lengths : starting position for pooled point, IntTensor[n_intervals]
interval_starts : how many points in each pooled point, IntTensor[n_intervals]
x_grad : gradient of the image fmap, FloatTensor
*/
__global__ void bev_pool_grad_kernel(int b, int d, int h, int w, int n, int c, int n_intervals,
const float *__restrict__ out_grad,
const int *__restrict__ geom_feats,
const int *__restrict__ interval_starts,
const int *__restrict__ interval_lengths,
float *__restrict__ x_grad)
{
int idx = blockIdx.x * blockDim.x + threadIdx.x;
int index = idx / c;
int cur_c = idx % c;
if (index >= n_intervals)
return;
int interval_start = interval_starts[index];
int interval_length = interval_lengths[index];
const int *cur_geom_feats = geom_feats + (interval_start + interval_length - 1) * 4;
float *cur_x_grad = x_grad + interval_start * c + cur_c;
const float *cur_out_grad = out_grad + cur_geom_feats[3] * d * h * w * c +
cur_geom_feats[2] * h * w * c + cur_geom_feats[0] * w * c +
cur_geom_feats[1] * c + cur_c;
for (int i = 0; i < interval_length; i++)
{
cur_x_grad[i * c] = *cur_out_grad;
}
}
// mean pooling
__global__ void bev_mean_pool_kernel(int b, int d, int h, int w, int n, int c, int n_intervals,
const float *__restrict__ x,
const int *__restrict__ geom_feats,
const int *__restrict__ interval_starts,
const int *__restrict__ interval_lengths,
float *__restrict__ out)
{
int idx = blockIdx.x * blockDim.x + threadIdx.x;
int index = idx / c;
int cur_c = idx % c;
if (index >= n_intervals)
return;
int interval_start = interval_starts[index];
int interval_length = interval_lengths[index];
const int *cur_geom_feats = geom_feats + (interval_start + interval_length - 1) * 4;
const float *cur_x = x + interval_start * c + cur_c;
float *cur_out = out + cur_geom_feats[3] * d * h * w * c +
cur_geom_feats[2] * h * w * c + cur_geom_feats[0] * w * c +
cur_geom_feats[1] * c + cur_c;
float psum = 0;
for (int i = 0; i < interval_length; i++)
{
psum += cur_x[i * c];
}
psum /= interval_length;
*cur_out = psum;
}
// mean pooling backward
__global__ void bev_mean_pool_grad_kernel(int b, int d, int h, int w, int n, int c, int n_intervals,
const float *__restrict__ out_grad,
const int *__restrict__ geom_feats,
const int *__restrict__ interval_starts,
const int *__restrict__ interval_lengths,
float *__restrict__ x_grad)
{
int idx = blockIdx.x * blockDim.x + threadIdx.x;
int index = idx / c;
int cur_c = idx % c;
if (index >= n_intervals)
return;
int interval_start = interval_starts[index];
int interval_length = interval_lengths[index];
const int *cur_geom_feats = geom_feats + (interval_start + interval_length - 1) * 4;
float *cur_x_grad = x_grad + interval_start * c + cur_c;
const float *cur_out_grad = out_grad + cur_geom_feats[3] * d * h * w * c +
cur_geom_feats[2] * h * w * c + cur_geom_feats[0] * w * c +
cur_geom_feats[1] * c + cur_c;
float grad_out = *cur_out_grad / interval_length;
for (int i = 0; i < interval_length; i++)
{
cur_x_grad[i * c] = grad_out;
}
}
void bev_pool(int b, int d, int h, int w, int n, int c, int n_intervals, const float *x,
const int *geom_feats, const int *interval_starts, const int *interval_lengths, float *out)
{
bev_pool_kernel<<<(int)ceil(((double)n_intervals * c / 256)), 256>>>(
b, d, h, w, n, c, n_intervals, x, geom_feats, interval_starts, interval_lengths, out);
}
void bev_pool_grad(int b, int d, int h, int w, int n, int c, int n_intervals, const float *out_grad,
const int *geom_feats, const int *interval_starts, const int *interval_lengths, float *x_grad)
{
bev_pool_grad_kernel<<<(int)ceil(((double)n_intervals * c / 256)), 256>>>(
b, d, h, w, n, c, n_intervals, out_grad, geom_feats, interval_starts, interval_lengths, x_grad);
}
void bev_mean_pool(int b, int d, int h, int w, int n, int c, int n_intervals, const float *x,
const int *geom_feats, const int *interval_starts, const int *interval_lengths, float *out)
{
bev_mean_pool_kernel<<<(int)ceil(((double)n_intervals * c / 256)), 256>>>(
b, d, h, w, n, c, n_intervals, x, geom_feats, interval_starts, interval_lengths, out);
}
void bev_mean_pool_grad(int b, int d, int h, int w, int n, int c, int n_intervals, const float *out_grad,
const int *geom_feats, const int *interval_starts, const int *interval_lengths, float *x_grad)
{
bev_mean_pool_grad_kernel<<<(int)ceil(((double)n_intervals * c / 256)), 256>>>(
b, d, h, w, n, c, n_intervals, out_grad, geom_feats, interval_starts, interval_lengths, x_grad);
}