.. _program_listing_file_src_flamegpu_io_JSONGraphWriter.cpp: Program Listing for File JSONGraphWriter.cpp ============================================ |exhale_lsh| :ref:`Return to documentation for file ` (``src/flamegpu/io/JSONGraphWriter.cpp``) .. |exhale_lsh| unicode:: U+021B0 .. UPWARDS ARROW WITH TIP LEFTWARDS .. code-block:: cpp #include "flamegpu/io/JSONGraphWriter.h" #include #include #include #include #include #include #include "flamegpu/exception/FLAMEGPUException.h" #include "flamegpu/simulation/detail/CUDAEnvironmentDirectedGraphBuffers.cuh" namespace flamegpu { namespace io { namespace { void writeAnyVertex(nlohmann::ordered_json& j, const std::pair &var, const unsigned int index, const std::shared_ptr& directed_graph, cudaStream_t stream) { size_type foo = 0; // Output value if (var.second.elements == 1) { if (var.second.type == std::type_index(typeid(float))) { j = directed_graph->getVertexPropertyBuffer(var.first, foo, stream)[var.second.elements * index]; } else if (var.second.type == std::type_index(typeid(double))) { j = directed_graph->getVertexPropertyBuffer(var.first, foo, stream)[var.second.elements * index]; } else if (var.second.type == std::type_index(typeid(int64_t))) { j = directed_graph->getVertexPropertyBuffer(var.first, foo, stream)[var.second.elements * index]; } else if (var.second.type == std::type_index(typeid(uint64_t))) { j = directed_graph->getVertexPropertyBuffer(var.first, foo, stream)[var.second.elements * index]; } else if (var.second.type == std::type_index(typeid(int32_t))) { j = directed_graph->getVertexPropertyBuffer(var.first, foo, stream)[var.second.elements * index]; } else if (var.second.type == std::type_index(typeid(uint32_t))) { j = directed_graph->getVertexPropertyBuffer(var.first, foo, stream)[var.second.elements * index]; } else if (var.second.type == std::type_index(typeid(int16_t))) { j = directed_graph->getVertexPropertyBuffer(var.first, foo, stream)[var.second.elements * index]; } else if (var.second.type == std::type_index(typeid(uint16_t))) { j = directed_graph->getVertexPropertyBuffer(var.first, foo, stream)[var.second.elements * index]; } else if (var.second.type == std::type_index(typeid(int8_t))) { j = static_cast(directed_graph->getVertexPropertyBuffer(var.first, foo, stream)[var.second.elements * index]); // Char outputs weird if being used as an integer } else if (var.second.type == std::type_index(typeid(uint8_t))) { j = static_cast(directed_graph->getVertexPropertyBuffer(var.first, foo, stream)[var.second.elements * index]); // Char outputs weird if being used as an integer } else if (var.second.type == std::type_index(typeid(char))) { j = static_cast(directed_graph->getVertexPropertyBuffer(var.first, foo, stream)[var.second.elements * index]); // Char outputs weird if being used as an integer } else { THROW exception::JSONError("Attempting to export value of unsupported type '%s', " "in JsonGraphWriter::writeAny()\n", var.second.type.name()); } return; } // Loop through elements, to construct array j = {}; for (unsigned int el = 0; el < var.second.elements; ++el) { if (var.second.type == std::type_index(typeid(float))) { j.push_back(directed_graph->getVertexPropertyBuffer(var.first, foo, stream)[var.second.elements * index + el]); } else if (var.second.type == std::type_index(typeid(double))) { j.push_back(directed_graph->getVertexPropertyBuffer(var.first, foo, stream)[var.second.elements * index + el]); } else if (var.second.type == std::type_index(typeid(int64_t))) { j.push_back(directed_graph->getVertexPropertyBuffer(var.first, foo, stream)[var.second.elements * index + el]); } else if (var.second.type == std::type_index(typeid(uint64_t))) { j.push_back(directed_graph->getVertexPropertyBuffer(var.first, foo, stream)[var.second.elements * index + el]); } else if (var.second.type == std::type_index(typeid(int32_t))) { j.push_back(directed_graph->getVertexPropertyBuffer(var.first, foo, stream)[var.second.elements * index + el]); } else if (var.second.type == std::type_index(typeid(uint32_t))) { j.push_back(directed_graph->getVertexPropertyBuffer(var.first, foo, stream)[var.second.elements * index + el]); } else if (var.second.type == std::type_index(typeid(int16_t))) { j.push_back(directed_graph->getVertexPropertyBuffer(var.first, foo, stream)[var.second.elements * index + el]); } else if (var.second.type == std::type_index(typeid(uint16_t))) { j.push_back(directed_graph->getVertexPropertyBuffer(var.first, foo, stream)[var.second.elements * index + el]); } else if (var.second.type == std::type_index(typeid(int8_t))) { j.push_back(static_cast(directed_graph->getVertexPropertyBuffer(var.first, foo, stream)[var.second.elements * index + el])); // Char outputs weird if being used as an integer } else if (var.second.type == std::type_index(typeid(uint8_t))) { j.push_back(static_cast(directed_graph->getVertexPropertyBuffer(var.first, foo, stream)[var.second.elements * index + el])); // Char outputs weird if being used as an integer } else if (var.second.type == std::type_index(typeid(char))) { j.push_back(static_cast(directed_graph->getVertexPropertyBuffer(var.first, foo, stream)[var.second.elements * index + el])); // Char outputs weird if being used as an integer } else { THROW exception::JSONError("Attempting to export value of unsupported type '%s', " "in JsonGraphWriter::writeAny()\n", var.second.type.name()); } } } void writeAnyEdge(nlohmann::ordered_json& j, const std::pair &var, const unsigned int index, const std::shared_ptr& directed_graph, cudaStream_t stream) { size_type foo = 0; // Output value if (var.second.elements == 1) { if (var.second.type == std::type_index(typeid(float))) { j = directed_graph->getEdgePropertyBuffer(var.first, foo, stream)[var.second.elements * index]; } else if (var.second.type == std::type_index(typeid(double))) { j = directed_graph->getEdgePropertyBuffer(var.first, foo, stream)[var.second.elements * index]; } else if (var.second.type == std::type_index(typeid(int64_t))) { j = directed_graph->getEdgePropertyBuffer(var.first, foo, stream)[var.second.elements * index]; } else if (var.second.type == std::type_index(typeid(uint64_t))) { j = directed_graph->getEdgePropertyBuffer(var.first, foo, stream)[var.second.elements * index]; } else if (var.second.type == std::type_index(typeid(int32_t))) { j = directed_graph->getEdgePropertyBuffer(var.first, foo, stream)[var.second.elements * index]; } else if (var.second.type == std::type_index(typeid(uint32_t))) { j = directed_graph->getEdgePropertyBuffer(var.first, foo, stream)[var.second.elements * index]; } else if (var.second.type == std::type_index(typeid(int16_t))) { j = directed_graph->getEdgePropertyBuffer(var.first, foo, stream)[var.second.elements * index]; } else if (var.second.type == std::type_index(typeid(uint16_t))) { j = directed_graph->getEdgePropertyBuffer(var.first, foo, stream)[var.second.elements * index]; } else if (var.second.type == std::type_index(typeid(int8_t))) { j = static_cast(directed_graph->getEdgePropertyBuffer(var.first, foo, stream)[var.second.elements * index]); // Char outputs weird if being used as an integer } else if (var.second.type == std::type_index(typeid(uint8_t))) { j = static_cast(directed_graph->getEdgePropertyBuffer(var.first, foo, stream)[var.second.elements * index]); // Char outputs weird if being used as an integer } else if (var.second.type == std::type_index(typeid(char))) { j = static_cast(directed_graph->getEdgePropertyBuffer(var.first, foo, stream)[var.second.elements * index]); // Char outputs weird if being used as an integer } else { THROW exception::JSONError("Attempting to export value of unsupported type '%s', " "in JsonGraphWriter::writeAny()\n", var.second.type.name()); } return; } // Loop through elements, to construct array j = {}; for (unsigned int el = 0; el < var.second.elements; ++el) { if (var.second.type == std::type_index(typeid(float))) { j.push_back(directed_graph->getEdgePropertyBuffer(var.first, foo, stream)[var.second.elements * index + el]); } else if (var.second.type == std::type_index(typeid(double))) { j.push_back(directed_graph->getEdgePropertyBuffer(var.first, foo, stream)[var.second.elements * index + el]); } else if (var.second.type == std::type_index(typeid(int64_t))) { j.push_back(directed_graph->getEdgePropertyBuffer(var.first, foo, stream)[var.second.elements * index + el]); } else if (var.second.type == std::type_index(typeid(uint64_t))) { j.push_back(directed_graph->getEdgePropertyBuffer(var.first, foo, stream)[var.second.elements * index + el]); } else if (var.second.type == std::type_index(typeid(int32_t))) { j.push_back(directed_graph->getEdgePropertyBuffer(var.first, foo, stream)[var.second.elements * index + el]); } else if (var.second.type == std::type_index(typeid(uint32_t))) { j.push_back(directed_graph->getEdgePropertyBuffer(var.first, foo, stream)[var.second.elements * index + el]); } else if (var.second.type == std::type_index(typeid(int16_t))) { j.push_back(directed_graph->getEdgePropertyBuffer(var.first, foo, stream)[var.second.elements * index + el]); } else if (var.second.type == std::type_index(typeid(uint16_t))) { j.push_back(directed_graph->getEdgePropertyBuffer(var.first, foo, stream)[var.second.elements * index + el]); } else if (var.second.type == std::type_index(typeid(int8_t))) { j.push_back(static_cast(directed_graph->getEdgePropertyBuffer(var.first, foo, stream)[var.second.elements * index + el])); // Char outputs weird if being used as an integer } else if (var.second.type == std::type_index(typeid(uint8_t))) { j.push_back(static_cast(directed_graph->getEdgePropertyBuffer(var.first, foo, stream)[var.second.elements * index + el])); // Char outputs weird if being used as an integer } else if (var.second.type == std::type_index(typeid(char))) { j.push_back(static_cast(directed_graph->getEdgePropertyBuffer(var.first, foo, stream)[var.second.elements * index + el])); // Char outputs weird if being used as an integer } else { THROW exception::JSONError("Attempting to export value of unsupported type '%s', " "in JsonGraphWriter::writeAny()\n", var.second.type.name()); } } } void toAdjancencyLike(nlohmann::ordered_json &j, const std::shared_ptr& directed_graph, cudaStream_t stream) { const EnvironmentDirectedGraphData &data = directed_graph->getDescription(); // Vertices if (directed_graph->getVertexCount()) { j["nodes"] = {}; for (unsigned int i = 0; i < directed_graph->getVertexCount(); ++i) { nlohmann::ordered_json j_v; // Reserved members first size_type foo = 0; j_v["id"] = std::to_string(directed_graph->getVertexPropertyBuffer(ID_VARIABLE_NAME, foo, stream)[i]); // Custom members after for (const auto &v : data.vertexProperties) { if (v.first[0] != '_') { writeAnyVertex(j_v[v.first], v, i, directed_graph, stream); if (i == 0 && v.first == "id" && v.first != ID_VARIABLE_NAME) { fprintf(stderr, "Warning: Graph vertices contain both 'id' and '%s' properties, export may be invalid.\n", ID_VARIABLE_NAME); } } } j["nodes"].push_back(j_v); } } // Edges if (directed_graph->getEdgeCount()) { j["links"] = {}; for (unsigned int i = 0; i < directed_graph->getEdgeCount(); ++i) { nlohmann::ordered_json j_e; // Reserved members first size_type foo = 0; const id_t *src_dest_buffer = directed_graph->getEdgePropertyBuffer(GRAPH_SOURCE_DEST_VARIABLE_NAME, foo, stream); j_e["source"] = std::to_string(src_dest_buffer[i * 2 + 1]); j_e["target"] = std::to_string(src_dest_buffer[i * 2 + 0]); // Custom members after for (const auto& e : data.edgeProperties) { if (e.first[0] != '_') { writeAnyEdge(j_e[e.first], e, i, directed_graph, stream); if (i == 0 && e.first == "source") { fprintf(stderr, "Warning: Graph edges contain both 'source' and '%s' properties, export may be invalid.\n", GRAPH_SOURCE_DEST_VARIABLE_NAME); } else if (i == 0 && e.first == "target") { fprintf(stderr, "Warning: Graph edges contain both 'target' and '%s' properties, export may be invalid.\n", GRAPH_SOURCE_DEST_VARIABLE_NAME); } } } j["links"].push_back(j_e); } } } } // namespace void JSONGraphWriter::saveAdjacencyLike(const std::string& filepath, const std::shared_ptr& directed_graph, cudaStream_t stream, bool pretty_print) { // Init writer nlohmann::ordered_json j; toAdjancencyLike(j, directed_graph, stream); // Perform output std::ofstream out(filepath, std::ios::trunc | std::ios::binary); if (!out.is_open()) { THROW exception::InvalidFilePath("Unable to open file '%s' for writing, in JSONGraphWriter::saveAdjacencyLike()\n", filepath.c_str()); } if (pretty_print) { out << std::setw(4); } out << j; out.close(); } } // namespace io } // namespace flamegpu