Skip to content

Commit 880abe6

Browse files
authored
[fix] fixes for building fpm with ifx (#1125)
2 parents cc704c8 + f4390ae commit 880abe6

30 files changed

+475
-241
lines changed
Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
name: 'Setup Intel oneAPI Environment'
2+
description: 'Sets up Intel oneAPI C++, Fortran compilers and MPI on Windows or Ubuntu runners.'
3+
4+
inputs:
5+
os:
6+
description: 'Operating system of the runner. Must contain "windows" or "ubuntu".'
7+
required: true
8+
type: string
9+
10+
runs:
11+
using: "composite"
12+
steps:
13+
- name: (Windows) Setup VS Build environment
14+
if: contains(inputs.os, 'windows')
15+
uses: seanmiddleditch/gha-setup-vsdevenv@v4
16+
17+
- name: (Windows) Retrieve and Install Intel toolchain
18+
if: contains(inputs.os, 'windows')
19+
shell: pwsh
20+
run: |
21+
$tempDir = "C:\TEMP\intel_install"
22+
New-Item -ItemType Directory -Force -Path $tempDir
23+
cd $tempDir
24+
$installerName = "w_HPCKit_p_2023.0.0.25931_offline.exe" # Consider using inputs.intel_version_windows if added
25+
$installerUrl = "https://registrationcenter-download.intel.com/akdlm/irc_nas/19085/$installerName"
26+
Write-Host "Downloading Intel oneAPI installer..."
27+
curl.exe --output $installerName --url $installerUrl --retry 5 --retry-delay 5 -L # Added -L for potential redirects
28+
Write-Host "Extracting installer..."
29+
Start-Process -FilePath ".\$installerName" -ArgumentList "-s -x -f oneAPI --log extract.log" -Wait -NoNewWindow
30+
Remove-Item ".\$installerName" -Force
31+
Write-Host "Installing oneAPI components..."
32+
# Install C++, Fortran, and MPI development tools silently
33+
Start-Process -FilePath ".\oneAPI\bootstrapper.exe" -ArgumentList "-s --action install --eula=accept --components=""intel.oneapi.win.cpp-compiler:intel.oneapi.win.ifort-compiler:intel.oneapi.win.mpi.devel"" -p=NEED_VS2017_INTEGRATION=0 -p=NEED_VS2019_INTEGRATION=0 -p=NEED_VS2022_INTEGRATION=0 --log-dir=." -Wait -NoNewWindow
34+
Write-Host "Cleaning up extracted files..."
35+
Remove-Item ".\oneAPI" -Force -Recurse
36+
cd ..
37+
Remove-Item $tempDir -Force -Recurse
38+
39+
- name: (Windows) Test that OneAPI is installed
40+
if: contains(inputs.os, 'windows')
41+
shell: pwsh
42+
run: |
43+
$setvarsPath = "C:\Program Files (x86)\Intel\oneAPI\setvars.bat"
44+
$compilerVarsPath = "C:\Program Files (x86)\Intel\oneAPI\compiler\latest\env\vars.bat"
45+
if (-not (Test-Path -Path $setvarsPath -PathType Leaf)) {
46+
Write-Error "Intel oneAPI setvars.bat not found at $setvarsPath"
47+
exit 1
48+
}
49+
if (-not (Test-Path -Path $compilerVarsPath -PathType Leaf)) {
50+
Write-Warning "Intel oneAPI compiler vars.bat not found at $compilerVarsPath. MPI might still work."
51+
# Depending on requirements, you might want to 'exit 1' here too
52+
}
53+
Write-Host "Intel oneAPI installation paths verified."
54+
55+
- name: (Windows) Load OneAPI environment variables
56+
if: contains(inputs.os, 'windows')
57+
shell: cmd
58+
run: |
59+
call "C:\Program Files (x86)\Intel\oneAPI\setvars.bat" > NUL
60+
echo "Setting Intel environment variables..."
61+
echo "PATH=%PATH%" >> %GITHUB_ENV%
62+
echo "INCLUDE=%INCLUDE%" >> %GITHUB_ENV%
63+
echo "LIB=%LIB%" >> %GITHUB_ENV%
64+
REM Add any other specific vars if needed, e.g., for MPI
65+
echo "I_MPI_ROOT=%I_MPI_ROOT%" >> %GITHUB_ENV%
66+
echo "FI_PROVIDER_PATH=%FI_PROVIDER_PATH%" >> %GITHUB_ENV%
67+
echo "MPI_BIN=%MPI_BIN%" >> %GITHUB_ENV%
68+
69+
# --- Ubuntu Intel Setup ---
70+
- name: (Ubuntu) Install prerequisites and Intel GPG key
71+
if: contains(inputs.os, 'ubuntu')
72+
shell: bash
73+
run: |
74+
sudo apt-get update -y -qq
75+
sudo apt-get install -y -qq gpg wget ca-certificates curl gpg-agent software-properties-common
76+
wget -O- https://apt.repos.intel.com/intel-gpg-keys/GPG-PUB-KEY-INTEL-SW-PRODUCTS.PUB | gpg --dearmor | sudo tee /usr/share/keyrings/oneapi-archive-keyring.gpg > /dev/null
77+
78+
- name: (Ubuntu) Add Intel oneAPI repository
79+
if: contains(inputs.os, 'ubuntu')
80+
shell: bash
81+
run: |
82+
echo "deb [signed-by=/usr/share/keyrings/oneapi-archive-keyring.gpg] https://apt.repos.intel.com/oneapi all main" | sudo tee /etc/apt/sources.list.d/oneAPI.list
83+
sudo apt-get update -y -qq
84+
85+
- name: (Ubuntu) Install Intel oneAPI Compilers using fortran-lang action
86+
if: contains(inputs.os, 'ubuntu')
87+
uses: fortran-lang/setup-fortran@v1
88+
with:
89+
compiler: intel
90+
version: 2024.1.0 # Pinned until issue #1090 is resolved
91+
92+
- name: (Ubuntu) Install Intel oneAPI MPI and build dependencies
93+
if: contains(inputs.os, 'ubuntu')
94+
shell: bash
95+
run: |
96+
# Install MPI devel package and common build tools
97+
# The compilers (icc, ifort) should already be installed by setup-fortran action
98+
sudo apt-get install -y -q intel-oneapi-mpi-devel ninja-build cmake libcurl4-gnutls-dev
99+
100+
- name: (Ubuntu) Source oneAPI environment and add to GITHUB_ENV
101+
if: contains(inputs.os, 'ubuntu')
102+
shell: bash
103+
run: |
104+
# Source the main setvars script to set up the environment for this step
105+
# Use --force as we might be in a non-interactive shell
106+
source /opt/intel/oneapi/setvars.sh --force > /dev/null 2>&1
107+
echo "Sourced setvars.sh. Adding key variables to GITHUB_ENV..."
108+
# Explicitly add key variables to GITHUB_ENV for subsequent steps
109+
echo "PATH=$PATH" >> $GITHUB_ENV
110+
echo "LD_LIBRARY_PATH=$LD_LIBRARY_PATH" >> $GITHUB_ENV
111+
echo "LIBRARY_PATH=$LIBRARY_PATH" >> $GITHUB_ENV
112+
echo "CPATH=$CPATH" >> $GITHUB_ENV
113+
echo "CMPLR_ROOT=$CMPLR_ROOT" >> $GITHUB_ENV # Example compiler root
114+
echo "MPI_ROOT=$MPI_ROOT" >> $GITHUB_ENV # MPI root (check actual variable name if needed, e.g., I_MPI_ROOT)
115+
echo "I_MPI_ROOT=$I_MPI_ROOT" >> $GITHUB_ENV # Common variable name for Intel MPI root
116+
echo "FI_PROVIDER_PATH=$FI_PROVIDER_PATH" >> $GITHUB_ENV # Often needed for MPI

.github/workflows/CI.yml

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,14 @@ jobs:
2828
- {compiler: gcc, version: 12}
2929
- {compiler: gcc, version: 13}
3030
- {compiler: gcc, version: 14}
31+
- {compiler: intel, version: 2025.1}
3132
exclude:
32-
# Not yet supported by setup-fortran
33-
- os: windows-latest
34-
toolchain: {compiler: gcc, version: 14}
33+
- os: macos-13 # No Intel on MacOS anymore since 2024
34+
toolchain: {compiler: intel, version: '2025.1'}
35+
- os: windows-latest # Doesn't pass build and tests yet
36+
toolchain: {compiler: intel, version: '2025.1'}
37+
- os: windows-latest # gcc 14 not available on Windows yet
38+
toolchain: {compiler: gcc, version: 14}
3539
include:
3640
- os: ubuntu-latest
3741
os-arch: linux-x86_64
@@ -49,7 +53,7 @@ jobs:
4953
uses: actions/checkout@v4
5054

5155
- name: Setup Fortran compiler
52-
uses: fortran-lang/[email protected].1
56+
uses: fortran-lang/[email protected].3
5357
id: setup-fortran
5458
with:
5559
compiler: ${{ matrix.toolchain.compiler }}
@@ -61,7 +65,7 @@ jobs:
6165
with:
6266
fpm-version: 'v0.8.0'
6367

64-
# Backport gfortran shared libraries to version 10 folder. This is necessary because the macOS release of fpm
68+
# Backport gfortran shared libraries to version 10 folder. This is necessary because the macOS release of fpm
6569
# 0.10.0 used for bootstrapping has these paths hardcoded in the executable.
6670
- name: MacOS patch libgfortran
6771
if: contains(matrix.os, 'macos') && !contains(matrix.toolchain.version, '10')
@@ -73,7 +77,7 @@ jobs:
7377
mkdir /usr/local/opt/gcc@10/lib/gcc
7478
mkdir /usr/local/opt/gcc@10/lib/gcc/10
7579
mkdir /usr/local/lib/gcc/10
76-
ln -fs /usr/local/opt/gcc@${{ matrix.toolchain.version }}/lib/gcc/${{ matrix.toolchain.version }}/libquadmath.0.dylib /usr/local/opt/gcc@10/lib/gcc/10/libquadmath.0.dylib
80+
ln -fs /usr/local/opt/gcc@${{ matrix.toolchain.version }}/lib/gcc/${{ matrix.toolchain.version }}/libquadmath.0.dylib /usr/local/opt/gcc@10/lib/gcc/10/libquadmath.0.dylib
7781
ln -fs /usr/local/opt/gcc@${{ matrix.toolchain.version }}/lib/gcc/${{ matrix.toolchain.version }}/libgfortran.5.dylib /usr/local/opt/gcc@10/lib/gcc/10/libgfortran.5.dylib
7882
ln -fs /usr/local/lib/gcc/${{ matrix.toolchain.version }}/libgcc_s.1.dylib /usr/local/lib/gcc/10/libgcc_s.1.dylib
7983
@@ -96,7 +100,7 @@ jobs:
96100
- name: Build Fortran fpm (bootstrap)
97101
shell: bash
98102
run: |
99-
${{ env.BOOTSTRAP }} build
103+
${{ env.BOOTSTRAP }} build
100104
101105
- name: Run Fortran fpm (bootstrap)
102106
shell: bash
@@ -193,7 +197,7 @@ jobs:
193197
fail-fast: false
194198
matrix:
195199
gcc_v: [11,12,13]
196-
200+
197201
steps:
198202
- uses: actions/checkout@v4
199203

.github/workflows/meta.yml

Lines changed: 41 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,6 @@ jobs:
4444
- os: macos-13
4545
mpi: mpich
4646

47-
4847
steps:
4948
- name: Checkout code
5049
uses: actions/checkout@v4
@@ -70,21 +69,6 @@ jobs:
7069
netcdf
7170
netcdf-fortran
7271
73-
- name: (Windows) Setup VS Build environment
74-
if: contains(matrix.os,'windows') && contains(matrix.mpi,'intel')
75-
uses: seanmiddleditch/gha-setup-vsdevenv@master
76-
77-
- name: (Windows) Retrieve Intel toolchain
78-
if: contains(matrix.os,'windows') && contains(matrix.mpi,'intel')
79-
shell: pwsh
80-
working-directory: C:\TEMP
81-
run: |
82-
curl.exe --output webimage.exe --url https://registrationcenter-download.intel.com/akdlm/irc_nas/19085/w_HPCKit_p_2023.0.0.25931_offline.exe --retry 5 --retry-delay 5
83-
Start-Process -FilePath "webimage.exe" -ArgumentList "-s -x -f oneAPI --log extract.log" -Wait
84-
Remove-Item "webimage.exe" -Force
85-
Start-Process -FilePath "oneAPI\bootstrapper.exe" -ArgumentList "-s --action install --eula=accept --components=""intel.oneapi.win.cpp-compiler:intel.oneapi.win.ifort-compiler:intel.oneapi.win.mpi.devel"" -p=NEED_VS2017_INTEGRATION=0 -p=NEED_VS2019_INTEGRATION=0 -p=NEED_VS2022_INTEGRATION=0 --log-dir=." -Wait
86-
Remove-Item "oneAPI" -Force -Recurse
87-
8872
- name: (Ubuntu) Install gfortran
8973
if: contains(matrix.os,'ubuntu')
9074
run: |
@@ -106,48 +90,66 @@ jobs:
10690
sudo apt install -y -q mpich hwloc fabric libhdf5-dev libhdf5-fortran-102 \
10791
libnetcdf-dev libnetcdff-dev
10892
109-
- name: (Ubuntu) Retrieve Intel toolchain
110-
if: contains(matrix.os,'ubuntu') && contains(matrix.mpi,'intel')
111-
timeout-minutes: 1
112-
run: |
113-
wget -O- https://apt.repos.intel.com/intel-gpg-keys/GPG-PUB-KEY-INTEL-SW-PRODUCTS.PUB | gpg --dearmor | sudo tee /usr/share/keyrings/oneapi-archive-keyring.gpg > /dev/null
114-
echo "deb [signed-by=/usr/share/keyrings/oneapi-archive-keyring.gpg] https://apt.repos.intel.com/oneapi all main" | sudo tee /etc/apt/sources.list.d/oneAPI.list
115-
sudo apt-get update
93+
# Intel
11694

117-
- name: (Ubuntu) Install Intel oneAPI
118-
if: contains(matrix.os,'ubuntu') && contains(matrix.mpi,'intel')
119-
uses: fortran-lang/[email protected]
120-
id: setup-fortran
95+
- name: Setup Intel Environment
96+
if: contains(matrix.mpi, 'intel')
97+
uses: ./.github/actions/setup-intel
12198
with:
122-
compiler: intel
123-
version: 2024.1.0
99+
os: ${{ matrix.os }}
124100

125-
- name: (Ubuntu) finalize oneAPI environment
126-
if: contains(matrix.os,'ubuntu') && contains(matrix.mpi,'intel')
101+
- name: (Ubuntu) Build and Install HDF5 from source
102+
if: contains(matrix.os, 'ubuntu') && contains(matrix.mpi, 'intel')
103+
# Needs checkout if source code isn't available, adjust if needed
104+
# Ensure compilers are available from the previous step's environment setup
105+
shell: bash
127106
run: |
128-
# Install MPI
129-
sudo apt-get install -y -q intel-oneapi-mpi-devel ninja-build cmake libcurl4-gnutls-dev
107+
# Source again just in case shell context is lost (shouldn't be, but safer)
130108
source /opt/intel/oneapi/setvars.sh --force
131-
printenv >> $GITHUB_ENV
132-
# To run HDF5 with oneAPI, we need to build it from source. Use CMake to generate pkg-config info
109+
# Download HDF5
133110
curl -O -L https://github.com/HDFGroup/hdf5/archive/refs/tags/snapshot-1.14.tar.gz
134111
tar zxf snapshot-1.14.tar.gz
135112
cd hdf5-snapshot-1.14
113+
# Configure HDF5 with Intel compilers
136114
cmake -B build -DCMAKE_Fortran_COMPILER=ifx -DCMAKE_C_COMPILER=icx -DCMAKE_CXX_COMPILER=icpx -DHDF5_BUILD_FORTRAN=ON -DCMAKE_INSTALL_PREFIX=/usr
137115
cd build
138-
make -j
116+
make -j $(nproc)
139117
sudo make install
118+
cd ../.. # Go back to workspace directory
119+
rm -rf hdf5-snapshot-1.14 snapshot-1.14.tar.gz # Clean up
120+
121+
- name: (Ubuntu) Build and Install NetCDF-C from source
122+
if: contains(matrix.os, 'ubuntu') && contains(matrix.mpi, 'intel')
123+
shell: bash
124+
run: |
125+
source /opt/intel/oneapi/setvars.sh --force
126+
# Download NetCDF-C
140127
curl -L https://github.com/Unidata/netcdf-c/archive/refs/tags/v4.9.2.tar.gz -o - | tar xz
141128
cd netcdf-c-4.9.2
142-
CC=icx CXX=icpx FC=ifx ./configure --prefix=/usr --with-hdf5=/usr
143-
CC=icx CXX=icpx FC=ifx make -j
129+
# Configure NetCDF-C with Intel Compilers, referencing installed HDF5
130+
# Set CC/CXX/FC explicitly in environment for configure script
131+
export CC=icx CXX=icpx FC=ifx
132+
./configure --prefix=/usr --enable-netcdf-4 --with-hdf5=/usr
133+
make -j $(nproc)
144134
sudo make install
135+
cd .. # Go back to workspace directory
136+
rm -rf netcdf-c-4.9.2 # Clean up
137+
138+
- name: (Ubuntu) Build and Install NetCDF-Fortran from source
139+
if: contains(matrix.os, 'ubuntu') && contains(matrix.mpi, 'intel')
140+
shell: bash
141+
run: |
142+
source /opt/intel/oneapi/setvars.sh --force
143+
# Download NetCDF-Fortran
145144
curl -L https://github.com/Unidata/netcdf-fortran/archive/refs/tags/v4.6.1.tar.gz -o - | tar xz
146145
cd netcdf-fortran-4.6.1
146+
# Configure NetCDF-Fortran with Intel Compilers using CMake
147147
cmake -B build -DCMAKE_Fortran_COMPILER=ifx -DCMAKE_C_COMPILER=icx -DCMAKE_CXX_COMPILER=icpx -DCMAKE_INSTALL_PREFIX=/usr
148148
cd build
149-
make -j
149+
make -j $(nproc)
150150
sudo make install
151+
cd ../.. # Go back to workspace directory
152+
rm -rf netcdf-fortran-4.6.1 # Clean up
151153
152154
- name: (Windows) Put MSYS2_MinGW64 on PATH
153155
if: contains(matrix.os,'windows') && (!contains(matrix.mpi,'intel'))
@@ -168,26 +170,13 @@ jobs:
168170
# can't use MSMPI_BIN as Actions doesn't update PATH from msmpisetup.exe
169171
run: Test-Path "C:\Program Files\Microsoft MPI\Bin\mpiexec.exe" -PathType leaf
170172

171-
- name: (Windows) test that OneAPI is installed
172-
if: contains(matrix.os,'windows') && contains(matrix.mpi,'intel')
173-
run: |
174-
Test-Path -Path "C:\Program Files (x86)\Intel\oneAPI\setvars.bat" -PathType leaf
175-
Test-Path -Path "C:\Program Files (x86)\Intel\oneAPI\compiler\latest\env\vars.bat" -PathType leaf
176-
177173
- name: (Windows) put MSMPI_BIN on PATH (where mpiexec is)
178174
if: contains(matrix.os,'windows') && contains(matrix.mpi,'msmpi')
179175
run: |
180176
echo "C:\Program Files\Microsoft MPI\Bin\" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
181177
echo "/c/Program Files/Microsoft MPI/Bin/" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
182178
echo "MSMPI_BIN=C:\Program Files\Microsoft MPI\Bin\" | Out-File -FilePath $env:GITHUB_ENV -Append
183179
184-
- name: (Windows) load OneAPI environment variables
185-
if: contains(matrix.os,'windows') && contains(matrix.mpi,'intel')
186-
shell: cmd
187-
run: |
188-
"C:\Program Files (x86)\Intel\oneAPI\setvars.bat"
189-
"C:\Program Files (x86)\Intel\oneAPI\compiler\latest\env\vars.bat"
190-
191180
- name: (Windows) Install MSYS2 msmpi package
192181
if: contains(matrix.os,'windows') && contains(matrix.mpi,'msmpi')
193182
shell: msys2 {0}

ci/run_tests.sh

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ test -e demo1.txt
6565
test -e demo2.txt
6666
popd
6767

68-
# Test building individual targets
68+
# Test building individual targets
6969
pushd many_targets
7070
cases=( "1" "2" "3" )
7171
targets=( "run" "example" "test" )
@@ -75,16 +75,16 @@ do
7575
for i in {0..2}
7676
do
7777
rm -f *.txt
78-
this=${cases[$i]}
78+
this=${cases[$i]}
7979
others=${cases[@]/$this}
8080
filename=${targets[$j]}$this
8181
echo "$filename"
82-
"$fpm" ${cmdrun[$j]} $filename
82+
"$fpm" ${cmdrun[$j]} $filename
8383
test -e $filename.txt
8484
# non-i-th tests should not have run
8585
for k in ${others[@]}
8686
do
87-
test ! -e ${targets[$k]}$k.txt
87+
test ! -e ${targets[$k]}$k.txt
8888
done
8989
done
9090
done
@@ -93,22 +93,22 @@ done
9393
if [[ "$(which time)" ]]; then
9494
targets=( "run" "run --example" "test" )
9595
names=( "run" "example" "test" )
96-
cmdrun=( " " " --runner time" )
96+
cmdrun=( " " " --runner time" )
9797
for j in {0..2}
9898
do
9999
for i in {0..1}
100100
do
101101
rm -f *.txt
102-
"$fpm" ${targets[$j]}${cmdrun[$i]}
102+
"$fpm" ${targets[$j]}${cmdrun[$i]}
103103
# all targets should have run
104104
for k in ${cases[@]}
105105
do
106-
test -e ${names[$j]}$k.txt
106+
test -e ${names[$j]}$k.txt
107107
done
108108
done
109109
done
110110
fi
111-
popd
111+
popd
112112

113113

114114
pushd auto_discovery_off
@@ -259,7 +259,11 @@ test $EXIT_CODE -eq 3
259259
# not an integer -> error 2
260260
EXIT_CODE=0
261261
"$fpm" run -- 3.1415 || EXIT_CODE=$?
262-
test $EXIT_CODE -eq 2
262+
if [[ "$FPM_FC" == "ifx" ]]; then
263+
test $EXIT_CODE -eq 0 # ifx does not return error code on non-integer input
264+
else
265+
test $EXIT_CODE -eq 2
266+
fi
263267

264268
# not a number -> error 2
265269
EXIT_CODE=0

fpm-docs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Subproject commit 2bb2038142e926c55eeea961f55506903c5b6827

0 commit comments

Comments
 (0)