| 24 | |
| 25 | template<typename T> |
| 26 | static void where(Param<uint> &out, CParam<T> in) { |
| 27 | auto where = common::getKernel("arrayfire::cuda::where", {{where_cuh_src}}, |
| 28 | TemplateArgs(TemplateTypename<T>())); |
| 29 | |
| 30 | uint threads_x = nextpow2(std::max(32u, (uint)in.dims[0])); |
| 31 | threads_x = std::min(threads_x, THREADS_PER_BLOCK); |
| 32 | uint threads_y = THREADS_PER_BLOCK / threads_x; |
| 33 | |
| 34 | uint blocks_x = divup(in.dims[0], threads_x * REPEAT); |
| 35 | uint blocks_y = divup(in.dims[1], threads_y); |
| 36 | |
| 37 | Param<uint> rtmp; |
| 38 | Param<uint> otmp; |
| 39 | rtmp.dims[0] = blocks_x; |
| 40 | otmp.dims[0] = in.dims[0]; |
| 41 | rtmp.strides[0] = 1; |
| 42 | otmp.strides[0] = 1; |
| 43 | |
| 44 | for (int k = 1; k < 4; k++) { |
| 45 | rtmp.dims[k] = in.dims[k]; |
| 46 | rtmp.strides[k] = rtmp.strides[k - 1] * rtmp.dims[k - 1]; |
| 47 | |
| 48 | otmp.dims[k] = in.dims[k]; |
| 49 | otmp.strides[k] = otmp.strides[k - 1] * otmp.dims[k - 1]; |
| 50 | } |
| 51 | |
| 52 | int rtmp_elements = rtmp.strides[3] * rtmp.dims[3]; |
| 53 | int otmp_elements = otmp.strides[3] * otmp.dims[3]; |
| 54 | auto rtmp_alloc = memAlloc<uint>(rtmp_elements); |
| 55 | auto otmp_alloc = memAlloc<uint>(otmp_elements); |
| 56 | rtmp.ptr = rtmp_alloc.get(); |
| 57 | otmp.ptr = otmp_alloc.get(); |
| 58 | |
| 59 | scan_first_launcher<T, uint, af_notzero_t>( |
| 60 | otmp, rtmp, in, blocks_x, blocks_y, threads_x, false, true); |
| 61 | |
| 62 | // Linearize the dimensions and perform scan |
| 63 | Param<uint> ltmp = rtmp; |
| 64 | ltmp.dims[0] = rtmp_elements; |
| 65 | for (int k = 1; k < 4; k++) { |
| 66 | ltmp.dims[k] = 1; |
| 67 | ltmp.strides[k] = rtmp_elements; |
| 68 | } |
| 69 | |
| 70 | scan_first<uint, uint, af_add_t>(ltmp, ltmp, true); |
| 71 | |
| 72 | // Get output size and allocate output |
| 73 | uint total; |
| 74 | CUDA_CHECK(cudaMemcpyAsync(&total, rtmp.ptr + rtmp_elements - 1, |
| 75 | sizeof(uint), cudaMemcpyDeviceToHost, |
| 76 | getActiveStream())); |
| 77 | CUDA_CHECK(cudaStreamSynchronize(cuda::getActiveStream())); |
| 78 | |
| 79 | auto out_alloc = memAlloc<uint>(total); |
| 80 | out.ptr = out_alloc.get(); |
| 81 | |
| 82 | out.dims[0] = total; |
| 83 | out.strides[0] = 1; |
nothing calls this directly
no test coverage detected