hitachi_run/
hitachi_run.rs1use ferrotherm::fabric::Device;
5use ferrotherm::ftp::Program;
6use ferrotherm::schedule::Schedule;
7use ferrotherm_cloud::hitachi::{Hitachi, Machine};
8
9fn main() {
10 let mut d = match Hitachi::from_env(Machine::Asic) {
11 Ok(d) => d,
12 Err(e) => { eprintln!("{e}"); return; }
13 };
14 let f = d.fabric();
15 println!("fabric {} | {:?} | {} sites | degree {} | coupling {:?}",
16 f.name, f.topology, f.max_spins.unwrap(), f.max_degree.unwrap(), f.coupling_precision);
17
18 let side = Machine::Asic.side();
20 let mut src = format!("ftp 1\nname acw-4x4-antiferro\nspins {}\n", 3 * side + 4);
21 let mut edges = 0;
22 for y in 0..4usize {
23 for x in 0..4usize {
24 let i = y * side + x;
25 if x + 1 < 4 { src.push_str(&format!("factor -1 {i} {}\n", i + 1)); edges += 1; }
26 if y + 1 < 4 { src.push_str(&format!("factor -1 {i} {}\n", i + side)); edges += 1; }
27 }
28 }
29 let p = Program::from_ftp(&src).expect("program");
30 println!("program {} spins declared, {edges} couplings, digest {:016x}", p.spins, p.digest());
31
32 let bad = d.program(&p);
33 if !bad.is_empty() {
34 for u in &bad { println!("REFUSED: {u}"); }
35 return;
36 }
37
38 match d.run(&Schedule::geometric(0.1, 10.0, 20, 50), 1) {
39 Err(e) => println!("run failed: {e}"),
40 Ok(state) => {
41 let g = p.to_graph().unwrap();
42 println!("machine energy (their sign) {:?}", d.last_energies);
43 println!("execution {:.3} ms on the ASIC", d.last_execution_ns as f64 / 1e6);
44 println!("our energy {}", g.energy(&state));
45 let ok = (0..4).all(|y| (0..4).all(|x| {
46 let i = y * side + x;
47 state[i] == if (x + y) % 2 == 0 { state[0] } else { -state[0] }
48 }));
49 println!("checkerboard {}", if ok { "yes - every bond satisfied" } else { "no" });
50 println!("ledger {} node updates", d.ledger().samples);
51 }
52 }
53}