Skip to content

feat!: handling multiple QSystem gatesets#1370

Draft
jake-arkinstall wants to merge 3 commits intomainfrom
feat/sol-gateset
Draft

feat!: handling multiple QSystem gatesets#1370
jake-arkinstall wants to merge 3 commits intomainfrom
feat/sol-gateset

Conversation

@jake-arkinstall
Copy link
Copy Markdown
Contributor

@jake-arkinstall jake-arkinstall commented Jan 21, 2026

This PR aims to explore the work required to add a second QSystem gateset within the framework of the existing gateset.

It is not complete, as rebasing work is required, but reviews will be extremely useful for knowing that this is going in the right direction.

The design choice is "least invasive". There is a good argument for a more invasive refactor to handle things naturally, but that is a longer term effort.

As a consequence of this least invasive approach, the QSystemOpBuilder trait remains a trait, and thus now requires platform arguments for the add and build functions (and for 1q operations this parameter is presently unused), which adds a lot of noise to the screen when reading and writing, and uses match blocks for when rebasing differs. I would like to explore handling this in a better manner.

Another design choice is to bundle all gates into QSystem itself. The intent is to have user-facing guppy code fetch gateset-specific functions from a submodule of qsystem (perhaps re-exporting Helios gates from the parent module to retain backwards compatibility), but on the tket definition side they're still in one big "bag". This choice is made because of the overlap between the two gatesets' 1q operations (rxy, rz) and platform functions (qalloc etc), and the intent is that the more invasive refactor will take gateset overlaps into account while hopefully introducing more separation.

BREAKING CHANGE: QSystemOpBuilder trait's build_* and add_* functions take an additional platform argument. LowerTketToQSystemPass now has a platform member and no longer satisfies Default (a platform must be provided, and there is no good 'default' platform).

@jake-arkinstall jake-arkinstall requested a review from a team as a code owner January 21, 2026 14:53
@jake-arkinstall jake-arkinstall marked this pull request as draft January 21, 2026 14:53
@codecov
Copy link
Copy Markdown

codecov bot commented Jan 21, 2026

Codecov Report

❌ Patch coverage is 91.30435% with 2 lines in your changes missing coverage. Please review.
✅ Project coverage is 83.33%. Comparing base (042ba1d) to head (048e7c4).

Files with missing lines Patch % Lines
...is-compiler/python/tests/test_qsystem_platforms.py 91.30% 2 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1370      +/-   ##
==========================================
- Coverage   83.84%   83.33%   -0.52%     
==========================================
  Files         187      188       +1     
  Lines       28959    29347     +388     
  Branches    27880    28239     +359     
