geometry-central icon indicating copy to clipboard operation
geometry-central copied to clipboard

Which methods are thread safe?

Open ghurstunither opened this issue 3 years ago • 3 comments

As far as I can tell, some methods that seem like they'd be thread safe aren't.

I think this is because under the hood some quantities are being precomputed and saved. So for example, applying a VectorHeatMethodSolver object vSolver on dummy data before calling vSolver in a parallel routine seems to make it thread safe.

Is this true?

Here is a small example illustrating what I mean:

std::unique_ptr<ManifoldSurfaceMesh> mesh;
std::unique_ptr<VertexPositionGeometry> geometry;
std::tie(mesh, geometry) = readManifoldSurfaceMesh("filename.obj");

VertexData<double> rhs(mesh, 0.2);
VectorHeatMethodSolver vSolver(geom, 1);

vSolver.scalarDiffuse(rhs); // comment out this line to cause problems

tbb::parallel_for(
  tbb::blocked_range<size_t>(0, 100),
  [&](tbb::blocked_range<size_t> rng)
  {
    for (size_t i = rng.begin(); i < rng.end(); i++)
      vSolver.scalarDiffuse(rhs);
  }
);

In general is there a way to tell which routines are thread safe, or can be made thread safe?

(My main motivation here was to parallelize the outer loop inside each Lloyd iteration of a GCVT routine.)

ghurstunither avatar Jan 30 '22 22:01 ghurstunither

Hi! Pardon the slow response here, I missed this issue.

Unfortunately the short answer is that almost nothing in geometry-central is guaranteed to be thread safe. There are a few methods that luck-out and happen to be thread-safe, but I can't make any promises.

I think that any routines which traverse a mesh without modifying it should be safe. But I haven't double-checked.

The geometry classes' require___() routines are not thread safe.

I believe that any classes that internally manage a linear solver will not be thread safe with Suitesparse, because Suitesparse uses shared scratch space for backsolves. I think that in your example above, pre-initializing helps because the factorization happens in a single thread (factoring is definitely thread safe). However, I don't think that your parallel backsolve are guaranteed to be safe, even after doing that.

Feel free to follow up if you (or anyone else) has questions about particular routines and their thread safety.

nmwsharp avatar Nov 22 '22 17:11 nmwsharp

I wanted to follow up with this question. I'm having problems running functions in threads which use MeshData objects on the same mesh. It seems to randomly crash when adding callbacks to the mesh. This is easily worked around by using vectors and indices instead of MeshData, but the MeshData format is convenient. Do you recommend not using MeshData unless it's a quantity that's meant to be kind of "permanently" attached the mesh?

nervoussystem avatar Mar 18 '23 14:03 nervoussystem

I believe accessing/reading/writing elements in a MeshData<> container should be thread-safe. At that point it's just a decorator over access into the underlying Eigen array. The only problems should arise when you create & delete the MeshData<> container, or modify the underlying mesh. (Which sounds consistent with what you observed).

In general it should be fine to temporarily create and delete short-lived MeshData<>s in the normal single-threaded cases (I certainly do this all the time). However for multi-threaded code this is indeed a source of non-thread-safety, because of the callback list.

This is all off the top of my head, but I think maybe you could make this thread safe by creating a mutex associated with the mesh, and requiring threads to lock the mutex before modifying the mesh or creating/deleting MeshData<>s. Hope that helps!

nmwsharp avatar Mar 20 '23 06:03 nmwsharp