#include "raid/core/manifest.hpp" #include "raid/core/error.hpp" #include #include #include #include #ifdef __APPLE__ #include #include #endif #include #include namespace raid { namespace { #ifdef __APPLE__ std::string sysctl_str(const char* name) { char buf[256]; size_t n = sizeof buf; if (sysctlbyname(name, buf, &n, nullptr, 0) == 0) return std::string(buf, n > 0 ? n - 1 : 0); return ""; } i64 sysctl_i64(const char* name) { i64 v = 0; size_t n = sizeof v; if (sysctlbyname(name, &v, &n, nullptr, 0) == 0) return v; return -1; } #endif std::string shell(const char* cmd) { std::string out; if (FILE* p = popen(cmd, "r")) { char b[512]; while (fgets(b, sizeof b, p)) out += b; pclose(p); } while (!out.empty() && (out.back() == '\n' || out.back() == ' ')) out.pop_back(); return out; } } // namespace std::string now_utc_iso() { const auto now = std::chrono::system_clock::now(); return timestamp_iso(Timestamp(std::chrono::duration_cast(now.time_since_epoch()).count())); } u64 peak_rss_bytes() { struct rusage ru{}; getrusage(RUSAGE_SELF, &ru); #ifdef __APPLE__ return static_cast(ru.ru_maxrss); #else return static_cast(ru.ru_maxrss) * 1024; #endif } nlohmann::json host_info() { nlohmann::json j; char host[256]; gethostname(host, sizeof host); j["hostname"] = host; j["hardware_threads"] = std::thread::hardware_concurrency(); #ifdef __APPLE__ j["chip"] = sysctl_str("machdep.cpu.brand_string"); j["ncpu"] = sysctl_i64("hw.ncpu"); j["perf_cores"] = sysctl_i64("hw.perflevel0.physicalcpu"); j["eff_cores"] = sysctl_i64("hw.perflevel1.physicalcpu"); j["mem_bytes"] = sysctl_i64("hw.memsize"); j["os_version"] = sysctl_str("kern.osproductversion"); j["os_build"] = sysctl_str("kern.osversion"); j["model"] = sysctl_str("hw.model"); j["thermal"] = shell("pmset -g therm 2>/dev/null | tr '\\n' ';'"); j["power"] = shell("pmset -g batt 2>/dev/null | head -1"); j["load_avg"] = shell("sysctl -n vm.loadavg"); #else j["os"] = shell("uname -sr"); j["chip"] = shell("grep -m1 'model name' /proc/cpuinfo | cut -d: -f2"); j["load_avg"] = shell("cat /proc/loadavg"); #endif #if defined(__clang__) j["compiler"] = std::string("clang ") + __clang_version__; #elif defined(__GNUC__) j["compiler"] = std::string("gcc ") + __VERSION__; #endif j["raid_version"] = RAID_VERSION; #ifdef RAID_WITH_ACCELERATE j["blas"] = "Apple Accelerate"; #else j["blas"] = "Eigen built-in"; #endif return j; } nlohmann::json ExperimentManifest::to_json() const { return {{"experiment", experiment}, {"created_at_utc", created_at_utc}, {"raid_version", raid_version}, {"git_commit", git_commit}, {"host", host}, {"plan", plan}, {"seed", seed}, {"inputs", inputs}, {"parameters", parameters}, {"records", records}}; } void ExperimentManifest::save(const std::string& path) const { std::ofstream f(path); RAID_REQUIRE(f.good(), io, "cannot write " + path); f << to_json().dump(1) << "\n"; } } // namespace raid