KingsburyLab / pyEQL

A Python library for solution chemistry
Other
64 stars 17 forks source link

Incomplete support for Apple silicon (M1, M2, etc.) #109

Open rkingsbury opened 6 months ago

rkingsbury commented 6 months ago

As reported by @yuxuanzhuang during the JOSS review, phreeqptyon does not work on Apple silicon, and thereby causes Solution to fail (even though pyEQL can be installed):

s1 = Solution() OSError: dlopen(/xxx/lib/python3.10/site-packages/phreeqpython/./lib/viphreeqc.dylib, 0x0006): tried: '/xxx/lib/python3.10/site-packages/phreeqpython/./lib/viphreeqc.dylib' (mach-o file, but is an incompatible architecture (have 'x86_64', need 'arm64')),

We need to work around this. At a minimum, it should be possible to instantiate and use a Solution without the equilibrate function (which is the only thing that relies on phreeqpython by default).

UPDATE as of v0.14.0

pyEQL currently works on Apple Silicon, but any features that depend on PHREEQC (e.g., the equilibrate method) will raise errors. Changes have been made to the documentation to reflect this, and an Error is logged when you create a Solution on Apple silicon notifying you of the limitation.

It would be great to have full support for Apple silicon; however, it isn't clear to me whether upstream PHREEQC / iphreeqc / phreeqpy support Apple Silicon. If they do, this issue will add motivation to address #61 so that support is not dependent on phreeqpython (as opposed to upstream iphreeqc).

rkingsbury commented 5 months ago

@yuxuanzhuang can you provide a more complete code snippet of the steps that led to this error? I added the macos-14 runner to my CI (which is supposed to be based on an M1 chip) and all tests pass, so I'm a bit puzzled. Thanks!

xiaoxiaozhu123 commented 5 months ago

~As reported by @yuxuanzhuang during the JOSS review, phreeqptyon does not work on Apple silicon, and thereby causes Solution to fail (even though pyEQL can be installed):~

s1 = Solution() OSError: dlopen(/xxx/lib/python3.10/site-packages/phreeqpython/./lib/viphreeqc.dylib, 0x0006): tried: '/xxx/lib/python3.10/site-packages/phreeqpython/./lib/viphreeqc.dylib' (mach-o file, but is an incompatible architecture (have 'x86_64', need 'arm64')),

~We need to work around this. At a minimum, it should be possible to instantiate and use a Solution without the equilibrate function (which is the only thing that relies on phreeqpython by default).~

UPDATE as of v0.14.0

pyEQL currently works on Apple Silicon, but any features that depend on PHREEQC (e.g., the equilibrate method) will raise errors. Changes have been made to the documentation to reflect this, and an Error is logged when you create a Solution on Apple silicon notifying you of the limitation.

It would be great to have full support for Apple silicon; however, it isn't clear to me whether upstream PHREEQC / iphreeqc / phreeqpy support Apple Silicon. If they do, this issue will add motivation to address #61 so that support is not dependent on phreeqpython (as opposed to upstream iphreeqc).

The problem had been confusing me for weeks.... It's because phreeqpython is not compatible with arm64 architecture. SOLUTION IS SIMPLE: If you want to run Solutions with the phreeqc engine, make a python env using a miniconda Intel-x86 installer (despite that it's designated for intel-chip macs, it's compatible with Apple Silicon. The only side effect is loss of performance, but python is already too slow for you to notice this...). At least pyEQL works on my M2 Mac now. DO NOT use the arm64 version installer for macs with M1/M2 chips. Phreeqpython just won't work.

rkingsbury commented 5 months ago

The problem had been confusing me for weeks.... It's because phreeqpython is not compatible with arm64 architecture. SOLUTION IS SIMPLE: If you want to run Solutions with the phreeqc engine, make a python env using a miniconda Intel-x86 installer (despite that it's designated for intel-chip macs, it's compatible with Apple Silicon. The only side effect is loss of performance, but python is already too slow for you to notice this...). At least pyEQL works on my M2 Mac now. DO NOT use the arm64 version installer for macs with M1/M2 chips. Phreeqpython just won't work.

Thanks for posting this solution @xiaoxiaozhu123 ! I'm actually going to be issuing a 1.0 release in the next 1-2 days and I'd love to update the documentation with this. Would you be able to suggest some edits / additions to the "Warning" box on this page? Feel free to post here or open a PR if you're comfortable doing that.

xiaoxiaozhu123 commented 5 months ago

The problem had been confusing me for weeks.... It's because phreeqpython is not compatible with arm64 architecture. SOLUTION IS SIMPLE: If you want to run Solutions with the phreeqc engine, make a python env using a miniconda Intel-x86 installer (despite that it's designated for intel-chip macs, it's compatible with Apple Silicon. The only side effect is loss of performance, but python is already too slow for you to notice this...). At least pyEQL works on my M2 Mac now. DO NOT use the arm64 version installer for macs with M1/M2 chips. Phreeqpython just won't work.

Thanks for posting this solution @xiaoxiaozhu123 ! I'm actually going to be issuing a 1.0 release in the next 1-2 days and I'd love to update the documentation with this. Would you be able to suggest some edits / additions to the "Warning" box on this page? Feel free to post here or open a PR if you're comfortable doing that.

As far as I know, It's impossible toggle the current architecture with just a python script. The only thing we can do is to inform users about compatibility issues and recommend actions they can take to adjust their environment. So it'll be good to execute a platform inspection in pyEQL's init.py. Here is a GPT demonstration:

import platform
import warnings

machine = platform.machine()  # Get the machine type (e.g., 'x86_64', 'arm64')

if machine == 'arm64':
    platform_warning_msg = ...
    warnings.warn(platform_warning_msg)
    disable_functions_related_to_phreeqc() # I guess here'll be similar statements in the future release...
rkingsbury commented 5 months ago

Yes, I do something similar to this in the unit tests right now. There is currently an error message that is raised, which I think is adequate as a technical solution for the time being.

            logger.error(
                "OSError encountered when trying to instantiate phreeqpython. Most likely this means you"
                " are running on an architecture that is not supported by PHREEQC, such as Apple M1/M2 chips."
                " pyEQL will work, but equilibrate() will have no effect."
            )

I have just updated the documentation page, adding the following so that other users can try your workaround. This appears in the Warning box that mentions the challenges with M1/M2.

NOTE: Some users have reported being able to use `phreeqpython` functions by installing 
an x86 version of `conda`/`miniconda`. See the issue report for more details.