Search code examples
repast-hpc

Issue with Synchronisation of Agents from different types in a shared discrete space projection


I have an issue regarding the synchronisation of different agents.

So I have a shared context with a BaseAgent class as the tutorial suggested for the case where we have more than 1 agent type in the same context. Then I have 4 more agent classes which are children of the Base Agent Class. For each of them I have the necessary serialisable agent packages and in my model class I also have specific package receivers and providers for each one of them.

All those agents are sharing a discrete spatial projection of the form:

repast::SharedDiscreteSpace<BaseAgentClass, repast::WrapAroundBorders, repast::SimpleAdder< BaseAgentClass > >* discreteSpace;

Three of my 4 agent types can move around and I have implemented their moves. However, they can move from one process to another and I need to use the 4 synchronisation statements which were introduced in the RepastHPC tutorial HPC:D03, Step 02: Agents Moving in Space.

The thing however is that I am not certain how to actually synchronise them, since the agents would need their specific providers, receivers and serialisable packages in order to be copied into the other process correctly. I tried doing the following:

discreteGridSpace->balance();
    
    repast::RepastProcess::instance()->synchronizeAgentStatus<BaseAgentClass, SpecificAgentPackage, SpecificAgentPackageProvider, SpecificAgentPackageReceiver>(context, *specificAgentProvider, *specificAgentProvider, *specificAgentReceiver);

    repast::RepastProcess::instance()->synchronizeProjectionInfo<BaseAgentClass, SpecificAgentPackage, SpecificAgentPackageProvider, SpecificAgentPackageReceiver>(context, *specificAgentProvider, *specificAgentProvider, *specificAgentReceiver);

    repast::RepastProcess::instance()->synchronizeAgentStates< SpecificAgentPackage, SpecificAgentPackageProvider, SpecificAgentPackageReceiver >(* specificAgentProvider, * specificAgentReceiver);

However, when running I get the following error:

===================================================================================
=   BAD TERMINATION OF ONE OF YOUR APPLICATION PROCESSES
=   PID 3224 RUNNING AT Aleksandars-MBP
=   EXIT CODE: 11
=   CLEANING UP REMAINING PROCESSES
=   YOU CAN IGNORE THE BELOW CLEANUP MESSAGES
===================================================================================
YOUR APPLICATION TERMINATED WITH THE EXIT STRING: Segmentation fault: 11 (signal 11)
This typically refers to a problem with your application.
Please see the FAQ page for debugging suggestions

So I am not certain how to actually synchronise the agents for each specific agent type, since they are all sharing the same context and spatial projection with the BaseAgentClass.

Thank you for the help in advance!


Solution

  • The intention here is that you'd have a single package that can be used for all the agent types. For example, in the Zombies demo model, the package has entries for the agent id components, and also infected and infectionTime. These last two only apply to the Human agents and not to the Zombies.

    The methods where you provide and receive content should check for the agent type and take the appropriate action. For example, in the Zombies Model we have

    void ZombieObserver::provideContent(RelogoAgent* agent, std::vector<AgentPackage>& out) {
        AgentId id = agent->getId();
        AgentPackage content = { id.id(), id.startingRank(), id.agentType(), id.currentRank(), 0, false };
        if (id.agentType() == humanType) {
            Human* human = static_cast<Human*> (agent);
            content.infected = human->infected();
            content.infectionTime = human->infectionTime();
        }
        out.push_back(content);
    }
    

    Here you can see we fill the AgentPackage with some defaults for infected and infectionTime and then update those if the agent is of the Human type. This is a ReLogo style model, so some of the details might be different but hopefully it's clear that there is a single package type that can handle all the agent types, and that you use the agent type to distinguish between types in your provide methods.