Skip to content

Commit

Permalink
Merge pull request #58 from DiCarloLab-Delft/cclight_eqasm_compiler_r…
Browse files Browse the repository at this point in the history
…esource_constraints

Cclight eqasm compiler resource constraints
  • Loading branch information
imranashraf committed Sep 25, 2017
2 parents 6d47925 + 588d107 commit 2e55705
Show file tree
Hide file tree
Showing 22 changed files with 1,412 additions and 279 deletions.
47 changes: 47 additions & 0 deletions configuration_specification.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,53 @@ OpenQL supports the following instructions
- `measure`
+ no arguments

## CC-Light platform configuration
The configuration file speficies the resources available in the target platforms and the topology.

### "resources" entry
These resources can be qubits, waveform generators, measurement units and possible edges for 2-qubit operations. This information is used to model these resources in OpenQL to perform resource-constraint scheduling. An example entry of a resource `meas_units` is shown below:

"meas_units" :
{
"count": 2,
"connection_map":
{
"0" : [0, 2, 3, 5, 6],
"1" : [1, 4]
}
}
where
- `count` is the number of `meas_units` resources available in the platform, which in the above example is 2.
- `connection_map` specifies how each `meas_unit` is connected to the qubits. For example the first instance of `meas_units` is connected to qubit numbers 0, 2, 3, 5, 6.

Another less clear example is the following `edges` resources:

"edges":
{
"count": 8,
"connection_map":
{
"0": [2],
"1": [3],
"2": [0],
"3": [1],
"4": [6],
"5": [7],
"6": [4],
"7": [5]
}
}

which specifies the 8 edges in ccLight platform. `connection_map` specifies, for instance that edge 0 is connected to edge 2. The constraint which is derived from this information is that, if there is an operation on edge 0, it is not possible to use edge 2 in a 2-qubit operation unless edge 0 is free. Similar constraints are deduced for rest of 7 the edges.

### topology
This section specifies:
- grid `x_size` and `y_size`
- `qubits` definition which maps qubit ids to qubit `x` and `y` coordinates on the grid
- `edges` definition which maps edge ids to edge `src` and `dst` qubits


## CC-Light instuction configuration
Every quantum operation (QISA instruction) is translated into one or multiple microinstructions. For the first release of CC-Light, only one microinstruction is supported. It should contain the following information:

Expand Down
70 changes: 70 additions & 0 deletions openql/CCL_platform.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
{
"platform": "ccLight007",
"resources":
{
"qubits":
{
"count": 7
},
"qwgs" :
{
"count": 3,
"connection_map":
{
"0" : [0, 1],
"1" : [2, 3, 4],
"2" : [5, 6]
}
},
"meas_units" :
{
"count": 2,
"connection_map":
{
"0" : [0, 2, 3, 5, 6],
"1" : [1, 4]
}
},
"edges":
{
"count": 8,
"connection_map":
{
"0": [2],
"1": [3],
"2": [0],
"3": [1],
"4": [6],
"5": [7],
"6": [4],
"7": [5]
}
}
},
"topology" :
{
"x_size": 5,
"y_size": 3,
"qubits":
[
{ "id": 0, "x": 1, "y": 2 },
{ "id": 1, "x": 3, "y": 2 },
{ "id": 2, "x": 0, "y": 1 },
{ "id": 3, "x": 2, "y": 1 },
{ "id": 4, "x": 4, "y": 1 },
{ "id": 5, "x": 1, "y": 0 },
{ "id": 6, "x": 3, "y": 0 }
],
"edges":
[
{ "id": 0, "src": 2, "dst": 0 },
{ "id": 1, "src": 0, "dst": 3 },
{ "id": 2, "src": 3, "dst": 1 },
{ "id": 3, "src": 1, "dst": 4 },
{ "id": 4, "src": 2, "dst": 5 },
{ "id": 5, "src": 5, "dst": 3 },
{ "id": 6, "src": 3, "dst": 6 },
{ "id": 7, "src": 6, "dst": 4 }
]
}
}
18 changes: 9 additions & 9 deletions openql/quick_feature_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -22,38 +22,38 @@ int main(int argc, char ** argv)


