aewallin / opencamlib

open source computer aided manufacturing algorithms library
http://www.anderswallin.net/CAM
GNU Lesser General Public License v2.1
394 stars 136 forks source link

Python multithreading... #139

Open joemarshall opened 1 year ago

joemarshall commented 1 year ago

When you call e.g. waterline.run() or waterline.run2() from python, it takes some time inside opencamlib, doing stuff only with opencamlib structures. Because of the python global interpreter lock, this blocks all python threads, meaning a) you can't do multiple different operations at once (e.g. run waterlines at multiple z values) and b) everything else in python hangs while any opencamlib operations are running.

Or alternatively, one could make waterline support taking a list of z values and running them in parallel, given that it is likely to be run on multiple layers anyway, and it would save reloading the stl for each thread.

vespakoen commented 1 year ago

I like this suggestion, and it is similar to #84.

Being able to pass in multiple z depths sounds like an easy addition that can help speed things up.

Alternatively, a function that can run multiple algorithms in parallel is even nicer, but I am not sure what a good API would be, and it is probably going to be a bit tricky to implement.

Here is some JS code of how I could imagine calling it:

const cutter = new ocl.CylCutter(4, 20)
const surface = new STLSurf()
// ... add triangles to surface here
ocl.runBatchOperations([
  {
    "type": "waterline",
    "surface": surface,
    "cutter": cutter,
    "z": 1,
     "sampling": 0.1",
     "cb": (loops) => { ... }
  },
  {
    "type": "adaptivewaterline",
    "surface": surface,
    "cutter": cutter,
    "z": 1,
     "sampling": 0.1",
     "minSampling": 0.001",
     "cb": (loops) => { ... }
  },
])

Anyways, would like to hear suggestions on how you think this can / should look. I will experiment with making such a function.

vespakoen commented 1 year ago

I have been playing around with this and came to some new conclusions:

Running waterline in parallel doesn't make much difference as running it serially, I tested it out over here and I think it even ran slower, it might be possible to improve this by tuning OpenMP, but I think the "gains" are minimal.

I agree that it would be nice to load the STL (into a KDTree) once, and then be able to run multiple operations on it, but that involves a big change to the current code, which perhaps isn't worth it.

You can actually re-use the STL with Waterline by using the wl.reset() method.

# throw this in a loop for the different z heights
wl.reset()
wl.setZ(height)
wl.run2()
loops = wl.getLoops()

In any case, it is a good idea to improve GIL handling in OCL, but this requires some work that is beyond my capabilities.

joemarshall commented 1 year ago

Is that because waterline is already using multiple threads internally, i.e. it is parallel enough already?

vespakoen commented 1 year ago

Yeah that seems to be the case indeed.