Skip to content

Commit cea3e23

Browse files
Robadobptheywood
authored andcommitted
Replace RapidJSON with nlohmann::json
RapidJSON has become outdated, which has led to increasing maintenance issues. - Amends JSON IO tests, now test that inf is loaded as NaN - Add warning when JSON readers interpret NULL as NaN - Not emitted when verbosity is set ot Quiet for JSONStateReader - Includes a CUDA 12.0 and 12.1 nlohmann_json compiler error workaround - Defines JSON_HAS_RANGES=0 to workaround CUDA 12.0 and 12.1 compiler error on linux, and a similar error on windows (which might ber 12.0 only)
1 parent e902356 commit cea3e23

21 files changed

Lines changed: 668 additions & 817 deletions

.github/workflows/Draft-Release.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -400,7 +400,7 @@ jobs:
400400
cuda: ${{ env.CUDA }}
401401
run: .github/scripts/install_cuda_el8.sh
402402

403-
# Downgrade CMake for DeVIL and rapidjson. See https://github.com/FLAMEGPU/FLAMEGPU2/issues/1276
403+
# Downgrade CMake for DeVIL. See https://github.com/FLAMEGPU/FLAMEGPU2/issues/1276
404404
- name: Install CMake < 4.0, overwriting the pipx installed version from manylinux
405405
run: |
406406
pipx install --global --force 'cmake<4.0'

.github/workflows/Manylinux_2_28.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ jobs:
103103
cuda: ${{ env.CUDA }}
104104
run: .github/scripts/install_cuda_el8.sh
105105

106-
# Downgrade CMake for DeVIL and rapidjson. See https://github.com/FLAMEGPU/FLAMEGPU2/issues/1276
106+
# Downgrade CMake for DeVIL. See https://github.com/FLAMEGPU/FLAMEGPU2/issues/1276
107107
- name: Install CMake < 4.0, overwriting the pipx installed version from manylinux
108108
run: |
109109
pipx install --global --force 'cmake<4.0'

