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

ImportError for Qiskit Aer built from source for MacOS arm64 #1286

Closed
JoelHBierman opened this issue Jul 2, 2021 · 51 comments · Fixed by #1362
Closed

ImportError for Qiskit Aer built from source for MacOS arm64 #1286

JoelHBierman opened this issue Jul 2, 2021 · 51 comments · Fixed by #1362
Labels
bug Something isn't working stable-backport-potential The issue or PR might be minimal and/or import enough to backport to stable

Comments

@JoelHBierman
Copy link

JoelHBierman commented Jul 2, 2021

EDIT NOTE: For anyone coming here for step-by-step instructions on how to get Aer to build properly, skip to end of discussion. (About 45 comments down.) Running pip install "git+https://github.com/Qiskit/qiskit-aer.git" also seems to work now with the latest GitHub main branch.

Informations

  • Qiskit Aer version: 0.8.2
  • Python version: 3.9.5
  • Operating system: MacOS 11.4

What is the current behavior?

It's quite possible that this is due to a mistake on my end, but either way I would like to know what is responsible for this error and how it can be remedied. Attempting to run the following snippet of code results in the following ImportError for installations of Aer built from source for MacOS arm64:

from qiskit import Aer
from qiskit.providers.aer import QasmSimulator

from qiskit.utils import QuantumInstance

backend = Aer.get_backend('statevector_simulator')

qasm_backend = QasmSimulator(mode='statevector', max_shots=10000)
QuantumInstance(backend=qasm_backend, shots=1000)
Traceback (most recent call last):
  File "/Users/joelbierman/Desktop/Qiskit ARM64 Tests/AerTests.py", line 2, in <module>
    from qiskit.providers.aer import QasmSimulator
  File "/Users/joelbierman/opt/anaconda3/envs/arm64_env/lib/python3.9/site-packages/qiskit/providers/aer/__init__.py", line 72, in <module>
    from .aerprovider import AerProvider
  File "/Users/joelbierman/opt/anaconda3/envs/arm64_env/lib/python3.9/site-packages/qiskit/providers/aer/aerprovider.py", line 19, in <module>
    from .backends.aer_simulator import AerSimulator
  File "/Users/joelbierman/opt/anaconda3/envs/arm64_env/lib/python3.9/site-packages/qiskit/providers/aer/backends/__init__.py", line 21, in <module>
    from .pulse_simulator import PulseSimulator
  File "/Users/joelbierman/opt/anaconda3/envs/arm64_env/lib/python3.9/site-packages/qiskit/providers/aer/backends/pulse_simulator.py", line 28, in <module>
    from ..pulse.controllers.pulse_controller import pulse_controller
  File "/Users/joelbierman/opt/anaconda3/envs/arm64_env/lib/python3.9/site-packages/qiskit/providers/aer/pulse/controllers/pulse_controller.py", line 27, in <module>
    from .digest_pulse_qobj import digest_pulse_qobj
  File "/Users/joelbierman/opt/anaconda3/envs/arm64_env/lib/python3.9/site-packages/qiskit/providers/aer/pulse/controllers/digest_pulse_qobj.py", line 23, in <module>
    from .pulse_utils import oplist_to_array
ImportError: dlopen(/Users/joelbierman/opt/anaconda3/envs/arm64_env/lib/python3.9/site-packages/qiskit/providers/aer/pulse/controllers/pulse_utils.cpython-39-darwin.so, 2): Symbol not found: __ZN3mup11ParserXBase7SetExprERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEE
  Referenced from: /Users/joelbierman/opt/anaconda3/envs/arm64_env/lib/python3.9/site-packages/qiskit/providers/aer/pulse/controllers/pulse_utils.cpython-39-darwin.so
  Expected in: flat namespace
 in /Users/joelbierman/opt/anaconda3/envs/arm64_env/lib/python3.9/site-packages/qiskit/providers/aer/pulse/controllers/pulse_utils.cpython-39-darwin.so

Steps to reproduce the problem

Initialize a conda environment native to MacOS arm64 by running the following terminal commands:

CONDA_SUBDIR=osx-arm64 conda create -n <env-name> numpy -c conda-forge

Next, run:

conda env config vars set CONDA_SUBDIR=osx-arm64

Deactivate the environment and reactivate it.

conda install scipy -c conda-forge
pip install qiskit-aer

Then just run the snippet of code. NOTE: It took me quite a few attempts to even get to the point where Aer would build. It's quite possible that in my latest attempt that resulted in the ImportError, running pip install qiskit-aer used some cached dependency installations from previous attempts and thus this list of instructions could be incomplete. Generally speaking, if a dependency package doesn't build using pip, I run conda install <package-name> -c conda-forge and try pip install qiskit-aer again.

What is the expected behavior?

No ImportError.

Suggested solutions

@JoelHBierman JoelHBierman added the bug Something isn't working label Jul 2, 2021
@vvilpas
Copy link
Contributor

vvilpas commented Jul 7, 2021

Hi. Unfortunately I don't have a MacOS arm64 to test, but it seems is trying to use some symbols from MuParserX lib, but it is unable to find it.
Can you rebuild in a fresh environment using this command: VERBOSE=1 python ./setup.py bdist_wheel 2>&1|tee build.log and post the build.log.

@JoelHBierman
Copy link
Author

JoelHBierman commented Jul 7, 2021

I have talked about this with Matthew Treinish on the Qiskit Aer Slack channel. He mentioned that there is some error in scikit-build that causes it to ignore the CPU architecture and instead build for the x86_64 architecture under the covers. He suggested building scikit-build from source from the GitHub master branch since there is a fix there, which I have done for these build log files. There also appear to be issues with Conan and targeting the arm64 architecture (even if you change settings.yml to allow arm64). For example, I realized that for some reason, the Conan profile settings will default to arch=x86_64 and arch_build=x86_64 for some reason. If I edit these settings to arch=x86_64 and arch_build=arm64, it will build but I will get the ImportError as mentioned above. These settings correspond to the attached file build1.log. If I switch these settings around to arch=arm64 and arch_build=x86_64, I get the CMake errors as given in the file below build2.log. This CMake error also happens if I set both to arm64. These are the resulting log files when I run the command VERBOSE=1 python ./setup.py bdist_wheel --plat-name macosx-11.0-arm64 2>&1|tee build.log.
build1.log
build2.log

