Files
neuron-tai/packages/node/native/tests/roundtrip_test.cpp
2026-07-15 23:42:58 +03:00

181 lines
6.1 KiB
C++

// C++ round-trip and cross-language compatibility test for the Shard protocol.
//
// Modes (composable):
// --selftest serialize a sample message, parse it back, verify fields.
// --read <path> parse a fixture serialized by another language; verify the
// known fields; tolerate unknown fields (forward compat).
// --write <path> serialize the C++ sample so another language can parse it.
//
// Exit code 0 means every requested check passed. The Python test drives this
// binary to prove Python<->C++ wire compatibility in both directions.
#include "shard_runtime.pb.h"
#include <cstdint>
#include <fstream>
#include <iostream>
#include <sstream>
#include <string>
using namespace meshnet::shard::v1;
namespace {
bool Fail(const std::string& why) {
std::cerr << "roundtrip_test: FAIL: " << why << std::endl;
return false;
}
SessionActivation MakeSample() {
SessionActivation act;
PrefillChunk* pre = act.mutable_prefill();
MessageHeader* h = pre->mutable_header();
h->set_schema_version(SCHEMA_VERSION_1);
h->set_work_id("w1");
h->set_route_session_id("s1");
h->set_route_epoch(3);
h->set_phase(PHASE_PREFILL);
h->set_idempotency_step(7);
h->set_cache_expectation(CACHE_FRESH);
h->set_compression(COMPRESSION_NONE);
ArtifactFingerprint* fp = h->mutable_fingerprint();
fp->set_model_id("meta-llama/Llama-3.1-8B");
fp->set_quantization("Q4_K_M");
fp->set_runtime_recipe_fingerprint("recipe-abc");
ShardRange* sr = h->mutable_shard_range();
sr->set_start_layer(0);
sr->set_end_layer(16);
sr->set_effective_start_layer(0);
sr->set_owns_embedding(true);
Position* pos = h->mutable_position();
pos->set_start_position(0);
pos->set_token_count(5);
pos->set_sequence_length(5);
pre->set_chunk_index(0);
pre->set_chunk_count(1);
pre->set_final_chunk(true);
TensorBundle* bundle = pre->mutable_activations();
bundle->set_bundle_version(1);
NamedTensor* t = bundle->add_tensors();
t->set_name("hidden");
t->add_shape(1);
t->add_shape(4096);
t->set_dtype(DTYPE_F16);
t->set_byte_order(BYTE_ORDER_LITTLE_ENDIAN);
t->set_total_byte_length(8);
t->set_compression(COMPRESSION_NONE);
TensorFragment* frag = t->add_fragments();
frag->set_fragment_index(0);
frag->set_fragment_count(1);
frag->set_byte_offset(0);
frag->set_data(std::string("\x01\x02\x03\x04\x05\x06\x07\x08", 8));
return act;
}
bool CheckSample(const SessionActivation& act) {
if (act.payload_case() != SessionActivation::kPrefill)
return Fail("payload is not prefill");
const PrefillChunk& pre = act.prefill();
const MessageHeader& h = pre.header();
if (h.schema_version() != SCHEMA_VERSION_1) return Fail("schema_version");
if (h.work_id() != "w1") return Fail("work_id");
if (h.route_session_id() != "s1") return Fail("route_session_id");
if (h.route_epoch() != 3) return Fail("route_epoch");
if (h.phase() != PHASE_PREFILL) return Fail("phase");
if (h.idempotency_step() != 7) return Fail("idempotency_step");
if (h.fingerprint().model_id() != "meta-llama/Llama-3.1-8B")
return Fail("model_id");
if (h.fingerprint().quantization() != "Q4_K_M") return Fail("quantization");
if (h.shard_range().end_layer() != 16) return Fail("end_layer");
if (!h.shard_range().owns_embedding()) return Fail("owns_embedding");
if (h.position().token_count() != 5) return Fail("token_count");
if (!pre.final_chunk()) return Fail("final_chunk");
if (pre.activations().tensors_size() != 1) return Fail("tensors_size");
const NamedTensor& t = pre.activations().tensors(0);
if (t.name() != "hidden") return Fail("tensor name");
if (t.dtype() != DTYPE_F16) return Fail("dtype");
if (t.byte_order() != BYTE_ORDER_LITTLE_ENDIAN) return Fail("byte_order");
if (t.shape_size() != 2 || t.shape(1) != 4096) return Fail("shape");
if (t.fragments_size() != 1) return Fail("fragments_size");
if (t.fragments(0).data().size() != 8) return Fail("fragment data length");
return true;
}
bool ReadFile(const std::string& path, std::string* out) {
std::ifstream in(path, std::ios::binary);
if (!in) return false;
std::ostringstream ss;
ss << in.rdbuf();
*out = ss.str();
return true;
}
bool WriteFile(const std::string& path, const std::string& data) {
std::ofstream out(path, std::ios::binary);
if (!out) return false;
out.write(data.data(), static_cast<std::streamsize>(data.size()));
return static_cast<bool>(out);
}
} // namespace
int main(int argc, char** argv) {
GOOGLE_PROTOBUF_VERIFY_VERSION;
std::string read_path;
std::string write_path;
bool selftest = (argc == 1);
for (int i = 1; i < argc; ++i) {
std::string arg = argv[i];
if (arg == "--selftest") {
selftest = true;
} else if (arg == "--read" && i + 1 < argc) {
read_path = argv[++i];
} else if (arg == "--write" && i + 1 < argc) {
write_path = argv[++i];
} else {
std::cerr << "unknown/incomplete arg: " << arg << std::endl;
return 2;
}
}
if (selftest) {
SessionActivation sample = MakeSample();
std::string bytes;
if (!sample.SerializeToString(&bytes)) return Fail("serialize"), 1;
SessionActivation parsed;
if (!parsed.ParseFromString(bytes)) return Fail("parse"), 1;
if (!CheckSample(parsed)) return 1;
std::cout << "selftest ok (" << bytes.size() << " bytes)" << std::endl;
}
if (!read_path.empty()) {
std::string bytes;
if (!ReadFile(read_path, &bytes)) return Fail("cannot read fixture"), 1;
SessionActivation parsed;
// ParseFromString tolerates and preserves unknown fields (forward compat).
if (!parsed.ParseFromString(bytes)) return Fail("parse fixture"), 1;
if (!CheckSample(parsed)) return 1;
std::cout << "read ok (" << bytes.size() << " bytes)" << std::endl;
}
if (!write_path.empty()) {
SessionActivation sample = MakeSample();
std::string bytes;
if (!sample.SerializeToString(&bytes)) return Fail("serialize for write"), 1;
if (!WriteFile(write_path, bytes)) return Fail("cannot write output"), 1;
std::cout << "write ok (" << bytes.size() << " bytes)" << std::endl;
}
google::protobuf::ShutdownProtobufLibrary();
return 0;
}