// create platform
ql::quantum_platform starmon("starmon","../tests/test_cfg_cbox.json");
ql::quantum_platform platf("seven_qubits_chip","../tests/hardware_config_cc_light.json");

// print info
starmon.print_info();
// platf.print_info();

// set platform
ql::set_platform(starmon);
ql::set_platform(platf);

// create program
ql::quantum_program prog("prog", 2, starmon);
ql::quantum_program prog("aProgram", 7, platf);
prog.set_sweep_points(sweep_points, num_circuits);

ql::quantum_kernel k("custom_gate_test",starmon);
ql::quantum_kernel k("aKernel",platf);

// print user-defined instructions (qasm/microcode)
k.print_gates_definition();
// k.print_gates_definition();

// create kernel
k.prepz(0);
k.x(0);
k.gate("rx180", 0); // custom gate
k.gate("rx90", 0); // custom gate
k.measure(0);
prog.add(k);

// compile the program
prog.compile( /*verbose*/ 1 );
prog.compile( /*optimize*/ false, /*verbose*/ true );

// print qasm
println(prog.qasm());

// print micro code
println(prog.microcode());
// println(prog.microcode());

return 0;
}
78 changes: 8 additions & 70 deletions openql/quick_feature_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,16 @@
output_dir = os.path.join(curdir, 'test_output')
ql.set_output_dir(output_dir)

# two qubit mask generation test
def test_smit():
# You can specify a config location, here we use a default config
def test():
config_fn = os.path.join(curdir, '../tests/hardware_config_cc_light.json')
platform = ql.Platform('seven_qubits_chip', config_fn)
sweep_points = [1,2]
num_circuits = 1
num_qubits = 7
p = ql.Program('my_program', num_qubits, platform)
p = ql.Program('aProgram', num_qubits, platform)
p.set_sweep_points(sweep_points, num_circuits)

# populate kernel using default gates
k = ql.Kernel('first_kernel', platform)
k = ql.Kernel('aKernel', platform)

k.prepz(0)
k.prepz(1)
Expand All @@ -28,9 +25,9 @@ def test_smit():
k.hadamard(1)
k.x(2)
k.x(3)
k.cnot(2,0)
k.cnot(2,0)
k.cnot(1,4)
k.cnot(2, 0)
k.cnot(2, 0)
k.cnot(1, 4)
k.measure(0)
k.measure(1)
k.measure(2)
Expand All @@ -41,65 +38,6 @@ def test_smit():

# compile the program
p.compile(optimize=False, verbose=True)

def test_AllXY():
"""
Single qubit AllXY sequence.
Writes output files to the directory specified in openql.
Output directory is set as an attribute to the program for convenience.
Input pars:
qubit_idx: int specifying the target qubit (starting at 0)
platf_cfg: filename of the platform config file
double_points: if true repeats every element twice
Returns:
p: OpenQL Program object containing
"""
config_fn = os.path.join(curdir, 'test_cfg_CCL.json')
platf = ql.Platform('seven_qubits_chip', config_fn)
p = ql.Program(pname="AllXY", nqubits=platf.get_qubit_number(), p=platf)

allXY = [ ['i', 'i'], ['rx180', 'rx180'], ['ry180', 'ry180'] ]

# this should be implicit
p.set_sweep_points(np.arange(len(allXY), dtype=float), len(allXY))
qubit_idx=0
for i, xy in enumerate(allXY):
k = ql.Kernel("AllXY_"+str(i), p=platf)
k.prepz(qubit_idx)
k.gate(xy[0], qubit_idx)
k.gate(xy[1], qubit_idx)
k.measure(qubit_idx)
p.add_kernel(k)

p.compile()

def test_independent():
config_fn = os.path.join(curdir, '../tests/test_config_default.json')
platf = ql.Platform("starmon", config_fn)
k = ql.Kernel("aKernel", platf)

for i in range(4):
k.prepz(i)

# no dependence
k.cnot(0, 1)
k.cnot(2, 3)

