diff --git a/src/MATLABDiffEq.jl b/src/MATLABDiffEq.jl index a70a724..12c0c96 100644 --- a/src/MATLABDiffEq.jl +++ b/src/MATLABDiffEq.jl @@ -6,12 +6,15 @@ using MATLAB, ModelingToolkit using PrecompileTools # MATLAB only supports Float64 arrays. Check if a type is MATLAB-compatible. +# Note: We specifically accept standard Julia integer types that MATLAB can convert, +# but NOT BigInt since MATLAB doesn't support arbitrary precision integers. _is_matlab_compatible_eltype(::Type{Float64}) = true -_is_matlab_compatible_eltype(::Type{<:Integer}) = true # MATLAB can convert integers +_is_matlab_compatible_eltype(::Type{<:Union{Int8, Int16, Int32, Int64, Int128}}) = true +_is_matlab_compatible_eltype(::Type{<:Union{UInt8, UInt16, UInt32, UInt64, UInt128}}) = true _is_matlab_compatible_eltype(::Type{<:Complex{Float64}}) = true _is_matlab_compatible_eltype(::Type) = false -function _check_matlab_compatible(u0, tspan) +function _check_matlab_compatible(u0, tspan)::Nothing T = eltype(u0) if !_is_matlab_compatible_eltype(T) throw( @@ -207,8 +210,10 @@ end # Precompile type compatibility checks _ = _is_matlab_compatible_eltype(Float64) _ = _is_matlab_compatible_eltype(Int64) + _ = _is_matlab_compatible_eltype(UInt64) _ = _is_matlab_compatible_eltype(Complex{Float64}) _ = _is_matlab_compatible_eltype(BigFloat) + _ = _is_matlab_compatible_eltype(BigInt) _ = _check_matlab_compatible([1.0, 2.0], (0.0, 1.0)) _ = _check_matlab_compatible(1.0, (0.0, 1.0)) end diff --git a/test/jet_tests.jl b/test/jet_tests.jl index 1770416..11d9645 100644 --- a/test/jet_tests.jl +++ b/test/jet_tests.jl @@ -106,4 +106,54 @@ end @test isconcretetype(ode15s_test) @test isconcretetype(ode15i_test) end + + @testset "Type compatibility functions" begin + # Test the type compatibility check functions + # These mirror the actual module implementations + # Note: BigInt is NOT accepted because MATLAB doesn't support arbitrary precision + + _is_matlab_compatible_eltype_test(::Type{Float64})::Bool = true + _is_matlab_compatible_eltype_test(::Type{<:Union{Int8, Int16, Int32, Int64, Int128}})::Bool = true + _is_matlab_compatible_eltype_test(::Type{<:Union{UInt8, UInt16, UInt32, UInt64, UInt128}})::Bool = true + _is_matlab_compatible_eltype_test(::Type{<:Complex{Float64}})::Bool = true + _is_matlab_compatible_eltype_test(::Type)::Bool = false + + # Test return types are Bool + @test _is_matlab_compatible_eltype_test(Float64) === true + @test _is_matlab_compatible_eltype_test(Int64) === true + @test _is_matlab_compatible_eltype_test(UInt64) === true + @test _is_matlab_compatible_eltype_test(Complex{Float64}) === true + @test _is_matlab_compatible_eltype_test(BigFloat) === false + @test _is_matlab_compatible_eltype_test(BigInt) === false + @test _is_matlab_compatible_eltype_test(Float32) === false + + # JET @test_opt analysis for type stability + if HAS_JET + @testset "JET @test_opt type stability" begin + # Test type stability of _is_matlab_compatible_eltype + @test_opt _is_matlab_compatible_eltype_test(Float64) + @test_opt _is_matlab_compatible_eltype_test(Int64) + @test_opt _is_matlab_compatible_eltype_test(BigFloat) + end + end + end + + @testset "Return type inference" begin + # Test that return types can be inferred correctly + function buildDEStats_test2(solverstats::Dict{String, <:Any})::DiffEqBase.Stats + destats = DiffEqBase.Stats(0) + destats.nf = Int(get(solverstats, "nfevals", 0)) + destats.nreject = Int(get(solverstats, "nfailed", 0)) + destats.naccept = Int(get(solverstats, "nsteps", 0)) + destats.nsolve = Int(get(solverstats, "nsolves", 0)) + destats.njacs = Int(get(solverstats, "npds", 0)) + destats.nw = Int(get(solverstats, "ndecomps", 0)) + destats + end + + # Verify return type is inferred as concrete + return_types = Base.return_types(buildDEStats_test2, (Dict{String, Any},)) + @test length(return_types) == 1 + @test return_types[1] == DiffEqBase.Stats + end end diff --git a/test/runtests.jl b/test/runtests.jl index 51c0a3b..53cd636 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -3,6 +3,9 @@ using DiffEqBase, MATLABDiffEq, ParameterizedFunctions, Test # Interface tests - these test type validation without needing MATLAB runtime include("interface_tests.jl") +# JET static analysis tests - these also run without MATLAB +include("jet_tests.jl") + # The following tests require MATLAB runtime to be available # They test the actual ODE solving functionality