Schedule multiple IJobParticleSystem on multiple ParticleSystems with same data native datstructure

Hello Community,

am trying to perform IJobParticleSystem jobs on two different particle systems but with both instances of the IJobParticleSystem writing to the same data structure.
I do not mind if both instances are always executed one after another (obviously, since otherwise we had race conditions).
However I do not seem to be able to get rid of the error:

InvalidOperationException: The previously scheduled job AirpocketsManager:AbsorbInPocketsTask writes to the Unity.Collections.NativeList`1[System.Single] AbsorbInPocketsTask.airpockets_data. You are trying to schedule a new job AirpocketsManager:AbsorbInPocketsTask, which writes to the same Unity.Collections.NativeList`1[System.Single] (via AbsorbInPocketsTask.airpockets_data). To guarantee safety, you must include AirpocketsManager:AbsorbInPocketsTask as a dependency of the newly scheduled job.

My code looks as follows:
This is in an initialization function, called on a list of all particle systems (which are just two for testing):

        foreach (ParticleSystem system in all_systems)
        {
            AbsorbInPocketsTask task = new AbsorbInPocketsTask();
            task.native_array = the_same_native_array;
            airpockets_absorption_tasks.Add(system, task);
        }

And this is the main part of the class:

    Dictionary<ParticleSystem, JobHandle> airpockets_absorption_handles = new Dictionary<ParticleSystem, JobHandle>();
    Dictionary<ParticleSystem, AbsorbInPocketsTask> airpockets_absorption_tasks = new Dictionary<ParticleSystem, AbsorbInPocketsTask>();
    ParticleSystem last_system = null;

    public void StartJobForSystem(ParticleSystem system)
    {
        if (last_system == null) // to ensure the very first call is not called without an existing system
            airpockets_absorption_handles[system] = airpockets_absorption_tasks[system].Schedule(system);
        else
            airpockets_absorption_handles[system] = airpockets_absorption_tasks[system].Schedule(system, airpockets_absorption_handles[last_system]);
        last_system = system;

        //airpockets_absorption_handles[system].Complete();
    }

StartJobForSystem() is called from the OnParticleUpdateJobScheduled() function of the two particle systems.

For testing purposes I did use two Dictionaries to go absolutely sure that each ParticleSystem gets its own instance of the job and its own JobHandler.

Using the second parameter of Schedule I intend to enforce that the last (or more like “other”, since there are just two currently) Job has finished before the new one is started.

However this always gives the error above, unless that line is not outcommented which obviously makes the whole usage of the job system pointless.

Anyone happen to know what I am doing wrong?

Huge thanks in advance :slight_smile:

Is the second script instance shared between the 2 systems?

I ask because it is important that last_system is not null when the second system is scheduled, for your code to work.

Hard to say with just snippets of code… could be a bug in your code or ours :smile:

Thank you kindly for the answer!
Yes, it is a common instance where the game objects that contain the particle systems call the StartJobForSystem of.

What more could I provide? Would uploading a simplified sample project help?

Yes please, then I’ll take a look from this end, thanks!

During making the simplified project, I found out what the cause was…
Apparently you are not allowed to access the native array from within the OnParticleUpdateJobScheduled function.
Unfortunately I cut out the relevant snippet in my sample. It was about like this:

public void StartJobForSystem(ParticleSystem system) // called from OnParticleUpdateJobScheduled
    {
        for(int i = 0; i < common_data.Length; i++)
        {
            common_data[i] += 1;
            Debug.Log("Out from Schedule function: " + common_data[i]); // <-- Either of those two lines causes the errors.
            // Accessing the native data from OnParticleUpdateJobScheduled appears to not be allowed.
        }

        if (last_system == null) // to ensure the very first call is not called without an existing system
            handles[system] = jobs[system].Schedule(system); // For every bubbles particle system, schedule the tasks from every buffer
        else
            handles[system] = jobs[system].Schedule(system, handles[last_system]); // For every bubbles particle system, schedule the tasks from every buffer
        last_system = system;
    }

So right before scheduling, I do access the data (because it needs to influence something through the Unity Api on the main thread). Even just reading seems to cause this error.

The same access loop in the Update() function works flawlessly. So guess there are some performance optimizations in place that do not allow the OnParticleUpdateJobScheduled function to be safe for accessing the data?

Would be great if the error message could distinguish this case to give the actual reason :slight_smile:

Here the sample project with more clear names and comments (note I have cleared the package cache to not upload 750mb uselessly. So first start will be a little longer): Dropbox

Ah ok… i guess you accessed the native array after the first job using it was scheduled?

That would cause the error. Otherwise, accessing it before scheduling any jobs using it should be fine too.

Glad you figured it out!!