test1111111 / native /compile_plan.cpp
spitfire4794's picture
CISM remote autobench: full source + fleet runner, serve results on 7860
28a1a01
Raw History Blame Contribute Delete
5.04 kB
#include "compile_plan.hpp"
#include <cstdint>
#include <sstream>
#include <stdexcept>
namespace cism {
const char* plan_code_version() {
return "cism-plan-v1";
}
namespace {
// Standard FNV-1a 64-bit parameters.
constexpr std::uint64_t kFnvOffsetBasis = 14695981039346656037ULL;
constexpr std::uint64_t kFnvPrime = 1099511628211ULL;
std::uint64_t fnv1a64(const std::string& data) {
std::uint64_t hash = kFnvOffsetBasis;
for (unsigned char octet : data) {
hash ^= static_cast<std::uint64_t>(octet);
hash *= kFnvPrime;
}
return hash;
}
std::string to_hex16(std::uint64_t value) {
static const char* kDigits = "0123456789abcdef";
std::string out(16, '0');
for (int i = 15; i >= 0; --i) {
out[static_cast<std::size_t>(i)] = kDigits[value & 0xF];
value >>= 4;
}
return out;
}
// Minimal JSON string escaper (no third-party deps). Passes UTF-8 bytes
// >= 0x20 through, escapes '"', '\\', and C0 controls per RFC 8259.
std::string json_escape(const std::string& value) {
std::string out;
out.reserve(value.size() + 2);
for (unsigned char c : value) {
switch (c) {
case '"': out += "\\\""; break;
case '\\': out += "\\\\"; break;
case '\b': out += "\\b"; break;
case '\f': out += "\\f"; break;
case '\n': out += "\\n"; break;
case '\r': out += "\\r"; break;
case '\t': out += "\\t"; break;
default:
if (c < 0x20) {
char buf[7];
const char* digits = "0123456789abcdef";
buf[0] = '\\';
buf[1] = 'u';
buf[2] = '0';
buf[3] = '0';
buf[4] = digits[(c >> 4) & 0xF];
buf[5] = digits[c & 0xF];
buf[6] = '\0';
out += buf;
} else {
out += static_cast<char>(c);
}
break;
}
}
return out;
}
} // namespace
std::string compute_compile_key(const std::string& canonical_config,
const std::string& precision,
const std::string& act_precision,
std::size_t threads,
const std::string& cpu_features,
const std::string& code_version) {
if (canonical_config.empty()) throw std::invalid_argument("canonical_config must be nonempty");
if (precision.empty()) throw std::invalid_argument("precision must be nonempty");
if (act_precision.empty()) throw std::invalid_argument("act_precision must be nonempty");
if (threads == 0) throw std::invalid_argument("threads must be in [1, 64]");
if (cpu_features.empty()) throw std::invalid_argument("cpu_features must be nonempty");
if (code_version.empty()) throw std::invalid_argument("code_version must be nonempty");
// Labeled join keeps every field load-bearing: flipping any single
// input changes the hashed string.
const std::string canonical = "canonical=" + canonical_config +
";precision=" + precision +
";act=" + act_precision +
";threads=" + std::to_string(threads) +
";cpu=" + cpu_features +
";code=" + code_version;
return to_hex16(fnv1a64(canonical));
}
std::string build_manifest(const std::string& key,
const std::string& precision,
const std::string& act_precision,
std::size_t threads,
const std::string& cpu_features,
const std::vector<std::pair<std::size_t, std::size_t>>& shapes) {
if (key.empty()) throw std::invalid_argument("key must be nonempty");
if (precision.empty()) throw std::invalid_argument("precision must be nonempty");
if (act_precision.empty()) throw std::invalid_argument("act_precision must be nonempty");
if (threads == 0) throw std::invalid_argument("threads must be in [1, 64]");
if (cpu_features.empty()) throw std::invalid_argument("cpu_features must be nonempty");
std::ostringstream out;
out << "{\"magic\":\"cism-plan\""
<< ",\"version\":\"" << json_escape(plan_code_version()) << "\""
<< ",\"key\":\"" << json_escape(key) << "\""
<< ",\"precision\":\"" << json_escape(precision) << "\""
<< ",\"act_precision\":\"" << json_escape(act_precision) << "\""
<< ",\"threads\":" << threads
<< ",\"cpu_features\":\"" << json_escape(cpu_features) << "\""
<< ",\"shapes\":[";
for (std::size_t i = 0; i < shapes.size(); ++i) {
if (i) out << ",";
out << "[" << shapes[i].first << "," << shapes[i].second << "]";
}
out << "]}";
return out.str();
}
} // namespace cism