common: add json.h abstraction - #27511
Conversation
ServeurpersoCom
left a comment
There was a problem hiding this comment.
LGTM. Read it on a checkout: the only silent change is a braced pair in value position, array before and object now, and they are all converted to json::array() here, tests included. Nice side effect, operator[] const throws where master aborted on the assert.
Two nits, non blocking: tests/gguf-model-data.cpp still includes nlohmann/json.hpp directly, and the object iterator re-walks with std::next(begin(), idx) on every dereference.
Every copy now sits behind one translation unit, which is also where a depth bound would live. Is that the intent, so #27434 can be closed without waiting for nlohmann/json#5389?
There was a problem hiding this comment.
Nice work! I see 10% build time reduction on my M2 Ultra with 8 threads for the total project and about ~20% reduction for user-space code (common, tool, examples, tests).
Btw, I think there is a low-hanging fruit for reducing compilation time by amalgamating the models/*.cpp files as part of the build process.
| // json.cpp defines this specialization, it must be declared before any use of it | ||
| template <> common_json common_json::get<common_json>() const; | ||
|
|
There was a problem hiding this comment.
nit: I think this declaration can be safely removed
|
@ServeurpersoCom thanks for testing, I added your points as code comments
maintainers are actively working on the upstream PR, so that this point we can be sure that it will be fixed upstream. let's close the PR #27434 to avoid duplicated works
@ggerganov TIL that cmakelists has a feature called UNITY_BUILD, may worth giving it a try? |
|
rebased to make sure I'm not missing any code paths that were not migrated, will merge this PR once is CI is green |
|
@ngxson: is it just me or this merge broke my build on windows using clang? links issues (undefined symbols) |
|
Interesting; I haven't tested Windows in advance at all, but it's inevitable: when I rebase my working branch, the little dedicated Windows machine (exposed at https://www.serveurperso.com/ia/windows/ !) is going to run into trouble, I check this now! |
|
It's simply the build folder that needs to be deleted on my side. Windows OK |
|
@ServeurpersoCom - nope... still fails at my end even after using a clean build folder... BTW i do wonder now what was the potential fixed you proposed earlier? |
Are you building master itself, or a branch of your own on top of it? If you carry local changes under tools/server or common, that is where I would look first: every JSON type and call in that code has to move to the new common_json. The header include becomes common/json.h instead of nlohmann/json.hpp, any nlohmann::ordered_json in a signature or a using alias becomes common_json, and a braced array literal in value position no longer builds, so {a, b, c} has to be written as json::array({a, b, c}). |
indeed on a fork.... which i keep on rebased from master here. i'll keep you posted either way... i just started looking into it and thanks for the quick response ❤️ |
|
Found it — it was the For anyone hitting the same thing on Windows + clang + LTO: explicit template instantiations in a static/shared lib can come out as weak (W) symbols instead of exported (T), so the linker reports them as undefined even though they're in the object. @ServeurpersoCom: sorry if made you worry man 😅 looks like it a it's a clang-on-Windows LTO bug. |
|
I can confirm this regression on Windows when building with The root cause appears to be tied to the recent Autoparser refactoring, which introduced new JSON-template instantiations inside static libraries. Under Windows (COFF format), Instead of forcing users to abandon Clang or LTO, could we fix this at the CMake or source level?
I'd love to keep using |
|
could you try #27575 ? |
Overview
Add a light-weight
common/json.hto avoid re-compilingjson.hppin multiple places. Also allow swapping another pimpl in the future if neededGoals:
nlohmann::jsonChanges to downstream code:
nlohmann::jsontocommon_jsonobj.push_back({key, val})is changed toobj[key] = valfor clarify;push_backcan be confused withstd::vectorin some placesstd::something<...> = obj["abc"], change to explicit= obj.get<std::something<...>>()to avoid excessive template instancesResults
End-to-end (compile common + server, exclude libllama/libmtmd, -j12):
Single-TU dev loop (touch tools/server/server-context.cpp, rebuild + link):
Binary size:
TODO:
remove the deps jinja --> common (the json-to-internal code path)maybe a follow-upRequirements