Selaa lähdekoodia

Add a Coccinelle script that checks that the return values of the CUDA fucntions are not ignored.

* Prints a warning when the return value is simply ignored
* Creates a patch if a cudaError_t variable is assigned that return value, but is never checked anywhere in the code.
Cyril Roelandt 13 vuotta sitten
vanhempi
commit
69d493a890

+ 56 - 0
tools/dev/experimental/cuda_check_return_values.cocci

@@ -0,0 +1,56 @@
+@initialize:python@
+l = []
+
+
+@seek@
+identifier func;
+expression E;
+statement S1, S2;
+position p;
+identifier cuda_func =~ "^cuda";
+@@
+func(...)
+{
+...
+E@p = cuda_func(...);
+... when != if (!E) S1
+    when != if (!E) S1 else S2
+    when != if (E) S1
+    when != !E
+    when != E != cudaSuccess
+    when != E == cudaSuccess
+    when != STARPU_UNLIKELY(!E)
+}
+
+@fix@
+expression seek.E;
+position seek.p;
+identifier seek.cuda_func;
+@@
+E@p = cuda_func(...);
++ if (STARPU_UNLIKELY(E != cudaSuccess))
++	STARPU_CUDA_REPORT_ERROR(E);
+
+
+@no_assignment@
+identifier cuda_func =~ "^cuda";
+position p;
+@@
+cuda_func@p(...);
+
+
+@script:python@
+p << no_assignment.p;
+func << no_assignment.cuda_func;
+@@
+l.append((p[0], func));
+
+
+@finalize:python@
+for e in l:
+	p, f = e[0], e[1]
+	print "%s:%s : the return value of %s is ignored" % (p.file, p.line, f)
+print "This should probably be patched by either :"
+print " * Checking the return value of the function : cudaError_t ret = f(...);"
+print " * Explicitely ignoring its return value : (void) f(...)"
+

+ 94 - 0
tools/dev/experimental/cuda_check_return_values_test.c

@@ -0,0 +1,94 @@
+static void
+bad_0(void)
+{
+	cudaError_t ret;
+	ret = cudaMalloc(&addr, size);
+
+	ret = foo();
+}
+
+static int
+bad_1(void)
+{
+	cudaError_t cures;
+	cures = cudaMemcpy(NULL, NULL, 0);
+
+	return 0;
+}
+
+static void
+good_0(void)
+{
+	cudaError_t st;
+	st = cudaMemcpy(dst, src, size);
+	if (st)
+		do_stg_good();
+}
+
+static void
+good_1(void)
+{
+	cudaError_t st;
+	st = cudaMemcpy(dst, src, size);
+	if (!st)
+		report_error();
+	else
+		lol();
+}
+
+static void
+good_2(void)
+{
+	cudaError_t st;
+	st = cudaMemcpy(dst, src, size);
+	if (STARPU_UNLIKELY(!st))
+		report_error();
+}
+
+static void
+good_3(void)
+{
+	cudaError_t st;
+	st = cudaMemcpy(dst, src, size);
+	if (STARPU_UNLIKELY(!st))
+		report_error();
+	else
+		foo();
+}
+
+static void
+good_4(void)
+{
+	cudaError_t st;
+	st = cudaMemcpy(dst, src, size);
+	if (st != cudaSuccess)
+		error();
+}
+
+static void
+good_5(void)
+{
+	cudaError_t st;
+	st = cudaMemcpy(dst, src, size);
+	if (st == cudaSuccess)
+		cool();
+}
+
+
+static void
+no_assignment_bad_0(void)
+{
+	cudaGetLastError();
+}
+
+static void
+no_assignment_bad_1(void)
+{
+	cudaMemcpy(dst, src, size);
+}
+
+static void
+no_assignment_good_0(void)
+{
+	(void) cudaGetLastError();
+}