diff --git a/benchmark/Project.toml b/benchmark/Project.toml index a73c2c4a4f..cf2ef5886a 100644 --- a/benchmark/Project.toml +++ b/benchmark/Project.toml @@ -1,6 +1,9 @@ [deps] +AtomsBase = "a963bdd2-2df7-4f54-a1ee-49d51e6be12a" BenchmarkCI = "20533458-34a3-403d-a444-e18f38190b5b" BenchmarkTools = "6e4b80f9-dd63-53aa-95a3-0cdb28fa8baf" DFTK = "acf6eb54-70d9-11e9-0013-234b7a5f5337" PkgBenchmark = "32113eaa-f34f-5b0d-bd6c-c81e245fc73d" TestItemRunner = "f8b46487-2199-4994-9208-9a1283c18c0a" +Unitful = "1986cc42-f94f-5a68-af5c-568840ba703d" +UnitfulAtomic = "a7773ee8-282e-5fa2-be4e-bd808c38a91a" diff --git a/benchmark/benchmarks.jl b/benchmark/benchmarks.jl index 8d8604868c..3b367ed2e4 100644 --- a/benchmark/benchmarks.jl +++ b/benchmark/benchmarks.jl @@ -3,5 +3,21 @@ using TestItemRunner const SUITE = BenchmarkGroup() -SUITE["minimal"] = BenchmarkGroup() -SUITE["minimal"] = @benchmarkable @run_package_tests filter=ti->(:minimal ∈ ti.tags) +# TOOD: Look if it can work. +# SUITE["fast"] = BenchmarkGroup() +# SUITE["fast"] = @run_package_tests filter=ti->(:regression ∈ ti.tags) + +SUITE["basis"] = BenchmarkGroup() +SUITE["basis"] = @benchmarkable filter=ti->(ti.name == "Basis construction") seconds=60 + +SUITE["density"] = BenchmarkGroup() +SUITE["density"] = @benchmarkable filter=ti->(ti.name == "Density + symmetrization") seconds=60 + +SUITE["scf"] = BenchmarkGroup() +SUITE["scf"] = @benchmarkable filter=ti->(ti.name == "Single SCF step") seconds=60 + +SUITE["ham"] = BenchmarkGroup() +SUITE["ham"] = @benchmarkable filter=ti->(ti.name == "Hamiltonian application") seconds=60 + +SUITE["sternheimer"] = BenchmarkGroup() +SUITE["sternheimer"] = @benchmarkable filter=ti->(ti.name == "Sternheimer") seconds=60 diff --git a/benchmark/regression/testcases.jl b/benchmark/regression/testcases.jl new file mode 100644 index 0000000000..99194da73d --- /dev/null +++ b/benchmark/regression/testcases.jl @@ -0,0 +1,103 @@ +@testsetup module Regression +using DFTK +using Unitful +using UnitfulAtomic +using AtomsBase +using ..TestCases: magnesium + +high_symmetry = let + a = 4.474 + lattice = [[0, a, a], [a, 0, a], [a, a, 0]]u"bohr" + x = 6.711 + y = 2.237 + atoms = [ + Atom(:Cu, [0, 0, 0]u"bohr", magnetic_moment=0), + Atom(:O, [x, y, x]u"bohr", magnetic_moment=0), + Atom(:O, [x, y, y]u"bohr", magnetic_moment=0), + ] + system = periodic_system(atoms, lattice) + merge(DFTK.parse_system(system), (; temperature=0.03, Ecut=10, kgrid=[4,4,4], + n_electrons=45)) +end +high_kpoints = merge(magnesium, (; kgrid=[13,13,13], Ecut=10)) +high_Ecut = merge(magnesium, (; kgrid=[4,4,4], Ecut=60)) +testcases = (; high_symmetry, high_kpoints, high_Ecut) +end + +@testitem "Hamiltonian application" tags=[:regression] setup=[TestCases, Regression] begin + using DFTK + using LinearAlgebra + + for testcase in Regression.testcases + model = Model(testcase.lattice, testcase.atoms, testcase.positions; + testcase.temperature, terms=[Kinetic()]) + basis = PlaneWaveBasis(model; testcase.Ecut, testcase.kgrid) + + n_electrons = testcase.n_electrons + n_bands = div(n_electrons, 2, RoundUp) + ψ = [Matrix(qr(randn(ComplexF64, length(G_vectors(basis, kpt)), n_bands)).Q) + for kpt in basis.kpoints] + filled_occ = DFTK.filled_occupation(model) + occupation = [filled_occ * rand(n_bands) for _ = 1:length(basis.kpoints)] + occ_scaling = n_electrons / sum(sum(occupation)) + occupation = [occ * occ_scaling for occ in occupation] + + (; ham) = energy_hamiltonian(basis, ψ, occupation) + + for ik = 1:length(basis.kpoints) + ham.blocks[ik]*ψ[ik] + end + end +end + +@testitem "Single SCF step" tags=[:regression] setup=[TestCases, Regression] begin + using DFTK + + for testcase in Regression.testcases + model = model_LDA(testcase.lattice, testcase.atoms, testcase.positions; + testcase.temperature) + basis = PlaneWaveBasis(model; testcase.Ecut, testcase.kgrid) + self_consistent_field(basis; tol=1e5) + end +end + +@testitem "Density + symmetrization" tags=[:regression] setup=[TestCases, Regression] begin + using DFTK + + for testcase in Regression.testcases + model = model_LDA(testcase.lattice, testcase.atoms, testcase.positions; + testcase.temperature) + basis = PlaneWaveBasis(model; testcase.Ecut, testcase.kgrid) + scfres = self_consistent_field(basis; tol=10) + + ψ, occupation = DFTK.select_occupied_orbitals(basis, scfres.ψ, scfres.occupation; + threshold=1e-6) + + ρ = compute_density(basis, ψ, occupation) + DFTK.symmetrize_ρ(basis, ρ) + end +end + +@testitem "Basis construction" tags=[:regression] setup=[TestCases, Regression] begin + using DFTK + + for testcase in Regression.testcases + model = model_LDA(testcase.lattice, testcase.atoms, testcase.positions; + testcase.temperature) + basis = PlaneWaveBasis(model; testcase.Ecut, testcase.kgrid) + end +end + +@testitem "Sternheimer" tags=[:regression] setup=[TestCases, Regression] begin + using DFTK + + for testcase in Regression.testcases + model = model_LDA(testcase.lattice, testcase.atoms, testcase.positions; + testcase.temperature) + basis = PlaneWaveBasis(model; testcase.Ecut, testcase.kgrid) + scfres = self_consistent_field(basis; tol=10) + + rhs = DFTK.compute_projected_gradient(basis, scfres.ψ, scfres.occupation) + DFTK.solve_ΩplusK_split(scfres, rhs) + end +end diff --git a/benchmark/run.jl b/benchmark/run.jl index 5f62499930..8ab416ed9b 100644 --- a/benchmark/run.jl +++ b/benchmark/run.jl @@ -1,4 +1,4 @@ -ROOTPATH = joinpath(@__DIR__, "../..") +ROOTPATH = joinpath(@__DIR__, "..") import Pkg Pkg.activate(@__DIR__) if !isfile(joinpath(@__DIR__, "Manifest.toml")) @@ -9,6 +9,6 @@ end using BenchmarkCI # Remove target once merged. Regression tests will only work after this is merged in master. -BenchmarkCI.judge(; baseline="HEAD~1") +BenchmarkCI.judge(; baseline="HEAD") BenchmarkCI.displayjudgement()