diff --git a/.github/workflows/PerformanceCheck.yml b/.github/workflows/PerformanceCheck.yml index ff40bcb5..2a4850c7 100644 --- a/.github/workflows/PerformanceCheck.yml +++ b/.github/workflows/PerformanceCheck.yml @@ -19,7 +19,7 @@ jobs: uses: julia-actions/julia-buildpkg@latest - run: julia -e ' using Pkg; - Pkg.add(["Test", "TestSetExtensions", "Random", "GitHubActions", "Logging", "AbstractAlgebra"]); + Pkg.add(["Test", "TestSetExtensions", "Random", "GitHubActions", "Logging", "AbstractAlgebra", "Nemo"]); Pkg.add(url="https://github.com/sumiya11/Groebner.jl"); using GitHubActions, Logging; global_logger(GitHubActionsLogger()); diff --git a/Project.toml b/Project.toml index a4cf0b2f..5f7c5b6c 100644 --- a/Project.toml +++ b/Project.toml @@ -9,11 +9,11 @@ Combinatorics = "861a8166-3701-5b0c-9a16-15d98fcdc6aa" ExprTools = "e2ba6199-217a-4e67-a87a-7c52f15ade04" Logging = "56ddb016-857b-54e1-b83d-db4d58db5568" MultivariatePolynomials = "102ac46a-7ee4-5c85-9060-abc95bfdeaa3" +PrecompileTools = "aea7be01-6a6a-4083-8856-8a6e6704d82a" Primes = "27ebfcd6-29c5-5fa9-bf4b-fb8fc14df3ae" Printf = "de0858da-6303-5e67-8744-51eddeeeb8d7" Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" SIMD = "fdea26ae-647d-5447-a871-4b548cad5224" -SnoopPrecompile = "66db9d55-30c0-4569-8b51-7e840670fc0c" TimerOutputs = "a759f4b9-e2f1-59dc-863e-4aeb61b1ea8f" [compat] @@ -22,9 +22,9 @@ BenchmarkTools = "1" Combinatorics = "1" ExprTools = "0.1" MultivariatePolynomials = "0.4, 0.5" +PrecompileTools = "1" Primes = "0.5" SIMD = "3" -SnoopPrecompile = "1" TestSetExtensions = "2" TimerOutputs = "0.5" julia = "1.6" diff --git a/benchmark/CI-scripts/Project.toml b/benchmark/CI-scripts/Project.toml index 72ca508c..02438d09 100644 --- a/benchmark/CI-scripts/Project.toml +++ b/benchmark/CI-scripts/Project.toml @@ -1,6 +1,7 @@ [deps] AbstractAlgebra = "c3fe647b-3220-5bb0-a1ea-a7954cac585d" BenchmarkTools = "6e4b80f9-dd63-53aa-95a3-0cdb28fa8baf" +Nemo = "2edaba10-b0f1-5616-af89-8c11ac63239a" Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" TestSetExtensions = "98d24dd4-01ad-11ea-1b02-c9a08f80db04" diff --git a/benchmark/CI-scripts/run_benchmarks.jl b/benchmark/CI-scripts/run_benchmarks.jl index ca8949ce..7e8d79c3 100644 --- a/benchmark/CI-scripts/run_benchmarks.jl +++ b/benchmark/CI-scripts/run_benchmarks.jl @@ -3,6 +3,7 @@ using Groebner using AbstractAlgebra +import Nemo suite = [] @@ -17,69 +18,138 @@ function compute_gb(system) minimum(times) end -# Compute Groebner bases over +# Compute Groebner bases over integers modulo a large prime +problem = ( + problem_name="groebner, AA, GF(2^31-1), katsura 5", + result=compute_gb(Groebner.katsuran(5, ordering=:degrevlex, ground=GF(2^31 - 1))) +) +push!(suite, problem) push!( suite, ( - problem_name="groebner, GF(2^31-1), katsura 5", + problem_name="groebner, AA, GF(2^31-1), katsura 5", result=compute_gb(Groebner.katsuran(5, ordering=:degrevlex, ground=GF(2^31 - 1))) ) ) push!( suite, ( - problem_name="groebner, GF(2^31-1), katsura 6", + problem_name="groebner, AA, GF(2^31-1), katsura 6", result=compute_gb(Groebner.katsuran(6, ordering=:degrevlex, ground=GF(2^31 - 1))) ) ) push!( suite, ( - problem_name="groebner, GF(2^31-1), katsura 8", + problem_name="groebner, AA, GF(2^31-1), katsura 8", result=compute_gb(Groebner.katsuran(8, ordering=:degrevlex, ground=GF(2^31 - 1))) ) ) push!( suite, ( - problem_name="groebner, GF(2^31-1), katsura 10", + problem_name="groebner, AA, GF(2^31-1), katsura 10", result=compute_gb(Groebner.katsuran(10, ordering=:degrevlex, ground=GF(2^31 - 1))) ) ) push!( suite, ( - problem_name="groebner, GF(2^31-1), cyclic 8", + problem_name="groebner, AA, GF(2^31-1), cyclic 8", result=compute_gb(Groebner.cyclicn(8, ordering=:degrevlex, ground=GF(2^31 - 1))) ) ) push!( suite, ( - problem_name="groebner, QQ, katsura 8", + problem_name="groebner, Nemo, GF(2^31-1), cyclic 8", + result=compute_gb( + Groebner.cyclicn(8, ordering=:degrevlex, ground=Nemo.GF(2^31 - 1), np=Nemo) + ) + ) +) + +# Compute Groebner bases over the rationals +push!( + suite, + ( + problem_name="groebner, AA, QQ, katsura 8", result=compute_gb(Groebner.katsuran(8, ordering=:degrevlex, ground=QQ)) ) ) push!( suite, ( - problem_name="groebner, QQ, eco 10", + problem_name="groebner, Nemo, QQ, katsura 8", + result=compute_gb( + Groebner.katsuran(8, ordering=:degrevlex, ground=Nemo.QQ, np=Nemo) + ) + ) +) +push!( + suite, + ( + problem_name="groebner, AA, QQ, eco 10", result=compute_gb(Groebner.eco10(ordering=:degrevlex, ground=QQ)) ) ) push!( suite, ( - problem_name="groebner, QQ, cyclic 7", + problem_name="groebner, AA, QQ, cyclic 7", result=compute_gb(Groebner.cyclicn(7, ordering=:degrevlex, ground=QQ)) ) ) +function compute_normalforms(system) + R = parent(system[1]) + gb = Groebner.groebner(system) + times = [] + trials = 7 + for _ in 1:trials + GC.gc() + time = @elapsed begin + n1 = normalform(gb, system) + n2 = normalform(gb, gb) + end + push!(times, time) + end + minimum(times) +end + +# Compute normal forms over integers modulo a prime push!( suite, ( - problem_name="groebner, QQ, cyclic 7", - result=compute_gb(Groebner.cyclicn(7, ordering=:degrevlex, ground=QQ)) + problem_name="normalform, AA, GF(2^31-1), cyclic 7", + result=compute_normalforms( + Groebner.cyclicn(7, ordering=:degrevlex, ground=GF(2^31 - 1)) + ) + ) +) +push!( + suite, + ( + problem_name="normalform, AA, GF(103), cyclic 8", + result=compute_normalforms( + Groebner.cyclicn(8, ordering=:degrevlex, ground=GF(103)) + ) + ) +) +push!( + suite, + ( + problem_name="normalform, Nemo, GF(103), cyclic 8", + result=compute_normalforms( + Groebner.cyclicn(8, ordering=:degrevlex, ground=Nemo.GF(103), np=Nemo) + ) + ) +) +push!( + suite, + ( + problem_name="normalform, AA, QQ, katsura 9", + result=compute_normalforms(Groebner.katsuran(9, ordering=:degrevlex, ground=QQ)) ) ) diff --git a/docs/developer.md b/docs/developer.md index 6b095cf9..f39f1a34 100644 --- a/docs/developer.md +++ b/docs/developer.md @@ -69,8 +69,7 @@ groebner([x*y + z, x*z + y], loglevel=-2) All functions in the interface have keyword argument `statistics`. This argument can be set to either of: `:no`, `:timings`, and `:all`. Use `statistics=:timings` to print the table with timings and allocations of internal functions of Groebner.jl. - -Since `Groebner.performance_counters_enabled()` is `false` by default, you should set it to `true` to record runtime statistics. For example, +You should also set `Groebner.performance_counters_enabled()` to `true` to record runtime statistics. For example, ```julia:dev-timings using Groebner, AbstractAlgebra diff --git a/src/Groebner.jl b/src/Groebner.jl index 07579e69..67ec5d9c 100644 --- a/src/Groebner.jl +++ b/src/Groebner.jl @@ -152,7 +152,7 @@ include("fglm/kbase.jl") # API include("interface.jl") -using SnoopPrecompile +using PrecompileTools include("precompile.jl") export groebner, groebner_learn, groebner_apply! diff --git a/src/precompile.jl b/src/precompile.jl index 6351bf63..4169646d 100644 --- a/src/precompile.jl +++ b/src/precompile.jl @@ -2,10 +2,10 @@ @assert VERSION >= v"1.6.0-DEV.154" -@precompile_setup begin +@setup_workload begin # Putting some things in `setup` can reduce the size of the # precompile file and potentially make loading faster. - @precompile_all_calls begin + @compile_workload begin # all calls in this block will be precompiled, regardless of whether # they belong to your package or not (on Julia 1.8 and higher) R, (x, y) = @@ -16,7 +16,7 @@ normalform(arr, arr) R, (x, y) = AbstractAlgebra.PolynomialRing(AbstractAlgebra.GF(2^31 - 1), ["x", "y"]) - arr = [x, y] + arr = [x^2 * y + 1, x * y^2 + 1] gb = groebner(arr, ordering=DegRevLex()) end end