From e27b7945fa6609061b6e337c56a88ba53ab908a7 Mon Sep 17 00:00:00 2001 From: Nicholas Sofroniew Date: Sat, 12 Mar 2022 17:33:35 -0800 Subject: [PATCH 1/5] add initial benchmarks --- benchmarks/__init__.py | 1 + benchmarks/benchmarks.py | 58 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+) create mode 100644 benchmarks/__init__.py create mode 100644 benchmarks/benchmarks.py diff --git a/benchmarks/__init__.py b/benchmarks/__init__.py new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/benchmarks/__init__.py @@ -0,0 +1 @@ + diff --git a/benchmarks/benchmarks.py b/benchmarks/benchmarks.py new file mode 100644 index 0000000..3048af6 --- /dev/null +++ b/benchmarks/benchmarks.py @@ -0,0 +1,58 @@ +# Write the benchmarking functions here. +# See "Writing benchmarks" in the asv docs for more information. +import dqc +import pyscf.dft + +# define molecule descriptions for benchmarking +moldesc_h2o = "O 0.0000 0.0000 0.2217; H 0.0000 1.4309 -0.8867; H 0.0000 -1.4309 -0.8867" # from CCCBDB, exp data +moldesc_c4h5n = """N 0.0000 0.0000 2.1199; H 0.0000 0.0000 4.0021; C 0.0000 2.1182 0.6314; + C 0.0000 -2.1182 0.6314; C 0.0000 1.3372 -1.8608; C 0.0000 -1.3372 -1.8608; + H 0.0000 3.9843 1.4388; H 0.0000 -3.9843 1.4388; H 0.0000 2.5636 -3.4826; + H 0.0000 -2.5636 -3.4826""" + +# create moldesc dictionary so parameter names are easy to understand +molecules = {'H2O': moldesc_h2o, 'C4H5N': moldesc_c4h5n} +molecule_names = ['H2O', 'C4H5N'] + + +class TimeDQC: + """ + Benchmark engery calculations for DQC with cc-pvdz + """ + params = molecule_names + param_names = ['molecule'] + + def setup(self, molecule_name): + moldesc = molecules[molecule_name] + self.m = dqc.Mol(moldesc, basis="cc-pvdz") + + def time_energy_HF(self, _): + # Hartree-Fock + dqc.HF(self.m).run().energy() + + def time_energy_LDA(self, _): + # LDA + # QUESTION: do I need to worry about grid level 4? + dqc.KS(self.m, xc="lda_x+lda_c_pw").run().energy() + + +class TimePySCF: + """ + Benchmark engery calculations for PySCF with cc-pvdz + """ + params = molecule_names + param_names = ['molecule'] + + def setup(self, molecule_name): + moldesc = molecules[molecule_name] + self.m = pyscf.gto.M(atom=moldesc, basis="cc-pvdz", unit="Bohr") + + def time_energy_HF(self, _): + # Hartree-Fock + pyscf.scf.RHF(self.m).kernel() + + def time_energy_LDA(self, _): + # LDA + mf = pyscf.dft.RKS(self.m, xc="lda_x+lda_c_pw") + mf.grids.level = 4 + mf.kernel() \ No newline at end of file From 9beadb981341cad45dc3a60684a579bccad454c8 Mon Sep 17 00:00:00 2001 From: Nicholas Sofroniew Date: Sat, 12 Mar 2022 19:22:33 -0800 Subject: [PATCH 2/5] add properties --- benchmarks/benchmark_properties.py | 62 ++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 benchmarks/benchmark_properties.py diff --git a/benchmarks/benchmark_properties.py b/benchmarks/benchmark_properties.py new file mode 100644 index 0000000..abc9f34 --- /dev/null +++ b/benchmarks/benchmark_properties.py @@ -0,0 +1,62 @@ +# Write the benchmarking functions here. +# See "Writing benchmarks" in the asv docs for more information. +import dqc +import torch + + +# create efield +efield = (torch.tensor([0, 0, 0], dtype=torch.double).requires_grad_(),) + +# define molecule descriptions for benchmarking +moldesc_h2o = "O 0.0000 0.0000 0.2217; H 0.0000 1.4309 -0.8867; H 0.0000 -1.4309 -0.8867" # from CCCBDB, exp data +moldesc_c4h5n = """N 0.0000 0.0000 2.1199; H 0.0000 0.0000 4.0021; C 0.0000 2.1182 0.6314; + C 0.0000 -2.1182 0.6314; C 0.0000 1.3372 -1.8608; C 0.0000 -1.3372 -1.8608; + H 0.0000 3.9843 1.4388; H 0.0000 -3.9843 1.4388; H 0.0000 2.5636 -3.4826; + H 0.0000 -2.5636 -3.4826""" + +# create moldesc dictionary so parameter names are easy to understand +molecules = {'H2O': moldesc_h2o, 'C4H5N': moldesc_c4h5n} +molecule_names = ['H2O', 'C4H5N'] + +# define the systems for benchmarking +systems = ['HF', 'LDA'] + +class TimeProperties: + """ + Benchmark property calculations for DQC with cc-pvdz + """ + params = (molecule_names, systems) + param_names = ['molecule', 'system'] + + def setup(self, molecule_name, system): + moldesc = molecules[molecule_name] + self.m = dqc.Mol(moldesc, basis="cc-pvdz", grid=4, efield=efield) + + if system == 'HF': + # Hartree-Fock + self.sys = dqc.HF(self.m).run() + elif system == 'LDA': + # LDA + self.sys = dqc.KS(self.m, xc="lda_x+lda_c_pw").run() + else: + raise ValueError(f'Unrecognized system {system}, must be one of HF or DFT') + + def time_energy(self, _, __): + # calculate energy + self.sys.energy() + + def time_ir_spectrum(self, _, __): + # calculate ir spectrum + self.m.atompos.requires_grad_() + dqc.ir_spectrum(self.sys, freq_unit='cm^-1') + + # WAITING on fix for #14 + # def time_optimal_geometry(self, _, __): + # # calculate optimal geometry + # self.m.atompos.requires_grad_() + # dqc.optimal_geometry(self.sys) + + def time_vibration(self, _, __): + # calculate vibrational frequency + self.m.atompos.requires_grad_() + dqc.vibration(self.sys, freq_unit='cm^-1') From 7b3832c1566ecaeeed119a84a765980279f1ae5b Mon Sep 17 00:00:00 2001 From: Nicholas Sofroniew Date: Sat, 12 Mar 2022 21:53:29 -0800 Subject: [PATCH 3/5] refactor --- benchmarks/benchmark_properties.py | 62 ----------------- benchmarks/benchmarks.py | 103 +++++++++++++++++++++-------- 2 files changed, 77 insertions(+), 88 deletions(-) delete mode 100644 benchmarks/benchmark_properties.py diff --git a/benchmarks/benchmark_properties.py b/benchmarks/benchmark_properties.py deleted file mode 100644 index abc9f34..0000000 --- a/benchmarks/benchmark_properties.py +++ /dev/null @@ -1,62 +0,0 @@ -# Write the benchmarking functions here. -# See "Writing benchmarks" in the asv docs for more information. -import dqc -import torch - - -# create efield -efield = (torch.tensor([0, 0, 0], dtype=torch.double).requires_grad_(),) - -# define molecule descriptions for benchmarking -moldesc_h2o = "O 0.0000 0.0000 0.2217; H 0.0000 1.4309 -0.8867; H 0.0000 -1.4309 -0.8867" # from CCCBDB, exp data -moldesc_c4h5n = """N 0.0000 0.0000 2.1199; H 0.0000 0.0000 4.0021; C 0.0000 2.1182 0.6314; - C 0.0000 -2.1182 0.6314; C 0.0000 1.3372 -1.8608; C 0.0000 -1.3372 -1.8608; - H 0.0000 3.9843 1.4388; H 0.0000 -3.9843 1.4388; H 0.0000 2.5636 -3.4826; - H 0.0000 -2.5636 -3.4826""" - -# create moldesc dictionary so parameter names are easy to understand -molecules = {'H2O': moldesc_h2o, 'C4H5N': moldesc_c4h5n} -molecule_names = ['H2O', 'C4H5N'] - -# define the systems for benchmarking -systems = ['HF', 'LDA'] - -class TimeProperties: - """ - Benchmark property calculations for DQC with cc-pvdz - """ - params = (molecule_names, systems) - param_names = ['molecule', 'system'] - - def setup(self, molecule_name, system): - moldesc = molecules[molecule_name] - self.m = dqc.Mol(moldesc, basis="cc-pvdz", grid=4, efield=efield) - - if system == 'HF': - # Hartree-Fock - self.sys = dqc.HF(self.m).run() - elif system == 'LDA': - # LDA - self.sys = dqc.KS(self.m, xc="lda_x+lda_c_pw").run() - else: - raise ValueError(f'Unrecognized system {system}, must be one of HF or DFT') - - def time_energy(self, _, __): - # calculate energy - self.sys.energy() - - def time_ir_spectrum(self, _, __): - # calculate ir spectrum - self.m.atompos.requires_grad_() - dqc.ir_spectrum(self.sys, freq_unit='cm^-1') - - # WAITING on fix for #14 - # def time_optimal_geometry(self, _, __): - # # calculate optimal geometry - # self.m.atompos.requires_grad_() - # dqc.optimal_geometry(self.sys) - - def time_vibration(self, _, __): - # calculate vibrational frequency - self.m.atompos.requires_grad_() - dqc.vibration(self.sys, freq_unit='cm^-1') diff --git a/benchmarks/benchmarks.py b/benchmarks/benchmarks.py index 3048af6..7754e38 100644 --- a/benchmarks/benchmarks.py +++ b/benchmarks/benchmarks.py @@ -2,6 +2,11 @@ # See "Writing benchmarks" in the asv docs for more information. import dqc import pyscf.dft +import torch + + +# create efield +efield = (torch.tensor([0, 0, 0], dtype=torch.double).requires_grad_(),) # define molecule descriptions for benchmarking moldesc_h2o = "O 0.0000 0.0000 0.2217; H 0.0000 1.4309 -0.8867; H 0.0000 -1.4309 -0.8867" # from CCCBDB, exp data @@ -14,45 +19,91 @@ molecules = {'H2O': moldesc_h2o, 'C4H5N': moldesc_c4h5n} molecule_names = ['H2O', 'C4H5N'] +# define the systems for benchmarking +systems = ['HF', 'LDA'] -class TimeDQC: + +class TimeCalcDQC: """ - Benchmark engery calculations for DQC with cc-pvdz + Benchmark calculations for dqc with cc-pvdz """ - params = molecule_names - param_names = ['molecule'] + params = (molecule_names, systems) + param_names = ['molecule', 'system'] - def setup(self, molecule_name): + def setup(self, molecule_name, _): moldesc = molecules[molecule_name] - self.m = dqc.Mol(moldesc, basis="cc-pvdz") - - def time_energy_HF(self, _): - # Hartree-Fock - dqc.HF(self.m).run().energy() + self.m = dqc.Mol(moldesc, basis="cc-pvdz", grid=4, efield=efield) - def time_energy_LDA(self, _): - # LDA - # QUESTION: do I need to worry about grid level 4? - dqc.KS(self.m, xc="lda_x+lda_c_pw").run().energy() + def time_calc(self, _, system): + if system == 'HF': + # Hartree-Fock + self.sys = dqc.HF(self.m).run() + elif system == 'LDA': + # LDA + self.sys = dqc.KS(self.m, xc="lda_x+lda_c_pw").run() + else: + raise ValueError(f'Unrecognized system {system}, must be one of {systems}') -class TimePySCF: +class TimeCalcPySCF: """ Benchmark engery calculations for PySCF with cc-pvdz """ - params = molecule_names - param_names = ['molecule'] + params = (molecule_names, systems) + param_names = ['molecule', 'system'] - def setup(self, molecule_name): + def setup(self, molecule_name, _): moldesc = molecules[molecule_name] self.m = pyscf.gto.M(atom=moldesc, basis="cc-pvdz", unit="Bohr") - def time_energy_HF(self, _): - # Hartree-Fock - pyscf.scf.RHF(self.m).kernel() + def time_calc(self, _, system): + if system == 'HF': + # Hartree-Fock + pyscf.scf.RHF(self.m).kernel() + elif system == 'LDA': + # LDA + mf = pyscf.dft.RKS(self.m, xc="lda_x+lda_c_pw") + mf.grids.level = 4 + mf.kernel() + else: + raise ValueError(f'Unrecognized system {system}, must be one of {systems}') + + +class TimePropertiesDQC: + """ + Benchmark property calculations for dqc with cc-pvdz + """ + params = (molecule_names, systems) + param_names = ['molecule', 'system'] + + def setup(self, molecule_name, system): + moldesc = molecules[molecule_name] + self.m = dqc.Mol(moldesc, basis="cc-pvdz", grid=4, efield=efield) + + if system == 'HF': + # Hartree-Fock + self.sys = dqc.HF(self.m).run() + elif system == 'LDA': + # LDA + self.sys = dqc.KS(self.m, xc="lda_x+lda_c_pw").run() + else: + raise ValueError(f'Unrecognized system {system}, must be one of {systems}') + + def time_energy(self, _, __): + # calculate energy + self.sys.energy() + + def time_ir_spectrum(self, _, __): + # calculate ir spectrum + self.m.atompos.requires_grad_() + dqc.ir_spectrum(self.sys, freq_unit='cm^-1') + + def time_optimal_geometry(self, _, __): + # calculate optimal geometry + self.m.atompos.requires_grad_() + dqc.optimal_geometry(self.sys) - def time_energy_LDA(self, _): - # LDA - mf = pyscf.dft.RKS(self.m, xc="lda_x+lda_c_pw") - mf.grids.level = 4 - mf.kernel() \ No newline at end of file + def time_vibration(self, _, __): + # calculate vibrational frequency + self.m.atompos.requires_grad_() + dqc.vibration(self.sys, freq_unit='cm^-1') \ No newline at end of file From 2649b5530c778f4be27955cf15e0e45a5086f670 Mon Sep 17 00:00:00 2001 From: Nicholas Sofroniew Date: Sat, 12 Mar 2022 21:57:26 -0800 Subject: [PATCH 4/5] rename --- benchmarks/benchmarks.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/benchmarks/benchmarks.py b/benchmarks/benchmarks.py index 7754e38..8d8e866 100644 --- a/benchmarks/benchmarks.py +++ b/benchmarks/benchmarks.py @@ -37,10 +37,10 @@ def setup(self, molecule_name, _): def time_calc(self, _, system): if system == 'HF': # Hartree-Fock - self.sys = dqc.HF(self.m).run() + self.qc = dqc.HF(self.m).run() elif system == 'LDA': # LDA - self.sys = dqc.KS(self.m, xc="lda_x+lda_c_pw").run() + self.qc = dqc.KS(self.m, xc="lda_x+lda_c_pw").run() else: raise ValueError(f'Unrecognized system {system}, must be one of {systems}') @@ -82,28 +82,28 @@ def setup(self, molecule_name, system): if system == 'HF': # Hartree-Fock - self.sys = dqc.HF(self.m).run() + self.qc = dqc.HF(self.m).run() elif system == 'LDA': # LDA - self.sys = dqc.KS(self.m, xc="lda_x+lda_c_pw").run() + self.qc = dqc.KS(self.m, xc="lda_x+lda_c_pw").run() else: raise ValueError(f'Unrecognized system {system}, must be one of {systems}') def time_energy(self, _, __): # calculate energy - self.sys.energy() + self.qc.energy() def time_ir_spectrum(self, _, __): # calculate ir spectrum self.m.atompos.requires_grad_() - dqc.ir_spectrum(self.sys, freq_unit='cm^-1') + dqc.ir_spectrum(self.qc, freq_unit='cm^-1') def time_optimal_geometry(self, _, __): # calculate optimal geometry self.m.atompos.requires_grad_() - dqc.optimal_geometry(self.sys) + dqc.optimal_geometry(self.qc) def time_vibration(self, _, __): # calculate vibrational frequency self.m.atompos.requires_grad_() - dqc.vibration(self.sys, freq_unit='cm^-1') \ No newline at end of file + dqc.vibration(self.qc, freq_unit='cm^-1') \ No newline at end of file From e152e758affeb6873653bdd7a7eb4e7c38bb1b62 Mon Sep 17 00:00:00 2001 From: Nicholas Sofroniew Date: Sat, 12 Mar 2022 22:01:31 -0800 Subject: [PATCH 5/5] more rename --- benchmarks/benchmarks.py | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/benchmarks/benchmarks.py b/benchmarks/benchmarks.py index 8d8e866..f651e34 100644 --- a/benchmarks/benchmarks.py +++ b/benchmarks/benchmarks.py @@ -19,75 +19,75 @@ molecules = {'H2O': moldesc_h2o, 'C4H5N': moldesc_c4h5n} molecule_names = ['H2O', 'C4H5N'] -# define the systems for benchmarking -systems = ['HF', 'LDA'] +# define the qccalcs for benchmarking +qccalcs = ['HF', 'LDA'] class TimeCalcDQC: """ Benchmark calculations for dqc with cc-pvdz """ - params = (molecule_names, systems) - param_names = ['molecule', 'system'] + params = (molecule_names, qccalcs) + param_names = ['molecule', 'qccalc'] def setup(self, molecule_name, _): moldesc = molecules[molecule_name] self.m = dqc.Mol(moldesc, basis="cc-pvdz", grid=4, efield=efield) - def time_calc(self, _, system): - if system == 'HF': + def time_qccalc(self, _, qccalc): + if qccalc == 'HF': # Hartree-Fock self.qc = dqc.HF(self.m).run() - elif system == 'LDA': + elif qccalc == 'LDA': # LDA self.qc = dqc.KS(self.m, xc="lda_x+lda_c_pw").run() else: - raise ValueError(f'Unrecognized system {system}, must be one of {systems}') + raise ValueError(f'Unrecognized qccalc {qccalc}, must be one of {qccalcs}') class TimeCalcPySCF: """ Benchmark engery calculations for PySCF with cc-pvdz """ - params = (molecule_names, systems) - param_names = ['molecule', 'system'] + params = (molecule_names, qccalcs) + param_names = ['molecule', 'qccalc'] def setup(self, molecule_name, _): moldesc = molecules[molecule_name] self.m = pyscf.gto.M(atom=moldesc, basis="cc-pvdz", unit="Bohr") - def time_calc(self, _, system): - if system == 'HF': + def time_qccalc(self, _, qccalc): + if qccalc == 'HF': # Hartree-Fock pyscf.scf.RHF(self.m).kernel() - elif system == 'LDA': + elif qccalc == 'LDA': # LDA mf = pyscf.dft.RKS(self.m, xc="lda_x+lda_c_pw") mf.grids.level = 4 mf.kernel() else: - raise ValueError(f'Unrecognized system {system}, must be one of {systems}') + raise ValueError(f'Unrecognized qccalc {qccalc}, must be one of {qccalcs}') class TimePropertiesDQC: """ Benchmark property calculations for dqc with cc-pvdz """ - params = (molecule_names, systems) - param_names = ['molecule', 'system'] + params = (molecule_names, qccalcs) + param_names = ['molecule', 'qccalc'] - def setup(self, molecule_name, system): + def setup(self, molecule_name, qccalc): moldesc = molecules[molecule_name] self.m = dqc.Mol(moldesc, basis="cc-pvdz", grid=4, efield=efield) - if system == 'HF': + if qccalc == 'HF': # Hartree-Fock self.qc = dqc.HF(self.m).run() - elif system == 'LDA': + elif qccalc == 'LDA': # LDA self.qc = dqc.KS(self.m, xc="lda_x+lda_c_pw").run() else: - raise ValueError(f'Unrecognized system {system}, must be one of {systems}') + raise ValueError(f'Unrecognized qccalc {qccalc}, must be one of {qccalcs}') def time_energy(self, _, __): # calculate energy