Skip to content

Commit

Permalink
add fusion optimization for qasm simulator (Qiskit#136)
Browse files Browse the repository at this point in the history
* add fusion

* Set configuration to circuit optimization

* add fusion options

* disable fusion without configuration

* add noise test cases and remove debug codes

* delete statevector_gate_opt configuration

* refactor fusion optimization for future optimization

* qubitvector expands matrixes for fusion.
  • Loading branch information
hhorii authored and gadial committed Apr 22, 2019
1 parent 1d67909 commit 4609d1b
Show file tree
Hide file tree
Showing 10 changed files with 902 additions and 441 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ Added
- Improve efficiency of parallelization with max_memory_mb a new parameter of backend_opts (#61)
- Add optimized mcx, mcy, mcz, mcu1, mcu2, mcu3, gates to QubitVector (#124)
- Add optimized controlled-swap gate to QubitVector
- Add gate-fusion optimization for QasmContoroller, which is enabled by setting fusion_enable=true (#136)

Changed
-------
Expand Down
21 changes: 17 additions & 4 deletions src/base/controller.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,10 @@ class Controller {
//-------------------------------------------------------------------------

// Generate an equivalent circuit with input_circ as output_circ.
Circuit optimize_circuit(const Circuit &input_circ) const;
template <class state_t>
Circuit optimize_circuit(const Circuit &input_circ,
state_t& state,
OutputData &data) const;

//-----------------------------------------------------------------------
// Config
Expand Down Expand Up @@ -271,6 +274,9 @@ void Controller::set_config(const json_t &config) {
max_memory_mb_ = system_memory_mb / 2;
}

for (std::shared_ptr<CircuitOptimization> opt: optimizations_)
opt->set_config(config_);

std::string path;
JSON::get_value(path, "library_dir", config);
// Fix for MacOS and OpenMP library double initialization crash.
Expand Down Expand Up @@ -429,12 +435,19 @@ bool Controller::validate_memory_requirements(state_t &state,
//-------------------------------------------------------------------------
// Circuit optimization
//-------------------------------------------------------------------------

Circuit Controller::optimize_circuit(const Circuit &input_circ) const {
template <class state_t>
Circuit Controller::optimize_circuit(const Circuit &input_circ,
state_t& state,
OutputData &data) const {

Circuit working_circ = input_circ;
Operations::OpSet allowed_opset;
allowed_opset.optypes = state.allowed_ops();
allowed_opset.gates = state.allowed_gates();
allowed_opset.snapshots = state.allowed_snapshots();

for (std::shared_ptr<CircuitOptimization> opt: optimizations_)
opt->optimize_circuit(working_circ);
opt->optimize_circuit(working_circ, allowed_opset, data);

return working_circ;
}
Expand Down
7 changes: 5 additions & 2 deletions src/framework/circuitopt.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,11 @@ namespace AER {

class CircuitOptimization {
public:
virtual void optimize_circuit(Circuit& circ) const = 0;
void set_config(const json_t &config);
virtual void optimize_circuit(Circuit& circ,
const Operations::OpSet &opset,
OutputData &data) const = 0;

virtual void set_config(const json_t &config);

protected:
json_t config_;
Expand Down
39 changes: 38 additions & 1 deletion src/framework/operations.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ enum class RegComparison {Equal, NotEqual, Less, LessEqual, Greater, GreaterEqua
// Enum class for operation types
enum class OpType {
gate, measure, reset, bfunc, barrier, snapshot,
matrix, kraus, roerror, noise_switch, initialize
matrix, matrix_sequence, kraus, roerror, noise_switch, initialize
};

std::ostream& operator<<(std::ostream& stream, const OpType& type) {
Expand All @@ -55,6 +55,9 @@ std::ostream& operator<<(std::ostream& stream, const OpType& type) {
case OpType::matrix:
stream << "matrix";
break;
case OpType::matrix_sequence:
stream << "matrix_sequence";
break;
case OpType::kraus:
stream << "kraus";
break;
Expand Down Expand Up @@ -83,6 +86,7 @@ struct Op {
OpType type; // operation type identifier
std::string name; // operation name
reg_t qubits; // qubits operation acts on
std::vector<reg_t> regs; // list of qubits for matrixes
std::vector<complex_t> params; // real or complex params for gates
std::vector<std::string> string_params; // used or snapshot label, and boolean functions

Expand Down Expand Up @@ -369,6 +373,17 @@ inline Op make_mat(const reg_t &qubits, const cmatrix_t &mat, std::string label
return op;
}

inline Op make_matrix_sequence(const std::vector<reg_t> &regs, const std::vector<cmatrix_t> &mats, std::string label = "") {
Op op;
op.type = OpType::matrix_sequence;
op.name = "matrix_sequence";
op.regs = regs;
op.mats = mats;
if (label != "")
op.string_params = {label};
return op;
}

template <typename T> // real or complex numeric type
inline Op make_u1(uint_t qubit, T lam) {
Op op;
Expand Down Expand Up @@ -431,7 +446,9 @@ inline Op make_roerror(const reg_t &memory, const std::vector<rvector_t> &probs)

// Main JSON deserialization functions
Op json_to_op(const json_t &js); // Patial TODO
json_t op_to_json(const Op &op); // Patial TODO
inline void from_json(const json_t &js, Op &op) {op = json_to_op(js);}
inline void to_json(json_t &js, const Op &op) { js = op_to_json(op);}

// Standard operations
Op json_to_op_gate(const json_t &js);
Expand Down Expand Up @@ -496,6 +513,26 @@ Op json_to_op(const json_t &js) {
return json_to_op_gate(js);
}

json_t op_to_json(const Op &op) {
json_t ret;
ret["name"] = op.name;
if (!op.qubits.empty())
ret["qubits"] = op.qubits;
if (!op.regs.empty())
ret["regs"] = op.regs;
if (!op.params.empty())
ret["params"] = op.params;
if (op.conditional)
ret["conditional"] = op.conditional_reg;
if (!op.memory.empty())
ret["memory"] = op.memory;
if (!op.registers.empty())
ret["register"] = op.registers;
if (!op.mats.empty())
ret["mats"] = op.mats;
return ret;
}


//------------------------------------------------------------------------------
// Implementation: Gates, measure, reset deserialization
Expand Down
Loading

0 comments on commit 4609d1b

Please sign in to comment.