==========================================
+ Hits        24282    24455     +173     
- Misses       3517     3739     +222     
+ Partials     1160     1153       -7     
Flag Coverage Δ
python 92.38% <ø> (+0.04%) ⬆️
qis-compiler 91.54% <91.30%> (-0.12%) ⬇️
rust 82.97% <ø> (-0.55%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@hugrbot
Copy link
Copy Markdown
Collaborator

hugrbot commented Jan 21, 2026

This PR contains breaking changes to the public Rust API.

cargo-semver-checks summary
    Building tket v0.18.0 (current)
     Built [  43.459s] (current)
   Parsing tket v0.18.0 (current)
    Parsed [   0.123s] (current)
  Building tket v0.18.0 (baseline)
     Built [  42.830s] (baseline)
   Parsing tket v0.18.0 (baseline)
    Parsed [   0.109s] (baseline)
  Checking tket v0.18.0 -> v0.18.0 (assume minor change)
   Checked [   0.134s] 196 checks: 196 pass, 56 skip
   Summary no semver update required
  Finished [  87.916s] tket
  Building tket-qec v0.1.0 (current)
     Built [  37.116s] (current)
   Parsing tket-qec v0.1.0 (current)
    Parsed [   0.006s] (current)
  Building tket-qec v0.1.0 (baseline)
     Built [  37.472s] (baseline)
   Parsing tket-qec v0.1.0 (baseline)
    Parsed [   0.006s] (baseline)
  Checking tket-qec v0.1.0 -> v0.1.0 (assume minor change)
   Checked [   0.014s] 196 checks: 196 pass, 56 skip
   Summary no semver update required
  Finished [  80.720s] tket-qec
  Building tket-qsystem v0.24.0 (current)
     Built [  43.925s] (current)
   Parsing tket-qsystem v0.24.0 (current)
    Parsed [   0.027s] (current)
  Building tket-qsystem v0.24.0 (baseline)
     Built [  43.872s] (baseline)
   Parsing tket-qsystem v0.24.0 (baseline)
    Parsed [   0.025s] (baseline)
  Checking tket-qsystem v0.24.0 -> v0.24.0 (assume minor change)
   Checked [   0.058s] 196 checks: 194 pass, 2 fail, 0 warn, 56 skip

--- failure function_parameter_count_changed: pub fn parameter count changed ---

Description:
A publicly-visible function now takes a different number of parameters.
      ref: https://doc.rust-lang.org/cargo/reference/semver.html#fn-change-arity
     impl: https://github.com/obi1kenobi/cargo-semver-checks/tree/v0.47.0/src/lints/function_parameter_count_changed.ron

Failed in:
tket_qsystem::extension::qsystem::lower_tk2_ops now takes 3 parameters instead of 2, in /home/runner/work/tket2/tket2/PR_BRANCH/tket-qsystem/src/extension/qsystem/lower.rs:106

--- failure trait_method_parameter_count_changed: pub trait method parameter count changed ---

Description:
A trait method now takes a different number of parameters.
      ref: https://doc.rust-lang.org/cargo/reference/semver.html#trait-item-signature
     impl: https://github.com/obi1kenobi/cargo-semver-checks/tree/v0.47.0/src/lints/trait_method_parameter_count_changed.ron

Failed in:
QSystemOpBuilder::build_zz_max now takes 3 instead of 2 parameters, in file /home/runner/work/tket2/tket2/PR_BRANCH/tket-qsystem/src/extension/qsystem.rs:378
QSystemOpBuilder::add_zz_phase now takes 4 instead of 3 parameters, in file /home/runner/work/tket2/tket2/PR_BRANCH/tket-qsystem/src/extension/qsystem.rs:403
QSystemOpBuilder::add_phased_x now takes 4 instead of 3 parameters, in file /home/runner/work/tket2/tket2/PR_BRANCH/tket-qsystem/src/extension/qsystem.rs:429
QSystemOpBuilder::add_rz now takes 3 instead of 2 parameters, in file /home/runner/work/tket2/tket2/PR_BRANCH/tket-qsystem/src/extension/qsystem.rs:442
QSystemOpBuilder::build_h now takes 2 instead of 1 parameters, in file /home/runner/work/tket2/tket2/PR_BRANCH/tket-qsystem/src/extension/qsystem.rs:479
QSystemOpBuilder::build_x now takes 2 instead of 1 parameters, in file /home/runner/work/tket2/tket2/PR_BRANCH/tket-qsystem/src/extension/qsystem.rs:489
QSystemOpBuilder::build_y now takes 2 instead of 1 parameters, in file /home/runner/work/tket2/tket2/PR_BRANCH/tket-qsystem/src/extension/qsystem.rs:496
QSystemOpBuilder::build_z now takes 2 instead of 1 parameters, in file /home/runner/work/tket2/tket2/PR_BRANCH/tket-qsystem/src/extension/qsystem.rs:503
QSystemOpBuilder::build_s now takes 2 instead of 1 parameters, in file /home/runner/work/tket2/tket2/PR_BRANCH/tket-qsystem/src/extension/qsystem.rs:509
QSystemOpBuilder::build_sdg now takes 2 instead of 1 parameters, in file /home/runner/work/tket2/tket2/PR_BRANCH/tket-qsystem/src/extension/qsystem.rs:515
QSystemOpBuilder::build_v now takes 2 instead of 1 parameters, in file /home/runner/work/tket2/tket2/PR_BRANCH/tket-qsystem/src/extension/qsystem.rs:521
QSystemOpBuilder::build_vdg now takes 2 instead of 1 parameters, in file /home/runner/work/tket2/tket2/PR_BRANCH/tket-qsystem/src/extension/qsystem.rs:528
QSystemOpBuilder::build_t now takes 2 instead of 1 parameters, in file /home/runner/work/tket2/tket2/PR_BRANCH/tket-qsystem/src/extension/qsystem.rs:535
QSystemOpBuilder::build_tdg now takes 2 instead of 1 parameters, in file /home/runner/work/tket2/tket2/PR_BRANCH/tket-qsystem/src/extension/qsystem.rs:541
QSystemOpBuilder::build_cx now takes 3 instead of 2 parameters, in file /home/runner/work/tket2/tket2/PR_BRANCH/tket-qsystem/src/extension/qsystem.rs:547
QSystemOpBuilder::build_cy now takes 3 instead of 2 parameters, in file /home/runner/work/tket2/tket2/PR_BRANCH/tket-qsystem/src/extension/qsystem.rs:583
QSystemOpBuilder::build_cz now takes 3 instead of 2 parameters, in file /home/runner/work/tket2/tket2/PR_BRANCH/tket-qsystem/src/extension/qsystem.rs:623
QSystemOpBuilder::build_rx now takes 3 instead of 2 parameters, in file /home/runner/work/tket2/tket2/PR_BRANCH/tket-qsystem/src/extension/qsystem.rs:654
QSystemOpBuilder::build_ry now takes 3 instead of 2 parameters, in file /home/runner/work/tket2/tket2/PR_BRANCH/tket-qsystem/src/extension/qsystem.rs:665
QSystemOpBuilder::build_crz now takes 4 instead of 3 parameters, in file /home/runner/work/tket2/tket2/PR_BRANCH/tket-qsystem/src/extension/qsystem.rs:676
QSystemOpBuilder::build_toffoli now takes 4 instead of 3 parameters, in file /home/runner/work/tket2/tket2/PR_BRANCH/tket-qsystem/src/extension/qsystem.rs:723
QSystemOpBuilder::build_measure_flip now takes 2 instead of 1 parameters, in file /home/runner/work/tket2/tket2/PR_BRANCH/tket-qsystem/src/extension/qsystem.rs:801

   Summary semver requires new major version: 2 major and 0 minor checks failed
  Finished [  89.118s] tket-qsystem

@jake-arkinstall jake-arkinstall changed the title DRAFT: handling multiple QSystem gatesets feat!: handling multiple QSystem gatesets Jan 21, 2026
@jake-arkinstall jake-arkinstall requested review from doug-q and removed request for ss2165 January 23, 2026 15:28
Comment thread qis-compiler/rust/lib.rs Outdated
/// Get the QSystemPlatform from the given string. Can be "Helios" or "Sol".
pub fn get_platform(platform: &str) -> Result<qsystem::QSystemPlatform> {
match platform {
"Helios" => Ok(qsystem::QSystemPlatform::Helios),
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: prefer lowercase strings, more natural in cli etc.


@functools.cached_property
def phasedXX(self) -> ExtOp:
"""Two-qubit XX gate (rpp)."""
Copy link
Copy Markdown
Member

@ss2165 ss2165 Jan 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
"""Two-qubit XX gate (rpp)."""
"""Two-qubit XX gate (alias 'rpp')."""

etc., could be confusing for external viewers

return self().get_op("PhasedXX").instantiate()

@functools.cached_property
def twinPhasedX(self) -> ExtOp:
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

don't love the camel case for a property...all the old ones should be snake case too :/

Comment thread tket-qsystem/src/pytket/qsystem.rs Outdated
QSystemOp::PhasedXX => {
return Ok(EncodeStatus::Unsupported);
}
QSystemOp::TwinPhasedX => PytketOptype::NPhasedX, // TODO
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

todo?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is for if OG Tket is to introduce a TwinPhasedX operation that is a special case of NPhasedX (and can't allow N!=2)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please add to the TODO comment 🙏

/// PhasedX gate.
PhasedX,
/// ZZ gate with an angle.
ZZPhase,
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should this be marked helios-only?

Comment thread tket-qsystem/src/extension/qsystem.rs Outdated
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

needs a version bump, non-breaking I guess?

/// Returns an error if the replacement fails.
pub fn lower_tk2_op(hugr: &mut impl HugrMut<Node = Node>) -> Result<Vec<Node>, LowerTk2Error> {
///
/// TODO: consider a rename - tk2 can mean both 'tket2' and the TK2 gate.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/// TODO: consider a rename - tk2 can mean both 'tket2' and the TK2 gate.
// TODO: consider a rename - tk2 can mean both 'tket2' and the TK2 gate.

comment not docstring

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

will leave this file for @doug-q

self.add_zz_phase(qb1, qb2, pi_2)
fn build_zz_max(
&mut self,
platform: QSystemPlatform,
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

to me this suggests that the add methods belong to QSystemOp and the build ones should be implemented on some struct that contains both op and platform

the better encapsulation there might not be worth the refactor

@narmlu
Copy link
Copy Markdown
Contributor

narmlu commented Mar 23, 2026

I noticed that it's emitting print_bool_arr. Current version of the QIS spec says ___print_bool_arr.

  ...
  store i32 1, i32* %y_ptr, align 4
  %84 = bitcast i1** %arr_ptr to i8**
  store i8* %70, i8** %84, align 8
  store i1* %.sub, i1** %mask_ptr, align 8
  call void @print_bool_arr(i8* getelementptr inbounds ([16 x i8], [16 x i8]* @res_cs.46C3C4B5.0, i64 0, i64 0), i64 15, <{ i32, i32, i1*, i1* }>* nonnull %out_arr_alloca)
  ret void

I can give you this specific example if you want it.

Disambiguate helios and sol during rebasing, rename N2PhasedX -> TwinPhasedX

Correct descriptions after the reintroduction of the rz gate

Format + rust test fixups

Rebase + document QSystemCodegenExtension::new

Rename python testing of unimplemented sol features and change from pytest.raises to xfail

Ruff format

Remove redundant variable setting in xfail test

Add unimplemented two-qubit operations for sol gateset (#1377)

[decompositions.py](https://github.com/user-attachments/files/24907896/decompositions.py)
Constructions should be as in attached python.

---------

Co-authored-by: Jake Arkinstall <65358059+jake-arkinstall@users.noreply.github.com>

Add missing maximally entangling XXPhase

Update ZZPhase and ZZMax

Correct output wire indexing for 2q sol gates, correct some typos in gate rebasing, add QFT test

Correct add_phased_xx

Apply requested changes, add addition test
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants