Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/nix support #120

Open
wants to merge 8 commits into
base: main
Choose a base branch
from
Open

Feature/nix support #120

wants to merge 8 commits into from

Conversation

jake-arkinstall
Copy link

Description

Added nix support, The nix flake fetches the pytket flake to fetch pytket, and uses a custom derivation to generate pyqir. mypy and pytest are run as part of nix flake check, which is performed in CI (currently set to every sunday at 2am).

At the moment, tket and pytket will be built. The speed of performing the flake check will be improved significantly if we use cachix.

To try out this flake:

nix develop github:CQCL/pytket-qir/feature/nix-support

Then invoke python. pytket.qir is importable and working, e.g.:

$ nix develop github:CQCL/pytket-qir/feature/nix-support

$ python3
Python 3.11.7 (main, Dec  4 2023, 18:10:11) [GCC 13.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from pytket.circuit import Circuit
>>> from pytket.qir.conversion.api import QIRFormat, pytket_to_qir
>>> c = Circuit(2)
>>> c.H(0)
[H q[0]; ]
>>> c.H(1)
[H q[0]; H q[1]; ]
>>> c.CX(0, 1)
[H q[0]; H q[1]; CX q[0], q[1]; ]
>>> c.H(0)
[H q[0]; H q[1]; CX q[0], q[1]; H q[0]; ]
>>> c.H(1)
[H q[0]; H q[1]; CX q[0], q[1]; H q[0]; H q[1]; ]
>>> print(pytket_to_qir(c, name="example", qir_format=QIRFormat.STRING))
; ModuleID = 'example'
source_filename = "example"

%Qubit = type opaque
%Result = type opaque
; ... and so on

After the merge of this PR, the development shell will be accessible with nix develop github:CQCL/pytket-qir

Checklist

  • I have performed a self-review of my code.
  • I have commented hard-to-understand parts of my code.
  • I have made corresponding changes to the public API documentation. (N/A)
  • I have added tests that prove my fix is effective or that my feature works.
  • I have updated the changelog with any user-facing changes. (N/A)

Copy link
Collaborator

@cqc-melf cqc-melf left a comment

Choose a reason for hiding this comment

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

Thank you for the suggestion!
I am not familiar with nix, so I have added a few questions / comments

@@ -0,0 +1,20 @@
name: build with nix
on:
schedule:
Copy link
Collaborator

Choose a reason for hiding this comment

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

Can you give some details why we would not want to run this on PRs? In case of changes we would like to know that this fails?

Copy link
Author

Choose a reason for hiding this comment

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

Ah, the moment we don't have a Cachix subscription, so we sint have a central store to place things that we have built before. This includes tket - so when this CI runs, it will need to build tket first.

Once we have a caching subscription, the latest tket build will already be available, so building and testing pytket-qir will just be a case of bundling the python package and running checks on it. Then, if we store the result in cachix, anyone can load up a pre-built environment with tket, pytket and pytket-qir very quickly.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Thank you for all the details!

flake.lock Outdated
Copy link
Collaborator

Choose a reason for hiding this comment

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

Is this a file we want to have in the git?

Copy link
Author

Choose a reason for hiding this comment

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

Yes. The flake.lock pins the nix flake dependencies to well-defined versions, which helps keep the repository and users of the repository in sync.

It's feasible that a future commit to nixpkgs e.g. breaks mypy, or updates scipy with a breaking change. By keeping the flake.lock file in the repository, maintainers of this repository get to decide when nixpkgs, tket etc can get updated, by pushing changes created by invoking nix flake update.

llvm = super.llvm_14;
llvm-v-major = lib.versions.major llvm.version;
llvm-v-minor = builtins.substring 0 1 (lib.versions.minor llvm.version);
pyqir-version = "0.10.0";
Copy link
Collaborator

Choose a reason for hiding this comment

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

Is it possible to import the version from the python packages here, or do we now need to update this in two places?

Copy link
Author

Choose a reason for hiding this comment

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

In this case it is customary to provide the exact git revision to pull, then specify the build process, as pyqir isn't available on nixpkgs.

I can update it to scan setup.py for a specific version, though if it changes to using a loose version match then the process will fail.

Though I will add that I am committed to supporting the nix support for this repository and others, so if a change breaks the nix support, or if a version update is required, I'm absolutely happy to action it.

Copy link
Collaborator

Choose a reason for hiding this comment

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

I case I am doing the update, is there anything else I need to do besides updating the version in this file as well?

Copy link
Collaborator

@cqc-melf cqc-melf left a comment

Choose a reason for hiding this comment

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

Do you have plans to add nix for the other extensions as well?

@@ -0,0 +1,20 @@
name: build with nix
on:
schedule:
Copy link
Collaborator

Choose a reason for hiding this comment

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

Thank you for all the details!

llvm = super.llvm_14;
llvm-v-major = lib.versions.major llvm.version;
llvm-v-minor = builtins.substring 0 1 (lib.versions.minor llvm.version);
pyqir-version = "0.10.0";
Copy link
Collaborator

Choose a reason for hiding this comment

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

I case I am doing the update, is there anything else I need to do besides updating the version in this file as well?

@cqc-melf
Copy link
Collaborator

And it would be nice if you could add something to the changelog?

@jake-arkinstall
Copy link
Author

For some reason my github app isnt letting my reply in thread, so:

I case I am doing the update, is there anything else I need to do besides updating the version in this file as well?

If the new version requires to change to the setup process, then this is my usual update process:

  1. Reset the hash to an empty string: ""
  2. Update the version number to an available tag of the repository
  3. Run "nix build"

The nix build log will then emit a warning along the lines of:
"Empty hash provided, assuming sha256 AAAAAAAA...."

Once it has built the package it will calculate the actual hash. It will emit an error along the lines of:

Incorrect hash.
    Specified: AAAAAAAA.....
    Got: "ABCDEF1234....."

What I do then is add the provided hash back into the nix file and run nix build again.

It should immediately notice that it has already seen a derivation with this source, build instructions, and output hash, and resolve to the package it previously built.

The hash thing is annoying but extremely useful. If Nix can verify the hash then it knows if it has seen it before and lets it skip steps.

Likewise, subsequent runs on that machine will serve that result immediately. If we get a cachix subscription, we can upload the resulting derivation there, and any user that needs it (as specified by the matching source, build instructions and output hash) will be offered a ready-to-go downloadable package instead of going through the build and test process.

Will you do the same with other packages?

Indeed! I was asked to look at pytket-quantinuum and pytket-qir is a dependency of it (in the testing pipeline) so I started here.

This, with the above about the caching possibilities, is quite exciting.

Cachix is when the real benefit of the nix integration will kick in: users will be able to run nix develop github:CQCL/pytket-foo on any Linux or Mac Silicon machine and everything from symengine to tket, pyket to pyqir, and everything they need, will be served over a download with no additional building or configuration required. One command and after a few seconds they'll be ready to go.

It doesn't stop at environments, but can also launch tools. So we could possibly have a one-liner to launch a Jupiter notebook pre-filled with demo code, with the environment all loaded up, ready to showcase. But this is all future ifs and maybes, and I don't want to push it in a direction you don't want to take it in.

@cqc-melf
Copy link
Collaborator

Thank you for all the information! I think it would be helpful if you could just copy this into a readme file and add this to the repo as well. Just to make sure this is documented somewhere.

Happy to review your PR on pytket-quantinuum as well.

@cqc-melf
Copy link
Collaborator

Maybe it would be good if we could add this to pytket-qiskit as well? As they are both the most used extensions?

@jake-arkinstall
Copy link
Author

jake-arkinstall commented Jan 30, 2024 via email

@cqc-melf
Copy link
Collaborator

cqc-melf commented Mar 5, 2024

@jake-arkinstall is this ready for re-review?

@jake-arkinstall
Copy link
Author

@jake-arkinstall is this ready for re-review?

Yes, it is! Although as some movement looks to have been made on the cachix side it might be worth waiting for that to land in tket itself, as it'll speed things up considerably (this repo can then rely on the tket's cached outputs instead of forcing a build).

