Skip to content

Commit 2ca9b6e

Browse files
Merge pull request mala-project#657 from RandomDefaultUser/migrate_to_p13
Migrating MALA to Python 3.13 (and generally newer packages)
2 parents dfc29f1 + d17f17c commit 2ca9b6e

File tree

14 files changed

+264
-167
lines changed

14 files changed

+264
-167
lines changed

Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ RUN conda env create -f mala_${DEVICE}_environment.yml && rm -rf /opt/conda/pkgs
2121
RUN /opt/conda/envs/mala-${DEVICE}/bin/pip install --no-input --no-cache-dir \
2222
pytest \
2323
pytest-cov \
24-
oapackage==2.6.8 \
24+
oapackage==2.7.14 \
2525
pqkmeans
2626

2727
RUN echo "source activate mala-${DEVICE}" > ~/.bashrc

docs/source/install/installing_mala.rst

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@ Prerequisites
55
**************
66

77
MALA supports any Python version starting from ``3.10.4``. No upper limit on
8-
Python versions are enforced. The most recent *tested* version is ``3.10.12``.
8+
Python versions are enforced. The most recent *tested* version is
9+
``3.13.3``.
910

1011
Installing the Python library
1112
*****************************

docs/source/install/installing_qe.rst

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,12 @@ tested with version ``7.2.``, the most recent version at the time of this
1010
release of MALA. Newer versions may work (untested), but installation
1111
instructions may vary.
1212

13+
.. note::
14+
The ``build_total_energy_module.sh`` script uses ``meson`` and ``ninja``
15+
as a build system, which may cause problems with older python versions
16+
(i.e., 3.10.* and 3.11.*). If you encounter problems, please use
17+
``build_total_energy_module_legacy.sh`` located in the same folder.
18+
1319
Make sure you have an (MPI-aware) F90 compiler such as ``mpif90`` (e.g.
1420
Debian-ish machine: ``apt install openmpi-bin``, on an HPC cluster something
1521
like ``module load openmpi gcc``). Make sure to use the same compiler
Lines changed: 61 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,6 @@
11
#!/bin/bash
22

3-
# usage:
4-
#
5-
# $ ./this.sh
6-
# or
7-
# $ F2PY=/usr/bin/f2py3 ./this.sh
8-
9-
set -u
3+
set -ue
104