k.measure(0)
k.measure(1)

sweep_points = [2]
num_circuits = 1
nqubits = 4

p = ql.Program("independent", nqubits, platf)
p.set_sweep_points(sweep_points, num_circuits)
p.add_kernel(k)
p.compile(False, True)
p.schedule("ASAP", True)


if __name__ == '__main__':
test_smit()
test()
2 changes: 1 addition & 1 deletion ql/arch/cbox_eqasm_compiler.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ namespace ql
* compile qasm to qumis
*/
// eqasm_t
void compile(std::string prog_name, ql::circuit& c, ql::quantum_platform& platform) throw (ql::exception)
void compile(std::string prog_name, ql::circuit& c, ql::quantum_platform& platform, bool verbose=false) throw (ql::exception)
{
if (verbose) println("[-] compiling qasm code ...");
if (c.empty())
Expand Down
18 changes: 9 additions & 9 deletions ql/arch/cc_light_eqasm_compiler.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ class cc_light_eqasm_compiler : public eqasm_compiler
size_t ns_per_cycle;
size_t total_exec_time = 0;
size_t buffer_matrix[__operation_types_num__][__operation_types_num__];
bool verbose = false;

#define __ns_to_cycle(t) ((size_t)t/(size_t)ns_per_cycle)

Expand All @@ -43,7 +42,7 @@ class cc_light_eqasm_compiler : public eqasm_compiler
* compile qasm to cc_light_eqasm
*/
// eqasm_t
void compile(std::string prog_name, ql::circuit& c, ql::quantum_platform& platform) throw (ql::exception)
void compile(std::string prog_name, ql::circuit& c, ql::quantum_platform& platform, bool verbose=false) throw (ql::exception)
{
if (verbose) println("[-] compiling qasm code ...");
if (c.empty())
Expand Down Expand Up @@ -242,7 +241,8 @@ class cc_light_eqasm_compiler : public eqasm_compiler
}
*/

cc_light_schedule(prog_name, num_qubits, c, platform, verbose);
// cc_light_schedule(prog_name, num_qubits, c, platform, verbose);
cc_light_schedule_rc(prog_name, num_qubits, c, platform, verbose);

// time analysis
// total_exec_time = time_analysis();
Expand All @@ -263,7 +263,7 @@ class cc_light_eqasm_compiler : public eqasm_compiler

// insert waits

emit_eqasm();
emit_eqasm(verbose);
// return eqasm_code;
}

Expand All @@ -283,7 +283,7 @@ class cc_light_eqasm_compiler : public eqasm_compiler
/**
* decompose
*/
void decompose_instructions()
void decompose_instructions(bool verbose=false)
{
/*
if (verbose) println("decomposing instructions...");
Expand Down Expand Up @@ -311,7 +311,7 @@ class cc_light_eqasm_compiler : public eqasm_compiler
/**
* time analysis
*/
size_t time_analysis()
size_t time_analysis(bool verbose=false)
{
if (verbose) println("time analysis...");
// update start time : find biggest latency
Expand Down Expand Up @@ -339,7 +339,7 @@ class cc_light_eqasm_compiler : public eqasm_compiler
/**
* compensate for latencies
*/
void compensate_latency()
void compensate_latency(bool verbose=false)
{
if (verbose) println("latency compensation...");
for (cc_light_eqasm_instruction * instr : cc_light_eqasm_instructions)
Expand All @@ -349,7 +349,7 @@ class cc_light_eqasm_compiler : public eqasm_compiler
/**
* optimize
*/
void resechedule()
void resechedule(bool verbose=false)
{
if (verbose) println("instruction rescheduling...");
if (verbose) println("resource dependency analysis...");
Expand Down Expand Up @@ -469,7 +469,7 @@ class cc_light_eqasm_compiler : public eqasm_compiler
/**
* emit qasm code
*/
void emit_eqasm()
void emit_eqasm(bool verbose=false)
{
if (verbose) println("compiling eqasm...");
eqasm_code.clear();
Expand Down
Loading

0 comments on commit 2e55705

Please sign in to comment.