diff --git a/CHANGELOG.md b/CHANGELOG.md index b9d9dc72..0f5d6bcf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,12 @@ This project adheres to [Semantic Versioning](http://semver.org/). - **Fixed** for any bug fixes. - **Removed** for now removed features. +## [ 1.4.0 ] - [ 2026-06-05 ] + +### Added +- `CV`, `CY`, `DCNOT`, `ECR`, `ISWAP`, `InvSqrtSWAP`, `M`, `MS`, `SqrtISWAP`, and `SqrtSWAP` unitary instructions. +- Aliases `measureX`, `measureY`, and `measureZ`, for the `measure` instruction along the respective axes. + ## [ 1.3.0 ] - [ 2026-03-23 ] ### Added diff --git a/emscripten/test_libqasm.ts b/emscripten/test_libqasm.ts index 2202b3a9..ebc49a09 100644 --- a/emscripten/test_libqasm.ts +++ b/emscripten/test_libqasm.ts @@ -8,7 +8,7 @@ wrapper().then(function(result: any) { try { let output = cqasm.get_version() - let expected_output = "1.3.0" + let expected_output = "1.4.0" console.log("\nThe version of libqasm compiled with emscripten is:", output); if (output !== expected_output) { console.log("\tExpected output:", expected_output) diff --git a/include/libqasm/v3x/instruction_set.hpp b/include/libqasm/v3x/instruction_set.hpp index aa6af2f9..74db90c2 100644 --- a/include/libqasm/v3x/instruction_set.hpp +++ b/include/libqasm/v3x/instruction_set.hpp @@ -25,6 +25,7 @@ class InstructionSet { InstructionListT single_qubit_named_gate_list; InstructionListT two_qubit_named_gate_list; InstructionListT non_gate_list; + InstructionListT measure_list; InstructionSet(); @@ -34,7 +35,6 @@ class InstructionSet { std::string single_qubit_gate_composition_prefix = "1q"; std::string two_qubit_gate_composition_prefix = "2q"; - std::string measure_name = "measure"; std::string reset_name = "reset"; std::string init_name = "init"; std::string barrier_name = "barrier"; @@ -53,6 +53,7 @@ class InstructionSet { [[nodiscard]] const InstructionListT& get_single_qubit_named_gate_list() const; [[nodiscard]] const InstructionListT& get_two_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; diff --git a/include/libqasm/versioning.hpp b/include/libqasm/versioning.hpp index 2a0ec6c1..a147618c 100644 --- a/include/libqasm/versioning.hpp +++ b/include/libqasm/versioning.hpp @@ -2,7 +2,7 @@ namespace cqasm { -static const char* version{ "1.3.0" }; +static const char* version{ "1.4.0" }; static const char* release_year{ "2026" }; [[nodiscard]] [[maybe_unused]] static const char* get_version() { diff --git a/package.json b/package.json index 907baaef..5836d16a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "libqasm", - "version": "1.3.0", + "version": "1.4.0", "repository": { "type": "git", "url": "https://github.com/QuTech-Delft/libqasm.git" diff --git a/src/v3x/instruction_set.cpp b/src/v3x/instruction_set.cpp index ab62438f..22e6d8a8 100644 --- a/src/v3x/instruction_set.cpp +++ b/src/v3x/instruction_set.cpp @@ -21,14 +21,46 @@ InstructionSet::InstructionSet() { "CRk", { "i", "QV" } }, { "CRk", { "i", "VQ" } }, { "CRk", { "i", "VV" } }, + { "CV", { std::nullopt, "QQ" } }, + { "CV", { std::nullopt, "QV" } }, + { "CV", { std::nullopt, "VQ" } }, + { "CV", { std::nullopt, "VV" } }, + { "CY", { std::nullopt, "QQ" } }, + { "CY", { std::nullopt, "QV" } }, + { "CY", { std::nullopt, "VQ" } }, + { "CY", { std::nullopt, "VV" } }, { "CZ", { std::nullopt, "QQ" } }, { "CZ", { std::nullopt, "QV" } }, { "CZ", { std::nullopt, "VQ" } }, { "CZ", { std::nullopt, "VV" } }, + { "DCNOT", { std::nullopt, "QQ" } }, + { "DCNOT", { std::nullopt, "QV" } }, + { "DCNOT", { std::nullopt, "VQ" } }, + { "DCNOT", { std::nullopt, "VV" } }, + { "ECR", { std::nullopt, "QQ" } }, + { "ECR", { std::nullopt, "QV" } }, + { "ECR", { std::nullopt, "VQ" } }, + { "ECR", { std::nullopt, "VV" } }, { "H", { std::nullopt, "Q" } }, { "H", { std::nullopt, "V" } }, { "I", { std::nullopt, "Q" } }, { "I", { std::nullopt, "V" } }, + { "InvSqrtSWAP", { std::nullopt, "QQ" } }, + { "InvSqrtSWAP", { std::nullopt, "QV" } }, + { "InvSqrtSWAP", { std::nullopt, "VQ" } }, + { "InvSqrtSWAP", { std::nullopt, "VV" } }, + { "ISWAP", { std::nullopt, "QQ" } }, + { "ISWAP", { std::nullopt, "QV" } }, + { "ISWAP", { std::nullopt, "VQ" } }, + { "ISWAP", { std::nullopt, "VV" } }, + { "M", { std::nullopt, "QQ" } }, + { "M", { std::nullopt, "QV" } }, + { "M", { std::nullopt, "VQ" } }, + { "M", { std::nullopt, "VV" } }, + { "MS", { std::nullopt, "QQ" } }, + { "MS", { std::nullopt, "QV" } }, + { "MS", { std::nullopt, "VQ" } }, + { "MS", { std::nullopt, "VV" } }, { "mX90", { std::nullopt, "Q" } }, { "mX90", { std::nullopt, "V" } }, { "mY90", { std::nullopt, "Q" } }, @@ -47,6 +79,14 @@ InstructionSet::InstructionSet() { "S", { std::nullopt, "V" } }, { "Sdag", { std::nullopt, "Q" } }, { "Sdag", { std::nullopt, "V" } }, + { "SqrtISWAP", { std::nullopt, "QQ" } }, + { "SqrtISWAP", { std::nullopt, "QV" } }, + { "SqrtISWAP", { std::nullopt, "VQ" } }, + { "SqrtISWAP", { std::nullopt, "VV" } }, + { "SqrtSWAP", { std::nullopt, "QQ" } }, + { "SqrtSWAP", { std::nullopt, "QV" } }, + { "SqrtSWAP", { std::nullopt, "VQ" } }, + { "SqrtSWAP", { std::nullopt, "VV" } }, { "SWAP", { std::nullopt, "QQ" } }, { "SWAP", { std::nullopt, "QV" } }, { "SWAP", { std::nullopt, "VQ" } }, @@ -75,6 +115,18 @@ InstructionSet::InstructionSet() { "measure", { std::nullopt, "WV" } }, { "measure", { std::nullopt, "BV" } }, { "measure", { std::nullopt, "WQ" } }, + { "measureX", { std::nullopt, "BQ" } }, + { "measureX", { std::nullopt, "WV" } }, + { "measureX", { std::nullopt, "BV" } }, + { "measureX", { std::nullopt, "WQ" } }, + { "measureY", { std::nullopt, "BQ" } }, + { "measureY", { std::nullopt, "WV" } }, + { "measureY", { std::nullopt, "BV" } }, + { "measureY", { std::nullopt, "WQ" } }, + { "measureZ", { std::nullopt, "BQ" } }, + { "measureZ", { std::nullopt, "WV" } }, + { "measureZ", { std::nullopt, "BV" } }, + { "measureZ", { std::nullopt, "WQ" } }, { "measure", { "fff", "BQ" } }, { "measure", { "fff", "WV" } }, { "measure", { "fff", "BV" } }, @@ -97,10 +149,13 @@ InstructionSet::InstructionSet() "H", "I", "mX90", "mY90", "mZ90", "Rn", "Rx", "Ry", "Rz", "S", "Sdag", "T", "Tdag", "U", "X", "X90", "Y", "Y90", "Z", "Z90" } , two_qubit_named_gate_list{ - "CNOT", "CR", "CRk", "CZ", "SWAP" + "CNOT", "CR", "CRk", "CV", "CY", "CZ", "DCNOT", "ECR", "InvSqrtSWAP", "ISWAP", "M", "MS", "SqrtISWAP", "SqrtSWAP", "SWAP" } , non_gate_list{ - "measure", "reset", "init", "barrier", "wait" + "measure", "measureX", "measureY", "measureZ", "reset", "init", "barrier", "wait" +} +, measure_list{ + "measure", "measureX", "measureY", "measureZ" } {} // NOLINTEND @@ -134,6 +189,10 @@ InstructionSet::InstructionSet() return non_gate_list; } +[[nodiscard]] const InstructionListT& InstructionSet::get_measure_list() const { + return measure_list; +} + [[nodiscard]] bool InstructionSet::is_single_qubit_named_gate(const std::string& name) const { return single_qubit_named_gate_list.contains(name); } @@ -171,7 +230,7 @@ InstructionSet::InstructionSet() } [[nodiscard]] bool InstructionSet::is_measure(const std::string& name) const { - return name == measure_name; + return measure_list.contains(name); } [[nodiscard]] bool InstructionSet::is_reset(const std::string& name) const { diff --git a/test/v3x/cpp/test_instruction_set.cpp b/test/v3x/cpp/test_instruction_set.cpp index 893428ec..07db93cd 100644 --- a/test/v3x/cpp/test_instruction_set.cpp +++ b/test/v3x/cpp/test_instruction_set.cpp @@ -18,11 +18,11 @@ class InstructionSetTest : public ::testing::Test { const InstructionListT& single_qubit_named_gate_list = instruction_set.get_single_qubit_named_gate_list(); const InstructionListT& two_qubit_named_gate_list = instruction_set.get_two_qubit_named_gate_list(); - const size_t number_of_gate_map_entries = 60; - const size_t number_of_non_gate_map_entries = 16; + const size_t number_of_gate_map_entries = 100; + const size_t number_of_non_gate_map_entries = 28; const size_t number_of_gate_modifier_map_entries = 3; const size_t number_of_single_qubit_named_gates = 20; - const size_t number_of_two_qubit_named_gates = 5; + const size_t number_of_two_qubit_named_gates = 15; }; TEST_F(InstructionSetTest, get_instance) { @@ -105,7 +105,13 @@ TEST_F(InstructionSetTest, is_gate) { } TEST_F(InstructionSetTest, is_measure) { EXPECT_TRUE(instruction_set.is_measure("measure")); + EXPECT_TRUE(instruction_set.is_measure("measureX")); + EXPECT_TRUE(instruction_set.is_measure("measureY")); + EXPECT_TRUE(instruction_set.is_measure("measureZ")); EXPECT_FALSE(instruction_set.is_measure("MEASURE")); + EXPECT_FALSE(instruction_set.is_measure("measure_z")); + EXPECT_FALSE(instruction_set.is_measure("MEASUREz")); + EXPECT_FALSE(instruction_set.is_measure("MEASUREZ")); } TEST_F(InstructionSetTest, is_reset) { EXPECT_TRUE(instruction_set.is_reset("reset"));