Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 52 additions & 0 deletions .github/workflows/Build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,58 @@ jobs:
# uses: mxschmitt/action-tmate@v3
# timeout-minutes: 15

# Build and test QUIP with MPI + ScaLAPACK (Linux only)
build-mpi:
name: Build QUIP with MPI (ubuntu-latest)
runs-on: ubuntu-latest

steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
submodules: 'recursive'

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.12'

- name: Install system dependencies
run: |
sudo apt-get update -y
sudo apt-get install -y gfortran meson ninja-build \
libopenblas-dev liblapack-dev \
libnetcdf-dev libhdf5-serial-dev \
libopenmpi-dev libscalapack-openmpi-dev

- name: Install Python dependencies
run: |
python -m pip install --upgrade pip
pip install numpy ase meson-python build
pip install 'f90wrap>=0.3.0'
env:
FC: gfortran
CC: gcc

- name: Build QUIP libraries (MPI)
run: |
meson setup builddir -Dmpi=true
meson compile -C builddir

- name: Build and install quippy
run: |
cd quippy
pip install .

- name: Run tests (including ScaLAPACK)
run: |
cd tests
BUILDDIR=${{ github.workspace }}/builddir/src/Programs \
HAVE_SCALAPACK=1 \
OMPI_ALLOW_RUN_AS_ROOT=1 \
OMPI_ALLOW_RUN_AS_ROOT_CONFIRM=1 \
python run_all.py

# Builds the QUIP docs webpage image. This only happens ON the public
# branch, after tests pass and pull requests are completed
# TEMPORARILY DISABLED - needs investigation
Expand Down
8 changes: 7 additions & 1 deletion meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ if get_option('gap')
'-DGAP_VERSION='+gap_version_res.stdout().strip(),
'-DHAVE_GAP',
'-DHAVE_TB',
'-DHAVE_QR',
], language:'fortran')
endif

Expand Down Expand Up @@ -65,8 +66,13 @@ add_global_arguments([

if get_option('mpi')
message('MPI ON')
scalapack_dep = dependency('scalapack', required: false)
if not scalapack_dep.found()
message('scalapack not found via pkg-config/cmake, trying system library search')
scalapack_dep = fortran.find_library('scalapack', required: true)
endif
mpi_dep = [
dependency('scalapack'),
scalapack_dep,
dependency('mpi', language: 'fortran'),
dependency('mpi', language: 'c'),
]
Expand Down
2 changes: 1 addition & 1 deletion src/Programs/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ link_quip = [
# gap_fit library (special case - needed before gap_fit_exe)
gap_fit_lib = library('gap_fit',
'../GAP/gap_fit_module.F90',
dependencies: [blas_dep],
dependencies: [blas_dep, mpi_dep],
link_with: link_quip,
)

Expand Down
12 changes: 12 additions & 0 deletions tests/test_gapfit.py
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,13 @@ def check_gap_committee(self, err_tol=0.2):
assert np.all(mean_errs < err_tol)
np.random.seed(None)

def check_qr_path(self):
"""check that QR decomposition was used (requires -DHAVE_QR)"""
with open(self.log_name) as f:
log = f.read()
self.assertIn("Using LAPACK to solve QR", log,
"QR decomposition not used - check -DHAVE_QR is set")

def check_gap_fit(self, ref_file=None):
"""check GP coefficients match expected values"""
assert self.proc.returncode == 0, self.proc
Expand Down Expand Up @@ -226,6 +233,7 @@ def test_si_soap_cur_points(self):
gap = self.get_gap(self.gap_soap_template, 'sparse_method=cur_points')
config = self.get_config('Si.np1.xyz', gap, extra='condition_number_norm=I')
self.run_gap_fit(config)
self.check_qr_path()
self.check_gap_fit(ref_file)

def test_si_distance_2b_uniform(self):
Expand All @@ -234,6 +242,7 @@ def test_si_distance_2b_uniform(self):
gap = self.get_gap(self.gap_distance_2b_template, 'sparse_method=uniform')
config = self.get_config('Si.np1.xyz', gap)
self.run_gap_fit(config)
self.check_qr_path()
self.check_gap_fit(ref_file)

def test_si_two_descriptors(self):
Expand All @@ -244,6 +253,7 @@ def test_si_two_descriptors(self):
gap = ":".join([gap1, gap2])
config = self.get_config('Si.np1.xyz', gap)
self.run_gap_fit(config)
self.check_qr_path()
self.check_gap_fit(ref_file)

def test_sic_distance_2b_uniform(self):
Expand All @@ -252,6 +262,7 @@ def test_sic_distance_2b_uniform(self):
gap = self.get_gap(self.gap_distance_2b_template, 'sparse_method=uniform')
config = self.get_config('SiC.np1.xyz', gap)
self.run_gap_fit(config)
self.check_qr_path()
self.check_gap_fit(ref_file)

def test_si_distance_2b_index(self):
Expand All @@ -261,6 +272,7 @@ def test_si_distance_2b_index(self):
config = self.get_config('Si.np1.xyz', gap)
self.make_first_index_file_from_ref(ref_file, self.index_name_inp)
self.run_gap_fit(config)
self.check_qr_path()
self.check_gap_fit(ref_file)

def test_si_config_file_sparsify_only(self):
Expand Down
Loading