@willemrc
Copy link

Preparing a M1 Mac and failing to setup qiskit-aer with a very similar error as described in @JoelHBierman's build2.log, I replaced the z_Linux_asm.S file created in ~/.conan/data/llvm-openmp/8.0.1///source/source_subfolder/runtime/src on first build with the current file on branch main from https://github.com/llvm/llvm-project/tree/main/openmp This avoids the unknown directive error (size __kmp_unnamed_critical_addr,8). With a 'pip install qiskit-aer' works as well as building qiskit-aer from source (using miniforge and description https://qiskit.org/documentation/getting_started.html#install-qiskit-aer). For full qiskit I got h5py via conda. I didn't test, just ran the lines above (with 'method' param) and a hello. Obviously, this not a final fix.

@JoelHBierman
Copy link
Author

@willemrc Wow! That did the trick! The ImportError is gone. Now I just need to do some testing to make sure everything is working as intended.

@vvilpas
Copy link
Contributor

vvilpas commented Jul 10, 2021

nice! If I understood correctly, we just need to upgrade the version of openmp. @willemrc @JoelHBierman If that is the case, can any of you try building changing the openmp version to the last available one in conan-center.
You just have to change this line:
set(REQUIREMENTS ${REQUIREMENTS} llvm-openmp/8.0.1)
to this:
set(REQUIREMENTS ${REQUIREMENTS} llvm-openmp/10.0.0)
here: openmp version location

If that doesn't work we'll need to add latest openmp release to conan center.

@willemrc
Copy link

@vvilpas @JoelHBierman well, I would bet on a openmp version > 10 (max. version on conan center), so @vvilpas's last comment line probably applies. As z_Linux_asm.S line 1752 in openmp v 10 still looks like it contains the directive at first sight.

@willemrc
Copy link

@vvilpas @JoelHBierman, same error with openmp 10.0.0:

/Users/marc/.conan/data/llvm-openmp/10.0.0///build/a236f81257d30ab7e0569c52cd50928aa0f29852/source_subfolder/runtime/src/z_Linux_asm.S:1752:5: error: unknown directive
.size __kmp_unnamed_critical_addr,8

After replacing z_Linux_asm.S with current one again, it builds. Still, I didn't test building after replacement of whole openmp source with current main branch.

@vvilpas
Copy link
Contributor

vvilpas commented Jul 10, 2021

ok, I'll try to add latest openmp version to conan when I'm back on Monday. When that's done I'll let you know so that you can try with that version . @JoelHBierman @willemrc thanks both for the help!

@mario-s
Copy link

mario-s commented Sep 11, 2021

Same issue, here. Tried as well with 10.0.0. I can not find any higher version in conan.io yet: https://conan.io/center/search/llvm-openmp

@JoelHBierman
Copy link
Author

JoelHBierman commented Sep 11, 2021

@vvilpas I have the .whl file for macosx-arm64 binaries for qiskit-aer 0.8.2 saved to my computer. After a few months of using it regularly to run qiskit-aer natively for this platform, I have not encountered any problems with it. The speed-up of running Aer natively as opposed to running it through Rosetta 2 is quite significant and I imagine this would be valuable for others to be able to use. I noticed that this binary is not published on pypi as of right now. I am relatively new to this sort of thing, so my question to you and the IBM team is this: Is there a proper way for me (or others, since I am definitely not the only or the first person to build qiskit-aer for this platform) to contribute to Qiskit by providing this binary file so that others do not have to go through this same annoying process? If so, what is the way to go about doing so? I imagine that simply posting the .whl file here for people to install using pip is not the way to do it for multiple reasons. (i.e. installing a file some stranger posted on GitHub seems like a poor security practice and a limited number of people would see it here anyways.)

@JoelHBierman
Copy link
Author

JoelHBierman commented Sep 11, 2021

@mario-s The temporary fix given by @willemrc above should do the trick even with openmp 10.0.0. You don't necessarily need openmp > 10.0.0. to get it to work. For now, you only need the one z_Linux_asm.S file obtainable on the GitHub master branch version of llvm-openmp mentioned above. The old version of that file is installed in the directory ~/.conan/data/llvm-openmp/8.0.1///source/source_subfolder/runtime/src on your machine. Just replace the old file with the new one on the GitHub branch and you should be good to go. (The 8.0.1 part of that directory may be different depending what version of openmp is on your machine. I don't know.)

Of course, in the long term Qiskit needs openmp > 10.0.0 so that anyone who tries to install Qiskit on M1 doesn't need to know that the problem lies in this one file in some directory on their machine and that the solution lies in some GitHub branch somewhere. Qiskit is meant to be be widely accessible to people with different levels of experience.

@mtreinish
Copy link
Member

mtreinish commented Sep 13, 2021

@JoelHBierman the only mechanism we really allow for publishing official builds is automated in CI to both avoid errors and add some traceability to the origin of the builds. Do you have a step by step on what extra manual things you needed to do to get it built on your arm64 mac? The builds published to pypi are automated using cibuildwheel the config is here: https://github.com/Qiskit/qiskit-aer/blob/main/.github/workflows/deploy.yml ). So to publish mac arm64 binaries we'll have to add a job for that (which will cross compile because ci is only x86_64 mac). For example, we do this on terra: https://github.com/Qiskit/qiskit-aer/blob/main/.github/workflows/deploy.yml and retworkx: https://github.com/Qiskit/retworkx/blob/main/.github/workflows/wheels.yml#L205-L231 We're preparing a release now so pushing a PR soon would let us publish a precompiled binary for the next release.

@vvilpas
Copy link
Contributor

vvilpas commented Sep 13, 2021

