Skip to content

Conversation

shanto268
Copy link

@shanto268 shanto268 commented Nov 18, 2024

What are the issues this pull addresses (issue numbers / links)?

Porting Qiskit Metal from PySide2 to PySide6 so that it can work natively on M* Macs (Apple Silicon).

Issues addressed:

Did you add tests to cover your changes (yes/no)?

No. N/A

Did you update the documentation accordingly (yes/no)?

Yes

Did you read the CONTRIBUTING document (yes/no)?

Yes

Summary

Fixed changes from PR #908 to pass automated CI workflows and tests, ensuring compatibility with updated dependencies, environment configurations, and the latest (11/17/2024) main branch.

Details and comments

  1. Built on top of changes made by @obrienpja in PR #908.

  2. Changes to QWidget_PlaceholderText and QTableView_AllComponents:

    • Refactored the QWidget_PlaceholderText class to ensure proper initialization and compatibility with PySide6.
    • Resolved issues with placeholder text styling by updating palette usage to align with PySide6 standards.
    • Updated QTableView_AllComponents to correctly inherit and integrate with QWidget_PlaceholderText, ensuring both functionality and visual styling work seamlessly.
    • Fixed initialization errors and ensured that the placeholder label behaves as intended when no components are available.
  3. Requirements and environment updates:

    • Updated the environment.yml file to use stable, OS-agnostic dependencies for Python 3.10.
    • Added missing dependencies, such as pyaedt, to ensure a consistent build across different operating systems.
    • Ensured that all dependencies align with the workflows and requirements in the lab's testing environment.
  4. Testing and validation:

    • Verified that the changes integrate seamlessly with the existing workflows and CI processes used in our lab.
    • Tested the updated branch against the current main branch workflows to confirm identical behavior.
    • All CI tests now pass successfully across all supported platforms (Windows, macOS, Ubuntu) and Python versions (3.9 and 3.10).

@CLAassistant
Copy link

CLAassistant commented Nov 18, 2024

CLA assistant check
All committers have signed the CLA.

@CLAassistant
Copy link

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you all sign our Contributor License Agreement before we can accept your contribution.
2 out of 3 committers have signed the CLA.

✅ obrienpja
✅ priti-ashvin-shah-ibm
❌ shanto268
You have signed the CLA already but the status is still pending? Let us recheck it.

@zlatko-minev
Copy link
Collaborator

Thank you, @shanto268! The tests are running. This is a giant PR, so it would be good to have more eyes on it than just you and me. Has anyone else from your lab tried this? I think after merging this, we could bump the Qiskit Metal version from 0.1.5 to 0.2. I just want to make sure it runs.

@zlatko-minev
Copy link
Collaborator

zlatko-minev commented Sep 8, 2025 via email

@PositroniumJS
Copy link
Contributor

Nope, not shelved, just now it’s community driven. We have been a little slow to get all the maintenance I’ve been running, but I think that’s the intention of community. So it would be nice to get this merged when you feel it’s ready.

From my humble point of view, this PR can be merged (94 files modified it is already quite a lot). In a new PR, it would then be easier to finish to set the correct requirements.

Regarding the second window that is staying open, I have tried to fix it but I could not manage it as I have never used PySide before. I would be very grateful if you @zlatko-minev could check this out.

PositroniumJS and others added 3 commits September 17, 2025 15:32
pyaedt is performing a refactor of its files, and the renaming of some functions' arguments
Raw string needed to use backslash inside. The button has been renamed in the GUI.
zlatko-minev
zlatko-minev previously approved these changes Sep 20, 2025
Copy link
Collaborator

@zlatko-minev zlatko-minev left a comment

Choose a reason for hiding this comment

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

This is a very exciting and extremely massive change at this point. Perhaps it’s better to just merge it with whatever issues there may be at this point and then have a more clean up version of fixes in smaller patches on top of that to fix whatever little issues may remain.

@zlatko-minev
Copy link
Collaborator

