1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
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);
}
|