| 275 | |
| 276 | template<typename T> |
| 277 | __global__ void get_features(float *x_out, float *y_out, float *score_out, |
| 278 | const T *flags, const unsigned *d_counts, |
| 279 | const unsigned *d_offsets, const unsigned total, |
| 280 | const unsigned idim0, const unsigned idim1, |
| 281 | const unsigned edge) { |
| 282 | const int xid = blockIdx.x * blockDim.x * 2 + threadIdx.x; |
| 283 | const int yid = blockIdx.y * blockDim.y * 8 + threadIdx.y; |
| 284 | const int tid = blockDim.x * threadIdx.y + threadIdx.x; |
| 285 | |
| 286 | const int xoff = blockDim.x; |
| 287 | const int yoff = blockDim.y; |
| 288 | |
| 289 | const int xend = (blockIdx.x + 1) * blockDim.x * 2; |
| 290 | const int yend = (blockIdx.y + 1) * blockDim.y * 8; |
| 291 | |
| 292 | const int bid = blockIdx.y * gridDim.x + blockIdx.x; |
| 293 | |
| 294 | __shared__ unsigned s_count; |
| 295 | __shared__ unsigned s_idx; |
| 296 | |
| 297 | if (tid == 0) { |
| 298 | s_count = d_counts[bid]; |
| 299 | s_idx = d_offsets[bid]; |
| 300 | } |
| 301 | __syncthreads(); |
| 302 | |
| 303 | // Blocks that are empty, please bail |
| 304 | if (s_count == 0) return; |
| 305 | for (int y = yid; y < yend; y += yoff) { |
| 306 | if (y >= idim1 - edge - 1 || y <= edge + 1) continue; |
| 307 | for (int x = xid; x < xend; x += xoff) { |
| 308 | if (x >= idim0 - edge - 1 || x <= edge + 1) continue; |
| 309 | |
| 310 | float v = flags[y * idim0 + x]; |
| 311 | if (v == 0) continue; |
| 312 | |
| 313 | unsigned id = atomicAdd(&s_idx, 1u); |
| 314 | if (id >= total) return; |
| 315 | y_out[id] = x; |
| 316 | x_out[id] = y; |
| 317 | score_out[id] = v; |
| 318 | } |
| 319 | } |
| 320 | } |
| 321 | |
| 322 | template<typename T> |
| 323 | void fast(unsigned *out_feat, float **x_out, float **y_out, float **score_out, |
nothing calls this directly
no test coverage detected