summaryrefslogtreecommitdiffstats
path: root/tools/cuda-ab/p2/src/p2_printf_err.cu
diff options
context:
space:
mode:
Diffstat (limited to 'tools/cuda-ab/p2/src/p2_printf_err.cu')
-rw-r--r--tools/cuda-ab/p2/src/p2_printf_err.cu100
1 files changed, 100 insertions, 0 deletions
diff --git a/tools/cuda-ab/p2/src/p2_printf_err.cu b/tools/cuda-ab/p2/src/p2_printf_err.cu
new file mode 100644
index 0000000..d7f449e
--- /dev/null
+++ b/tools/cuda-ab/p2/src/p2_printf_err.cu
@@ -0,0 +1,100 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * p2_printf_err - device printf plus an intentional launch error path.
+ *
+ * 1. A 4-thread kernel prints deterministic P2PRINT lines from the device.
+ * 2. A kernel launched with gridDim.x == 0 must be rejected:
+ * cudaErrorInvalidConfiguration (9), and the error must be cleared by
+ * cudaGetLastError. A blockDim.x == 0 launch is exercised too.
+ * 3. A normal launch after the errors proves error recovery.
+ *
+ * Expected error strings come from the statically linked CUDA runtime, so
+ * they must be identical on host and guest.
+ * Device memory: out 4 B.
+ */
+#include "common.h"
+
+__global__ void hello(int nthreads)
+{
+ int i = threadIdx.x;
+
+ if (i < nthreads)
+ printf("P2PRINT hello i=%d\n", i);
+}
+
+__global__ void second(void)
+{
+ if (threadIdx.x == 0)
+ printf("P2PRINT second c=%c v=%d\n", 'Z', 7);
+}
+
+__global__ void simple(int *out)
+{
+ out[0] = 42;
+}
+
+int main(int argc, char **argv)
+{
+ if (p2_emit_mode(argc, argv)) {
+ printf("P2PRINT hello i=0\n");
+ printf("P2PRINT hello i=1\n");
+ printf("P2PRINT hello i=2\n");
+ printf("P2PRINT hello i=3\n");
+ printf("P2PRINT second c=Z v=7\n");
+ printf("ERR launch grid0 rc=%d name=%s\n",
+ (int)cudaErrorInvalidConfiguration,
+ cudaGetErrorString(cudaErrorInvalidConfiguration));
+ printf("ERR launch block0 rejected=1\n");
+ printf("ERR cleared rc=0\n");
+ printf("RESULT errmode grid0_bad=0 block0_bad=0 clear_bad=0 recovered=1\n");
+ return p2_status(0);
+ }
+
+ p2_device_info();
+
+ int *d_out = NULL;
+ P2_CHECK(cudaMalloc(&d_out, sizeof(int)));
+
+ hello<<<1, 4>>>(4);
+ P2_CHECK(cudaGetLastError());
+ P2_CHECK(cudaDeviceSynchronize());
+ second<<<1, 4>>>();
+ P2_CHECK(cudaGetLastError());
+ P2_CHECK(cudaDeviceSynchronize());
+
+ (void)cudaGetLastError();
+
+ int badgrid = 0, badblock = 0;
+ cudaError_t e_grid, e_block, cleared;
+ int got = 0;
+
+ simple<<<badgrid, 1>>>(d_out);
+ e_grid = cudaGetLastError();
+ printf("ERR launch grid0 rc=%d name=%s\n", (int)e_grid,
+ cudaGetErrorString(e_grid));
+
+ simple<<<1, badblock>>>(d_out);
+ e_block = cudaGetLastError();
+ printf("ERR launch block0 rejected=%d\n",
+ (e_block != cudaSuccess) ? 1 : 0);
+
+ cleared = cudaGetLastError();
+ printf("ERR cleared rc=%d\n", (int)cleared);
+
+ simple<<<1, 1>>>(d_out);
+ P2_CHECK(cudaGetLastError());
+ P2_CHECK(cudaDeviceSynchronize());
+ P2_CHECK(cudaMemcpy(&got, d_out, sizeof(int), cudaMemcpyDeviceToHost));
+
+ int grid0_bad = (e_grid != cudaErrorInvalidConfiguration) ? 1 : 0;
+ int block0_bad = (e_block == cudaSuccess) ? 1 : 0;
+ int clear_bad = (cleared != cudaSuccess) ? 1 : 0;
+ int recovered = (got == 42) ? 1 : 0;
+ int bad = grid0_bad + block0_bad + clear_bad + (recovered ? 0 : 1);
+
+ printf("RESULT errmode grid0_bad=%d block0_bad=%d clear_bad=%d recovered=%d\n",
+ grid0_bad, block0_bad, clear_bad, recovered);
+
+ cudaFree(d_out);
+ return p2_status(bad);
+}