use crate::verify::{RocmBenchmarkReport, RocmBenchmarkRow, proof_replay_artifact_digest};
use crate::{Error, Result};
pub const HIP_AUDIT_REPORT_ARTIFACT: &str = "tokitai-hip-proof-audit-report";
pub const HIP_AUDIT_REPORT_VERSION: u32 = 1;
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct HipAuditReport {
pub artifact: String,
pub version: u32,
pub traces: Vec<HipAuditTrace>,
pub non_claims: Vec<String>,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct HipAuditTrace {
pub workload: String,
pub domain: String,
pub backend: String,
pub status: String,
pub device_fingerprint: String,
pub kernel_source_fingerprint: String,
pub compiler_fingerprint: String,
pub kernel_symbol: String,
pub code_object_metadata_fingerprint: String,
pub disassembly_metadata: String,
pub cpu_oracle_matches: bool,
pub fallback_reason: String,
pub transfer_evidence: String,
pub launch_metadata: String,
pub theory_constraints: Vec<String>,
pub obligations: Vec<String>,
pub audit_fingerprint: String,
}
pub fn generate_hip_audit_report() -> Result<HipAuditReport> {
let benchmarks = crate::verify::generate_rocm_benchmark_report()?;
hip_audit_report_from_rocm_benchmarks(&benchmarks)
}
pub fn hip_audit_report_from_rocm_benchmarks(
report: &RocmBenchmarkReport,
) -> Result<HipAuditReport> {
let traces = report
.rows
.iter()
.map(HipAuditTrace::from_benchmark_row)
.collect::<Vec<_>>();
let audit = HipAuditReport {
artifact: HIP_AUDIT_REPORT_ARTIFACT.to_string(),
version: HIP_AUDIT_REPORT_VERSION,
traces,
non_claims: vec![
"HIP audit traces bind source, compiler, device, transfer, kernel-symbol, code-object metadata, fallback, and CPU oracle evidence; they do not formally verify generated machine code".to_string(),
"ROCm/HIP traces are local hardware evidence, not portable AMD GPU support".to_string(),
"timing fields remain benchmark smoke evidence, not production speedup claims".to_string(),
],
};
validate_hip_audit_report(&audit)?;
Ok(audit)
}
pub fn hip_audit_report_from_padic_stratified_benchmarks(
report: &crate::backend::hip_padic_benchmarks::PadicStratifiedBenchmarkReport,
) -> Result<HipAuditReport> {
let traces = report
.rows
.iter()
.filter(|row| row.backend.starts_with("rocm_hip"))
.map(HipAuditTrace::from_padic_stratified_benchmark_row)
.collect::<Vec<_>>();
let audit = HipAuditReport {
artifact: HIP_AUDIT_REPORT_ARTIFACT.to_string(),
version: HIP_AUDIT_REPORT_VERSION,
traces,
non_claims: vec![
"HIP audit traces bind p-adic matmul benchmark evidence to source, compiler, device, transfer, kernel-symbol, code-object metadata, fallback, CPU oracle, sparse oracle, and certificate obligations; they do not formally verify generated machine code".to_string(),
"ROCm/HIP p-adic matmul traces are local Q_5[3] 2x3x2 evidence, not portable AMD GPU or arbitrary p-adic support".to_string(),
"timing fields remain benchmark smoke evidence, not production speedup claims".to_string(),
],
};
validate_hip_audit_report(&audit)?;
Ok(audit)
}
pub fn validate_hip_audit_report(report: &HipAuditReport) -> Result<()> {
if report.artifact != HIP_AUDIT_REPORT_ARTIFACT {
return Err(Error::verification(format!(
"unexpected HIP audit artifact {}",
report.artifact
)));
}
if report.version != HIP_AUDIT_REPORT_VERSION {
return Err(Error::verification(format!(
"unsupported HIP audit version {}",
report.version
)));
}
if report.traces.is_empty() {
return Err(Error::verification("HIP audit report has no traces"));
}
if !report
.non_claims
.iter()
.any(|claim| claim.contains("do not formally verify generated machine code"))
{
return Err(Error::verification(
"HIP audit report must include the machine-code verification non-claim",
));
}
for trace in &report.traces {
validate_trace(trace)?;
}
Ok(())
}
impl HipAuditReport {
pub fn to_json(&self) -> String {
let traces = self
.traces
.iter()
.map(HipAuditTrace::to_json)
.collect::<Vec<_>>()
.join(",");
format!(
"{{\"artifact\":{},\"version\":{},\"traces\":[{}],\"non_claims\":{}}}",
json_string(&self.artifact),
self.version,
traces,
json_array(&self.non_claims)
)
}
pub fn to_markdown(&self) -> String {
let mut lines = vec![
"# HIP Proof and Audit Report".to_string(),
String::new(),
format!("artifact: {}", self.artifact),
format!("version: {}", self.version),
String::new(),
"| Workload | Backend | Status | Kernel | Compiler | Device | Symbol | Code metadata | CPU oracle | Fallback | Audit fingerprint |".to_string(),
"| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |".to_string(),
];
for trace in &self.traces {
lines.push(format!(
"| {} | {} | {} | {} | {} | {} | {} | {} | {} | {} | {} |",
md(&trace.workload),
md(&trace.backend),
md(&trace.status),
md(&trace.kernel_source_fingerprint),
md(&trace.compiler_fingerprint),
md(&trace.device_fingerprint),
md(&trace.kernel_symbol),
md(&trace.code_object_metadata_fingerprint),
trace.cpu_oracle_matches,
md(&trace.fallback_reason),
md(&trace.audit_fingerprint)
));
}
lines.push(String::new());
lines.push("## Non-Claims".to_string());
for claim in &self.non_claims {
lines.push(format!("- {claim}"));
}
lines.join("\n")
}
}
impl HipAuditTrace {
fn from_benchmark_row(row: &RocmBenchmarkRow) -> Self {
let mut trace = Self {
workload: row.workload.clone(),
domain: row.domain.clone(),
backend: row.backend.clone(),
status: row.status.clone(),
device_fingerprint: row.device_fingerprint.clone(),
kernel_source_fingerprint: row.kernel_source_fingerprint.clone(),
compiler_fingerprint: row.compiler_fingerprint.clone(),
kernel_symbol: if row.status == "passed" {
kernel_symbol_for_backend(&row.backend, &row.workload)
} else {
"not_built".to_string()
},
code_object_metadata_fingerprint: String::new(),
disassembly_metadata: disassembly_metadata_for(row.status.as_str(), &row.backend),
cpu_oracle_matches: row.cpu_oracle_matches,
fallback_reason: row.fallback_reason.clone(),
transfer_evidence: row.transfer_evidence.clone(),
launch_metadata: row.launch_metadata.clone(),
theory_constraints: theory_constraints_for(row),
obligations: obligations_for(row),
audit_fingerprint: String::new(),
};
trace.code_object_metadata_fingerprint = trace.compute_code_object_metadata_fingerprint();
trace.audit_fingerprint = trace.compute_audit_fingerprint();
trace
}
fn from_padic_stratified_benchmark_row(
row: &crate::backend::hip_padic_benchmarks::PadicStratifiedBenchmarkRow,
) -> Self {
let mut trace = Self {
workload: row.fixture.clone(),
domain: format!("padic:fixed_precision:p{}:k{}", row.prime, row.precision),
backend: row.backend.clone(),
status: row.status.clone(),
device_fingerprint: row.device_fingerprint.clone(),
kernel_source_fingerprint: row.kernel_source_fingerprint.clone(),
compiler_fingerprint: row.compiler_fingerprint.clone(),
kernel_symbol: if row.status == "passed" {
"padic_stratified_matmul_kernel".to_string()
} else {
"not_built".to_string()
},
code_object_metadata_fingerprint: String::new(),
disassembly_metadata: disassembly_metadata_for(row.status.as_str(), &row.backend),
cpu_oracle_matches: row.dense_cpu_oracle_matches
&& row.sparse_cpu_oracle_matches
&& row.certificate_coverage,
fallback_reason: row.fallback_reason.clone(),
transfer_evidence: if row.transfer_time_ns > 0 {
"host_to_device_lhs;host_to_device_rhs;device_to_host_output;device_to_host_certificates".to_string()
} else {
"no_device_transfer;cpu_dense_and_certified_sparse_oracles_required".to_string()
},
launch_metadata: if row.kernel_time_ns > 0 {
format!(
"shape={};grid=recorded_by_pilot;block=recorded_by_pilot;transfer_time_ns={};kernel_time_ns={}",
row.shape, row.transfer_time_ns, row.kernel_time_ns
)
} else {
"not_launched".to_string()
},
theory_constraints: vec![
"padic:valuation:valuation_skip_dot_product_sound_mod_pk".to_string(),
"padic:valuation:valuation_skip_matrix_output_sound_mod_pk".to_string(),
"dense_cpu_oracle_required".to_string(),
"certified_sparse_cpu_oracle_required".to_string(),
"per_output_certificate_required".to_string(),
],
obligations: vec![
format!("dense_cpu_oracle_matches={}", row.dense_cpu_oracle_matches),
format!(
"sparse_cpu_oracle_matches={}",
row.sparse_cpu_oracle_matches
),
format!("certificate_coverage={}", row.certificate_coverage),
format!("skipped_products={}", row.skipped_products),
format!("evaluated_products={}", row.evaluated_products),
format!("precision_margin_min={:?}", row.precision_margin_min),
format!("fallback={}", row.fallback_reason),
],
audit_fingerprint: String::new(),
};
trace.code_object_metadata_fingerprint = trace.compute_code_object_metadata_fingerprint();
trace.audit_fingerprint = trace.compute_audit_fingerprint();
trace
}
fn compute_code_object_metadata_fingerprint(&self) -> String {
proof_replay_artifact_digest(&format!(
"hip-code-metadata:{}:{}:{}:{}:{}:{}",
self.backend,
self.kernel_symbol,
self.kernel_source_fingerprint,
self.compiler_fingerprint,
self.device_fingerprint,
self.launch_metadata
))
}
fn compute_audit_fingerprint(&self) -> String {
proof_replay_artifact_digest(&format!(
"workload={};domain={};backend={};status={};device={};kernel={};compiler={};symbol={};code_metadata={};disassembly={};oracle={};fallback={};transfer={};launch={};theory={};obligations={}",
self.workload,
self.domain,
self.backend,
self.status,
self.device_fingerprint,
self.kernel_source_fingerprint,
self.compiler_fingerprint,
self.kernel_symbol,
self.code_object_metadata_fingerprint,
self.disassembly_metadata,
self.cpu_oracle_matches,
self.fallback_reason,
self.transfer_evidence,
self.launch_metadata,
self.theory_constraints.join("|"),
self.obligations.join("|")
))
}
fn to_json(&self) -> String {
format!(
"{{\"workload\":{},\"domain\":{},\"backend\":{},\"status\":{},\"device_fingerprint\":{},\"kernel_source_fingerprint\":{},\"compiler_fingerprint\":{},\"kernel_symbol\":{},\"code_object_metadata_fingerprint\":{},\"disassembly_metadata\":{},\"cpu_oracle_matches\":{},\"fallback_reason\":{},\"transfer_evidence\":{},\"launch_metadata\":{},\"theory_constraints\":{},\"obligations\":{},\"audit_fingerprint\":{}}}",
json_string(&self.workload),
json_string(&self.domain),
json_string(&self.backend),
json_string(&self.status),
json_string(&self.device_fingerprint),
json_string(&self.kernel_source_fingerprint),
json_string(&self.compiler_fingerprint),
json_string(&self.kernel_symbol),
json_string(&self.code_object_metadata_fingerprint),
json_string(&self.disassembly_metadata),
self.cpu_oracle_matches,
json_string(&self.fallback_reason),
json_string(&self.transfer_evidence),
json_string(&self.launch_metadata),
json_array(&self.theory_constraints),
json_array(&self.obligations),
json_string(&self.audit_fingerprint)
)
}
}
fn validate_trace(trace: &HipAuditTrace) -> Result<()> {
if !trace.backend.starts_with("rocm_hip") {
return Err(Error::verification(format!(
"HIP audit trace {} is not a ROCm/HIP backend",
trace.workload
)));
}
if trace.theory_constraints.is_empty() || trace.obligations.is_empty() {
return Err(Error::verification(format!(
"HIP audit trace {} lacks theory constraints or obligations",
trace.workload
)));
}
if trace.audit_fingerprint != trace.compute_audit_fingerprint() {
return Err(Error::verification(format!(
"HIP audit trace {} has a stale audit fingerprint",
trace.workload
)));
}
if trace.code_object_metadata_fingerprint != trace.compute_code_object_metadata_fingerprint() {
return Err(Error::verification(format!(
"HIP audit trace {} has stale code-object metadata fingerprint",
trace.workload
)));
}
match trace.status.as_str() {
"passed" => validate_executed_trace(trace),
"fallback_captured" => validate_fallback_trace(trace),
"unavailable" => validate_unavailable_trace(trace),
status => Err(Error::verification(format!(
"HIP audit trace {} has unsupported status {}",
trace.workload, status
))),
}
}
fn validate_executed_trace(trace: &HipAuditTrace) -> Result<()> {
if !trace.cpu_oracle_matches {
return Err(Error::verification(format!(
"HIP audit trace {} is missing CPU oracle equality",
trace.workload
)));
}
if !trace.device_fingerprint.starts_with("rocmhip-") {
return Err(Error::verification(format!(
"HIP audit trace {} has stale or missing ROCm device fingerprint",
trace.workload
)));
}
if !valid_kernel_source_fingerprint(&trace.kernel_source_fingerprint) {
return Err(Error::verification(format!(
"HIP audit trace {} has missing or tampered kernel source fingerprint",
trace.workload
)));
}
if !trace.compiler_fingerprint.starts_with("hipcc-") {
return Err(Error::verification(format!(
"HIP audit trace {} has missing hipcc compiler fingerprint",
trace.workload
)));
}
if trace.kernel_symbol == "unknown" || trace.kernel_symbol == "not_built" {
return Err(Error::verification(format!(
"HIP audit trace {} lacks kernel-symbol metadata",
trace.workload
)));
}
if !trace
.code_object_metadata_fingerprint
.starts_with("sha256:")
{
return Err(Error::verification(format!(
"HIP audit trace {} lacks code-object metadata fingerprint",
trace.workload
)));
}
if trace.disassembly_metadata == "missing" {
return Err(Error::verification(format!(
"HIP audit trace {} lacks disassembly metadata status",
trace.workload
)));
}
if trace.transfer_evidence.contains("no_device_transfer")
|| !trace.launch_metadata.contains("grid=")
|| !trace.launch_metadata.contains("block=")
{
return Err(Error::verification(format!(
"HIP audit trace {} lacks transfer or launch evidence",
trace.workload
)));
}
Ok(())
}
fn validate_fallback_trace(trace: &HipAuditTrace) -> Result<()> {
if !trace.cpu_oracle_matches {
return Err(Error::verification(format!(
"HIP fallback trace {} is missing CPU oracle comparison",
trace.workload
)));
}
if trace.fallback_reason == "none"
|| trace.fallback_reason.is_empty()
|| trace.launch_metadata != "not_launched"
|| !trace.transfer_evidence.contains("no_device_transfer")
{
return Err(Error::verification(format!(
"HIP fallback trace {} lacks closed fallback evidence",
trace.workload
)));
}
if !valid_kernel_source_fingerprint(&trace.kernel_source_fingerprint)
&& trace.kernel_source_fingerprint != "not_built"
{
return Err(Error::verification(format!(
"HIP fallback trace {} has missing kernel provenance",
trace.workload
)));
}
if trace.kernel_symbol != "not_built"
|| trace.disassembly_metadata != "not_built"
|| !trace
.code_object_metadata_fingerprint
.starts_with("sha256:")
{
return Err(Error::verification(format!(
"HIP fallback trace {} must record closed non-built code-object metadata",
trace.workload
)));
}
Ok(())
}
fn validate_unavailable_trace(trace: &HipAuditTrace) -> Result<()> {
if trace.fallback_reason.is_empty()
|| trace.launch_metadata != "not_launched"
|| trace.kernel_source_fingerprint != "not_built"
|| trace.kernel_symbol != "not_built"
|| trace.disassembly_metadata != "not_built"
|| !trace.transfer_evidence.contains("no_device_transfer")
{
return Err(Error::verification(format!(
"HIP unavailable trace {} lacks fail-closed evidence",
trace.workload
)));
}
Ok(())
}
fn valid_kernel_source_fingerprint(value: &str) -> bool {
value.starts_with("hip-source-")
|| value.starts_with("hip-padic-valuation-source-")
|| value.starts_with("hip-padic-stratified-matmul-source-")
|| value.starts_with("hip-sheaf-overlap-source-")
}
fn kernel_symbol_for_backend(backend: &str, workload: &str) -> String {
if backend.contains("dense_i32") {
"add_i32_kernel".to_string()
} else if backend.contains("padic_valuation") {
"padic_valuation_kernel".to_string()
} else if backend.contains("sheaf") {
"sheaf_overlap_kernel".to_string()
} else if workload.contains("padic_stratified") || backend.contains("matmul") {
"padic_stratified_matmul_kernel".to_string()
} else if backend == "rocm_hip" || backend.contains("portability") {
"not_built".to_string()
} else {
"unknown".to_string()
}
}
fn disassembly_metadata_for(status: &str, backend: &str) -> String {
match status {
"passed" => format!(
"metadata_bound:kernel_symbol={};disassembly_capture=not_required_for_nonclaim",
kernel_symbol_for_backend(backend, "")
),
"fallback_captured" | "unavailable" => "not_built".to_string(),
_ => "missing".to_string(),
}
}
fn theory_constraints_for(row: &RocmBenchmarkRow) -> Vec<String> {
if row.domain.starts_with("padic") {
vec![
"padic:valuation:valuation_skip_sound_mod_pk".to_string(),
"cpu_oracle_padic_valuation_required".to_string(),
]
} else if row.domain.starts_with("sheaf") {
vec![
"sheaf:finite_site:finite_sheaf_gluing_boundary".to_string(),
"sectiontable_cpu_obstruction_oracle_required".to_string(),
]
} else if row.domain == "integer" {
vec![
"integer_elementwise_addition_only".to_string(),
"cpu_oracle_elementwise_equality_required".to_string(),
]
} else {
vec!["hip_unavailable_no_semantic_execution".to_string()]
}
}
fn obligations_for(row: &RocmBenchmarkRow) -> Vec<String> {
vec![
format!("kernel_source={}", row.kernel_source_fingerprint),
format!("compiler={}", row.compiler_fingerprint),
format!("device={}", row.device_fingerprint),
format!("transfer={}", row.transfer_evidence),
format!("launch={}", row.launch_metadata),
format!("cpu_oracle_matches={}", row.cpu_oracle_matches),
format!("fallback={}", row.fallback_reason),
]
}
fn json_array(values: &[String]) -> String {
format!(
"[{}]",
values
.iter()
.map(|value| json_string(value))
.collect::<Vec<_>>()
.join(",")
)
}
fn json_string(value: &str) -> String {
let mut escaped = String::from("\"");
for ch in value.chars() {
match ch {
'"' => escaped.push_str("\\\""),
'\\' => escaped.push_str("\\\\"),
'\n' => escaped.push_str("\\n"),
'\r' => escaped.push_str("\\r"),
'\t' => escaped.push_str("\\t"),
ch if ch.is_control() => escaped.push_str(&format!("\\u{:04x}", ch as u32)),
ch => escaped.push(ch),
}
}
escaped.push('"');
escaped
}
fn md(value: &str) -> String {
value.replace('|', "\\|")
}