| 143 | } |
| 144 | |
| 145 | void runTest(int version, size_t M, size_t N, |
| 146 | std::unique_ptr<float[]> &inputPtr, |
| 147 | std::unique_ptr<float[]> &outputPtr) { |
| 148 | bool isCPU = version == 0; |
| 149 | |
| 150 | // Allocate GPU buffers and copy data |
| 151 | Context ctx = createContext(); |
| 152 | Tensor input = createTensor(ctx, Shape{M, N}, kf32, inputPtr.get()); |
| 153 | Tensor output = createTensor(ctx, Shape{N, M}, kf32); |
| 154 | |
| 155 | constexpr size_t nIter = 50; |
| 156 | |
| 157 | // Initialize Kernel and bind GPU buffers |
| 158 | LOG(kDefLog, kInfo, "Creating Kernel"); |
| 159 | Kernel kernel = selectTranspose(ctx, version, {input, output}, M, N); |
| 160 | |
| 161 | // Dispatch kernel execution |
| 162 | LOG(kDefLog, kInfo, "Dispatching Kernel version %d, %d iterations ...", |
| 163 | version, nIter); |
| 164 | |
| 165 | // pre-allocate promises and futures for async dispatch |
| 166 | // TODO(avh): implement a pooling mechanism for promises/futures in gpu.h |
| 167 | std::array<std::promise<void>, nIter> promises; |
| 168 | std::array<std::future<void>, nIter> futures; |
| 169 | for (int i = 0; i < nIter; i++) { |
| 170 | futures[i] = promises[i].get_future(); |
| 171 | } |
| 172 | |
| 173 | // Dispatch kernel nIter times |
| 174 | auto start = std::chrono::high_resolution_clock::now(); |
| 175 | for (int i = 0; i < nIter; i++) { |
| 176 | if (!isCPU) { |
| 177 | dispatchKernel(ctx, kernel, promises[i]); |
| 178 | wait(ctx, futures[i]); |
| 179 | resetCommandBuffer(ctx.device, kernel); |
| 180 | } else { |
| 181 | transpose(inputPtr.get(), outputPtr.get(), M, N); |
| 182 | } |
| 183 | } |
| 184 | auto end = std::chrono::high_resolution_clock::now(); |
| 185 | |
| 186 | // Report performance. |
| 187 | // Use microsecond for more accurate time measurement |
| 188 | auto duration = |
| 189 | std::chrono::duration_cast<std::chrono::microseconds>(end - start); |
| 190 | float gbps = sizeof(float) * M * N / |
| 191 | (static_cast<double>(duration.count()) / 1000000.0) / |
| 192 | 1000000000.0 * static_cast<float>(nIter); |
| 193 | |
| 194 | LOG(kDefLog, kInfo, "Copying result to CPU"); |
| 195 | if (!isCPU) { |
| 196 | toCPU(ctx, output, outputPtr.get(), M * N * sizeof(float)); |
| 197 | } |
| 198 | LOG(kDefLog, kInfo, "%s", |
| 199 | show<float>(outputPtr.get(), N, M, "Output").c_str()); |
| 200 | |
| 201 | LOG(kDefLog, kInfo, "\n\n====================================================================" |
| 202 | "============\nExecution Time: (M = %d, N = %d) x %d iterations " |
no test coverage detected