kimodo-mrp.ccc/tests/capi_test.cpp
2026-08-22 09:40:35 +01:00

84 lines
3.7 KiB
C++

#include <kimodo/kimodo_capi.h>
#include <cassert>
#include <cmath>
#include <cstdint>
#include <cstdio>
#include <cstring>
#include <fstream>
#include <string>
#include <vector>
template <class T> static void put(std::ofstream &out, T value) {
out.write(reinterpret_cast<const char *>(&value), sizeof(value));
}
static void put_string(std::ofstream &out, const char *value) {
const auto n = static_cast<std::uint64_t>(std::strlen(value)); put(out, n); out.write(value, static_cast<std::streamsize>(n));
}
static void put_key_string(std::ofstream &out, const char *key, const char *value) {
put_string(out, key); put(out, std::uint32_t{8}); put_string(out, value);
}
static void put_key_uint(std::ofstream &out, const char *key, std::uint64_t value) {
put_string(out, key); put(out, std::uint32_t{10}); put(out, value);
}
static void motion_gguf(const char *path) {
std::ofstream out(path, std::ios::binary);
put(out, std::uint32_t{0x46554747}); put(out, std::uint32_t{3}); put(out, std::uint64_t{0}); put(out, std::uint64_t{5});
put_key_string(out, "general.architecture", "kimodo-motion");
put_key_uint(out, "kimodo.format_version", 1);
put_key_string(out, "kimodo.skeleton", "smplx22");
put_key_uint(out, "kimodo.text_embedding_width", 4096);
put_key_string(out, "kimodo.model_identity", "fixture-v1");
}
int main(int argc, char **argv) {
assert(kimodo_abi_version() == 1);
char error[64];
auto *model = kimodo_model_load("does-not-exist.gguf", nullptr, nullptr, nullptr, error, sizeof(error));
assert(model == nullptr && std::strlen(error) > 0);
const char *path = "kimodo-test-motion.gguf";
motion_gguf(path);
model = kimodo_model_load(path, nullptr, nullptr, nullptr, error, sizeof(error));
assert(model == nullptr);
assert(std::strlen(error) > 0);
// A tensorless metadata-only fixture must never be treated as a model.
std::remove(path);
assert(kimodo_generate_embedding(nullptr, nullptr, nullptr, error, sizeof(error)) == nullptr);
if (argc == 2 || argc == 3) {
kimodo_runtime_options runtime{};
runtime.size = sizeof(runtime);
auto *loaded = kimodo_model_load(argv[1], argc == 3 ? argv[2] : nullptr, nullptr, &runtime, error, sizeof(error));
assert(loaded != nullptr);
std::vector<float> embedding(4096);
kimodo_embedding input{embedding.data(), static_cast<uint32_t>(embedding.size())};
kimodo_generation_options options{};
options.size = sizeof(options);
options.seed = 42;
options.frames = 2;
options.diffusion_steps = 1;
options.text_cfg_weight = 2.f;
options.constraint_cfg_weight = 2.f;
auto *motion = kimodo_generate_embedding(loaded, &input, &options, error, sizeof(error));
assert(motion != nullptr);
assert(kimodo_motion_frames(motion) == 2);
assert(kimodo_motion_joints(motion) == 22);
const float *root = kimodo_motion_root_positions(motion);
const float *rotations = kimodo_motion_local_rotations_xyzw(motion);
assert(root != nullptr && rotations != nullptr);
for (int i = 0; i < 6; ++i) assert(std::isfinite(root[i]));
for (int i = 0; i < 2 * 22 * 4; ++i) assert(std::isfinite(rotations[i]));
kimodo_motion_free(motion);
if (argc == 3) {
motion = kimodo_generate(loaded,
"A person runs forward and then leaps over an obstacle in front of them.",
&options, error, sizeof(error));
assert(motion != nullptr);
assert(kimodo_motion_frames(motion) == 2);
assert(kimodo_motion_joints(motion) == 22);
kimodo_motion_free(motion);
}
kimodo_model_free(loaded);
}
}