diff --git a/src/DimensionalAnalysis.jl b/src/DimensionalAnalysis.jl index 511492f8d..d0e975fbf 100644 --- a/src/DimensionalAnalysis.jl +++ b/src/DimensionalAnalysis.jl @@ -194,14 +194,11 @@ function violates_dimensional_constraints( end function violates_dimensional_constraints( tree::AbstractExpressionNode{T}, - X_units::Union{AbstractVector{<:Quantity},Nothing}, + X_units::AbstractVector{<:Quantity}, y_units::Union{Quantity,Nothing}, x::AbstractVector{T}, options::Options, ) where {T} - if X_units === nothing && y_units === nothing - return false - end allow_wildcards = !(options.dimensionless_constants_only) dimensional_output = violates_dimensional_constraints_dispatch( tree, X_units, x, options.operators, allow_wildcards @@ -217,5 +214,15 @@ function violates_dimensional_constraints( end return violates end +function violates_dimensional_constraints( + ::AbstractExpressionNode{T}, ::Nothing, ::Quantity, ::AbstractVector{T}, ::Options +) where {T} + return error("This should never happen. Please submit a bug report.") +end +function violates_dimensional_constraints( + ::AbstractExpressionNode{T}, ::Nothing, ::Nothing, ::AbstractVector{T}, ::Options +) where {T} + return false +end end diff --git a/src/InterfaceDynamicExpressions.jl b/src/InterfaceDynamicExpressions.jl index 2645f1b66..ebd88c7f2 100644 --- a/src/InterfaceDynamicExpressions.jl +++ b/src/InterfaceDynamicExpressions.jl @@ -129,10 +129,10 @@ end Evaluate an expression tree in a way that can be auto-differentiated. """ function differentiable_eval_tree_array( - tree::AbstractExpressionNode, X::AbstractArray, options::Options; kws... + tree::AbstractExpressionNode, X::AbstractArray, options::Options ) A = expected_array_type(X) - return differentiable_eval_tree_array(tree, X, options.operators; kws...)::Tuple{A,Bool} + return differentiable_eval_tree_array(tree, X, options.operators)::Tuple{A,Bool} end const WILDCARD_UNIT_STRING = "[?]" diff --git a/src/LossFunctions.jl b/src/LossFunctions.jl index 7048ced25..ac5493234 100644 --- a/src/LossFunctions.jl +++ b/src/LossFunctions.jl @@ -13,7 +13,7 @@ using ..DimensionalAnalysisModule: violates_dimensional_constraints function _loss( x::AbstractArray{T}, y::AbstractArray{T}, loss::LT ) where {T<:DATA_TYPE,LT<:Union{Function,SupervisedLoss}} - if LT <: SupervisedLoss + if loss isa SupervisedLoss return LossFunctions.mean(loss, x, y) else l(i) = loss(x[i], y[i]) @@ -24,7 +24,7 @@ end function _weighted_loss( x::AbstractArray{T}, y::AbstractArray{T}, w::AbstractArray{T}, loss::LT ) where {T<:DATA_TYPE,LT<:Union{Function,SupervisedLoss}} - if LT <: SupervisedLoss + if loss isa SupervisedLoss return LossFunctions.sum(loss, x, y, w; normalize=true) else l(i) = loss(x[i], y[i], w[i]) diff --git a/src/Operators.jl b/src/Operators.jl index 6933d8d40..cc756f0d6 100644 --- a/src/Operators.jl +++ b/src/Operators.jl @@ -96,7 +96,7 @@ function logical_and(x, y) end # Deprecated operations: -@deprecate pow safe_pow -@deprecate pow_abs safe_pow +@deprecate pow(x, y) safe_pow(x, y) +@deprecate pow_abs(x, y) safe_pow(x, y) end diff --git a/src/Options.jl b/src/Options.jl index 8f2c4ba16..4131a40bf 100644 --- a/src/Options.jl +++ b/src/Options.jl @@ -549,10 +549,16 @@ $(OPTION_DESCRIPTIONS) ) end + is_testing = parse(Bool, get(ENV, "SYMBOLIC_REGRESSION_IS_TESTING", "false")) + if output_file === nothing # "%Y-%m-%d_%H%M%S.%f" date_time_str = Dates.format(Dates.now(), "yyyy-mm-dd_HHMMSS.sss") output_file = "hall_of_fame_" * date_time_str * ".csv" + if is_testing + tmpdir = mktempdir() + output_file = joinpath(tmpdir, output_file) + end end nuna = length(unary_operators) diff --git a/src/SearchUtils.jl b/src/SearchUtils.jl index 4079a977d..fb2da4876 100644 --- a/src/SearchUtils.jl +++ b/src/SearchUtils.jl @@ -37,6 +37,9 @@ Base.@kwdef struct RuntimeOptions{PARALLELISM,DIM_OUT,RETURN_STATE} runtests::Bool verbosity::Int64 progress::Bool + parallelism::Val{PARALLELISM} + dim_out::Val{DIM_OUT} + return_state::Val{RETURN_STATE} end @unstable @inline function Base.getproperty( roptions::RuntimeOptions{P,D,R}, name::Symbol @@ -108,8 +111,8 @@ macro sr_spawner(expr, kws...) @assert all(ex -> ex.head == :(=), kws) @assert any(ex -> ex.args[1] == :parallelism, kws) @assert any(ex -> ex.args[1] == :worker_idx, kws) - parallelism = kws[findfirst(ex -> ex.args[1] == :parallelism, kws)].args[2] - worker_idx = kws[findfirst(ex -> ex.args[1] == :worker_idx, kws)].args[2] + parallelism = kws[findfirst(ex -> ex.args[1] == :parallelism, kws)::Int].args[2] + worker_idx = kws[findfirst(ex -> ex.args[1] == :worker_idx, kws)::Int].args[2] return quote if $(parallelism) == :serial $(expr) diff --git a/src/SymbolicRegression.jl b/src/SymbolicRegression.jl index 0ea9e5599..01632afb3 100644 --- a/src/SymbolicRegression.jl +++ b/src/SymbolicRegression.jl @@ -570,7 +570,7 @@ function equation_search( # Underscores here mean that we have mutated the variable return _equation_search( datasets, - RuntimeOptions{concurrency,dim_out,_return_state}(; + RuntimeOptions(; niterations=niterations, total_cycles=options.populations * niterations, numprocs=_numprocs, @@ -580,6 +580,9 @@ function equation_search( runtests=runtests, verbosity=_verbosity, progress=_progress, + parallelism=Val(concurrency), + dim_out=Val(dim_out), + return_state=Val(_return_state), ), options, saved_state, diff --git a/src/Utils.jl b/src/Utils.jl index 08cccceba..9636252e6 100644 --- a/src/Utils.jl +++ b/src/Utils.jl @@ -6,7 +6,7 @@ using MacroTools: splitdef, combinedef const pseudo_time = Ref(0) -function get_birth_order(; deterministic=false)::Int +function get_birth_order(; deterministic::Bool=false)::Int """deterministic gives a birth time with perfect resolution, but is not thread safe.""" if deterministic global pseudo_time diff --git a/src/deprecates.jl b/src/deprecates.jl index 374756d0a..54816a408 100644 --- a/src/deprecates.jl +++ b/src/deprecates.jl @@ -5,11 +5,11 @@ import .MutationFunctionsModule: gen_random_tree, gen_random_tree_fixed_size @deprecate( gen_random_tree(length::Int, options::Options, nfeatures::Int, t::Type), - gen_random_tree(length, options, nfeatures, t, Node) + gen_random_tree(length, options, nfeatures, t) ) @deprecate( gen_random_tree_fixed_size(node_count::Int, options::Options, nfeatures::Int, t::Type), - gen_random_tree_fixed_size(node_count, options, nfeatures, t, Node) + gen_random_tree_fixed_size(node_count, options, nfeatures, t) ) @deprecate( diff --git a/src/precompile.jl b/src/precompile.jl index 313db452f..87442695d 100644 --- a/src/precompile.jl +++ b/src/precompile.jl @@ -85,7 +85,7 @@ function do_precompilation(::Val{mode}) where {mode} return_state=false, verbosity=0, ) - nout == 1 && calculate_pareto_frontier(hof) + nout == 1 && calculate_pareto_frontier(hof::HallOfFame) end end end diff --git a/test/Project.toml b/test/Project.toml index 422b648aa..b6f96c2d9 100644 --- a/test/Project.toml +++ b/test/Project.toml @@ -6,6 +6,7 @@ Distributed = "8ba89e20-285c-5b6f-9357-94700520ee1b" DynamicExpressions = "a40a106e-89c9-4ca8-8020-a735e8728b6b" DynamicQuantities = "06fc5a27-2a28-4c7c-a15d-362465fb6821" ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210" +JET = "c3a54625-cd67-489e-a8e7-0a5a0ff4e31b" JSON3 = "0f8b85d8-7281-11e9-16c2-39a750bddbf1" LineSearches = "d3d80556-e9d4-5f37-9878-2ab0fcc64255" LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" diff --git a/test/full.jl b/test/full.jl deleted file mode 100644 index f5ecb3e2a..000000000 --- a/test/full.jl +++ /dev/null @@ -1,53 +0,0 @@ -using SymbolicRegression -using Test -using SafeTestsets -using SymbolicRegression: string_tree -using Random - -@safetestset "Test mixed settings." begin - include("test_mixed.jl") -end - -@safetestset "Testing fast-cycle and custom variable names, with mutations" begin - include("test_fast_cycle.jl") -end - -@safetestset "Testing whether we can stop based on clock time." begin - include("test_stop_on_clock.jl") -end - -@safetestset "Running README example." begin - include("../example.jl") -end - -@safetestset "Testing whether the recorder works." begin - include("test_recorder.jl") -end - -@safetestset "Testing whether deterministic mode works." begin - include("test_deterministic.jl") -end - -@safetestset "Testing whether early stop criteria works." begin - include("test_early_stop.jl") -end - -@safetestset "Test MLJ integration" begin - include("test_mlj.jl") -end - -@testset "Testing whether we can move operators to workers." begin - include("test_custom_operators_multiprocessing.jl") -end - -@testset "Test whether the precompilation script works." begin - include("test_precompilation.jl") -end - -@testset "Test whether custom objectives work." begin - include("test_custom_objectives.jl") -end - -@testset "Test abstract numbers" begin - include("test_abstract_numbers.jl") -end diff --git a/test/runtests.jl b/test/runtests.jl index edfa4eb86..dd2209874 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -1,26 +1,168 @@ -using SafeTestsets -using Test +using TestItems: @testitem +using TestItemRunner: @run_package_tests ENV["SYMBOLIC_REGRESSION_TEST"] = "true" -TEST_SUITE = get(ENV, "SYMBOLIC_REGRESSION_TEST_SUITE", "all") +tags_to_run = let t = get(ENV, "SYMBOLIC_REGRESSION_TEST_SUITE", "unit,integration") + t = split(t, ",") + t = map(Symbol, t) + t +end + +@eval @run_package_tests filter = ti -> !isdisjoint(ti.tags, $tags_to_run) + +@testitem "JET tests" tags = [:integration, :jet] begin + test_jet_file = joinpath((@__DIR__), "test_jet.jl") + run(`$(Base.julia_cmd()) --startup-file=no $test_jet_file`) +end + +@testitem "Test custom operators and additional types" tags = [:unit] begin + include("test_operators.jl") +end + +@testitem "Test tree construction and scoring" tags = [:unit] begin + include("test_tree_construction.jl") +end + +@testitem "Test SymbolicUtils interface" tags = [:unit] begin + include("test_symbolic_utils.jl") +end -if TEST_SUITE in ("all", "integration") - @safetestset "Aqua tests" begin - include("test_aqua.jl") - end +@testitem "Test constraints interface" tags = [:unit] begin + include("test_constraints.jl") end -# Trigger extensions: -using LoopVectorization, Bumper, Zygote +@testitem "Test custom losses" tags = [:unit] begin + include("test_losses.jl") +end + +@testitem "Test derivatives" tags = [:unit] begin + include("test_derivatives.jl") +end + +@testitem "Test simplification" tags = [:unit] begin + include("test_simplification.jl") +end + +@testitem "Test printing" tags = [:unit] begin + include("test_print.jl") +end + +@testitem "Test validity of expression evaluation" tags = [:unit] begin + include("test_evaluation.jl") +end + +@testitem "Test turbo mode with NaN" tags = [:unit] begin + include("test_turbo_nan.jl") +end + +@testitem "Test validity of integer expression evaluation" tags = [:unit] begin + include("test_integer_evaluation.jl") +end + +@testitem "Test tournament selection" tags = [:unit] begin + include("test_prob_pick_first.jl") +end + +@testitem "Test crossover mutation" tags = [:unit] begin + include("test_crossover.jl") +end + +@testitem "Test NaN detection in evaluator" tags = [:unit] begin + include("test_nan_detection.jl") +end + +@testitem "Test nested constraint checking" tags = [:unit] begin + include("test_nested_constraints.jl") +end + +@testitem "Test complexity evaluation" tags = [:unit] begin + include("test_complexity.jl") +end + +@testitem "Test options" tags = [:unit] begin + include("test_options.jl") +end + +@testitem "Test hash of tree" tags = [:unit] begin + include("test_hash.jl") +end + +@testitem "Test migration" tags = [:unit] begin + include("test_migration.jl") +end + +@testitem "Test deprecated options" tags = [:unit] begin + include("test_deprecation.jl") +end + +@testitem "Test optimization mutation" tags = [:unit] begin + include("test_optimizer_mutation.jl") +end + +@testitem "Test RunningSearchStatistics" tags = [:unit] begin + include("test_search_statistics.jl") +end + +@testitem "Test utils" tags = [:unit] begin + include("test_utils.jl") +end + +@testitem "Test units" tags = [:integration] begin + include("test_units.jl") +end + +@testitem "Dataset" tags = [:unit] begin + include("test_dataset.jl") +end + +@testitem "Test mixed settings." tags = [:integration] begin + include("test_mixed.jl") +end + +@testitem "Testing fast-cycle and custom variable names" tags = [:integration] begin + include("test_fast_cycle.jl") +end + +@testitem "Testing whether we can stop based on clock time." tags = [:integration] begin + include("test_stop_on_clock.jl") +end + +@testitem "Running README example." tags = [:integration] begin + include("../example.jl") +end + +@testitem "Testing whether the recorder works." tags = [:integration] begin + include("test_recorder.jl") +end + +@testitem "Testing whether deterministic mode works." tags = [:integration] begin + include("test_deterministic.jl") +end + +@testitem "Testing whether early stop criteria works." tags = [:integration] begin + include("test_early_stop.jl") +end + +@testitem "Test MLJ integration" tags = [:integration] begin + include("test_mlj.jl") +end + +@testitem "Testing whether we can move operators to workers." tags = [:integration] begin + include("test_custom_operators_multiprocessing.jl") +end + +@testitem "Test whether the precompilation script works." tags = [:integration] begin + include("test_precompilation.jl") +end + +@testitem "Test whether custom objectives work." tags = [:integration] begin + include("test_custom_objectives.jl") +end -if TEST_SUITE in ("all", "unit") - @safetestset "Unit tests" begin - include("unittest.jl") - end +@testitem "Test abstract numbers" tags = [:integration] begin + include("test_abstract_numbers.jl") end -if TEST_SUITE in ("all", "integration") - @eval @testset "End to end test" begin - include("full.jl") - end +@testitem "Aqua tests" tags = [:integration, :aqua] begin + include("test_aqua.jl") end diff --git a/test/test_abstract_numbers.jl b/test/test_abstract_numbers.jl index 60155be2c..d1ca4412b 100644 --- a/test/test_abstract_numbers.jl +++ b/test/test_abstract_numbers.jl @@ -1,6 +1,6 @@ using SymbolicRegression -using Test using Random +include("test_params.jl") get_base_type(::Type{<:Complex{BT}}) where {BT} = BT diff --git a/test/test_constraints.jl b/test/test_constraints.jl index a7afb3ad9..0a6306923 100644 --- a/test/test_constraints.jl +++ b/test/test_constraints.jl @@ -1,7 +1,6 @@ using DynamicExpressions: count_depth using SymbolicRegression using SymbolicRegression: check_constraints -using Test include("test_params.jl") _inv(x) = 1 / x diff --git a/test/test_crossover.jl b/test/test_crossover.jl index 941ef8cfc..c1da48bb0 100644 --- a/test/test_crossover.jl +++ b/test/test_crossover.jl @@ -1,6 +1,5 @@ println("Testing crossover function.") using SymbolicRegression -using Test using SymbolicRegression: crossover_trees include("test_params.jl") diff --git a/test/test_custom_objectives.jl b/test/test_custom_objectives.jl index 6b9cb1ff4..3696f1750 100644 --- a/test/test_custom_objectives.jl +++ b/test/test_custom_objectives.jl @@ -1,17 +1,26 @@ using SymbolicRegression -using Test include("test_params.jl") -function my_custom_loss( - tree::AbstractExpressionNode{T}, dataset::Dataset{T}, options::Options -) where {T} - # We multiply the tree by 2.0: - tree = Node(1, tree, Node(T; val=2.0)) - out, completed = eval_tree_array(tree, dataset.X, options) - if !completed - return T(Inf) +def = quote + function my_custom_loss( + tree::$(AbstractExpressionNode){T}, dataset::$(Dataset){T}, options::$(Options) + ) where {T} + # We multiply the tree by 2.0: + tree = $(Node)(1, tree, $(Node)(T; val=2.0)) + out, completed = $(eval_tree_array)(tree, dataset.X, options) + if !completed + return T(Inf) + end + return sum(abs, out .- dataset.y) end - return sum(abs, out .- dataset.y) +end + +# TODO: Required for workers as they assume the function is defined in the Main module +if (@__MODULE__) != Core.Main + Core.eval(Core.Main, def) + eval(:(using Main: my_custom_loss)) +else + eval(def) end options = Options(; diff --git a/test/test_custom_operators.jl b/test/test_custom_operators.jl index 46be30c3e..50e72cd16 100644 --- a/test/test_custom_operators.jl +++ b/test/test_custom_operators.jl @@ -1,5 +1,4 @@ using SymbolicRegression -using Test using Random # Test that we can work with custom operators: diff --git a/test/test_custom_operators_multiprocessing.jl b/test/test_custom_operators_multiprocessing.jl index 164278bae..2fca2298e 100644 --- a/test/test_custom_operators_multiprocessing.jl +++ b/test/test_custom_operators_multiprocessing.jl @@ -1,18 +1,26 @@ using SymbolicRegression -using Test -_plus(x, y) = x + y -_mult(x, y) = x * y -_div(x, y) = x / y -_min(x, y) = x - y -_cos(x) = cos(x) -_exp(x) = exp(x) +defs = quote + _plus(x, y) = x + y + _mult(x, y) = x * y + _div(x, y) = x / y + _min(x, y) = x - y + _cos(x) = cos(x) + _exp(x) = exp(x) + early_stop(loss, c) = ((loss <= 1e-10) && (c <= 10)) + my_loss(x, y, w) = abs(x - y)^2 * w +end + +# This is needed as workers are initialized in `Core.Main`! +if (@__MODULE__) != Core.Main + Core.eval(Core.Main, defs) + eval(:(using Main: _plus, _mult, _div, _min, _cos, _exp, early_stop, my_loss)) +else + eval(defs) +end X = randn(Float32, 5, 100) y = _mult.(2, _cos.(X[4, :])) + _mult.(X[1, :], X[1, :]) -early_stop(loss, c) = ((loss <= 1e-10) && (c <= 10)) - -my_loss(x, y, w) = abs(x - y)^2 * w options = SymbolicRegression.Options(; binary_operators=(_plus, _mult, _div, _min), diff --git a/test/test_dataset.jl b/test/test_dataset.jl index fbff37af3..9fdbcfd74 100644 --- a/test/test_dataset.jl +++ b/test/test_dataset.jl @@ -1,5 +1,4 @@ using SymbolicRegression -using Test using DispatchDoctor: allow_unstable @testset "Dataset construction" begin diff --git a/test/test_deprecation.jl b/test/test_deprecation.jl index 2553b6b8c..dda563741 100644 --- a/test/test_deprecation.jl +++ b/test/test_deprecation.jl @@ -1,5 +1,4 @@ using SymbolicRegression -using Test # Deprecated kwargs should still work: options = Options(; diff --git a/test/test_derivatives.jl b/test/test_derivatives.jl index ce444ee17..ee2d4ddfd 100644 --- a/test/test_derivatives.jl +++ b/test/test_derivatives.jl @@ -1,4 +1,3 @@ -using Test using SymbolicRegression using SymbolicRegression: eval_diff_tree_array, eval_grad_tree_array using Random diff --git a/test/test_deterministic.jl b/test/test_deterministic.jl index 8fa1d32c8..d541eea70 100644 --- a/test/test_deterministic.jl +++ b/test/test_deterministic.jl @@ -1,5 +1,4 @@ using SymbolicRegression -using Test using Random macro maybe_inferred(ex) diff --git a/test/test_early_stop.jl b/test/test_early_stop.jl index a50c47522..3ba36e555 100644 --- a/test/test_early_stop.jl +++ b/test/test_early_stop.jl @@ -1,5 +1,4 @@ using SymbolicRegression -using Test X = randn(Float32, 5, 100) y = 2 * cos.(X[4, :]) + X[1, :] .^ 2 diff --git a/test/test_evaluation.jl b/test/test_evaluation.jl index 21625c73c..a3c05dd0c 100644 --- a/test/test_evaluation.jl +++ b/test/test_evaluation.jl @@ -1,6 +1,5 @@ using SymbolicRegression using Random -using Test include("test_params.jl") # Test simple evaluations: diff --git a/test/test_fast_cycle.jl b/test/test_fast_cycle.jl index 1d186faf6..e7d2de845 100644 --- a/test/test_fast_cycle.jl +++ b/test/test_fast_cycle.jl @@ -1,5 +1,4 @@ using SymbolicRegression -using Test using Random include("test_params.jl") diff --git a/test/test_graph_nodes.jl b/test/test_graph_nodes.jl index be0d38a20..639546dc0 100644 --- a/test/test_graph_nodes.jl +++ b/test/test_graph_nodes.jl @@ -1,5 +1,4 @@ using SymbolicRegression -using Test options = Options(; binary_operators=[+, -, *, /], unary_operators=[cos, sin], maxsize=30) diff --git a/test/test_hash.jl b/test/test_hash.jl index e8a84c7ca..5013efea9 100644 --- a/test/test_hash.jl +++ b/test/test_hash.jl @@ -1,5 +1,4 @@ using SymbolicRegression -using Test options = Options(; binary_operators=(+, *, ^, /, greater), unary_operators=(cos,)) @extend_operators options diff --git a/test/test_integer_evaluation.jl b/test/test_integer_evaluation.jl index 4abc3ec68..4b84f8be7 100644 --- a/test/test_integer_evaluation.jl +++ b/test/test_integer_evaluation.jl @@ -1,6 +1,5 @@ using SymbolicRegression using Random -using Test include("test_params.jl") # Test evaluation on integer-based trees. diff --git a/test/test_jet.jl b/test/test_jet.jl new file mode 100644 index 000000000..28476febb --- /dev/null +++ b/test/test_jet.jl @@ -0,0 +1,27 @@ +if VERSION < v"1.10.0" + exit(0) +end + +dir = mktempdir() + +@info "Starting test_jet.jl" dir + +using Pkg +@info "Creating environment..." +Pkg.activate(dir; io=devnull) +Pkg.develop(; path=dirname(@__DIR__), io=devnull) +Pkg.add(["JET", "Preferences"]; io=devnull) +@info "Done!" + +using Preferences +cd(dir) +Preferences.set_preferences!("SymbolicRegression", "instability_check" => "disable") + +using SymbolicRegression +using JET + +@info "Running tests..." +JET.test_package(SymbolicRegression; target_defined_modules=true) +@info "Done!" + +@info "test_jet.jl finished" diff --git a/test/test_losses.jl b/test/test_losses.jl index e5e450772..9277ed23c 100644 --- a/test/test_losses.jl +++ b/test/test_losses.jl @@ -1,7 +1,6 @@ using SymbolicRegression using SymbolicRegression: eval_loss using Random -using Test include("test_params.jl") _loss = SymbolicRegression.LossFunctionsModule._loss diff --git a/test/test_migration.jl b/test/test_migration.jl index fd1d546a7..13c69753e 100644 --- a/test/test_migration.jl +++ b/test/test_migration.jl @@ -1,5 +1,4 @@ using SymbolicRegression -using Test using Random: seed! seed!(0) diff --git a/test/test_mixed.jl b/test/test_mixed.jl index bff1693d9..1da2b1a3e 100644 --- a/test/test_mixed.jl +++ b/test/test_mixed.jl @@ -1,7 +1,6 @@ using SymbolicRegression -using Test using SymbolicRegression: string_tree -using Random +using Random, Bumper, LoopVectorization include("test_params.jl") for i in 0:5 diff --git a/test/test_mlj.jl b/test/test_mlj.jl index 2b0cdc7de..ca0416209 100644 --- a/test/test_mlj.jl +++ b/test/test_mlj.jl @@ -3,7 +3,6 @@ using SymbolicRegression: Node, SRRegressor, MultitargetSRRegressor, node_to_symbolic, symbolic_to_node using MLJTestInterface: MLJTestInterface as MTI using MLJBase: machine, fit!, report, predict -using Test using SymbolicUtils: SymbolicUtils using Suppressor: @capture_err diff --git a/test/test_nan_detection.jl b/test/test_nan_detection.jl index dce861579..fb2a21d1f 100644 --- a/test/test_nan_detection.jl +++ b/test/test_nan_detection.jl @@ -1,6 +1,5 @@ println("Testing NaN detection.") using SymbolicRegression -using Test for T in [Float16, Float32, Float64], turbo in [true, false] T == Float16 && turbo && continue diff --git a/test/test_nested_constraints.jl b/test/test_nested_constraints.jl index f117e7f94..8d3932c01 100644 --- a/test/test_nested_constraints.jl +++ b/test/test_nested_constraints.jl @@ -1,6 +1,5 @@ println("Test operator nesting and flagging.") using SymbolicRegression -using Test function create_options(nested_constraints) return Options(; diff --git a/test/test_operators.jl b/test/test_operators.jl index 21d519dba..47b83418a 100644 --- a/test/test_operators.jl +++ b/test/test_operators.jl @@ -18,7 +18,6 @@ using SymbolicRegression: logical_or, logical_and, gamma -using Test using Random: MersenneTwister using Suppressor: @capture_err using LoopVectorization diff --git a/test/test_optimizer_mutation.jl b/test/test_optimizer_mutation.jl index abaf44bde..41f3bd67d 100644 --- a/test/test_optimizer_mutation.jl +++ b/test/test_optimizer_mutation.jl @@ -4,7 +4,6 @@ using SymbolicRegression: Dataset, RunningSearchStatistics, RecordType using Optim: Optim using SymbolicRegression.MutateModule: next_generation using DynamicExpressions: get_constants -using Test mutation_weights = (; optimize=1e30) # We also test whether a named tuple works. options = Options(; diff --git a/test/test_options.jl b/test/test_options.jl index 1a6a8b7f0..9c7bc0d99 100644 --- a/test/test_options.jl +++ b/test/test_options.jl @@ -1,4 +1,3 @@ -using Test using SymbolicRegression using Optim: Optim diff --git a/test/test_params.jl b/test/test_params.jl index 75f78ab49..7aafd7f48 100644 --- a/test/test_params.jl +++ b/test/test_params.jl @@ -3,10 +3,14 @@ using Optim: Optim using LineSearches: LineSearches using Test: Test -maximum_residual = 1e-2 -custom_cos(x) = cos(x) +ENV["SYMBOLIC_REGRESSION_IS_TESTING"] = "true" -default_params = ( +const maximum_residual = 1e-2 +if !@isdefined(custom_cos) || !hasmethod(custom_cos, (String,)) + @eval custom_cos(x) = cos(x) +end + +const default_params = ( binary_operators=(/, +, *), unary_operators=(exp, custom_cos), constraints=nothing, diff --git a/test/test_print.jl b/test/test_print.jl index 99052851a..fff027504 100644 --- a/test/test_print.jl +++ b/test/test_print.jl @@ -1,4 +1,3 @@ -using Test using SymbolicRegression using SymbolicRegression.UtilsModule: split_string diff --git a/test/test_prob_pick_first.jl b/test/test_prob_pick_first.jl index 84ec44357..8967f0e04 100644 --- a/test/test_prob_pick_first.jl +++ b/test/test_prob_pick_first.jl @@ -1,7 +1,6 @@ println("Testing whether tournament_selection_p works.") using SymbolicRegression using DynamicExpressions.EquationModule: with_type_parameters -using Test include("test_params.jl") n = 10 diff --git a/test/test_recorder.jl b/test/test_recorder.jl index 065877884..95d7b7348 100644 --- a/test/test_recorder.jl +++ b/test/test_recorder.jl @@ -1,8 +1,10 @@ using SymbolicRegression using SymbolicRegression.UtilsModule: recursive_merge -using Test using JSON3 +include("test_params.jl") +base_dir = mktempdir() +recorder_file = joinpath(base_dir, "pysr_recorder.json") X = 2 .* randn(Float32, 2, 1000) y = 3 * cos.(X[2, :]) + X[1, :] .^ 2 .- 2 @@ -10,7 +12,7 @@ options = SymbolicRegression.Options(; binary_operators=(+, *, /, -), unary_operators=(cos,), use_recorder=true, - recorder_file="pysr_recorder.json", + recorder_file=recorder_file, crossover_probability=0.0, # required for recording, as not set up to track crossovers. populations=2, population_size=100, diff --git a/test/test_search_statistics.jl b/test/test_search_statistics.jl index 7247aae2a..35a9b0175 100644 --- a/test/test_search_statistics.jl +++ b/test/test_search_statistics.jl @@ -1,7 +1,6 @@ using SymbolicRegression using SymbolicRegression.AdaptiveParsimonyModule: RunningSearchStatistics, update_frequencies!, move_window!, normalize_frequencies! -using Test using Random options = Options() diff --git a/test/test_simplification.jl b/test/test_simplification.jl index 0518c77c8..ad6c0a562 100644 --- a/test/test_simplification.jl +++ b/test/test_simplification.jl @@ -47,20 +47,20 @@ tree_copy = convert(Node, eqn, options) # with custom operators, and unary operators: x1, x2, x3 = Node("x1"), Node("x2"), Node("x3") pow_abs2(x, y) = abs(x)^y -custom_cos(x) = cos(x)^2 +custom_cos2(x) = cos(x)^2 options = Options(; - binary_operators=(+, *, -, /, pow_abs2), unary_operators=(custom_cos, exp, sin) + binary_operators=(+, *, -, /, pow_abs2), unary_operators=(custom_cos2, exp, sin) ) @extend_operators options tree = ( ((x2 + x2) * ((-0.5982493 / pow_abs2(x1, x2)) / -0.54734415)) + ( sin( - custom_cos( + custom_cos2( sin(1.2926733 - 1.6606787) / sin(((0.14577048 * x1) + ((0.111149654 + x1) - -0.8298334)) - -1.2071426), - ) * (custom_cos(x3 - 2.3201916) + ((x1 - (x1 * x2)) / x2)), - ) / (0.14854191 - ((custom_cos(x2) * -1.6047639) - 0.023943262)) + ) * (custom_cos2(x3 - 2.3201916) + ((x1 - (x1 * x2)) / x2)), + ) / (0.14854191 - ((custom_cos2(x2) * -1.6047639) - 0.023943262)) ) ) # We use `index_functions` to avoid converting the custom operators into the primitives. diff --git a/test/test_stop_on_clock.jl b/test/test_stop_on_clock.jl index f6c40dc3a..295586e57 100644 --- a/test/test_stop_on_clock.jl +++ b/test/test_stop_on_clock.jl @@ -1,5 +1,4 @@ using SymbolicRegression -using Test using Random include("test_params.jl") diff --git a/test/test_symbolic_utils.jl b/test/test_symbolic_utils.jl index a5c040cfc..3e074abaa 100644 --- a/test/test_symbolic_utils.jl +++ b/test/test_symbolic_utils.jl @@ -1,6 +1,5 @@ using SymbolicUtils using SymbolicRegression -using Test include("test_params.jl") _inv(x) = 1 / x diff --git a/test/test_tree_construction.jl b/test/test_tree_construction.jl index f055ea566..f233bf118 100644 --- a/test/test_tree_construction.jl +++ b/test/test_tree_construction.jl @@ -2,7 +2,6 @@ using SymbolicRegression using Random using SymbolicRegression: eval_loss, score_func, Dataset using ForwardDiff -using Test include("test_params.jl") x1 = 2.0 diff --git a/test/test_turbo_nan.jl b/test/test_turbo_nan.jl index 9165c82c9..2447b8253 100644 --- a/test/test_turbo_nan.jl +++ b/test/test_turbo_nan.jl @@ -1,5 +1,4 @@ using SymbolicRegression -using Test bad_op(x::T) where {T} = (x >= 0) ? x : T(0) diff --git a/test/test_units.jl b/test/test_units.jl index ae0855a38..0e58173e1 100644 --- a/test/test_units.jl +++ b/test/test_units.jl @@ -30,7 +30,6 @@ using DynamicQuantities: sym_uparse, ustrip, dimension -using Test using MLJBase: MLJBase as MLJ using MLJModelInterface: MLJModelInterface as MMI include("utils.jl") diff --git a/test/test_utils.jl b/test/test_utils.jl index e13f6d34e..67ceb0dcc 100644 --- a/test/test_utils.jl +++ b/test/test_utils.jl @@ -2,7 +2,6 @@ using SymbolicRegression using SymbolicRegression.UtilsModule: findmin_fast, argmin_fast, bottomk_fast, is_anonymous_function using Random -using Test function simple_bottomk(x, k) idx = sortperm(x)[1:k] diff --git a/test/unittest.jl b/test/unittest.jl deleted file mode 100644 index f4cd99cba..000000000 --- a/test/unittest.jl +++ /dev/null @@ -1,104 +0,0 @@ -using SafeTestsets - -# Trigger extensions: -using LoopVectorization - -@safetestset "Test custom operators and additional types" begin - include("test_operators.jl") -end - -@safetestset "Test tree construction and scoring" begin - include("test_tree_construction.jl") -end - -@safetestset "Test SymbolicUtils interface" begin - include("test_symbolic_utils.jl") -end - -@safetestset "Test constraints interface" begin - include("test_constraints.jl") -end - -@safetestset "Test custom losses" begin - include("test_losses.jl") -end - -@safetestset "Test derivatives" begin - include("test_derivatives.jl") -end - -@safetestset "Test simplification" begin - include("test_simplification.jl") -end - -@safetestset "Test printing" begin - include("test_print.jl") -end - -@safetestset "Test validity of expression evaluation" begin - include("test_evaluation.jl") -end - -@safetestset "Test turbo mode with NaN" begin - include("test_turbo_nan.jl") -end - -@safetestset "Test validity of integer expression evaluation" begin - include("test_integer_evaluation.jl") -end - -@safetestset "Test tournament selection" begin - include("test_prob_pick_first.jl") -end - -@safetestset "Test crossover mutation" begin - include("test_crossover.jl") -end - -@safetestset "Test NaN detection in evaluator" begin - include("test_nan_detection.jl") -end - -@safetestset "Test nested constraint checking" begin - include("test_nested_constraints.jl") -end - -@safetestset "Test complexity evaluation" begin - include("test_complexity.jl") -end - -@safetestset "Test options" begin - include("test_options.jl") -end - -@safetestset "Test hash of tree" begin - include("test_hash.jl") -end - -@safetestset "Test migration" begin - include("test_migration.jl") -end - -@safetestset "Test deprecated options" begin - include("test_deprecation.jl") -end - -@safetestset "Test optimization mutation" begin - include("test_optimizer_mutation.jl") -end - -@safetestset "Test RunningSearchStatistics" begin - include("test_search_statistics.jl") -end - -@safetestset "Test utils" begin - include("test_utils.jl") -end - -@safetestset "Test units" begin - include("test_units.jl") -end - -@safetestset "Dataset" begin - include("test_dataset.jl") -end