Program Listing for File DeviceAgentVector_impl.h
↰ Return to documentation for file (include/flamegpu/runtime/agent/DeviceAgentVector_impl.h
)
#ifndef INCLUDE_FLAMEGPU_RUNTIME_AGENT_DEVICEAGENTVECTOR_IMPL_H_
#define INCLUDE_FLAMEGPU_RUNTIME_AGENT_DEVICEAGENTVECTOR_IMPL_H_
#include <string>
#include <utility>
#include <memory>
#include <list>
#include <map>
#include <set>
#include <vector>
#include "flamegpu/simulation/AgentVector.h"
#include "flamegpu/simulation/detail/CUDAFatAgentStateList.h" // VariableBuffer
namespace flamegpu {
namespace detail {
class CUDAScatter;
class CUDAAgent;
} // detail
struct VarOffsetStruct;
struct NewAgentStorage;
class DeviceAgentVector_impl : protected AgentVector {
public:
using AgentVector::Agent;
using AgentVector::CAgent;
DeviceAgentVector_impl(detail::CUDAAgent& _cuda_agent, const std::string& cuda_agent_state,
const VarOffsetStruct& _agentOffsets, std::vector<NewAgentStorage>& _newAgentData,
detail::CUDAScatter& scatter, unsigned int streamId, cudaStream_t stream);
// DeviceAgentVector_t(const DeviceAgentVector_t& other) = delete;
// DeviceAgentVector_t& operator=(const DeviceAgentVector_t& other) = delete;
void syncChanges();
void purgeCache();
using AgentVector::at;
using AgentVector::operator[];
using AgentVector::front;
using AgentVector::back;
// using AgentVector::data; // Would need to assume whole vector changed
using AgentVector::begin;
using AgentVector::end;
using AgentVector::cbegin;
using AgentVector::cend;
using AgentVector::rbegin;
using AgentVector::rend;
using AgentVector::crbegin;
using AgentVector::crend;
using AgentVector::empty;
using AgentVector::size;
using AgentVector::max_size;
using AgentVector::reserve;
using AgentVector::capacity;
using AgentVector::shrink_to_fit;
using AgentVector::clear;
using AgentVector::insert;
#ifdef SWIG
using AgentVector::py_insert;
#endif
using AgentVector::erase;
#ifdef SWIG
using AgentVector::py_erase;
#endif
using AgentVector::push_back;
using AgentVector::pop_back;
using AgentVector::resize;
// using AgentVector::swap; // This would essentially require replacing the entire on-device agent vector
protected:
void _insert(size_type pos, size_type count) override;
void _erase(size_type pos, size_type count) override;
void _changed(const std::string& variable_name, size_type pos) override;
void _changedAfter(const std::string& variable_name, size_type pos) override;
void _require(const std::string& variable_name) const override;
void _requireAll() const override;
void _requireLength() const override;
std::map<std::string, std::pair<size_type, size_type>> change_detail;
mutable std::set<std::string> invalid_variables;
bool unbound_buffers_has_changed;
private:
struct VariableBufferPair {
explicit VariableBufferPair(const std::shared_ptr<detail::VariableBuffer>& _device)
: device(_device) { }
VariableBufferPair(VariableBufferPair&& other) {
*this = std::move(other);
}
VariableBufferPair& operator=(VariableBufferPair&& other) {
std::swap(this->host, other.host);
std::swap(this->device, other.device);
return *this;
}
// @todo Solve this
// VariableBufferPair(const VariableBufferPair& other) = delete;
// VariableBufferPair& operator=(const VariableBufferPair& other) = delete;
~VariableBufferPair() {
if (host) free(host);
}
char* host = nullptr;
std::shared_ptr<detail::VariableBuffer> device;
};
std::list<VariableBufferPair> unbound_buffers;
unsigned int known_device_buffer_size = 0;
unsigned int unbound_host_buffer_size = 0;
unsigned int unbound_host_buffer_capacity = 0;
bool unbound_host_buffer_invalid = false;
void initUnboundBuffers();
void reinitUnboundBuffers();
void resizeUnboundBuffers(unsigned int new_capacity, bool init);
detail::CUDAAgent& cuda_agent;
std::string cuda_agent_state;
const VarOffsetStruct& agentOffsets;
std::vector<NewAgentStorage>& newAgentData;
detail::CUDAScatter& scatter;
const unsigned int streamId;
const cudaStream_t stream;
};
} // namespace flamegpu
#endif // INCLUDE_FLAMEGPU_RUNTIME_AGENT_DEVICEAGENTVECTOR_IMPL_H_