Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tensor TriangleMesh.from_legacy() using python multiprocessing gets stuck in waiting. #4923

Closed
3 tasks done
dalnoguer opened this issue Mar 25, 2022 · 11 comments
Closed
3 tasks done
Labels
bug Not a build issue, this is likely a bug.

Comments

@dalnoguer
Copy link

dalnoguer commented Mar 25, 2022

Checklist

Describe the issue

Hello everyone,

I am trying to speed up the raycasting scene by using python multiprocessing.

Loading the mesh in legacy format is fine, but when I try to convert the mesh to tensor format it gets stuck in waiting.

Steps to reproduce the bug

python
import open3d as o3d

def load_meshes(num):
    mesh_path = "..."
    obj_mesh = o3d.io.read_triangle_mesh(mesh_path))
    obj_mesh = o3d.t.geometry.TriangleMesh.from_legacy(obj_mesh)

parallel_jobs = 3
pool = multiprocessing.Pool(parallel_jobs)
list = [1, 2, 3]
pool.map(load_meshes, list)

Error message

It gets stuck, no error message.
When I terminate the program I get this:

^CTraceback (most recent call last):
  File "oa_datasets/modules/segmentation_mask_generation/segmentation_mask_projector.py", line 219, in <module>
    pool.map(load_meshes, list)
  File "/home/dnoguer/miniconda3/envs/oa_datasets/lib/python3.7/multiprocessing/pool.py", line 268, in map
    return self._map_async(func, iterable, mapstar, chunksize).get()
  File "/home/dnoguer/miniconda3/envs/oa_datasets/lib/python3.7/multiprocessing/pool.py", line 651, in get
    self.wait(timeout)
  File "/home/dnoguer/miniconda3/envs/oa_datasets/lib/python3.7/multiprocessing/pool.py", line 648, in wait
    self._event.wait(timeout)
  File "/home/dnoguer/miniconda3/envs/oa_datasets/lib/python3.7/threading.py", line 552, in wait
    signaled = self._cond.wait(timeout)
  File "/home/dnoguer/miniconda3/envs/oa_datasets/lib/python3.7/threading.py", line 296, in wait
    waiter.acquire()
KeyboardInterrupt

Expected behavior

I would expect to run in parallel, since the mesh is around 70MB and there is plenty of memory.

Open3D, Python and System information

- Operating system: Ubuntu 20.04
- Python version: Python 3.7.11
- Open3D version: 0.14.1
- System architecture: x86
- Is this a remote workstation?: yes
- How did you install Open3D?: pip
@dalnoguer dalnoguer added the bug Not a build issue, this is likely a bug. label Mar 25, 2022
@jordanott
Copy link

Any update on this?

@benjaminum
Copy link
Contributor

How is the example related to raycasting?

@jordanott
Copy link

The call to o3d.t.geometry.TriangleMesh.from_legacy is needed in order to create a RaycastingScene later on. However, the bug occurs on that line, so we never make it to create the scene. This would be a more complete example based on the raycasting tutorial

import multiprocessing
import open3d as o3d

def ray_cast(i):
    # Load mesh and convert to open3d.t.geometry.TriangleMesh
    cube = o3d.geometry.TriangleMesh.create_box().translate([0, 0, 0])
    cube = o3d.t.geometry.TriangleMesh.from_legacy(cube)

    # Create a scene and add the triangle mesh
    scene = o3d.t.geometry.RaycastingScene()
    cube_id = scene.add_triangles(cube)

    # The first ray starts at (0.5,0.5,10) and has direction (0,0,-1).
    # The second ray start at (-1,-1,-1) and has direction (0,0,-1).
    rays = o3d.core.Tensor([
        [0.5, 0.5, 10, 0, 0, -1], 
        [-1, -1, -1, 0, 0, -1]
    ], dtype=o3d.core.Dtype.Float32)

    ans = scene.cast_rays(rays)
    print(ans)

# Serial ray cast
ray_cast(0)

parallel_jobs = 3
pool = multiprocessing.Pool(parallel_jobs)
list = [1, 2, 3]
pool.map(ray_cast, list)

@benjaminum benjaminum changed the title Raycasting using python multiprocessing gets stuck in waiting. Tensor TriangleMesh.from_legacy() using python multiprocessing gets stuck in waiting. Jun 23, 2022
@benjaminum
Copy link
Contributor

OK, so the problem it is not related to RaycastingScene. I changed the title to reflect this.

Can you reproduce the problem without reading data by creating meshes for example with TriangleMesh.create_sphere()?

@jordanott
Copy link

I think this should be the same as the example I posted previously, just creating a sphere instead of a box. Same issue though:

import multiprocessing
import open3d as o3d

def create_triangle_mesh_from_legacy(i):
    sphere = o3d.geometry.TriangleMesh.create_sphere()
    print("Sphere created")

    sphere = o3d.t.geometry.TriangleMesh.from_legacy(sphere)
    print("Sphere converted to TriangleMesh from legacy")

# Serial
create_triangle_mesh_from_legacy(0)

parallel_jobs = 3
pool = multiprocessing.Pool(parallel_jobs)
pool.map(create_triangle_mesh_from_legacy, [1, 2, 3])

@benjaminum
Copy link
Contributor

You need to create the processes in __main__

import multiprocessing
import open3d as o3d

def create_triangle_mesh_from_legacy(i):
    sphere = o3d.geometry.TriangleMesh.create_sphere()
    print("Sphere created")

    sphere = o3d.t.geometry.TriangleMesh.from_legacy(sphere)
    print("Sphere converted to TriangleMesh from legacy")

if __name__ == '__main__':
    parallel_jobs = 3
    pool = multiprocessing.Pool(parallel_jobs)
    pool.map(create_triangle_mesh_from_legacy, [1, 2, 3])

@jordanott
Copy link

That doesn't change anything for me, does that work for you?
I'm still seeing "Sphere created" three times, then it just hangs

@benjaminum
Copy link
Contributor

Can you try to add

...
if __name__ == '__main__':
    multiprocessing.set_start_method('spawn') # or 'forkserver'
...

@benjaminum
Copy link
Contributor

@jordanott Did changing the start method fix the problem for you?

@jordanott
Copy link

Yes, changing the start method fixes the waiting issue.
However, I'm still not seeing the hoped for speed up from using multiprocessing. Any suggestions?

@benjaminum
Copy link
Contributor

The raycasting itself is multithreaded. If you have many rays then probably there is not much benefit of processing meshes in parallel.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Not a build issue, this is likely a bug.
Projects
None yet
Development

No branches or pull requests

3 participants