The only issue right now is that the docs and linting are failing along with a few tests

@zlatko-minev
Copy link
Collaborator

Maybe we can try to resolve this in a couple days and then merge it to Maine, we wouldn’t yet publish to any of the pip etc. Until it’s a little more cleaned up and tested bugs, which I feel are present in some key functionality

@PositroniumJS
Copy link
Contributor

  • Lint is fixed by my new PR Lint shanto268/qiskit-metal#5 (@shanto268 may you merge it please)
  • doc needs an update of the config of GitHub actions, since this update is dropping support of python<3.10, could you please @zlatko-minev at the same time update the versions used to run the tests?

@abhishekchak52
Copy link

abhishekchak52 commented Sep 23, 2025

Hi folks, my PR shanto268#6 to @shanto268's fork moves to pyproject.toml and uv for significantly faster virtual environment creation. Dependencies are now locked (some more testing is needed to isolate specific version constraints for M* Macs, etc. but we have the same versions as in the previous setup.py for now). This only affects development and does not change anything for users. This setup is currently incompatible with the GitHub actions workflows, but I will update those in a follow-up commit which will speedup workflows by a lot as we can use caching extensively. uv simplifies a lot of things, including package building and upload to PyPI.

Tox tasks have been moved into pyproject.toml, helping us move towards a more centralized package configuration. tox-uv is used to ensure that uv is used for the tox environment management. Some general updates to various tox tasks:

  • pytest can work as a drop-in replacement for unittest in this case.
  • (Dev) Dependency groups can reproduce previous tox workflows where different requirements-*.txt files were used. I haven't removed those files yet, but will do so during the docs cleanup for the next release.
  • Instead of checking for a particular file to determine whether we are building docs, we check for an environment variable instead. This bypassed the need for touch to be an allowlist_external.

For me, pylint stalls on one of the source files in qiskit_metal/_gui/, but the lint task starts running just fine. Given how slow yapf and pylint are, we should really move to the drop-in replacement ruff for yet another significant speedup. It supports all the various rules in .style.yapf and .pylintrc (some of which are now deprecated), but ruff also has pretty sensible defaults. @zlatko-minev, do we need to preserve the current rules? Once lint is faster, we could even move it to pre-commit (it would be pretty much instantaneous, even on a modest laptop).

Regarding PyPI release, I think it would help to push to PyPI as a pre-release (with granular alpha/beta/dev version tags) so that uses can try a pip install --pre qiskit-metal.


if "fillet" in qgeometry_element:
if (math.isnan(qgeometry_element.fillet) or
qgeometry_element.fillet <= 0 or
qgeometry_element.fillet < qgeometry_element.width):
Copy link
Contributor

Choose a reason for hiding this comment

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

I do not want to create a PR only to delete one line so I make my suggestion here: I think the condition

qgeometry_element.fillet < qgeometry_element.width

when creating the GDS is invalid. Currently, the matplotlib output is right but the GDS output gives something squarred instead of bended

