From 39a7a2f20e563a7218f0b8ac45c5d5f836a68b3a Mon Sep 17 00:00:00 2001 From: Jack Atkinson Date: Thu, 13 Feb 2025 14:57:18 +0000 Subject: [PATCH 1/5] Add instructions for a conda environment on mac that can successfully build FTorch and utilise the MPS backend on Apple Silicon. Co-authored-by: Karl Harrison --- README.md | 9 ++++++--- conda/README.md | 26 ++++++++++++++++++++++++++ conda/environment_mac.yaml | 13 +++++++++++++ 3 files changed, 45 insertions(+), 3 deletions(-) create mode 100644 conda/environment_mac.yaml diff --git a/README.md b/README.md index 393f20ab..0d33212f 100644 --- a/README.md +++ b/README.md @@ -115,9 +115,12 @@ Note that LibTorch is not supported for the GNU Fortran compiler with MinGW. #### Apple Silicon Support -At the time of writing, LibTorch is only officially available for x86 architectures -(according to https://pytorch.org/). However, the version of PyTorch provided by -`pip install torch` uses an ARM binary for LibTorch which works on Apple Silicon. +At the time of writing [there are issues](https://github.com/pytorch/pytorch/issues/143571) +building FTorch on apple silicon when linking to downloaded `LibTorch` binaries or +pip-installed PyTorch. +FTorch can successfully be built, including utilising the MPS backend, from inside a +conda environment using the environment files and instructions in +[`conda/`](https://github.com/Cambridge-ICCS/FTorch/tree/main/conda). #### Conda Support diff --git a/conda/README.md b/conda/README.md index 9090210a..b44c7b79 100644 --- a/conda/README.md +++ b/conda/README.md @@ -74,6 +74,32 @@ cmake --build . --target install Note: There is the option of using `--parallel` to speed this up as described in the main documentation. +### Mac and MPS + +At the time of writing [there are issues](https://github.com/pytorch/pytorch/issues/143571) +building FTorch when linking to downloaded `LibTorch` binaries or pip-installed PyTorch. +FTorch can successfully be built, including utilising the MPS backend, from inside a +conda environment using the environment files provided here. + +From a conda base environment run: +```sh +conda env create -f environment_mac.yaml +``` +from this directory to create the environment and install dependencies. +We install PyTorch using `pip` from within the conda environment which should include +the MPS backend. + +FTorch can then be build with a CMake command similar to the following: +```sh +cmake \ + -DCMAKE_INSTALL_PREFIX=$CONDA_PREFIX \ + -DCMAKE_PREFIX_PATH=$(python -c 'import torch;print(torch.utils.cmake_prefix_path)') \ + -DCMAKE_BUILD_TYPE=Release \ + .. +cmake --build . --target install +``` +Note: There is the option of using `--parallel` to speed this up as described in +the main documentation. ### Other Backends diff --git a/conda/environment_mac.yaml b/conda/environment_mac.yaml new file mode 100644 index 00000000..439cf074 --- /dev/null +++ b/conda/environment_mac.yaml @@ -0,0 +1,13 @@ +name: ftorch-mac +channels: + - conda-forge + - nodefaults +dependencies: + - fortran-compiler + - cxx-compiler + - cmake >=3.15 + - openmpi >=5.0.6 # For pFUnit + - pip + - pip: # We install PyTorch using pip as recommended by PyTorch + - torch + - torchvision From f44500aecbb7526e805c328a0fbf4347381eccd6 Mon Sep 17 00:00:00 2001 From: Jack Atkinson Date: Thu, 15 Aug 2024 11:47:04 +0100 Subject: [PATCH 2/5] Update test-suite workflow to use the fortran-lang github action to access intel compilers. --- .github/workflows/test_suite_ubuntu.yml | 30 ++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/.github/workflows/test_suite_ubuntu.yml b/.github/workflows/test_suite_ubuntu.yml index aab34ede..bce4caf2 100644 --- a/.github/workflows/test_suite_ubuntu.yml +++ b/.github/workflows/test_suite_ubuntu.yml @@ -40,7 +40,21 @@ jobs: strategy: fail-fast: false matrix: - std: ["f2008", "f2018"] + toolchain: + - {compiler: gcc, version: 13} + - {compiler: gcc, version: 12} + - {compiler: gcc, version: 11} + - {compiler: gcc, version: 10} + - {compiler: gcc, version: 9} + - {compiler: intel, version: '2024.1'} + - {compiler: intel-classic, version: '2021.10'} + - {compiler: lfortran, version: '0.33.0'} + - {compiler: nvidia-hpc, version: '23.11'} + std: ["f2008"] + include: + # Run 2018 Fortran standards on latest gcc only + - toolchain: {compiler: gcc, version: 13} + std: "f2018" # Steps represent a sequence of tasks that will be executed as part of the job steps: @@ -50,6 +64,17 @@ jobs: persist-credentials: false uses: actions/checkout@v4 + - name: setup-fortran + uses: fortran-lang/setup-fortran@v1 + with: + compiler: ${{ matrix.toolchain.compiler }} + version: ${{ matrix.toolchain.version }} + + - name: check-compilers-env + run: ${FC} + env: + FC: ${{ steps.setup-fortran.outputs.fc }} + - name: Install Python uses: actions/setup-python@v5 with: @@ -92,6 +117,9 @@ jobs: cmake .. \ -DPython_EXECUTABLE="$(which python)" \ -DCMAKE_BUILD_TYPE=Release \ + -DCMAKE_Fortran_COMPILER=${FC} \ + -DCMAKE_C_COMPILER=${CC} \ + -DCMAKE_CXX_COMPILER=${CXX} \ -DCMAKE_INSTALL_PREFIX=${BUILD_DIR} \ -DCMAKE_BUILD_TESTS=TRUE \ -DCMAKE_PREFIX_PATH="${PFUNIT_DIR};${Torch_DIR}" \ From e50915c1e9a74cd86195fd43a2fd45a2f35f279f Mon Sep 17 00:00:00 2001 From: Jack Atkinson Date: Wed, 18 Dec 2024 17:53:12 +0000 Subject: [PATCH 3/5] Add macos test suite --- .github/workflows/test_suite_macos.yml | 123 +++++++++++++++++++++++++ 1 file changed, 123 insertions(+) create mode 100644 .github/workflows/test_suite_macos.yml diff --git a/.github/workflows/test_suite_macos.yml b/.github/workflows/test_suite_macos.yml new file mode 100644 index 00000000..901b0c53 --- /dev/null +++ b/.github/workflows/test_suite_macos.yml @@ -0,0 +1,123 @@ +# Workflow to run the FTorch test suite +name: TestSuiteMacOS + +# Controls when the workflow will run +on: + # Triggers the workflow on pushes to the "main" branch, i.e., PR merges + push: + branches: [ "main" ] + + # Triggers the workflow on pushes to open pull requests with code changes + pull_request: + paths: + - '.github/workflows/test_suite_macos.yml' + - '**.c' + - '**.cpp' + - '**.fypp' + - '**.f90' + - '**.F90' + - '**.pf' + - '**.py' + - '**.sh' + - '**CMakeLists.txt' + - '**requirements.txt' + - '**data/*' + + # Allows you to run this workflow manually from the Actions tab + workflow_dispatch: + +# Cancel jobs running if new commits are pushed +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + +# Workflow run - one or more jobs that can run sequentially or in parallel +jobs: + # This workflow contains a single job called "test-suite-macos" + test-suite-macos: + # The type of runner that the job will run on + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + include: + # Newest possible gcc on macos-latest (arm64) + - os: macos-latest + toolchain: {compiler: gcc, version: 13} + # Oldest possible gcc on macos-latest (arm64) + - os: macos-latest + toolchain: {compiler: gcc, version: 11} + # Newest possible gcc on macos (x86) + - os: macos-15 + toolchain: {compiler: gcc, version: 13} + - os: macos-13 + toolchain: {compiler: gcc, version: 13} + # Newest possible intel-classic on macos + - os: macos-15 + toolchain: {compiler: intel-classic, version: '2021.10'} + - os: macos-14 + toolchain: {compiler: intel-classic, version: '2021.10'} + - os: macos-13 + toolchain: {compiler: intel-classic, version: '2021.10'} + # Newest possible lfortran on macos + - os: macos-15 + toolchain: {compiler: lfortran, version: '0.33.0'} + - os: macos-14 + toolchain: {compiler: lfortran, version: '0.33.0'} + - os: macos-13 + toolchain: {compiler: lfortran, version: '0.33.0'} + + # Steps represent a sequence of tasks that will be executed as part of the job + steps: + # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it + - name: Checkout code + with: + persist-credentials: false + uses: actions/checkout@v4 + + - name: setup-fortran + uses: fortran-lang/setup-fortran@v1 + with: + compiler: ${{ matrix.toolchain.compiler }} + version: ${{ matrix.toolchain.version }} + + - name: check-compilers-env + run: ${FC} + env: + FC: ${{ steps.setup-fortran.outputs.fc }} + + - name: Install Python + uses: actions/setup-python@v5 + with: + python-version: '3.x' + + - name: Install PyTorch + run: | + python -m pip install --upgrade pip + python -m venv ftorch + . ftorch/bin/activate + pip install torch torchvision --index-url https://download.pytorch.org/whl/cpu + + - name: Build FTorch + run: | + . ftorch/bin/activate + VN=$(python -c "import sys; print('.'.join(sys.version.split('.')[:2]))") + export Torch_DIR=${VIRTUAL_ENV}/lib/python${VN}/site-packages + export BUILD_DIR=$(pwd)/src/build + mkdir ${BUILD_DIR} + cd ${BUILD_DIR} + cmake .. \ + -DPython_EXECUTABLE="$(which python)" \ + -DCMAKE_BUILD_TYPE=Release \ + -DCMAKE_Fortran_COMPILER=${FC} \ + -DCMAKE_C_COMPILER=${CC} \ + -DCMAKE_CXX_COMPILER=${CXX} \ + -DCMAKE_INSTALL_PREFIX=${BUILD_DIR} \ + -DCMAKE_BUILD_TESTS=TRUE + cmake --build . + cmake --install . + + - name: Integration tests + run: | + . ftorch/bin/activate + ./run_integration_tests.sh -V From e934187e1607d6cfdd9cfc444ae37161bc482290 Mon Sep 17 00:00:00 2001 From: Jack Atkinson Date: Tue, 22 Oct 2024 18:10:50 +0100 Subject: [PATCH 4/5] Restrict to python 3.11 to allow torch to be pip installed on macOS. --- .github/workflows/test_suite_macos.yml | 2 +- .github/workflows/test_suite_ubuntu.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/test_suite_macos.yml b/.github/workflows/test_suite_macos.yml index 901b0c53..54a2bfdc 100644 --- a/.github/workflows/test_suite_macos.yml +++ b/.github/workflows/test_suite_macos.yml @@ -89,7 +89,7 @@ jobs: - name: Install Python uses: actions/setup-python@v5 with: - python-version: '3.x' + python-version: '3.11' - name: Install PyTorch run: | diff --git a/.github/workflows/test_suite_ubuntu.yml b/.github/workflows/test_suite_ubuntu.yml index bce4caf2..30682fe9 100644 --- a/.github/workflows/test_suite_ubuntu.yml +++ b/.github/workflows/test_suite_ubuntu.yml @@ -78,7 +78,7 @@ jobs: - name: Install Python uses: actions/setup-python@v5 with: - python-version: '3.x' + python-version: '3.11' - name: Install PyTorch run: | From 1a2a8da2160f34fa46f19a1637a223299d2dcb20 Mon Sep 17 00:00:00 2001 From: Jack Atkinson Date: Thu, 13 Feb 2025 16:23:46 +0000 Subject: [PATCH 5/5] Update mac workflow to try and use a conda environment. --- .github/workflows/test_suite_macos.yml | 45 +++++++++++++++++--------- 1 file changed, 30 insertions(+), 15 deletions(-) diff --git a/.github/workflows/test_suite_macos.yml b/.github/workflows/test_suite_macos.yml index 54a2bfdc..6323cdef 100644 --- a/.github/workflows/test_suite_macos.yml +++ b/.github/workflows/test_suite_macos.yml @@ -1,4 +1,4 @@ -# Workflow to run the FTorch test suite +# Workflow to run the FTorch test suite on Macos platforms name: TestSuiteMacOS # Controls when the workflow will run @@ -66,6 +66,9 @@ jobs: toolchain: {compiler: lfortran, version: '0.33.0'} - os: macos-13 toolchain: {compiler: lfortran, version: '0.33.0'} + defaults: + run: + shell: bash -el {0} # Steps represent a sequence of tasks that will be executed as part of the job steps: @@ -86,38 +89,50 @@ jobs: env: FC: ${{ steps.setup-fortran.outputs.fc }} - - name: Install Python - uses: actions/setup-python@v5 + # Conda following instructions at https://github.com/conda-incubator/setup-miniconda + - name: Setup Conda environment + uses: conda-incubator/setup-miniconda@v3 + continue-on-error: true with: - python-version: '3.11' + environment-file: conda/environment_mac.yaml + activate-environment: ftorch-mac + miniforge-version: latest + - name: Check arm64 + run: | + python -c "import platform; assert platform.machine() == 'arm64', platform.machine()" + + - name: Check conda + run: | + conda info + conda list - - name: Install PyTorch + - name: Install pFUnit run: | - python -m pip install --upgrade pip - python -m venv ftorch - . ftorch/bin/activate - pip install torch torchvision --index-url https://download.pytorch.org/whl/cpu + # TODO: Avoid version pinning (needed because version appears in install path) + git clone -b v4.10.0 https://github.com/Goddard-Fortran-Ecosystem/pFUnit.git + mkdir pFUnit/build + cd pFUnit/build + cmake .. -DCMAKE_INSTALL_PREFIX=$CONDA_PREFIX + make -j 4 install - name: Build FTorch run: | - . ftorch/bin/activate VN=$(python -c "import sys; print('.'.join(sys.version.split('.')[:2]))") - export Torch_DIR=${VIRTUAL_ENV}/lib/python${VN}/site-packages - export BUILD_DIR=$(pwd)/src/build + export BUILD_DIR=$(pwd)/build mkdir ${BUILD_DIR} cd ${BUILD_DIR} + python -c 'import torch;print(torch.utils.cmake_prefix_path)' cmake .. \ - -DPython_EXECUTABLE="$(which python)" \ + -DCMAKE_PREFIX_PATH="${CONDA_PREFIX};$(python -c 'import torch;print(torch.utils.cmake_prefix_path)')" \ -DCMAKE_BUILD_TYPE=Release \ -DCMAKE_Fortran_COMPILER=${FC} \ -DCMAKE_C_COMPILER=${CC} \ -DCMAKE_CXX_COMPILER=${CXX} \ - -DCMAKE_INSTALL_PREFIX=${BUILD_DIR} \ + -DCMAKE_INSTALL_PREFIX=${CONDA_PREFIX} \ -DCMAKE_BUILD_TESTS=TRUE cmake --build . cmake --install . - name: Integration tests run: | - . ftorch/bin/activate ./run_integration_tests.sh -V