math: Asynchronous OpenCL calls have potential for undefined behaviour

Description

There are some innocent-looking code patterns that can actually result in reading memory from destroyed objects.

1) Using any temporary matrix_cl variable in a function that calls a kernel. Synce kernel call is asynchrounous that temporary could be destroyed before the kernel is executed. This is only problem with arguments of type matrix_cl - setKernelArguments() makes a copy of scalars, but not of cl::Buffers.

  1. Constructing a matrix_cl from any temporary object. Since we are using asynchronous copying that that temporary could be destroyed before copying happens.

Example

1)

N=100;
matrix_cl<double> a(N,N), b(N,N), c(N,N);
matrix_cl<double> d = a + b + c;
MatrixXd a = ...
MatrixXd b = ...

matrix_cl<double> c(a + b);

Expected Output

Well-defined behaviour.

Current Version:

v2.20.0

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Comments: 20 (11 by maintainers)

Most upvoted comments

I just found out that documentation for clReleaseMemoryObject says that a memory object is not deleted until all comands using it have completed, even if its reference count is 0. So 1 is not actually an issue.

My clinfo is (two computers) here. I only managed to reproduce the bug on second computer. But I think the bug is completely ours. ICD might only affect the fact that I could not reproduce it on one computer.

I will open a PR later today, after I retry to reproduce bug 1.

Yep! Either way tho’ this is a goof on our end for not checking that sort of stuff well enough or not handling temporaries well. Let’s get those replicated and then we can work out the best fix

It might also be good to open up a PR with these failure cases in the test suite