Skip to content
Open
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: 6 additions & 0 deletions include/libqasm/v3x/instruction_set.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ class InstructionSet {

InstructionListT single_qubit_named_gate_list;
InstructionListT two_qubit_named_gate_list;
InstructionListT three_qubit_named_gate_list;
InstructionListT non_gate_list;
InstructionListT measure_list;

Expand All @@ -34,6 +35,7 @@ class InstructionSet {
// since an identifier cannot start with a number
std::string single_qubit_gate_composition_prefix = "1q";
std::string two_qubit_gate_composition_prefix = "2q";
std::string three_qubit_gate_composition_prefix = "3q";

std::string reset_name = "reset";
std::string init_name = "init";
Expand All @@ -52,19 +54,23 @@ class InstructionSet {
[[nodiscard]] const GateModifierMapT& get_gate_modifier_map() const;
[[nodiscard]] const InstructionListT& get_single_qubit_named_gate_list() const;
[[nodiscard]] const InstructionListT& get_two_qubit_named_gate_list() const;
[[nodiscard]] const InstructionListT& get_three_qubit_named_gate_list() const;
[[nodiscard]] const InstructionListT& get_non_gate_list() const;
[[nodiscard]] const InstructionListT& get_measure_list() const;

[[nodiscard]] bool is_single_qubit_named_gate(const std::string& name) const;
[[nodiscard]] bool is_two_qubit_named_gate(const std::string& name) const;
[[nodiscard]] bool is_three_qubit_named_gate(const std::string& name) const;
[[nodiscard]] bool is_named_gate(const std::string& name) const;

[[nodiscard]] bool is_single_qubit_gate_composition(const std::string& name) const;
[[nodiscard]] bool is_two_qubit_gate_composition(const std::string& name) const;
[[nodiscard]] bool is_three_qubit_gate_composition(const std::string& name) const;
[[nodiscard]] bool is_gate_composition(const std::string& name) const;

[[nodiscard]] bool is_single_qubit_gate(const std::string& name) const;
[[nodiscard]] bool is_two_qubit_gate(const std::string& name) const;
[[nodiscard]] bool is_three_qubit_gate(const std::string& name) const;
[[nodiscard]] bool is_gate(const std::string& name) const;

[[nodiscard]] bool is_measure(const std::string& name) const;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
SUCCESS
Program(
version: <
Version( # input.cq:1:9..10
items: 3
)
>
block: <
GlobalBlock(
statements: [
Variable( # input.cq:3:10..11
name: <
Identifier(
name: q
)
>
typ: <
Type( # input.cq:3:1..9
name: <
Keyword(
name: qubit
)
>
size: <
IntegerLiteral(
value: 3
)
>
)
>
annotations: []
)
GateInstruction( # input.cq:5:1..6
gate: <
Gate( # input.cq:5:1..6
name: <
Identifier(
name: CCNOT
)
>
gate: -
parameters: <
ExpressionList(
items: []
)
>
annotations: []
)
>
operands: <
ExpressionList(
items: [
Index( # input.cq:5:7..8
expr: <
Identifier(
name: q
)
>
indices: <
IndexList(
items: [
IndexItem(
index: <
IntegerLiteral( # input.cq:5:9..10
value: 0
)
>
)
]
)
>
)
Index( # input.cq:5:13..14
expr: <
Identifier(
name: q
)
>
indices: <
IndexList(
items: [
IndexItem(
index: <
IntegerLiteral( # input.cq:5:15..16
value: 1
)
>
)
]
)
>
)
Index( # input.cq:5:19..20
expr: <
Identifier(
name: q
)
>
indices: <
IndexList(
items: [
IndexItem(
index: <
IntegerLiteral( # input.cq:5:21..22
value: 2
)
>
)
]
)
>
)
]
)
>
annotations: []
)
]
)
>
)

Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
version 3

qubit[3] q

CCNOT q[0], q[1], q[2]
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
SUCCESS
Program(
api_version: 3.0
version: <
Version(
items: 3
)
>
block: <
Block(
statements: [
GateInstruction(
instruction_ref: CCNOT(qubit, qubit, qubit)
gate: <
Gate(
name: CCNOT
gate: -
parameters: []
annotations: []
)
>
operands: [
IndexRef(
variable --> <
Variable(
name: q
typ: <
QubitArray(
size: 3
)
>
annotations: []
)
>
indices: [
ConstInt(
value: 0
)
]
)
IndexRef(
variable --> <
Variable(
name: q
typ: <
QubitArray(
size: 3
)
>
annotations: []
)
>
indices: [
ConstInt(
value: 1
)
]
)
IndexRef(
variable --> <
Variable(
name: q
typ: <
QubitArray(
size: 3
)
>
annotations: []
)
>
indices: [
ConstInt(
value: 2
)
]
)
]
annotations: []
)
]
)
>
variables: [
Variable(
name: q
typ: <
QubitArray(
size: 3
)
>
annotations: []
)
]
)

48 changes: 46 additions & 2 deletions src/v3x/instruction_set.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,30 @@ namespace cqasm::v3x::instruction {
// NOLINTBEGIN
InstructionSet::InstructionSet()
: named_gate_map{
{ "CCNOT", { std::nullopt, "QQQ" } },
{ "CCNOT", { std::nullopt, "QQV" } },
{ "CCNOT", { std::nullopt, "QVQ" } },
{ "CCNOT", { std::nullopt, "QVV" } },
{ "CCNOT", { std::nullopt, "VQQ" } },
{ "CCNOT", { std::nullopt, "VQV" } },
{ "CCNOT", { std::nullopt, "VVQ" } },
{ "CCNOT", { std::nullopt, "VVV" } },
{ "CCX", { std::nullopt, "QQQ" } },
{ "CCX", { std::nullopt, "QQV" } },
{ "CCX", { std::nullopt, "QVQ" } },
{ "CCX", { std::nullopt, "QVV" } },
{ "CCX", { std::nullopt, "VQQ" } },
{ "CCX", { std::nullopt, "VQV" } },
{ "CCX", { std::nullopt, "VVQ" } },
{ "CCX", { std::nullopt, "VVV" } },
{ "CSWAP", { std::nullopt, "QQQ" } },
{ "CSWAP", { std::nullopt, "QQV" } },
{ "CSWAP", { std::nullopt, "QVQ" } },
{ "CSWAP", { std::nullopt, "QVV" } },
{ "CSWAP", { std::nullopt, "VQQ" } },
{ "CSWAP", { std::nullopt, "VQV" } },
{ "CSWAP", { std::nullopt, "VVQ" } },
{ "CSWAP", { std::nullopt, "VVV" } },
{ "CNOT", { std::nullopt, "QQ" } },
{ "CNOT", { std::nullopt, "QV" } },
{ "CNOT", { std::nullopt, "VQ" } },
Expand Down Expand Up @@ -151,6 +175,9 @@ InstructionSet::InstructionSet()
, two_qubit_named_gate_list{
"CNOT", "CR", "CRk", "CV", "CY", "CZ", "DCNOT", "ECR", "InvSqrtSWAP", "ISWAP", "M", "MS", "SqrtISWAP", "SqrtSWAP", "SWAP"
}
, three_qubit_named_gate_list{
"CCNOT", "CCX", "CSWAP"
}
, non_gate_list{
"measure", "measureX", "measureY", "measureZ", "reset", "init", "barrier", "wait"
}
Expand Down Expand Up @@ -185,6 +212,10 @@ InstructionSet::InstructionSet()
return two_qubit_named_gate_list;
}

[[nodiscard]] const InstructionListT& InstructionSet::get_three_qubit_named_gate_list() const {
return three_qubit_named_gate_list;
}

[[nodiscard]] const InstructionListT& InstructionSet::get_non_gate_list() const {
return non_gate_list;
}
Expand All @@ -201,8 +232,12 @@ InstructionSet::InstructionSet()
return two_qubit_named_gate_list.contains(name);
}

[[nodiscard]] bool InstructionSet::is_three_qubit_named_gate(const std::string& name) const {
return three_qubit_named_gate_list.contains(name);
}

[[nodiscard]] bool InstructionSet::is_named_gate(const std::string& name) const {
return is_single_qubit_named_gate(name) || is_two_qubit_named_gate(name);
return is_single_qubit_named_gate(name) || is_two_qubit_named_gate(name) || is_three_qubit_named_gate(name);
}

[[nodiscard]] bool InstructionSet::is_single_qubit_gate_composition(const std::string& name) const {
Expand All @@ -213,8 +248,13 @@ InstructionSet::InstructionSet()
return name.starts_with(two_qubit_gate_composition_prefix);
}

[[nodiscard]] bool InstructionSet::is_three_qubit_gate_composition(const std::string& name) const {
return name.starts_with(three_qubit_gate_composition_prefix);
}

[[nodiscard]] bool InstructionSet::is_gate_composition(const std::string& name) const {
return is_single_qubit_gate_composition(name) || is_two_qubit_gate_composition(name);
return is_single_qubit_gate_composition(name) || is_two_qubit_gate_composition(name) ||
is_three_qubit_gate_composition(name);
}

[[nodiscard]] bool InstructionSet::is_single_qubit_gate(const std::string& name) const {
Expand All @@ -225,6 +265,10 @@ InstructionSet::InstructionSet()
return is_two_qubit_named_gate(name) || is_two_qubit_gate_composition(name);
}

[[nodiscard]] bool InstructionSet::is_three_qubit_gate(const std::string& name) const {
return is_three_qubit_named_gate(name) || is_three_qubit_gate_composition(name);
}

[[nodiscard]] bool InstructionSet::is_gate(const std::string& name) const {
return is_named_gate(name) || is_gate_composition(name);
}
Expand Down
7 changes: 6 additions & 1 deletion src/v3x/semantic_analyzer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,11 @@ bool is_two_qubit_gate(const tree::One<semantic::Gate>& gate) {
return InstructionSet::get_instance().is_two_qubit_gate(resolution_name);
}

bool is_three_qubit_gate(const tree::One<semantic::Gate>& gate) {
const auto& resolution_name = get_gate_resolution_name(gate);
return InstructionSet::get_instance().is_three_qubit_gate(resolution_name);
}

values::Values resolve_parameters(const std::string& instruction_name, const values::Values& parameters) {
auto ret = values::Values{};
const auto& instruction_set = InstructionSet::get_instance();
Expand Down Expand Up @@ -280,7 +285,7 @@ values::Values resolve_parameters(const std::string& instruction_name, const val
}

void check_gate(const tree::One<semantic::Gate>& gate) {
if (!gate->gate.empty() && is_two_qubit_gate(gate->gate)) {
if (!gate->gate.empty() && (is_two_qubit_gate(gate->gate) || is_three_qubit_gate(gate->gate))) {
throw error::AnalysisError{ "trying to apply a gate modifier to a multi-qubit gate" };
}
}
Expand Down
Loading
Loading