From 9052192310b4e44ddf0bb11a6cabbc376f2a4e55 Mon Sep 17 00:00:00 2001 From: gbrunin Date: Thu, 14 Apr 2022 14:26:45 +0200 Subject: [PATCH 1/7] Updated the e-ph plotting script --- abipy/examples/plot/advanced/plot_eph_flow.py | 79 ++++++++++++------- 1 file changed, 49 insertions(+), 30 deletions(-) diff --git a/abipy/examples/plot/advanced/plot_eph_flow.py b/abipy/examples/plot/advanced/plot_eph_flow.py index cb768c324..6d0c58373 100644 --- a/abipy/examples/plot/advanced/plot_eph_flow.py +++ b/abipy/examples/plot/advanced/plot_eph_flow.py @@ -1,14 +1,29 @@ +#!/usr/bin/env python +r""" +Alas mobility +============= + +This example shows how to plot the electronic band structure, +phonon dispersion, electron linewidths and +the convergence of the electron mobility in the case of AlAs +(see example e-ph mobility flow). +Only electrons are considered, but the script can easily be +extended to holes (and combination of e/h as well). +""" + +#%% + import numpy as np +import matplotlib as mlp import matplotlib.pyplot as plt from abipy.abilab import abiopen -import os import glob from abipy.eph.rta import RtaRobot root = "../../flows/flow_eph_mob/" -fz = 13 -mz = 2 +fz = 13 # Fontsize for text, labels,... +mz = 2 # Markersize for dots (linewidths plot) fig, axes = plt.subplots(2, 2) plt.subplots_adjust(wspace=0.35, hspace=0.33) @@ -39,7 +54,7 @@ labels = [label for tick, label in enumerate(ebands.kpoints.names) if label != None] axes[0, 0].set_xticks(ticks, [], size=fz) for tick in ticks: - axes[0, 0].plot([tick, tick], [-100, 100], '-k', linewidth=1/2, alpha=0.6) + axes[0, 0].axvline(tick, color='k', linewidth=1/2, alpha=0.6) # Set limits of the axis axes[0, 0].set_xlim([ticks[0], ticks[-1]]) @@ -53,6 +68,7 @@ ### # Open the DDB file and get phonon dispersion +# Can be used to check the phonon dispersion obtained with the e-ph code with abiopen(root + "w1/outdata/out_DDB") as abifile: phbst, phdos = abifile.anaget_phbst_and_phdos_files(ndivsm=10) @@ -64,7 +80,7 @@ labels = [label for tick, label in enumerate(phbst.qpoints.names) if label != None] axes[1, 0].set_xticks(ticks, labels, size=fz-2) for tick in ticks: - axes[1, 0].plot([tick, tick], [-100, 100], '-k', linewidth=1/2, alpha=0.6) + axes[1, 0].axvline(tick, color='k', linewidth=1/2, alpha=0.6) # Set limits of the axis axes[1, 0].set_xlim([ticks[0], ticks[-1]]) @@ -80,21 +96,32 @@ # We get the linewidths for the densest mesh computed # We open the SIGEPH file corresponding to this task with abiopen(root + 'w3/t2/outdata/out_SIGEPH.nc') as abifile: - qplist = abifile.reader.read_allqps()[0] - eigs = qplist.get_field_itemp(field="qpe", itemp=0).real - lws = 2000*qplist.get_field_itemp(field="fan0", itemp=0).imag # Factor or 2x1000 to get from linewidths to 1/tau in meV - -# The zero of the energy axis is the CBM if there are holes, + # First within SERTA + qparray = abifile.get_qp_array(mode="ks+lifetimes", rta_type="serta") + qparray = qparray[np.nonzero(qparray)] + eigs = qparray.real + lws = 2000*qparray.imag # Factor or 2x1000 to get from linewidths to 1/tau in meV + + # Then within MRTA + qparray_mrta = abifile.get_qp_array(mode="ks+lifetimes", rta_type="mrta") + qparray_mrta = qparray_mrta[np.nonzero(qparray_mrta)] + eigs_mrta = qparray_mrta.real + lws_mrta = 2000*qparray_mrta.imag + +# The zero of the energy axis is the CBM zero = np.min(eigs) # CBM -# Plot 1/tau for electrons only : much easier -axes[0, 1].plot(eigs-zero, lws, 'ok', markersize=mz) -xlabel = r'$\varepsilon_{n\mathbf{k}} - \varepsilon_{\mathrm{CBM}}$ (eV)' +# Plot 1/tau +axes[0, 1].plot(eigs-zero, lws, 'ob', markersize=mz, label='SERTA') +axes[0, 1].plot(eigs_mrta-zero, lws_mrta, 'xr', markersize=mz, label='MRTA') + axes[0, 1].set_xticks([0, 0.25], ['0', '0.25']) -# Set the axis labels -axes[0, 1].set_xlabel(xlabel, labelpad=2, fontsize=fz) +# Set the axis labels and legend +axes[0, 1].set_xlabel(r'$\varepsilon_{n\mathbf{k}} - \varepsilon_{\mathrm{CBM}}$ (eV)', labelpad=2, fontsize=fz) axes[0, 1].set_ylabel(r'$\tau_{n\mathbf{k}}^{-1}$ (meV)', fontsize=fz) +axes[0, 1].legend(loc='best', labelcolor='linecolor') + ### ### Lower right : convergence of the mobility @@ -103,24 +130,16 @@ # First we find all the RTA.nc files abifiles = glob.glob(root+'w*/t*/outdata/*RTA.nc') -# We create a robot with these files and get the k-meshes and mobilities -# Alternatively we could sort the files and get the data ourselves +# We create a robot with these files and plot the mobilities robot = RtaRobot.from_files(abifiles) -figconv = robot.plot_mobility_kconv(eh=0, bte=["ibte"], show=False) +robot.plot_mobility_kconv(eh=0, bte=["ibte", "mrta", "serta"], ax=axes[1, 1], show=False, ax_grid=False) -# xdata : ngkpt, ydata: IBTE mobility -xdata = figconv.axes[0].lines[0].get_xdata() -ydata = figconv.axes[0].lines[0].get_ydata() - -# We plot the convergence on our axes -axes[1, 1].plot(xdata, ydata, '-ok') -# Set the xticks on the ngkpt values -axes[1, 1].set_xticks(xdata) -# Set the yticks at the minimum and maximum mobilities only -axes[1, 1].set_yticks([ydata[0], ydata[-1]], [int(np.round(ydata[0])), int(np.round(ydata[-1]))]) -# Set the labels +# Tune the plot +axes[1, 1].set_title(None) +axes[1, 1].legend(fontsize=fz, framealpha=0.5) axes[1, 1].set_xlabel('$N_k \\times$ $N_k \\times$ $N_k$ $\\mathbf{k}$-point grid', fontsize=fz) -axes[1, 1].set_ylabel(r'$\mu_e^\mathrm{IBTE}$'+' (cm$^2$/(V$\\cdot$s))', fontsize=fz) +axes[1, 1].set_ylabel(r'$\mu_e$'+' (cm$^2$/(V$\\cdot$s))', fontsize=fz) + # We save the figure in pdf format fig.savefig(pretty_formula + ".pdf", bbox_inches='tight') From 209efc9e7077aa6879d651c026353dc432891aa0 Mon Sep 17 00:00:00 2001 From: gbrunin Date: Thu, 14 Apr 2022 15:31:36 +0200 Subject: [PATCH 2/7] Make use of decorators for band structures --- abipy/examples/plot/advanced/plot_eph_flow.py | 51 ++++++------------- 1 file changed, 15 insertions(+), 36 deletions(-) diff --git a/abipy/examples/plot/advanced/plot_eph_flow.py b/abipy/examples/plot/advanced/plot_eph_flow.py index 6d0c58373..9ef2ade88 100644 --- a/abipy/examples/plot/advanced/plot_eph_flow.py +++ b/abipy/examples/plot/advanced/plot_eph_flow.py @@ -10,7 +10,6 @@ Only electrons are considered, but the script can easily be extended to holes (and combination of e/h as well). """ - #%% import numpy as np @@ -46,22 +45,12 @@ pretty_formula = "".join([i for i in formula if i != str(1) and i != " "]) # Remove '1's and spaces fig.suptitle(pretty_formula) -# Plot the bands -ebands.plot_ax(axes[0,0], e0="fermie", color="black") - -# Decorate the axes with the correct ticks and labels -ticks = [tick for tick, label in enumerate(ebands.kpoints.names) if label != None] -labels = [label for tick, label in enumerate(ebands.kpoints.names) if label != None] -axes[0, 0].set_xticks(ticks, [], size=fz) -for tick in ticks: - axes[0, 0].axvline(tick, color='k', linewidth=1/2, alpha=0.6) - -# Set limits of the axis -axes[0, 0].set_xlim([ticks[0], ticks[-1]]) -axes[0, 0].set_ylim([-3, 6]) +# Plot the bands (keep only the grid on the x-axis) +ebands.plot(ax=axes[0,0], show=False, linewidth=1.5, ylims=(-3, 6), ax_grid=False) # Set label axes[0, 0].set_ylabel('Energy (eV)', fontsize=fz) +axes[0, 0].set_xlabel(None) ### ### Lower left : phonon dispersion @@ -72,22 +61,12 @@ with abiopen(root + "w1/outdata/out_DDB") as abifile: phbst, phdos = abifile.anaget_phbst_and_phdos_files(ndivsm=10) -# Plot phonon dispersion -phbst.phbands.plot_ax(axes[1,0], branch=None, units="mev", color="black") - -# Decorate the axes with the correct ticks and labels -ticks = [tick for tick, label in enumerate(phbst.qpoints.names) if label != None] -labels = [label for tick, label in enumerate(phbst.qpoints.names) if label != None] -axes[1, 0].set_xticks(ticks, labels, size=fz-2) -for tick in ticks: - axes[1, 0].axvline(tick, color='k', linewidth=1/2, alpha=0.6) - -# Set limits of the axis -axes[1, 0].set_xlim([ticks[0], ticks[-1]]) -axes[1, 0].set_ylim([0, np.max(phbst.phbands.phfreqs)*1000+1]) +# Plot phonon dispersion (keep only the grid on the x-axis) +phbst.phbands.plot(ax=axes[1,0], show=False, units="mev", linewidth=1.5, ax_grid=False) # Set label axes[1, 0].set_ylabel('Frequency (meV)', fontsize=fz) +axes[1, 0].set_xlabel(None) ### ### Upper right : linewidths @@ -99,21 +78,18 @@ # First within SERTA qparray = abifile.get_qp_array(mode="ks+lifetimes", rta_type="serta") qparray = qparray[np.nonzero(qparray)] - eigs = qparray.real + eigs = qparray.real - np.min(qparray.real) # 0 to CBM lws = 2000*qparray.imag # Factor or 2x1000 to get from linewidths to 1/tau in meV # Then within MRTA qparray_mrta = abifile.get_qp_array(mode="ks+lifetimes", rta_type="mrta") qparray_mrta = qparray_mrta[np.nonzero(qparray_mrta)] - eigs_mrta = qparray_mrta.real + eigs_mrta = qparray_mrta.real - np.min(qparray_mrta.real) # 0 to CBM lws_mrta = 2000*qparray_mrta.imag -# The zero of the energy axis is the CBM -zero = np.min(eigs) # CBM - # Plot 1/tau -axes[0, 1].plot(eigs-zero, lws, 'ob', markersize=mz, label='SERTA') -axes[0, 1].plot(eigs_mrta-zero, lws_mrta, 'xr', markersize=mz, label='MRTA') +axes[0, 1].plot(eigs, lws, 'ob', markersize=mz, label='SERTA') +axes[0, 1].plot(eigs_mrta, lws_mrta, 'xr', markersize=mz, label='MRTA') axes[0, 1].set_xticks([0, 0.25], ['0', '0.25']) @@ -132,7 +108,7 @@ # We create a robot with these files and plot the mobilities robot = RtaRobot.from_files(abifiles) -robot.plot_mobility_kconv(eh=0, bte=["ibte", "mrta", "serta"], ax=axes[1, 1], show=False, ax_grid=False) +robot.plot_mobility_kconv(ax=axes[1, 1], eh=0, bte=["ibte", "mrta", "serta"], show=False, ax_grid=False) # Tune the plot axes[1, 1].set_title(None) @@ -140,6 +116,9 @@ axes[1, 1].set_xlabel('$N_k \\times$ $N_k \\times$ $N_k$ $\\mathbf{k}$-point grid', fontsize=fz) axes[1, 1].set_ylabel(r'$\mu_e$'+' (cm$^2$/(V$\\cdot$s))', fontsize=fz) - +# Reactivate the grid on the x-axis for the band structures +axes[0, 0].grid(True, axis='x') +axes[1, 0].grid(True, axis='x') + # We save the figure in pdf format fig.savefig(pretty_formula + ".pdf", bbox_inches='tight') From 3e58a885a315e99bba0f325669a236452e547eec Mon Sep 17 00:00:00 2001 From: gbrunin Date: Fri, 1 Dec 2023 15:14:30 +0100 Subject: [PATCH 3/7] Modified EventReport.stat to allow for paths that are not found on the local machine. --- abipy/flowtk/events.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/abipy/flowtk/events.py b/abipy/flowtk/events.py index 99e2d0aaa..80b94bdc3 100644 --- a/abipy/flowtk/events.py +++ b/abipy/flowtk/events.py @@ -273,7 +273,10 @@ def __init__(self, filename: str, events=None): events: List of Event objects """ self.filename = os.path.abspath(filename) - self.stat = os.stat(self.filename) + try: + self.stat = os.stat(self.filename) + except FileNotFoundError: + self.stat = None self.start_datetime, self.end_datetime = None, None self._events = [] From 9b11d60f2f99cc4ac44da5e0c8d5a035c455020d Mon Sep 17 00:00:00 2001 From: gbrunin Date: Fri, 1 Dec 2023 15:29:41 +0100 Subject: [PATCH 4/7] Clean up of old stuff. --- abipy/examples/plot/advanced/plot_eph_flow.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/abipy/examples/plot/advanced/plot_eph_flow.py b/abipy/examples/plot/advanced/plot_eph_flow.py index 212c3070f..b9a37ca9b 100755 --- a/abipy/examples/plot/advanced/plot_eph_flow.py +++ b/abipy/examples/plot/advanced/plot_eph_flow.py @@ -4,11 +4,11 @@ ============= This example shows how to plot the electronic band structure, -phonon dispersion, electron linewidths and -the convergence of the electron mobility in the case of AlAs +phonon dispersion, electron linewidths and +the convergence of the electron mobility in the case of AlAs (see example e-ph mobility flow). Only electrons are considered, but the script can easily be -extended to holes (and combination of e/h as well). +extended to holes (and combination of e/h as well). """ #%% @@ -80,13 +80,13 @@ qparray = qparray[np.nonzero(qparray)] eigs = qparray.real - np.min(qparray.real) # 0 to CBM lws = 2000*qparray.imag # Factor or 2x1000 to get from linewidths to 1/tau in meV - + # Then within MRTA qparray_mrta = abifile.get_qp_array(mode="ks+lifetimes", rta_type="mrta") qparray_mrta = qparray_mrta[np.nonzero(qparray_mrta)] eigs_mrta = qparray_mrta.real - np.min(qparray_mrta.real) # 0 to CBM lws_mrta = 2000*qparray_mrta.imag - + # Plot 1/tau axes[0, 1].plot(eigs, lws, 'ob', markersize=mz, label='SERTA') axes[0, 1].plot(eigs_mrta, lws_mrta, 'xr', markersize=mz, label='MRTA') From 2abee5d6d79f275e8bea60dfac04908cb7e972c5 Mon Sep 17 00:00:00 2001 From: gbrunin Date: Fri, 19 Jul 2024 16:01:33 +0200 Subject: [PATCH 5/7] Update of memory units. Tests fixing. --- abipy/abilab.py | 2 +- abipy/core/mixins.py | 12 ++++++------ abipy/data/managers/dragon1_manager.yml | 2 +- abipy/data/managers/gmac_manager.yml | 2 +- abipy/data/managers/hercules_manager.yml | 2 +- abipy/data/managers/hmem_manager.yml | 6 +++--- abipy/data/managers/juqueen_manager.yml | 4 ++-- abipy/data/managers/jureca_manager.yml | 4 ++-- abipy/data/managers/lemaitre2_manager.yml | 2 +- abipy/data/managers/lemaitre3_manager.yml | 2 +- abipy/data/managers/lumi_manager.yml | 2 +- abipy/data/managers/manneback_manager.yml | 6 +++--- abipy/data/managers/nic4_manager.yml | 2 +- abipy/data/managers/shell_manager.yml | 2 +- abipy/data/managers/shell_nompi_manager.yml | 2 +- abipy/data/managers/travis_manager.yml | 2 +- abipy/data/managers/ubu_manager.yml | 2 +- abipy/data/managers/vega_manager.yml | 2 +- abipy/data/managers/viper_manager.yml | 2 +- abipy/data/managers/zenobe_manager.yml | 4 ++-- abipy/electrons/arpes.py | 5 ++++- abipy/electrons/lobster.py | 4 +++- abipy/flowtk/flows.py | 10 ++++++---- abipy/flowtk/qadapters.py | 16 +++++++++------- abipy/flowtk/qutils.py | 7 ++++++- abipy/flowtk/tasks.py | 8 ++++---- abipy/flowtk/tests/test_flows.py | 4 ++-- abipy/flowtk/tests/test_qadapters.py | 14 +++++++------- abipy/flowtk/tests/test_tasks.py | 2 +- abipy/lumi/deltaSCF.py | 2 +- abipy/lumi/lineshape.py | 2 +- abipy/panels/core.py | 2 +- abipy/scripts/abirun.py | 2 +- abipy/test_files/taskmanager.yml | 2 +- abipy/tools/cli_parsers.py | 2 +- 35 files changed, 80 insertions(+), 66 deletions(-) diff --git a/abipy/abilab.py b/abipy/abilab.py index fe3419512..97afc638d 100644 --- a/abipy/abilab.py +++ b/abipy/abilab.py @@ -544,7 +544,7 @@ def install_config_files(workdir: Optional[str] = None, force_reinstall: Optiona num_nodes: 1 sockets_per_node: 1 cores_per_socket: 2 - mem_per_node: 4 Gb + mem_per_node: 4 GB """ # Write configuration files. diff --git a/abipy/core/mixins.py b/abipy/core/mixins.py index a7d1f5432..baa4919fc 100644 --- a/abipy/core/mixins.py +++ b/abipy/core/mixins.py @@ -575,12 +575,12 @@ def dump(self, filepath: str) -> str: _ABBREVS = [ - (1 << 50, 'Pb'), - (1 << 40, 'Tb'), - (1 << 30, 'Gb'), - (1 << 20, 'Mb'), - (1 << 10, 'kb'), - (1, 'b'), + (1 << 50, 'PB'), + (1 << 40, 'TB'), + (1 << 30, 'GB'), + (1 << 20, 'MB'), + (1 << 10, 'kB'), + (1, 'B'), ] diff --git a/abipy/data/managers/dragon1_manager.yml b/abipy/data/managers/dragon1_manager.yml index 91b2949e2..1c98f1125 100644 --- a/abipy/data/managers/dragon1_manager.yml +++ b/abipy/data/managers/dragon1_manager.yml @@ -3,7 +3,7 @@ hardware: &hardware num_nodes: 26 sockets_per_node: 2 cores_per_socket: 8 - mem_per_node: 112Gb + mem_per_node: 112GB job: &job mpi_runner: mpirun diff --git a/abipy/data/managers/gmac_manager.yml b/abipy/data/managers/gmac_manager.yml index 46bf64687..72465d003 100644 --- a/abipy/data/managers/gmac_manager.yml +++ b/abipy/data/managers/gmac_manager.yml @@ -16,7 +16,7 @@ qadapters: num_nodes: 1 sockets_per_node: 1 cores_per_socket: 2 - mem_per_node: 4 Gb + mem_per_node: 4 GB # Optional #condition: {"$eq": {omp_threads: 2}} diff --git a/abipy/data/managers/hercules_manager.yml b/abipy/data/managers/hercules_manager.yml index 95321d4e2..cb93647a8 100644 --- a/abipy/data/managers/hercules_manager.yml +++ b/abipy/data/managers/hercules_manager.yml @@ -3,7 +3,7 @@ hardware: &hardware num_nodes: 65 sockets_per_node: 2 cores_per_socket: 8 - mem_per_node: 54Gb + mem_per_node: 54GB job: &job mpi_runner: mpirun diff --git a/abipy/data/managers/hmem_manager.yml b/abipy/data/managers/hmem_manager.yml index f5f206093..27fbbaedb 100644 --- a/abipy/data/managers/hmem_manager.yml +++ b/abipy/data/managers/hmem_manager.yml @@ -4,19 +4,19 @@ high: &high num_nodes: 2 sockets_per_node: 4 cores_per_socket: 12 - mem_per_node: 512Gb + mem_per_node: 512GB middle: &middle num_nodes: 7 sockets_per_node: 4 cores_per_socket: 12 - mem_per_node: 256Gb + mem_per_node: 256GB low: &low num_nodes: 7 sockets_per_node: 4 cores_per_socket: 12 - mem_per_node: 128Gb + mem_per_node: 128GB job: &job mpi_runner: mpirun diff --git a/abipy/data/managers/juqueen_manager.yml b/abipy/data/managers/juqueen_manager.yml index cdd556aa1..98b70b89c 100644 --- a/abipy/data/managers/juqueen_manager.yml +++ b/abipy/data/managers/juqueen_manager.yml @@ -2,7 +2,7 @@ batch: &batch num_nodes: 128 sockets_per_node: 1 cores_per_socket: 16 - mem_per_node: 128Gb + mem_per_node: 128GB job: &job mpi_runner: runjob @@ -48,7 +48,7 @@ qadapters: num_nodes: 1 sockets_per_node: 1 cores_per_socket: 1 - mem_per_node: 12Gb + mem_per_node: 12GB job: #mpi_runner: runjob shell_env: diff --git a/abipy/data/managers/jureca_manager.yml b/abipy/data/managers/jureca_manager.yml index 2ec8e2b2c..7853e1179 100644 --- a/abipy/data/managers/jureca_manager.yml +++ b/abipy/data/managers/jureca_manager.yml @@ -5,13 +5,13 @@ devel: &devel num_nodes: 8 sockets_per_node: 2 cores_per_socket: 12 - mem_per_node: 128Gb + mem_per_node: 128GB batch: &batch num_nodes: 128 sockets_per_node: 2 cores_per_socket: 12 - mem_per_node: 128Gb + mem_per_node: 128GB job: &job # mpirun is not available on jureca. diff --git a/abipy/data/managers/lemaitre2_manager.yml b/abipy/data/managers/lemaitre2_manager.yml index 6231826d1..b85ce68c5 100644 --- a/abipy/data/managers/lemaitre2_manager.yml +++ b/abipy/data/managers/lemaitre2_manager.yml @@ -3,7 +3,7 @@ hardware: &hardware num_nodes: 112 sockets_per_node: 2 cores_per_socket: 6 - mem_per_node: 48Gb + mem_per_node: 48GB job: &job mpi_runner: mpirun diff --git a/abipy/data/managers/lemaitre3_manager.yml b/abipy/data/managers/lemaitre3_manager.yml index 65d610d01..fa9c50995 100644 --- a/abipy/data/managers/lemaitre3_manager.yml +++ b/abipy/data/managers/lemaitre3_manager.yml @@ -5,7 +5,7 @@ hardware: &hardware num_nodes: 80 sockets_per_node: 2 cores_per_socket: 12 - mem_per_node: 95Gb + mem_per_node: 95GB job: &job mpi_runner: mpirun diff --git a/abipy/data/managers/lumi_manager.yml b/abipy/data/managers/lumi_manager.yml index 3f27b7061..da6564294 100644 --- a/abipy/data/managers/lumi_manager.yml +++ b/abipy/data/managers/lumi_manager.yml @@ -5,7 +5,7 @@ hardware: &hardware num_nodes: 1376 sockets_per_node: 2 cores_per_socket: 64 - mem_per_node: 256Gb + mem_per_node: 256GB job: &job mpi_runner: srun diff --git a/abipy/data/managers/manneback_manager.yml b/abipy/data/managers/manneback_manager.yml index ba2fef568..857810294 100644 --- a/abipy/data/managers/manneback_manager.yml +++ b/abipy/data/managers/manneback_manager.yml @@ -3,19 +3,19 @@ Def: &Def num_nodes: 672 sockets_per_node: 2 cores_per_socket: 4 - mem_per_node: 24 Gb + mem_per_node: 24 GB ObanAMD: &ObanAMD num_nodes: 6 sockets_per_node: 4 cores_per_socket: 8 - mem_per_node: 128 Gb + mem_per_node: 128 GB ObanIntel: &ObanIntel num_nodes: 3 sockets_per_node: 4 cores_per_socket: 8 - mem_per_node: 256 Gb + mem_per_node: 256 GB # Environment, modules, and parameters used to launch jobs. job: &job diff --git a/abipy/data/managers/nic4_manager.yml b/abipy/data/managers/nic4_manager.yml index c09dc24cd..9d3b2f557 100644 --- a/abipy/data/managers/nic4_manager.yml +++ b/abipy/data/managers/nic4_manager.yml @@ -3,7 +3,7 @@ hardware: &hardware num_nodes: 120 sockets_per_node: 2 cores_per_socket: 8 - mem_per_node: 64Gb + mem_per_node: 64GB job: &job mpi_runner: "mpirun" diff --git a/abipy/data/managers/shell_manager.yml b/abipy/data/managers/shell_manager.yml index a90b28190..cf6fc833d 100644 --- a/abipy/data/managers/shell_manager.yml +++ b/abipy/data/managers/shell_manager.yml @@ -15,4 +15,4 @@ qadapters: num_nodes: 1 sockets_per_node: 1 cores_per_socket: 2 - mem_per_node: 4 Gb + mem_per_node: 4 GB diff --git a/abipy/data/managers/shell_nompi_manager.yml b/abipy/data/managers/shell_nompi_manager.yml index 6cc5838cd..e7f26376e 100644 --- a/abipy/data/managers/shell_nompi_manager.yml +++ b/abipy/data/managers/shell_nompi_manager.yml @@ -15,4 +15,4 @@ qadapters: num_nodes: 1 sockets_per_node: 1 cores_per_socket: 2 - mem_per_node: 4 Gb + mem_per_node: 4 GB diff --git a/abipy/data/managers/travis_manager.yml b/abipy/data/managers/travis_manager.yml index cf567ce82..b0cba8de8 100644 --- a/abipy/data/managers/travis_manager.yml +++ b/abipy/data/managers/travis_manager.yml @@ -16,4 +16,4 @@ qadapters: num_nodes: 1 sockets_per_node: 1 cores_per_socket: 2 - mem_per_node: 4 Gb + mem_per_node: 4 GB diff --git a/abipy/data/managers/ubu_manager.yml b/abipy/data/managers/ubu_manager.yml index 10228cd2e..5e273d6e5 100644 --- a/abipy/data/managers/ubu_manager.yml +++ b/abipy/data/managers/ubu_manager.yml @@ -17,4 +17,4 @@ qadapters: num_nodes: 1 sockets_per_node: 1 cores_per_socket: 24 - mem_per_node: 4 Gb + mem_per_node: 4 GB diff --git a/abipy/data/managers/vega_manager.yml b/abipy/data/managers/vega_manager.yml index a75f7fa8c..99ffd260f 100644 --- a/abipy/data/managers/vega_manager.yml +++ b/abipy/data/managers/vega_manager.yml @@ -3,7 +3,7 @@ hardware: &hardware num_nodes: 44 sockets_per_node: 4 cores_per_socket: 16 - mem_per_node: 256Gb + mem_per_node: 256GB job: &job mpi_runner: mpirun diff --git a/abipy/data/managers/viper_manager.yml b/abipy/data/managers/viper_manager.yml index afd2f5e3c..80e1e2b7d 100644 --- a/abipy/data/managers/viper_manager.yml +++ b/abipy/data/managers/viper_manager.yml @@ -2,7 +2,7 @@ hardware: &hardware num_nodes: 1 sockets_per_node: 2 cores_per_socket: 4 - mem_per_node: 32Gb + mem_per_node: 32GB job: &job mpi_runner: ~/bin/mpirun.openmpi diff --git a/abipy/data/managers/zenobe_manager.yml b/abipy/data/managers/zenobe_manager.yml index 5a16c0b68..71a408462 100644 --- a/abipy/data/managers/zenobe_manager.yml +++ b/abipy/data/managers/zenobe_manager.yml @@ -3,13 +3,13 @@ westmere: &westmere num_nodes: 274 sockets_per_node: 2 cores_per_socket: 6 - mem_per_node: 24 Gb + mem_per_node: 24 GB ivybridge: &ivybridge num_nodes: 342 sockets_per_node: 2 cores_per_socket: 12 - mem_per_node: 64 Gb + mem_per_node: 64 GB # Environment, modules, and parameters used to launch jobs. job: &job diff --git a/abipy/electrons/arpes.py b/abipy/electrons/arpes.py index 016a606ad..5e6a1abd7 100644 --- a/abipy/electrons/arpes.py +++ b/abipy/electrons/arpes.py @@ -36,7 +36,10 @@ def model_from_ebands(cls, ebands, tmesh=(0, 300, 600), poorman_polaron=False): #aw: [nwr, ntemp, max_nbcalc, nkcalc, nsppol] array #aw_meshes: [max_nbcalc, nkcalc, nsppol] array with energy mesh in eV from abipy.tools.numtools import lorentzian - from scipy.integrate import cumtrapz + try: + from scipy.integrate import cumulative_trapezoid as cumtrapz + except ImportError: + from scipy.integrate import cumtrapz for spin in ebands.spins: for ik, kpt in enumerate(ebands.kpoints): for band in range(ebands.nband_sk[spin, ik]): diff --git a/abipy/electrons/lobster.py b/abipy/electrons/lobster.py index 75d7d2bdf..479e74b79 100644 --- a/abipy/electrons/lobster.py +++ b/abipy/electrons/lobster.py @@ -771,7 +771,9 @@ def plot(self, ax=None, **kwargs) -> Figure: """Barplot with average values.""" ax, fig, plt = get_ax_fig_plt(ax=ax) import seaborn as sns - sns.barplot(x="average", y="pair", hue="spin", data=self.dataframe, ax=ax) + df = self.dataframe.copy() + df["pair"] = df["type0"] + "-" + df["type1"] + sns.barplot(x="average", y="pair", hue="spin", data=df, ax=ax) return fig def yield_figs(self, **kwargs): # pragma: no cover diff --git a/abipy/flowtk/flows.py b/abipy/flowtk/flows.py index 12ef779be..c86e59ce5 100644 --- a/abipy/flowtk/flows.py +++ b/abipy/flowtk/flows.py @@ -1292,7 +1292,7 @@ def show_status(self, return_df=False, **kwargs): events = '{:>4}|{:>3}'.format(*map(str, (report.num_warnings, report.num_comments))) para_info = '{:>4}|{:>3}|{:>3}'.format(*map(str, ( - task.mpi_procs, task.omp_threads, "%.1f" % task.mem_per_proc.to("Gb")))) + task.mpi_procs, task.omp_threads, "%.1f" % task.mem_per_proc.to("GB")))) task_info = list(map(str, [task.__class__.__name__, (task.num_launches, task.num_restarts, task.num_corrections), stime, task.node_id])) @@ -2486,7 +2486,7 @@ def make_tarfile(self, name=None, max_filesize=None, exclude_exts=None, exclude_ Args: name: Name of the tarball file. Set to os.path.basename(`flow.workdir`) + "tar.gz"` if name is None. max_filesize (int or string with unit): a file is included in the tar file if its size <= max_filesize - Can be specified in bytes e.g. `max_files=1024` or with a string with unit e.g. `max_filesize="1 Mb"`. + Can be specified in bytes e.g. `max_files=1024` or with a string with unit e.g. `max_filesize="1 MB"`. No check is done if max_filesize is None. exclude_exts: List of file extensions to be excluded from the tar file. exclude_dirs: List of directory basenames to be excluded. @@ -2498,11 +2498,13 @@ def make_tarfile(self, name=None, max_filesize=None, exclude_exts=None, exclude_ def any2bytes(s): """Convert string or number to memory in bytes.""" if is_string(s): + s = s.upper() # Convert in upper case for pymatgen compatibility # Support for deprecated pymatgen API try: - mem = int(Memory.from_string(s).to("b")) + mem = int(Memory.from_string(s).to("B")) except Exception: - mem = int(Memory.from_str(s).to("b")) + mem = int(Memory.from_str(s).to("B")) + return mem else: return int(s) diff --git a/abipy/flowtk/qadapters.py b/abipy/flowtk/qadapters.py index 2f4907a1e..12fb63024 100644 --- a/abipy/flowtk/qadapters.py +++ b/abipy/flowtk/qadapters.py @@ -215,11 +215,13 @@ def __init__(self, **kwargs): # Convert memory to megabytes. m = str(kwargs.pop("mem_per_node")) + # Convert to upper case for compatibility with pymatgen + m = m.upper() # Support for old pymatgen API try: - self.mem_per_node = int(Memory.from_string(m).to("Mb")) + self.mem_per_node = int(Memory.from_string(m).to("MB")) except: - self.mem_per_node = int(Memory.from_str(m).to("Mb")) + self.mem_per_node = int(Memory.from_str(m).to("MB")) if self.mem_per_node <= 0 or self.sockets_per_node <= 0 or self.cores_per_socket <= 0: raise ValueError("invalid parameters: %s" % kwargs) @@ -262,7 +264,7 @@ def as_dict(self) -> dict: return {'num_nodes': self.num_nodes, 'sockets_per_node': self.sockets_per_node, 'cores_per_socket': self.cores_per_socket, - 'mem_per_node': str(Memory(val=self.mem_per_node, unit='Mb'))} + 'mem_per_node': str(Memory(val=self.mem_per_node, unit='MB'))} @classmethod def from_dict(cls, d: dict) -> Hardware: @@ -439,9 +441,9 @@ def autodoc(cls) -> str: # it's the limit beyond which the scheduler will not accept the job (MANDATORY). hint_cores: # The limit used in the initial setup of jobs. # Fix_Critical method may increase this number until max_cores is reached - min_mem_per_proc: # Minimum memory per MPI process in Mb, units can be specified e.g. 1.4 Gb + min_mem_per_proc: # Minimum memory per MPI process in MB, units can be specified e.g. 1.4 GB # (DEFAULT: hardware.mem_per_core) - max_mem_per_proc: # Maximum memory per MPI process in Mb, units can be specified e.g. `1.4Gb` + max_mem_per_proc: # Maximum memory per MPI process in MB, units can be specified e.g. `1.4GB` # (DEFAULT: hardware.mem_per_node) timelimit: # Initial time-limit. Accepts time according to slurm-syntax i.e: # "days-hours" or "days-hours:minutes" or "days-hours:minutes:seconds" or @@ -464,7 +466,7 @@ def autodoc(cls) -> str: # # limits_for_task_class: { # NscfTask: {min_cores: 1, max_cores: 10}, - # KerangeTask: {min_cores: 1, max_cores: 1, max_mem_per_proc: 1 Gb}, + # KerangeTask: {min_cores: 1, max_cores: 1, max_mem_per_proc: 1 GB}, # } """ @@ -901,7 +903,7 @@ def set_master_mem_overhead(self, mem_mb): @property def total_mem(self) -> Memory: """Total memory required by the job in megabytes.""" - return Memory(self.mem_per_proc * self.mpi_procs + self.master_mem_overhead, "Mb") + return Memory(self.mem_per_proc * self.mpi_procs + self.master_mem_overhead, "MB") @abc.abstractmethod def cancel(self, job_id: int) -> int: diff --git a/abipy/flowtk/qutils.py b/abipy/flowtk/qutils.py index 303631d42..9e4b81661 100644 --- a/abipy/flowtk/qutils.py +++ b/abipy/flowtk/qutils.py @@ -132,7 +132,12 @@ def timelimit_parser(s): def any2mb(s): """Convert string or number to memory in megabytes.""" if is_string(s): - return int(Memory.from_str(s).to("Mb")) + s = s.upper() # Convert in upper case for pymatgen compatibility + try: + mem = int(Memory.from_string(s).to("MB")) + except Exception: + mem = int(Memory.from_str(s).to("MB")) + return mem else: return int(s) diff --git a/abipy/flowtk/tasks.py b/abipy/flowtk/tasks.py index 2e0034d23..d1d5f16d3 100644 --- a/abipy/flowtk/tasks.py +++ b/abipy/flowtk/tasks.py @@ -209,7 +209,7 @@ def speedup(self) -> float: @property def tot_mem(self) -> float: - """Estimated total memory in Mbs (computed from mem_per_proc)""" + """Estimated total memory in MBs (computed from mem_per_proc)""" return self.mem_per_proc * self.mpi_procs @@ -609,7 +609,7 @@ def get_simple_manager(cls) -> str: num_nodes: 1 sockets_per_node: 1 cores_per_socket: 2 - mem_per_node: 4 Gb + mem_per_node: 4 GB """ @classmethod @@ -1872,7 +1872,7 @@ def omp_threads(self) -> int: @property def mem_per_proc(self) -> Memory: """Memory per MPI process.""" - return Memory(self.manager.mem_per_proc, "Mb") + return Memory(self.manager.mem_per_proc, "MB") @property def status(self): @@ -1939,7 +1939,7 @@ def set_status(self, status: Status, msg: str) -> Status: if status == self.S_SUB: self.datetimes.submission = datetime.datetime.now() self.history.info("Submitted with MPI=%s, Omp=%s, Memproc=%.1f [Gb] %s " % ( - self.mpi_procs, self.omp_threads, self.mem_per_proc.to("Gb"), msg)) + self.mpi_procs, self.omp_threads, self.mem_per_proc.to("GB"), msg)) elif status == self.S_OK: self.history.info("Task completed %s", msg) diff --git a/abipy/flowtk/tests/test_flows.py b/abipy/flowtk/tests/test_flows.py index 760eac37a..b6ea271f6 100644 --- a/abipy/flowtk/tests/test_flows.py +++ b/abipy/flowtk/tests/test_flows.py @@ -36,13 +36,13 @@ class FlowUnitTest(AbipyTest): #condition: {"$eq": {omp_threads: 2}} limits_for_task_class: { DdkTask: {min_cores: 2, max_cores: 30}, - KerangeTask: {timelimit: 0:10:00, max_mem_per_proc: 1 Gb}, + KerangeTask: {timelimit: 0:10:00, max_mem_per_proc: 1 GB}, } hardware: num_nodes: 10 sockets_per_node: 1 cores_per_socket: 2 - mem_per_node: 4 Gb + mem_per_node: 4 GB job: modules: - intel/compilerpro/13.0.1.117 diff --git a/abipy/flowtk/tests/test_qadapters.py b/abipy/flowtk/tests/test_qadapters.py index 6cbc479e4..7a4240170 100644 --- a/abipy/flowtk/tests/test_qadapters.py +++ b/abipy/flowtk/tests/test_qadapters.py @@ -65,7 +65,7 @@ class QadapterTest(AbipyTest): num_nodes: 3 sockets_per_node: 2 cores_per_socket: 4 - mem_per_node: 8 Gb + mem_per_node: 8 GB """) def test_base(self): @@ -123,7 +123,7 @@ def test_base(self): aequal(new_script, script) # Test can_run and distribute - # The hardware has num_nodes=3, sockets_per_node=2, cores_per_socket=4, mem_per_node="8 Gb" + # The hardware has num_nodes=3, sockets_per_node=2, cores_per_socket=4, mem_per_node="8 GB" afalse(qad.can_run_pconf(ParalConf(mpi_ncpus=hw.num_cores+1, omp_ncpus=1, mem_per_cpu=0.1))) afalse(qad.can_run_pconf(ParalConf(mpi_ncpus=4, omp_ncpus=9, mem_per_cpu=0.1))) afalse(qad.can_run_pconf(ParalConf(mpi_ncpus=4, omp_ncpus=1, mem_per_cpu=10 * giga))) @@ -192,7 +192,7 @@ class ShellAdapterTest(AbipyTest): num_nodes: 1 sockets_per_node: 1 cores_per_socket: 1 - mem_per_node: 4 Gb + mem_per_node: 4 GB """) def test_methods(self): qad = make_qadapter(**self.QDICT) @@ -257,7 +257,7 @@ class SlurmAdapterTest(AbipyTest): num_nodes: 2 sockets_per_node: 2 cores_per_socket: 4 - mem_per_node: 8 Gb + mem_per_node: 8 GB """) def test_methods(self): @@ -342,7 +342,7 @@ class PbsProadapterTest(AbipyTest): num_nodes: 100 sockets_per_node: 2 cores_per_socket: 4 - mem_per_node: 8 Gb""") + mem_per_node: 8 GB""") QDICT_SHARED = safe_load("""\ priority: 1 queue: @@ -363,7 +363,7 @@ class PbsProadapterTest(AbipyTest): num_nodes: 100 sockets_per_node: 2 cores_per_socket: 12 - mem_per_node: 48000 Mb""") + mem_per_node: 48000 MB""") QDICT_EXCLUSIVE = safe_load("""\ priority: 1 queue: @@ -384,7 +384,7 @@ class PbsProadapterTest(AbipyTest): num_nodes: 100 sockets_per_node: 2 cores_per_socket: 12 - mem_per_node: 48000 Mb""") + mem_per_node: 48000 MB""") def test_methods(self): self.maxDiff = None diff --git a/abipy/flowtk/tests/test_tasks.py b/abipy/flowtk/tests/test_tasks.py index 401f27a76..759914d46 100644 --- a/abipy/flowtk/tests/test_tasks.py +++ b/abipy/flowtk/tests/test_tasks.py @@ -28,7 +28,7 @@ class TaskManagerTest(AbipyTest): num_nodes: 10 sockets_per_node: 1 cores_per_socket: 2 - mem_per_node: 4 Gb + mem_per_node: 4 GB job: modules: - intel/compilerpro/13.0.1.117 diff --git a/abipy/lumi/deltaSCF.py b/abipy/lumi/deltaSCF.py index a52e640b9..06ebb43f0 100644 --- a/abipy/lumi/deltaSCF.py +++ b/abipy/lumi/deltaSCF.py @@ -433,7 +433,7 @@ def lineshape_1D_zero_temp(self,energy_range=[0.5,5],max_m=25,phonon_width=0.01, A=A*E_x**3 if normalized=="Area": - C = 1 / (simps(A, E_x)) + C = 1 / (simps(y=A, x=E_x)) if normalized=="Sum": C=1/(max(A)) diff --git a/abipy/lumi/lineshape.py b/abipy/lumi/lineshape.py index f3f392d88..817607a6c 100644 --- a/abipy/lumi/lineshape.py +++ b/abipy/lumi/lineshape.py @@ -333,7 +333,7 @@ def L_hw(self, T=0, lamb=5, w=1, model='multi-D'): """ E_x, A = self.A_hw(T, lamb, w, model) - C = 1 / (simps(A * E_x ** 3, E_x)) + C = 1 / (simps(y=A * E_x ** 3, x=E_x)) I = C * A * E_x ** 3 # intensity prop to energy CUBE return (E_x, I) diff --git a/abipy/panels/core.py b/abipy/panels/core.py index 3ee921649..35c4d7c61 100644 --- a/abipy/panels/core.py +++ b/abipy/panels/core.py @@ -1566,7 +1566,7 @@ class BaseRobotPanel(AbipyParameterized): def __init__(self, robot, **params): self.robot = robot self.compare_params_btn = pnw.Button(name="Compare structures", button_type='primary') - self.transpose_params = pnw.Checkbox(name='Transpose table', default=True) + self.transpose_params = pnw.Checkbox(name='Transpose table', value=True) super().__init__(**params) diff --git a/abipy/scripts/abirun.py b/abipy/scripts/abirun.py index c135bf05b..86697625d 100755 --- a/abipy/scripts/abirun.py +++ b/abipy/scripts/abirun.py @@ -683,7 +683,7 @@ def parse_wslice(s): # Subparser for tar. p_tar = subparsers.add_parser('tar', parents=[copts_parser], help="Create tarball file.") p_tar.add_argument("-s", "--max-filesize", default=None, - help="Exclude file whose size > max-filesize bytes. Accept integer or string e.g `1Mb`.") + help="Exclude file whose size > max-filesize bytes. Accept integer or string e.g `1MB`.") p_tar.add_argument("-e", "--exclude-exts", default=None, type=parse_strings, help="Exclude file extensions. Accept string or comma-separated strings. Ex: -eWFK or --exclude-exts=WFK,GSR") p_tar.add_argument("-d", "--exclude-dirs", default=None, type=parse_strings, diff --git a/abipy/test_files/taskmanager.yml b/abipy/test_files/taskmanager.yml index f5d5d7f23..edfad6f17 100644 --- a/abipy/test_files/taskmanager.yml +++ b/abipy/test_files/taskmanager.yml @@ -6,7 +6,7 @@ hardware: &hardware num_nodes: 1 sockets_per_node: 1 cores_per_socket: 2 - mem_per_node: 4 Gb + mem_per_node: 4 GB job: &job mpi_runner: mpirun diff --git a/abipy/tools/cli_parsers.py b/abipy/tools/cli_parsers.py index dfaafb05a..6a67799ab 100644 --- a/abipy/tools/cli_parsers.py +++ b/abipy/tools/cli_parsers.py @@ -53,7 +53,7 @@ def pn_serve_parser(**kwargs) -> argparse.ArgumentParser: help="Public hostnames which may connect to the Bokeh websocket.\n Syntax: " + "HOST[:PORT] or *. Default: None") p.add_argument('--max_size_mb', default=150, type=int, - help="Maximum message size in Mb allowed by Bokeh and Tornado. Default: 150") + help="Maximum message size in MB allowed by Bokeh and Tornado. Default: 150") p.add_argument('--no-browser', action='store_true', default=False, help=("Start the jupyter server to serve the notebook " From 630fe0840325d5e3f27810b015e3d2d69244e941 Mon Sep 17 00:00:00 2001 From: gbrunin Date: Mon, 22 Jul 2024 10:45:04 +0200 Subject: [PATCH 6/7] Making it possible to use older versions of pymatgen as well. --- abipy/flowtk/flows.py | 22 ++++++++++++++-------- abipy/flowtk/qadapters.py | 32 +++++++++++++++++++++----------- abipy/flowtk/qutils.py | 13 ++++++++----- abipy/flowtk/tasks.py | 16 ++++++++++++---- 4 files changed, 55 insertions(+), 28 deletions(-) diff --git a/abipy/flowtk/flows.py b/abipy/flowtk/flows.py index c86e59ce5..126c2de11 100644 --- a/abipy/flowtk/flows.py +++ b/abipy/flowtk/flows.py @@ -30,7 +30,7 @@ from monty.termcolor import cprint, colored, cprint_map, get_terminal_size from monty.inspect import find_top_pyfile from monty.json import MSONable -from pymatgen.core.units import Memory +from pymatgen.core.units import Memory, UnitError from abipy.tools.iotools import AtomicFile from abipy.tools.serialization import pmg_pickle_load, pmg_pickle_dump, pmg_serialize from abipy.tools.typing import Figure, TYPE_CHECKING @@ -1291,8 +1291,12 @@ def show_status(self, return_df=False, **kwargs): if report is not None: events = '{:>4}|{:>3}'.format(*map(str, (report.num_warnings, report.num_comments))) - para_info = '{:>4}|{:>3}|{:>3}'.format(*map(str, ( - task.mpi_procs, task.omp_threads, "%.1f" % task.mem_per_proc.to("GB")))) + try: + para_info = '{:>4}|{:>3}|{:>3}'.format(*map(str, ( + task.mpi_procs, task.omp_threads, "%.1f" % task.mem_per_proc.to("GB")))) + except (KeyError, UnitError): + para_info = '{:>4}|{:>3}|{:>3}'.format(*map(str, ( + task.mpi_procs, task.omp_threads, "%.1f" % task.mem_per_proc.to("Gb")))) task_info = list(map(str, [task.__class__.__name__, (task.num_launches, task.num_restarts, task.num_corrections), stime, task.node_id])) @@ -2498,12 +2502,14 @@ def make_tarfile(self, name=None, max_filesize=None, exclude_exts=None, exclude_ def any2bytes(s): """Convert string or number to memory in bytes.""" if is_string(s): - s = s.upper() # Convert in upper case for pymatgen compatibility - # Support for deprecated pymatgen API try: - mem = int(Memory.from_string(s).to("B")) - except Exception: - mem = int(Memory.from_str(s).to("B")) + # latest pymatgen version (as of july 2024) + mem = int(Memory.from_str(s.upper()).to("B")) + except (KeyError, UnitError): # For backward compatibility with older pymatgen versions + try: + mem = int(Memory.from_str(s.replace("B", "b")).to("b")) + except AttributeError: # For even older pymatgen versions + mem = int(Memory.from_string(s.replace("B", "b")).to("b")) return mem else: return int(s) diff --git a/abipy/flowtk/qadapters.py b/abipy/flowtk/qadapters.py index 12fb63024..55f643495 100644 --- a/abipy/flowtk/qadapters.py +++ b/abipy/flowtk/qadapters.py @@ -32,11 +32,12 @@ from monty.inspect import all_subclasses from monty.io import FileLock from monty.json import MSONable -from pymatgen.core.units import Memory +from pymatgen.core.units import Memory, UnitError from abipy.tools.iotools import AtomicFile from .utils import Condition from .launcher import ScriptEditor from .qjobs import QueueJob +from .qutils import any2mb import logging logger = logging.getLogger(__name__) @@ -215,13 +216,7 @@ def __init__(self, **kwargs): # Convert memory to megabytes. m = str(kwargs.pop("mem_per_node")) - # Convert to upper case for compatibility with pymatgen - m = m.upper() - # Support for old pymatgen API - try: - self.mem_per_node = int(Memory.from_string(m).to("MB")) - except: - self.mem_per_node = int(Memory.from_str(m).to("MB")) + self.mem_per_node = any2mb(m) if self.mem_per_node <= 0 or self.sockets_per_node <= 0 or self.cores_per_socket <= 0: raise ValueError("invalid parameters: %s" % kwargs) @@ -261,10 +256,21 @@ def divmod_node(self, mpi_procs: int, omp_threads: int) -> tuple[int, int]: return divmod(mpi_procs * omp_threads, self.cores_per_node) def as_dict(self) -> dict: - return {'num_nodes': self.num_nodes, + try: + dct = { + 'num_nodes': self.num_nodes, 'sockets_per_node': self.sockets_per_node, 'cores_per_socket': self.cores_per_socket, - 'mem_per_node': str(Memory(val=self.mem_per_node, unit='MB'))} + 'mem_per_node': str(Memory(val=self.mem_per_node, unit='MB')) + } + except UnitError: + dct = { + 'num_nodes': self.num_nodes, + 'sockets_per_node': self.sockets_per_node, + 'cores_per_socket': self.cores_per_socket, + 'mem_per_node': str(Memory(val=self.mem_per_node, unit='Mb')) + } + return dct @classmethod def from_dict(cls, d: dict) -> Hardware: @@ -903,7 +909,11 @@ def set_master_mem_overhead(self, mem_mb): @property def total_mem(self) -> Memory: """Total memory required by the job in megabytes.""" - return Memory(self.mem_per_proc * self.mpi_procs + self.master_mem_overhead, "MB") + try: + mem = Memory(self.mem_per_proc * self.mpi_procs + self.master_mem_overhead, "MB") + except UnitError: + mem = Memory(self.mem_per_proc * self.mpi_procs + self.master_mem_overhead, "Mb") + return mem @abc.abstractmethod def cancel(self, job_id: int) -> int: diff --git a/abipy/flowtk/qutils.py b/abipy/flowtk/qutils.py index 9e4b81661..00200ffcf 100644 --- a/abipy/flowtk/qutils.py +++ b/abipy/flowtk/qutils.py @@ -12,7 +12,7 @@ from subprocess import Popen, PIPE, run from monty.string import is_string -from pymatgen.core.units import Time, Memory +from pymatgen.core.units import Time, Memory, UnitError from abipy.tools.typing import PathLike from abipy.tools import duck from abipy.tools.text import rm_multiple_spaces @@ -132,11 +132,14 @@ def timelimit_parser(s): def any2mb(s): """Convert string or number to memory in megabytes.""" if is_string(s): - s = s.upper() # Convert in upper case for pymatgen compatibility try: - mem = int(Memory.from_string(s).to("MB")) - except Exception: - mem = int(Memory.from_str(s).to("MB")) + # latest pymatgen version (as of july 2024) + mem = int(Memory.from_str(s.upper()).to("MB")) + except (KeyError, UnitError): # For backward compatibility with older pymatgen versions + try: + mem = int(Memory.from_str(s.replace("B", "b")).to("Mb")) + except AttributeError: # For even older pymatgen versions + mem = int(Memory.from_string(s.replace("B", "b")).to("Mb")) return mem else: return int(s) diff --git a/abipy/flowtk/tasks.py b/abipy/flowtk/tasks.py index 025e09da0..46c6b5880 100644 --- a/abipy/flowtk/tasks.py +++ b/abipy/flowtk/tasks.py @@ -23,7 +23,7 @@ from monty.functools import lazy_property, return_none_if_raise from monty.json import MSONable from monty.fnmatch import WildCard -from pymatgen.core.units import Memory +from pymatgen.core.units import Memory, UnitError from abipy.core.globals import get_workdir from abipy.core.structure import Structure from abipy.tools.serialization import json_pretty_dump, pmg_serialize @@ -1881,7 +1881,11 @@ def omp_threads(self) -> int: @property def mem_per_proc(self) -> Memory: """Memory per MPI process.""" - return Memory(self.manager.mem_per_proc, "MB") + try: + mem = Memory(self.manager.mem_per_proc, "MB") + except UnitError: # For older versions of pymatgen + mem = Memory(self.manager.mem_per_proc, "Mb") + return mem @property def status(self): @@ -1947,8 +1951,12 @@ def set_status(self, status: Status, msg: str) -> Status: if changed: if status == self.S_SUB: self.datetimes.submission = datetime.datetime.now() - self.history.info("Submitted with MPI=%s, Omp=%s, Memproc=%.1f [Gb] %s " % ( - self.mpi_procs, self.omp_threads, self.mem_per_proc.to("GB"), msg)) + try: + self.history.info("Submitted with MPI=%s, Omp=%s, Memproc=%.1f [GB] %s " % ( + self.mpi_procs, self.omp_threads, self.mem_per_proc.to("GB"), msg)) + except (KeyError, UnitError): + self.history.info("Submitted with MPI=%s, Omp=%s, Memproc=%.1f [Gb] %s " % ( + self.mpi_procs, self.omp_threads, self.mem_per_proc.to("Gb"), msg)) elif status == self.S_OK: self.history.info("Task completed %s", msg) From ba92770b1705896d3740f06f476ab04f17bf6289 Mon Sep 17 00:00:00 2001 From: gbrunin Date: Mon, 22 Jul 2024 11:11:06 +0200 Subject: [PATCH 7/7] Typo. --- abipy/electrons/arpes.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/abipy/electrons/arpes.py b/abipy/electrons/arpes.py index b7d81dee7..5e6a1abd7 100644 --- a/abipy/electrons/arpes.py +++ b/abipy/electrons/arpes.py @@ -36,11 +36,7 @@ def model_from_ebands(cls, ebands, tmesh=(0, 300, 600), poorman_polaron=False): #aw: [nwr, ntemp, max_nbcalc, nkcalc, nsppol] array #aw_meshes: [max_nbcalc, nkcalc, nsppol] array with energy mesh in eV from abipy.tools.numtools import lorentzian -<<<<<<< HEAD try: -======= - try : ->>>>>>> b0405a954dfa31ba114272e62b924cc4a1c92c80 from scipy.integrate import cumulative_trapezoid as cumtrapz except ImportError: from scipy.integrate import cumtrapz