cmake/common.cmake

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,11 @@ if(DEFINED CMAKE_CUDA_ARCHITECTURES AND NOT flamegpu_printed_cmake_cuda_architec
2727
endif()
2828

2929
# Ensure that other dependencies are downloaded and available.
30-
# As flamegpu is a static library, linking only only occurs at consumption not generation, so dependent targets must also know of PRIVATE shared library dependencies such as tinyxml2 and rapidjson, as well any intentionally public dependencies (for include dirs)
30+
# As flamegpu is a static library, linking only only occurs at consumption not generation, so dependent targets must also know of PRIVATE shared library dependencies such as tinyxml2, as well any intentionally public dependencies (for include dirs)
3131
include(${CMAKE_CURRENT_LIST_DIR}/dependencies/CCCL.cmake)
3232
include(${CMAKE_CURRENT_LIST_DIR}/dependencies/Jitify.cmake)
3333
include(${CMAKE_CURRENT_LIST_DIR}/dependencies/Tinyxml2.cmake)
34-
include(${CMAKE_CURRENT_LIST_DIR}/dependencies/rapidjson.cmake)
34+
include(${CMAKE_CURRENT_LIST_DIR}/dependencies/nlohmann_json.cmake)
3535
if(FLAMEGPU_ENABLE_GLM)
3636
include(${CMAKE_CURRENT_LIST_DIR}/dependencies/glm.cmake)
3737
endif()
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
#################
2+
# nlohmann/json #
3+
#################
4+
5+
include(FetchContent)
6+
cmake_policy(SET CMP0079 NEW)
7+
# Temporary CMake >= 3.30 fix https://github.com/FLAMEGPU/FLAMEGPU2/issues/1223
8+
if(POLICY CMP0169)
9+
cmake_policy(SET CMP0169 OLD)
10+
endif()
11+
FetchContent_Declare(
12+
nlohmann_json
13+
URL "https://github.com/nlohmann/json/releases/download/v3.11.3/json.tar.xz"
14+
)
15+
FetchContent_GetProperties(nlohmann_json)
16+
if(NOT nlohmann_json_POPULATED)
17+
FetchContent_Populate(nlohmann_json)
18+
# Add the project as a subdirectory
19+
add_subdirectory(${nlohmann_json_SOURCE_DIR} ${nlohmann_json_BINARY_DIR} EXCLUDE_FROM_ALL)
20+
21+
# If we are using CUDA 12.0 or 12.1 on linux or windows, add an interface definition of JSON_HAS_RANGES to 0 to the nlohmann target to workaround an nvcc bug. See https://github.com/nlohmann/json/issues/3907.
22+
if(CMAKE_CUDA_COMPILER_VERSION VERSION_GREATER_EQUAL 12.0 AND CMAKE_CUDA_COMPILER_VERSION VERSION_LESS 12.2)
23+
target_compile_definitions(nlohmann_json INTERFACE $<$<COMPILE_LANGUAGE:CUDA>:JSON_HAS_RANGES=0>)
24+
endif()
25+
26+
endif()
27+
28+
# Mark some CACHE vars advanced for a cleaner GUI
29+
mark_as_advanced(FETCHCONTENT_QUIET)
30+
mark_as_advanced(FETCHCONTENT_BASE_DIR)
31+
mark_as_advanced(FETCHCONTENT_FULLY_DISCONNECTED)
32+
mark_as_advanced(FETCHCONTENT_UPDATES_DISCONNECTED)
33+
mark_as_advanced(FETCHCONTENT_SOURCE_DIR_NLOHMANN_JSON)
34+
mark_as_advanced(FETCHCONTENT_UPDATES_DISCONNECTED_NLOHMANN_JSON)
35+
mark_as_advanced(JSON_BuildTests)
36+
mark_as_advanced(JSON_CI)
37+
mark_as_advanced(JSON_Diagnostics)
38+
mark_as_advanced(JSON_DisableEnumSerialization)
39+
mark_as_advanced(JSON_GlobalUDLs)
40+
mark_as_advanced(JSON_ImplicitConversions)
41+
mark_as_advanced(JSON_Install)
42+
mark_as_advanced(JSON_LegacyDiscardedValueComparison)
43+
mark_as_advanced(JSON_MultipleHeaders)
44+
mark_as_advanced(JSON_SystemInclude)

cmake/dependencies/patches/rapidjson-cmake-3.5-deprecation.patch

Lines changed: 0 additions & 12 deletions
This file was deleted.

cmake/dependencies/rapidjson.cmake

Lines changed: 0 additions & 86 deletions
This file was deleted.

include/flamegpu/exception/FLAMEGPUException.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -361,9 +361,9 @@ DERIVED_FLAMEGPUException(OutOfBoundsException, "Index exceeds bounds of array!"
361361
*/
362362
DERIVED_FLAMEGPUException(TinyXMLError, "TinyXML returned an error code!");
363363
/**
364-
* Defines an exception for errors reported by RapidJSON
364+
* Defines an exception for errors reported whilst processing JSON
365365
*/
366-
DERIVED_FLAMEGPUException(RapidJSONError, "RapidJSON returned an error code!");
366+
DERIVED_FLAMEGPUException(JSONError, "JSON error occured!");
367367

368368
/**
369369
* Defines an exception for errors when model components are mixed up

include/flamegpu/io/JSONGraphReader.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ class JSONGraphReader {
2222
* @param stream CUDA stream (required by directed_graph for synchronising device buffers)
2323
*
2424
* @throws exception::InvalidFilePath If the file cannot be opened for reading
25-
* @throws exception::RapidJSONError If JSON fails for any reason (e.g. structure does not match expectations)
25+
* @throws exception::JSONError If JSON fails for any reason (e.g. structure does not match expectations)
2626
*/
2727
static void loadAdjacencyLike(const std::string &filepath, const std::shared_ptr<detail::CUDAEnvironmentDirectedGraphBuffers> &directed_graph, cudaStream_t stream);
2828
};

include/flamegpu/io/JSONGraphWriter.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ class JSONGraphWriter {
2323
* @param pretty_print Whether JSON should be human readable (vs minified)
2424
*
2525
* @throws exception::InvalidFilePath If the file cannot be opened for writing
26-
* @throws exception::RapidJSONError If conversion to JSON fails for any reason
26+
* @throws exception::JSONError If conversion to JSON fails for any reason
2727
*/
2828
static void saveAdjacencyLike(const std::string &filepath, const std::shared_ptr<const detail::CUDAEnvironmentDirectedGraphBuffers> &directed_graph, cudaStream_t stream, bool pretty_print = true);
2929
};

include/flamegpu/io/JSONLogger.h

Lines changed: 22 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
#include <string>
55
#include <typeindex>
66

7+
#include <nlohmann/json.hpp>
8+
79
#include "flamegpu/io/Logger.h"
810
#include "flamegpu/detail/Any.h"
911

@@ -38,98 +40,62 @@ class JSONLogger : public Logger{
3840
* Internal logging method, allows Plan to be passed as null
3941
*/
4042
void logCommon(const RunLog &log, const RunPlan *plan, bool logConfig, bool logSteps, bool logExit, bool logStepTime, bool logExitTime) const;
43+
44+
void logCommon(nlohmann::ordered_json& j, const RunLog &log, const RunPlan *plan, bool logConfig, bool logSteps, bool logExit, bool logStepTime, bool logExitTime) const;
4145
/**
42-
* rapidjson::Writer doesn't have virtual methods, so can't pass rapidjson::PrettyWriter around as ptr to rapidjson::writer
43-
* Instead we call a templated version of all the methods
44-
*/
45-
template<typename T>
46-
void logCommon(T &writer, const RunLog &log, const RunPlan *plan, bool logConfig, bool logSteps, bool logExit, bool logStepTime, bool logExitTime) const;
47-
/**
48-
* Writes out the run config via a JSON object
49-
* @param writer Rapidjson writer instance
46+
* Returns the run config as a JSON object
5047
* @param log RunLog containing the config items to be written
51-
* @tparam T Instance of rapidjson::Writer or subclass (e.g. rapidjson::PrettyWriter)
52-
* @note Templated as can't forward declare rapidjson::Writer<rapidjson::StringBuffer>
5348
*/
54-
template<typename T>
55-
void logConfig(T &writer, const RunLog &log) const;
49+
nlohmann::ordered_json logConfig(const RunLog &log) const;
5650
/**
57-
* Writes out step logs as a JSON array via the provided writer
58-
* @param writer Rapidjson writer instance
51+
* Returns the run plan as a JSON object
5952
* @param plan RunPlan containing the config items to be written
60-
* @tparam T Instance of rapidjson::Writer or subclass (e.g. rapidjson::PrettyWriter)
61-
* @note Templated as can't forward declare rapidjson::Writer<rapidjson::StringBuffer>
6253
*/
63-
template<typename T>
64-
void logConfig(T &writer, const RunPlan &plan) const;
54+
nlohmann::ordered_json logConfig(const RunPlan &plan) const;
6555
/**
66-
* Writes out step logs as a JSON array via the provided writer
67-
* @param writer Rapidjson writer instance
56+
* Return a json object containing performance specs
6857
* @param log RunLog containing the config items to be written
69-
* @tparam T Instance of rapidjson::Writer or subclass (e.g. rapidjson::PrettyWriter)
70-
* @note Templated as can't forward declare rapidjson::Writer<rapidjson::StringBuffer>
7158
*/
72-
template<typename T>
73-
void logPerformanceSpecs(T& writer, const RunLog& log) const;
59+
nlohmann::ordered_json logPerformanceSpecs(const RunLog& log) const;
7460
/**
7561
* Writes out step logs as a JSON array via the provided writer
76-
* @param writer Rapidjson writer instance
62+
* @param j nhlomann::json instance
7763
* @param log RunLog containing the step logs to be written
7864
* @param logTime Include time in the log to be written
79-
* @tparam T Instance of rapidjson::Writer or subclass (e.g. rapidjson::PrettyWriter)
80-
* @note Templated as can't forward declare rapidjson::Writer<rapidjson::StringBuffer>
8165
*/
82-
template<typename T>
83-
void logSteps(T &writer, const RunLog &log, bool logTime) const;
66+
void logSteps(nlohmann::ordered_json& j, const RunLog &log, bool logTime) const;
8467
/**
8568
* Writes out an exit log as a JSON object via the provided writer
86-
* @param writer Rapidjson writer instance
69+
* @param j nhlomann::json instance
8770
* @param log RunLog containing the exit log to be written
8871
* @param logTime Include time in the log to be written
89-
* @tparam T Instance of rapidjson::Writer or subclass (e.g. rapidjson::PrettyWriter)
90-
* @note Templated as can't forward declare rapidjson::Writer<rapidjson::StringBuffer>
9172
*/
92-
template<typename T>
93-
void logExit(T &writer, const RunLog &log, bool logTime) const;
73+
void logExit(nlohmann::ordered_json& j, const RunLog &log, bool logTime) const;
9474
/**
95-
* Writes out an StepLogFrame instance as a JSON object via the provided writer
96-
* @param writer Rapidjson writer instance
75+
* Returns the StepLogFrame as a JSON object
9776
* @param log LogFrame to be written
9877
* @param logTime Include time in the log to be written
99-
* @tparam T Instance of rapidjson::Writer or subclass (e.g. rapidjson::PrettyWriter)
100-
* @note Templated as can't forward declare rapidjson::Writer<rapidjson::StringBuffer>
10178
*/
102-
template<typename T>
103-
void writeLogFrame(T &writer, const StepLogFrame&log, bool logTime) const;
79+
nlohmann::ordered_json writeLogFrame(const StepLogFrame&log, bool logTime) const;
10480
/**
105-
* Writes out an ExitLogFrame instance as a JSON object via the provided writer
106-
* @param writer Rapidjson writer instance
81+
* Returns the ExitLogFrame as a JSON object
10782
* @param log LogFrame to be written
10883
* @param logTime Include time in the log to be written
109-
* @tparam T Instance of rapidjson::Writer or subclass (e.g. rapidjson::PrettyWriter)
110-
* @note Templated as can't forward declare rapidjson::Writer<rapidjson::StringBuffer>
11184
*/
112-
template<typename T>
113-
void writeLogFrame(T& writer, const ExitLogFrame& log, bool logTime) const;
85+
nlohmann::ordered_json writeLogFrame(const ExitLogFrame& log, bool logTime) const;
11486
/**
11587
* Writes out a LogFrame instance as a JSON object via the provided writer
116-
* @param writer Rapidjson writer instance
88+
* @param j nhlomann::json instance
11789
* @param log LogFrame to be written
118-
* @tparam T Instance of rapidjson::Writer or subclass (e.g. rapidjson::PrettyWriter)
119-
* @note Templated as can't forward declare rapidjson::Writer<rapidjson::StringBuffer>
12090
*/
121-
template<typename T>
122-
void writeCommonLogFrame(T& writer, const LogFrame& log) const;
91+
void writeCommonLogFrame(nlohmann::ordered_json& j, const LogFrame& log) const;
12392
/**
12493
* Writes out the value of an Any via the provided writer
125-
* @param writer Rapidjson writer instance
94+
* @param j nhlomann::json instance
12695
* @param value The Any to be written
12796
* @param elements The number of individual elements stored in the Any (1 if not an array)
128-
* @tparam T Instance of rapidjson::Writer or subclass (e.g. rapidjson::PrettyWriter)
129-
* @note Templated as can't forward declare rapidjson::Writer<rapidjson::StringBuffer>
13097
*/
131-
template<typename T>
132-
void writeAny(T &writer, const detail::Any &value, unsigned int elements = 1) const;
98+
void writeAny(nlohmann::ordered_json& j, const detail::Any &value, unsigned int elements = 1) const;
13399

134100
std::string out_path;
135101
bool prettyPrint;

0 commit comments

Comments
 (0)