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

Agent ID generation (host and device) #199

Closed
ptheywood opened this issue Feb 26, 2020 · 4 comments · Fixed by #512
Closed

Agent ID generation (host and device) #199

ptheywood opened this issue Feb 26, 2020 · 4 comments · Fixed by #512
Assignees

Comments

@ptheywood
Copy link
Member

FLAME GPU 1 has methods to generate (probably) unique IDs for agents from the host or the device.

General process is:

  1. After any agents have been loaded from disk (i.e. already have Ids) the maximum id value is found and stored on the host and the device.
  2. host method to generate new IDs in init/step functions, which increments the host-value and sets a flag indicating that the device copy is out of date
  3. If the flag was set, copy the new value to the device before any kernels which generate new agents (or kernels in general?).
  4. Device function which generates new id (atomically). If this value has been updated it needs copying back to the host

It might be easeir to just use managed memory.

@ptheywood ptheywood added this to the FGPU1 Parity milestone Feb 26, 2020
@Robadob
Copy link
Member

Robadob commented Feb 26, 2020

Device function which generates new id (atomically). If this value has been updated it needs copying back to the host

Device agent creation can use the position flag at scatter time. That's a contiguous 0 index for all new agents, just requires the existing max index to add it to.

@ptheywood
Copy link
Member Author

ptheywood commented Mar 5, 2020

To avoid using atomics to generate new individual Ids, we could make the an automatic, compulsory feature.

  • When agents are read in from disk their Ids are auto populated (and explicitly not read in?)
  • When agents are created from the host, their Ids are auto generated, based on the maximum value which exists previously.
  • When agents are created on the device, their Ids are auto generated, probably in the scattering of the new agents once it is known how many there are.

This would be instead of explicit newAgentId() methods like in current flame.

Enforcing that agents have immutable, unique IDs might not be generally beneficial - to avoid self-messages and just prevent users from having to explcitly provide them (although some users may not want this)

Self message avoidance would not be automatic however, as it depends on the message being read by the same population which output the message, and some models do want self messaging. THe inclusion of the id in the message would likely not be compulsory.

This could be an optional feature, specified in the agent description.

To prevent users overwriting, access could be controlled through explicit methods rather than getVariable / set variable, but the type would need to be specified upfront. e.g. in an agent function

const unsigned int id = FLAMEGPU->agent.id()

or similar. the agent reduced ambiguity in my opinion compared to FLAMEGPU->id() which implies id of FLAME GPU rather than an agent. This also carries over to the current (s/g)etVariable functions which also exist for FLAMEGPU->environment. and message.

@ptheywood
Copy link
Member Author

After discussion with @mondus

Give all agents IDs automatically, but prevent users from over writing it.

Give a new method to get agent ids automatically, rather than letting users set and get this property like other agent variables.

@ptheywood ptheywood self-assigned this Mar 12, 2020
This was referenced Apr 24, 2020
@Robadob
Copy link
Member

Robadob commented Apr 13, 2021

Assuming #457 is merged, I will end up working on this next. So need to begin tying down a rough plan of action.
It appears there might be a bunch of Primage work coming down the line before the end of May, so it's possible that will delay any work on this.

Agent ID notes

  • Generated automatically (e.g. consecutive integers, albeit no guarantee of there not being gaps) per agent type (e.g. not state).
  • Read-only with dedicated method, e.g. getID()
  • Stored as internal agent variable with name _id
  • Agents birthed on device, will be assigned an ID instantly, allowing the parent of the birth'd agent to track it's child if necessary.
    • This can either be achieved by assigning based on thread index, or atomics. The prior would leave alot of IDs empty, the latter could be more costly.
  • Agents birthed on host receive an ID instantly, there are no special considerations here.
  • AgentVector::Agent and HostNewAgentAPI setVariable() and getVariable() will need updating to block access to variables with name beginning with _.

To Solve

  • How will agent ids behave within AgentVector
    • If a user creates two new AgentVectors to assign to different states of the same agent, their auto ids must not collide.
    • If a user exports, and imports and agents data to file, their ID musts be retained, throwing exception if they collide.
    • When build AgentVectors a user requires access to their IDs, incase they need to link agents.

Solution

  • When an Agent is created via an AgentVector it has no ID, this sits as some empty flag (e.g. 0 or UINT_MAX).
  • AgentVector::Agent will return an agent's id if it isn't the empty flag, otherwise it will throw an exception.
  • When CUDASimulation::setAgentPopulation() is called, any set agent ids are retained, uninitialised ones are left as the empty flag.
  • When CUDASimulation::simulate() is called, prior to init functions. Agent data is processed to detect currently assigned agent IDs. This is used to set an internal counter for next ID, and assign IDs to any unassigned agents.
  • Users can then perform any mapping between agents as part of an init function.
  • How should calling CUDASimulation::step() without triggering init functions behave?
  • How can users purge an agent's ID, e.g. if there's a conflict but they don't care as IDs don't matter to them?

@Robadob Robadob mentioned this issue Apr 13, 2021
28 tasks
Robadob added a commit that referenced this issue May 13, 2021
This is managed by FLAMEGPU and can be accessed with getID() in all places where getVariable is available.
IDs are assigned when a simulation begins, but can be exported and reimported to/from AgentVector/file.
Users cannot change or disable agent IDs.
id_t is the type of ID, is currently a typedef to unsigned int, but can be changed to uint64_t if desired.
If an id_t type agent/message/env variable is required in Python, newVariableID() or similar can be used.

Closes #199
Robadob added a commit that referenced this issue May 13, 2021
This is managed by FLAMEGPU and can be accessed with getID() in all places where getVariable is available.
IDs are assigned when a simulation begins, but can be exported and reimported to/from AgentVector/file.
Users cannot change or disable agent IDs.
id_t is the type of ID, is currently a typedef to unsigned int, but can be changed to uint64_t if desired.
If an id_t type agent/message/env variable is required in Python, newVariableID() or similar can be used.

Closes #199
Robadob added a commit that referenced this issue May 13, 2021
This is managed by FLAMEGPU and can be accessed with getID() in all places where getVariable is available.
IDs are assigned when a simulation begins, but can be exported and reimported to/from AgentVector/file.
Users cannot change or disable agent IDs.
id_t is the type of ID, is currently a typedef to unsigned int, but can be changed to uint64_t if desired.
If an id_t type agent/message/env variable is required in Python, newVariableID() or similar can be used.

Closes #199
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants