Skip to content

Commit

Permalink
BugFix: Swig did not support CUDASimulation::get/setEnvironmentProper…
Browse files Browse the repository at this point in the history
…ty() element version

Also unified API of all other array element methods to have optional 2nd length arg (C++ API).

Closes #912
  • Loading branch information
Robadob committed Aug 31, 2022
1 parent 731aaf2 commit 683ebc0
Show file tree
Hide file tree
Showing 9 changed files with 154 additions and 108 deletions.
18 changes: 14 additions & 4 deletions include/flamegpu/pop/AgentInstance.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ class AgentInstance {
T getVariable(const std::string& variable_name) const;
template <typename T, unsigned int N>
std::array<T, N> getVariable(const std::string& variable_name) const;
template <typename T>
template <typename T, unsigned int N = 0>
T getVariable(const std::string& variable_name, const unsigned int& index) const;
#ifdef SWIG
template <typename T>
Expand All @@ -68,7 +68,7 @@ class AgentInstance {
void setVariable(const std::string& variable_name, const T& value);
template <typename T, unsigned int N>
void setVariable(const std::string& variable_name, const std::array<T, N>& value);
template <typename T>
template <typename T, unsigned int N = 0>
void setVariable(const std::string& variable_name, const unsigned int& index, const T& value);
#ifdef SWIG
template <typename T>
Expand Down Expand Up @@ -127,7 +127,7 @@ std::array<T, N> AgentInstance::getVariable(const std::string& variable_name) co
memcpy(rtn.data(), v_buff.ptr, sizeof(T) * N);
return rtn;
}
template <typename T>
template <typename T, unsigned int N>
T AgentInstance::getVariable(const std::string& variable_name, const unsigned int& index) const {
const auto v_it = _data.find(variable_name);
if (v_it == _data.end()) {
Expand All @@ -136,6 +136,11 @@ T AgentInstance::getVariable(const std::string& variable_name, const unsigned in
variable_name.c_str());
}
const auto& v_buff = v_it->second;
if (N && N != v_buff.elements) {
THROW exception::OutOfBoundsException("Variable array '%s' length mismatch '%u' != '%u', "
"in AgentInstance::getVariable()\n",
variable_name.c_str(), N, v_buff.elements);
}
if (v_buff.elements % type_decode<T>::len_t != 0) {
THROW exception::InvalidVarType("Variable array length (%u) is not visible by vector length (%u), "
"in AgentInstance::getVariable().",
Expand Down Expand Up @@ -226,7 +231,7 @@ void AgentInstance::setVariable(const std::string& variable_name, const std::arr
}
memcpy(static_cast<T*>(v_buff.ptr), value.data(), sizeof(T) * N);
}
template <typename T>
template <typename T, unsigned int N>
void AgentInstance::setVariable(const std::string& variable_name, const unsigned int& index, const T& value) {
const auto v_it = _data.find(variable_name);
if (v_it == _data.end()) {
Expand All @@ -235,6 +240,11 @@ void AgentInstance::setVariable(const std::string& variable_name, const unsigned
variable_name.c_str());
}
auto& v_buff = v_it->second;
if (N && N != v_buff.elements) {
THROW exception::OutOfBoundsException("Variable array '%s' length mismatch '%u' != '%u', "
"in AgentInstance::setVariable()\n",
variable_name.c_str(), N, v_buff.elements);
}
if (v_buff.elements % type_decode<T>::len_t != 0) {
THROW exception::InvalidVarType("Variable array length (%u) is not visible by vector length (%u), "
"in AgentInstance::setVariable().",
Expand Down
20 changes: 15 additions & 5 deletions include/flamegpu/pop/AgentVector_Agent.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ class AgentVector_CAgent {
T getVariable(const std::string& variable_name) const;
template <typename T, unsigned int N>
std::array<T, N> getVariable(const std::string& variable_name) const;
template <typename T>
template <typename T, unsigned int N = 0>
T getVariable(const std::string& variable_name, const unsigned int& index) const;
#ifdef SWIG
template <typename T>
Expand Down Expand Up @@ -84,7 +84,7 @@ class AgentVector_Agent : public AgentVector_CAgent {
void setVariable(const std::string &variable_name, const T &value);
template <typename T, unsigned int N>
void setVariable(const std::string &variable_name, const std::array<T, N> &value);
template <typename T>
template <typename T, unsigned int N = 0>
void setVariable(const std::string &variable_name, const unsigned int &index, const T &value);
#ifdef SWIG
template <typename T>
Expand Down Expand Up @@ -205,7 +205,7 @@ void AgentVector_Agent::setVariable(const std::string &variable_name, const std:
// Notify (_data was locked above)
_parent->_changed(variable_name, index);
}
template <typename T>
template <typename T, unsigned int N>
void AgentVector_Agent::setVariable(const std::string &variable_name, const unsigned int &array_index, const T &value) {
if (!variable_name.empty() && variable_name[0] == '_') {
THROW exception::ReservedName("Agent variable names that begin with '_' are reserved for internal usage and cannot be changed directly, "
Expand All @@ -223,9 +223,14 @@ void AgentVector_Agent::setVariable(const std::string &variable_name, const unsi
variable_name.c_str());
}
auto& v_buff = v_it->second;
if (N && N != v_buff->getElements()) {
THROW exception::OutOfBoundsException("Variable array '%s' length mismatch '%u' != '%u', "
"in AgentVector_Agent::setVariable()\n",
variable_name.c_str(), N, v_buff->getElements());
}
if (v_buff->getElements() % type_decode<T>::len_t != 0) {
THROW exception::InvalidVarType("Variable array length (%u) is not divisible by vector type length (%u) for variable '%s', "
"in AgentVector_Agent::getVariable().",
"in AgentVector_Agent::setVariable().",
v_buff->getElements(), type_decode<T>::len_t, variable_name.c_str());
}
if (v_buff->getType() != std::type_index(typeid(typename type_decode<T>::type_t))) {
Expand Down Expand Up @@ -343,7 +348,7 @@ std::array<T, N> AgentVector_CAgent::getVariable(const std::string &variable_nam
memcpy(rtn.data(), static_cast<const T*>(v_buff->getReadOnlyDataPtr()) + (index * N), sizeof(T) * N);
return rtn;
}
template <typename T>
template <typename T, unsigned int N>
T AgentVector_CAgent::getVariable(const std::string &variable_name, const unsigned int &array_index) const {
const auto data = _data.lock();
if (!data) {
Expand All @@ -357,6 +362,11 @@ T AgentVector_CAgent::getVariable(const std::string &variable_name, const unsign
variable_name.c_str());
}
const auto& v_buff = v_it->second;
if (N && N != v_buff->getElements()) {
THROW exception::OutOfBoundsException("Variable array '%s' length mismatch '%u' != '%u', "
"in AgentVector_Agent::getVariable()\n",
variable_name.c_str(), N, v_buff->getElements());
}
if (v_buff->getElements() % type_decode<T>::len_t != 0) {
THROW exception::InvalidVarType("Variable array length (%u) is not divisible by vector type length (%u) for variable '%s', "
"in AgentVector_Agent::getVariable().",
Expand Down
110 changes: 57 additions & 53 deletions include/flamegpu/runtime/HostNewAgentAPI.h
Original file line number Diff line number Diff line change
Expand Up @@ -152,41 +152,42 @@ struct NewAgentStorage {
}
memcpy(data + var->second.offset, &val, var->second.len);
}
template<typename T, unsigned int N>
void setVariable(const std::string &var_name, const std::array<T, N> &val) {
template<typename T, unsigned int N = 0>
void setVariable(const std::string &var_name, const unsigned int &index, const T &val) {
const auto &var = offsets.vars.find(var_name);
if (var == offsets.vars.end()) {
THROW exception::InvalidAgentVar("Variable '%s' not found, "
"in NewAgentStorage::setVariable().",
var_name.c_str());
}
// if (var.second.len == 1 || N == 1) {
// THROW exception::InvalidAgentVar("Agent variable '%s' in not an array variable, "
// "in NewAgentStorage::setVariable().",
// var_name.c_str());
// }
if (N && N != var->second.len / sizeof(typename type_decode<T>::type_t)) {
THROW exception::InvalidAgentVar("Agent variable '%s' length mismatch %u != %u, "
"in NewAgentStorage::setVariable().",
var_name.c_str(), N, var->second.len / sizeof(typename type_decode<T>::type_t));
}
const auto t_type = std::type_index(typeid(typename type_decode<T>::type_t));
if (var->second.type != t_type) {
THROW exception::InvalidVarType("Variable '%s' has type '%s, incorrect type '%s' was requested, "
"in NewAgentStorage::setVariable().",
var_name.c_str(), var->second.type.name(), t_type.name());
}
if (var->second.len != sizeof(typename type_decode<T>::type_t) * type_decode<T>::len_t * N) {
THROW exception::InvalidVarArrayLen("Variable '%s' is an array with %u elements, incorrect array of length %u was provided, "
if (var->second.len < (sizeof(typename type_decode<T>::type_t) * type_decode<T>::len_t) * (index + 1)) {
THROW exception::OutOfRangeVarArray("Variable '%s' is an array with %u elements, index %u is out of range, "
"in NewAgentStorage::setVariable().",
var_name.c_str(), var->second.len / (sizeof(typename type_decode<T>::type_t) * type_decode<T>::len_t), N);
var_name.c_str(), var->second.len / (sizeof(typename type_decode<T>::type_t) * type_decode<T>::len_t), index);
}
memcpy(data + var->second.offset, val.data(), var->second.len);
memcpy(data + var->second.offset + (index * sizeof(typename type_decode<T>::type_t) * type_decode<T>::len_t), &val, sizeof(typename type_decode<T>::type_t) * type_decode<T>::len_t);
}
template<typename T>
void setVariable(const std::string &var_name, const unsigned int &index, const T &val) {
#ifndef SWIG
template<typename T, unsigned int N>
void setVariable(const std::string &var_name, const std::array<T, N> &val) {
const auto &var = offsets.vars.find(var_name);
if (var == offsets.vars.end()) {
THROW exception::InvalidAgentVar("Variable '%s' not found, "
"in NewAgentStorage::setVariable().",
var_name.c_str());
}
// if (var.second.len == 1) {
// if (var.second.len == 1 || N == 1) {
// THROW exception::InvalidAgentVar("Agent variable '%s' in not an array variable, "
// "in NewAgentStorage::setVariable().",
// var_name.c_str());
Expand All @@ -197,14 +198,14 @@ struct NewAgentStorage {
"in NewAgentStorage::setVariable().",
var_name.c_str(), var->second.type.name(), t_type.name());
}
if (var->second.len < (sizeof(typename type_decode<T>::type_t) * type_decode<T>::len_t) * (index + 1)) {
THROW exception::OutOfRangeVarArray("Variable '%s' is an array with %u elements, index %u is out of range, "
if (var->second.len != sizeof(typename type_decode<T>::type_t) * type_decode<T>::len_t * N) {
THROW exception::InvalidVarArrayLen("Variable '%s' is an array with %u elements, incorrect array of length %u was provided, "
"in NewAgentStorage::setVariable().",
var_name.c_str(), var->second.len / (sizeof(typename type_decode<T>::type_t) * type_decode<T>::len_t), index);
var_name.c_str(), var->second.len / (sizeof(typename type_decode<T>::type_t) * type_decode<T>::len_t), N);
}
memcpy(data + var->second.offset + (index * sizeof(typename type_decode<T>::type_t) * type_decode<T>::len_t), &val, sizeof(typename type_decode<T>::type_t) * type_decode<T>::len_t);
memcpy(data + var->second.offset, val.data(), var->second.len);
}
#ifdef SWIG
#else
template<typename T>
void setVariableArray(const std::string &var_name, const std::vector<T> &val) {
const auto &var = offsets.vars.find(var_name);
Expand Down Expand Up @@ -254,43 +255,42 @@ struct NewAgentStorage {
}
return *reinterpret_cast<T*>(data + var->second.offset);
}
template<typename T, unsigned int N>
std::array<T, N> getVariable(const std::string &var_name) {
template<typename T, unsigned int N = 0>
T getVariable(const std::string &var_name, const unsigned int &index) {
const auto &var = offsets.vars.find(var_name);
if (var == offsets.vars.end()) {
THROW exception::InvalidAgentVar("Variable '%s' not found, "
"in NewAgentStorage::getVariable().",
var_name.c_str());
}
// if (var.second.len == 1 || N == 1) {
// THROW exception::InvalidAgentVar("Agent variable '%s' in not an array variable, "
// "in NewAgentStorage::getVariable().",
// var_name.c_str());
// }
if (N && N != var->second.len / sizeof(typename type_decode<T>::type_t)) {
THROW exception::InvalidAgentVar("Agent variable '%s' length mismatch %u != %u, "
"in NewAgentStorage::getVariable().",
var_name.c_str(), N, var->second.len / sizeof(typename type_decode<T>::type_t));
}
const auto t_type = std::type_index(typeid(typename type_decode<T>::type_t));
if (var->second.type != t_type) {
THROW exception::InvalidVarType("Variable '%s' has type '%s, incorrect type '%s' was requested, "
"in NewAgentStorage::getVariable().",
var_name.c_str(), var->second.type.name(), t_type.name());
}
if (var->second.len != sizeof(typename type_decode<T>::type_t) * type_decode<T>::len_t * N) {
THROW exception::InvalidVarArrayLen("Variable '%s' is an array with %u elements, incorrect array of length %u was specified, "
if (var->second.len < sizeof(typename type_decode<T>::type_t) * type_decode<T>::len_t * (index + 1)) {
THROW exception::OutOfRangeVarArray("Variable '%s' is an array with %u elements, index %u is out of range, "
"in NewAgentStorage::getVariable().",
var_name.c_str(), var->second.len / (sizeof(typename type_decode<T>::type_t) * type_decode<T>::len_t), N);
var_name.c_str(), var->second.len / (sizeof(typename type_decode<T>::type_t) * type_decode<T>::len_t), index);
}
std::array<T, N> rtn;
memcpy(rtn.data(), data + var->second.offset, var->second.len);
return rtn;
return *reinterpret_cast<T*>(data + var->second.offset + (index * sizeof(typename type_decode<T>::type_t) * type_decode<T>::len_t));
}
template<typename T>
T getVariable(const std::string &var_name, const unsigned int &index) {
#ifndef SWIG
template<typename T, unsigned int N>
std::array<T, N> getVariable(const std::string &var_name) {
const auto &var = offsets.vars.find(var_name);
if (var == offsets.vars.end()) {
THROW exception::InvalidAgentVar("Variable '%s' not found, "
"in NewAgentStorage::getVariable().",
var_name.c_str());
}
// if (var.second.len == 1) {
// if (var.second.len == 1 || N == 1) {
// THROW exception::InvalidAgentVar("Agent variable '%s' in not an array variable, "
// "in NewAgentStorage::getVariable().",
// var_name.c_str());
Expand All @@ -301,14 +301,16 @@ struct NewAgentStorage {
"in NewAgentStorage::getVariable().",
var_name.c_str(), var->second.type.name(), t_type.name());
}
if (var->second.len < sizeof(typename type_decode<T>::type_t) * type_decode<T>::len_t * (index + 1)) {
THROW exception::OutOfRangeVarArray("Variable '%s' is an array with %u elements, index %u is out of range, "
if (var->second.len != sizeof(typename type_decode<T>::type_t) * type_decode<T>::len_t * N) {
THROW exception::InvalidVarArrayLen("Variable '%s' is an array with %u elements, incorrect array of length %u was specified, "
"in NewAgentStorage::getVariable().",
var_name.c_str(), var->second.len / (sizeof(typename type_decode<T>::type_t) * type_decode<T>::len_t), index);
var_name.c_str(), var->second.len / (sizeof(typename type_decode<T>::type_t) * type_decode<T>::len_t), N);
}
return *reinterpret_cast<T*>(data + var->second.offset + (index * sizeof(typename type_decode<T>::type_t) * type_decode<T>::len_t));
std::array<T, N> rtn;
memcpy(rtn.data(), data + var->second.offset, var->second.len);
return rtn;
}
#ifdef SWIG
#else
template<typename T>
std::vector<T> getVariableArray(const std::string &var_name) {
const auto &var = offsets.vars.find(var_name);
Expand Down Expand Up @@ -385,23 +387,24 @@ class HostNewAgentAPI {
}
s->setVariable<T>(var_name, val);
}
template<typename T, unsigned int N>
void setVariable(const std::string &var_name, const std::array<T, N> &val) {
template<typename T, unsigned int N = 0>
void setVariable(const std::string &var_name, const unsigned int &index, const T &val) {
if (!var_name.empty() && var_name[0] == '_') {
THROW exception::ReservedName("Agent variable names cannot begin with '_', this is reserved for internal usage, "
"in HostNewAgentAPI::setVariable().");
}
s->setVariable<T, N>(var_name, val);
s->setVariable<T, N>(var_name, index, val);
}
template<typename T>
void setVariable(const std::string &var_name, const unsigned int &index, const T &val) {
#ifndef SWIG
template<typename T, unsigned int N>
void setVariable(const std::string& var_name, const std::array<T, N>& val) {
if (!var_name.empty() && var_name[0] == '_') {
THROW exception::ReservedName("Agent variable names cannot begin with '_', this is reserved for internal usage, "
"in HostNewAgentAPI::setVariable().");
}
s->setVariable<T>(var_name, index, val);
s->setVariable<T, N>(var_name, val);
}
#ifdef SWIG
#else
template<typename T>
void setVariableArray(const std::string &var_name, const std::vector<T> &val) {
if (!var_name.empty() && var_name[0] == '_') {
Expand All @@ -418,15 +421,16 @@ class HostNewAgentAPI {
T getVariable(const std::string &var_name) const {
return s->getVariable<T>(var_name);
}
template<typename T, unsigned int N = 0>
T getVariable(const std::string &var_name, const unsigned int &index) {
return s->getVariable<T, N>(var_name, index);
}
#ifndef SWIG
template<typename T, unsigned int N>
std::array<T, N> getVariable(const std::string &var_name) {
std::array<T, N> getVariable(const std::string& var_name) {
return s->getVariable<T, N>(var_name);
}
template<typename T>
T getVariable(const std::string &var_name, const unsigned int &index) {
return s->getVariable<T>(var_name, index);
}
#ifdef SWIG
#else
template<typename T>
std::vector<T> getVariableArray(const std::string &var_name) {
return s->getVariableArray<T>(var_name);
Expand Down
Loading

0 comments on commit 683ebc0

Please sign in to comment.