@cqc-alec
Copy link
Collaborator

cqc-alec commented Jun 7, 2024

Please rebase and retarget to main which is now the default branch.

Added a nix flake and derivations for pyqir and pytket-qir,
using the tket flake from github for pytket module inclusion.
The tket flake's nixpkgs is overridden with the current package's
flake to avoid unnecessary download, and to help spot compatibility
problems more easily.

Currently mypy tests are disabled because there are several
type errors that appear. I do not know if these are expected,
or if it is a problem with this derivation. I have also tested
with my `feature/nix-support-add-mypy` branch of tket and,
although the errors are reduced, there are some outstanding
mypy issues coming from within this repository (at least, on
the nix build). Advice would be appreciated on this aspect.

Added result directory to .gitignore, as this can be created
by nix during development.
Previous mypy failures were due to scipy and IPython stubs
missing. By adding them to mypy.ini and setting them to
ignore, mypy checks now work.
@jake-arkinstall jake-arkinstall changed the base branch from develop to main June 7, 2024 10:57
@jake-arkinstall
Copy link
Author

I have rebased to main, and I have also updated the flake and workflow to utilise the TKET cachix (binary cache).

For the workflow to succeed, CACHIX_AUTH_TOKEN will need to be available in the workflow environment, as in the tket repository.

I have also run nix flake check locally (x86_64-linux) and everything passes.

@jake-arkinstall
Copy link
Author

(Additionally, I set nixpkgs to follow TKET's - this will help with possible cache misses if the two disagree on nixpkgs. As more weight is on TKET's build, doing it this way around seems to make the most sense)

@cqc-alec
Copy link
Collaborator

cqc-alec commented Jun 7, 2024

I added CACHIX_AUTH_TOKEN to the repo.

@cqc-alec
Copy link
Collaborator

cqc-alec commented Jun 7, 2024

Closing and reopening to trigger CI...

@cqc-alec cqc-alec closed this Jun 7, 2024
@cqc-alec cqc-alec reopened this Jun 7, 2024
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.

3 participants