Suggested change
qgeometry_element.fillet < qgeometry_element.width):
if "fillet" in qgeometry_element:
if (math.isnan(qgeometry_element.fillet) or
qgeometry_element.fillet <= 0):
to_return = gdstk.FlexPath(

Matplotlib output
Image

Current code
Image

After removing this condition
Image

@SamWolski
Copy link

Hi folks, my PR shanto268#6 to @shanto268's fork moves to pyproject.toml and uv for significantly faster virtual environment creation. Dependencies are now locked (some more testing is needed to isolate specific version constraints for M* Macs, etc. but we have the same versions as in the previous setup.py for now). This only affects development and does not change anything for users. This setup is currently incompatible with the GitHub actions workflows, but I will update those in a follow-up commit which will speedup workflows by a lot as we can use caching extensively. uv simplifies a lot of things, including package building and upload to PyPI.

Tox tasks have been moved into pyproject.toml, helping us move towards a more centralized package configuration. tox-uv is used to ensure that uv is used for the tox environment management. Some general updates to various tox tasks:

  • pytest can work as a drop-in replacement for unittest in this case.
  • (Dev) Dependency groups can reproduce previous tox workflows where different requirements-*.txt files were used. I haven't removed those files yet, but will do so during the docs cleanup for the next release.
  • Instead of checking for a particular file to determine whether we are building docs, we check for an environment variable instead. This bypassed the need for touch to be an allowlist_external.

For me, pylint stalls on one of the source files in qiskit_metal/_gui/, but the lint task starts running just fine. Given how slow yapf and pylint are, we should really move to the drop-in replacement ruff for yet another significant speedup. It supports all the various rules in .style.yapf and .pylintrc (some of which are now deprecated), but ruff also has pretty sensible defaults. @zlatko-minev, do we need to preserve the current rules? Once lint is faster, we could even move it to pre-commit (it would be pretty much instantaneous, even on a modest laptop).

Regarding PyPI release, I think it would help to push to PyPI as a pre-release (with granular alpha/beta/dev version tags) so that uses can try a pip install --pre qiskit-metal.

While these are great changes, it feels like it should be a separate PR. Please correct me if I'm mistaken, but this doesn't seem directly relevant to migrating away from PySide2.

@abhishekchak52
Copy link

abhishekchak52 commented Sep 25, 2025

@SamWolski I agree. This would build upon the changes corresponding to this part of the update (quoting from Zlatko's comment above):

Installation Improvements: Transitioned to venv for faster environment setup, moving away from conda as the default. Also, most package versions have been floated and upgraded.

I'm more than happy to open a new PR once the existing set of changes are merged.
This is rather separate from the PySide and pyaedt things and I don't want to hold this PR back.

@SamWolski
Copy link

I don't know if I'm doing something wrong, but bumping pyaedt to any version beyond 0.17.5 seems to knock out Macs from being able to import aedt at all, and thereby being unable to run metal in any substantial capacity:
ansys/pyaedt@f059f32#diff-c863a56d1bb236623c1cbc17f49785d2a87277da612daf3ecbfd7c663ab62867L221

Obviously I don't expect to actually run any Ansys simulations on macOS, but currently I can't even instantiate a Design object due to metal trying to import the renderer and failing. We could restrict importing to only happen when you want to actually render to Ansys, maybe even going as far as making it an optional dependency.

@abhishekchak52
Copy link

Obviously I don't expect to actually run any Ansys simulations on macOS, but currently I can't even instantiate a Design object due to metal trying to import the renderer and failing. We could restrict importing to only happen when you want to actually render to Ansys, maybe even going as far as making it an optional dependency.

Currently, a lot of things (analysis backends, rendering backends, etc.) are imported with the module. Decoupling this would take some refactoring, but a more modular package structure would benefit us in the long term.

@SamWolski
Copy link

Obviously I don't expect to actually run any Ansys simulations on macOS, but currently I can't even instantiate a Design object due to metal trying to import the renderer and failing. We could restrict importing to only happen when you want to actually render to Ansys, maybe even going as far as making it an optional dependency.

Currently, a lot of things (analysis backends, rendering backends, etc.) are imported with the module. Decoupling this would take some refactoring, but a more modular package structure would benefit us in the long term.

My point is that this fork/PR doesn't run at all on any Mac. The module imports, but if I can't instantiate a DesignPlanar then I can't actually do anything.

On the main branch, the pyaedt version is much older, and although metal can't be installed "natively" due to some pyside2 futzing (one of the central motivations for this PR in the first place), there are workarounds using for example the CONDA_SUBDIR=osx-64 var when creating the environment in anaconda.

@PositroniumJS
Copy link
Contributor

I don't know if I'm doing something wrong, but bumping pyaedt to any version beyond 0.17.5 seems to knock out Macs from being able to import aedt at all, and thereby being unable to run metal in any substantial capacity: ansys/pyaedt@f059f32#diff-c863a56d1bb236623c1cbc17f49785d2a87277da612daf3ecbfd7c663ab62867L221

Obviously I don't expect to actually run any Ansys simulations on macOS, but currently I can't even instantiate a Design object due to metal trying to import the renderer and failing. We could restrict importing to only happen when you want to actually render to Ansys, maybe even going as far as making it an optional dependency.

  • What is your python version? aedt version? (they released 0.20.0 today, maybe it can help)
  • What is the error message?
  • A quick fix is to import some files or not depending on the OS that is running the code. It is supposed to be compatible with Windows and Linux if I am right

@SamWolski
Copy link

Python version 3.10.18 or 3.11.13
pyaedt 0.19.0 or 0.20.0

Attempted code execution:

import qiskit_metal
qiskit_metal.designs.DesignPlanar()

Error message:

File ~/miniconda3/envs/metal11/lib/python3.11/site-packages/ansys/aedt/core/generic/settings.py:234, in Settings.__init__(self)
    232         pyaedt_settings_path = Path(os.environ["HOME"]) / "pyaedt_settings.yaml"
    233     else:
--> 234         pyaedt_settings_path = Path(os.environ["APPDATA"]) / "pyaedt_settings.yaml"
    235 self.load_yaml_configuration(pyaedt_settings_path)

File <frozen os>:679, in __getitem__(self, key)

KeyError: 'APPDATA'

The problem is that pyaedt pre-0.17.5 tested for any posix OS and tried to fetch the 'HOME' variable on those, which is correct. Post-0.17.5 only tests for 'linux', meaning macOS defaults to the Windows code path and tries to get a non-existent 'APPDATA' environment variable.

@abhishekchak52
Copy link

Since this is an upstream issue with pyaedt, it sounds like we should pin pyaedt<=0.17.5 for now, until we have a better way of dealing with this issue in general?

@abhishekchak52
Copy link

The problem is that pyaedt pre-0.17.5 tested for any posix OS and tried to fetch the 'HOME' variable on those, which is correct. Post-0.17.5 only tests for 'linux', meaning macOS defaults to the Windows code path and tries to get a non-existent 'APPDATA' environment variable.

@SamWolski, unfortunately I don't have a Mac and cannot test this. Does setting APPDATA to the value of HOME fix the pyaedt problems, or are there more things that fail?

@PositroniumJS
Copy link
Contributor

The problem is that pyaedt pre-0.17.5 tested for any posix OS and tried to fetch the 'HOME' variable on those, which is correct. Post-0.17.5 only tests for 'linux', meaning macOS defaults to the Windows code path and tries to get a non-existent 'APPDATA' environment variable.

For me it sounds like an issue from their side then. Opening an issue or a PR replacing all the Linux by posix should be enough.

In the meantime, you can fix it by setting an environment variable

The path to the configuration file should be specified with the environment variable
``PYAEDT_LOCAL_SETTINGS_PATH``. If no environment variable is set, the class will look for the
configuration file ``pyaedt_settings.yaml`` in the user's ``APPDATA`` folder for Windows and
``HOME`` folder for Linux.

https://github.com/ansys/pyaedt/blob/578a33474ea918ee603decf884ea29a740f7a907/src/ansys/aedt/core/generic/settings.py#L32

@SamWolski
Copy link

There's a somewhat strange situation where the core Ansys computing platform explicitly indicates support exclusively for Windows and Linux, but the PyAnsys project has references to macOS in the guidelines. I can bring it up as an issue in the PyAedt repo to get some clarification, but it is what it is right now.

In any case, I don't think it's a good idea to release a large and long-awaited update to Qiskit Metal, which might I remind everyone is explicitly advertised as "enables native support for M* Macs (Apple Silicon)", as requiring non-trivial user intervention post-install to enable the fundamental functionality of the package itself.

@SamWolski
Copy link

The problem is that pyaedt pre-0.17.5 tested for any posix OS and tried to fetch the 'HOME' variable on those, which is correct. Post-0.17.5 only tests for 'linux', meaning macOS defaults to the Windows code path and tries to get a non-existent 'APPDATA' environment variable.

@SamWolski, unfortunately I don't have a Mac and cannot test this. Does setting APPDATA to the value of HOME fix the pyaedt problems, or are there more things that fail?

I bypassed it locally by editing the pyaedt files directly in an editable install. The imports are fine otherwise.

The design generation seems fine, but I've got an error coming up on a gdstk.Cell.add() call when trying to render to GDS (https://github.com/shanto268/qiskit-metal/blob/bbc7d29b8225d5476294585b9740dd0ba82a3324/qiskit_metal/renderers/renderer_gds/gds_renderer.py#L1715 to be precise). At first glance it looks like one of the entries in the Series is a list with a single Polygon object, rather than the Polygon object itself.

I can try look into it in a bit more detail when I have time. It may also be an edge case with my design, but I don't think I'm doing anything particularly crazy in terms of the actual design elements.

@PositroniumJS
Copy link
Contributor

In any case, I don't think it's a good idea to release a large and long-awaited update to Qiskit Metal, which might I remind everyone is explicitly advertised as "enables native support for M* Macs (Apple Silicon)", as requiring non-trivial user intervention post-install to enable the fundamental functionality of the package itself.

I did not mean to ask, in the next release of qiskit-metal, the Mac user to setup this env variable. I meant that I do not see why PyAedt would not agree to replace the occurences of "Linux" by "posix" since it does not change anything from their side, while enabling Mac users to use some depending libraries on the other side. Thus, setting this variable is a short fix in the meantime (I guess they will release a new version of it before qiskit-metal).

At first glance it looks like one of the entries in the Series is a list with a single Polygon object, rather than the Polygon object itself.

It has to be a list, on the next line, the * is unroling the list

@SamWolski
Copy link

At first glance it looks like one of the entries in the Series is a list with a single Polygon object, rather than the Polygon object itself.

It has to be a list, on the next line, the * is unroling the list

Not quite. The * is unrolling a pandas Series, which should contain the geometry objects directly, but one of the Series entries is itself a list.

I figured it out though: the handling of geometry with interior holes was not ported to gdstk entirely correctly in QGDSRenderer._qgeometry_to_gds. Previously, gdspy.boolean was done with a PolygonSet which resulted in another PolygonSet which is legal to add to the GDS cell. Now, it is gdstk.boolean done with a list of polygons, which returns a list of polygons, which is added to the geometry table etc., hence the error.

The easiest fix I could think of is to return the first (and only) element of this list, ie return result[0] instead of return result. There should in theory only ever be a single element in result as we are only dealing with geometry with full interior holes, rather than geometry which could be split up into multiple disjoint segments by the boolean operation.

The return statement in question is here (line 2339):
https://github.com/shanto268/qiskit-metal/blob/bbc7d29b8225d5476294585b9740dd0ba82a3324/qiskit_metal/renderers/renderer_gds/gds_renderer.py#L2339C29-L2339C29

If this works for everyone, someone with write access can make the change directly (@shanto268 ?). 3 characters doesn't seem worth it for a PR.

@SamWolski
Copy link

In any case, I don't think it's a good idea to release a large and long-awaited update to Qiskit Metal, which might I remind everyone is explicitly advertised as "enables native support for M* Macs (Apple Silicon)", as requiring non-trivial user intervention post-install to enable the fundamental functionality of the package itself.

I did not mean to ask, in the next release of qiskit-metal, the Mac user to setup this env variable. I meant that I do not see why PyAedt would not agree to replace the occurences of "Linux" by "posix" since it does not change anything from their side, while enabling Mac users to use some depending libraries on the other side. Thus, setting this variable is a short fix in the meantime (I guess they will release a new version of it before qiskit-metal).

I asked for clarification on the pyaedt side here: ansys/pyaedt#6704

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.

10 participants