Search Unity

  1. Want to see 2020.1b in action? Sign up for our Beta 2020.1 Overview Webinar on April 20th for a live presentation from our evangelists and a Q&A session with guests from R&D.
    Dismiss Notice
  2. Interested in giving us feedback? Join our online research interviews on a broad range of topics and share your insights with us.
    Dismiss Notice
  3. We're hosting a webinar for the new Input System where you'll be able to get in touch with the devs. Sign up now and share your questions with us in preparation for the session on April 15.
    Dismiss Notice
  4. Dismiss Notice

How to pass Array/Lists to a IJobParallelFor job?

Discussion in 'Data Oriented Technology Stack' started by whiskers434, Dec 28, 2019.

  1. whiskers434

    whiskers434

    Joined:
    Sep 23, 2014
    Posts:
    22
    Hi,

    How does one correctly pass a list of lists to a parallel for job to be used by each parallel?

    Seeing as you can't have structs containing native collections or have 2d native collections or am i just missing something?

    Below is just a sample job to show my problem, trying to pass an array of structs containing an array to the parallel job, but if I do that i get some error about its not bitable or something

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using Unity.Collections;
    4. using Unity.Jobs;
    5. using UnityEngine;
    6.  
    7. public class TestJobScript : MonoBehaviour
    8. {
    9.     [System.Serializable]
    10.     struct JobValues
    11.     {
    12.         public int value;
    13.         public int other_value;
    14.         public NativeArray<MoreValues> more_values_array;
    15.     }
    16.  
    17.     [System.Serializable]
    18.     struct MoreValues
    19.     {
    20.         public int value;
    21.         public int other_value;
    22.  
    23.         public MoreValues(int value, int other_value)
    24.         {
    25.             this.value = value;
    26.             this.other_value = other_value;
    27.         }
    28.     }
    29.  
    30.     [System.Serializable]
    31.     struct JobResult
    32.     {
    33.         public int result;
    34.         public int other_result;
    35.  
    36.         public JobResult(int result, int other_result)
    37.         {
    38.             this.result = result;
    39.             this.other_result = other_result;
    40.         }
    41.     }
    42.  
    43.  
    44.     SampleParallelJob sample_job;
    45.     JobHandle job_handle;
    46.     NativeArray<JobValues> job_values;
    47.     NativeMultiHashMap<int, JobResult> job_results;
    48.  
    49.     void SampleJob()
    50.     {
    51.         //set up
    52.         job_values = new NativeArray<JobValues>(10, Allocator.TempJob);
    53.         job_results = new NativeMultiHashMap<int, JobResult>(10 * 10, Allocator.TempJob);
    54.  
    55.         //get the data
    56.         for (int i = 0; i < 10; i++)
    57.         {
    58.             var values = new JobValues();
    59.             values.value = 1;
    60.             values.other_value = 10;
    61.             values.more_values_array = new NativeArray<MoreValues>(10, Allocator.TempJob);
    62.  
    63.             for (int j = 0; j < 10; j++)
    64.             {
    65.                 values.more_values_array[j] = new MoreValues(1,2);
    66.             }
    67.  
    68.             job_values[i] = values;
    69.         }
    70.  
    71.         //create the job
    72.         sample_job = new SampleParallelJob();
    73.         sample_job.job_values = job_values;
    74.         sample_job.job_results = job_results.ToConcurrent();
    75.  
    76.         //start job
    77.         job_handle = sample_job.Schedule(job_values.Length, 1);
    78.  
    79.         //job complete
    80.         job_handle.Complete();
    81.  
    82.         //handle results
    83.         var results = job_results.GetValueArray(Allocator.Temp);
    84.         for (int i = 0; i < results.Length; i++)
    85.         {
    86.             var temp = results[i].result;
    87.             //process results etc...
    88.         }
    89.  
    90.         //clean up
    91.         results.Dispose();
    92.         job_values.Dispose();
    93.         job_results.Dispose();
    94.     }
    95.  
    96.     struct SampleParallelJob : IJobParallelFor
    97.     {
    98.         [ReadOnly]
    99.         public NativeArray<JobValues> job_values;
    100.  
    101.         [WriteOnly]
    102.         public NativeMultiHashMap<int, JobResult>.Concurrent job_results;
    103.  
    104.         public void Execute(int index)
    105.         {
    106.             var job_value = job_values[index];
    107.  
    108.             for (int i = 0; i < 10; i++)
    109.             {
    110.                 var result = job_value.more_values_array[i].other_value;
    111.                 var other_result = job_value.more_values_array[i].value;
    112.                 job_results.Add(index, new JobResult(result, other_result));
    113.  
    114.             }
    115.  
    116.             job_value.more_values_array.Dispose();
    117.         }
    118.     }
    119. }
    120.  
     
  2. Soaryn

    Soaryn

    Joined:
    Apr 17, 2015
    Posts:
    247
    To do a 2D array really just allocating an 1D array with the "area" of the 2D Array. So instead of having array[x][y] you'd have something like array[x+y*x] or something similar. You'd encode all of it into 1 dimension. It is non-ideal, but it is how most architectures work.

    You unfortunately, can not pass a NativeArray<NativeArray<int>> nor a NativeArray2D<int>; though you could probably create one as a helper using the NativeContainer structures as a guide.
     
    whiskers434 likes this.
  3. whiskers434

    whiskers434

    Joined:
    Sep 23, 2014
    Posts:
    22
    thank you, I have a workable solution now, its not perfect but it will do

    I am adding all my MoreValues (y's*) to a NativeList and storing the start_index and length in the JobValues struct, then in the job it loops through just the part of the list that is for that index

    Updated sample parallel job
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using Unity.Collections;
    4. using Unity.Jobs;
    5. using UnityEngine;
    6.  
    7. public class TestJobScript : MonoBehaviour
    8. {
    9.     [System.Serializable]
    10.     struct JobValues
    11.     {
    12.         public int value;
    13.         public int other_value;
    14.         public int more_values_array_start_index;
    15.         public int more_values_array_length;
    16.     }
    17.  
    18.     [System.Serializable]
    19.     struct MoreValues
    20.     {
    21.         public int value;
    22.         public int other_value;
    23.  
    24.         public MoreValues(int value, int other_value)
    25.         {
    26.             this.value = value;
    27.             this.other_value = other_value;
    28.         }
    29.     }
    30.  
    31.     [System.Serializable]
    32.     struct JobResult
    33.     {
    34.         public int result;
    35.         public int other_result;
    36.  
    37.         public JobResult(int result, int other_result)
    38.         {
    39.             this.result = result;
    40.             this.other_result = other_result;
    41.         }
    42.     }
    43.  
    44.     SampleParallelJob sample_job;
    45.     JobHandle job_handle;
    46.     NativeArray<JobValues> job_values;
    47.     NativeList<MoreValues> more_values;
    48.     NativeMultiHashMap<int, JobResult> job_results;
    49.  
    50.     void SampleJob()
    51.     {
    52.         //set up
    53.         job_values = new NativeArray<JobValues>(10, Allocator.TempJob);
    54.         job_results = new NativeMultiHashMap<int, JobResult>(10 * 10, Allocator.TempJob);
    55.         more_values = new NativeList<MoreValues>(Allocator.TempJob);
    56.  
    57.         //get the data
    58.         for (int i = 0; i < 10; i++)
    59.         {
    60.             var values = new JobValues();
    61.             values.value = 1;
    62.             values.other_value = 10;
    63.             values.more_values_array_start_index = i * 10;
    64.             values.more_values_array_length = 10;
    65.  
    66.             for (int j = 0; j < 10; j++)
    67.             {
    68.                 more_values.Add(new MoreValues(1,2));
    69.             }
    70.  
    71.             job_values[i] = values;
    72.         }
    73.  
    74.         //create the job
    75.         sample_job = new SampleParallelJob();
    76.         sample_job.job_values = job_values;
    77.         sample_job.more_values = more_values;
    78.         sample_job.job_results = job_results.ToConcurrent();
    79.  
    80.         //start job
    81.         job_handle = sample_job.Schedule(job_values.Length, 1);
    82.  
    83.         //job complete
    84.         job_handle.Complete();
    85.  
    86.         //handle results
    87.         var results = job_results.GetValueArray(Allocator.Temp);
    88.         for (int i = 0; i < results.Length; i++)
    89.         {
    90.             var temp = results[i].result;
    91.             //process results etc...
    92.         }
    93.  
    94.         //clean up
    95.         results.Dispose();
    96.         job_values.Dispose();
    97.         more_values.Dispose();
    98.         job_results.Dispose();
    99.     }
    100.  
    101.     struct SampleParallelJob : IJobParallelFor
    102.     {
    103.         [ReadOnly]
    104.         public NativeArray<JobValues> job_values;
    105.  
    106.         [ReadOnly]
    107.         public NativeList<MoreValues> more_values;
    108.  
    109.         [WriteOnly]
    110.         public NativeMultiHashMap<int, JobResult>.Concurrent job_results;
    111.  
    112.         public void Execute(int index)
    113.         {
    114.             var job_value = job_values[index];
    115.  
    116.             for (int i = job_value.more_values_array_start_index; i < job_value.more_values_array_start_index + job_value.more_values_array_length; i++)
    117.             {
    118.                 var result = more_values[i].other_value;
    119.                 var other_result = more_values[i].value;
    120.                 job_results.Add(index, new JobResult(result, other_result));
    121.             }
    122.         }
    123.     }
    124. }
    125.  
     
unityunity