| 166 | } |
| 167 | |
| 168 | void testStreamCaptureWithAtomics() |
| 169 | { |
| 170 | // The default stream does not support HipGraph stream capture, so create our own. |
| 171 | hipStream_t stream; |
| 172 | HIP_CHECK(hipStreamCreateWithFlags(&stream, hipStreamNonBlocking)); |
| 173 | |
| 174 | // Allocate a counter variable on the device. |
| 175 | // We will have each thread atomically increment it. |
| 176 | int* d_data = nullptr; |
| 177 | int h_data = 0; |
| 178 | const int num_blocks = 2; |
| 179 | const int num_threads = 33; |
| 180 | |
| 181 | // Create a new graph |
| 182 | hipGraph_t graph; |
| 183 | HIP_CHECK(hipGraphCreate(&graph, 0)); |
| 184 | |
| 185 | // Note: currently, calls to hipMallocAsync do not work inside the stream capture section |
| 186 | HIP_CHECK(hipMallocAsync(&d_data, sizeof(int), stream)); |
| 187 | |
| 188 | // ** Begin stream capture ** |
| 189 | HIP_CHECK(hipStreamBeginCapture(stream, hipStreamCaptureModeGlobal)); |
| 190 | |
| 191 | // Transfer the host value |
| 192 | HIP_CHECK(hipMemcpyAsync(d_data, &h_data, sizeof(int), hipMemcpyHostToDevice, stream)); |
| 193 | |
| 194 | // Launch kernel |
| 195 | hipLaunchKernelGGL(atomicIncrement, dim3(num_blocks), dim3(num_threads), 0, stream, d_data); |
| 196 | |
| 197 | // Transfer result back to host |
| 198 | HIP_CHECK(hipMemcpyAsync(&h_data, d_data, sizeof(int), hipMemcpyDeviceToHost, stream)); |
| 199 | |
| 200 | // ** End stream capture ** |
| 201 | HIP_CHECK(hipStreamEndCapture(stream, &graph)); |
| 202 | |
| 203 | // Instantiate the graph |
| 204 | hipGraphExec_t instance; |
| 205 | HIP_CHECK(hipGraphInstantiate(&instance, graph, nullptr, nullptr, 0)); |
| 206 | |
| 207 | // Launch it |
| 208 | const int num_launches = 3; |
| 209 | for (int i = 0; i < num_launches; i++) |
| 210 | { |
| 211 | HIP_CHECK(hipGraphLaunch(instance, stream)); |
| 212 | } |
| 213 | HIP_CHECK(hipStreamSynchronize(stream)); |
| 214 | |
| 215 | // Counter value should match the number of graph launches multiplied by |
| 216 | // the number of threads that were launched. |
| 217 | ASSERT_EQ(h_data, num_launches * num_blocks * num_threads); |
| 218 | |
| 219 | // Clean up |
| 220 | HIP_CHECK(hipFreeAsync(d_data, stream)); |
| 221 | HIP_CHECK(hipStreamDestroy(stream)); |
| 222 | HIP_CHECK(hipGraphDestroy(graph)); |
| 223 | HIP_CHECK(hipGraphExecDestroy(instance)); |
| 224 | } |
| 225 | |