Skip to content

Commit d7d26e0

Browse files
committed
fix expected Aspen-8 compiler ISA; fix bug in json-equality comparison, and improve error output
1 parent 7a1bac4 commit d7d26e0

File tree

2 files changed

+45
-143
lines changed

2 files changed

+45
-143
lines changed

crates/lib/src/compiler/isa/mod.rs

Lines changed: 44 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ pub enum Error {
100100

101101
#[cfg(test)]
102102
mod describe_compiler_isa {
103-
use std::{convert::TryFrom, fs::read_to_string};
103+
use std::{convert::TryFrom, fs::{self, read_to_string}};
104104

105105
use float_cmp::{approx_eq, F64Margin};
106106
use qcs_api_client_openapi::models::{InstructionSetArchitecture, Node};
@@ -111,65 +111,61 @@ mod describe_compiler_isa {
111111
/// Compare two JSON values and make sure they are equivalent while allowing for some precision
112112
/// loss in numbers.
113113
///
114-
/// Return Ok if equivalent, or tuple containing the differing elements.
115-
fn json_is_equivalent<'a>(
116-
first: &'a Value,
117-
second: &'a Value,
118-
) -> Result<(), (&'a Value, &'a Value)> {
119-
let equal = match (first, second) {
120-
(Value::Number(first_num), Value::Number(second_num)) => {
121-
if !first_num.is_f64() || !second_num.is_f64() {
122-
first_num == second_num
114+
/// Panics if there is any inequality.
115+
fn assert_json_is_equivalent<'a>(
116+
expected: &'a Value,
117+
actual: &'a Value,
118+
) {
119+
assert_json_is_equivalent_inner(expected, actual, "");
120+
}
121+
122+
fn assert_json_is_equivalent_inner<'a>(
123+
expected: &'a Value,
124+
actual: &'a Value,
125+
path: &str,
126+
) {
127+
match (expected, actual) {
128+
(Value::Number(expected_num), Value::Number(actual_num)) => {
129+
if !expected_num.is_f64() || !actual_num.is_f64() {
130+
assert_eq!(expected_num, actual_num, "path '{}': non-f64 numeric inequality: expected: {}, actual: {}", path, expected_num, actual_num);
123131
} else {
124-
let first_f64 = first_num.as_f64().unwrap();
125-
let second_f64 = second_num.as_f64().unwrap();
126-
approx_eq!(
132+
let expected_f64 = expected_num.as_f64().unwrap();
133+
let actual_f64 = actual_num.as_f64().unwrap();
134+
assert!(approx_eq!(
127135
f64,
128-
first_f64,
129-
second_f64,
136+
expected_f64,
137+
actual_f64,
130138
F64Margin {
131139
ulps: 1,
132140
epsilon: 0.000_000_1
133141
}
134-
)
142+
), "path '{}': numeric inequality out of range: expected: {}, actual: {}", path, expected_f64, actual_f64);
135143
}
136144
}
137-
(Value::Object(first_map), Value::Object(second_map)) => {
138-
let mut found_missing = false;
139-
for (key, first_value) in first_map {
140-
let second_value = second_map.get(key);
141-
if second_value.is_none() {
142-
found_missing = true;
145+
(Value::Object(expected_map), Value::Object(actual_map)) => {
146+
147+
let mut expected_key_missing_from_actual = None;
148+
for (key, expected_value) in expected_map {
149+
let actual_value = actual_map.get(key);
150+
if actual_value.is_none() {
151+
expected_key_missing_from_actual = Some(key);
143152
break;
144153
}
145-
let cmp = json_is_equivalent(first_value, second_value.unwrap());
146-
cmp?;
154+
assert_json_is_equivalent_inner(expected_value, actual_value.unwrap(), &(format!("{}.{}", path, key)));
155+
}
156+
assert!(expected_key_missing_from_actual.is_none(), "path '{}': expected map has key not in actual map: {}", path, expected_key_missing_from_actual.unwrap());
157+
for (key, _) in actual_map {
158+
assert!(expected_map.contains_key(key), "path '{}': actual map has key not in expected map: {}", path, key);
147159
}
148-
!found_missing
149-
}
150-
(Value::Array(first_array), Value::Array(second_array))
151-
if first_array.len() != second_array.len() =>
152-
{
153-
false
154160
}
155-
(Value::Array(first_array), Value::Array(second_array)) => {
156-
let error = first_array.iter().zip(second_array).find(
157-
|(first_value, second_value)| -> bool {
158-
json_is_equivalent(first_value, second_value).is_err()
159-
},
160-
);
161-
if let Some(values) = error {
162-
return Err(values);
161+
(Value::Array(expected_array), Value::Array(actual_array)) => {
162+
assert!(expected_array.len() == actual_array.len(), "expected array has more elements than actual array");
163+
for (index, (expected_value, actual_value)) in expected_array.iter().zip(actual_array).enumerate() {
164+
assert_json_is_equivalent_inner(expected_value, actual_value, &(format!("{}[{}]", path, index)));
163165
}
164-
true
165166
}
166-
(first, second) => first == second,
167+
(expected, actual) => assert_eq!(expected, actual, "path '{}': inequality: expected: {:?}, actual: {:?}", path, expected, actual),
167168
};
168-
if equal {
169-
Ok(())
170-
} else {
171-
Err((first, second))
172-
}
173169
}
174170

175171
#[test]
@@ -197,8 +193,8 @@ mod describe_compiler_isa {
197193

198194
let serialized =
199195
serde_json::to_value(compiler_isa).expect("Unable to serialize CompilerIsa");
200-
let result = json_is_equivalent(&serialized, &expected);
201-
result.expect("JSON was not equivalent");
196+
197+
assert_json_is_equivalent(&expected, &serialized);
202198
}
203199

204200
#[test]
@@ -242,7 +238,6 @@ mod describe_compiler_isa {
242238
let serialized_without_dead = serde_json::to_value(compiler_isa_excluding_dead)
243239
.expect("Unable to serialize CompilerIsa");
244240

245-
let result = json_is_equivalent(&serialized, &serialized_without_dead);
246-
result.expect("JSON was not equivalent");
241+
assert_json_is_equivalent(&serialized, &serialized_without_dead);
247242
}
248243
}

crates/lib/tests/compiler-isa-Aspen-8.json

Lines changed: 1 addition & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -186,11 +186,6 @@
186186
],
187187
"id": 1
188188
},
189-
"10": {
190-
"dead": true,
191-
"gates": [],
192-
"id": 10
193-
},
194189
"11": {
195190
"gates": [
196191
{
@@ -1865,11 +1860,6 @@
18651860
],
18661861
"id": 30
18671862
},
1868-
"31": {
1869-
"dead": true,
1870-
"gates": [],
1871-
"id": 31
1872-
},
18731863
"32": {
18741864
"gates": [
18751865
{
@@ -2802,14 +2792,6 @@
28022792
}
28032793
},
28042794
"2Q": {
2805-
"0-1": {
2806-
"dead": true,
2807-
"gates": [],
2808-
"ids": [
2809-
0,
2810-
1
2811-
]
2812-
},
28132795
"0-7": {
28142796
"gates": [
28152797
{
@@ -2882,22 +2864,6 @@
28822864
2
28832865
]
28842866
},
2885-
"10-11": {
2886-
"dead": true,
2887-
"gates": [],
2888-
"ids": [
2889-
10,
2890-
11
2891-
]
2892-
},
2893-
"10-17": {
2894-
"dead": true,
2895-
"gates": [],
2896-
"ids": [
2897-
10,
2898-
17
2899-
]
2900-
},
29012867
"11-12": {
29022868
"gates": [
29032869
{
@@ -2994,14 +2960,6 @@
29942960
13
29952961
]
29962962
},
2997-
"12-25": {
2998-
"dead": true,
2999-
"gates": [],
3000-
"ids": [
3001-
12,
3002-
25
3003-
]
3004-
},
30052963
"13-14": {
30062964
"gates": [
30072965
{
@@ -3522,25 +3480,6 @@
35223480
4
35233481
]
35243482
},
3525-
"30-31": {
3526-
"gates": [
3527-
{
3528-
"arguments": [
3529-
"_",
3530-
"_"
3531-
],
3532-
"duration": 200.0,
3533-
"fidelity": 0.962505082735891,
3534-
"operator": "CZ",
3535-
"operator_type": "gate",
3536-
"parameters": []
3537-
}
3538-
],
3539-
"ids": [
3540-
30,
3541-
31
3542-
]
3543-
},
35443483
"30-37": {
35453484
"gates": [
35463485
{
@@ -3560,38 +3499,6 @@
35603499
37
35613500
]
35623501
},
3563-
"31-32": {
3564-
"gates": [
3565-
{
3566-
"arguments": [
3567-
"_",
3568-
"_"
3569-
],
3570-
"duration": 200.0,
3571-
"fidelity": 0.984330374008766,
3572-
"operator": "CZ",
3573-
"operator_type": "gate",
3574-
"parameters": []
3575-
},
3576-
{
3577-
"arguments": [
3578-
"_",
3579-
"_"
3580-
],
3581-
"duration": 200.0,
3582-
"fidelity": 0.970416051000658,
3583-
"operator": "XY",
3584-
"operator_type": "gate",
3585-
"parameters": [
3586-
"theta"
3587-
]
3588-
}
3589-
],
3590-
"ids": [
3591-
31,
3592-
32
3593-
]
3594-
},
35953502
"32-33": {
35963503
"gates": [
35973504
{
@@ -3849,4 +3756,4 @@
38493756
]
38503757
}
38513758
}
3852-
}
3759+
}

0 commit comments

Comments
 (0)