NCAR / wrf-python

A collection of diagnostic and interpolation routines for use with output from the Weather Research and Forecasting (WRF-ARW) Model.
https://wrf-python.readthedocs.io
Apache License 2.0
392 stars 149 forks source link

aarch64 support #204

Open Makeshift opened 1 year ago

Makeshift commented 1 year ago

Seen a couple issues with people asking for Apple M1 support, but to correctly name the problem: the library won't build on the aarch64/arm64 architecture.

We encountered pretty much this issue with wrf-python today when trying to put together multi-arch container images to support both amd64 and aarch64 hosts. This issue affects all aarch64 machines, not just M1's.

While the wheels for basemap-1.3.6 aren't available for aarch64, when built on an aarch64 build host (with appropriate build tools and geos-3.11.2 compiled and installed previously), basemap seems to install fine. I'd provide Dockerfile samples, but it would be a pain to extract to a simplified example and it fails with some numpy issues later on anyway.

I'll continue bashing my head against it for a bit and see if I can come up with a build process that works for the whole library.

Related: #199, #148

Makeshift commented 1 year ago

Alright well, here's how to fix the basemap issue at least.

This is going to be an extract from a Dockerfile, because I'm still in the middle of debugging this, but just in case anyone happens to want to continue from where I'm inevitably going to leave this, I thought it was worth documenting.

Basemap requires geos to build, and geos doesn't have an aarch64 wheel in the conda-forge repo. So we build geos ourselves:

RUN curl -L "https://download.osgeo.org/geos/geos-3.11.2.tar.bz2" | tar -xvj \
    && cd geos-3.11.2 \
    && make \
    && make install

If you then clone the repo and pip install . as per the installation instructions, it works. You can import wrf-python on aarch64 and it works, as far as I can tell (note: I'm not a python dev, I'm devops engineer working on this to support my python devs, so I got as far as importing it and declaring it worked).

However, this 1) makes nicely defined conda envs impossible because as far as I can tell there's no way to tell conda to skip running setuptools and 2) means you don't get OpenMP support. I don't need OpenMP support, but I'm kinda motivated to see if I can get this working anyway. The reason OpenMP support fails I assume is because there's no aarch64 wheels for pyngl and pynio, which I just opened the "how to compile" page for and I already want to bury myself in sand.

@erogluorhan @wjcapehart @MauricioLorey10 If you only need wrf-python to work and you don't especially care about OpenMP support, this might be enough for you.

edit: simplified the extract a little to remove the unneeded core count stuff

Makeshift commented 1 year ago

The fact that pip install . works but installing via conda/mamba doesn't is rather confounding me. Conda appears to be failing because it's running setup.py, which by the looks of it handles all of the OpenMP stuff via numpy's distutil, which then forces a build and spits out a lot of warnings and errors that look like they're from autogenerated code so I'm having trouble parsing it to actually understand what's wrong.

I can't figure out how to stop conda from calling setup.py, or at least act in exactly the same way pip install does. I would have thought that this conda file would work:

name: test
channels:
    - conda-forge
dependencies:
    - python=3.11.2
    - pip:
      - "--editable=git+https://github.com/Makeshift/wrf-python.git@develop#egg=wrf-python"

(forked repo for my own testing) but it seems no edits to how I'm specifying it in the env definition, nor edits to conda_recipe/meta.yaml or build.sh make much of a difference.

Unfortunately, while getting random stuff built in containers is where I know what I'm doing, Python dependency management very much isn't!

Makeshift commented 1 year ago

I started writing out Dockerfiles for pyngl and pynio to get an aarch64 version building, then realised they need NCL built locally to be able to work, and while I could probably write out a way to compile it, it would take me a few days and I'm not willing to put in the time investment if I'm not sure that's the actual issue. If anyone happens to understand the attached log, I'd appreciate a push in the right direction. micromamba_install_wrf-python.log

Makeshift commented 1 year ago

I was having some weird issues previously, but here's a workaround that appears to work, even if it's not... pretty. Be warned, it skips OpenMP support.

You must also have geos installed as per my second comment to build basemap.

Conda env file:

name: raw_to_cf
channels:
  - conda-forge
  - default
dependencies:
  # Note: Nuitka only supports up to 3.10 at the moment
  - python=3.10.9
  - boto3
  - cloudpathlib
  - xarray
  - netcdf4
  # Ideally this would be in its own env, because it ends up in the final image otherwise
  - conda-pack
  # This is the only way I could find to install currently because of https://github.com/NCAR/wrf-python/issues/204
  # This requires a force reinstall of numpy for conda to think the environment is sane
  #  because pip clobbers it
  # Run this after installation:
  # micromamba install -n base -c conda-forge --force-reinstall numpy
  - pip:
    - wrf-python

pip is managing the install for wrf-python, which clobbers numpy, then you force a reinstall of numpy with micromamba install -n base -c conda-forge --force-reinstall numpy so conda is happy again.

johnseed commented 1 year ago

Very simple

conda create -n wrf -c anaconda python=3.8 Basemap
conda activate wrf
apt update && apt install gcc g++ make cmake gfortran
git clone https://github.com/NCAR/wrf-python.git
pip install .
kkey00 commented 1 year ago

I've been trying to get wrf-python to work on my M1 device as well. I am getting errors about the setup.py file when I try to run pip install .