Skip to content

Commit

Permalink
Initial tests and fixes.
Browse files Browse the repository at this point in the history
  • Loading branch information
Robadob committed Sep 9, 2022
1 parent 7c94f5f commit e0848f9
Show file tree
Hide file tree
Showing 4 changed files with 209 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@ void EnvironmentDirectedGraph::Description::newVertexProperty(const std::string&
if (graph->vertexProperties.find(property_name) == graph->vertexProperties.end()) {
const std::array<typename type_decode<T>::type_t, type_decode<T>::len_t* N>* casted_default =
reinterpret_cast<const std::array<typename type_decode<T>::type_t, type_decode<T>::len_t* N>*>(&default_value);
graph->vertexProperties.emplace(property_name, property(*casted_default));
graph->vertexProperties.emplace(property_name, Variable(*casted_default));
return;
}
THROW exception::InvalidGraphProperty("Graph ('%s') already contains vertex property '%s', "
Expand All @@ -234,7 +234,7 @@ void EnvironmentDirectedGraph::Description::newEdgeProperty(const std::string& p
if (graph->edgeProperties.find(property_name) == graph->edgeProperties.end()) {
const std::array<typename type_decode<T>::type_t, type_decode<T>::len_t* N>* casted_default =
reinterpret_cast<const std::array<typename type_decode<T>::type_t, type_decode<T>::len_t* N>*>(&default_value);
graph->edgeProperties.emplace(property_name, property(*casted_default));
graph->edgeProperties.emplace(property_name, Variable(*casted_default));
return;
}
THROW exception::InvalidGraphProperty("Graph ('%s') already contains edge property '%s', "
Expand Down Expand Up @@ -262,7 +262,7 @@ void EnvironmentDirectedGraph::Description::newVertexPropertyArray(const std::st
if (default_value.size()) {
memcpy(temp.data(), default_value.data(), sizeof(typename type_decode<T>::type_t) * type_decode<T>::len_t * length);
}
graph->vertexProperties.emplace(property_name, property(type_decode<T>::len_t * length, temp));
graph->vertexProperties.emplace(property_name, Variable(type_decode<T>::len_t * length, temp));
return;
}
THROW exception::InvalidGraphProperty("Graph ('%s') already contains vertex property '%s', "
Expand All @@ -289,7 +289,7 @@ void EnvironmentDirectedGraph::Description::newEdgePropertyArray(const std::stri
if (default_value.size()) {
memcpy(temp.data(), default_value.data(), sizeof(typename type_decode<T>::type_t) * type_decode<T>::len_t * length);
}
graph->edgeProperties.emplace(property_name, property(type_decode<T>::len_t * length, temp));
graph->edgeProperties.emplace(property_name, Variable(type_decode<T>::len_t * length, temp));
return;
}
THROW exception::InvalidGraphProperty("Graph ('%s') already contains edge property '%s', "
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ void EnvironmentDirectedGraph::CUDABuffers::allocateVertexBuffers(const size_typ
THROW exception::UnknownInternalError("Device buffer already allocated, in EnvironmentDirectedGraph::CUDABuffers::allocateVertexBuffers()");
}
if (!vb.h_ptr) {
vb.h_ptr = malloc(vertex_count * v.second.type_size * v.second.elements);
vb.h_ptr = malloc(count * v.second.type_size * v.second.elements);
} else {
THROW exception::UnknownInternalError("Host buffer already allocated, in EnvironmentDirectedGraph::CUDABuffers::allocateVertexBuffers()");
}
Expand All @@ -65,7 +65,7 @@ void EnvironmentDirectedGraph::CUDABuffers::allocateEdgeBuffers(const size_type
THROW exception::UnknownInternalError("Device buffer already allocated, in EnvironmentDirectedGraph::CUDABuffers::allocateEdgeBuffers()");
}
if (!eb.h_ptr) {
eb.h_ptr = malloc(edge_count * e.second.type_size * e.second.elements);
eb.h_ptr = malloc(count * e.second.type_size * e.second.elements);
} else {
THROW exception::UnknownInternalError("Host buffer already allocated, in EnvironmentDirectedGraph::CUDABuffers::allocateEdgeBuffers()");
}
Expand Down Expand Up @@ -129,7 +129,7 @@ void EnvironmentDirectedGraph::CUDABuffers::setEdgeCount(const size_type count)
auto& eb = edge_buffers.at(e.first);
eb.device_ready = false;
// Possibly faster if we checked default_value == 0 and memset, but awkward with vague type and lack of template
for (unsigned int i = 0; i < vertex_count; ++i) {
for (unsigned int i = 0; i < edge_count; ++i) {
memcpy(static_cast<char*>(eb.h_ptr) + i * e.second.type_size * e.second.elements, e.second.default_value, e.second.type_size * e.second.elements);
}
}
Expand Down
1 change: 1 addition & 0 deletions tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ SET(TESTS_SRC
${CMAKE_CURRENT_SOURCE_DIR}/test_cases/runtime/test_device_api.cu
${CMAKE_CURRENT_SOURCE_DIR}/test_cases/runtime/test_device_environment.cu
${CMAKE_CURRENT_SOURCE_DIR}/test_cases/runtime/test_device_macro_property.cu
${CMAKE_CURRENT_SOURCE_DIR}/test_cases/runtime/test_environment_directed_graph.cu
${CMAKE_CURRENT_SOURCE_DIR}/test_cases/runtime/test_environment_manager.cu
${CMAKE_CURRENT_SOURCE_DIR}/test_cases/runtime/test_host_api.cu
${CMAKE_CURRENT_SOURCE_DIR}/test_cases/runtime/test_host_agent_sort.cu
Expand Down
201 changes: 201 additions & 0 deletions tests/test_cases/runtime/test_environment_directed_graph.cu
Original file line number Diff line number Diff line change
@@ -0,0 +1,201 @@
/**
* Tests of: Environment Directed Graph functionality
* This combines testing of all features as they are quite tightly linked
*
* Tests cover:
* > Host set/get
* > Host get default
* > Device get
* > Device get default
* > Host validation (todo)
* > Device validation (todo)
*/

#include "flamegpu/flamegpu.h"
#include "flamegpu/runtime/environment/EnvironmentDirectedGraph/EnvironmentDirectedGraphDescription.cuh"

#include "gtest/gtest.h"

namespace flamegpu {
const unsigned int EDGE_COUNT = 10;
const unsigned int VERTEX_COUNT = 10;
FLAMEGPU_HOST_FUNCTION(hostfn_HostSetGet_Edge) {
auto graph = FLAMEGPU->environment.getDirectedGraph("graph");
graph.setEdgeCount(EDGE_COUNT);
// Check default matches
for (unsigned int i = 0; i < EDGE_COUNT; ++i) {
EXPECT_EQ(graph.getEdgeProperty<float>("edge", i), 12.0f);
}
// Set all values
for (unsigned int i = 0; i < EDGE_COUNT; ++i) {
graph.setEdgeProperty<float>("edge", i, 14.0f + i);
}
// Check set values match
for (unsigned int i = 0; i < EDGE_COUNT; ++i) {
EXPECT_EQ(graph.getEdgeProperty<float>("edge", i), 14.0f + i);
}
graph.setEdgeCount(EDGE_COUNT * 2);
// Check default matches
for (unsigned int i = 0; i < EDGE_COUNT * 2; ++i) {
EXPECT_EQ(graph.getEdgeProperty<float>("edge", i), 12.0f);
}
}
TEST(EnvironmentDirectedGraphTest, HostSetGet_Edge) {
ModelDescription model("test");
model.newAgent("agent");
auto &graph = model.Environment().newDirectedGraph("graph");
graph.newEdgeProperty<float>("edge", 12.0f);
model.newLayer().addHostFunction(hostfn_HostSetGet_Edge);
}

FLAMEGPU_HOST_FUNCTION(hostfn_HostSetGet_Vertex) {
auto graph = FLAMEGPU->environment.getDirectedGraph("graph");
graph.setVertexCount(VERTEX_COUNT);
// Check default matches
for (unsigned int i = 0; i < VERTEX_COUNT; ++i) {
EXPECT_EQ(graph.getVertexProperty<int>("vertex", i), 12.0f);
}
// Set all values
for (unsigned int i = 0; i < VERTEX_COUNT; ++i) {
graph.setVertexProperty<int>("vertex", i, 14 + static_cast<int>(i));
}
// Check set values match
for (unsigned int i = 0; i < VERTEX_COUNT; ++i) {
EXPECT_EQ(graph.getVertexProperty<int>("vertex", i), 14.0f + i);
}
graph.setVertexCount(VERTEX_COUNT * 2);
// Check default matches
for (unsigned int i = 0; i < VERTEX_COUNT * 2; ++i) {
EXPECT_EQ(graph.getVertexProperty<int>("vertex", i), 12.0f);
}
}
TEST(EnvironmentDirectedGraphTest, HostSetGet_Vertex) {
ModelDescription model("test");
model.newAgent("agent");
auto& graph = model.Environment().newDirectedGraph("graph");
graph.newVertexProperty<int>("vertex", 5);
model.newLayer().addHostFunction(hostfn_HostSetGet_Edge);
}
FLAMEGPU_HOST_FUNCTION(hostfn_DeviceGet_Edge) {
auto graph = FLAMEGPU->environment.getDirectedGraph("graph");
graph.setEdgeCount(EDGE_COUNT);
// Set all values
for (unsigned int i = 0; i < EDGE_COUNT; ++i) {
graph.setEdgeProperty<float>("edge", i, 14.0f + i);
}
}
FLAMEGPU_AGENT_FUNCTION(DeviceGet_Edge, MessageNone, MessageNone) {
auto graph = FLAMEGPU->environment.getDirectedGraph("graph");
const float t = graph.getEdgeProperty<float>("edge", FLAMEGPU->getThreadIndex());
FLAMEGPU->setVariable<unsigned int>("tid", FLAMEGPU->getThreadIndex());
FLAMEGPU->setVariable<float>("edge_value", t);
return flamegpu::ALIVE;
}
TEST(EnvironmentDirectedGraphTest, DeviceGet_Edge) {
ModelDescription model("test");
auto &agent = model.newAgent("agent");
agent.newVariable<float>("edge_value", 0.0f);
agent.newVariable<unsigned int>("tid", 0);
agent.newFunction("DeviceGet_Edge", DeviceGet_Edge);
auto& graph = model.Environment().newDirectedGraph("graph");
graph.newEdgeProperty<float>("edge", 12.0f);
model.newLayer().addHostFunction(hostfn_DeviceGet_Edge);
model.newLayer().addAgentFunction(DeviceGet_Edge);

CUDASimulation sim(model);
AgentVector pop(agent, EDGE_COUNT);
sim.setPopulationData(pop);
sim.step();
sim.getPopulationData(pop);
// Check result matches
for (const auto &p : pop) {
EXPECT_EQ(p.getVariable<float>("edge_value"), 14.0f + p.getVariable<unsigned int>("tid"));
}
}
FLAMEGPU_HOST_FUNCTION(hostfn_DeviceGetDefault_Edge) {
auto graph = FLAMEGPU->environment.getDirectedGraph("graph");
graph.setEdgeCount(EDGE_COUNT);
}
TEST(EnvironmentDirectedGraphTest, DeviceGetDefault_Edge) {
ModelDescription model("test");
auto& agent = model.newAgent("agent");
agent.newVariable<float>("edge_value", 0.0f);
agent.newVariable<unsigned int>("tid", 0);
agent.newFunction("DeviceGet_Edge", DeviceGet_Edge);
auto& graph = model.Environment().newDirectedGraph("graph");
graph.newEdgeProperty<float>("edge", 12.0f);
model.newLayer().addHostFunction(hostfn_DeviceGetDefault_Edge);
model.newLayer().addAgentFunction(DeviceGet_Edge);

CUDASimulation sim(model);
AgentVector pop(agent, EDGE_COUNT);
sim.setPopulationData(pop);
sim.step();
sim.getPopulationData(pop);
// Check result matches
for (const auto& p : pop) {
EXPECT_EQ(p.getVariable<float>("edge_value"), 12.0f);
}
}
FLAMEGPU_HOST_FUNCTION(hostfn_DeviceGet_Vertex) {
auto graph = FLAMEGPU->environment.getDirectedGraph("graph");
graph.setVertexCount(VERTEX_COUNT);
// Set all values
for (unsigned int i = 0; i < VERTEX_COUNT; ++i) {
graph.setVertexProperty<int>("vertex", i, 14 + static_cast<int>(i));
}
}
FLAMEGPU_AGENT_FUNCTION(DeviceGet_Vertex, MessageNone, MessageNone) {
auto graph = FLAMEGPU->environment.getDirectedGraph("graph");
const float t = graph.getVertexProperty<int>("vertex", FLAMEGPU->getThreadIndex());
FLAMEGPU->setVariable<unsigned int>("tid", FLAMEGPU->getThreadIndex());
FLAMEGPU->setVariable<int>("vertex_value", t);
return flamegpu::ALIVE;
}
TEST(EnvironmentDirectedGraphTest, DeviceGet_Vertex) {
ModelDescription model("test");
auto& agent = model.newAgent("agent");
agent.newVariable<int>("vertex_value", 0u);
agent.newVariable<unsigned int>("tid", 0);
agent.newFunction("DeviceGet_Vertex", DeviceGet_Vertex);
auto& graph = model.Environment().newDirectedGraph("graph");
graph.newVertexProperty<int>("vertex", 12);
model.newLayer().addHostFunction(hostfn_DeviceGet_Vertex);
model.newLayer().addAgentFunction(DeviceGet_Vertex);

CUDASimulation sim(model);
AgentVector pop(agent, VERTEX_COUNT);
sim.setPopulationData(pop);
sim.step();
sim.getPopulationData(pop);
// Check result matches
for (const auto& p : pop) {
EXPECT_EQ(p.getVariable<int>("vertex_value"), 14 + static_cast<int>(p.getVariable<unsigned int>("tid")));
}
}
FLAMEGPU_HOST_FUNCTION(hostfn_DeviceGetDefault_Vertex) {
auto graph = FLAMEGPU->environment.getDirectedGraph("graph");
graph.setVertexCount(VERTEX_COUNT);
}
TEST(EnvironmentDirectedGraphTest, DeviceGetDefault_Vertex) {
ModelDescription model("test");
auto& agent = model.newAgent("agent");
agent.newVariable<int>("vertex_value", 0u);
agent.newVariable<unsigned int>("tid", 0);
agent.newFunction("DeviceGet_Vertex", DeviceGet_Vertex);
auto& graph = model.Environment().newDirectedGraph("graph");
graph.newVertexProperty<int>("vertex", 12);
model.newLayer().addHostFunction(hostfn_DeviceGetDefault_Vertex);
model.newLayer().addAgentFunction(DeviceGet_Vertex);

CUDASimulation sim(model);
AgentVector pop(agent, VERTEX_COUNT);
sim.setPopulationData(pop);
sim.step();
sim.getPopulationData(pop);
// Check result matches
for (const auto& p : pop) {
EXPECT_EQ(p.getVariable<int>("vertex_value"), 12);
}
}
} // namespace flamegpu

0 comments on commit e0848f9

Please sign in to comment.