115
err(){
126
echo "error $@"
@@ -15,6 +9,23 @@ err(){
159

1610
[ $# -eq 1 ] || err "Please provide exactly one argument (the path to the QE directory)" && root_dir=$1
1711

12+
13+
# ----------------------------------------------------------------------------
14+
# Settings to adapt to your machine
15+
# ----------------------------------------------------------------------------
16+
17+
# default: system blas,lapack and fftw, adapt as needed
18+
linalg="-lblas -llapack"
19+
fftw="-lfftw3"
20+
21+
# This is for OpenMPI. Intel MPI's compiler wrappers are called mpiifort and
22+
# mpiicc. Both libraries provide other aliases like mpif90 and mpicc.
23+
f_compiler="mpifort"
24+
c_compiler="mpicc"
25+
26+
# ----------------------------------------------------------------------------
27+
28+
1829
echo "Using QE root dir: $root_dir"
1930

2031
pw_src_path=$root_dir/PW/src
@@ -32,37 +43,54 @@ modobjs="$(find $root_dir/Modules/ -name "*.o")"
3243
[ -n "$utilobjs" ] || err "utilobjs empty"
3344
[ -n "$modobjs" ] || err "modobjs empty"
3445

35-
project_lib_folders=" -L$root_dir/Modules -L$root_dir/KS_Solvers -L$root_dir/FFTXlib/src -L$root_dir/LAXlib -L$root_dir/UtilXlib -L$root_dir/dft-d3 -L$root_dir/upflib -L$root_dir/XClib -L$root_dir/external/devxlib/src -L$root_dir/external/mbd/src"
36-
project_libs="-lqemod -lks_solvers -lqefft -lqela -lutil -ldftd3qe -lupf -ldevXlib -lmbd"
37-
project_inc_folders="-I$root_dir/Modules -I$root_dir/FFTXlib/src -I$root_dir/LAXlib -I$root_dir/KS_Solvers -I$root_dir/UtilXlib -I$root_dir/upflib -I$root_dir/XClib -I$root_dir/external/devxlib/src -I$root_dir/external/mbd/src"
3846

39-
# default: system blas,lapack and fftw, adapt as needed
40-
linalg="-lblas -llapack"
41-
fftw="-lfftw3"
47+
# -lfoo will link shared libs (libfoo.so) as well as static ones (libfoo.a). In
48+
# qe_libs we list the ones we need in total_energy (which are almost all of
49+
# them anyway), but since we are lazy, we use all paths to them as link (-L)
50+
# and include (-I) dirs.
51+
qe_static_lib_dirs=$(find $root_dir -name "*.a" | xargs dirname | sort -u | paste -s -d '@')
52+
qe_lib_dirs=-L$(echo "$qe_static_lib_dirs" | sed -re 's/@/ -L/g')
53+
qe_inc_dirs=-I$(echo "$qe_static_lib_dirs" | sed -re 's/@/ -I/g')
54+
qe_libs="-lks_solvers -lqefft -lqela -lutil -ldftd3qe -lupf -ldevXlib -lmbd"
4255

56+
echo "qe_lib_dirs: $qe_lib_dirs"
57+
echo "qe_inc_dirs: $qe_inc_dirs"
4358

4459
here=$(pwd)
4560
mod_name=total_energy
46-
src=${mod_name}.f90
47-
cp -v $src $pw_src_path/
48-
cd $pw_src_path
49-
rm -vf ${mod_name}.*.so
50-
51-
${F2PY:=f2py} \
52-
--f90exec=mpif90 \
53-
--f77exec=mpif90 \
54-
-c $src \
61+
tmp_lib_dir=$here/libs
62+
meson_builddir=$here/meson_builddir
63+
rm -rf $tmp_lib_dir $meson_builddir
64+
65+
mkdir -p $tmp_lib_dir
66+
# xc_lib.a needs to be called lib<someting>.a to be linkable with -l<something>
67+
cp $root_dir/XClib/xc_lib.a $here/libs/libxclib.a
68+
69+
# Stick all object files into a static lib so that we can link them, just
70+
# specifying them on the f2py CLI doesn't work with the meson backend, as it
71+
# seems.
72+
ar rcs $tmp_lib_dir/liballobjs.a $pwobjs $utilobjs $modobjs
73+
74+
FC="$f_compiler" \
75+
CC="$c_compiler" \
76+
FFLAGS="-I$tmp_lib_dir -I$pw_src_path $qe_inc_dirs" \
77+
LDFLAGS="-L$tmp_lib_dir -L$pw_src_path $qe_lib_dirs" \
78+
python3 -m numpy.f2py \
79+
--backend meson \
80+
--dep mpi \
81+
--build-dir $meson_builddir \
82+
-c ${mod_name}.f90 \
5583
-m $mod_name \
56-
$project_inc_folders \
57-
$project_lib_folders \
58-
$project_libs \
59-
$pwobjs \
60-
$utilobjs \
61-
$modobjs \
6284
$linalg \
6385
$fftw \
64-
$root_dir/XClib/xc_lib.a
65-
66-
rm $src
67-
mv -v ${mod_name}.*.so $here/
68-
cd $here
86+
$qe_libs \
87+
-lallobjs -lxclib
88+
89+
# Workaround for f2py+meson+mpi bug
90+
# (https://github.com/numpy/numpy/issues/28902)
91+
cd $meson_builddir
92+
sed -i -re "s/dependency\('mpi'\)/dependency\('mpi', language: 'fortran')/" meson.build
93+
meson setup --reconfigure bbdir
94+
#meson configure bbdir -Db_lto=true
95+
meson compile -C bbdir
96+
cp -v bbdir/${mod_name}.*.so $here/
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
#!/bin/bash
2+
3+
# usage:
4+
#
5+
# $ ./this.sh
6+
# or
7+
# $ F2PY=/usr/bin/f2py3 ./this.sh
8+
9+
set -u
10+
11+
err(){
12+
echo "error $@"
13+
exit 1
14+
}
15+
16+
[ $# -eq 1 ] || err "Please provide exactly one argument (the path to the QE directory)" && root_dir=$1
17+
18+
echo "Using QE root dir: $root_dir"
19+
20+
pw_src_path=$root_dir/PW/src
21+
22+
# Object files from the PW/src folder
23+
pwobjs="$(find $pw_src_path -name "*.o" | grep -E -v 'generate_vdW_kernel_table|generate_rVV10_kernel_table')"
24+
25+
# Object files from the UtilXlib folder
26+
utilobjs="$(find $root_dir/UtilXlib/ -name "*.o")"
27+
28+
# Object files from the Modules folder
29+
modobjs="$(find $root_dir/Modules/ -name "*.o")"
30+
31+
[ -n "$pwobjs" ] || err "pwobjs empty"
32+
[ -n "$utilobjs" ] || err "utilobjs empty"
33+
[ -n "$modobjs" ] || err "modobjs empty"
34+
35+
project_lib_folders=" -L$root_dir/Modules -L$root_dir/KS_Solvers -L$root_dir/FFTXlib/src -L$root_dir/LAXlib -L$root_dir/UtilXlib -L$root_dir/dft-d3 -L$root_dir/upflib -L$root_dir/XClib -L$root_dir/external/devxlib/src -L$root_dir/external/mbd/src"
36+
project_libs="-lqemod -lks_solvers -lqefft -lqela -lutil -ldftd3qe -lupf -ldevXlib -lmbd"
37+
project_inc_folders="-I$root_dir/Modules -I$root_dir/FFTXlib/src -I$root_dir/LAXlib -I$root_dir/KS_Solvers -I$root_dir/UtilXlib -I$root_dir/upflib -I$root_dir/XClib -I$root_dir/external/devxlib/src -I$root_dir/external/mbd/src"
38+
39+
# default: system blas,lapack and fftw, adapt as needed
40+
linalg="-lblas -llapack"
41+
fftw="-lfftw3"
42+
43+
44+
here=$(pwd)
45+
mod_name=total_energy
46+
src=${mod_name}.f90
47+
cp -v $src $pw_src_path/
48+
cd $pw_src_path
49+
rm -vf ${mod_name}.*.so
50+
51+
${F2PY:=f2py} \
52+
--f90exec=mpif90 \
53+
--f77exec=mpif90 \
54+
-c $src \
55+
-m $mod_name \
56+
$project_inc_folders \
57+
$project_lib_folders \
58+
$project_libs \
59+
$pwobjs \
60+
$utilobjs \
61+
$modobjs \
62+
$linalg \
63+
$fftw \
64+
$root_dir/XClib/xc_lib.a
65+
66+
rm $src
67+
mv -v ${mod_name}.*.so $here/
68+
cd $here

external_modules/total_energy_module/total_energy.f90

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -72,12 +72,8 @@ SUBROUTINE run_pwscf_setup ( exit_status, calculate_eigts)
7272
USE control_flags, ONLY : conv_ions, istep, nstep, restart, lmd, lbfgs, &
7373
lforce => tprnfor
7474
USE command_line_options, ONLY : command_line
75-
USE force_mod, ONLY : sigma, force
7675
USE check_stop, ONLY : check_stop_init, check_stop_now
7776
USE mp_images, ONLY : intra_image_comm
78-
USE extrapolation, ONLY : update_file, update_pot
79-
USE scf, ONLY : rho
80-
USE lsda_mod, ONLY : nspin
8177
USE fft_base, ONLY : dfftp
8278
USE qmmm, ONLY : qmmm_initialization, qmmm_shutdown, &
8379
qmmm_update_positions, qmmm_update_forces
@@ -176,9 +172,6 @@ SUBROUTINE init_run_setup(calculate_eigts)
176172
!! modifications by Normand Modine, August 2020
177173
!
178174
USE kinds, ONLY : DP
179-
USE klist, ONLY : nkstot
180-
USE symme, ONLY : sym_rho_init
181-
USE wvfct, ONLY : nbnd, et, wg, btype
182175
USE control_flags, ONLY : lmd, gamma_only, smallmem, ts_vdw
183176
USE gvect, ONLY : g, gg, eigts1, eigts2, eigts3, mill, gcutm, ig_l2g, ngm, ngm_g, &
184177
gshells, gstart ! to be comunicated to the Solvers if gamma_only

mala/descriptors/ace.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -655,7 +655,7 @@ def __default_settings(self):
655655
lmb_def_str : str
656656
String with default lambda values.
657657
"""
658-
#for each bond type, determine what cutoff radii should be allowed
658+
# for each bond type, determine what cutoff radii should be allowed
659659
# these values (and ranges of values) are determined based on the element type with some defaults provided below
660660
rc_range = {bp: None for bp in self.__bonds}
661661
rin_def = {bp: None for bp in self.__bonds}
@@ -849,7 +849,7 @@ def __init_wigner_3j(self, lmax):
849849
)
850850
)
851851
lmaxes = [
852-
int(os.path.basename(x.split("_")[1].split(".")[0]))
852+
int(os.path.basename(x).split("_")[1].split(".")[0])
853853
for x in raw_list
854854
]
855855
if len(lmaxes) > 0:
@@ -921,7 +921,7 @@ def __init_clebsch_gordan(self, lmax):
921921
)
922922
)
923923
lmaxes = [
924-
int(os.path.basename(x.split("_")[1].split(".")[0]))
924+
int(os.path.basename(x).split("_")[1].split(".")[0])
925925
for x in raw_list
926926
]
927927
if len(lmaxes) > 0:
@@ -986,7 +986,7 @@ def __init_element_arrays(self):
986986

987987
@staticmethod
988988
def __init_element_lists():
989-
#initially, the hard-coded values included vdW radii for elements where available (thus the weird definition of metal here). Where they werent available, other radii were used. We may use ionic radii instead, but we may want to change the factor by which we multiply the radii by to get the default cutoffs. Having them be ~2x the vdW radii is usually a good starting point.
989+
# initially, the hard-coded values included vdW radii for elements where available (thus the weird definition of metal here). Where they werent available, other radii were used. We may use ionic radii instead, but we may want to change the factor by which we multiply the radii by to get the default cutoffs. Having them be ~2x the vdW radii is usually a good starting point.
990990
"""
991991
Initialize a dictionary with ionic/vdW radii and list of metals.
992992

mala/descriptors/bispectrum.py

Lines changed: 17 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
"""Bispectrum descriptor class."""
22

3+
import math
34
import os
45

56
import ase
@@ -659,11 +660,11 @@ def __init_index_arrays(self):
659660
# Needed for the Clebsch-Gordan product matrices (below)
660661

661662
def deltacg(j1, j2, j):
662-
sfaccg = np.math.factorial((j1 + j2 + j) // 2 + 1)
663+
sfaccg = math.factorial((j1 + j2 + j) // 2 + 1)
663664
return np.sqrt(
664-
np.math.factorial((j1 + j2 - j) // 2)
665-
* np.math.factorial((j1 - j2 + j) // 2)
666-
* np.math.factorial((-j1 + j2 + j) // 2)
665+
math.factorial((j1 + j2 - j) // 2)
666+
* math.factorial((j1 - j2 + j) // 2)
667+
* math.factorial((-j1 + j2 + j) // 2)
667668
/ sfaccg
668669
)
669670

@@ -892,26 +893,22 @@ def deltacg(j1, j2, j):
892893
):
893894
ifac = -1 if z % 2 else 1
894895
cgsum += ifac / (
895-
np.math.factorial(z)
896-
* np.math.factorial((j1 + j2 - j) // 2 - z)
897-
* np.math.factorial((j1 - aa2) // 2 - z)
898-
* np.math.factorial((j2 + bb2) // 2 - z)
899-
* np.math.factorial(
900-
(j - j2 + aa2) // 2 + z
901-
)
902-
* np.math.factorial(
903-
(j - j1 - bb2) // 2 + z
904-
)
896+
math.factorial(z)
897+
* math.factorial((j1 + j2 - j) // 2 - z)
898+
* math.factorial((j1 - aa2) // 2 - z)
899+
* math.factorial((j2 + bb2) // 2 - z)
900+
* math.factorial((j - j2 + aa2) // 2 + z)
901+
* math.factorial((j - j1 - bb2) // 2 + z)
905902
)
906903
cc2 = 2 * m - j
907904
dcg = deltacg(j1, j2, j)
908905
sfaccg = np.sqrt(
909-
np.math.factorial((j1 + aa2) // 2)
910-
* np.math.factorial((j1 - aa2) // 2)
911-
* np.math.factorial((j2 + bb2) // 2)
912-
* np.math.factorial((j2 - bb2) // 2)
913-
* np.math.factorial((j + cc2) // 2)
914-
* np.math.factorial((j - cc2) // 2)
906+
math.factorial((j1 + aa2) // 2)
907+
* math.factorial((j1 - aa2) // 2)
908+
* math.factorial((j2 + bb2) // 2)
909+
* math.factorial((j2 - bb2) // 2)
910+
* math.factorial((j + cc2) // 2)
911+
* math.factorial((j - cc2) // 2)
915912
* (j + 1)
916913
)
917914
self.__cglist[idxcg_count] = cgsum * dcg * sfaccg

mala/network/trainer.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -576,7 +576,7 @@ def train_network(self):
576576
):
577577
printout("Checkpointing training.", min_verbosity=0)
578578
self._last_epoch = epoch
579-
self._last_loss = vloss_old
579+
self._last_loss = torch.tensor(vloss_old)
580580
self.__create_training_checkpoint()
581581
checkpoint_counter = 0
582582

mala/targets/dos.py

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -519,7 +519,7 @@ def read_from_qe_out(self, path=None, smearing_factor=2):
519519
atoms_object = self.atoms
520520
else:
521521
atoms_object = ase.io.read(path, format="espresso-out")
522-
kweights = atoms_object.get_calculator().get_k_point_weights()
522+
kweights = atoms_object.calc.get_k_point_weights()
523523
if kweights is None:
524524
raise Exception(
525525
"QE output file does not contain band information."
@@ -551,9 +551,7 @@ def read_from_qe_out(self, path=None, smearing_factor=2):
551551

552552
dos_per_band = gaussians(
553553
self.energy_grid[previous_beginning:size_for_spacing],
554-
atoms_object.get_calculator()
555-
.band_structure()
556-
.energies[0, :, :],
554+
atoms_object.calc.band_structure().energies[0, :, :],
557555
_smearing_factors[spacing_idx] * grid_spacing,
558556
)
559557
dos_per_band = kweights[:, np.newaxis, np.newaxis] * dos_per_band

0 commit comments

Comments
 (0)