Last active
October 11, 2022 03:26
-
-
Save mindon/55de83a032412ae48b569536efa94b06 to your computer and use it in GitHub Desktop.
qconvert typescript for deno, a Quantum Computing Language Converter
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// qconvert for deno | |
// updated: 2022-10-11, Mindon<mindon@live.com> | |
// e.g. `deno run --allow-read --allow-write --unstable qconvert.ts -i hello.qasm -s qasm -o hello.quil -t quil` | |
// original: https://github.com/quantastica/qconvert-js | |
import { default as QuantumCircuit } from "npm:quantum-circuit"; | |
import { parse } from "https://deno.land/std/flags/mod.ts"; | |
import { exists } from "https://deno.land/std/fs/mod.ts"; | |
import { assert } from "https://deno.land/std/testing/asserts.ts"; | |
const sourceSupports = [ | |
"qasm", | |
"quil", | |
"qobj", | |
"quantum-circuit", | |
"toaster", | |
] as const; | |
const targetSupports = [ | |
"qiskit", | |
"qasm", | |
"qobj", | |
"quil", | |
"pyquil", | |
"braket", | |
"cirq", | |
"tfq", | |
"qsharp", | |
"quest", | |
"js", | |
"quantum-circuit", | |
"toaster", | |
"svg", | |
"svg-inline", | |
] as const; | |
interface Options { | |
source: (typeof sourceSupports)[number]; | |
target: (typeof targetSupports)[number]; | |
jupyter?: boolean; // (for qiskit, pyquil, braket, cirq, tfq, qsharp, and js only) | |
} | |
const jpy = "qiskit, pyquil, braket, cirq, tfq, qsharp, js".split(","); | |
function transform(circuit: QuantumCircuit, args: Options): string { | |
const { target } = args; | |
assert( | |
targetSupports.includes(target), | |
`unknown target format "${target}", supports:\n${ | |
targetSupports.join(" | ") | |
}`, | |
); | |
const jupyter = !!args.jupyter; | |
if (jupyter) { | |
assert(jpy.indexOf(target) >= 0); | |
} | |
switch (target) { | |
case "qiskit": | |
return circuit.exportQiskit("", false, null, null, null, null, jupyter); | |
case "qasm": | |
return circuit.exportQASM(); | |
case "qobj": | |
return JSON.stringify(circuit.exportQobj()); | |
case "quil": | |
return circuit.exportQuil(); | |
case "pyquil": | |
return circuit.exportPyquil("", false, null, null, null, null, jupyter); | |
case "braket": | |
return circuit.exportBraket("", false, null, null, jupyter); | |
case "cirq": | |
return circuit.exportCirq("", false, null, null, jupyter); | |
case "tfq": | |
return circuit.exportTFQ("", false, null, null, jupyter); | |
case "qsharp": | |
return circuit.exportQSharp("", false, null, null, jupyter); | |
case "js": | |
return circuit.exportJavaScript("", false, null, jupyter); | |
case "quest": | |
return circuit.exportQuEST("", false, null, null); | |
case "quantum-circuit": | |
return JSON.stringify(circuit.save()); | |
case "toaster": | |
return JSON.stringify(circuit.exportRaw()); | |
case "svg": | |
return circuit.exportSVG(false); | |
case "svg-inline": | |
return circuit.exportSVG(true); | |
} | |
} | |
function convert(code: string, args: Options): Promise<string | number> { | |
const { source } = args; | |
assert( | |
sourceSupports.includes(source), | |
`unknown source format "${source}", supports:\n${ | |
sourceSupports.join(" | ") | |
}`, | |
); | |
const circuit = new QuantumCircuit(); | |
return new Promise((resovle, reject) => { | |
let inputJson = null; | |
switch (source) { | |
case "qasm": { | |
return circuit.importQASM(code, (errors) => { | |
if (errors && errors.length) { | |
reject(errors); | |
return; | |
} | |
resovle(transform(circuit, args)); | |
}); | |
} | |
case "quil": { | |
return circuit.importQuil(code, function (errors) { | |
if (errors && errors.length) { | |
reject(errors); | |
return; | |
} | |
resovle(transform(circuit, args)); | |
}); | |
} | |
case "qobj": { | |
inputJson = JSON.parse(code); | |
circuit.importQobj(inputJson, (errors) => { | |
if (errors && errors.length) { | |
reject(errors); | |
return; | |
} | |
resovle(transform(circuit, args)); | |
}); | |
return; | |
} | |
case "quantum-circuit": { | |
inputJson = JSON.parse(code); | |
circuit.load(inputJson); | |
resovle(transform(circuit, args)); | |
return; | |
} | |
case "toaster": { | |
inputJson = JSON.parse(code); | |
circuit.importRaw(inputJson, function (errors) { | |
if (errors && errors.length) { | |
reject(errors); | |
return; | |
} | |
resovle(transform(circuit, args)); | |
}); | |
return; | |
} | |
} | |
}); | |
} | |
const args = parse(Deno.args, { | |
boolean: ["jupyter", "j", "overwrite", "w"], | |
string: ["input", "i", "source", "s", "output", "o", "target", "t"], | |
default: { | |
j: false, | |
w: false, | |
s: "qasm", | |
t: "qiskit", | |
}, | |
}); | |
let code = `OPENQASM 2.0; | |
include "qelib1.inc"; | |
qreg q[4]; | |
creg c1[1]; | |
h q[0]; | |
h q[1]; | |
rx (0) q[3]; | |
r2 q[0]; | |
u1 (0) q[1]; | |
r8 q[2]; | |
srndg q[0]; | |
zz (0) q[1], q[3]; | |
r2 q[1]; | |
crz (0) q[2], q[1]; | |
t q[0]; | |
reset q[1]; | |
r2 q[2]; | |
`; | |
const { s, t, j, w, i, o } = args; | |
const { | |
source = s, | |
target = t, | |
jupyter = j, | |
overwrite = w, | |
input = i, | |
output = o, | |
} = args; | |
const options = { | |
source, | |
target, | |
jupyter: jupyter || j, | |
}; | |
if (input) { | |
assert(await exists(input), `input file "${input}" not found`); | |
console.log(`reading from "${input}"...`); | |
code = await Deno.readTextFile(input); | |
} | |
const result = await convert( | |
code, | |
options, | |
); | |
if (!output) { | |
console.log(result); | |
Deno.exit(0); | |
} | |
assert( | |
overwrite || w || !await exists(output), | |
`output file "${output}" already exists`, | |
); | |
console.log(`writing to "${output}"`); | |
await Deno.writeTextFile(output, result); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment