Parallel for loop data tree Mesh | Ray intersection

I’ve been trying this script to speed up the Mesh | Ray component. Unfortunately, it randomly execute some branches twice, resulting in those branches having twice the number of outputs that I expect. I tried this method below as well as first creating a list and putting items to specific indecies, rather than just adding to an empty result list… but got the same results (not working).

  /*
        INPUTS
        M: Opaque mesh for collision (one item)
        P: Start Point of ray (multiple branches, one item each branch)
        D: Ray vector (multiple branches, multiple items in each branch)

   */

        DataTree <bool> resultTree = new DataTree<bool>();

        System.Threading.Tasks.Parallel.For(0, D.BranchCount, i => 
        {
          GH_Path pth = D.Paths[i];
          var vectorsList = D.Branch(i);
          var startPt = P.Branch(i);
          List<bool> resultList = new List<bool>();

          for (int j = 0; j < vectorsList.Count; j++) 
          {
            Rhino.Geometry.Ray3d ray = new Rhino.Geometry.Ray3d(startPt[0], vectorsList[j]);
            bool result = (Rhino.Geometry.Intersect.Intersection.MeshRay(M, ray)) >= 0;
            resultList.Add(result);
          }

          resultTree.AddRange(resultList, pth);
        });

      R = resultTree;

I’m not sure exactly what is wrong. Maybe I need to use a parallel foreach and make sure each output from the loop has a specific GH path and index before creating the resultTree, and/or use a dictionary?

Also… side point for this particular task… It seems very slow, even parallelized. Maybe someone could point me in the right direction for using the gpu or other ways for mesh raycasting to speed this up further? I’m calculating 2,000,000 intersections, more would be even better.

not an expert on this, but i think most types are not thread safe… you’ll need something like this:

The resultList variable in your example is a death sin in parallel loops. Always use arrays (= fixed length) for collecting results, because parallel-loops will not conflate indexes, therefore each “slot” in a fixed array is always “safe” (no risk for overwriting by another thread). Create the array before entering the parallel-loop.

Finally, copy the contents of the result-array to a result tree outside the parallel-loop.

// Rolf