Skip to content

Instantly share code, notes, and snippets.

@mindon
Last active October 11, 2022 03:26
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mindon/55de83a032412ae48b569536efa94b06 to your computer and use it in GitHub Desktop.
Save mindon/55de83a032412ae48b569536efa94b06 to your computer and use it in GitHub Desktop.
qconvert typescript for deno, a Quantum Computing Language Converter
// 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