Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DumpMachine output in Python and console should be empty with no qubits allocated #1984

Merged
merged 1 commit into from
Oct 31, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions compiler/qsc/src/interpret/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -267,7 +267,7 @@ mod given_interpreter {
let (result, output) = line(&mut interpreter, "import Std.Diagnostics.*;");
is_only_value(&result, &output, &Value::unit());
let (result, output) = line(&mut interpreter, "DumpMachine()");
is_unit_with_output(&result, &output, "STATE:\n|0⟩: 1+0i");
is_unit_with_output(&result, &output, "STATE:\nNo qubits allocated");
}

#[test]
Expand All @@ -277,7 +277,7 @@ mod given_interpreter {
&mut interpreter,
"open Microsoft.Quantum.Diagnostics; DumpMachine()",
);
is_unit_with_output(&result, &output, "STATE:\n|0⟩: 1+0i");
is_unit_with_output(&result, &output, "STATE:\nNo qubits allocated");
}

#[test]
Expand Down Expand Up @@ -332,7 +332,7 @@ mod given_interpreter {
let (result, output) = line(&mut interpreter, "import Std.Diagnostics.*;");
is_only_value(&result, &output, &Value::unit());
let (result, output) = line(&mut interpreter, "DumpMachine()");
is_unit_with_output(&result, &output, "STATE:\n|0⟩: 1+0i");
is_unit_with_output(&result, &output, "STATE:\nNo qubits allocated");
let (result, output) = line(&mut interpreter, "use (q0, qs) = (Qubit(), Qubit[3]);");
is_only_value(&result, &output, &Value::unit());
let (result, output) = line(&mut interpreter, "DumpMachine()");
Expand Down
2 changes: 1 addition & 1 deletion compiler/qsc_eval/src/intrinsic/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -294,7 +294,7 @@ fn dump_machine() {
"Microsoft.Quantum.Diagnostics.DumpMachine()",
&expect![[r#"
STATE:
|0⟩: 1.0000+0.0000𝑖
No qubits allocated
"#]],
);
}
Expand Down
40 changes: 24 additions & 16 deletions compiler/qsc_eval/src/output.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,14 +40,18 @@ impl<'a> GenericReceiver<'a> {
impl<'a> Receiver for GenericReceiver<'a> {
fn state(&mut self, state: Vec<(BigUint, Complex64)>, qubit_count: usize) -> Result<(), Error> {
writeln!(self.writer, "STATE:").map_err(|_| Error)?;
for (id, state) in state {
writeln!(
self.writer,
"{}: {}",
format_state_id(&id, qubit_count),
fmt_complex(&state),
)
.map_err(|_| Error)?;
if qubit_count > 0 {
for (id, state) in state {
writeln!(
self.writer,
"{}: {}",
format_state_id(&id, qubit_count),
fmt_complex(&state),
)
.map_err(|_| Error)?;
}
} else {
writeln!(self.writer, "No qubits allocated").map_err(|_| Error)?;
}
Ok(())
}
Expand Down Expand Up @@ -88,14 +92,18 @@ impl<'a> CursorReceiver<'a> {
impl<'a> Receiver for CursorReceiver<'a> {
fn state(&mut self, state: Vec<(BigUint, Complex64)>, qubit_count: usize) -> Result<(), Error> {
writeln!(self.cursor, "STATE:").map_err(|_| Error)?;
for (id, state) in state {
writeln!(
self.cursor,
"{}: {}",
format_state_id(&id, qubit_count),
state
)
.map_err(|_| Error)?;
if qubit_count > 0 {
for (id, state) in state {
writeln!(
self.cursor,
"{}: {}",
format_state_id(&id, qubit_count),
state
)
.map_err(|_| Error)?;
}
} else {
writeln!(self.cursor, "No qubits allocated").map_err(|_| Error)?;
}
Ok(())
}
Expand Down
2 changes: 1 addition & 1 deletion compiler/qsc_eval/src/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -350,7 +350,7 @@ fn get_terms_for_state(state: &Vec<(BigUint, Complex64)>) -> Vec<Term> {
/// if the formula consists of more than 16 terms or if more than two coefficients are not recognized.
#[must_use]
pub fn get_state_latex(state: &Vec<(BigUint, Complex64)>, qubit_count: usize) -> Option<String> {
if state.len() > 16 {
if state.len() > 16 || qubit_count == 0 {
return None;
}

Expand Down
1 change: 1 addition & 0 deletions npm/qsharp/src/compiler/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ interface DumpMsg {
type: "DumpMachine";
state: Dump;
stateLatex: string | null;
qubitCount: number;
}

interface MatrixMsg {
Expand Down
1 change: 1 addition & 0 deletions npm/qsharp/src/compiler/compiler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -292,6 +292,7 @@ export function onCompilerEvent(msg: string, eventTarget: IQscEventTarget) {
qscEvent = makeEvent("DumpMachine", {
state: qscMsg.state,
stateLatex: qscMsg.stateLatex,
qubitCount: qscMsg.qubitCount,
});
break;
case "Result":
Expand Down
12 changes: 10 additions & 2 deletions npm/qsharp/src/compiler/events.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,10 @@ import { IServiceEventTarget } from "../workers/common.js";
// Create strongly typed compiler events
export type QscEventData =
| { type: "Message"; detail: string }
| { type: "DumpMachine"; detail: { state: Dump; stateLatex: string | null } }
| {
type: "DumpMachine";
detail: { state: Dump; stateLatex: string | null; qubitCount: number };
}
billti marked this conversation as resolved.
Show resolved Hide resolved
| { type: "Matrix"; detail: { matrix: number[][][]; matrixLatex: string } }
| { type: "Result"; detail: Result };

Expand Down Expand Up @@ -108,14 +111,19 @@ export class QscEventTarget implements IQscEventTarget {
this.queueUiRefresh();
}

private onDumpMachine(detail: { state: Dump; stateLatex: string | null }) {
private onDumpMachine(detail: {
state: Dump;
stateLatex: string | null;
qubitCount: number;
}) {
this.ensureActiveShot();

const shotIdx = this.results.length - 1;
this.results[shotIdx].events.push({
type: "DumpMachine",
state: detail.state,
stateLatex: detail.stateLatex,
qubitCount: detail.qubitCount,
});

this.queueUiRefresh();
Expand Down
1 change: 1 addition & 0 deletions npm/qsharp/src/debug-service/debug-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,7 @@ export function onCompilerEvent(msg: string, eventTarget: IQscEventTarget) {
qscEvent = makeEvent("DumpMachine", {
state: qscMsg.state,
stateLatex: qscMsg.stateLatex,
qubitCount: qscMsg.qubitCount,
});
break;
case "Result":
Expand Down
77 changes: 44 additions & 33 deletions pip/src/displayable_output.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,42 +18,53 @@ pub struct DisplayableMatrix(pub Vec<Vec<Complex64>>);

impl DisplayableState {
pub fn to_plain(&self) -> String {
format!(
"STATE:{}",
self.0
.iter()
.fold(String::new(), |mut output, (id, state)| {
let _ = write!(
output,
"\n{}: {}",
format_state_id(id, self.1),
fmt_complex(state)
);
output
})
)
if self.1 > 0 {
format!(
"STATE:{}",
self.0
.iter()
.fold(String::new(), |mut output, (id, state)| {
let _ = write!(
output,
"\n{}: {}",
format_state_id(id, self.1),
fmt_complex(state)
);
output
})
)
} else {
"STATE:\nNo qubits allocated".to_string()
}
}

pub fn to_html(&self) -> String {
format!(
include_str!("state_header_template.html"),
self.0
.iter()
.fold(String::new(), |mut output, (id, state)| {
let amplitude = state.abs().powi(2) * 100.0;
let _ = write!(
output,
include_str!("state_row_template.html"),
fmt_basis_state_label(id, self.1),
fmt_complex(state),
amplitude,
amplitude,
get_phase(state),
get_phase(state)
);
output
})
)
if self.1 > 0 {
format!(
include_str!("state_header_template.html"),
self.0
.iter()
.fold(String::new(), |mut output, (id, state)| {
let amplitude = state.abs().powi(2) * 100.0;
let _ = write!(
output,
include_str!("state_row_template.html"),
fmt_basis_state_label(id, self.1),
fmt_complex(state),
amplitude,
amplitude,
get_phase(state),
get_phase(state)
);
output
})
)
} else {
format!(
include_str!("state_header_template.html"),
"<tr><td>No qubits allocated</td></tr>".to_string()
)
}
}

pub fn to_latex(&self) -> Option<String> {
Expand Down
4 changes: 2 additions & 2 deletions samples_test/src/tests/language.rs
Original file line number Diff line number Diff line change
Expand Up @@ -214,11 +214,11 @@ pub const LOGICALOPERATORS_EXPECT: Expect = expect!["()"];
pub const LOGICALOPERATORS_EXPECT_DEBUG: Expect = expect!["()"];
pub const NAMESPACES_EXPECT: Expect = expect![[r#"
STATE:
|0⟩: 1.0000+0.0000𝑖
No qubits allocated
[]"#]];
pub const NAMESPACES_EXPECT_DEBUG: Expect = expect![[r#"
STATE:
|0⟩: 1.0000+0.0000𝑖
No qubits allocated
[]"#]];
pub const OPERATIONS_EXPECT: Expect = expect![[r#"
Measurement result: Zero
Expand Down
20 changes: 12 additions & 8 deletions vscode/src/debugger/output.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ export function createDebugConsoleEventTarget(out: (message: string) => void) {
}

const stateTable = evt.detail.state;
const qubitCount = evt.detail.qubitCount;
const basisStates = Object.keys(stateTable);
const basisColumnWidth = Math.max(
basisStates[0]?.length ?? 0,
Expand All @@ -44,16 +45,19 @@ export function createDebugConsoleEventTarget(out: (message: string) => void) {
" ".padEnd(basisColumnWidth, "-") +
"-------------------------------------------\n";

for (const row of basisStates) {
const [real, imag] = stateTable[row];
const basis = row.padStart(basisColumnWidth);
const amplitude = formatComplex(real, imag).padStart(16);
const probability = formatProbabilityPercent(real, imag).padStart(11);
const phase = formatPhase(real, imag).padStart(8);
if (qubitCount === 0) {
out_str += " No qubits allocated\n";
} else {
for (const row of basisStates) {
const [real, imag] = stateTable[row];
const basis = row.padStart(basisColumnWidth);
const amplitude = formatComplex(real, imag).padStart(16);
const probability = formatProbabilityPercent(real, imag).padStart(11);
const phase = formatPhase(real, imag).padStart(8);

out_str += ` ${basis} | ${amplitude} | ${probability} | ${phase}\n`;
out_str += ` ${basis} | ${amplitude} | ${probability} | ${phase}\n`;
}
}

out(out_str);
});

Expand Down
7 changes: 5 additions & 2 deletions wasm/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -263,8 +263,11 @@ where

let json_latex = serde_json::to_string(&get_state_latex(&state, qubit_count))
.expect("serialization should succeed");
write!(dump_json, r#" "stateLatex": {json_latex} }} "#)
.expect("writing to string should succeed");
write!(
dump_json,
r#" "stateLatex": {json_latex}, "qubitCount": {qubit_count} }} "#
)
.expect("writing to string should succeed");
(self.event_cb)(&dump_json);
Ok(())
}
Expand Down
Loading