MilesCranmer / PySR

High-Performance Symbolic Regression in Python and Julia
https://astroautomata.com/PySR
Apache License 2.0
2.32k stars 211 forks source link

[BUG]: Using dimensional constraints result in "UndefVarError: `k` not defined" error #544

Closed drcassar closed 7 months ago

drcassar commented 7 months ago

What happened?

I tried the dimensional constraint tutorial (https://astroautomata.com/PySR/examples/#10-dimensional-constraints) in a new python environment with the newest version of PySR (v0.17.0) and it throws the error juliacall.JuliaError: UndefVarError: "k" not defined.

The code is the same as the tutorial, but I created a gist of it if it helps: https://gist.github.com/drcassar/ad351bc48931f753c321eec214135513. Commenting lines 46 and 47 of the code makes it run without issues.

Version

0.17.0

Operating System

Linux

Package Manager

pip

Interface

Script (i.e., python my_script.py)

Relevant log output

Traceback (most recent call last):
  File "/home/.../Pysr/dimension_constraint_toy.py", line 43, in <module>
    model.fit(
  File "/home/daniel/data/Venv/test/lib/python3.11/site-packages/pysr/sr.py", line 1905, in fit
    self._run(X, y, mutated_params, weights=weights, seed=seed)
  File "/home/daniel/data/Venv/test/lib/python3.11/site-packages/pysr/sr.py", line 1728, in _run
    out = SymbolicRegression.equation_search(
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/daniel/.julia/packages/PythonCall/wXfah/src/jlwrap/any.jl", line 208, in __call__
    return self._jl_callmethod($(pyjl_methodnum(pyjlany_call)), args, kwargs)
       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
juliacall.JuliaError: UndefVarError: `k` not defined
Stacktrace:
  [1] top-level scope
    @ :0
  [2] eval
    @ ./boot.jl:385 [inlined]
  [3] eval
    @ ~/.julia/packages/DynamicQuantities/5QflN/src/uparse.jl:1 [inlined]
  [4] uparse(s::String)
    @ DynamicQuantities.UnitsParse ~/.julia/packages/DynamicQuantities/5QflN/src/uparse.jl:37
  [5] get_units(::Type{T}, ::Type{D}, x::AbstractVector, f::Function) where {T, D}
    @ SymbolicRegression.InterfaceDynamicQuantitiesModule ~/.julia/packages/SymbolicRegression/NCIOt/src/InterfaceDynamicQuantities.jl:33 [inlined]
  [6] get_si_units
    @ ~/.julia/packages/SymbolicRegression/NCIOt/src/InterfaceDynamicQuantities.jl:55 [inlined]
  [7] Dataset(X::Matrix{Float32}, y::Vector{Float32}; weights::Nothing, variable_names::Vector{String}, display_variable_names::Vector{String}, y_variable_name::String, extra::@NamedTuple{}, loss_type::Type{Nothing}, X_units::Vector{String}, y_units::String, varMap::Nothing)
    @ SymbolicRegression.CoreModule.DatasetModule ~/.julia/packages/SymbolicRegression/NCIOt/src/Dataset.jl:153
  [8] #32
    @ ~/.julia/packages/SymbolicRegression/NCIOt/src/SearchUtils.jl:378 [inlined]
  [9] (::SymbolicRegression.SearchUtilsModule.var"#32#33"{Matrix{Float32}, Matrix{Float32}, Nothing, Vector{String}, Vector{String}, Nothing, Vector{String}, Vector{String}, DataType, Int64})(j::Int64)
    @ SymbolicRegression.SearchUtilsModule ./none:0
 [10] iterate
    @ ./generator.jl:47 [inlined]
 [11] collect(itr::Base.Generator{UnitRange{Int64}, SymbolicRegression.SearchUtilsModule.var"#32#33"{Matrix{Float32}, Matrix{Float32}, Nothing, Vector{String}, Vector{String}, Nothing, Vector{String}, Vector{String}, DataType, Int64}})
    @ Base ./array.jl:834
 [12] construct_datasets
    @ ~/.julia/packages/SymbolicRegression/NCIOt/src/SearchUtils.jl:358 [inlined]
 [13] equation_search(X::Matrix{Float32}, y::Matrix{Float32}; niterations::Int64, weights::Nothing, options::Options{Int64, DynamicExpressions.OperatorEnumModule.OperatorEnum, false, Optim.Options{Float64, Nothing}, StatsBase.Weights{Float64, Float64, Vector{Float64}}}, variable_names::Vector{String}, display_variable_names::Vector{String}, y_variable_names::Nothing, parallelism::String, numprocs::Nothing, procs::Nothing, addprocs_function::Nothing, heap_size_hint_in_bytes::Nothing, runtests::Bool, saved_state::Nothing, return_state::Bool, loss_type::Type{Nothing}, verbosity::Int64, progress::Bool, X_units::Vector{String}, y_units::Vector{String}, v_dim_out::Val{1}, multithreaded::Nothing, varMap::Nothing)
    @ SymbolicRegression ~/.julia/packages/SymbolicRegression/NCIOt/src/SymbolicRegression.jl:375
 [14] equation_search
    @ SymbolicRegression ~/.julia/packages/SymbolicRegression/NCIOt/src/SymbolicRegression.jl:335 [inlined]
 [15] #equation_search#26
    @ SymbolicRegression ~/.julia/packages/SymbolicRegression/NCIOt/src/SymbolicRegression.jl:417 [inlined]
 [16] pyjlany_call(self::typeof(equation_search), args_::Py, kwargs_::Py)
    @ PythonCall ~/.julia/packages/PythonCall/wXfah/src/jlwrap/any.jl:34
 [17] _pyjl_callmethod(f::Any, self_::Ptr{PythonCall.C.PyObject}, args_::Ptr{PythonCall.C.PyObject}, nargs::Int64)
    @ PythonCall ~/.julia/packages/PythonCall/wXfah/src/jlwrap/base.jl:69
 [18] _pyjl_callmethod(o::Ptr{PythonCall.C.PyObject}, args::Ptr{PythonCall.C.PyObject})

Extra Info

No response

MilesCranmer commented 7 months ago

Very strange indeed. Are you able to run the unit tests without issue? i.e.,

python -m pysr test main

which internally calls this test suite: https://github.com/MilesCranmer/PySR/blob/b3a5026a02f28f97726476ab0f5b89eb29f809cb/pysr/test/test.py#L991 that is supposed to do fairly intensive tests of the units

MilesCranmer commented 7 months ago

Wait, I see the same bug... Okay this is definitely real.

MilesCranmer commented 7 months ago

Seems like self.y_units_ is being interpreted as a vector rather than a string somewhere...

MilesCranmer commented 7 months ago

Fixed by #545 btw. Fix is on PySR 0.17.1 which has been released.