Skip to content

Commit ae86e64

Browse files
authored
Add testing workflow (#1)
- fix LAPACK / BLAS detection - fix issue with Intel and do concurrent - add parallelisation for charge model
1 parent 38b4516 commit ae86e64

10 files changed

Lines changed: 243 additions & 34 deletions

File tree

.github/dco.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
require:
2+
members: false

.github/workflows/build.yml

Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
name: CI
2+
3+
on: [push, pull_request]
4+
5+
env:
6+
BUILD_DIR: _build
7+
8+
jobs:
9+
gcc-build:
10+
runs-on: ${{ matrix.os }}
11+
strategy:
12+
fail-fast: false
13+
matrix:
14+
os: [ubuntu-latest, macos-latest]
15+
16+
env:
17+
FC: gfortran
18+
GCC_V: 9
19+
OMP_NUM_THREADS: 2,1
20+
21+
steps:
22+
- name: Checkout code
23+
uses: actions/checkout@v2
24+
25+
- uses: actions/setup-python@v1
26+
with:
27+
python-version: '3.x'
28+
29+
- name: Install GCC (OSX)
30+
if: contains(matrix.os, 'macos')
31+
run: |
32+
ln -s /usr/local/bin/gfortran-${GCC_V} /usr/local/bin/gfortran
33+
which gfortran-${GCC_V}
34+
which gfortran
35+
36+
- name: Install GCC (Linux)
37+
if: contains(matrix.os, 'ubuntu')
38+
run: |
39+
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-${GCC_V} 100 \
40+
--slave /usr/bin/gfortran gfortran /usr/bin/gfortran-${GCC_V} \
41+
--slave /usr/bin/gcov gcov /usr/bin/gcov-${GCC_V}
42+
43+
- name: Install meson
44+
run: pip3 install meson==0.55.3 ninja
45+
46+
- name: Configure build
47+
run: >-
48+
meson setup ${{ env.BUILD_DIR }}
49+
--buildtype=debug
50+
--warnlevel=0
51+
-Db_coverage=true
52+
-Dlapack=netlib
53+
54+
- name: Build library
55+
run: meson compile -C ${{ env.BUILD_DIR }}
56+
57+
- name: Run unit tests
58+
run: meson test -C ${{ env.BUILD_DIR }} --print-errorlogs --no-rebuild
59+
60+
- name: Upload coverage report
61+
if: contains(matrix.os, 'ubuntu')
62+
run: bash <(curl -s https://codecov.io/bash)
63+
64+
# Test native MinGW Windows build
65+
mingw-build:
66+
runs-on: windows-latest
67+
strategy:
68+
fail-fast: false
69+
matrix:
70+
include: [
71+
{ msystem: MINGW64, arch: x86_64 },
72+
# { msystem: MINGW32, arch: i686 }
73+
]
74+
defaults:
75+
run:
76+
shell: msys2 {0}
77+
steps:
78+
- name: Checkout code
79+
uses: actions/checkout@v2
80+
81+
- name: Setup MSYS2 toolchain
82+
uses: msys2/setup-msys2@v2
83+
with:
84+
msystem: ${{ matrix.msystem }}
85+
update: false
86+
install: >-
87+
git
88+
mingw-w64-${{ matrix.arch }}-gcc-fortran
89+
mingw-w64-${{ matrix.arch }}-openblas
90+
mingw-w64-${{ matrix.arch }}-lapack
91+
mingw-w64-${{ matrix.arch }}-meson
92+
mingw-w64-${{ matrix.arch }}-ninja
93+
94+
- name: Configure build
95+
run: meson setup ${{ env.BUILD_DIR }} -Dla_backend=netlib --warnlevel=0
96+
env:
97+
FC: gfortran
98+
CC: gcc
99+
100+
- name: Build project
101+
run: meson compile -C ${{ env.BUILD_DIR }}
102+
103+
- name: Run unit tests
104+
run: meson test -C ${{ env.BUILD_DIR }} --print-errorlogs --no-rebuild
105+
env:
106+
OMP_NUM_THREADS: 2,1
107+
108+
intel-build:
109+
runs-on: ${{ matrix.os }}
110+
strategy:
111+
fail-fast: false
112+
matrix:
113+
os: [ubuntu-20.04]
114+
fc: [ifort]
115+
116+
env:
117+
FC: ${{ matrix.fc }}
118+
OMP_NUM_THREADS: 2,1
119+
APT_PACKAGES: >-
120+
intel-oneapi-compiler-fortran
121+
intel-oneapi-mkl-devel
122+
123+
steps:
124+
- name: Checkout code
125+
uses: actions/checkout@v2
126+
127+
- uses: actions/setup-python@v1
128+
with:
129+
python-version: '3.x'
130+
131+
- name: Add Intel repository
132+
run: |
133+
wget https://apt.repos.intel.com/intel-gpg-keys/GPG-PUB-KEY-INTEL-SW-PRODUCTS-2023.PUB
134+
sudo apt-key add GPG-PUB-KEY-INTEL-SW-PRODUCTS-2023.PUB
135+
rm GPG-PUB-KEY-INTEL-SW-PRODUCTS-2023.PUB
136+
echo "deb https://apt.repos.intel.com/oneapi all main" | sudo tee /etc/apt/sources.list.d/oneAPI.list
137+
sudo apt-get update
138+
139+
- name: Install Intel oneAPI compiler
140+
run: |
141+
sudo apt-get install ${{ env.APT_PACKAGES }}
142+
source /opt/intel/oneapi/setvars.sh
143+
printenv >> $GITHUB_ENV
144+
145+
- name: Install meson/cmake
146+
run: pip3 install meson==0.56.2 ninja
147+
148+
- name: Configure meson build
149+
run: meson setup ${{ env.BUILD_DIR }} -Dfortran_link_args=-qopenmp
150+
151+
- name: Build library
152+
run: meson compile -C ${{ env.BUILD_DIR }}
153+
154+
- name: Run unit tests
155+
run: meson test -C ${{ env.BUILD_DIR }} --print-errorlogs --no-rebuild

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
# Atomic Partial Charge Model
22

3+
[![Apache-2.0](https://img.shields.io/github/license/grimme-lab/multicharge)](LICENSE)
4+
[![Release](https://img.shields.io/github/v/release/grimme-lab/multicharge)](https://github.com/grimme-lab/multicharge/releases/latest)
5+
[![CI](https://github.com/grimme-lab/multicharge/workflows/CI/badge.svg)](https://github.com/grimme-lab/multicharge/actions)
6+
37
Electronegativity equilibration model for atomic partial charges.
48

59

config/meson.build

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -81,30 +81,28 @@ if lapack_vendor == 'mkl'
8181
elif lapack_vendor == 'openblas'
8282
openblas_dep = dependency('openblas', required: false)
8383
if not openblas_dep.found()
84-
openblas_dep += fc.find_library('openblas_dep')
84+
openblas_dep = fc.find_library('openblas_dep')
8585
endif
8686
lib_deps += openblas_dep
8787
if not fc.links('external dsytrs; call dsytrs(); end', dependencies: openblas_dep)
8888
lapack_dep = dependency('lapack', required: false)
8989
if not lapack_dep.found()
90-
lapack_dep += fc.find_library('lapack')
90+
lapack_dep = fc.find_library('lapack')
9191
endif
9292
lib_deps += lapack_dep
9393
endif
9494

9595
else
9696
lapack_dep = dependency('lapack', required: false)
9797
if not lapack_dep.found()
98-
lapack_dep += fc.find_library('lapack')
98+
lapack_dep = fc.find_library('lapack')
9999
endif
100100
lib_deps += lapack_dep
101-
if not fc.links('external dsymv; call dsymv(); end', dependencies: lapack_dep)
102-
blas_dep = dependency('blas', required: false)
103-
if not blas_dep.found()
104-
lapack_dep += fc.find_library('blas')
105-
endif
106-
lib_deps += blas_dep
101+
blas_dep = dependency('blas', required: false)
102+
if not blas_dep.found()
103+
blas_dep = fc.find_library('blas')
107104
endif
105+
lib_deps += blas_dep
108106
endif
109107

110108
# Create the tool chain library as subproject

src/multicharge/cutoff.f90

Lines changed: 27 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -39,21 +39,37 @@ subroutine get_lattice_points_rep_3d(lat, rep, origin, trans)
3939
itr = 0
4040
if (origin) then
4141
allocate(trans(3, product(2*rep+1)))
42-
do concurrent(ix = 0:rep(1), iy = 0:rep(2), iz = 0:rep(3))
43-
do concurrent(jx = 1:merge(-1, 1, ix > 0):-2, &
44-
& jy = 1:merge(-1, 1, iy > 0):-2, jz = 1:merge(-1, 1, iz > 0):-2)
45-
itr = itr + 1
46-
trans(:, itr) = lat(:, 1)*ix*jx + lat(:, 2)*iy*jy + lat(:, 3)*iz*jz
42+
do ix = 0, rep(1)
43+
do iy = 0, rep(2)
44+
do iz = 0, rep(3)
45+
do jx = 1, merge(-1, 1, ix > 0), -2
46+
do jy = 1, merge(-1, 1, iy > 0), -2
47+
do jz = 1, merge(-1, 1, iz > 0), -2
48+
itr = itr + 1
49+
trans(:, itr) = lat(:, 1)*ix*jx &
50+
& + lat(:, 2)*iy*jy + lat(:, 3)*iz*jz
51+
end do
52+
end do
53+
end do
54+
end do
4755
end do
4856
end do
4957
else
5058
allocate(trans(3, product(2*rep+1)-1))
51-
do concurrent(ix = 0:rep(1), iy = 0:rep(2), iz = 0:rep(3), &
52-
ix > 0 .or. iy > 0 .or. iz > 0)
53-
do concurrent(jx = 1:merge(-1, 1, ix > 0):-2, &
54-
& jy = 1:merge(-1, 1, iy > 0):-2, jz = 1:merge(-1, 1, iz > 0):-2)
55-
itr = itr + 1
56-
trans(:, itr) = lat(:, 1)*ix*jx + lat(:, 2)*iy*jy + lat(:, 3)*iz*jz
59+
do ix = 0, rep(1)
60+
do iy = 0, rep(2)
61+
do iz = 0, rep(3)
62+
if (ix == 0 .and. iy == 0 .and. iz == 0) cycle
63+
do jx = 1, merge(-1, 1, ix > 0), -2
64+
do jy = 1, merge(-1, 1, iy > 0), -2
65+
do jz = 1, merge(-1, 1, iz > 0), -2
66+
itr = itr + 1
67+
trans(:, itr) = lat(:, 1)*ix*jx &
68+
& + lat(:, 2)*iy*jy + lat(:, 3)*iz*jz
69+
end do
70+
end do
71+
end do
72+
end do
5773
end do
5874
end do
5975
end if

src/multicharge/model.f90

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,8 @@ subroutine get_vrhs(self, mol, cn, xvec, dxdcn)
7474
real(wp) :: tmp
7575

7676
if (present(dxdcn)) then
77+
!$omp parallel do default(none) schedule(runtime) &
78+
!$omp shared(mol, self, cn, xvec, dxdcn) private(iat, izp, tmp)
7779
do iat = 1, mol%nat
7880
izp = mol%id(iat)
7981
tmp = self%kcn(izp) / sqrt(cn(iat) + reg)
@@ -82,6 +84,8 @@ subroutine get_vrhs(self, mol, cn, xvec, dxdcn)
8284
end do
8385
dxdcn(mol%nat+1) = 0.0_wp
8486
else
87+
!$omp parallel do default(none) schedule(runtime) &
88+
!$omp shared(mol, self, cn, xvec) private(iat, izp, tmp)
8589
do iat = 1, mol%nat
8690
izp = mol%id(iat)
8791
tmp = self%kcn(izp) / sqrt(cn(iat) + reg)
@@ -124,6 +128,9 @@ subroutine get_amat_0d(self, mol, amat)
124128

125129
amat(:, :) = 0.0_wp
126130

131+
!$omp parallel do default(none) schedule(runtime) &
132+
!$omp reduction(+:amat) shared(mol, self) &
133+
!$omp private(iat, izp, jat, jzp, gam, vec, r2, tmp)
127134
do iat = 1, mol%nat
128135
izp = mol%id(iat)
129136
do jat = 1, iat-1
@@ -162,6 +169,9 @@ subroutine get_amat_3d(self, mol, wsc, alpha, amat)
162169
call get_dir_trans(mol%lattice, dtrans)
163170
call get_rec_trans(mol%lattice, rtrans)
164171

172+
!$omp parallel do default(none) schedule(runtime) &
173+
!$omp reduction(+:amat) shared(mol, self, wsc, dtrans, rtrans, alpha, vol) &
174+
!$omp private(iat, izp, jat, jzp, gam, wsw, vec, dtmp, rtmp)
165175
do iat = 1, mol%nat
166176
izp = mol%id(iat)
167177
do jat = 1, iat-1
@@ -256,6 +266,9 @@ subroutine get_damat_0d(self, mol, qvec, dadr, dadL, atrace)
256266
dadr(:, :, :) = 0.0_wp
257267
dadL(:, :, :) = 0.0_wp
258268

269+
!$omp parallel do default(none) schedule(runtime) &
270+
!$omp reduction(+:atrace, dadr, dadL) shared(mol, self, qvec) &
271+
!$omp private(iat, izp, jat, jzp, gam, r2, vec, dG, dS, dtmp, arg)
259272
do iat = 1, mol%nat
260273
izp = mol%id(iat)
261274
do jat = 1, iat-1
@@ -301,6 +314,11 @@ subroutine get_damat_3d(self, mol, wsc, alpha, qvec, dadr, dadL, atrace)
301314
call get_dir_trans(mol%lattice, dtrans)
302315
call get_rec_trans(mol%lattice, rtrans)
303316

317+
!$omp parallel do default(none) schedule(runtime) &
318+
!$omp reduction(+:atrace, dadr, dadL) &
319+
!$omp shared(mol, self, wsc, alpha, vol, dtrans, rtrans, qvec) &
320+
!$omp private(iat, izp, jat, jzp, img, gam, wsw, vec, dG, dS, &
321+
!$omp& dGr, dSr, dGd, dSd)
304322
do iat = 1, mol%nat
305323
izp = mol%id(iat)
306324
do jat = 1, iat-1

src/multicharge/ncoord.f90

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ subroutine ncoord_erf(mol, trans, cutoff, rcov, cn)
9393
cn(:) = 0.0_wp
9494
cutoff2 = cutoff**2
9595

96-
!$omp parallel do default(none) reduction(+:cn) &
96+
!$omp parallel do default(none) schedule(runtime) reduction(+:cn) &
9797
!$omp shared(mol, trans, cutoff2, rcov) &
9898
!$omp private(jat, itr, izp, jzp, r2, rij, r1, rc, countf)
9999
do iat = 1, mol%nat
@@ -154,8 +154,8 @@ subroutine ncoord_derf(mol, trans, cutoff, rcov, cn, dcndr, dcndL)
154154
dcndL(:, :, :) = 0.0_wp
155155
cutoff2 = cutoff**2
156156

157-
!$omp parallel do default(none) reduction(+:cn, dcndr, dcndL) &
158-
!$omp shared(mol, trans, cutoff2, rcov) &
157+
!$omp parallel do default(none) schedule(runtime) &
158+
!$omp reduction(+:cn, dcndr, dcndL) shared(mol, trans, cutoff2, rcov) &
159159
!$omp private(jat, itr, izp, jzp, r2, rij, r1, rc, countf, countd, sigma)
160160
do iat = 1, mol%nat
161161
izp = mol%id(iat)
@@ -198,7 +198,7 @@ end subroutine ncoord_derf
198198

199199

200200
!> Error function counting function for coordination number contributions.
201-
pure function erf_count(k, r, r0) result(count)
201+
elemental function erf_count(k, r, r0) result(count)
202202

203203
!> Steepness of the counting function.
204204
real(wp), intent(in) :: k
@@ -217,7 +217,7 @@ end function erf_count
217217

218218

219219
!> Derivative of the counting function w.r.t. the distance.
220-
pure function derf_count(k, r, r0) result(count)
220+
elemental function derf_count(k, r, r0) result(count)
221221

222222
!> Steepness of the counting function.
223223
real(wp), intent(in) :: k

src/multicharge/wignerseitz.f90

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -47,21 +47,28 @@ subroutine new_wignerseitz_cell(self, mol)
4747
!> Molecular structure data
4848
type(structure_type), intent(in) :: mol
4949

50-
integer :: iat, jat
50+
integer :: iat, jat, ntr, nimg
51+
integer, allocatable :: tridx(:)
5152
real(wp) :: vec(3)
53+
real(wp), allocatable :: trans(:, :)
5254

53-
call get_lattice_points(mol%periodic, mol%lattice, thr, self%trans)
54-
allocate(self%nimg(mol%nat, mol%nat))
55-
allocate(self%tridx(size(self%trans, 2), mol%nat, mol%nat))
55+
call get_lattice_points(mol%periodic, mol%lattice, thr, trans)
56+
ntr = size(trans, 2)
57+
allocate(self%nimg(mol%nat, mol%nat), self%tridx(ntr, mol%nat, mol%nat), &
58+
& tridx(ntr))
5659

5760
!$omp parallel do default(none) schedule(runtime) collapse(2) &
58-
!$omp shared(mol, self) private(iat, jat, vec)
61+
!$omp shared(mol, trans, self) private(iat, jat, vec, nimg, tridx)
5962
do iat = 1, mol%nat
6063
do jat = 1, mol%nat
6164
vec(:) = mol%xyz(:, iat) - mol%xyz(:, jat)
62-
call get_pairs(self%nimg(jat, iat), self%trans, vec, self%tridx(:, jat, iat))
65+
call get_pairs(nimg, trans, vec, tridx)
66+
self%nimg(jat, iat) = nimg
67+
self%tridx(:, jat, iat) = tridx
6368
end do
6469
end do
70+
71+
call move_alloc(trans, self%trans)
6572

6673
end subroutine new_wignerseitz_cell
6774

@@ -72,8 +79,8 @@ subroutine get_pairs(iws, trans, rij, list)
7279
real(wp), intent(in) :: trans(:, :)
7380
integer, intent(out) :: list(:)
7481

75-
logical :: mask(size(trans, 2))
76-
real(wp) :: dist(size(trans, 2)), vec(3), r2
82+
logical :: mask(size(list))
83+
real(wp) :: dist(size(list)), vec(3), r2
7784
integer :: itr, img, pos
7885

7986
iws = 0

0 commit comments

Comments
 (0)