@JoelHBierman I have been updating the PR to Conan for OpenMP 12.0.1 and everything is green now (conan-io/conan-center-index#6312), although there was a weird issue with running in macos in Debug mode failing if less than 5 threads were used. Once they approve it and merge it we can try to use that version in AER and check that everything works. In the meantime maybe you can follow @mtreinish approach, just in case conan PR merge takes too much time or it doesn't work at the end.

@JoelHBierman
Copy link
Author

JoelHBierman commented Sep 13, 2021

Since this was a while ago that I built Aer, I built it again from source just now. Here are the steps to reproduce it as complete as it occurs to me to make them. If there's any other info you need, let me know. This is starting from a fresh Miniconda3 environment.

  1. Install the macosx-arm64 version of miniforge here: https://github.com/conda-forge/miniforge
  2. Run terminal command conda create --name your-env-name python=3.9
  3. download the source file qiskit-aer-0.8.2.tar.gz from pypi and unzip it to get the folder qiskit-aer-0.8.2
  4. Follow the instructions for building Aer at https://qiskit.org/documentation/getting_started.html by running the following terminal commands:

pip install cmake scikit-build cython
brew install libomp
brew install openblas
xcode-select --install (I already had this installed)

  1. Run terminal command conda install numpy scipy to get the arm64 version of these packages from conda-forge. (Although I think this is not strictly speaking necessary as numpy already has published macosx-arm64 wheels and I recall being able to build scipy from source with a bit of effort previously a couple of months ago.) Note: Running this command seems to install llvm-openmp 12.0.0.

  2. Run terminal command cd qiskit-aer-0.8.2 to get to the source code folder you downloaded from pypi.

Now at this point I tried just running the command python setup.py bdist_wheel --plat-name macosx-11.0-arm64 to see if this new version of llvm-openmp made a difference. I still got this cmake error:

Screen Shot 2021-09-13 at 11 28 01 AM

In particular we still get the error message that @willemrc mentions above:

Screen Shot 2021-09-13 at 11 28 01 AM

so to get around this error, we can replace the z_Linux_asm.S installed in the directory /Users/yourusername/.conan/data/llvm-openmp/8.0.1/_/_/source/source_subfolder/runtime/src/ on your local machine with the one that's included in the GitHub branch that @willemrc mentions above. Note: To reproduce this build just now, I did not re-download this file from the Github branch of llvm-openmp. I had it already saved to my M1 MacBook (which is the original machine on which I did the build) and copied it to my M1 Mac mini (which is the machine I am currently reproducing the build on and did not previously have this file on it as far as I am aware, which is why I ran into the CMake error again.) For complete thoroughness, we would have to either re-do this build experiment with the z_Linux_asm.S file that's on the current Github branch or otherwise verify that they are identical.

After making this file replacement, I ran the terminal command python setup.py bdist_wheel --plat-name macosx-11.0-arm64 again and the build completes and I get the file qiskit_aer-0.8.2-cp39-cp39-macosx_11_0_arm64.whl in the dist folder of qiskit-aer-0.8.2.

  1. Run terminal commands cd dist and pip install qiskit_aer-0.8.2-cp39-cp39-macosx_11_0_arm64.whl. It then downloads the wheel and seems to also install qiskit-terra amongst other things like tweedledum without any additional effort on my part.

I ran the following snippet of code just so I could verify on Activity Monitor that it is indeed running natively:

import numpy as np
from qiskit import QuantumCircuit, transpile
from qiskit.providers.aer import QasmSimulator

backend = QasmSimulator()

for n in range(100000):
    circ = QuantumCircuit(3)
    circ.h(0)
    circ.cx(0, 1)
    circ.cx(0, 2)

    qc_compiled = transpile(circ, backend)

And indeed it does appear to be running natively without issue. (This is just some simple code copied from one of the Qiskit tutorials, looped over enough times so that the program runs long enough for me to verify on Activity Monitor that it's running natively and not through Rosetta 2.)

The one and only issue really seems to be that z_Linux_asm.S file on llvm-openmp. As far as I can tell, currently that's the only thing that has to be done manually to build Aer from source. If it wasn't for that one issue, you could probably just run pip install qiskit-aer in a proper macosx-arm64 miniconda environment and it would build from source without issue.

@mario-s
Copy link

mario-s commented Sep 14, 2021

I can confirm that the instructions from @JoelHBierman also worked for me. Thanks a lot!

@mtreinish
Copy link
Member

Thank you for posting detailed instructions, that is super helpful for everyone currently stuck on an m1 mac right now. Unfortunately, I don't think that will be trivial to automate in CI since it involves coordinating modifying conan's source cache with an assembly file pulled from git, which will be tricky to get right (or building openmp from source prior to the wheel builds and disabling conan). Especially since the aer 0.9.0 is pending as soon as #1344 merges I don't think publishing arm64 wheels is viable for this release. But when @vvilpas's conan pr merges and conan is hosting a version of openmp that works on arm64 mac we can prepare a patch release (0.9.1) that will publish arm64 (or universal2) wheels.

@vvilpas
Copy link
Contributor

vvilpas commented Sep 20, 2021

Conan llvm-openmp PR has been approved and merged so there is now v12.0.1 available. I've opened this PR #1348 updating llvm-openmpto this version in AER. Everything seems to be working fine in CI.
@willemrc @JoelHBierman @mario-s Could any of you check if, with that updated version, compilation works and tests pass for Macos arm64?

@JoelHBierman
Copy link
Author

JoelHBierman commented Sep 20, 2021

build.log
Starting from a fresh Miniconda3 environment, I cloned the current main GitHub branch for Aer and changed the line in the cmake/conan_utils.cmake file to set(REQUIREMENTS ${REQUIREMENTS} llvm-openmp/12.0.1) and tried just building Qiskit from source as if I was someone trying to do so from a fresh environment following the instructions at https://qiskit.org/documentation/getting_started.html. When I install the build dependencies and change directories to the GitHub clone folder and run VERBOSE=1 python ./setup.py bdist_wheel --plat-name macosx-11.0-arm64 2>&1|tee build.log, I run into the error given in the log file attached.

Note: It does create the directory /Users/yourusername/.conan/data/llvm-openmp/12.0.1/_/_ so the line change in the cmake.conan_utils.cmake file seems to be doing what it intended, but it does not seem like the build process is getting to the point where the source folder (and thus the troublesome z_Linux_asm.S file) in that directory is being created. So either something happened between llvm-openmp 8.0.1 and 12.0.1 that changes how the directory is structured or the build is failing before it gets to the point where it creates that directory.

What I see as noteworthy in the error message in the build.log file is that some package is trying to build for the platform macosx-10.9-arm64, despite me specifying it to build for macosx-11.0-arm64. A macosx-10.9-arm64 file is nonsense because Mac arm64 chips are not backwards compatible with macOS < 11.0. (My understanding is that the official version number of macOS Big Sur is 11.0 and above). Because the error seemed to be happening in the qiskit-aer/_skbuild directory, I went to the folder qiskit-aer/_skbuild/macos-10.9-arm64-3.9/cmake-build/makefile that gets generated during the build process. In that file there is a section that reads as:

# The main all target
all: cmake_check_build_system
	$(CMAKE_COMMAND) -E cmake_progress_start /Users/joelbierman/Desktop/qiskit-aer-main/_skbuild/macosx-10.9-arm64-3.9/cmake-build/CMakeFiles /Users/joelbierman/Desktop/qiskit-aer-main/_skbuild/macosx-10.9-arm64-3.9/cmake-build//CMakeFiles/progress.marks
	$(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 all
	$(CMAKE_COMMAND) -E cmake_progress_start /Users/joelbierman/Desktop/qiskit-aer-main/_skbuild/macosx-10.9-arm64-3.9/cmake-build/CMakeFiles 0
.PHONY : all

I manually changed macosx-10.9-arm64-3.9 to macosx-11.0-arm64-3.9 wherever it appeared in this section of the file. I also went back and manually changed the directory qiskit-aer/_skbuild/macos-10.9-arm64-3.9/cmake-build/makefile to qiskit-aer/_skbuild/macos-11.0-arm64-3.9/cmake-build/makefile.

I then run the command VERBOSE=1 python ./setup.py bdist_wheel --plat-name macosx-11.0-arm64 2>&1|tee build.log again. This time the build finishes and I get the wheel qiskit_aer-0.9.0-cp39-cp39-macosx_11_0_arm64.whl and pip install it along with Qiskit-terra so I can run my script to see if it's running natively:

import numpy as np
from qiskit import QuantumCircuit, transpile, Aer
from qiskit.providers.aer import QasmSimulator


backend = QasmSimulator()

for n in range(100000):
    circ = QuantumCircuit(3)
    circ.h(0)
    circ.cx(0, 1)
    circ.cx(0, 2)

    qc_compiled = transpile(circ, backend)
    qc_compiled.draw()

and sure enough it does seem to be running natively for M1. Interestingly, if I go back to the directory qiskit-aer/_skbuild/, this is what I see:
Screen Shot 2021-09-20 at 11 06 00 AM

The bottom one labeled with macosx-11.0 is the one that was originally generated during my first build attempt that I manually changed. The top one seems to have been generated during my second build attempt (Notice that it was generated 3 minutes after the bottom one) but it built for macosx-11.0-arm64 anyways. Another interesting thing that I noticed is that after my second build attempt, I navigated back to the /Users/yourusername/.conan/data/llvm-openmp/12.0.1/_/_ directory to see if that was different after the build process had completed. There does not seem to be a source/source_subfolder/runtime/src/ subdirectory in that folder still. Did something about llvm-openmp 12.0.1 change how the directories are structured? Note: I ran conda list in this environment just to check what version of llvm-openmp is installed in this environment. It seems to be 12.0.0. Why this is, I am not sure. For thoroughness, I did go back to the directory /Users/yourusername/.conan/data/llvm-openmp/8.0.1/_/_/source/source_subfolder/runtime/src/ and put the old z_Linux_asm.S file back to make sure that in no way was the manual replacement of this file responsible for any successful build that may occur.

I am not sure what exactly is going on here because the manual changes I had to do this time around were not necessary last time. Would you like me to run tests on this build anyways? And are the tests you referring to the ones mentioned at: https://github.com/Qiskit/qiskit-aer/blob/daae9cf6039c9f14f7cc3ddc56a252ee686722fc/CONTRIBUTING.md ? I only ran my one minimal test given above but I imagine there are more thorough tests that have to be passed for official builds.

@vvilpas
Copy link
Contributor

vvilpas commented Sep 20, 2021

Wow! I guess the problem with 10.9 being forced comes from here:

if(APPLE AND CMAKE_CXX_COMPILER_ID MATCHES "Clang")
# In order to build for MacOSX 10.9 and above with Clang, we need to force the "deployment target" to 10.9
# and force using libc++ instead of the default for this target: libstdc++ otherwise we could not
# use C++11/14
set(CMAKE_OSX_DEPLOYMENT_TARGET "10.9" CACHE STRING "" FORCE)
enable_cxx_compiler_flag_if_supported("-stdlib=libc++")
endif()

Maybe commenting that line 94 you don't need to do those manual adjustments?

Sorry, but without a M1 I can't help much more.

@JoelHBierman
Copy link
Author

JoelHBierman commented Sep 20, 2021

Yes, give me one second and I'll test it making that change. I will also note that I did try and see what happens if I simply run the command VERBOSE=1 python ./setup.py bdist_wheel 2>&1|tee build.log just to see if it had something to do with a string mismatch between the fact that I had specified version 11.0 but it wanted to build for 10.9. The build seems to finish but if I try to pip install the resulting wheel I get the message:

ERROR: qiskit_aer-0.9.0-cp39-cp39-macosx_10_9_arm64.whl is not a supported wheel on this platform.

so one way or another one needs to specify macOS-11.0 I think. UPDATE: I just manually changed the name of this .whl file to qiskit_aer-0.9.0-cp39-cp39-macosx_11_0_arm64.whl and pip installed it to see what happens. It installs fine and seems to run natively. It seems to be the correct whl file in disguise or something like that. So I think at the end of all this, the build process is just having an issue with the fact that when Apple released macOS Big Sur they changed the version number to 11.x and that's causing issues with the naming of strings and such.

Be right back while I try building with that one line commented out.

@JoelHBierman
Copy link
Author

JoelHBierman commented Sep 20, 2021

Commenting out that one line does appear to allow it to build, but only if you specify the build version 11.0 as VERBOSE=1 python ./setup.py bdist_wheel --plat-name macosx-11.0-arm64 2>&1|tee build.log. If you simply run VERBOSE=1 python ./setup.py bdist_wheel 2>&1|tee build.log it will create a .whl file of the wrong name and complain that it's not a supported wheel when you try and install it. Again, it appears to not be an issue with the contents of the file, but just with the file name. Weirdly, even if I comment out that one line, all the named things in _skbuild that I manually changed before are still incorrectly labelled with the version 10.9, but for some reason the build works anyways.

NOTE: In a matter of weeks Apple is going to be releasing MacOS Monterey which (unless I am mistaken) will go by the version number 12.0. It seems that Apple is changing their longstanding version numbering convention from 10.x.y to x.y.z where x = 11 for Big Sur, x = 12 for Monterey, probably x = 13 for MacOS some-naturey-place, ect... Whatever changes need to be made to Qiskit, they should probably be made to anticipate this new version numbering so we don't run into this issue for every version of MacOS going forward.

@vvilpas
Copy link
Contributor

vvilpas commented Sep 20, 2021

Thanks for the testing @JoelHBierman! One thing, because I sometimes forgot and caused trouble, did you delete the _skbuild before rebuilding?

@JoelHBierman
Copy link
Author

JoelHBierman commented Sep 20, 2021

Every time I ran a new test, I did so using a fresh environment, so there should be no _skbuild to delete before rebuilding. So if I make the change regarding llvm-openmp and comment out the forced version line, it should be completely separate from the other build environments.

So what's puzzling to me is that even in a fresh environment where I use a fresh qiskit-aer GitHub clone, if I make the two changes mentioned earlier and I specify version 11.0 in the wheel build, it will work and install just fine, but everything in _skbuild is still named incorrectly. I guess that doesn't matter a whole lot as long as it builds, but if someone trying to build Aer from source doesn't know that they need to specify --macosx-11.0-arm64 in the wheel build, they will run into a lot of frustration. And on top of that we will probably run into the same issue for every future version of macOS, given the new version numbering convention Apple seems to be using now.

@JoelHBierman
Copy link
Author

JoelHBierman commented Sep 20, 2021

It seems like in the CMakeLists.txt there needs to be some modified conditional statement to force string versions based on some detection of the CPU architecture. Something like (I don't really know what the CMake syntax is so I'm just kind of making up my own):

 if(APPLE AND CMAKE_CXX_COMPILER_ID MATCHES "Clang" AND <something-to-detect-x86-architecture>) 
 	# In order to build for MacOSX 10.9 and above with Clang, we need to force the "deployment target" to 10.9 
 	# and force using libc++ instead of the default for this target: libstdc++ otherwise we could not 
 	# use C++11/14 
 	set(CMAKE_OSX_DEPLOYMENT_TARGET "10.9" CACHE STRING "" FORCE) 
 	enable_cxx_compiler_flag_if_supported("-stdlib=libc++") 
 endif() 

 if(APPLE AND CMAKE_CXX_COMPILER_ID MATCHES "Clang" AND <something-to-detect-arm64-architecture>) 
 	enable_cxx_compiler_flag_if_supported("-stdlib=libc++") 
 endif() 

The only thing that worries me about implementing something like this is that some people might want to have a mix of some Conda environments which are arm64 native and some which run non-natively through Rosetta-2 because other non-qiskit packages might be a pain to build from source if they don't publish arm-native binaries. Up until recently I did this because I couldn't get pyscf to build from source for macosx-arm64, which is important if you use the PYSCFDrivers in Qiskit-nature. So I had some x86 environments and some arm64 environments, where I would generate the pyscf drivers in an x86 environment, save it to a HDF5Driver file, then load it in an arm64 environment. Or some newcomers who just bought a new Mac and just started learning how to code might not know how to install Miniconda to get all the arm64 package dependencies since Anaconda doesn't run natively for arm64 yet and a lot of packages are not published for arm64 on pypi yet. My point being here is that I don't know if changing this file in this way to detect CPU architecture would cause problems for people who run Qiskit through rosetta-2. (i.e. if one is running an environment through rosetta-2, does the CPU architecture get detected as x86 or arm64?)

@vvilpas
Copy link
Contributor

vvilpas commented Sep 20, 2021

It's been a long time since I work on AER so I didn't remember but I think I might have find the problem. In setup.py we have this as well:

cmake_args = ["-DCMAKE_OSX_DEPLOYMENT_TARGET:STRING=10.9"]

Can you substitute with this:

 cmake_args = []

and try again when you have time. No hurries!

@JoelHBierman
Copy link
Author

Making that change, in addition to the other changes already mentioned, seems to do the trick. It builds and installs the wheel without me needing to specify the version number as 11.0.

@JoelHBierman
Copy link
Author

Just out of curiosity, from a fresh environment and a fresh GitHub clone, I also tried building where I made the changes to the llvm-openmp version and to the cmake_args in setup.py, but made no manual changes to the CMakeLists.txt file. That also builds successfully without me needing to specify version 11.0.

@vvilpas
Copy link
Contributor

vvilpas commented Sep 22, 2021

Yes, I think we need to update Catch2 to be compatible with macos arm64. I have updated in my PR to the 2.13.6.
The failure in pip install . looks like related to building scipy?

@mtreinish
Copy link
Member

The scipy build thing is a packaging bug, the setup.py lists scipy as a build requirement. Setuptools tries to install packages in the build requirements using it's own mechanism instead of pip and often fails to find packages that are preinstalled (especially if they're installed via conda). I think the fix for that is to move: https://github.com/Qiskit/qiskit-aer/blob/main/setup.py#L71 to https://github.com/Qiskit/qiskit-aer/blob/main/setup.py#L90 since scipy shouldn't be a build requirement.

You also should be able to workaround this by using pip install --no-deps . which will skip the build requirements installation.

@JoelHBierman
Copy link
Author

JoelHBierman commented Sep 22, 2021

Okay, we are making some progress here. I manually made all the changes to a fresh clone of the current Qiskit-Aer GitHub main branch given in the PR that @vvilpas made. I also manually made the changes that @mtreinish made regarding the way Scipy is handled in setup.py. Both builds now complete, which I did with separate clones in separate environments. There are still some lingering issues with both:

C++ Tests:

I ran python ./setup.py bdist_wheel --build-type=Debug -- -DBUILD_TESTS=True -- -j4 2>&1 |tee build.log and the build completes. I then ran ./test/unitc_tests while in the qiskit-aer directory. I get the error: zsh: no such file or directory: ./test/unitc_tests. It seems that the file unitc_tests is not being generated during the build process, at least in the test directory for some reason. I double checked to see if that file was in that directory and it does not appear to be there. (Also, I thought it was interesting that the directions for setting this up do not say to pip install the wheel. I thought that was odd, but took the instructions literally and did not install it on my first try. I then tried running this file after pip installing the wheel and it still did not work.) I left [Catch2-options] blank since I don't have any knowledge of how this works or what sensible options I could put.

Terra integration tests:

I run pip install . 2>&1 |tee build.log while in the qiskit-aer directory and it builds just fine now that I made that one change to Scipy in the setup.py file. When I run stestr run 2>&1 |tee build2.log, I get a bunch of errors how it cannot find a module named ddt. I assumed this was just a dependency that wasn't explicitly mentioned in the instructions, so I just ran pip install ddt and sure enough that error goes away when I run stestr run 2>&1 |tee build3.log. Here is the log output of that test:

build3.log

@mtreinish
Copy link
Member

I just pushed up #1353 to fix the scipy issue

@mtreinish mtreinish added the stable-backport-potential The issue or PR might be minimal and/or import enough to backport to stable label Sep 24, 2021
@mtreinish
Copy link
Member

I've tagged this as stable backport potential because fixing this and adding ci automation for publishing arm64/universal2 wheels on macOS is the last blocker for a pending 0.9.1 release

@chriseclectic
Copy link
Member

chriseclectic commented Sep 28, 2021

What's the status of automatically building the universal wheels? Is it something that can ready to go for the 0.9.1 patch release? @vvilpas @mtreinish

@mtreinish
Copy link
Member

It's still not quite working in CI even with #1348 . I pushed up a test PR in #1362 to verify the CI config and conan is having trouble resolving we're in a cross-compilation configuration for the ci wheel jobs. I'll need some help to figure out how to explicitly configure conan to use arm64 instead of x86_64 there because it doesn't look like it's doing the right thing.

@JoelHBierman
Copy link
Author

JoelHBierman commented Sep 28, 2021

In #1362 it appears to be trying to build an arm64 wheel for python 3.8. To my knowledge, the minimum version of python that officially supports MacOS arm64 is 3.9.1 (Unless there are cross-compiled builds of <= 3.8. on conda forge or something.). That could be why that build is failing. I don't know enough to know why the other two tests are failing.

EDIT: It appears that there are arm64 builds on conda-forge for python 3.8.

@mtreinish
Copy link
Member

Python 3.8.10 also added support for arm64 on macOS: https://docs.python.org/3.8/whatsnew/changelog.html#python-3-8-10-final so the arm64 ci job is trying to build a wheel for both 3.8 and 3.9 (starting 3.8 first):

https://github.com/Qiskit/qiskit-aer/pull/1362/checks?check_run_id=3736623634#step:5:191

@JoelHBierman
Copy link
Author

JoelHBierman commented Sep 28, 2021

That is interesting. In all of my tests, all of them involved python 3.9 because I was not aware of the added support for Python 3.8. I'll trying building for that as well. Let me know if there's anything in particular that you would like me to test. I could even try doing a cross-compilation build because I can set up conda environments that are built for either architecture. (i.e. try and build and arm64 wheel in an x86 environment running rosetta 2.)

@JoelHBierman
Copy link
Author

The build for python 3.8.11 seems to work fine. I'll play around a bit with trying to build an arm64 wheel from an x86 Conda environment.

@JoelHBierman
Copy link
Author

JoelHBierman commented Sep 29, 2021

It looks like Conan has published instructions for how to cross-compile to M1 specifically:

https://blog.conan.io/2021/09/21/m1.html

I've only started to read through this, so I don't know if the information in this blog will be helpful. I just thought I would post the link here just incase it turns out to have helpful information that someone else could take advantage of because I'm not sure when I'll have time to investigate this further.

@HilbertSpecs
Copy link

Hello Everyone,
Thanks for all the hard work troubleshooting the qiskit-aer build for M1 Mac. I'm dealing with the same issue now. I'm having a hard time following the most recent list of events for successfully building from in conda virtual environment. If some one could help clarify the correct list of commands to follow it would be greatly appreciated.

  1. Create virtual environment and Activate
    conda create -y -n QisKitDevEnv python=3
    conda activate QisKitDevEnv
  2. Install qiskit-terra from source following instructions at: https://qiskit.org/documentation/contributing_to_qiskit.html#aer-wheel-build-options
  3. Build and Install qiskit-aer from source:
    %git clone https://github.com/Qiskit/qiskit-aer
    %pip install cmake scikit-build cython

#Edit_File --> 'qiskit-aer/cmake/conan_utils.cmake'
set(REQUIREMENTS ${REQUIREMENTS} llvm-openmp/8.0.1)
to
set(REQUIREMENTS ${REQUIREMENTS} llvm-openmp/12.0.1)
#Edit_File --> 'setup.py'
cmake_args = ["-DCMAKE_OSX_DEPLOYMENT_TARGET:STRING=10.9"]
to
cmake_args = []

%brew install libomp
%brew install openblas
%xcode-select --install

#BuildWheel
%cd qiskit-aer
%python ./setup.py bdist_wheel

#####_InstallWheel-->(Not sure about these two lines also.)
%cd dist
%pip install qiskit-aer_wheelname.whl

3.Build and Install qiskit-ignis, qiskit-aqua, and qiskit-imbq-provider following remaining instructions at:
https://qiskit.org/documentation/contributing_to_qiskit.html#aer-wheel-build-options

Any Feedback on clarifying some of the results in the method procedure to successfully building and installing qiskit on M1 Mac would be of great assitance! Thanks for your help!

@JoelHBierman
Copy link
Author

@HilbertSpecs

Hi! It's not completely clear to me from your post which steps you are stuck on. I think throughout the course of this discussion we figured out different ways to get Aer to build correctly, which probably makes it less straightforward to follow. Furthermore the last few posts pertain to cross-compilation using CI wheel build, which is relevant to the Qiskit team who have to automate the wheel-build process to publish binaries on pypi, but is not relevant if you are trying to build for M1 on an M1 machine since that is not cross-compilation. Here I will try to compile the relevant parts of the discussion into a straightforward set of steps that one should be able to get Aer to build successfully if they follow them. I will also try to elaborate on certain steps a bit more. My goal is to try and be as specific as possible so people with a wide range of experience levels should not have much problem following it.

  1. The first step is to to set up an M1-native python virtual environment. That is, an environment which will automatically install M1-native packages from pypi or condo-forge if they are available and attempt to build for M1 if they are not available. A python virtual environment which is not set up in this way will default to installing Intel x86 packages and build for Intel CPUs. There are multiple ways to do this, but in my opinion the most straightforward way to do this is to install the M1-native version of miniconda3 at: https://github.com/conda-forge/miniforge You will want to install the macosx-arm64 one. This is a file that will install miniconda3 for M1 when you run it in the terminal. NOTE: There is not an M1-native version of Anaconda available at this time. Most people use Anaconda to use python and conda, but Anaconda environments will default to x86. You can get it to work with some extra steps, but using miniconda is easier.

  2. With your M1-native conda environment set up, you can now start to install the Qiskit dependencies and build Aer from source. Start by running terminal command:

conda create --name your-env-name python=3.9. (You can also now use python 3.8 as well if you prefer.) Activate the environment by running the command conda activate your-env-name.

  1. Now you need a copy of the Aer source code. You can do this by either downloading a Github clone or downloading the qiskit-aer-0.9.1.tar.gz file at https://pypi.org/project/qiskit-aer/#files and unzipping it. Both of these download a folder that contains the Aer source code, so as long as you know where this folder has been downloaded on your machine, either will work.

  2. Now you need to install the build dependencies, which you do by running the following terminal commands:

pip install cmake scikit-build cython
brew install libomp
brew install openblas
xcode-select --install
conda install numpy scipy
  1. Navigate to the folder where the Aer source code is located. There are a few lines in a couple of files in this folder that need to be changed. The first change that needs to be made is in the file /cmake/conan_utils.cmake on line 16. The line:

     set(REQUIREMENTS ${REQUIREMENTS} llvm-openmp/8.0.1)
    

needs to be changed to:

    set(REQUIREMENTS ${REQUIREMENTS} llvm-openmp/12.0.1)
  1. Now a change need to be made in the file setup.py. On line 107, the line:

    cmake_args = ["-DCMAKE_OSX_DEPLOYMENT_TARGET:STRING=10.9"]
    

needs to be changed to:

 cmake_args = []

If I remember correctly (It's been a while, so hopefully this is correct.) this should be all you need to do as far as editing source code files is concerned.

  1. Now with the qiskit Aer source code folder as your working directory, you can run the terminal command python setup.py bdist_wheel . This will build the wheel file which will be located in the folder dist. You can navigate to this folder by running the command cd dist. You can check the name of the wheel file by running the command ls. It should be something like: qiskit_aer-0.9.1-cp39-cp39-macosx_11_0_arm64.whl. (It might not be this exactly, I'm not sure.) Whatever the name of this file is, run the command:

    pip install file-name.whl

and this should install Aer native for M1. You can verify that everything has been done correctly by running any Qiskit code which utilizes Aer by opening the Activity Monitor app that comes pre-installed on every Mac. It should say "Apple" under the "Kind" column next to the process that corresponds to the python program. If it says "Intel", then something because that indicates that it's running non-natively through Rosetta 2. Let me know if this works or if there are some steps which are still not quite clear.

@HilbertSpecs
Copy link

@JoelHBierman

Thank you so much for your detailed response. That was the solution that I had filtered out of reading everything above with the other newly added guide on the Qiskit documentation for building from source: (https://qiskit.org/documentation/getting_started.html)
Before I gave myself another headache and went through unnecessary outdated or conflicting steps I thought I'd just double check to clarify the process. It helps to have it all in one spot for the next people that come along with the same issue. Also I did not know that you could run 'brew' inside a conda virtual environment. Thanks again.

@phierhager
Copy link

Hello!
I am having trouble as well installing qiskit on my Mac M1. I followed the steps described two posts above exactly and I could successfully install qiskit-aer (+qiskit-terra). If I now import the QASM Simulator with
from qiskit.providers.aer import QasmSimulator though, I get following error:

from .pulse_utils import oplist_to_array
ImportError: dlopen(/Users/philiphierhager/miniforge3/envs/qiskit/lib/python3.8/site-packages/qiskit/providers/aer/pulse/controllers/pulse_utils.cpython-38-darwin.so, 
2): Symbol not found: __ZN3mup11ParserXBase7SetExprERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEE
 Referenced from: /Users/philiphierhager/miniforge3/envs/qiskit/lib/python3.8/site-packages/qiskit/providers/aer/pulse/controllers/pulse_utils.cpython-38-darwin.so
 Expected in: flat namespace
in /Users/philiphierhager/miniforge3/envs/qiskit/lib/python3.8/site-packages/qiskit/providers/aer/pulse/controllers/pulse_utils.cpython-38-darwin.so

I tried it with python 3.8 and 3.9. I understand, that this may have something to do with C++ libraries as discussed there,
but I do not know how to solve the issue. Any hints on how to fix it are greatly appreciated! Thanks in advance!

@JoelHBierman
Copy link
Author

JoelHBierman commented Nov 26, 2021

@PhilipHierhager

That could be a number of things, but in my experience that is the bug that shows up when a version of llvm-openmp less than 12.0.1 is being used (thus why step 5 given above is necessary). For versions of llvm-openmp older than this, for some reason Conan builds for x86 under the covers rather than arm64, which results in the issues you are experiencing when you try to import modules in Aer. Are you using source code obtained from the main GitHub branch or the .tar.gz file from pypi?

NOTE: It looks like a lot of the manual file changes given in the steps above have been merged to the main GitHub branch. It is possible that pip installing straight from the GitHub branch (so long as you have all the build dependencies installed) should work, but this is something I will have to test myself.

EDIT: I tried this today and it worked for me. Instead of doing all of the manual file changes given above, you can run pip install "git+https://github.com/Qiskit/qiskit-aer.git". This will clone the latest GitHub main branch and pip install it for you, avoiding the need for the manual file changes.

@phierhager
Copy link

@JoelHBierman

Thank you very much for the detailed answer! I was using the GitHub Branch and now I tried it again with your edit. I created a new environment with python 3.10 (I also tried 3.8), installed requirements with
pip install cmake scikit-build cython brew install libomp brew install openblas xcode-select --install conda install numpy scipy
Then I ran the command pip install "git+https://github.com/Qiskit/qiskit-aer.git".
Still, I get the same error, when I try to run from qiskit.providers.aer import QasmSimulator. I do not get, why it does not work for me.

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Users/usr/miniforge3/envs/qiskit2/lib/python3.8/site-packages/qiskit/providers/aer/__init__.py", line 65, in <module>
    from .aerprovider import AerProvider
  File "/Users/usr/miniforge3/envs/qiskit2/lib/python3.8/site-packages/qiskit/providers/aer/aerprovider.py", line 19, in <module>
    from .backends.aer_simulator import AerSimulator
  File "/Users/usr/miniforge3/envs/qiskit2/lib/python3.8/site-packages/qiskit/providers/aer/backends/__init__.py", line 21, in <module>
    from .pulse_simulator import PulseSimulator
  File "/Users/usr/miniforge3/envs/qiskit2/lib/python3.8/site-packages/qiskit/providers/aer/backends/pulse_simulator.py", line 30, in <module>
    from ..pulse.controllers.pulse_controller import pulse_controller
  File "/Users/usr/miniforge3/envs/qiskit2/lib/python3.8/site-packages/qiskit/providers/aer/pulse/controllers/pulse_controller.py", line 27, in <module>
    from .digest_pulse_qobj import digest_pulse_qobj
  File "/Users/usr/miniforge3/envs/qiskit2/lib/python3.8/site-packages/qiskit/providers/aer/pulse/controllers/digest_pulse_qobj.py", line 25, in <module>
    from .pulse_utils import oplist_to_array
ImportError: dlopen(/Users/usr/miniforge3/envs/qiskit2/lib/python3.8/site-packages/qiskit/providers/aer/pulse/controllers/pulse_utils.cpython-38-darwin.so, 2): Symbol not found: __ZN3mup11ParserXBase7SetExprERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEE
  Referenced from: /Users/usr/miniforge3/envs/qiskit2/lib/python3.8/site-packages/qiskit/providers/aer/pulse/controllers/pulse_utils.cpython-38-darwin.so
  Expected in: flat namespace
 in /Users/usr/miniforge3/envs/qiskit2/lib/python3.8/site-packages/qiskit/providers/aer/pulse/controllers/pulse_utils.cpython-38-darwin.so```

mtreinish added a commit that referenced this issue Jan 19, 2022
This PR adds CI jobs to build qiskit-aer wheels on arm64 macOS wheels. Since no CI system provides native arm64
macOS environments these CI jobs are configured to cross compile arm64 binaries from an x86_64 macOS
environment. This has the limitation of not letting us execute the binaries but we can at least test building them in
PR CI and publish the built binaries at release time. The two jobs added here do just that, the first is run as part
of the Build workflow that runs on every proposed commit to test that we can at least compile on arm64 macOS
(for supported python versions). The second job is a release publishing job that will build and publish arm64
macOS wheels to PyPI whenever there is a release.

Fixes #1286
Fixes #1397
@mtreinish
Copy link
Member

This was closed by #1362 because that PR added the release time CI jobs to build and publish arm64 macos wheels. The precompiled binaries will be published to pypi automatically as part of the next qiskit-aer release. If there are any issues after the next release running on macOS with arm64 feel free to reopen this or open a new issue.

hhorii pushed a commit to hhorii/qiskit-aer that referenced this issue Jan 21, 2022
This PR adds CI jobs to build qiskit-aer wheels on arm64 macOS wheels. Since no CI system provides native arm64
macOS environments these CI jobs are configured to cross compile arm64 binaries from an x86_64 macOS
environment. This has the limitation of not letting us execute the binaries but we can at least test building them in
PR CI and publish the built binaries at release time. The two jobs added here do just that, the first is run as part
of the Build workflow that runs on every proposed commit to test that we can at least compile on arm64 macOS
(for supported python versions). The second job is a release publishing job that will build and publish arm64
macOS wheels to PyPI whenever there is a release.

Fixes Qiskit#1286
Fixes Qiskit#1397
@ankitsharma22458
Copy link

Hi is it now published to qiskit-aer version 0.10.2 ?

hhorii pushed a commit that referenced this issue Feb 9, 2022
This PR adds CI jobs to build qiskit-aer wheels on arm64 macOS wheels. Since no CI system provides native arm64
macOS environments these CI jobs are configured to cross compile arm64 binaries from an x86_64 macOS
environment. This has the limitation of not letting us execute the binaries but we can at least test building them in
PR CI and publish the built binaries at release time. The two jobs added here do just that, the first is run as part
of the Build workflow that runs on every proposed commit to test that we can at least compile on arm64 macOS
(for supported python versions). The second job is a release publishing job that will build and publish arm64
macOS wheels to PyPI whenever there is a release.

Fixes #1286
Fixes #1397
hhorii pushed a commit to hhorii/qiskit-aer that referenced this issue Feb 9, 2022
This PR adds CI jobs to build qiskit-aer wheels on arm64 macOS wheels. Since no CI system provides native arm64
macOS environments these CI jobs are configured to cross compile arm64 binaries from an x86_64 macOS
environment. This has the limitation of not letting us execute the binaries but we can at least test building them in
PR CI and publish the built binaries at release time. The two jobs added here do just that, the first is run as part
of the Build workflow that runs on every proposed commit to test that we can at least compile on arm64 macOS
(for supported python versions). The second job is a release publishing job that will build and publish arm64
macOS wheels to PyPI whenever there is a release.

Fixes Qiskit#1286
Fixes Qiskit#1397
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working stable-backport-potential The issue or PR might be minimal and/or import enough to backport to stable
Projects
None yet
Development

Successfully merging a pull request may close this issue.

9 participants