Commit 4dcb479c authored by Lauri Himanen's avatar Lauri Himanen
Browse files

First tests with parsing the YAML output of BigDFT, finally a sane parser output format.

parent ea1ca62d
Pipeline #8375 failed with stage
in 4 minutes and 18 seconds
......@@ -24,11 +24,13 @@ class BigDFTParser(ParserInterface):
"""
# Search for the BigDFT version specification. The correct parser is
# initialized based on this information.
regex_version = re.compile(" Northwest Computational Chemistry Package \(NWChem\) (\d+\.\d+)")
regex_version = re.compile(" Version Number\s+: (\d\.\d)")
version_id = None
with open(self.parser_context.main_file, 'r') as outputfile:
for line in outputfile:
# Look for version
header = outputfile.read(50*80)
for line in header.split("\n"):
# Look for version definition
result_version = regex_version.match(line)
if result_version:
version_id = result_version.group(1).replace('.', '')
......@@ -64,7 +66,7 @@ class BigDFTParser(ParserInterface):
parser_module = importlib.import_module(base)
except ImportError:
logger.warning("Could not find a parser for version '{}'. Trying to default to the base implementation for BigDFT 1.8.0".format(version_id))
base = "bigdftparser.versions.bigdft180.mainparser"
base = "bigdftparser.versions.bigdft18.mainparser"
try:
parser_module = importlib.import_module(base)
except ImportError:
......
"""
This is a module for unit testing the BigDFT parser. The unit tests are run with
a custom backend that outputs the results directly into native python object for
easier and faster analysis.
Each property that has an enumerable list of different possible options is
assigned a new test class, that should ideally test through all the options.
The properties that can have non-enumerable values will be tested only for one
specific case inside a test class that is designed for a certain type of run
(MD, optimization, QM/MM, etc.)
"""
import os
import unittest
import logging
import numpy as np
from bigdftparser import BigDFTParser
from nomadcore.unit_conversion.unit_conversion import convert_unit
#===============================================================================
def get_results(folder, metainfo_to_keep=None):
"""Get the given result from the calculation in the given folder by using
the Analyzer in the nomadtoolkit package. Tries to optimize the parsing by
giving the metainfo_to_keep argument.
Args:
folder: The folder relative to the directory of this script where the
parsed calculation resides.
metaname: The quantity to extract.
"""
dirname = os.path.dirname(__file__)
filename = os.path.join(dirname, folder, "output.out")
parser = BigDFTParser(filename, None, debug=True, log_level=logging.WARNING)
results = parser.parse()
return results
#===============================================================================
def get_result(folder, metaname, optimize=True):
if optimize:
results = get_results(folder, None)
else:
results = get_results(folder)
result = results[metaname]
return result
#===============================================================================
class TestSinglePoint(unittest.TestCase):
"""Tests that the parser can handle single point calculations.
"""
@classmethod
def setUpClass(cls):
cls.results = get_results("single_point", "section_run")
# cls.results.print_summary()
def test_program_name(self):
result = self.results["program_name"]
self.assertEqual(result, "BigDFT")
# def test_configuration_periodic_dimensions(self):
# result = self.results["configuration_periodic_dimensions"]
# self.assertTrue(np.array_equal(result, np.array([False, False, False])))
# def test_program_version(self):
# result = self.results["program_version"]
# self.assertEqual(result, "6.6")
# def test_xc_functional(self):
# result = self.results["XC_functional"]
# self.assertEqual(result, "1.0*MGGA_C_TPSS+1.0*MGGA_X_TPSS")
# def test_atom_labels(self):
# atom_labels = self.results["atom_labels"]
# expected_labels = np.array(["O", "H", "H"])
# self.assertTrue(np.array_equal(atom_labels, expected_labels))
# def test_atom_positions(self):
# atom_position = self.results["atom_positions"]
# expected_position = convert_unit(np.array(
# [
# [0.00000000, 0.00000000, -0.11817375],
# [0.76924532, 0.00000000, 0.47269501],
# [-0.76924532, 0.00000000, 0.47269501],
# ]
# ), "angstrom")
# self.assertTrue(np.array_equal(atom_position, expected_position))
# def test_number_of_atoms(self):
# n_atoms = self.results["number_of_atoms"]
# self.assertEqual(n_atoms, 3)
# def test_total_charge(self):
# charge = self.results["total_charge"]
# self.assertEqual(charge, 0)
# def test_energy_total(self):
# result = self.results["energy_total"]
# expected_result = convert_unit(np.array(-76.436222730188), "hartree")
# self.assertTrue(np.array_equal(result, expected_result))
# def test_energy_x(self):
# result = self.results["energy_X"]
# expected_result = convert_unit(np.array(-9.025345841743), "hartree")
# self.assertTrue(np.array_equal(result, expected_result))
# def test_energy_c(self):
# result = self.results["energy_C"]
# expected_result = convert_unit(np.array(-0.328011552453), "hartree")
# self.assertTrue(np.array_equal(result, expected_result))
# def test_energy_total_scf_iteration(self):
# result = self.results["energy_total_scf_iteration"]
# # Test the first and last energies
# expected_result = convert_unit(np.array(
# [
# [-76.3916403957],
# [-76.4362227302],
# ]), "hartree")
# self.assertTrue(np.array_equal(np.array([[result[0]], [result[-1]]]), expected_result))
# def test_energy_change_scf_iteration(self):
# result = self.results["energy_change_scf_iteration"]
# expected_result = convert_unit(np.array(
# [
# [-8.55E+01],
# [-3.82E-07],
# ]), "hartree")
# self.assertTrue(np.array_equal(np.array([[result[0]], [result[-1]]]), expected_result))
# def test_scf_max_iteration(self):
# result = self.results["scf_max_iteration"]
# self.assertEqual(result, 50)
# def test_scf_threshold_energy_change(self):
# result = self.results["scf_threshold_energy_change"]
# self.assertEqual(result, convert_unit(1.00E-06, "hartree"))
# def test_electronic_structure_method(self):
# result = self.results["electronic_structure_method"]
# self.assertEqual(result, "DFT")
# def test_scf_dft_number_of_iterations(self):
# result = self.results["number_of_scf_iterations"]
# self.assertEqual(result, 6)
# def test_spin_target_multiplicity(self):
# multiplicity = self.results["spin_target_multiplicity"]
# self.assertEqual(multiplicity, 1)
# def test_single_configuration_to_calculation_method_ref(self):
# result = self.results["single_configuration_to_calculation_method_ref"]
# self.assertEqual(result, 0)
# def test_single_configuration_calculation_to_system_description_ref(self):
# result = self.results["single_configuration_calculation_to_system_ref"]
# self.assertEqual(result, 0)
# def test_single_configuration_calculation_converged(self):
# result = self.results["single_configuration_calculation_converged"]
# self.assertTrue(result)
# def test_section_method_atom_kind(self):
# kind = self.results["section_method_atom_kind"][0]
# self.assertEqual(kind["method_atom_kind_atom_number"][0], 1)
# self.assertEqual(kind["method_atom_kind_label"][0], "H")
# def test_section_method_basis_set(self):
# kind = self.results["section_method_basis_set"][0]
# self.assertEqual(kind["method_basis_set_kind"][0], "wavefunction")
# self.assertTrue(np.array_equal(kind["mapping_section_method_basis_set_cell_associated"][0], 0))
# def test_number_of_spin_channels(self):
# result = self.results["number_of_spin_channels"]
# self.assertEqual(result, 1)
# def test_simulation_cell(self):
# cell = self.results["simulation_cell"]
# n_vectors = cell.shape[0]
# n_dim = cell.shape[1]
# self.assertEqual(n_vectors, 3)
# self.assertEqual(n_dim, 3)
# expected_cell = convert_unit(np.array([[15.1178, 0, 0], [0, 15.1178, 0], [0, 0, 15.1178]]), "bohr")
# self.assertTrue(np.array_equal(cell, expected_cell))
# def test_basis_set_cell_dependent(self):
# kind = self.results["basis_set_cell_dependent_kind"]
# name = self.results["basis_set_cell_dependent_name"]
# cutoff = self.results["basis_set_planewave_cutoff"]
# self.assertEqual(kind, "plane_waves")
# self.assertEqual(name, "PW_70.0")
# self.assertEqual(cutoff, convert_unit(70.00000, "rydberg"))
#===============================================================================
if __name__ == '__main__':
suites = []
suites.append(unittest.TestLoader().loadTestsFromTestCase(TestSinglePoint))
alltests = unittest.TestSuite(suites)
unittest.TextTestRunner(verbosity=0).run(alltests)
2 angstroemd0 -1.98834837256869790E+01 (Ha) Geometry + metaData forces
free
N 0.00000000000000000E+00 0.00000000000000000E+00 0.00000000000000000E+00
N 0.00000000000000000E+00 0.00000000000000000E+00 1.11498999595642090E+00
forces
N -1.69406589450860068E-21 -3.38813178901720136E-21 5.67055414067736407E-02
N 1.69406589450860068E-21 3.38813178901720136E-21 -5.67055414067736407E-02
#---------------------------------------------------------------------- Minimal input file
#This file indicates the minimal set of input variables which has to be given to perform
#the run. The code would produce the same output if this file is used as input.
posinp:
units: angstroem
positions:
- N: [0.0, 0.0, 0.0]
- N: [0.0, 0.0, 1.114989995956421]
properties:
format: xyz
source: posinp.xyz
psolver:
environment:
gammaS: water
alphaS: water
betaV: water
---
INIT: # % , Time (s)
Classes:
Flib LowLevel : [ 12.0, 7.98E-02]
Communications : [ 0.0, 2.48E-05]
BLAS-LAPACK : [ 0.8, 5.23E-03]
PS Computation : [ 36.8, 0.25]
Potential : [ 6.5, 4.32E-02]
Convolutions : [ 12.6, 8.43E-02]
Other : [ 0.1, 8.41E-04]
Initialization : [ 6.8, 4.52E-02]
Total : [ 75.6, 0.67]
Categories: #Ordered by time consumption
PSolver Kernel Creation:
Data : [ 21.1, 0.14]
Class : PS Computation
Info : ISF operations and creation of the kernel
PSolver Computation:
Data : [ 15.6, 0.10]
Class : PS Computation
Info : 3D SG_FFT and related operations
Init to Zero:
Data : [ 8.5, 5.65E-02]
Class : Flib LowLevel
Info : Memset of storage space
ApplyLocPotKin:
Data : [ 6.9, 4.61E-02]
Class : Convolutions
Info : OpenCL ported
Exchange-Correlation:
Data : [ 6.5, 4.32E-02]
Class : Potential
Info : Operations needed to construct local XC potential
wavefunction:
Data : [ 6.0, 4.03E-02]
Class : Initialization
Info : Miscellaneous
Rho_comput:
Data : [ 5.7, 3.82E-02]
Class : Convolutions
Info : OpenCL ported
Array allocations:
Data : [ 2.3, 1.51E-02]
Class : Flib LowLevel
Info : Heap storage allocation and associated profiling
Blas (d-s-c-z)GeMM:
Data : [ 0.8, 5.23E-03]
Class : BLAS-LAPACK
Info : Blas General Matrix-Matrix multiplications of any float type
Vector copy:
Data : [ 0.6, 4.20E-03]
Class : Flib LowLevel
Info : Memory copy of arrays (excluded allocations)
Routine Profiling:
Data : [ 0.6, 4.02E-03]
Class : Flib LowLevel
Info : Profiling performances for debugging
CrtLocPot:
Data : [ 0.3, 2.16E-03]
Class : Initialization
Info : Miscellaneous
CrtDescriptors:
Data : [ 0.3, 1.85E-03]
Class : Initialization
Info : RMA Pattern
Input_comput:
Data : [ 0.1, 8.84E-04]
Class : Initialization
Info : Miscellaneous
ApplyProj:
Data : [ 0.1, 6.82E-04]
Class : Other
Info : RMA pattern
ionic_energy:
Data : [ 0.0, 8.49E-05]
Class : Other
Info : Miscellaneous
calc_bounds:
Data : [ 0.0, 3.67E-05]
Class : Other
Info : Miscellaneous
Un-TransSwitch:
Data : [ 0.0, 3.05E-05]
Class : Other
Info : RMA pattern
Allreduce, Large Size:
Data : [ 0.0, 1.79E-05]
Class : Communications
Info : Allreduce operations for more than 5 elements
Pot_after_comm:
Data : [ 0.0, 7.39E-06]
Class : Other
Info : global_to_loca
Pot_commun:
Data : [ 0.0, 5.01E-06]
Class : Communications
Info : AllGathrv grid
Allreduce, Small Size:
Data : [ 0.0, 1.91E-06]
Class : Communications
Info : Allreduce operations for less than 5 elements
WFN_OPT: # % , Time (s)
Classes:
Flib LowLevel : [ 12.4, 0.28]
Communications : [ 0.0, 5.39E-05]
BLAS-LAPACK : [ 0.4, 9.48E-03]
PS Computation : [ 19.5, 0.44]
Potential : [ 17.5, 0.40]
Convolutions : [ 37.8, 0.85]
Linear Algebra : [ 0.4, 8.92E-03]
Other : [ 10.0, 0.23]
Total : [ 98.0, 2.3]
Categories: #Ordered by time consumption
PSolver Computation:
Data : [ 19.5, 0.44]
Class : PS Computation
Info : 3D SG_FFT and related operations
Exchange-Correlation:
Data : [ 17.5, 0.40]
Class : Potential
Info : Operations needed to construct local XC potential
ApplyLocPotKin:
Data : [ 14.2, 0.32]
Class : Convolutions
Info : OpenCL ported
Rho_comput:
Data : [ 12.8, 0.29]
Class : Convolutions
Info : OpenCL ported
Precondition:
Data : [ 10.8, 0.24]
Class : Convolutions
Info : OpenCL ported
ApplyProj:
Data : [ 9.0, 0.20]
Class : Other
Info : RMA pattern
Init to Zero:
Data : [ 6.2, 0.14]
Class : Flib LowLevel
Info : Memset of storage space
Array allocations:
Data : [ 2.6, 5.78E-02]
Class : Flib LowLevel
Info : Heap storage allocation and associated profiling
Routine Profiling:
Data : [ 2.1, 4.81E-02]
Class : Flib LowLevel
Info : Profiling performances for debugging
Vector copy:
Data : [ 1.5, 3.36E-02]
Class : Flib LowLevel
Info : Memory copy of arrays (excluded allocations)
Diis:
Data : [ 1.0, 2.15E-02]
Class : Other
Info : Other
Blas (d-s-c-z)GeMM:
Data : [ 0.4, 9.48E-03]
Class : BLAS-LAPACK
Info : Blas General Matrix-Matrix multiplications of any float type
Chol_comput:
Data : [ 0.4, 8.82E-03]
Class : Linear Algebra
Info : ALLReduce orbs
Un-TransSwitch:
Data : [ 0.0, 4.20E-04]
Class : Other
Info : RMA pattern
LagrM_comput:
Data : [ 0.0, 1.02E-04]
Class : Linear Algebra
Info : DGEMM
Pot_after_comm:
Data : [ 0.0, 8.58E-05]
Class : Other
Info : global_to_loca
Pot_commun:
Data : [ 0.0, 5.39E-05]
Class : Communications
Info : AllGathrv grid
LAST: # % , Time (s)
Classes:
Flib LowLevel : [ 12.9, 4.29E-02]
Communications : [ 0.0, 1.65E-05]
BLAS-LAPACK : [ 0.3, 9.79E-04]
PS Computation : [ 25.2, 8.39E-02]
Potential : [ 11.4, 3.80E-02]
Convolutions : [ 29.3, 9.75E-02]
Other : [ 7.0, 2.32E-02]
Finalization : [ 0.8, 2.72E-03]
Total : [ 87.0, 0.33]
Categories: #Ordered by time consumption
PSolver Computation:
Data : [ 25.2, 8.39E-02]
Class : PS Computation
Info : 3D SG_FFT and related operations
Rho_comput:
Data : [ 15.5, 5.17E-02]
Class : Convolutions
Info : OpenCL ported
ApplyLocPotKin:
Data : [ 13.8, 4.59E-02]
Class : Convolutions
Info : OpenCL ported
Exchange-Correlation:
Data : [ 11.4, 3.80E-02]
Class : Potential
Info : Operations needed to construct local XC potential
Init to Zero:
Data : [ 9.7, 3.22E-02]
Class : Flib LowLevel
Info : Memset of storage space
ApplyProj:
Data : [ 7.0, 2.32E-02]
Class : Other
Info : RMA pattern
Array allocations:
Data : [ 1.3, 4.20E-03]
Class : Flib LowLevel
Info : Heap storage allocation and associated profiling
Vector copy:
Data : [ 1.0, 3.38E-03]
Class : Flib LowLevel
Info : Memory copy of arrays (excluded allocations)
Routine Profiling:
Data : [ 0.9, 3.08E-03]
Class : Flib LowLevel
Info : Profiling performances for debugging
Forces:
Data : [ 0.8, 2.72E-03]
Class : Finalization
Info : Miscellaneous
Blas (d-s-c-z)GeMM:
Data : [ 0.3, 9.50E-04]
Class : BLAS-LAPACK
Info : Blas General Matrix-Matrix multiplications of any float type
Lapack (dsy-ssy-che-zhe)eev:
Data : [ 0.0, 2.93E-05]
Class : BLAS-LAPACK
Info : Lapack Eigenvalue Problem
Un-TransSwitch:
Data : [ 0.0, 1.26E-05]
Class : Other
Info : RMA pattern
Pot_after_comm:
Data : [ 0.0, 8.34E-06]
Class : Other
Info : global_to_loca
Allreduce, Small Size:
Data : [ 0.0, 5.96E-06]
Class : Communications
Info : Allreduce operations for less than 5 elements
Pot_commun:
Data : [ 0.0, 5.72E-06]
Class : Communications
Info : AllGathrv grid
Allreduce, Large Size:
Data : [ 0.0, 4.77E-06]
Class : Communications
Info : Allreduce operations for more than 5 elements
SUMMARY: # % , Time (s)
INIT : [ 20.4, 0.67]
WFN_OPT : [ 69.4, 2.3]
LAST : [ 10.2, 0.33]
Total : [ 100.0, 3.3]
Routines timing and number of calls:
- Main_program: [ 3.58, 1, ~*]
Subroutines:
- process_run (id="posinp"): [ 3.26, 1, 91.17%*]
Subroutines:
- bigdft_state: [ 3.26, 1, 100.12%*]
Subroutines:
- quantum_mechanical_state: [ 3.26, 1, 100.12%*]
Subroutines:
- cluster: [ 3.26, 1, 100.09%]
Subroutines:
- Electrostatic_Solver: [ 0.558, 11, 17.13%]
Subroutines:
- apply_kernel: [ 0.535, 11, 95.91%]
Subroutines:
- G_PoissonSolver: [ 0.455, 11, 84.96%]
- XC_potential: [ 0.450, 11, 13.80%]
Subroutines:
- xc_energy_new: [ 0.427, 11, 94.92%]
Subroutines:
- xc_getvxc: [ 0.403, 11, 94.38%]
- LocalHamiltonianApplication: [ 0.447, 11, 13.71%]
Subroutines:
- psir_to_vpsi: [ 9.405E-02, 55, 21.04%]
Subroutines:
- apply_potential_lr_bounds: [ 8.978E-02, 55, 95.46%]
- orbital_basis_associate: [ 7.953E-04, 11, 0.18%]
- input_wf: [ 0.418, 1, 12.83%]
Subroutines:
- updatePotential: [ 0.103, 1, 24.60%]
Subroutines:
- Electrostatic_Solver: [ 5.468E-02, 1, 53.09%]
Subroutines:
- apply_kernel: [ 5.267E-02, 1, 96.32%]
Subroutines:
- G_PoissonSolver: [ 3.807E-02, 1, 72.28%]
- XC_potential: [ 4.549E-02, 1, 44.17%]
Subroutines:
- xc_energy_new: [ 4.242E-02, 1, 93.25%]
Subroutines:
- xc_getvxc: [ 4.014E-02, 1, 94.63%]
- LocalHamiltonianApplication: [ 5.015E-02, 1, 12.00%]
Subroutines:
- psir_to_vpsi: [ 1.137E-02, 8, 22.66%]
Subroutines:
- apply_potential_lr_bounds: [ 1.082E-02, 8, 95.21%]