On the device generation whose vector engine multiplies 23-bit numbers (PCI 1e52:b140), a second dataflow member, dataflow-1e52-b140-vector, runs the gate's arithmetic on that engine, 32 lanes at a time, on 32 compute tiles. - Each tile's first core writes the unpacker's and the packer's configuration, then hands the tile its instructions inline (a word with low bits other than 0b11 in its own instruction stream): the unpacker copies the pairs' columns into the destination registers as 32-bit integers, the vector engine forms each pair's four rows, the packer copies them back, and the core signals when the packer is done. - Exact arithmetic: each operand split into 23 and 9 bits; four partial products give the unsigned high word, corrected for sign to P_hi, and the bits of the low word the rounding reaches; fx = P_hi * 2^(32-s) + t, held as 30 low bits and the rest; each row adds or subtracts its terms with a carry after each. The three mutants are the other members'. - quantum_fabric::tensix: the instructions used, transcribed from the device simulator's own table; CI checks the transcription against it. quantum_fabric::vector_engine builds the programs (rows and probe); the assembler check covers them (14 programs, identical words). - A pass is sized to its share of the pairs in steps of 64 lanes: one iteration covers the even or the odd columns of four destination rows, so two cover the next 64 pairs in order. Measured on the simulator, built from source: 66020 probe pairs agree, 2000 kernel cases match run_words, all four pinned certificates, circuits up to 20 qubits match native, 3 of 3 mutants killed; the instruction table matches for all 20 instructions; the other generation's cores member is unchanged (9 of 9). Co-Authored-By: Claude Opus 5.5 <[email protected]>
43 lines
2.2 KiB
Rust
43 lines
2.2 KiB
Rust
//! Writes the dataflow member's RV32IM programs, exactly as the device runs
|
|
//! them (conforming and mutants), as assembly listings and as the machine words
|
|
//! this crate encodes, so an independent assembler can be checked against the
|
|
//! encoder:
|
|
//!
|
|
//! ```text
|
|
//! cargo run --example rv32_listing --features quantum_fabric_dataflow -- <dir>
|
|
//! ```
|
|
//!
|
|
//! In `<dir>`, for each program `<name>`: `<name>.s` (the listing, with a
|
|
//! `.text` header) and `<name>.bin` (the words, little-endian).
|
|
use wai_quantum::quantum_fabric::vector_engine::{self, Constants};
|
|
use wai_quantum::quantum_fabric_dataflow::{Variant, programs};
|
|
|
|
fn main() {
|
|
let dir = std::path::PathBuf::from(std::env::args().nth(1).expect("an output directory"));
|
|
std::fs::create_dir_all(&dir).expect("the directory");
|
|
// The programs the device runs: the rows and probe programs of the
|
|
// conforming kernel and of each mutant (M3's probe is the conforming one).
|
|
let mut all = Vec::new();
|
|
for (tag, v) in [("", Variant::Conforming), ("_m1", Variant::M1), ("_m2", Variant::M2), ("_m3", Variant::M3)] {
|
|
let (rows, probe) = programs(v);
|
|
all.push((format!("rows{tag}"), rows));
|
|
if v != Variant::M3 {
|
|
all.push((format!("probe{tag}"), probe));
|
|
}
|
|
}
|
|
// The vector engine's, over a full pass, with a sample gate's entries.
|
|
let m = [0x2000_0000, -0x2000_0000, 0x1234_5678, -0x0765_4321, 1, -1, i32::MAX, i32::MIN];
|
|
for (tag, v) in [("", Variant::Conforming), ("_m1", Variant::M1), ("_m2", Variant::M2), ("_m3", Variant::M3)] {
|
|
let (rnd, shift, last_add) = v.constants();
|
|
let c = Constants { round_bit: rnd.trailing_zeros(), shift, last_add };
|
|
all.push((format!("vector_rows{tag}"), vector_engine::rows_program(&m, c, 16)));
|
|
if v != Variant::M3 {
|
|
all.push((format!("vector_probe{tag}"), vector_engine::probe_program(c, 16)));
|
|
}
|
|
}
|
|
for (name, (words, text)) in all {
|
|
std::fs::write(dir.join(format!("{name}.s")), format!(".text\n.option norvc\n{text}")).expect("the listing");
|
|
std::fs::write(dir.join(format!("{name}.bin")), words.iter().flat_map(|w| w.to_le_bytes()).collect::<Vec<u8>>()).expect("the words");
|
|
println!("{name}: {} words", words.len());
|
|
}
|
|
}
|