From f8e34a443f9b134d2d56856dd06066356b462abc Mon Sep 17 00:00:00 2001 From: MilesCranmer Date: Sun, 7 Sep 2025 12:36:18 +0100 Subject: [PATCH 1/6] style: clean up stale imports --- src/ComposableExpression.jl | 3 +++ src/Core.jl | 20 ++++++++++++++++++++ src/DimensionalAnalysis.jl | 2 +- src/ExpressionSpec.jl | 2 +- src/InterfaceDynamicExpressions.jl | 2 +- src/MLJInterface.jl | 9 ++++++++- src/MutationFunctions.jl | 4 +--- src/Operators.jl | 6 ++++-- src/Options.jl | 1 - src/ParametricExpression.jl | 1 - src/Population.jl | 2 +- src/SearchUtils.jl | 2 +- src/SingleIteration.jl | 3 +-- src/SymbolicRegression.jl | 11 ++++++++--- src/TemplateExpression.jl | 6 +++--- src/Utils.jl | 6 ++++++ 16 files changed, 59 insertions(+), 21 deletions(-) diff --git a/src/ComposableExpression.jl b/src/ComposableExpression.jl index 7e3ee3dd0..75379cc28 100644 --- a/src/ComposableExpression.jl +++ b/src/ComposableExpression.jl @@ -20,9 +20,12 @@ using DynamicExpressions.InterfacesModule: ExpressionInterface, Interfaces, @implements, all_ei_methods_except, Arguments using DynamicExpressions.ValueInterfaceModule: is_valid_array +using ..UtilsModule: @intentional_import using ..ConstantOptimizationModule: ConstantOptimizationModule as CO using ..CoreModule: get_safe_op +@intentional_import Interfaces + abstract type AbstractComposableExpression{T,N} <: AbstractExpression{T,N} end """ diff --git a/src/Core.jl b/src/Core.jl index 76f7e0fe4..abe6282c5 100644 --- a/src/Core.jl +++ b/src/Core.jl @@ -71,5 +71,25 @@ using .ExpressionSpecModule: get_expression_options, get_node_type using .InterfaceDataTypesModule: init_value, sample_value, mutate_value +using .UtilsModule: @intentional_import + +# These are imported from submodules for use by parent module +@intentional_import RecordType, DATA_TYPE, LOSS_TYPE +@intentional_import Dataset, BasicDataset, SubDataset, is_weighted, has_units +@intentional_import max_features, batch, get_indices, get_full_dataset, dataset_fraction +@intentional_import AbstractMutationWeights, MutationWeights, sample_mutation +@intentional_import AbstractOptions, Options, ComplexityMapping, WarmStartIncompatibleError +@intentional_import check_warm_start_compatibility, get_safe_op +@intentional_import plus, sub, mult, square, cube, pow, safe_pow, div +@intentional_import safe_log, safe_log2, safe_log10, safe_log1p, safe_asin +@intentional_import safe_acos, safe_atan, safe_acosh, safe_atanh_clip +@intentional_import safe_sqrt, safe_cbrt, neg, greater, cond, relu +@intentional_import greater_equal, less, less_equal +@intentional_import logical_or, logical_and, gamma, safe_atanh, safe_csch +@intentional_import operator_specialization, specialized_options +@intentional_import erf, erfc, atanh_clip +@intentional_import AbstractExpressionSpec, ExpressionSpec, get_expression_type +@intentional_import get_expression_options, get_node_type +@intentional_import init_value, sample_value, mutate_value end diff --git a/src/DimensionalAnalysis.jl b/src/DimensionalAnalysis.jl index 5690e4a06..1632401e9 100644 --- a/src/DimensionalAnalysis.jl +++ b/src/DimensionalAnalysis.jl @@ -1,7 +1,7 @@ module DimensionalAnalysisModule using DynamicExpressions: - AbstractExpression, AbstractExpressionNode, get_tree, get_child, tree_mapreduce + AbstractExpression, AbstractExpressionNode, get_tree, tree_mapreduce using DynamicQuantities: Quantity, DimensionError, AbstractQuantity, constructorof using ..CoreModule: AbstractOptions, Dataset diff --git a/src/ExpressionSpec.jl b/src/ExpressionSpec.jl index d09acf514..d930a7ef0 100644 --- a/src/ExpressionSpec.jl +++ b/src/ExpressionSpec.jl @@ -1,6 +1,6 @@ module ExpressionSpecModule -using DynamicExpressions: AbstractExpression, Expression, AbstractExpressionNode, Node +using DynamicExpressions: Expression, Node abstract type AbstractExpressionSpec end diff --git a/src/InterfaceDynamicExpressions.jl b/src/InterfaceDynamicExpressions.jl index 5a96addcb..cb948b5c1 100644 --- a/src/InterfaceDynamicExpressions.jl +++ b/src/InterfaceDynamicExpressions.jl @@ -14,7 +14,7 @@ using DynamicExpressions: GraphNode, EvalOptions using DynamicQuantities: dimension, ustrip -using ..CoreModule: AbstractOptions, Dataset +using ..CoreModule: AbstractOptions using ..CoreModule.OptionsModule: inverse_opmap using ..UtilsModule: subscriptify diff --git a/src/MLJInterface.jl b/src/MLJInterface.jl index 5845e2db2..8e5bc68ba 100644 --- a/src/MLJInterface.jl +++ b/src/MLJInterface.jl @@ -42,12 +42,19 @@ using ..CoreModule: using ..CoreModule.OptionsModule: DEFAULT_OPTIONS, OPTION_DESCRIPTIONS using ..ComplexityModule: compute_complexity using ..HallOfFameModule: HallOfFame, format_hall_of_fame -using ..UtilsModule: subscriptify, @ignore +using ..UtilsModule: subscriptify, @ignore, @intentional_import using ..LoggingModule: AbstractSRLogger using ..TemplateExpressionModule: TemplateExpression import ..equation_search +# These imports are needed for MLJ generated code +@intentional_import AbstractADType, AbstractExpressionNode, AbstractExpressionSpec +@intentional_import AbstractLogger, AbstractMutationWeights, AbstractOperatorEnum +@intentional_import ComplexityMapping, Dataset, Expression, MutationWeights +@intentional_import Node, SupervisedLoss, TemplateExpression, compute_complexity +@intentional_import default_node_type, get_tree + abstract type AbstractSymbolicRegressor <: MMI.Deterministic end abstract type AbstractSingletargetSRRegressor <: AbstractSymbolicRegressor end diff --git a/src/MutationFunctions.jl b/src/MutationFunctions.jl index 3f46c879b..2c66d15c2 100644 --- a/src/MutationFunctions.jl +++ b/src/MutationFunctions.jl @@ -10,12 +10,10 @@ using DynamicExpressions: with_contents, constructorof, set_node!, - count_nodes, has_constants, has_operators, get_child, - set_child!, - max_degree + set_child! using ..CoreModule: AbstractOptions, DATA_TYPE, init_value, sample_value import ..CoreModule: mutate_value diff --git a/src/Operators.jl b/src/Operators.jl index d26484da1..366d1fa82 100644 --- a/src/Operators.jl +++ b/src/Operators.jl @@ -6,8 +6,10 @@ using DynamicQuantities: UnionAbstractQuantity using SpecialFunctions: erf, erfc using Base: @deprecate using DynamicDiff: ForwardDiff -using ..ProgramConstantsModule: DATA_TYPE -using ...UtilsModule: @ignore +using ...UtilsModule: @ignore, @intentional_import + +@intentional_import erf, erfc + #TODO - actually add these operators to the module! # TODO: Should this be limited to AbstractFloat instead? diff --git a/src/Options.jl b/src/Options.jl index cde0d5a31..bb7df25b7 100644 --- a/src/Options.jl +++ b/src/Options.jl @@ -5,7 +5,6 @@ using Optim: Optim using DynamicExpressions: OperatorEnum, AbstractOperatorEnum, - Expression, default_node_type, AbstractExpression, AbstractExpressionNode diff --git a/src/ParametricExpression.jl b/src/ParametricExpression.jl index 2717afbdc..fd380fd96 100644 --- a/src/ParametricExpression.jl +++ b/src/ParametricExpression.jl @@ -18,7 +18,6 @@ using Random: default_rng, AbstractRNG using ..CoreModule: AbstractOptions, Dataset, - SubDataset, DATA_TYPE, AbstractMutationWeights, AbstractExpressionSpec, diff --git a/src/Population.jl b/src/Population.jl index 739ca828e..ea2c0a767 100644 --- a/src/Population.jl +++ b/src/Population.jl @@ -3,7 +3,7 @@ module PopulationModule using StatsBase: StatsBase using DispatchDoctor: @unstable using DynamicExpressions: AbstractExpression, string_tree -using ..CoreModule: AbstractOptions, Options, Dataset, RecordType, DATA_TYPE, LOSS_TYPE +using ..CoreModule: AbstractOptions, Dataset, RecordType, DATA_TYPE, LOSS_TYPE using ..ComplexityModule: compute_complexity using ..LossFunctionsModule: eval_cost, update_baseline_loss! using ..AdaptiveParsimonyModule: RunningSearchStatistics diff --git a/src/SearchUtils.jl b/src/SearchUtils.jl index 89eaa8cbf..914c4e313 100644 --- a/src/SearchUtils.jl +++ b/src/SearchUtils.jl @@ -14,7 +14,7 @@ using Logging: AbstractLogger using DynamicExpressions: AbstractExpression, string_tree, parse_expression, EvalOptions, with_type_parameters using ..UtilsModule: subscriptify -using ..CoreModule: Dataset, AbstractOptions, Options, RecordType, max_features +using ..CoreModule: Dataset, AbstractOptions, RecordType, max_features using ..ComplexityModule: compute_complexity using ..PopulationModule: Population using ..PopMemberModule: PopMember diff --git a/src/SingleIteration.jl b/src/SingleIteration.jl index 426abc8f8..4f666ec93 100644 --- a/src/SingleIteration.jl +++ b/src/SingleIteration.jl @@ -3,14 +3,13 @@ module SingleIterationModule using ADTypes: AutoEnzyme using DynamicExpressions: AbstractExpression, string_tree, simplify_tree!, combine_operators using ..UtilsModule: @threads_if -using ..CoreModule: AbstractOptions, Dataset, RecordType, create_expression, batch +using ..CoreModule: AbstractOptions, Dataset, RecordType, batch using ..ComplexityModule: compute_complexity using ..PopMemberModule: generate_reference using ..PopulationModule: Population, finalize_costs using ..HallOfFameModule: HallOfFame using ..AdaptiveParsimonyModule: RunningSearchStatistics using ..RegularizedEvolutionModule: reg_evol_cycle -using ..LossFunctionsModule: eval_cost using ..ConstantOptimizationModule: optimize_constants using ..RecorderModule: @recorder diff --git a/src/SymbolicRegression.jl b/src/SymbolicRegression.jl index de709ddde..c9b293c9b 100644 --- a/src/SymbolicRegression.jl +++ b/src/SymbolicRegression.jl @@ -91,12 +91,12 @@ export Population, erfc, atanh_clip -using Distributed +using Distributed: @everywhere, @spawnat, RemoteChannel, addprocs, procs using Printf: @printf, @sprintf using Pkg: Pkg using TOML: parsefile using Random: seed!, shuffle! -using Reexport +using Reexport: Reexport, @reexport using ProgressMeter: finish! using DynamicExpressions: Node, @@ -287,7 +287,8 @@ using .CoreModule: atanh_clip, create_expression, has_units -using .UtilsModule: is_anonymous_function, recursive_merge, json3_write, @ignore +using .UtilsModule: + is_anonymous_function, recursive_merge, json3_write, @ignore, @intentional_import using .ComplexityModule: compute_complexity using .CheckConstraintsModule: check_constraints using .AdaptiveParsimonyModule: @@ -349,6 +350,10 @@ using .ExpressionBuilderModule: embed_metadata, strip_metadata using .ParametricExpressionModule: ParametricExpressionSpec using .TemplateExpressionMacroModule: @template_spec +@intentional_import BasicDataset, ComplexityMapping, StdinReader, best_of_sample +@intentional_import get_constants, set_constants!, with_type_parameters +@intentional_import get_logger, get_safe_op, has_params, random_node, reset_birth! + @stable default_mode = "disable" begin include("deprecates.jl") include("Configure.jl") diff --git a/src/TemplateExpression.jl b/src/TemplateExpression.jl index af86f4825..5bd0b1ae4 100644 --- a/src/TemplateExpression.jl +++ b/src/TemplateExpression.jl @@ -9,7 +9,6 @@ using DispatchDoctor: @unstable, @stable using StyledStrings: @styled_str, annotatedstring using DynamicExpressions: DynamicExpressions as DE, - AbstractStructuredExpression, AbstractExpressionNode, AbstractExpression, AbstractOperatorEnum, @@ -25,13 +24,12 @@ using DynamicExpressions: with_metadata, with_contents, node_type, - count_nodes, preserve_sharing using DynamicExpressions.InterfacesModule: ExpressionInterface, Interfaces, @implements, all_ei_methods_except, Arguments using DynamicExpressions.ExpressionModule: _copy -using ..UtilsModule: FixKws +using ..UtilsModule: FixKws, @intentional_import using ..CoreModule: AbstractOptions, Options, @@ -55,6 +53,8 @@ using ..MutateModule: MutateModule as MM using ..PopMemberModule: PopMember using ..ComposableExpressionModule: ComposableExpression, ValidVector +@intentional_import Interfaces + struct ParamVector{T} <: AbstractVector{T} _data::Vector{T} end diff --git a/src/Utils.jl b/src/Utils.jl index eca69119d..cab2cb72a 100644 --- a/src/Utils.jl +++ b/src/Utils.jl @@ -9,6 +9,12 @@ using DispatchDoctor: @unstable macro ignore(args...) end +""" +A no-op macro used to mark symbols as intentionally imported. +This tells ExplicitImports.jl that we need these symbols even if they appear unused. +""" +macro intentional_import(args...) end + const pseudo_time = Ref(0) function get_birth_order(; deterministic::Bool=false)::Int From c09470ca1cdb18464d4b00f4c4d739d72a6b40c4 Mon Sep 17 00:00:00 2001 From: MilesCranmer Date: Sun, 7 Sep 2025 13:07:20 +0100 Subject: [PATCH 2/6] fix: missing `rmprocs` import --- src/SymbolicRegression.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/SymbolicRegression.jl b/src/SymbolicRegression.jl index c9b293c9b..2e11d28d5 100644 --- a/src/SymbolicRegression.jl +++ b/src/SymbolicRegression.jl @@ -91,7 +91,7 @@ export Population, erfc, atanh_clip -using Distributed: @everywhere, @spawnat, RemoteChannel, addprocs, procs +using Distributed: @everywhere, @spawnat, RemoteChannel, addprocs, procs, rmprocs using Printf: @printf, @sprintf using Pkg: Pkg using TOML: parsefile From faa6a1d409577c9a2819c3344620c03c6141623f Mon Sep 17 00:00:00 2001 From: MilesCranmer Date: Sun, 7 Sep 2025 13:52:12 +0100 Subject: [PATCH 3/6] refactor: pass `options` explicitly to `recorder` --- src/Mutate.jl | 42 ++++++++++++++++++------------------- src/Recorder.jl | 8 +++---- src/RegularizedEvolution.jl | 4 ++-- src/SingleIteration.jl | 2 +- src/SymbolicRegression.jl | 11 +++++----- 5 files changed, 33 insertions(+), 34 deletions(-) diff --git a/src/Mutate.jl b/src/Mutate.jl index f5fd88457..652e03fad 100644 --- a/src/Mutate.jl +++ b/src/Mutate.jl @@ -247,7 +247,7 @@ end tree = rtree[] if !successful_mutation - @recorder begin + @recorder options begin tmp_recorder["result"] = "reject" tmp_recorder["reason"] = "failed_constraint_check" end @@ -271,7 +271,7 @@ end num_evals += dataset_fraction(dataset) if isnan(after_cost) - @recorder begin + @recorder options begin tmp_recorder["result"] = "reject" tmp_recorder["reason"] = "nan_loss" end @@ -315,7 +315,7 @@ end end if probChange < rand() - @recorder begin + @recorder options begin tmp_recorder["result"] = "reject" tmp_recorder["reason"] = "annealing_or_frequency" end @@ -334,7 +334,7 @@ end num_evals, ) else - @recorder begin + @recorder options begin tmp_recorder["result"] = "accept" tmp_recorder["reason"] = "pass" end @@ -429,7 +429,7 @@ function mutate!( kws..., ) where {N<:AbstractExpression,P<:PopMember} tree = mutate_constant(tree, temperature, options) - @recorder recorder["type"] = "mutate_constant" + @recorder options recorder["type"] = "mutate_constant" return MutationResult{N,P}(; tree=tree) end @@ -443,7 +443,7 @@ function mutate!( kws..., ) where {N<:AbstractExpression,P<:PopMember} tree = mutate_operator(tree, options) - @recorder recorder["type"] = "mutate_operator" + @recorder options recorder["type"] = "mutate_operator" return MutationResult{N,P}(; tree=tree) end @@ -458,7 +458,7 @@ function mutate!( kws..., ) where {N<:AbstractExpression,P<:PopMember} tree = mutate_feature(tree, nfeatures) - @recorder recorder["type"] = "mutate_feature" + @recorder options recorder["type"] = "mutate_feature" return MutationResult{N,P}(; tree=tree) end @@ -472,7 +472,7 @@ function mutate!( kws..., ) where {N<:AbstractExpression,P<:PopMember} tree = swap_operands(tree) - @recorder recorder["type"] = "swap_operands" + @recorder options recorder["type"] = "swap_operands" return MutationResult{N,P}(; tree=tree) end @@ -488,10 +488,10 @@ function mutate!( ) where {N<:AbstractExpression,P<:PopMember} if rand() < 0.5 tree = append_random_op(tree, options, nfeatures) - @recorder recorder["type"] = "add_node:append" + @recorder options recorder["type"] = "add_node:append" else tree = prepend_random_op(tree, options, nfeatures) - @recorder recorder["type"] = "add_node:prepend" + @recorder options recorder["type"] = "add_node:prepend" end return MutationResult{N,P}(; tree=tree) end @@ -507,7 +507,7 @@ function mutate!( kws..., ) where {N<:AbstractExpression,P<:PopMember} tree = insert_random_op(tree, options, nfeatures) - @recorder recorder["type"] = "insert_node" + @recorder options recorder["type"] = "insert_node" return MutationResult{N,P}(; tree=tree) end @@ -521,7 +521,7 @@ function mutate!( kws..., ) where {N<:AbstractExpression,P<:PopMember} tree = delete_random_op!(tree) - @recorder recorder["type"] = "delete_node" + @recorder options recorder["type"] = "delete_node" return MutationResult{N,P}(; tree=tree) end @@ -535,7 +535,7 @@ function mutate!( kws..., ) where {N<:AbstractExpression,P<:PopMember} tree = form_random_connection!(tree) - @recorder recorder["type"] = "form_connection" + @recorder options recorder["type"] = "form_connection" return MutationResult{N,P}(; tree=tree) end @@ -549,7 +549,7 @@ function mutate!( kws..., ) where {N<:AbstractExpression,P<:PopMember} tree = break_random_connection!(tree) - @recorder recorder["type"] = "break_connection" + @recorder options recorder["type"] = "break_connection" return MutationResult{N,P}(; tree=tree) end @@ -563,7 +563,7 @@ function mutate!( kws..., ) where {N<:AbstractExpression,P<:PopMember} tree = randomly_rotate_tree!(tree) - @recorder recorder["type"] = "rotate_tree" + @recorder options recorder["type"] = "rotate_tree" return MutationResult{N,P}(; tree=tree) end @@ -581,7 +581,7 @@ function mutate!( @assert options.should_simplify simplify_tree!(tree, options.operators) tree = combine_operators(tree, options.operators) - @recorder recorder["type"] = "simplify" + @recorder options recorder["type"] = "simplify" return MutationResult{N,P}(; member=PopMember( tree, @@ -607,7 +607,7 @@ function mutate!( kws..., ) where {T,N<:AbstractExpression{T},P<:PopMember} tree = randomize_tree(tree, curmaxsize, options, nfeatures) - @recorder recorder["type"] = "randomize" + @recorder options recorder["type"] = "randomize" return MutationResult{N,P}(; tree=tree) end @@ -622,7 +622,7 @@ function mutate!( kws..., ) where {N<:AbstractExpression,P<:PopMember} cur_member, new_num_evals = optimize_constants(dataset, member, options) - @recorder recorder["type"] = "optimize" + @recorder options recorder["type"] = "optimize" return MutationResult{N,P}(; member=cur_member, num_evals=new_num_evals, return_immediately=true ) @@ -638,7 +638,7 @@ function mutate!( parent_ref, kws..., ) where {N<:AbstractExpression,P<:PopMember} - @recorder begin + @recorder options begin recorder["type"] = "identity" recorder["result"] = "accept" recorder["reason"] = "identity" @@ -686,7 +686,7 @@ function crossover_generation( break end if num_tries > max_tries - @recorder begin + @recorder options begin recorder["result"] = "reject" recorder["reason"] = "failed_constraint_check" end @@ -723,7 +723,7 @@ function crossover_generation( deterministic=options.deterministic, )::P - @recorder begin + @recorder options begin recorder["result"] = "accept" recorder["reason"] = "pass" end diff --git a/src/Recorder.jl b/src/Recorder.jl index 171a1f46b..b12927238 100644 --- a/src/Recorder.jl +++ b/src/Recorder.jl @@ -2,10 +2,10 @@ module RecorderModule using ..CoreModule: RecordType -"Assumes that `options` holds the user options::AbstractOptions" -macro recorder(ex) - quote - if $(esc(:options)).use_recorder +"Conditionally execute code based on options.use_recorder" +macro recorder(options, ex) + return quote + if $(esc(options)).use_recorder $(esc(ex)) end end diff --git a/src/RegularizedEvolution.jl b/src/RegularizedEvolution.jl index ad1223d5c..473e7557c 100644 --- a/src/RegularizedEvolution.jl +++ b/src/RegularizedEvolution.jl @@ -44,7 +44,7 @@ function reg_evol_cycle( oldest = argmin_fast([pop.members[member].birth for member in 1:(pop.n)]) - @recorder begin + @recorder options begin if !haskey(record, "mutations") record["mutations"] = RecordType() end @@ -102,7 +102,7 @@ function reg_evol_cycle( i == oldest1 ? typemax(BT) : pop.members[i].birth for i in 1:(pop.n) ]) - @recorder begin + @recorder options begin if !haskey(record, "mutations") record["mutations"] = RecordType() end diff --git a/src/SingleIteration.jl b/src/SingleIteration.jl index 4f666ec93..83d6f5302 100644 --- a/src/SingleIteration.jl +++ b/src/SingleIteration.jl @@ -101,7 +101,7 @@ function optimize_and_simplify_population( pop.members[j].parent = old_ref pop.members[j].ref = new_ref - @recorder begin + @recorder options begin # Same structure as in RegularizedEvolution.jl, # except we assume that the record already exists. @assert haskey(record, "mutations") diff --git a/src/SymbolicRegression.jl b/src/SymbolicRegression.jl index 2e11d28d5..d171b112e 100644 --- a/src/SymbolicRegression.jl +++ b/src/SymbolicRegression.jl @@ -632,7 +632,7 @@ end stdin_reader = watch_stream(options.input_stream) record = RecordType() - @recorder record["options"] = "$(options)" + @recorder options record["options"] = "$(options)" nout = length(datasets) example_dataset = first(datasets) @@ -660,7 +660,6 @@ end options, worker_imports=ropt.worker_imports, project_path=splitdir(Pkg.project().path)[1], - file=@__FILE__, ropt.exeflags, ropt.verbosity, example_dataset, @@ -839,7 +838,7 @@ function _warmup_search!( dataset = datasets[j] running_search_statistics = state.all_running_search_statistics[j] cur_maxsize = state.cur_maxsizes[j] - @recorder state.record[]["out$(j)_pop$(i)"] = RecordType() + @recorder options state.record[]["out$(j)_pop$(i)"] = RecordType() worker_idx = assign_next_worker!( state.worker_assignment; out=j, pop=i, parallelism=ropt.parallelism, state.procs ) @@ -954,7 +953,7 @@ function _main_search_loop!( end::DefaultWorkerOutputType{Population{T,L,N},HallOfFame{T,L,N}} state.last_pops[j][i] = copy(cur_pop) state.best_sub_pops[j][i] = best_sub_pop(cur_pop; topn=options.topn) - @recorder state.record[] = recursive_merge(state.record[], cur_record) + @recorder options state.record[] = recursive_merge(state.record[], cur_record) state.num_evals[j][i] += cur_num_evals dataset = datasets[j] cur_maxsize = state.cur_maxsizes[j] @@ -1136,7 +1135,7 @@ function _tear_down!( wait(state.worker_output[j][i]) end end - @recorder json3_write(state.record[], options.recorder_file) + @recorder options json3_write(state.record[], options.recorder_file) return nothing end function _format_output( @@ -1170,7 +1169,7 @@ end running_search_statistics, ) where {T,L,N} record = RecordType() - @recorder record["out$(out)_pop$(pop)"] = RecordType( + @recorder options record["out$(out)_pop$(pop)"] = RecordType( "iteration$(iteration)" => record_population(in_pop, options) ) num_evals = 0.0 From f4a9f407cf46c6a1cac7d23ffab1772c1c4efd24 Mon Sep 17 00:00:00 2001 From: MilesCranmer Date: Sun, 7 Sep 2025 13:52:55 +0100 Subject: [PATCH 4/6] refactor: no need for relative import code --- src/Configure.jl | 22 ++++------------------ 1 file changed, 4 insertions(+), 18 deletions(-) diff --git a/src/Configure.jl b/src/Configure.jl index e1c04c7e5..27ccd70fa 100644 --- a/src/Configure.jl +++ b/src/Configure.jl @@ -253,23 +253,10 @@ function activate_env_on_workers( end function import_module_on_workers( - procs, - filename::String, - @nospecialize(worker_imports::Union{Vector{Symbol},Nothing}), - verbosity, + procs, @nospecialize(worker_imports::Union{Vector{Symbol},Nothing}), verbosity ) - loaded_modules_head_worker = [k.name for (k, _) in Base.loaded_modules] - - included_as_local = "SymbolicRegression" ∉ loaded_modules_head_worker - expr = if included_as_local - quote - include($filename) - using .SymbolicRegression - end - else - quote - using SymbolicRegression - end + expr = quote + using SymbolicRegression end # Need to import any extension code, if loaded on head node @@ -372,7 +359,6 @@ function configure_workers(; options::AbstractOptions, @nospecialize(worker_imports::Union{Vector{Symbol},Nothing}), project_path, - file, exeflags::Cmd, verbosity, example_dataset::Dataset, @@ -387,7 +373,7 @@ function configure_workers(; end if we_created_procs - import_module_on_workers(procs, file, worker_imports, verbosity) + import_module_on_workers(procs, worker_imports, verbosity) end move_functions_to_workers(procs, options, example_dataset, verbosity) From b31b5b1cd5985dcd0376e8ed15461b59474b44b4 Mon Sep 17 00:00:00 2001 From: MilesCranmer Date: Sun, 7 Sep 2025 16:20:28 +0100 Subject: [PATCH 5/6] test: automated ExplicitImports checks --- test/Project.toml | 1 + test/runtests.jl | 4 ++++ test/test_explicit_imports.jl | 7 +++++++ 3 files changed, 12 insertions(+) create mode 100644 test/test_explicit_imports.jl diff --git a/test/Project.toml b/test/Project.toml index 7b9a01e1d..b42dd02ed 100644 --- a/test/Project.toml +++ b/test/Project.toml @@ -7,6 +7,7 @@ DispatchDoctor = "8d63f2c5-f18a-4cf2-ba9d-b3f60fc568c8" Distributed = "8ba89e20-285c-5b6f-9357-94700520ee1b" DynamicExpressions = "a40a106e-89c9-4ca8-8020-a735e8728b6b" DynamicQuantities = "06fc5a27-2a28-4c7c-a15d-362465fb6821" +ExplicitImports = "7d51a73a-1435-4ff3-83d9-f097790105c7" ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210" JSON3 = "0f8b85d8-7281-11e9-16c2-39a750bddbf1" LineSearches = "d3d80556-e9d4-5f37-9878-2ab0fcc64255" diff --git a/test/runtests.jl b/test/runtests.jl index 7aef02fea..fa01b341a 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -181,6 +181,10 @@ include("test_loss_scale.jl") include("test_aqua.jl") end +@testitem "ExplicitImports tests" tags = [:part3] begin + include("test_explicit_imports.jl") +end + @testitem "JET tests" tags = [:jet] begin test_jet_file = joinpath((@__DIR__), "test_jet.jl") run(`$(Base.julia_cmd()) --startup-file=no $test_jet_file`) diff --git a/test/test_explicit_imports.jl b/test/test_explicit_imports.jl new file mode 100644 index 000000000..dae626003 --- /dev/null +++ b/test/test_explicit_imports.jl @@ -0,0 +1,7 @@ +using SymbolicRegression +using ExplicitImports +using Test + +# Test that we have no implicit imports or stale imports +@test ExplicitImports.check_no_implicit_imports(SymbolicRegression) === nothing +@test ExplicitImports.check_no_stale_explicit_imports(SymbolicRegression) === nothing From e8c502e14a3c3c9bc002ee1153d08a1de4db5a5d Mon Sep 17 00:00:00 2001 From: MilesCranmer Date: Sun, 7 Sep 2025 18:04:25 +0100 Subject: [PATCH 6/6] fix: missing variable --- ext/SymbolicRegressionSymbolicUtilsExt.jl | 2 +- src/Configure.jl | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/ext/SymbolicRegressionSymbolicUtilsExt.jl b/ext/SymbolicRegressionSymbolicUtilsExt.jl index c723228af..87821fb43 100644 --- a/ext/SymbolicRegressionSymbolicUtilsExt.jl +++ b/ext/SymbolicRegressionSymbolicUtilsExt.jl @@ -1,7 +1,7 @@ module SymbolicRegressionSymbolicUtilsExt using SymbolicUtils: Symbolic -using SymbolicRegression: AbstractExpressionNode, AbstractExpression, Node, Options +using SymbolicRegression: AbstractExpressionNode, AbstractExpression, Options using SymbolicRegression.MLJInterfaceModule: AbstractSymbolicRegressor, get_options using DynamicExpressions: get_tree, get_operators diff --git a/src/Configure.jl b/src/Configure.jl index 27ccd70fa..d1ec87fcd 100644 --- a/src/Configure.jl +++ b/src/Configure.jl @@ -255,6 +255,8 @@ end function import_module_on_workers( procs, @nospecialize(worker_imports::Union{Vector{Symbol},Nothing}), verbosity ) + loaded_modules_head_worker = [k.name for (k, _) in Base.loaded_modules] + expr = quote using SymbolicRegression end