diff --git a/Manifest.toml b/Manifest.toml index 8f60785..d81184c 100644 --- a/Manifest.toml +++ b/Manifest.toml @@ -2,7 +2,7 @@ julia_version = "1.13.0-DEV" manifest_format = "2.0" -project_hash = "d2c28a8e33664424dc750db4dae46c782768f682" +project_hash = "746cb775f4faad2538ec3bf8181fbd2c66618df8" [[deps.ADTypes]] git-tree-sha1 = "e2478490447631aedba0823d4d7a80b2cc8cdb32" @@ -171,9 +171,9 @@ uuid = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f" version = "1.11.0" [[deps.Bijections]] -git-tree-sha1 = "6aaafea90a56dc1fc8cbc15e3cf26d6bc81eb0a3" +git-tree-sha1 = "a2d308fcd4c2fb90e943cf9cd2fbfa9c32b69733" uuid = "e2ed5e7c-b2de-5872-ae92-c73ca462fb04" -version = "0.1.10" +version = "0.2.2" [[deps.BitTwiddlingConvenienceFunctions]] deps = ["Static"] @@ -229,9 +229,9 @@ version = "1.1.0" [[deps.ChainRules]] deps = ["Adapt", "ChainRulesCore", "Compat", "Distributed", "GPUArraysCore", "IrrationalConstants", "LinearAlgebra", "Random", "RealDot", "SparseArrays", "SparseInverseSubset", "Statistics", "StructArrays", "SuiteSparse"] -git-tree-sha1 = "a975ae558af61a2a48720a6271661bf2621e0f4e" +git-tree-sha1 = "224f9dc510986549c8139def08e06f78c562514d" uuid = "082447d4-558c-5d27-93f4-14fc19e9eca2" -version = "1.72.3" +version = "1.72.5" [[deps.ChainRulesCore]] deps = ["Compat", "LinearAlgebra"] @@ -293,11 +293,11 @@ weakdeps = ["Dates", "LinearAlgebra"] CompatLinearAlgebraExt = "LinearAlgebra" [[deps.Compiler]] -git-tree-sha1 = "34d243f805bb74759f9b9856413834a9871b0952" +git-tree-sha1 = "382d79bfe72a406294faca39ef0c3cef6e6ce1f1" repo-rev = "master" repo-url = "https://github.com/JuliaLang/BaseCompiler.jl.git" uuid = "807dbc54-b67e-4c79-8afb-eafe4df6f2e1" -version = "0.1.0" +version = "0.1.1" [[deps.CompilerSupportLibraries_jll]] deps = ["Artifacts", "Libdl"] @@ -324,9 +324,9 @@ uuid = "2569d6c7-a4a2-43d3-a901-331e8e4be471" version = "0.2.3" [[deps.ConstructionBase]] -git-tree-sha1 = "76219f1ed5771adbb096743bff43fb5fdd4c1157" +git-tree-sha1 = "b4b092499347b18a015186eae3042f72267106cb" uuid = "187b0558-2788-49d3-abe0-74a17ed4e7c9" -version = "1.5.8" +version = "1.6.0" weakdeps = ["IntervalSets", "LinearAlgebra", "StaticArrays"] [deps.ConstructionBase.extensions] @@ -362,7 +362,7 @@ version = "4.1.1" [[deps.Cthulhu]] deps = ["CodeTracking", "FoldingTrees", "InteractiveUtils", "JuliaSyntax", "PrecompileTools", "Preferences", "REPL", "TypedSyntax", "UUIDs", "Unicode", "WidthLimitedIO"] -git-tree-sha1 = "c1e4aefb264d17e30613fad7d32779cddd019af8" +git-tree-sha1 = "aead4b65e9eac8bf96fd704ff88a965ba40c54a3" repo-rev = "master" repo-url = "https://github.com/JuliaDebug/Cthulhu.jl.git" uuid = "f68482b8-f384-11e8-15f7-abe071a5a75f" @@ -373,7 +373,7 @@ weakdeps = ["Compiler"] CthulhuCompilerExt = "Compiler" [[deps.DAECompiler]] -deps = ["Accessors", "AutoHashEquals", "CentralizedCaches", "ChainRules", "ChainRulesCore", "Compiler", "Cthulhu", "DiffEqBase", "DiffEqCallbacks", "DifferentiationInterface", "Diffractor", "Distributions", "ExprTools", "ForwardDiff", "Graphs", "InteractiveUtils", "LinearAlgebra", "NonlinearSolve", "OrderedCollections", "OrdinaryDiffEq", "PrecompileTools", "Preferences", "REPL", "Random", "SciMLBase", "SimpleNonlinearSolve", "SparseArrays", "StateSelection", "StaticArraysCore", "Sundials", "SymbolicIndexingInterface", "TimerOutputs", "Tracy"] +deps = ["Accessors", "AutoHashEquals", "CentralizedCaches", "ChainRules", "ChainRulesCore", "Compiler", "ConstructionBase", "Cthulhu", "DiffEqBase", "DiffEqCallbacks", "DifferentiationInterface", "Diffractor", "Distributions", "ExprTools", "ForwardDiff", "Graphs", "InteractiveUtils", "LinearAlgebra", "NonlinearSolve", "OrderedCollections", "OrdinaryDiffEq", "PrecompileTools", "Preferences", "REPL", "Random", "SciMLBase", "SimpleNonlinearSolve", "SparseArrays", "StateSelection", "StaticArraysCore", "Sundials", "SymbolicIndexingInterface", "TimerOutputs", "Tracy"] path = "." uuid = "32805668-c3d0-42c2-aafd-0d0a9857a104" version = "1.21.0" @@ -579,9 +579,9 @@ version = "0.25.120" Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" [[deps.DocStringExtensions]] -git-tree-sha1 = "e7b7e6f178525d17c720ab9c081e4ef04429f860" +git-tree-sha1 = "7442a5dfe1ebb773c29cc2962a8980f47221d76c" uuid = "ffbed154-4ef7-542d-bbb7-c09d3a79fcae" -version = "0.9.4" +version = "0.9.5" [[deps.DomainSets]] deps = ["CompositeTypes", "IntervalSets", "LinearAlgebra", "Random", "StaticArrays"] @@ -630,9 +630,9 @@ uuid = "4e289a0a-7415-4d19-859d-a7e5c4648b56" version = "1.0.5" [[deps.EnzymeCore]] -git-tree-sha1 = "1eb59f40a772d0fbd4cb75e00b3fa7f5f79c975a" +git-tree-sha1 = "8272a687bca7b5c601c0c24fc0c71bff10aafdfd" uuid = "f151be2c-9106-41f4-ab19-57ee4f262869" -version = "0.8.9" +version = "0.8.12" weakdeps = ["Adapt"] [deps.EnzymeCore.extensions] @@ -814,10 +814,10 @@ uuid = "c27321d9-0574-5035-807b-f59d2c89b15c" version = "1.3.1" [[deps.Graphs]] -deps = ["ArnoldiMethod", "Compat", "DataStructures", "Distributed", "Inflate", "LinearAlgebra", "Random", "SharedArrays", "SimpleTraits", "SparseArrays", "Statistics"] -git-tree-sha1 = "3169fd3440a02f35e549728b0890904cfd4ae58a" +deps = ["ArnoldiMethod", "DataStructures", "Distributed", "Inflate", "LinearAlgebra", "Random", "SharedArrays", "SimpleTraits", "SparseArrays", "Statistics"] +git-tree-sha1 = "c5abfa0ae0aaee162a3fbb053c13ecda39be545b" uuid = "86223c79-3864-5bf0-83f7-82e725a168b6" -version = "1.12.1" +version = "1.13.0" [[deps.HashArrayMappedTries]] git-tree-sha1 = "2eaa69a7cab70a52b9687c8bf950a5a93ec895ae" @@ -832,9 +832,9 @@ version = "0.3.28" [[deps.IRTools]] deps = ["InteractiveUtils", "MacroTools"] -git-tree-sha1 = "950c3717af761bc3ff906c2e8e52bd83390b6ec2" +git-tree-sha1 = "57e9ce6cf68d0abf5cb6b3b4abf9bedf05c939c0" uuid = "7869d1d1-7146-5819-86e3-90919afe41df" -version = "0.4.14" +version = "0.4.15" [[deps.IfElse]] git-tree-sha1 = "debdd00ffef04665ccbb3e150747a77560e8fad1" @@ -922,17 +922,17 @@ uuid = "ac6e5ff7-fb65-4e79-a425-ec3bc9c03011" version = "1.12.0" [[deps.JumpProcesses]] -deps = ["ArrayInterface", "DataStructures", "DiffEqBase", "DocStringExtensions", "FunctionWrappers", "Graphs", "LinearAlgebra", "Markdown", "PoissonRandom", "Random", "RandomNumbers", "RecursiveArrayTools", "Reexport", "SciMLBase", "Setfield", "StaticArrays", "SymbolicIndexingInterface", "UnPack"] -git-tree-sha1 = "f2bdec5b4580414aee3178c8caa6e46c344c0bbc" +deps = ["ArrayInterface", "DataStructures", "DiffEqBase", "DiffEqCallbacks", "DocStringExtensions", "FunctionWrappers", "Graphs", "LinearAlgebra", "Markdown", "PoissonRandom", "Random", "RandomNumbers", "RecursiveArrayTools", "Reexport", "SciMLBase", "Setfield", "StaticArrays", "SymbolicIndexingInterface", "UnPack"] +git-tree-sha1 = "fb7fd516de38db80f50fe15e57d44da2836365e7" uuid = "ccbc3e58-028d-4f4c-8cd5-9ae44345cda5" -version = "9.14.3" +version = "9.16.0" weakdeps = ["FastBroadcast"] [[deps.KernelAbstractions]] deps = ["Adapt", "Atomix", "InteractiveUtils", "MacroTools", "PrecompileTools", "Requires", "StaticArrays", "UUIDs"] -git-tree-sha1 = "80d268b2f4e396edc5ea004d1e0f569231c71e9e" +git-tree-sha1 = "602c0e9efadafb8abfe8281c3fbf9cf6f406fc03" uuid = "63c18a36-062a-441e-b654-da1e3ab1ce7c" -version = "0.9.34" +version = "0.9.35" weakdeps = ["EnzymeCore", "LinearAlgebra", "SparseArrays"] [deps.KernelAbstractions.extensions] @@ -948,9 +948,9 @@ version = "0.10.1" [[deps.LLVM]] deps = ["CEnum", "LLVMExtra_jll", "Libdl", "Preferences", "Printf", "Unicode"] -git-tree-sha1 = "5e8b243b2e4c86648dac82cf767ae1456000b92d" +git-tree-sha1 = "cfedf80c59000507cc8115a0281931253f4a33cd" uuid = "929cbde3-209d-540e-8aea-75f648917ca0" -version = "9.4.0" +version = "9.4.1" [deps.LLVM.extensions] BFloat16sExt = "BFloat16s" @@ -960,9 +960,9 @@ version = "9.4.0" [[deps.LLVMExtra_jll]] deps = ["Artifacts", "JLLWrappers", "LazyArtifacts", "Libdl", "TOML"] -git-tree-sha1 = "f8022e2c8b5eef5f30e7fb2fe52c97cc5674db23" +git-tree-sha1 = "2ea068aac1e7f0337d381b0eae3110581e3f3216" uuid = "dad2f222-ce93-54a1-a47d-0025e8a3acab" -version = "0.0.36+0" +version = "0.0.37+2" [[deps.LaTeXStrings]] git-tree-sha1 = "dda21b8cbd6a6c40d9d02a73230f9d70fed6918c" @@ -1022,7 +1022,7 @@ uuid = "b27032c2-a3e7-50c8-80cd-2d36dbcbfd21" version = "0.6.4" [[deps.LibCURL_jll]] -deps = ["Artifacts", "LibSSH2_jll", "Libdl", "OpenSSL_jll", "Zlib_jll", "nghttp2_jll"] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "LibSSH2_jll", "Libdl", "OpenSSL_jll", "Zlib_jll", "nghttp2_jll"] uuid = "deac9b47-8bc7-5906-a0fe-35ac56dc84c0" version = "8.12.1+1" @@ -1032,12 +1032,12 @@ uuid = "76f85450-5226-5b5a-8eaa-529ad045b433" version = "1.11.0" [[deps.LibGit2_jll]] -deps = ["Artifacts", "LibSSH2_jll", "Libdl", "OpenSSL_jll"] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "LibSSH2_jll", "Libdl", "OpenSSL_jll"] uuid = "e37daf67-58a4-590a-8e99-b0245dd2ffc5" version = "1.9.0+0" [[deps.LibSSH2_jll]] -deps = ["Artifacts", "Libdl", "OpenSSL_jll", "Zlib_jll"] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "Libdl", "OpenSSL_jll", "Zlib_jll"] uuid = "29816b5a-b9ab-546f-933c-edad1886dfa8" version = "1.11.3+1" @@ -1063,9 +1063,9 @@ weakdeps = ["LineSearches"] [[deps.LineSearches]] deps = ["LinearAlgebra", "NLSolversBase", "NaNMath", "Parameters", "Printf"] -git-tree-sha1 = "e4c3be53733db1051cc15ecf573b1042b3a712a1" +git-tree-sha1 = "4adee99b7262ad2a1a4bbbc59d993d24e55ea96f" uuid = "d3d80556-e9d4-5f37-9878-2ab0fcc64255" -version = "7.3.0" +version = "7.4.0" [[deps.LinearAlgebra]] deps = ["Libdl", "OpenBLAS_jll", "libblastrampoline_jll"] @@ -1086,9 +1086,9 @@ weakdeps = ["ChainRulesCore", "SparseArrays", "Statistics"] [[deps.LinearSolve]] deps = ["ArrayInterface", "ChainRulesCore", "ConcreteStructs", "DocStringExtensions", "EnumX", "GPUArraysCore", "InteractiveUtils", "Krylov", "LazyArrays", "Libdl", "LinearAlgebra", "MKL_jll", "Markdown", "PrecompileTools", "Preferences", "RecursiveArrayTools", "Reexport", "SciMLBase", "SciMLOperators", "Setfield", "StaticArraysCore", "UnPack"] -git-tree-sha1 = "c618a6a774d5712c6bf02dbcceb51b6dc6b9bb89" +git-tree-sha1 = "c0d1a91a50af6778863d320761f807f641f74935" uuid = "7ed4a6bd-45f5-4d41-b270-4a48e9bafcae" -version = "3.16.0" +version = "3.17.0" [deps.LinearSolve.extensions] LinearSolveBandedMatricesExt = "BandedMatrices" @@ -1255,9 +1255,9 @@ version = "1.6.4" [[deps.NLSolversBase]] deps = ["ADTypes", "DifferentiationInterface", "Distributed", "FiniteDiff", "ForwardDiff"] -git-tree-sha1 = "b14c7be6046e7d48e9063a0053f95ee0fc954176" +git-tree-sha1 = "25a6638571a902ecfb1ae2a18fc1575f86b1d4df" uuid = "d41bc354-129a-5804-8e4c-c37616107c6c" -version = "7.9.1" +version = "7.10.0" [[deps.NNlib]] deps = ["Adapt", "Atomix", "ChainRulesCore", "GPUArraysCore", "KernelAbstractions", "LinearAlgebra", "Random", "ScopedValues", "Statistics"] @@ -1390,7 +1390,7 @@ uuid = "4536629a-c528-5b80-bd46-f80d51c5b363" version = "0.3.29+0" [[deps.OpenLibm_jll]] -deps = ["Artifacts", "Libdl"] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "Libdl"] uuid = "05823500-19ac-5b8b-9628-191a04bc5112" version = "0.8.5+0" @@ -1407,9 +1407,9 @@ version = "0.5.6+0" [[deps.Optim]] deps = ["Compat", "EnumX", "FillArrays", "ForwardDiff", "LineSearches", "LinearAlgebra", "NLSolversBase", "NaNMath", "PositiveFactorizations", "Printf", "SparseArrays", "StatsBase"] -git-tree-sha1 = "31b3b1b8e83ef9f1d50d74f1dd5f19a37a304a1f" +git-tree-sha1 = "61942645c38dd2b5b78e2082c9b51ab315315d10" uuid = "429524aa-4258-5aef-a3af-852621145aeb" -version = "1.12.0" +version = "1.13.2" [deps.Optim.extensions] OptimMOIExt = "MathOptInterface" @@ -1452,15 +1452,15 @@ version = "1.2.0" [[deps.OrdinaryDiffEqBDF]] deps = ["ADTypes", "ArrayInterface", "DiffEqBase", "FastBroadcast", "LinearAlgebra", "MacroTools", "MuladdMacro", "OrdinaryDiffEqCore", "OrdinaryDiffEqDifferentiation", "OrdinaryDiffEqNonlinearSolve", "OrdinaryDiffEqSDIRK", "PrecompileTools", "Preferences", "RecursiveArrayTools", "Reexport", "StaticArrays", "TruncatedStacktraces"] -git-tree-sha1 = "42755bd13fe56e9d9ce1bc005f8b206a6b56b731" +git-tree-sha1 = "9124a686af119063bb4d3a8f87044a8f312fcad9" uuid = "6ad6398a-0878-4a85-9266-38940aa047c8" -version = "1.5.1" +version = "1.6.0" [[deps.OrdinaryDiffEqCore]] deps = ["ADTypes", "Accessors", "Adapt", "ArrayInterface", "DataStructures", "DiffEqBase", "DocStringExtensions", "EnumX", "FastBroadcast", "FastClosures", "FastPower", "FillArrays", "FunctionWrappersWrappers", "InteractiveUtils", "LinearAlgebra", "Logging", "MacroTools", "MuladdMacro", "Polyester", "PrecompileTools", "Preferences", "RecursiveArrayTools", "Reexport", "SciMLBase", "SciMLOperators", "SciMLStructures", "SimpleUnPack", "Static", "StaticArrayInterface", "StaticArraysCore", "SymbolicIndexingInterface", "TruncatedStacktraces"] -git-tree-sha1 = "d29adfeb720dd7c251b216d91c4bd4fe67c087df" +git-tree-sha1 = "08dac9c6672a4548439048089bac293759a897fd" uuid = "bbf590c4-e513-4bbe-9b18-05decba2e5d8" -version = "1.26.0" +version = "1.26.1" weakdeps = ["EnzymeCore"] [deps.OrdinaryDiffEqCore.extensions] @@ -1474,9 +1474,9 @@ version = "1.4.0" [[deps.OrdinaryDiffEqDifferentiation]] deps = ["ADTypes", "ArrayInterface", "ConcreteStructs", "ConstructionBase", "DiffEqBase", "DifferentiationInterface", "FastBroadcast", "FiniteDiff", "ForwardDiff", "FunctionWrappersWrappers", "LinearAlgebra", "LinearSolve", "OrdinaryDiffEqCore", "SciMLBase", "SciMLOperators", "SparseArrays", "SparseMatrixColorings", "StaticArrayInterface", "StaticArrays"] -git-tree-sha1 = "c78060115fa4ea9d70ac47fa49496acbc630aefa" +git-tree-sha1 = "efecf0c4cc44e16251b0e718f08b0876b2a82b80" uuid = "4302a76b-040a-498a-8c04-15b101fed76b" -version = "1.9.1" +version = "1.10.0" [[deps.OrdinaryDiffEqExplicitRK]] deps = ["DiffEqBase", "FastBroadcast", "LinearAlgebra", "MuladdMacro", "OrdinaryDiffEqCore", "RecursiveArrayTools", "Reexport", "TruncatedStacktraces"] @@ -1582,9 +1582,9 @@ version = "1.1.0" [[deps.OrdinaryDiffEqRosenbrock]] deps = ["ADTypes", "DiffEqBase", "DifferentiationInterface", "FastBroadcast", "FiniteDiff", "ForwardDiff", "LinearAlgebra", "LinearSolve", "MacroTools", "MuladdMacro", "OrdinaryDiffEqCore", "OrdinaryDiffEqDifferentiation", "Polyester", "PrecompileTools", "Preferences", "RecursiveArrayTools", "Reexport", "Static"] -git-tree-sha1 = "063e5ff1447b3869856ed264b6dcbb21e6e8bdb0" +git-tree-sha1 = "1ce0096d920e95773220e818f29bf4b37ea2bb78" uuid = "43230ef6-c299-4910-a778-202eb28ce4ce" -version = "1.10.1" +version = "1.11.0" [[deps.OrdinaryDiffEqSDIRK]] deps = ["ADTypes", "DiffEqBase", "FastBroadcast", "LinearAlgebra", "MacroTools", "MuladdMacro", "OrdinaryDiffEqCore", "OrdinaryDiffEqDifferentiation", "OrdinaryDiffEqNonlinearSolve", "RecursiveArrayTools", "Reexport", "SciMLBase", "TruncatedStacktraces"] @@ -2196,9 +2196,9 @@ version = "3.29.0" [[deps.Symbolics]] deps = ["ADTypes", "ArrayInterface", "Bijections", "CommonWorldInvalidations", "ConstructionBase", "DataStructures", "DiffRules", "Distributions", "DocStringExtensions", "DomainSets", "DynamicPolynomials", "LaTeXStrings", "Latexify", "Libdl", "LinearAlgebra", "LogExpFunctions", "MacroTools", "Markdown", "NaNMath", "OffsetArrays", "PrecompileTools", "Primes", "RecipesBase", "Reexport", "RuntimeGeneratedFunctions", "SciMLBase", "Setfield", "SparseArrays", "SpecialFunctions", "StaticArraysCore", "SymbolicIndexingInterface", "SymbolicLimits", "SymbolicUtils", "TermInterface"] -git-tree-sha1 = "e14834f421edaa8a30493f7864dfc8582855bb3c" +git-tree-sha1 = "3d9551301d9ecdb8c193aac2ed0a3efc303494ca" uuid = "0c5d862f-8b57-4792-8d23-62f2024744c7" -version = "6.40.0" +version = "6.41.0" [deps.Symbolics.extensions] SymbolicsForwardDiffExt = "ForwardDiff" @@ -2229,9 +2229,9 @@ version = "1.0.1" [[deps.Tables]] deps = ["DataAPI", "DataValueInterfaces", "IteratorInterfaceExtensions", "OrderedCollections", "TableTraits"] -git-tree-sha1 = "598cd7c1f68d1e205689b1c2fe65a9f85846f297" +git-tree-sha1 = "f2c1efbc8f3a609aadf318094f8fc5204bdaf344" uuid = "bd369af6-aec1-5ad0-b16a-f7cc5008161c" -version = "1.12.0" +version = "1.12.1" [[deps.Tar]] deps = ["ArgTools", "SHA"] @@ -2260,9 +2260,9 @@ version = "1.0.0" [[deps.ThreadingUtilities]] deps = ["ManualMemory"] -git-tree-sha1 = "2d529b6b22791f3e22e7ec5c60b9016e78f5f6bf" +git-tree-sha1 = "d969183d3d244b6c33796b5ed01ab97328f2db85" uuid = "8290d209-cae3-49c0-8002-c8c24d57dab5" -version = "0.5.4" +version = "0.5.5" [[deps.TimerOutputs]] deps = ["ExprTools", "Printf"] @@ -2316,9 +2316,9 @@ uuid = "d265eb64-f81a-44ad-a842-4247ee1503de" version = "1.4.2" [[deps.URIs]] -git-tree-sha1 = "cbbebadbcc76c5ca1cc4b4f3b0614b3e603b5000" +git-tree-sha1 = "24c1c558881564e2217dcf7840a8b2e10caeb0f9" uuid = "5c2747f8-b7ea-4ff2-ba2e-563bfd36b1d4" -version = "1.5.2" +version = "1.6.0" [[deps.UUIDs]] deps = ["Random", "SHA"] @@ -2336,14 +2336,16 @@ version = "1.11.0" [[deps.Unitful]] deps = ["Dates", "LinearAlgebra", "Random"] -git-tree-sha1 = "d62610ec45e4efeabf7032d67de2ffdea8344bed" +git-tree-sha1 = "d2282232f8a4d71f79e85dc4dd45e5b12a6297fb" uuid = "1986cc42-f94f-5a68-af5c-568840ba703d" -version = "1.22.1" -weakdeps = ["ConstructionBase", "InverseFunctions"] +version = "1.23.1" +weakdeps = ["ConstructionBase", "ForwardDiff", "InverseFunctions", "Printf"] [deps.Unitful.extensions] ConstructionBaseUnitfulExt = "ConstructionBase" + ForwardDiffExt = "ForwardDiff" InverseFunctionsUnitfulExt = "InverseFunctions" + PrintfExt = "Printf" [[deps.Unityper]] deps = ["ConstructionBase"] @@ -2411,7 +2413,7 @@ uuid = "8e850b90-86db-534c-a0d3-1478176c7d93" version = "5.12.0+0" [[deps.nghttp2_jll]] -deps = ["Artifacts", "Libdl"] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "Libdl"] uuid = "8e850ede-7688-5339-a07c-302acd2aaf8d" version = "1.65.0+0" diff --git a/Project.toml b/Project.toml index c1d8752..0d4aa93 100644 --- a/Project.toml +++ b/Project.toml @@ -13,6 +13,7 @@ CentralizedCaches = "d1073d05-2d26-4019-b855-dfa0385fef5e" ChainRules = "082447d4-558c-5d27-93f4-14fc19e9eca2" ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" Compiler = "807dbc54-b67e-4c79-8afb-eafe4df6f2e1" +ConstructionBase = "187b0558-2788-49d3-abe0-74a17ed4e7c9" Cthulhu = "f68482b8-f384-11e8-15f7-abe071a5a75f" DiffEqBase = "2b5f629d-d688-5b77-993f-72d75c75574e" DiffEqCallbacks = "459566f4-90b8-5000-8ac3-15dfb0a30def" @@ -59,6 +60,7 @@ CentralizedCaches = "1.1.0" ChainRules = "1.50" ChainRulesCore = "1.20" Compiler = "0" +ConstructionBase = "1.5.9" DiffEqBase = "6.149.2" DifferentiationInterface = "0.6.52" Diffractor = "0.2.7" diff --git a/src/DAECompiler.jl b/src/DAECompiler.jl index 6a30c48..e77ab60 100644 --- a/src/DAECompiler.jl +++ b/src/DAECompiler.jl @@ -6,16 +6,16 @@ module DAECompiler using Diffractor using OrderedCollections using Compiler - using Compiler: IRCode, IncrementalCompact, argextype, singleton_type, isexpr, widenconst + using Compiler: IRCode, IncrementalCompact, DebugInfoStream, NewInstruction, argextype, singleton_type, isexpr, widenconst using Core.IR using SciMLBase using AutoHashEquals using LinearAlgebra: LinearAlgebra using InteractiveUtils: gen_call_with_extracted_types_and_kwargs + include("settings.jl") include("utils.jl") include("intrinsics.jl") - include("settings.jl") include("analysis/utils.jl") include("analysis/lattice.jl") include("analysis/ADAnalyzer.jl") diff --git a/src/analysis/flattening.jl b/src/analysis/flattening.jl index 0173de8..95a018a 100644 --- a/src/analysis/flattening.jl +++ b/src/analysis/flattening.jl @@ -1,4 +1,4 @@ -function _flatten_parameter!(𝕃, compact, argtypes, ntharg, line) +function _flatten_parameter!(𝕃, compact, argtypes, ntharg, line, settings) list = Any[] for (argn, argt) in enumerate(argtypes) if isa(argt, Const) @@ -18,12 +18,11 @@ function _flatten_parameter!(𝕃, compact, argtypes, ntharg, line) continue end this = ntharg(argn) - nthfield(i) = insert_node_here!(compact, - NewInstruction(Expr(:call, getfield, this, i), Compiler.getfield_tfunc(𝕃, argextype(this, compact), Const(i)), line)) + nthfield(i) = @insert_instruction_here(compact, line, settings, getfield(this, i)::Compiler.getfield_tfunc(𝕃, argextype(this, compact), Const(i))) if isa(argt, PartialStruct) - fields = _flatten_parameter!(𝕃, compact, argt.fields, nthfield, line) + fields = _flatten_parameter!(𝕃, compact, argt.fields, nthfield, line, settings) else - fields = _flatten_parameter!(𝕃, compact, fieldtypes(argt), nthfield, line) + fields = _flatten_parameter!(𝕃, compact, fieldtypes(argt), nthfield, line, settings) end append!(list, fields) end @@ -31,9 +30,8 @@ function _flatten_parameter!(𝕃, compact, argtypes, ntharg, line) return list end -function flatten_parameter!(𝕃, compact, argtypes, ntharg, line) - return insert_node_here!(compact, - NewInstruction(Expr(:call, tuple, _flatten_parameter!(𝕃, compact, argtypes, ntharg, line)...), Tuple, line)) +function flatten_parameter!(𝕃, compact, argtypes, ntharg, line, settings) + return @insert_instruction_here(compact, line, settings, tuple(_flatten_parameter!(𝕃, compact, argtypes, ntharg, line, settings)...)::Tuple) end # Needs to match flatten_arguments! @@ -76,7 +74,7 @@ struct TransformedArg TransformedArg(@nospecialize(arg), new_offset::Int, new_eqoffset::Int) = new(arg, new_offset, new_eqoffset) end -function flatten_argument!(compact::Compiler.IncrementalCompact, @nospecialize(argt), offset::Int, eqoffset::Int, argtypes::Vector{Any})::TransformedArg +function flatten_argument!(compact::Compiler.IncrementalCompact, settings::Settings, @nospecialize(argt), offset::Int, eqoffset::Int, argtypes::Vector{Any})::TransformedArg @assert !isa(argt, Incidence) && !isa(argt, Eq) if isa(argt, Const) return TransformedArg(argt.val, offset, eqoffset) @@ -86,28 +84,32 @@ function flatten_argument!(compact::Compiler.IncrementalCompact, @nospecialize(a push!(argtypes, argt) return TransformedArg(Argument(offset+1), offset+1, eqoffset) elseif argt === equation - ssa = insert_node_here!(compact, NewInstruction(Expr(:invoke, nothing, InternalIntrinsics.external_equation), Eq(eqoffset+1), compact[Compiler.OldSSAValue(1)][:line])) + line = compact[Compiler.OldSSAValue(1)][:line] + ssa = @insert_instruction_here(compact, line, settings, (:invoke)(nothing, InternalIntrinsics.external_equation)::Eq(eqoffset+1)) return TransformedArg(ssa, offset, eqoffset+1) elseif isabstracttype(argt) || ismutabletype(argt) || (!isa(argt, DataType) && !isa(argt, PartialStruct)) - ssa = insert_node_here!(compact, NewInstruction(Expr(:call, error, "Cannot IPO model arg type $argt"), Union{}, compact[Compiler.OldSSAValue(1)][:line])) + line = compact[Compiler.OldSSAValue(1)][:line] + ssa = @insert_instruction_here(compact, line, settings, error("Cannot IPO model arg type $argt")::Union{}) return TransformedArg(ssa, -1, eqoffset) else if !isa(argt, PartialStruct) && Base.datatype_fieldcount(argt) === nothing - ssa = insert_node_here!(compact, NewInstruction(Expr(:call, error, "Cannot IPO model arg type $argt"), Union{}, compact[Compiler.OldSSAValue(1)][:line])) + line = compact[Compiler.OldSSAValue(1)][:line] + ssa = @insert_instruction_here(compact, line, settings, error("Cannot IPO model arg type $argt")::Union{}) return TransformedArg(ssa, -1, eqoffset) end - (args, _, offset) = flatten_arguments!(compact, isa(argt, PartialStruct) ? argt.fields : collect(Any, fieldtypes(argt)), offset, eqoffset, argtypes) + (args, _, offset) = flatten_arguments!(compact, settings, isa(argt, PartialStruct) ? argt.fields : collect(Any, fieldtypes(argt)), offset, eqoffset, argtypes) offset == -1 && return TransformedArg(ssa, -1, eqoffset) this = Expr(:new, isa(argt, PartialStruct) ? argt.typ : argt, args...) - ssa = insert_node_here!(compact, NewInstruction(this, argt, compact[Compiler.OldSSAValue(1)][:line])) + line = compact[Compiler.OldSSAValue(1)][:line] + ssa = @insert_instruction_here(compact, line, settings, this::argt) return TransformedArg(ssa, offset, eqoffset) end end -function flatten_arguments!(compact::Compiler.IncrementalCompact, argtypes::Vector{Any}, offset::Int=0, eqoffset::Int=0, new_argtypes::Vector{Any} = Any[]) +function flatten_arguments!(compact::Compiler.IncrementalCompact, settings::Settings, argtypes::Vector{Any}, offset::Int=0, eqoffset::Int=0, new_argtypes::Vector{Any} = Any[]) args = Any[] for argt in argtypes - (; ssa, offset, eqoffset) = flatten_argument!(compact, argt, offset, eqoffset, new_argtypes) + (; ssa, offset, eqoffset) = flatten_argument!(compact, settings, argt, offset, eqoffset, new_argtypes) offset == -1 && break push!(args, ssa) end diff --git a/src/analysis/refiner.jl b/src/analysis/refiner.jl index c2e602a..be5b849 100644 --- a/src/analysis/refiner.jl +++ b/src/analysis/refiner.jl @@ -7,6 +7,7 @@ of structural incidence information. """ struct StructuralRefiner <: Compiler.AbstractInterpreter world::UInt + settings::Settings var_to_diff::DiffGraph varkinds::Vector{Intrinsics.VarKind} varclassification::Vector{VarEqClassification} @@ -51,7 +52,7 @@ Compiler.cache_owner(::StructuralRefiner) = StructureCache() end callee_codeinst = invokee::CodeInstance - callee_result = structural_analysis!(callee_codeinst, Compiler.get_inference_world(interp)) + callee_result = structural_analysis!(callee_codeinst, Compiler.get_inference_world(interp), interp.settings) if isa(callee_result, UncompilableIPOResult) || isa(callee_result.extended_rt, Const) || isa(callee_result.extended_rt, Type) # If this is uncompilable, we will be notfiying the user in the outer loop - here we just ignore it diff --git a/src/analysis/structural.jl b/src/analysis/structural.jl index 3234adb..644f551 100644 --- a/src/analysis/structural.jl +++ b/src/analysis/structural.jl @@ -16,14 +16,14 @@ function find_matching_ci(predicate, mi::MethodInstance, world::UInt) return nothing end -function structural_analysis!(ci::CodeInstance, world::UInt) +function structural_analysis!(ci::CodeInstance, world::UInt, settings::Settings) # Check if we have aleady done this work - if so return the cached result result_ci = find_matching_ci(ci->ci.owner == StructureCache(), ci.def, world) if result_ci !== nothing return result_ci.inferred end - result = _structural_analysis!(ci, world) + result = _structural_analysis!(ci, world, settings) # TODO: The world bounds might have been narrowed cache_dae_ci!(ci, result, nothing, nothing, StructureCache()) @@ -40,7 +40,7 @@ struct EqVarState eq_callee_mapping end -function _structural_analysis!(ci::CodeInstance, world::UInt) +function _structural_analysis!(ci::CodeInstance, world::UInt, settings::Settings) # Variables var_to_diff = DiffGraph(0) varclassification = VarEqClassification[] @@ -83,7 +83,7 @@ function _structural_analysis!(ci::CodeInstance, world::UInt) compact = IncrementalCompact(ir) old_argtypes = copy(ir.argtypes) empty!(ir.argtypes) - (arg_replacements, new_argtypes, nexternalargvars, nexternaleqs) = flatten_arguments!(compact, old_argtypes, 0, 0, ir.argtypes) + (arg_replacements, new_argtypes, nexternalargvars, nexternaleqs) = flatten_arguments!(compact, settings, old_argtypes, 0, 0, ir.argtypes) if nexternalargvars == -1 return UncompilableIPOResult(warnings, UnsupportedIRException("Unhandled argument types", Compiler.finish(compact))) end @@ -98,7 +98,7 @@ function _structural_analysis!(ci::CodeInstance, world::UInt) argtypes = Any[Incidence(new_argtypes[i], i) for i = 1:nexternalargvars] # Allocate variable and equation numbers of any incoming arguments - refiner = StructuralRefiner(world, var_to_diff, varkinds, varclassification, eqkinds, eqclassification) + refiner = StructuralRefiner(world, settings, var_to_diff, varkinds, varclassification, eqkinds, eqclassification) nexternalargvars = length(var_to_diff) # Go through the IR, annotating each intrinsic with an appropriate taint @@ -337,7 +337,7 @@ function _structural_analysis!(ci::CodeInstance, world::UInt) if isa(info, MappingInfo) (; result, mapping) = info else - result = structural_analysis!(callee_codeinst, Compiler.get_inference_world(refiner)) + result = structural_analysis!(callee_codeinst, Compiler.get_inference_world(refiner), settings) if isa(result, UncompilableIPOResult) # TODO: Stack trace? @@ -360,9 +360,9 @@ function _structural_analysis!(ci::CodeInstance, world::UInt) # Rewrite to flattened ABI compact[SSAValue(i)] = nothing compact.result_idx -= 1 - new_args = _flatten_parameter!(Compiler.optimizer_lattice(refiner), compact, callee_codeinst.inferred.ir.argtypes, arg->stmt.args[arg+1], line) + new_args = _flatten_parameter!(Compiler.optimizer_lattice(refiner), compact, callee_codeinst.inferred.ir.argtypes, arg->stmt.args[arg+1], line, settings) - new_call = insert_node_here!(compact, + new_call = insert_instruction_here!(compact, settings, @__SOURCE__, NewInstruction(Expr(:invoke, (StructuralSSARef(compact.result_idx), callee_codeinst), new_args...), stmtype, info, line, stmtflags)) compact.ssa_rename[compact.idx - 1] = new_call @@ -386,8 +386,8 @@ function _structural_analysis!(ci::CodeInstance, world::UInt) line = ret_stmt_inst[:line] Compiler.delete_inst_here!(compact) - (new_ret, ultimate_rt) = rewrite_ipo_return!(Compiler.typeinf_lattice(refiner), compact, line, ret_stmt.val, ultimate_rt, eqvars) - insert_node_here!(compact, NewInstruction(ReturnNode(new_ret), ultimate_rt, Compiler.NoCallInfo(), line, Compiler.IR_FLAG_REFINED), true) + (new_ret, ultimate_rt) = rewrite_ipo_return!(Compiler.typeinf_lattice(refiner), compact, line, settings, ret_stmt.val, ultimate_rt, eqvars) + insert_instruction_here!(compact, settings, @__SOURCE__, NewInstruction(ReturnNode(new_ret), ultimate_rt, Compiler.NoCallInfo(), line, Compiler.IR_FLAG_REFINED), reverse_affinity = true) elseif isa(ultimate_rt, Type) # If we don't have any internal variables (in which case we might have to to do a more aggressive rewrite), strengthen the incidence # by demoting to full incidence over the argument variables. Incidence is not allowed to propagate through global mutable state, so @@ -415,7 +415,7 @@ function _structural_analysis!(ci::CodeInstance, world::UInt) warnings) end -function rewrite_ipo_return!(𝕃, compact::IncrementalCompact, line, ssa, ultimate_rt::Any, eqvars::EqVarState) +function rewrite_ipo_return!(𝕃, compact::IncrementalCompact, line, settings, ssa, ultimate_rt::Any, eqvars::EqVarState) if isa(ultimate_rt, Eq) return Pair{Any, Any}(ssa, ultimate_rt) end @@ -425,22 +425,23 @@ function rewrite_ipo_return!(𝕃, compact::IncrementalCompact, line, ssa, ultim new_types = Any[] for i = 1:length(ultimate_rt.fields) ssa_type = Compiler.getfield_tfunc(𝕃, ultimate_rt, Const(i)) - ssa_field = insert_node_here!(compact, - NewInstruction(Expr(:call, getfield, variable), ssa_type, Compiler.NoCallInfo(), line, Compiler.IR_FLAG_REFINED), true) + ssa_field = insert_instruction_here!(compact, settings, @__SOURCE__, + NewInstruction(Expr(:call, getfield, variable), ssa_type, Compiler.NoCallInfo(), line, Compiler.IR_FLAG_REFINED), reverse_affinity = true) - (new_field, new_type) = rewrite_ipo_return!(𝕃, compact, line, ssa_field, ssa_type, eqvars) + (new_field, new_type) = rewrite_ipo_return!(𝕃, compact, line, settings, ssa_field, ssa_type, eqvars) push!(new_fields, new_field) push!(new_types, new_type) end newT = Compiler.PartialStruct(ultimate_rt.typ, new_types) if widenconst(ultimate_rt) <: Tuple - retssa = insert_node_here!(compact, - NewInstruction(Expr(:call, tuple, new_fields...), newT, Compiler.NoCallInfo(), line, Compiler.IR_FLAG_REFINED), true) + retssa = insert_instruction_here!(compact, settings, @__SOURCE__, + NewInstruction(Expr(:call, tuple, new_fields...), newT, Compiler.NoCallInfo(), line, Compiler.IR_FLAG_REFINED), reverse_affinity = true) else - T = insert_node_here!(compact, - NewInstruction(Expr(:call, typeof, ssa), Type, Compiler.NoCallInfo(), line, Compiler.IR_FLAG_REFINED), true) - retssa = insert_node_here!(compact, - NewInstruction(Expr(:new, T, new_fields...), newT, Compiler.NoCallInfo(), line, Compiler.IR_FLAG_REFINED), true) + T = insert_instruction_here!(compact, settings, @__SOURCE__, + NewInstruction(Expr(:call, typeof, ssa), Type, Compiler.NoCallInfo(), line, Compiler.IR_FLAG_REFINED), reverse_affinity = true) + + retssa = insert_instruction_here!(compact, settings, @__SOURCE__, + NewInstruction(Expr(:new, T, new_fields...), newT, Compiler.NoCallInfo(), line, Compiler.IR_FLAG_REFINED), reverse_affinity = true) end return Pair{Any, Any}(retssa, newT) end @@ -453,8 +454,8 @@ function rewrite_ipo_return!(𝕃, compact::IncrementalCompact, line, ssa, ultim push!(eqvars.varclassification, External) push!(eqvars.varkinds, Intrinsics.Continuous) - new_var_ssa = insert_node_here!(compact, - NewInstruction(Expr(:invoke, nothing, variable), Incidence(nonlinrepl), Compiler.NoCallInfo(), line, Compiler.IR_FLAG_REFINED), true) + new_var_ssa = insert_instruction_here!(compact, settings, @__SOURCE__, + NewInstruction(Expr(:invoke, nothing, variable), Incidence(nonlinrepl), Compiler.NoCallInfo(), line, Compiler.IR_FLAG_REFINED); reverse_affinity = true) eq_incidence = ultimate_rt - Incidence(nonlinrepl) push!(eqvars.total_incidence, eq_incidence) @@ -463,14 +464,14 @@ function rewrite_ipo_return!(𝕃, compact::IncrementalCompact, line, ssa, ultim push!(eqvars.eqkinds, Intrinsics.Always) new_eq = length(eqvars.total_incidence) - new_eq_ssa = insert_node_here!(compact, - NewInstruction(Expr(:invoke, nothing, equation), Eq(new_eq), Compiler.NoCallInfo(), line, Compiler.IR_FLAG_REFINED), true) + new_eq_ssa = insert_instruction_here!(compact, settings, @__SOURCE__, + NewInstruction(Expr(:invoke, nothing, equation), Eq(new_eq), Compiler.NoCallInfo(), line, Compiler.IR_FLAG_REFINED); reverse_affinity = true) - eq_val_ssa = insert_node_here!(compact, - NewInstruction(Expr(:call, InternalIntrinsics.assign_var, new_var_ssa, ssa), eq_incidence, Compiler.NoCallInfo(), line, Compiler.IR_FLAG_REFINED), true) + eq_val_ssa = insert_instruction_here!(compact, settings, @__SOURCE__, + NewInstruction(Expr(:call, InternalIntrinsics.assign_var, new_var_ssa, ssa), eq_incidence, Compiler.NoCallInfo(), line, Compiler.IR_FLAG_REFINED); reverse_affinity = true) - eq_call_ssa = insert_node_here!(compact, - NewInstruction(Expr(:invoke, nothing, new_eq_ssa, eq_val_ssa), Nothing, Compiler.NoCallInfo(), line, Compiler.IR_FLAG_REFINED), true) + eq_call_ssa = insert_instruction_here!(compact, settings, @__SOURCE__, + NewInstruction(Expr(:invoke, nothing, new_eq_ssa, eq_val_ssa), Nothing, Compiler.NoCallInfo(), line, Compiler.IR_FLAG_REFINED); reverse_affinity = true) T = widenconst(ultimate_rt) # TODO: We don't have a way to express that the return value is directly this variable for arbitrary types diff --git a/src/interface.jl b/src/interface.jl index 16e2db4..d884061 100644 --- a/src/interface.jl +++ b/src/interface.jl @@ -11,7 +11,7 @@ function factory_gen(@nospecialize(fT), settings::Settings, world::UInt = Base.g ci = ad_typeinf(world, Tuple{fT}; force_inline_all=settings.force_inline_all, edges=Core.svec(factory_mi)) # Perform or lookup DAECompiler specific analysis for this system. - result = structural_analysis!(ci, world) + result = structural_analysis!(ci, world, settings) if isa(result, UncompilableIPOResult) if isa(result.error, FunctionErrorsException) @@ -58,17 +58,18 @@ function factory_gen(@nospecialize(fT), settings::Settings, world::UInt = Base.g end # Generate the IR implementation of `factory`, returning the DAEFunction/ODEFunction + slotnames = nothing if settings.mode in (DAE, DAENoInit) - ir_factory = dae_factory_gen(tstate, ci, diff_key, world, settings, settings.mode == DAE ? init_key : nothing) + ir_factory, slotnames = dae_factory_gen(tstate, ci, diff_key, world, settings, settings.mode == DAE ? init_key : nothing) elseif settings.mode in (ODE, ODENoInit) - ir_factory = ode_factory_gen(tstate, ci, diff_key, world, settings, settings.mode == ODE ? init_key : nothing) + ir_factory, slotnames = ode_factory_gen(tstate, ci, diff_key, world, settings, settings.mode == ODE ? init_key : nothing) elseif settings.mode == InitUncompress ir_factory = init_uncompress_gen(result, ci, init_key, diff_key, world, settings) else return :(error("Unknown generation mode: $(settings.mode)")) end - src = ir_to_src(ir_factory, settings) + src = ir_to_src(ir_factory, settings; slotnames) src.ssavaluetypes = length(src.code) src.min_world = @atomic ci.min_world src.max_world = @atomic ci.max_world @@ -107,5 +108,6 @@ function refresh() $(Expr(:meta, :generated_only)) $(Expr(:meta, :generated, factory_gen)) end + return nothing end refresh() diff --git a/src/problem_interface.jl b/src/problem_interface.jl index 738eda6..f8ab5ab 100644 --- a/src/problem_interface.jl +++ b/src/problem_interface.jl @@ -24,8 +24,9 @@ function DAECProblem(f, init::Union{Vector, Tuple{Vararg{Pair}}}, tspan::Tuple{R guesses = nothing, force_inline_all=false, insert_stmt_debuginfo=false, + insert_ssa_debuginfo=false, kwargs...) - settings = Settings(; force_inline_all, insert_stmt_debuginfo) + settings = Settings(; mode = DAENoInit, force_inline_all, insert_stmt_debuginfo, insert_ssa_debuginfo) DAECProblem(f, init, guesses, tspan, kwargs, settings, missing, nothing, nothing) end @@ -33,14 +34,14 @@ function DAECProblem(f, tspan::Tuple{Real, Real} = (0., 1.); guesses = nothing, force_inline_all=false, insert_stmt_debuginfo=false, + insert_ssa_debuginfo=false, kwargs...) - settings = Settings(; force_inline_all, insert_stmt_debuginfo) + settings = Settings(; mode = DAE, force_inline_all, insert_stmt_debuginfo, insert_ssa_debuginfo) DAECProblem(f, nothing, guesses, tspan, kwargs, settings, missing, nothing, nothing) end function DiffEqBase.get_concrete_problem(prob::DAECProblem, isadaptive; kwargs...) - settings = Settings(; mode=prob.init === nothing ? DAE : DAENoInit, prob.settings.force_inline_all, prob.settings.insert_stmt_debuginfo) - (daef, differential_vars) = factory(Val(settings), prob.f) + (daef, differential_vars) = factory(Val(prob.settings), prob.f) u0 = zeros(length(differential_vars)) du0 = zeros(length(differential_vars)) @@ -74,8 +75,9 @@ function ODECProblem(f, init::Union{Vector, Tuple{Vararg{Pair}}}, tspan::Tuple{R guesses = nothing, force_inline_all=false, insert_stmt_debuginfo=false, + insert_ssa_debuginfo=false, kwargs...) - settings = Settings(; force_inline_all, insert_stmt_debuginfo) + settings = Settings(; mode = ODENoInit, force_inline_all, insert_stmt_debuginfo, insert_ssa_debuginfo) ODECProblem(f, init, guesses, tspan, kwargs, settings, missing, nothing) end @@ -83,14 +85,14 @@ function ODECProblem(f, tspan::Tuple{Real, Real} = (0., 1.); guesses = nothing, force_inline_all=false, insert_stmt_debuginfo=false, + insert_ssa_debuginfo=false, kwargs...) - settings = Settings(; force_inline_all, insert_stmt_debuginfo) + settings = Settings(; mode = ODE, force_inline_all, insert_stmt_debuginfo, insert_ssa_debuginfo) ODECProblem(f, nothing, guesses, tspan, kwargs, settings, missing, nothing) end function DiffEqBase.get_concrete_problem(prob::ODECProblem, isadaptive; kwargs...) - settings = Settings(; mode=prob.init === nothing ? ODE : ODENoInit, prob.settings.force_inline_all, prob.settings.insert_stmt_debuginfo) - (odef, n) = factory(Val(settings), prob.f) + (odef, n) = factory(Val(prob.settings), prob.f) u0 = zeros(n) diff --git a/src/reflection.jl b/src/reflection.jl index 457a9bd..aa15b76 100644 --- a/src/reflection.jl +++ b/src/reflection.jl @@ -26,9 +26,10 @@ end code_ad_by_type(@nospecialize(tt::Type); kwargs...) = _code_ad_by_type(tt; kwargs...).inferred.ir -function code_structure_by_type(@nospecialize(tt::Type); world::UInt = Base.tls_world_age(), result = false, matched = false, mode = DAE, kwargs...) +function code_structure_by_type(@nospecialize(tt::Type); world::UInt = Base.tls_world_age(), result = false, matched = false, mode = DAE, force_inline_all = false, insert_stmt_debuginfo = false, insert_ssa_debuginfo = false, kwargs...) ci = _code_ad_by_type(tt; world, kwargs...) - _result = structural_analysis!(ci, world) + settings = Settings(; mode, force_inline_all, insert_stmt_debuginfo, insert_ssa_debuginfo) + _result = structural_analysis!(ci, world, settings) isa(_result, UncompilableIPOResult) && throw(_result.error) !matched && return result ? _result : _result.ir result = _result diff --git a/src/settings.jl b/src/settings.jl index 149b27c..62a0758 100644 --- a/src/settings.jl +++ b/src/settings.jl @@ -13,5 +13,6 @@ struct Settings mode::GenerationMode force_inline_all::Bool insert_stmt_debuginfo::Bool + insert_ssa_debuginfo::Bool end -Settings(; mode::GenerationMode=DAE, force_inline_all::Bool=false, insert_stmt_debuginfo::Bool=false) = Settings(mode, force_inline_all, insert_stmt_debuginfo) +Settings(; mode::GenerationMode=DAE, force_inline_all::Bool=false, insert_stmt_debuginfo::Bool=false, insert_ssa_debuginfo::Bool=false) = Settings(mode, force_inline_all, insert_stmt_debuginfo, insert_ssa_debuginfo) diff --git a/src/transform/autodiff/index_lowering.jl b/src/transform/autodiff/index_lowering.jl index 448068d..10ce921 100644 --- a/src/transform/autodiff/index_lowering.jl +++ b/src/transform/autodiff/index_lowering.jl @@ -45,7 +45,7 @@ function is_diffed_equation_call_invoke_or_call(@nospecialize(stmt), ir::IRCode) return widenconst(ft) === equation end -function index_lowering_ad!(state::TransformationState, key::TornCacheKey) +function index_lowering_ad!(state::TransformationState, key::TornCacheKey, settings::Settings) (; result, structure) = state (; var_to_diff, eq_to_diff, graph, solvable_graph) = structure @@ -116,7 +116,7 @@ function index_lowering_ad!(state::TransformationState, key::TornCacheKey) return vars[dvar] end - function diff_variable!(ir, ssa, stmt, order) + function diff_variable!(ir, settings, ssa, stmt, order) inst = ir[ssa] var = idnum(ir[ssa][:type]) primal = insert_node!(ir, ssa, NewInstruction(inst)) @@ -129,7 +129,7 @@ function index_lowering_ad!(state::TransformationState, key::TornCacheKey) duals = insert_node!(ir, ssa, NewInstruction( Expr(:call, tuple, diffs...), Any )) - replace_call!(ir, ssa, Expr(:call, Diffractor.TaylorBundle{order}, primal, duals)) + replace_call!(ir, ssa, Expr(:call, Diffractor.TaylorBundle{order}, primal, duals), settings, @__SOURCE__) end function transform!(ir, ssa, order, maparg) @@ -180,7 +180,7 @@ function index_lowering_ad!(state::TransformationState, key::TornCacheKey) return nothing elseif is_known_invoke(stmt, sim_time, ir) time = insert_node!(ir, ssa, NewInstruction(inst)) - replace_call!(ir, ssa, Expr(:call, Diffractor.∂xⁿ{order}(), time)) + replace_call!(ir, ssa, Expr(:call, Diffractor.∂xⁿ{order}(), time), settings, @__SOURCE__) return nothing elseif is_diffed_equation_call_invoke_or_call(stmt, ir) eq = idnum(argextype(_eq_function_arg(stmt), ir)) @@ -210,9 +210,9 @@ function index_lowering_ad!(state::TransformationState, key::TornCacheKey) elseif is_known_invoke(stmt, ddt, ir) arg = maparg(stmt.args[end], ssa, order+1) if order == 0 - replace_call!(ir, ssa, Expr(:call, Diffractor.partial, arg, 1)) + replace_call!(ir, ssa, Expr(:call, Diffractor.partial, arg, 1), settings, @__SOURCE__()) else - replace_call!(ir, ssa, Expr(:call, diff_bundle, arg)) + replace_call!(ir, ssa, Expr(:call, diff_bundle, arg), settings, @__SOURCE__()) end return nothing else @@ -224,7 +224,7 @@ function index_lowering_ad!(state::TransformationState, key::TornCacheKey) end inst[:inst] = urs[] primal = insert_node!(ir, ssa, NewInstruction(inst)) - replace_call!(ir, ssa, Expr(:call, Diffractor.zero_bundle{order}(), primal)) + replace_call!(ir, ssa, Expr(:call, Diffractor.zero_bundle{order}(), primal), settings, @__SOURCE__) return nothing end end @@ -302,4 +302,4 @@ function empty_eq_list!(graph::BipartiteGraph, eq) rem_edge!(graph, eq, v) end return vs -end \ No newline at end of file +end diff --git a/src/transform/codegen/dae_factory.jl b/src/transform/codegen/dae_factory.jl index cae52cd..1741c89 100644 --- a/src/transform/codegen/dae_factory.jl +++ b/src/transform/codegen/dae_factory.jl @@ -4,16 +4,13 @@ Given an IR value `arg` that corresponds to `u` in SciML's DAE ABI, split it into component pieces for the DAECompiler internal ABI. """ -function sciml_dae_split_u!(compact, line, arg, numstates) +function sciml_dae_split_u!(compact, line, settings, arg, numstates) nassgn = numstates[AssignedDiff] ntotalstates = numstates[AssignedDiff] + numstates[UnassignedDiff] + numstates[Algebraic] - u_mm = insert_node_here!(compact, - NewInstruction(Expr(:call, view, arg, 1:nassgn), VectorViewType, line)) - u_unassgn = insert_node_here!(compact, - NewInstruction(Expr(:call, view, arg, (nassgn+1):(nassgn+numstates[UnassignedDiff])), VectorViewType, line)) - alg = insert_node_here!(compact, - NewInstruction(Expr(:call, view, arg, (nassgn+numstates[UnassignedDiff]+1):ntotalstates), VectorViewType, line)) + u_mm = @insert_instruction_here(compact, line, settings, view(arg, 1:nassgn)::VectorViewType) + u_unassgn = @insert_instruction_here(compact, line, settings, view(arg, (nassgn+1):(nassgn+numstates[UnassignedDiff]))::VectorViewType) + alg = @insert_instruction_here(compact, line, settings, view(arg, (nassgn+numstates[UnassignedDiff]+1):ntotalstates)::VectorViewType) return (u_mm, u_unassgn, alg) end @@ -24,14 +21,12 @@ end Given an IR value `arg` that corresponds to `du` in SciML's DAE ABI, split it into component pieces for the DAECompiler internal ABI. """ -function sciml_dae_split_du!(compact, line, arg, numstates) +function sciml_dae_split_du!(compact, line, settings, arg, numstates) nassgn = numstates[AssignedDiff] ntotalstates = numstates[AssignedDiff] + numstates[UnassignedDiff] + numstates[Algebraic] - in_du_assgn = insert_node_here!(compact, - NewInstruction(Expr(:call, view, arg, 1:nassgn), VectorViewType, line)) - in_du_unassgn = insert_node_here!(compact, - NewInstruction(Expr(:call, view, arg, (nassgn+1):(nassgn+numstates[UnassignedDiff])), VectorViewType, line)) + in_du_assgn = @insert_instruction_here(compact, line, settings, view(arg, 1:nassgn)::VectorViewType) + in_du_unassgn = @insert_instruction_here(compact, line, settings, view(arg, (nassgn+1):(nassgn+numstates[UnassignedDiff]))::VectorViewType) return (in_du_assgn, in_du_unassgn) end @@ -78,9 +73,8 @@ function dae_factory_gen(state::TransformationState, ci::CodeInstance, key::Torn @assert sicm_ci !== nothing line = result.ir[SSAValue(1)][:line] - param_list = flatten_parameter!(Compiler.fallback_lattice, compact, ci.inferred.ir.argtypes[1:end], argn->Argument(2+argn), line) - sicm = insert_node_here!(compact, - NewInstruction(Expr(:call, invoke, param_list, sicm_ci), Tuple, line)) + param_list = flatten_parameter!(Compiler.fallback_lattice, compact, ci.inferred.ir.argtypes[1:end], argn->Argument(2+argn), line, settings) + sicm = @insert_instruction_here(compact, line, settings, invoke(param_list, sicm_ci)::Tuple) else sicm = () end @@ -116,27 +110,22 @@ function dae_factory_gen(state::TransformationState, ci::CodeInstance, key::Torn # Zero the output line = ir_oc[SSAValue(1)][:line] - insert_node_here!(oc_compact, - NewInstruction(Expr(:call, zero!, Argument(2)), VectorViewType, line)) + @insert_instruction_here(oc_compact, line, settings, zero!(Argument(2))::VectorViewType) # out_du_mm, out_eq, in_u_mm, in_u_unassgn, in_du_unassgn, in_alg nassgn = numstates[AssignedDiff] ntotalstates = numstates[AssignedDiff] + numstates[UnassignedDiff] + numstates[Algebraic] - out_du_mm = insert_node_here!(oc_compact, - NewInstruction(Expr(:call, view, Argument(2), 1:nassgn), VectorViewType, line)) - out_eq = insert_node_here!(oc_compact, - NewInstruction(Expr(:call, view, Argument(2), (nassgn+1):ntotalstates), VectorViewType, line)) + out_du_mm = @insert_instruction_here(oc_compact, line, settings, view(Argument(2), 1:nassgn)::VectorViewType) + out_eq = @insert_instruction_here(oc_compact, line, settings, view(Argument(2), (nassgn+1):ntotalstates)::VectorViewType) - (in_du_assgn, in_du_unassgn) = sciml_dae_split_du!(oc_compact, line, Argument(3), numstates) - (in_u_mm, in_u_unassgn, in_alg) = sciml_dae_split_u!(oc_compact, line, Argument(4), numstates) + (in_du_assgn, in_du_unassgn) = sciml_dae_split_du!(oc_compact, line, settings, Argument(3), numstates) + (in_u_mm, in_u_unassgn, in_alg) = sciml_dae_split_u!(oc_compact, line, settings, Argument(4), numstates) # Call DAECompiler-generated RHS with internal ABI - oc_sicm = insert_node_here!(oc_compact, - NewInstruction(Expr(:call, getfield, Argument(1), 1), Tuple, line)) + oc_sicm = @insert_instruction_here(oc_compact, line, settings, getfield(Argument(1), 1)::Core.OpaqueClosure) # N.B: The ordering of arguments should match the ordering in the StateKind enum - insert_node_here!(oc_compact, - NewInstruction(Expr(:invoke, daef_ci, oc_sicm, (), in_u_mm, in_u_unassgn, in_du_unassgn, in_alg, out_du_mm, out_eq, Argument(6)), Nothing, line)) + @insert_instruction_here(oc_compact, line, settings, (:invoke)(daef_ci, oc_sicm, (), in_u_mm, in_u_unassgn, in_du_unassgn, in_alg, out_du_mm, out_eq, Argument(6))::Nothing) # TODO: We should not have to recompute this here var_eq_matching = matching_for_key(state, key) @@ -157,19 +146,15 @@ function dae_factory_gen(state::TransformationState, ci::CodeInstance, key::Torn @assert kind == AssignedDiff @assert dkind in (AssignedDiff, UnassignedDiff) - v_val = insert_node_here!(oc_compact, - NewInstruction(Expr(:call, Base.getindex, dkind == AssignedDiff ? in_u_mm : in_u_unassgn, dslot), Any, line)) - insert_node_here!(oc_compact, - NewInstruction(Expr(:call, Base.setindex!, out_du_mm, v_val, slot), Any, line)) + v_val = @insert_instruction_here(oc_compact, line, settings, getindex(dkind == AssignedDiff ? in_u_mm : in_u_unassgn, dslot)::Any) + @insert_instruction_here(oc_compact, line, settings, setindex!(out_du_mm, v_val, slot)::Any) end - bc = insert_node_here!(oc_compact, - NewInstruction(Expr(:call, Base.Broadcast.broadcasted, -, out_du_mm, in_du_assgn), Any, line)) - insert_node_here!(oc_compact, - NewInstruction(Expr(:call, Base.Broadcast.materialize!, out_du_mm, bc), Nothing, line)) + bc = @insert_instruction_here(oc_compact, line, settings, Base.Broadcast.broadcasted(-, out_du_mm, in_du_assgn)::Any) + @insert_instruction_here(oc_compact, line, settings, Base.Broadcast.materialize!(out_du_mm, bc)::Nothing) # Return - insert_node_here!(oc_compact, NewInstruction(ReturnNode(nothing), Union{}, line)) + @insert_instruction_here(oc_compact, line, settings, (return nothing)::Union{}) ir_oc = Compiler.finish(oc_compact) maybe_rewrite_debuginfo!(ir_oc, settings) @@ -186,31 +171,27 @@ function dae_factory_gen(state::TransformationState, ci::CodeInstance, key::Torn @atomic oc_ci.max_world = @atomic ci.max_world @atomic oc_ci.min_world = 1 # @atomic ci.min_world - new_oc = insert_node_here!(compact, NewInstruction(Expr(:new_opaque_closure, - argt, Union{}, Nothing, true, oc_source_method, sicm), Core.OpaqueClosure, line), true) + new_oc = @insert_instruction_here(compact, line, settings, (:new_opaque_closure)(argt, Union{}, Nothing, true, oc_source_method, sicm)::Core.OpaqueClosure, true) differential_states = Bool[v in key.diff_states for v in all_states] if init_key !== nothing initf = init_uncompress_gen!(compact, result, ci, init_key, key, world, settings) - daef = insert_node_here!(compact, NewInstruction(Expr(:call, make_daefunction, new_oc, initf), - DAEFunction, line), true) + daef = @insert_instruction_here(compact, line, settings, make_daefunction(new_oc, initf)::DAEFunction, true) else - daef = insert_node_here!(compact, NewInstruction(Expr(:call, make_daefunction, new_oc), - DAEFunction, line), true) + daef = @insert_instruction_here(compact, line, settings, make_daefunction(new_oc)::DAEFunction, true) end # TODO: Ideally, this'd be in DAEFunction - daef_and_diff = insert_node_here!(compact, NewInstruction( - Expr(:call, tuple, daef, differential_states), - Tuple, line), true) + daef_and_diff = @insert_instruction_here(compact, line, settings, tuple(daef, differential_states)::Tuple, true) - insert_node_here!(compact, NewInstruction(ReturnNode(daef_and_diff), Core.OpaqueClosure, line), true) + @insert_instruction_here(compact, line, settings, (return daef_and_diff)::Tuple, true) ir_factory = Compiler.finish(compact) resize!(ir_factory.cfg.blocks, 1) empty!(ir_factory.cfg.blocks[1].succs) Compiler.verify_ir(ir_factory) - return ir_factory + slotnames = [[:factory, :settings]; Symbol.(:arg, 1:(length(ir_factory.argtypes) - 2))] + return ir_factory, slotnames end diff --git a/src/transform/codegen/init_factory.jl b/src/transform/codegen/init_factory.jl index e0b002c..0b96a6a 100644 --- a/src/transform/codegen/init_factory.jl +++ b/src/transform/codegen/init_factory.jl @@ -6,7 +6,8 @@ function init_uncompress_gen(result::DAEIPOResult, ci::CodeInstance, init_key::T compact = IncrementalCompact(ir_factory) new_oc = init_uncompress_gen!(compact, result, ci, init_key, diff_key, world, settings) - insert_node_here!(compact, NewInstruction(ReturnNode(new_oc), Core.OpaqueClosure, result.ir[SSAValue(1)][:line]), true) + line = result.ir[SSAValue(1)][:line] + @insert_instruction_here(compact, line, settings, (return new_oc)::Core.OpaqueClosure, true) ir_factory = Compiler.finish(compact) Compiler.verify_ir(ir_factory) @@ -26,9 +27,8 @@ function init_uncompress_gen!(compact::Compiler.IncrementalCompact, result::DAEI @assert sicm_ci !== nothing line = result.ir[SSAValue(1)][:line] - param_list = flatten_parameter!(Compiler.fallback_lattice, compact, ci.inferred.ir.argtypes[1:end], argn->Argument(2+argn), line) - sicm = insert_node_here!(compact, - NewInstruction(Expr(:call, invoke, param_list, sicm_ci), Tuple, line)) + param_list = flatten_parameter!(Compiler.fallback_lattice, compact, ci.inferred.ir.argtypes[1:end], argn->Argument(2+argn), line, settings) + sicm = @insert_instruction_here(compact, line, settings, invoke(param_list, sicm_ci)::Tuple) else sicm = () end @@ -61,32 +61,27 @@ function init_uncompress_gen!(compact::Compiler.IncrementalCompact, result::DAEI # Zero the output nout = numstates[UnassignedDiff] + numstates[AssignedDiff] - out_arr = insert_node_here!(oc_compact, - NewInstruction(Expr(:call, zeros, nout), Vector{Float64}, line)) + out_arr = @insert_instruction_here(oc_compact, line, settings, zeros(nout)::Vector{Float64}) nscratch = numstates[Algebraic] + numstates[AlgebraicDerivative] - scratch_arr = insert_node_here!(oc_compact, - NewInstruction(Expr(:call, zeros, nout), Vector{Float64}, line)) + scratch_arr = @insert_instruction_here(oc_compact, line, settings, zeros(nout)::Vector{Float64}) # Get the solution vector out of the solution object - in_nlsol_u = insert_node_here!(oc_compact, - NewInstruction(Expr(:call, getproperty, Argument(2), QuoteNode(:u0)), Vector{Float64}, line)) + in_nlsol_u = @insert_instruction_here(oc_compact, line, settings, getproperty(Argument(2), QuoteNode(:u0))::Vector{Float64}) # Adapt to DAECompiler ABI nassgn = numstates[AssignedDiff] ntotalstates = numstates[AssignedDiff] + numstates[UnassignedDiff] + numstates[Algebraic] - (out_u_mm, out_u_unassgn, out_alg) = sciml_dae_split_u!(oc_compact, line, out_arr, numstates) - (out_du_unassgn, _) = sciml_dae_split_du!(oc_compact, line, scratch_arr, numstates) + (out_u_mm, out_u_unassgn, out_alg) = sciml_dae_split_u!(oc_compact, line, settings, out_arr, numstates) + (out_du_unassgn, _) = sciml_dae_split_du!(oc_compact, line, settings, scratch_arr, numstates) # Call DAECompiler-generated RHS with internal ABI - oc_sicm = insert_node_here!(oc_compact, - NewInstruction(Expr(:call, getfield, Argument(1), 1), Tuple, line)) - insert_node_here!(oc_compact, - NewInstruction(Expr(:invoke, daef_ci, oc_sicm, (), out_u_mm, out_u_unassgn, out_du_unassgn, out_alg, in_nlsol_u, 0.0), Nothing, line)) + oc_sicm = @insert_instruction_here(oc_compact, line, settings, getfield(Argument(1), 1)::Core.OpaqueClosure) + @insert_instruction_here(oc_compact, line, settings, (:invoke)(daef_ci, oc_sicm, (), out_u_mm, out_u_unassgn, out_du_unassgn, out_alg, in_nlsol_u, 0.0)::Nothing) # Return - insert_node_here!(oc_compact, NewInstruction(ReturnNode(out_arr), Vector{Float64}, line)) + @insert_instruction_here(oc_compact, line, settings, (return out_arr)::Vector{Float64}) ir_oc = Compiler.finish(oc_compact) oc = Core.OpaqueClosure(ir_oc) @@ -99,8 +94,8 @@ function init_uncompress_gen!(compact::Compiler.IncrementalCompact, result::DAEI @atomic oc_ci.max_world = @atomic ci.max_world @atomic oc_ci.min_world = 1 # @atomic ci.min_world - new_oc = insert_node_here!(compact, NewInstruction(Expr(:new_opaque_closure, - argt, Vector{Float64}, Vector{Float64}, true, oc_source_method, sicm), Core.OpaqueClosure, line), true) + new_oc = @insert_instruction_here(compact, line, settings, (:new_opaque_closure)( + argt, Vector{Float64}, Vector{Float64}, true, oc_source_method, sicm)::Core.OpaqueClosure, true) return new_oc end diff --git a/src/transform/codegen/init_uncompress.jl b/src/transform/codegen/init_uncompress.jl index 4476bc4..94acabc 100644 --- a/src/transform/codegen/init_uncompress.jl +++ b/src/transform/codegen/init_uncompress.jl @@ -98,7 +98,7 @@ function gen_init_uncompress!( spec_data = stmt.args[1] callee_key = stmt.args[1][2] callee_ordinal = stmt.args[1][end]::Int - callee_result = structural_analysis!(callee_ci, world) + callee_result = structural_analysis!(callee_ci, world, settings) callee_daef_ci = rhs_finish!(callee_result, callee_ci, callee_key, world, settings, callee_ordinal) # Allocate a continuous block of variables for all callee alg and diff states @@ -136,19 +136,14 @@ function gen_init_uncompress!( else (kind, slotidx) = slot which = kind == AssignedDiff ? out_u_mm : error() - replace_call!(ir, SSAValue(i), Expr(:call, Base.setindex!, which, argval, slotidx)) + replace_call!(ir, SSAValue(i), Expr(:call, Base.setindex!, which, argval, slotidx), settings, @__SOURCE__) end else - replace_if_intrinsic!(ir, SSAValue(i), nothing, nothing, Argument(1), t, var_assignment) + replace_if_intrinsic!(ir, settings, SSAValue(i), nothing, nothing, Argument(1), t, var_assignment) end end # Just before the end of the function - idx = length(ir.stmts) - function ir_add!(a, b) - ni = NewInstruction(Expr(:call, +, a, b), Any, ir[SSAValue(idx)][:line]) - insert_node!(ir, idx, ni) - end ir = Compiler.compact!(ir) Compiler.verify_ir(ir) diff --git a/src/transform/codegen/ode_factory.jl b/src/transform/codegen/ode_factory.jl index 217f35f..450dd1c 100644 --- a/src/transform/codegen/ode_factory.jl +++ b/src/transform/codegen/ode_factory.jl @@ -4,17 +4,17 @@ Given an IR value `arg` that corresponds to `u` in SciML's ODE ABI, split it into component pieces for the DAECompiler internal ABI. """ -function sciml_ode_split_u!(compact, line, arg, numstates) +function sciml_ode_split_u!(compact, line, settings, arg, numstates) ntotalstates = numstates[AssignedDiff] + numstates[UnassignedDiff] + numstates[Algebraic] + numstates[AlgebraicDerivative] - u_mm = @insert_node_here compact line view(arg, - 1:numstates[AssignedDiff])::VectorViewType - u_unassgn = @insert_node_here compact line view(arg, - (numstates[AssignedDiff] + 1):(numstates[AssignedDiff] + numstates[UnassignedDiff]))::VectorViewType - alg = @insert_node_here compact line view(arg, - (numstates[AssignedDiff] + numstates[UnassignedDiff] + 1):(numstates[AssignedDiff] + numstates[UnassignedDiff] + numstates[Algebraic]))::VectorViewType - alg_derv = @insert_node_here compact line view(arg, - (numstates[AssignedDiff] + numstates[UnassignedDiff] + numstates[Algebraic] + 1):ntotalstates)::VectorViewType + u_mm = @insert_instruction_here(compact, line, settings, view(arg, + 1:numstates[AssignedDiff])::VectorViewType) + u_unassgn = @insert_instruction_here(compact, line, settings, view(arg, + (numstates[AssignedDiff] + 1):(numstates[AssignedDiff] + numstates[UnassignedDiff]))::VectorViewType) + alg = @insert_instruction_here(compact, line, settings, view(arg, + (numstates[AssignedDiff] + numstates[UnassignedDiff] + 1):(numstates[AssignedDiff] + numstates[UnassignedDiff] + numstates[Algebraic]))::VectorViewType) + alg_derv = @insert_instruction_here(compact, line, settings, view(arg, + (numstates[AssignedDiff] + numstates[UnassignedDiff] + numstates[Algebraic] + 1):ntotalstates)::VectorViewType) return (u_mm, u_unassgn, alg, alg_derv) end @@ -57,24 +57,23 @@ function ode_factory_gen(state::TransformationState, ci::CodeInstance, key::Torn torn_ci = find_matching_ci(ci->isa(ci.owner, TornIRSpec) && ci.owner.key == key, ci.def, world) torn_ir = torn_ci.inferred - (;ir_sicm) = torn_ir + sicm_ir = torn_ir.ir_sicm - ir_factory = copy(ci.inferred.ir) - pushfirst!(ir_factory.argtypes, Settings) - pushfirst!(ir_factory.argtypes, typeof(factory)) - compact = IncrementalCompact(ir_factory) + returned_ir = copy(ci.inferred.ir) + pushfirst!(returned_ir.argtypes, Settings) + pushfirst!(returned_ir.argtypes, typeof(factory)) + returned_ic = IncrementalCompact(returned_ir) local line - if ir_sicm !== nothing + if sicm_ir !== nothing sicm_ci = find_matching_ci(ci->isa(ci.owner, SICMSpec) && ci.owner.key == key, ci.def, world) @assert sicm_ci !== nothing line = result.ir[SSAValue(1)][:line] - param_list = flatten_parameter!(Compiler.fallback_lattice, compact, ci.inferred.ir.argtypes[1:end], argn->Argument(2+argn), line) - sicm = insert_node_here!(compact, - NewInstruction(Expr(:call, invoke, param_list, sicm_ci), Tuple, line)) + param_list = flatten_parameter!(Compiler.fallback_lattice, returned_ic, ci.inferred.ir.argtypes[1:end], argn->Argument(2+argn), line, settings) + sicm_state = @insert_instruction_here(returned_ic, line, settings, (:call)(invoke, param_list, sicm_ci)::Tuple) else - sicm = () + sicm_state = () end odef_ci = rhs_finish!(state, ci, key, world, settings, 1) @@ -92,75 +91,73 @@ function ode_factory_gen(state::TransformationState, ci::CodeInstance, key::Torn (kind != AlgebraicDerivative) && push!(all_states, var) end - ir_oc = copy(ci.inferred.ir) - empty!(ir_oc.argtypes) + interface_ir = copy(ci.inferred.ir) + empty!(interface_ir.argtypes) argt = Tuple{Vector{Float64}, Vector{Float64}, SciMLBase.NullParameters, Float64} - push!(ir_oc.argtypes, Tuple) - append!(ir_oc.argtypes, fieldtypes(argt)) - Compiler.verify_ir(ir_oc) + push!(interface_ir.argtypes, Tuple) + append!(interface_ir.argtypes, fieldtypes(argt)) + Compiler.verify_ir(interface_ir) - oc_compact = IncrementalCompact(ir_oc) + interface_ic = IncrementalCompact(interface_ir) self = Argument(1) du = Argument(2) u = Argument(3) p = Argument(4) t = Argument(5) - line = ir_oc[SSAValue(1)][:line] + line = interface_ir[SSAValue(1)][:line] # Zero the output - @insert_node_here oc_compact line zero!(du)::VectorViewType + @insert_instruction_here(interface_ic, line, settings, zero!(du)::VectorViewType) nassgn = numstates[AssignedDiff] nunassgn = numstates[UnassignedDiff] ntotalstates = numstates[AssignedDiff] + numstates[UnassignedDiff] + numstates[Algebraic] + numstates[AlgebraicDerivative] - (in_u_mm, in_u_unassgn, in_alg, in_alg_derv) = sciml_ode_split_u!(oc_compact, line, u, numstates) - out_du_mm = @insert_node_here oc_compact line view(du, 1:nassgn)::VectorViewType - out_du_unassgn = @insert_node_here oc_compact line view(du, (nassgn+1):(nassgn+nunassgn))::VectorViewType - out_eq = @insert_node_here oc_compact line view(du, (nassgn+nunassgn+1):ntotalstates)::VectorViewType + (in_u_mm, in_u_unassgn, in_alg, in_alg_derv) = sciml_ode_split_u!(interface_ic, line, settings, u, numstates) + out_du_mm = @insert_instruction_here(interface_ic, line, settings, view(du, 1:nassgn)::VectorViewType) + out_du_unassgn = @insert_instruction_here(interface_ic, line, settings, view(du, (nassgn+1):(nassgn+nunassgn))::VectorViewType) + out_eq = @insert_instruction_here(interface_ic, line, settings, view(du, (nassgn+nunassgn+1):ntotalstates)::VectorViewType) # Call DAECompiler-generated RHS with internal ABI - oc_sicm = @insert_node_here oc_compact line getfield(self, 1)::Tuple + sicm_oc = @insert_instruction_here(interface_ic, line, settings, getfield(self, 1)::Core.OpaqueClosure) # N.B: The ordering of arguments should match the ordering in the StateKind enum - @insert_node_here oc_compact line (:invoke)(odef_ci, oc_sicm, (), in_u_mm, in_u_unassgn, in_alg_derv, in_alg, out_du_mm, out_eq, t)::Nothing + @insert_instruction_here(interface_ic, line, settings, (:invoke)(odef_ci, sicm_oc, (), in_u_mm, in_u_unassgn, in_alg_derv, in_alg, out_du_mm, out_eq, t)::Nothing) # Assign the algebraic derivatives to the their corresponding variables - bc = insert_node_here!(oc_compact, - NewInstruction(Expr(:call, Base.Broadcast.broadcasted, identity, in_alg_derv), Any, line)) - insert_node_here!(oc_compact, - NewInstruction(Expr(:call, Base.Broadcast.materialize!, out_du_unassgn, bc), Nothing, line)) + bc = @insert_instruction_here(interface_ic, line, settings, Base.Broadcast.broadcasted(identity, in_alg_derv)::Any) + @insert_instruction_here(interface_ic, line, settings, Base.Broadcast.materialize!(out_du_unassgn, bc)::Nothing) # Return - @insert_node_here oc_compact line (return)::Union{} + @insert_instruction_here(interface_ic, line, settings, (return)::Union{}) - ir_oc = Compiler.finish(oc_compact) - maybe_rewrite_debuginfo!(ir_oc, settings) - Compiler.verify_ir(ir_oc) - oc = Core.OpaqueClosure(ir_oc) + interface_ir = Compiler.finish(interface_ic) + maybe_rewrite_debuginfo!(interface_ir, settings) + Compiler.verify_ir(interface_ir) + interface_oc = Core.OpaqueClosure(interface_ir; slotnames = [:self, :du, :u, :p, :t]) line = result.ir[SSAValue(1)][:line] - oc_source_method = oc.source + interface_method = interface_oc.source # Sketchy, but not clear that we have something better for the time being - oc_ci = oc_source_method.specializations.cache - @atomic oc_ci.max_world = @atomic ci.max_world - @atomic oc_ci.min_world = 1 # @atomic ci.min_world + interface_ci = interface_method.specializations.cache + @atomic interface_ci.max_world = @atomic ci.max_world + @atomic interface_ci.min_world = 1 # @atomic ci.min_world - new_oc = @insert_node_here compact line (:new_opaque_closure)(argt, Union{}, Nothing, true, oc_source_method, sicm)::Core.OpaqueClosure true + new_oc = @insert_instruction_here(returned_ic, line, settings, (:new_opaque_closure)(argt, Union{}, Nothing, true, interface_method, sicm_state)::Core.OpaqueClosure, true) nd = numstates[AssignedDiff] + numstates[UnassignedDiff] na = numstates[Algebraic] + numstates[AlgebraicDerivative] - mass_matrix = na == 0 ? GlobalRef(LinearAlgebra, :I) : @insert_node_here compact line generate_ode_mass_matrix(nd, na)::Matrix{Float64} - initf = init_key !== nothing ? init_uncompress_gen!(compact, result, ci, init_key, key, world, settings) : nothing - odef = @insert_node_here compact line make_odefunction(new_oc, mass_matrix, initf)::ODEFunction true + mass_matrix = na == 0 ? GlobalRef(LinearAlgebra, :I) : @insert_instruction_here(returned_ic, line, settings, generate_ode_mass_matrix(nd, na)::Matrix{Float64}) + initf = init_key !== nothing ? init_uncompress_gen!(returned_ic, result, ci, init_key, key, world, settings) : nothing + odef = @insert_instruction_here(returned_ic, line, settings, make_odefunction(new_oc, mass_matrix, initf)::ODEFunction, true) + odef_and_n = @insert_instruction_here(returned_ic, line, settings, tuple(odef, nd + na)::Tuple, true) + @insert_instruction_here(returned_ic, line, settings, (return odef_and_n)::Core.OpaqueClosure, true) - odef_and_n = @insert_node_here compact line tuple(odef, nd + na)::Tuple true - @insert_node_here compact line (return odef_and_n)::Core.OpaqueClosure true + returned_ir = Compiler.finish(returned_ic) + Compiler.verify_ir(returned_ir) - ir_factory = Compiler.finish(compact) - Compiler.verify_ir(ir_factory) - - return ir_factory + slotnames = [[:factory, :settings]; Symbol.(:arg, 1:(length(returned_ir.argtypes) - 2))] + return returned_ir, slotnames end diff --git a/src/transform/codegen/rhs.jl b/src/transform/codegen/rhs.jl index 2455b6b..0215d29 100644 --- a/src/transform/codegen/rhs.jl +++ b/src/transform/codegen/rhs.jl @@ -16,13 +16,13 @@ function Base.StackTraces.show_custom_spec_sig(io::IO, owner::RHSSpec, linfo::Co return Base.StackTraces.show_spec_sig(io, mi.def, mi.specTypes) end -function handle_contribution!(ir::Compiler.IRCode, inst::Compiler.Instruction, kind, slot, arg_range, red) +function handle_contribution!(ir::Compiler.IRCode, settings::Settings, source, inst::Compiler.Instruction, kind, slot, arg_range, red) pos = SSAValue(inst.idx) @assert Int(LastStateKind) < Int(kind) <= Int(LastEquationStateKind) which = Argument(arg_range[Int(kind)]) prev = insert_node!(ir, pos, NewInstruction(inst; stmt=Expr(:call, Base.getindex, which, slot), type=Float64)) sum = insert_node!(ir, pos, NewInstruction(inst; stmt=Expr(:call, +, prev, red), type=Float64)) - replace_call!(ir, pos, Expr(:call, Base.setindex!, which, sum, slot)) + replace_call!(ir, pos, Expr(:call, Base.setindex!, which, sum, slot), settings, source) end function compute_slot_ranges(caller_state::TransformationState, info::MappingInfo, callee_key, var_assignment, eq_assignment) @@ -117,6 +117,13 @@ function rhs_finish!( empty!(ir.argtypes) push!(ir.argtypes, Tuple) # SICM State push!(ir.argtypes, Tuple) # in vars + if in(settings.mode, (ODE, ODENoInit)) + slotnames = [:sicm_state, :vars, :in_u_mm, :in_u_unassgn, :in_alg_derv, :in_alg, :out_du_mm, :out_eq, :t] + elseif in(settings.mode, (DAE, DAENoInit)) + slotnames = [:sicm_state, :vars, :in_u_mm, :in_u_unassgn, :in_du_unassgn, :in_alg, :out_du_mm, :out_eq, :t] + else + slotnames = nothing # XXX: define slotnames for `InitUncompress` + end arg_range = 3:8 @assert length(arg_range) == Int(LastEquationStateKind) @@ -157,7 +164,7 @@ function rhs_finish!( spec_data = stmt.args[1] callee_key = spec_data[2] callee_ordinal = spec_data[end]::Int - callee_result = structural_analysis!(callee_ci, world) + callee_result = structural_analysis!(callee_ci, world, settings) callee_daef_ci = rhs_finish!(callee_result, callee_ci, callee_key, world, settings, callee_ordinal) # Allocate a continuous block of variables for all callee alg and diff states @@ -186,7 +193,7 @@ function rhs_finish!( varnum = idnum(ir.stmts.type[i]) kind = varkind(state, varnum) if kind == Intrinsics.Epsilon - replace_call!(ir, SSAValue(i), 0.) + replace_call!(ir, SSAValue(i), 0., settings, @__SOURCE__) continue end @assert kind == Intrinsics.Continuous @@ -200,14 +207,14 @@ function rhs_finish!( (kind, slot) = assgn @assert 1 <= Int(kind) <= Int(LastStateKind) which = Argument(arg_range[Int(kind)]) - replace_call!(ir, SSAValue(i), Expr(:call, Base.getindex, which, slot)) + replace_call!(ir, SSAValue(i), Expr(:call, Base.getindex, which, slot), settings, @__SOURCE__) elseif is_known_invoke_or_call(stmt, InternalIntrinsics.contribution!, ir) eq = stmt.args[end-2]::Int kind = stmt.args[end-1]::EquationStateKind (eqkind, slot) = eq_assignment[eq]::Pair @assert eqkind == kind red = stmt.args[end] - handle_contribution!(ir, inst, kind, slot, arg_range, red) + handle_contribution!(ir, settings, @__SOURCE__(), inst, kind, slot, arg_range, red) elseif is_known_invoke(stmt, equation, ir) # Equation - used, but only as an arg to equation call, which will all get # eliminated by the end of this loop, so we can delete this statement, as @@ -217,28 +224,23 @@ function rhs_finish!( var = stmt.args[end-1] vint = invview(structure.var_to_diff)[var] if vint !== nothing && key.diff_states !== nothing && (vint in key.diff_states) && !(var in diff_states_in_callee) - handle_contribution!(ir, inst, StateDiff, var_assignment[vint][2], arg_range, stmt.args[end]) + handle_contribution!(ir, settings, @__SOURCE__(), inst, StateDiff, var_assignment[vint][2], arg_range, stmt.args[end]) else ir[SSAValue(i)] = nothing end else - replace_if_intrinsic!(ir, SSAValue(i), nothing, nothing, Argument(1), t, var_assignment) + replace_if_intrinsic!(ir, settings, SSAValue(i), nothing, nothing, Argument(1), t, var_assignment) end end # Just before the end of the function - idx = length(ir.stmts) - function ir_add!(a, b) - ni = NewInstruction(Expr(:call, +, a, b), Any, ir[SSAValue(idx)][:line]) - insert_node!(ir, idx, ni) - end ir = Compiler.compact!(ir) resize!(ir.cfg.blocks, 1) empty!(ir.cfg.blocks[1].succs) widen_extra_info!(ir) Compiler.verify_ir(ir) - src = ir_to_src(ir, settings) + src = ir_to_src(ir, settings; slotnames) abi = Tuple{Tuple, Tuple, (VectorViewType for _ in arg_range)..., Float64} daef_ci = cache_dae_ci!(ci, src, src.debuginfo, abi, RHSSpec(key, ir_ordinal)) diff --git a/src/transform/common.jl b/src/transform/common.jl index 211a4ae..492d7aa 100644 --- a/src/transform/common.jl +++ b/src/transform/common.jl @@ -40,9 +40,8 @@ function widen_extra_info!(ir) end end -function ir_to_src(ir::IRCode, settings::Settings) +function ir_to_src(ir::IRCode, settings::Settings; slotnames = nothing) isva = false - slotnames = nothing ir.debuginfo.def === nothing && (ir.debuginfo.def = :var"generated IR for OpaqueClosure") maybe_rewrite_debuginfo!(ir, settings) nargtypes = length(ir.argtypes) @@ -65,31 +64,29 @@ function ir_to_src(ir::IRCode, settings::Settings) end function maybe_rewrite_debuginfo!(ir::IRCode, settings::Settings) - settings.insert_stmt_debuginfo && rewrite_debuginfo!(ir) + settings.insert_ssa_debuginfo && rewrite_debuginfo!(ir) return ir end function rewrite_debuginfo!(ir::IRCode) - debuginfo = ir.debuginfo - firstline = debuginfo.firstline - empty!(debuginfo.edges) - empty!(debuginfo.codelocs) for (i, stmt) in enumerate(ir.stmts) - push!(debuginfo.codelocs, i, i, 1) - inst = stmt[:inst] type = stmt[:type] - push!(debuginfo.edges, debuginfo_edge(i, inst, type)) + annotation = type === nothing ? "" : " (inferred type: $type)" + # Work around `show` functions requiring `invokelatest` queries + # that may be problematic to execute from within generated functions. + local inst + try + inst = string(stmt[:inst]) + catch e + isa(e, UndefVarError) && continue + rethrow() + end + filename = Symbol("%$i = $inst", annotation) + lineno = LineNumberNode(1, filename) + stmt[:line] = insert_debuginfo!(ir.debuginfo, i, lineno, stmt[:line]) end end -function debuginfo_edge(i, stmt, type) - annotation = type === nothing ? "" : " (inferred type: $type)" - filename = Symbol("%$i = $stmt", annotation) - codelocs = Int32[1, 0, 0] - compressed = ccall(:jl_compress_codelocs, Any, (Int32, Any, Int), 1#=firstline=#, codelocs, 1) - DebugInfo(filename, nothing, Core.svec(), compressed) -end - function cache_dae_ci!(old_ci, src, debuginfo, abi, owner; rettype=Tuple) mi = old_ci.def edges = Core.svec(old_ci) @@ -101,12 +98,63 @@ function cache_dae_ci!(old_ci, src, debuginfo, abi, owner; rettype=Tuple) return daef_ci end +function replace_call!(ir::Union{IRCode,IncrementalCompact}, idx::SSAValue, @nospecialize(new_call), settings::Settings, source) + replace_call!(ir, idx, new_call) + settings.insert_stmt_debuginfo || return new_call + debuginfo = isa(ir, IncrementalCompact) ? ir.ir.debuginfo : ir.debuginfo + if isa(source, Tuple) + ir[idx][:line] = source + else + maybe_insert_debuginfo!(debuginfo, settings, idx.id, source, ir[idx][:line]) + end + return new_call +end + function replace_call!(ir::Union{IRCode,IncrementalCompact}, idx::SSAValue, @nospecialize(new_call)) @assert !isa(ir[idx][:inst], PhiNode) ir[idx][:inst] = new_call ir[idx][:type] = Any ir[idx][:info] = Compiler.NoCallInfo() ir[idx][:flag] |= Compiler.IR_FLAG_REFINED + return new_call +end + +function maybe_insert_debuginfo!(compact::IncrementalCompact, settings::Settings, source::LineNumberNode, previous = nothing, i = compact.result_idx) + maybe_insert_debuginfo!(compact.ir.debuginfo, settings, i, source, previous) +end + +function maybe_insert_debuginfo!(debuginfo::DebugInfoStream, settings::Settings, i::Integer, source::LineNumberNode, previous) + settings.insert_stmt_debuginfo || return previous + insert_debuginfo!(debuginfo, i, source, previous) +end + +function insert_debuginfo!(debuginfo::DebugInfoStream, i::Integer, source::LineNumberNode, previous) + if previous !== nothing && isa(previous, Tuple) + prev_edge_index, prev_edge_line = previous[2], previous[3] + end + prev_edge = prev_edge_index === nothing ? nothing : get(debuginfo.edges, prev_edge_index, nothing) + edge = new_debuginfo_edge(source, prev_edge, prev_edge_line) + push!(debuginfo.edges, edge) + edge_index = length(debuginfo.edges) + line = Int32.((i, edge_index, 1)) + length(debuginfo.codelocs) ≥ 3i || resize!(debuginfo.codelocs, 3i) + debuginfo.codelocs[3(i - 1) + 1] = line[1] + debuginfo.codelocs[3(i - 1) + 2] = line[2] + debuginfo.codelocs[3(i - 1) + 3] = line[3] + return line +end + +function new_debuginfo_edge((; file, line)::LineNumberNode, prev_edge, prev_edge_line) + if prev_edge !== nothing && prev_edge_line !== nothing + codelocs = Int32[line, 1, prev_edge_line] + edges = Core.svec(prev_edge) + else + codelocs = [line, 0, 0] + edges = Core.svec() + end + firstline = codelocs[1] + compressed = ccall(:jl_compress_codelocs, Any, (Int32, Any, Int), firstline, codelocs, 1) + DebugInfo(@something(file, :none), nothing, edges, compressed) end is_solved_variable(stmt) = isexpr(stmt, :call) && stmt.args[1] == solved_variable || @@ -133,7 +181,7 @@ If doing an ODE, then can put `nothing` for `du` argument as we know it will not If `var_assignment` is `nothing`, all variables are assumed unassigned. In this case `u` and `du` may be `nothing` as well. """ -function replace_if_intrinsic!(compact, ssa, du, u, p, t, var_assignment) +function replace_if_intrinsic!(compact, settings, ssa, du, u, p, t, var_assignment) inst = compact[ssa] stmt = inst[:inst] # Transform references to `Argument(1)` into `p` @@ -161,7 +209,7 @@ function replace_if_intrinsic!(compact, ssa, du, u, p, t, var_assignment) inst[:inst] = GlobalRef(DAECompiler.Intrinsics, :_VARIABLE_UNASSIGNED) else source = in_du ? du : u - replace_call!(compact, ssa, Expr(:call, getindex, source, var_idx)) + replace_call!(compact, ssa, Expr(:call, getindex, source, var_idx), settings, @__SOURCE__) end elseif is_known_invoke_or_call(stmt, sim_time, compact) inst[:inst] = t diff --git a/src/transform/tearing/schedule.jl b/src/transform/tearing/schedule.jl index f5035dc..d9c3a46 100644 --- a/src/transform/tearing/schedule.jl +++ b/src/transform/tearing/schedule.jl @@ -33,41 +33,39 @@ function find_eqs_vars(state::TransformationState) find_eqs_vars(state.structure.graph, compact) end -function ir_add!(compact::IncrementalCompact, line, @nospecialize(_a), @nospecialize(_b)) +function ir_add!(compact::IncrementalCompact, line, settings::Settings, @nospecialize(_a), @nospecialize(_b), source = @__SOURCE__) a, b = _a, _b (b === nothing || b === 0.) && return _a (a === nothing || b === 0.) && return _b - ni = NewInstruction(Expr(:call, +, a, b), Any, line) - z = insert_node_here!(compact, ni) - compact[z][:flag] |= Compiler.IR_FLAG_REFINED - z + idx = insert_instruction_here!(compact, line, settings, source, :($a + $b), Any) + compact[idx][:flag] |= Compiler.IR_FLAG_REFINED + idx end -function ir_mul_const!(compact, line, coeff::Float64, _a) +function ir_mul_const!(compact, line, settings, coeff::Float64, _a, source = @__SOURCE__) if isone(coeff) return _a end - ni = NewInstruction(Expr(:call, *, coeff, _a), Any, line) - z = insert_node_here!(compact, ni) - compact[z][:flag] |= Compiler.IR_FLAG_REFINED - return z + idx = insert_instruction_here!(compact, line, settings, source, :($coeff * $_a), Any) + compact[idx][:flag] |= Compiler.IR_FLAG_REFINED + return idx end Base.IteratorSize(::Type{Compiler.UseRefIterator}) = Base.SizeUnknown() -function schedule_incidence!(compact, curval, ::Type, var, line; vars=nothing, schedule_missing_var! = nothing) +function schedule_incidence!(compact, curval, ::Type, var, line, settings; vars=nothing, schedule_missing_var! = nothing) # This just needs the linear part, which is `0` in `Type` return (curval, nothing) end -function schedule_incidence!(compact, curval, incT::Const, var, line; vars=nothing, schedule_missing_var! = nothing) +function schedule_incidence!(compact, curval, incT::Const, var, line, settings; vars=nothing, schedule_missing_var! = nothing) if curval !== nothing - return (ir_add!(compact, line, curval, incT.val), nothing) + return (ir_add!(compact, line, settings, curval, incT.val, @__SOURCE__), nothing) end return (incT.val, nothing) end -function schedule_incidence!(compact, curval, incT::Incidence, var, line; vars=nothing, schedule_missing_var! = nothing) +function schedule_incidence!(compact, curval, incT::Incidence, var, line, settings; vars=nothing, schedule_missing_var! = nothing) thiscoeff = nothing # We do need to materialize the linear parts of the incidence here @@ -83,11 +81,7 @@ function schedule_incidence!(compact, curval, incT::Incidence, var, line; vars=n isa(coeff, Float64) || continue if lin_var == 0 - lin_var_ssa = insert_node_here!(compact, - NewInstruction( - Expr(:invoke, nothing, Intrinsics.sim_time), - Incidence(0), - line)) + lin_var_ssa = @insert_instruction_here(compact, line, settings, (:invoke)(nothing, Intrinsics.sim_time)::Incidence(0)) else if vars === nothing || !isassigned(vars, lin_var) lin_var_ssa = schedule_missing_var!(lin_var) @@ -99,10 +93,10 @@ function schedule_incidence!(compact, curval, incT::Incidence, var, line; vars=n end end - acc = ir_mul_const!(compact, line, coeff, lin_var_ssa) - curval = curval === nothing ? acc : ir_add!(compact, line, curval, acc) + acc = ir_mul_const!(compact, line, settings, coeff, lin_var_ssa, @__SOURCE__) + curval = curval === nothing ? acc : ir_add!(compact, line, settings, curval, acc, @__SOURCE__) end - (curval, _) = schedule_incidence!(compact, curval, incT.typ, var, line; vars, schedule_missing_var!) + (curval, _) = schedule_incidence!(compact, curval, incT.typ, var, line, settings; vars, schedule_missing_var!) return (curval, thiscoeff) end @@ -129,7 +123,7 @@ is_const_plus_var_known_linear(incT::Const) = true is_fully_state_linear(incT, param_vars) = is_const_plus_var_known_linear(incT) && is_fully_state_linear(incT.typ, param_vars) is_fully_state_linear(incT::Const, param_vars) = iszero(incT.val) -function schedule_nonlinear!(compact, param_vars, var_eq_matching, ir, ordinal, val::Union{SSAValue, Argument}, ssa_rename::AbstractVector{Any}; vars, schedule_missing_var! = nothing) +function schedule_nonlinear!(compact, settings, param_vars, var_eq_matching, ir, ordinal, val::Union{SSAValue, Argument}, ssa_rename::AbstractVector{Any}; vars, schedule_missing_var! = nothing) isa(val, Argument) && return vars[idnum(argextype(val, ir))] if isassigned(ssa_rename, val.id) @@ -185,7 +179,7 @@ function schedule_nonlinear!(compact, param_vars, var_eq_matching, ir, ordinal, if isa(typ, Const) this_nonlinear = nothing elseif !is_const_plus_var_known_linear(typ::Incidence) - this_nonlinear = schedule_nonlinear!(compact, param_vars, var_eq_matching, ir, ordinal, arg, ssa_rename; vars, schedule_missing_var!) + this_nonlinear = schedule_nonlinear!(compact, settings, param_vars, var_eq_matching, ir, ordinal, arg, ssa_rename; vars, schedule_missing_var!) else if @isdefined(result) # This relies on the flattening transform @@ -201,7 +195,7 @@ function schedule_nonlinear!(compact, param_vars, var_eq_matching, ir, ordinal, return this_nonlinear end - argval = schedule_incidence!(compact, this_nonlinear, typ, -1, inst[:line]; vars, schedule_missing_var!)[1] + argval = schedule_incidence!(compact, this_nonlinear, typ, -1, inst[:line], settings; vars, schedule_missing_var!)[1] if argval === nothing display(ir) end @@ -215,7 +209,7 @@ function schedule_nonlinear!(compact, param_vars, var_eq_matching, ir, ordinal, end if is_const_plus_var_known_linear(incT) - ret = schedule_incidence!(compact, nothing, info.result.extended_rt, -1, inst[:line]; vars= + ret = schedule_incidence!(compact, nothing, info.result.extended_rt, -1, inst[:line], settings; vars= [arg === nothing ? 0.0 : arg for arg in args], schedule_missing_var! = var->error((var, incT, args)))[1] else new_stmt = copy(stmt) @@ -232,7 +226,7 @@ function schedule_nonlinear!(compact, param_vars, var_eq_matching, ir, ordinal, new_stmt.args[i] = arg end - ret = insert_node_here!(compact, NewInstruction(inst; stmt=new_stmt)) + ret = insert_instruction_here!(compact, settings, @__SOURCE__, NewInstruction(inst; stmt=new_stmt)) end ssa_rename[val.id] = isa(ret, SSAValue) ? CarriedSSAValue(ordinal, ret.id) : ret @@ -714,7 +708,7 @@ function tearing_schedule!(state::TransformationState, ci::CodeInstance, key::To mss = StateSelection.MatchedSystemStructure(result, structure, var_eq_matching) (eq_orders, callee_schedules) = compute_eq_schedule(key, total_incidence, result, mss) - ir = index_lowering_ad!(state, key) + ir = index_lowering_ad!(state, key, settings) ir = Compiler.sroa_pass!(ir, Compiler.InliningState(DummyOptInterp(world))) ir = Compiler.compact!(ir) @@ -751,8 +745,7 @@ function tearing_schedule!(state::TransformationState, ci::CodeInstance, key::To var_sols = Vector{Any}(undef, length(structure.var_to_diff)) for (idx, var) in enumerate(key.param_vars) - var_sols[var] = insert_node_here!(compact, - NewInstruction(Expr(:call, getfield, Argument(1), idx), Any, line)) + var_sols[var] = @insert_instruction_here(compact, line, settings, getfield(Argument(1), idx)::Any) end carried_states = Dict{StructuralSSARef, Any}() @@ -883,7 +876,7 @@ function tearing_schedule!(state::TransformationState, ci::CodeInstance, key::To if isa(callee_codeinst, MethodInstance) callee_codeinst = Compiler.get(Compiler.code_cache(interp), callee_codeinst, nothing) end - callee_result = structural_analysis!(callee_codeinst, world) + callee_result = structural_analysis!(callee_codeinst, world, settings) callee_sicm_ci = tearing_schedule!(callee_result, callee_codeinst, callee_key, world, settings) inst[:type] = Any @@ -900,16 +893,16 @@ function tearing_schedule!(state::TransformationState, ci::CodeInstance, key::To varmap = info.mapping.var_coeffs[var] nonlin = nothing if !is_const_plus_var_known_linear(varmap) - nonlin = schedule_nonlinear!(compact, key.param_vars, var_eq_matching, ir, 0, stmt.args[1+var], sicm_rename; vars=var_sols) + nonlin = schedule_nonlinear!(compact, settings, key.param_vars, var_eq_matching, ir, 0, stmt.args[1+var], sicm_rename; vars=var_sols) end (argval, _) = schedule_incidence!(compact, - nonlin, info.mapping.var_coeffs[var], -1, line; vars=var_sols) + nonlin, info.mapping.var_coeffs[var], -1, line, settings; vars=var_sols) @assert argval !== nothing push!(in_param_vars.args, argval) end - new_stmt.args[2] = insert_node_here!(compact, NewInstruction(inst; stmt=in_param_vars, type=Tuple, flag=UInt32(0))) - sstate = insert_node_here!(compact, NewInstruction(inst; stmt=new_stmt, type=Tuple, flag=UInt32(0))) + new_stmt.args[2] = insert_instruction_here!(compact, settings, @__SOURCE__, NewInstruction(inst; stmt=in_param_vars, type=Tuple, flag=UInt32(0))) + sstate = insert_instruction_here!(compact, settings, @__SOURCE__, NewInstruction(inst; stmt=new_stmt, type=Tuple, flag=UInt32(0))) carried_states[sref] = CarriedSSAValue(0, sstate.id) else carried_states[sref] = isdefined(callee_sicm_ci, :rettype_const) ? callee_sicm_ci.rettype_const : callee_sicm_ci.rettype.instance @@ -964,7 +957,7 @@ function tearing_schedule!(state::TransformationState, ci::CodeInstance, key::To ssa_rename = Vector{Any}(undef, length(result.ir.stmts)) function insert_solved_var_here!(compact1, var, curval, line) - insert_node_here!(compact1, NewInstruction(Expr(:call, solved_variable, var, curval), Nothing, line)) + @insert_instruction_here(compact1, line, settings, solved_variable(var, curval)::Nothing) end isempty(var_schedule) && (var_schedule = Pair{BitSet, BitSet}[BitSet()=>BitSet()]) @@ -986,11 +979,7 @@ function tearing_schedule!(state::TransformationState, ci::CodeInstance, key::To display(result.ir) error("Tried to schedule variable $(lin_var) that we do not have a solution to (but our scheduling should have ensured that we do)") end - var_sols[lin_var] = CarriedSSAValue(ordinal, insert_node_here!(compact1, - NewInstruction( - Expr(:invoke, nothing, Intrinsics.variable), - Incidence(lin_var), - line)).id) + var_sols[lin_var] = CarriedSSAValue(ordinal, (@insert_instruction_here(compact1, line, settings, (:invoke)(nothing, Intrinsics.variable)::Incidence(lin_var)).id)) end end @@ -1006,8 +995,7 @@ function tearing_schedule!(state::TransformationState, ci::CodeInstance, key::To (in_vars, out_eqs) = sched for (idx, var) in enumerate(in_vars) - var_sols[var] = CarriedSSAValue(ordinal, insert_node_here!(compact1, - NewInstruction(Expr(:call, getfield, Argument(2), idx), Any, line)).id) + var_sols[var] = CarriedSSAValue(ordinal, (@insert_instruction_here(compact1, line, settings, getfield(Argument(2), idx)::Any).id)) insert_solved_var_here!(compact1, var, var_sols[var], line) end @@ -1028,16 +1016,16 @@ function tearing_schedule!(state::TransformationState, ci::CodeInstance, key::To nonlin = nothing varmap = info.mapping.var_coeffs[var] if !is_const_plus_var_known_linear(varmap) - nonlin = schedule_nonlinear!(compact1, key.param_vars, var_eq_matching, ir, ordinal, eqinst[:stmt].args[1+var], ssa_rename; vars=var_sols, schedule_missing_var!) + nonlin = schedule_nonlinear!(compact1, settings, key.param_vars, var_eq_matching, ir, ordinal, eqinst[:stmt].args[1+var], ssa_rename; vars=var_sols, schedule_missing_var!) end (argval, _) = schedule_incidence!(compact1, - nonlin, info.mapping.var_coeffs[var], -1, line; vars=var_sols, schedule_missing_var!) + nonlin, info.mapping.var_coeffs[var], -1, line, settings; vars=var_sols, schedule_missing_var!) @assert argval !== nothing push!(in_vars.args, argval) end - in_vars_ssa = insert_node_here!(compact1, NewInstruction(eqinst; stmt=in_vars, type=Tuple)) + in_vars_ssa = insert_instruction_here!(compact1, settings, @__SOURCE__, NewInstruction(eqinst; stmt=in_vars, type=Tuple)) new_stmt = copy(eqinst[:stmt]) resize!(new_stmt.args, 2) @@ -1055,14 +1043,17 @@ function tearing_schedule!(state::TransformationState, ci::CodeInstance, key::To callee_ordinals[eq] = callee_ordinal+1 - this_call = insert_node_here!(compact1, NewInstruction(eqinst; stmt=urs[])) - this_eqresids = insert_node_here!(compact1, NewInstruction(eqinst; stmt=Expr(:call, getfield, this_call, 1), type=Any)) - new_state = insert_node_here!(compact1, NewInstruction(eqinst; stmt=Expr(:call, getfield, this_call, 2), type=Any)) + this_call = insert_instruction_here!(compact1, settings, @__SOURCE__, NewInstruction(eqinst; stmt=urs[])) + + this_eqresids = insert_instruction_here!(compact1, settings, @__SOURCE__, NewInstruction(eqinst; stmt=Expr(:call, getfield, this_call, 1), type=Any)) + + new_state = insert_instruction_here!(compact1, settings, @__SOURCE__, NewInstruction(eqinst; stmt=Expr(:call, getfield, this_call, 2), type=Any)) + carried_states[eq] = CarriedSSAValue(ordinal, new_state.id) for (idx, this_callee_eq) in enumerate(callee_out_eqs) this_eq = callee_eq_mapping[eq][this_callee_eq] - curval = insert_node_here!(compact1, NewInstruction(eqinst; stmt=Expr(:call, getfield, this_eqresids, idx), type=Any)) + curval = insert_instruction_here!(compact1, settings, @__SOURCE__, NewInstruction(eqinst; stmt=Expr(:call, getfield, this_eqresids, idx), type=Any)) push!(eqs[this_eq][2], NewSSAValue(curval.id)) end else @@ -1073,19 +1064,19 @@ function tearing_schedule!(state::TransformationState, ci::CodeInstance, key::To nonlinearssa = nothing if anynonlinear if isa(var, Int) && isa(vars[var], SolvedVariable) - nonlinearssa = schedule_nonlinear!(compact1, key.param_vars, var_eq_matching, ir, ordinal, vars[var].ssa, ssa_rename; vars=var_sols, schedule_missing_var!) + nonlinearssa = schedule_nonlinear!(compact1, settings, key.param_vars, var_eq_matching, ir, ordinal, vars[var].ssa, ssa_rename; vars=var_sols, schedule_missing_var!) else for eqcallssa in eqs[eq][2] if !isa(eqcallssa, NewSSAValue) inst = ir[eqcallssa] - this_nonlinearssa = schedule_nonlinear!(compact1, key.param_vars, var_eq_matching, ir, ordinal, inst[:stmt].args[end], ssa_rename; vars=var_sols, schedule_missing_var!) + this_nonlinearssa = schedule_nonlinear!(compact1, settings, key.param_vars, var_eq_matching, ir, ordinal, inst[:stmt].args[end], ssa_rename; vars=var_sols, schedule_missing_var!) line = ir[eqcallssa][:line] else # From getfield from a callee this_nonlinearssa = SSAValue(eqcallssa.id) line = compact1[eqcallssa][:line] end - nonlinearssa = nonlinearssa === nothing ? this_nonlinearssa : ir_add!(compact1, line, this_nonlinearssa, nonlinearssa) + nonlinearssa = nonlinearssa === nothing ? this_nonlinearssa : ir_add!(compact1, line, settings, this_nonlinearssa, nonlinearssa, @__SOURCE__) end mapping = result.eq_callee_mapping[eq] if mapping !== nothing @@ -1097,9 +1088,9 @@ function tearing_schedule!(state::TransformationState, ci::CodeInstance, key::To function schedule_argument(var) vc = callee_info.mapping.var_coeffs[var] is_fully_state_linear(vc, nothing) && return 0. - return schedule_nonlinear!(compact1, key.param_vars, var_eq_matching, ir, ordinal, eqinst[:stmt].args[var+1], ssa_rename; vars=var_sols, schedule_missing_var!) + return schedule_nonlinear!(compact1, settings, key.param_vars, var_eq_matching, ir, ordinal, eqinst[:stmt].args[var+1], ssa_rename; vars=var_sols, schedule_missing_var!) end - nonlinearssa = schedule_incidence!(compact1, nonlinearssa, callee_var_incidence, -1, line; schedule_missing_var! = schedule_argument)[1] + nonlinearssa = schedule_incidence!(compact1, nonlinearssa, callee_var_incidence, -1, line, settings; schedule_missing_var! = schedule_argument)[1] end end end @@ -1111,15 +1102,15 @@ function tearing_schedule!(state::TransformationState, ci::CodeInstance, key::To if isa(var, Int) curval = nonlinearssa - (curval, thiscoeff) = schedule_incidence!(compact1, curval, incT, var, line; vars=var_sols, schedule_missing_var!) + (curval, thiscoeff) = schedule_incidence!(compact1, curval, incT, var, line, settings; vars=var_sols, schedule_missing_var!) @assert isa(thiscoeff, Float64) - curval = ir_mul_const!(compact1, line, 1/thiscoeff, curval) + curval = ir_mul_const!(compact1, line, settings, 1/thiscoeff, curval, @__SOURCE__) var_sols[var] = isa(curval, SSAValue) ? CarriedSSAValue(ordinal, curval.id) : curval insert_solved_var_here!(compact1, var, curval, line) else curval = nonlinearssa - (curval, thiscoeff) = schedule_incidence!(compact1, curval, incT, -1, line; vars=var_sols, schedule_missing_var!) - insert_node_here!(compact1, NewInstruction(Expr(:call, InternalIntrinsics.contribution!, eq, Explicit, curval), Nothing, line)) + (curval, thiscoeff) = schedule_incidence!(compact1, curval, incT, -1, line, settings; vars=var_sols, schedule_missing_var!) + @insert_instruction_here(compact1, line, settings, InternalIntrinsics.contribution!(eq, Explicit, curval)::Nothing) end end end @@ -1129,7 +1120,7 @@ function tearing_schedule!(state::TransformationState, ci::CodeInstance, key::To for eq in out_eqs var = invview(var_eq_matching)[eq] if isa(var, Int) && isa(vars[var], SolvedVariable) - nonlinearssa = schedule_nonlinear!(compact1, key.param_vars, var_eq_matching, ir, ordinal, vars[var].ssa, ssa_rename; vars=var_sols, schedule_missing_var!) + nonlinearssa = schedule_nonlinear!(compact1, settings, key.param_vars, var_eq_matching, ir, ordinal, vars[var].ssa, ssa_rename; vars=var_sols, schedule_missing_var!) else if isempty(eqs[eq][2]) nonlinearssa = nothing @@ -1138,16 +1129,15 @@ function tearing_schedule!(state::TransformationState, ci::CodeInstance, key::To if isa(eqcallssa, NewSSAValue) nonlinearssa = SSAValue(eqcallssa.id) else - nonlinearssa = schedule_nonlinear!(compact1, key.param_vars, var_eq_matching, ir, ordinal, ir[eqcallssa][:stmt].args[3], ssa_rename; vars=var_sols, schedule_missing_var!) + nonlinearssa = schedule_nonlinear!(compact1, settings, key.param_vars, var_eq_matching, ir, ordinal, ir[eqcallssa][:stmt].args[3], ssa_rename; vars=var_sols, schedule_missing_var!) end end end push!(eq_resids.args, nonlinearssa === nothing ? 0.0 : nonlinearssa) end - eq_resid_ssa = isempty(out_eqs) ? () : - insert_node_here!(compact1, NewInstruction(eq_resids, Tuple, - ir[SSAValue(length(ir.stmts))][:line])) + line = ir[SSAValue(length(ir.stmts))][:line] + eq_resid_ssa = isempty(out_eqs) ? () : @insert_instruction_here(compact1, line, settings, eq_resids::Tuple) state_resid = Expr(:call, tuple) resids[ordinal] = (compact1, state_resid, eq_resid_ssa) @@ -1157,16 +1147,10 @@ function tearing_schedule!(state::TransformationState, ci::CodeInstance, key::To sicm_resid_rename = Dict{CarriedSSAValue, Dict{Int, Union{SSAValue, NewSSAValue}}}() for i = length(resids):-1:1 (this_compact, this_resid, eq_resid_ssa) = resids[i] - state_resid_ssa = - insert_node_here!(this_compact, NewInstruction(this_resid, Tuple, - ir[SSAValue(length(ir.stmts))][:line])) - - tup_resid_ssa = - insert_node_here!(this_compact, NewInstruction(Expr(:call, tuple, eq_resid_ssa, state_resid_ssa), Tuple{Tuple, Tuple}, - ir[SSAValue(length(ir.stmts))][:line])) - - insert_node_here!(this_compact, NewInstruction(ReturnNode(tup_resid_ssa), Union{}, - ir[SSAValue(length(ir.stmts))][:line])) + line = ir[SSAValue(length(ir.stmts))][:line] + state_resid_ssa = @insert_instruction_here(this_compact, line, settings, this_resid::Tuple) + tup_resid_ssa = @insert_instruction_here(this_compact, line, settings, tuple(eq_resid_ssa, state_resid_ssa)::Tuple{Tuple, Tuple}) + @insert_instruction_here(this_compact, line, settings, (return tup_resid_ssa)::Union{}) # Rewrite SICM to state references line = this_compact[SSAValue(1)][:line] @@ -1211,8 +1195,8 @@ function tearing_schedule!(state::TransformationState, ci::CodeInstance, key::To debuginfo = Core.DebugInfo(:sicm) sicm_rettype = Tuple{} else - resid_ssa = insert_node_here!(compact, NewInstruction(sicm_resid, Tuple, line)) - insert_node_here!(compact, NewInstruction(ReturnNode(resid_ssa), Union{}, line)) + resid_ssa = @insert_instruction_here(compact, line, settings, sicm_resid::Tuple) + @insert_instruction_here(compact, line, settings, (return resid_ssa)::Union{}) ir_sicm = Compiler.finish(compact) resize!(ir_sicm.cfg.blocks, 1) empty!(ir_sicm.cfg.blocks[1].succs) diff --git a/src/utils.jl b/src/utils.jl index a0ec74a..03d0385 100644 --- a/src/utils.jl +++ b/src/utils.jl @@ -101,31 +101,61 @@ macro defintrmethod(name, fdef) end) end +"Get the current file location as a `LineNumberNode`." +macro __SOURCE__() + return :(LineNumberNode($(__source__.line), $(QuoteNode(__source__.file)))) +end + """ - @insert_node_here compact line make_odefunction(f)::ODEFunction - @insert_node_here compact line make_odefunction(f)::ODEFunction true - @insert_node_here compact line (:invoke)(ci, args...)::Int true - @insert_node_here compact line (return x)::Int true + @insert_instruction_here(compact, line, settings, make_odefunction(f)::ODEFunction) + @insert_instruction_here(compact, line, settings, make_odefunction(f)::ODEFunction true) + @insert_instruction_here(compact, line, settings, (:invoke)(ci, args...)::Int true) + @insert_instruction_here(compact, line, settings, (return x)::Int true) """ -macro insert_node_here(compact, line, ex, reverse_affinity = false) +macro insert_instruction_here(compact, line, settings, ex, reverse_affinity = false) + source = :(LineNumberNode($(__source__.line), $(QuoteNode(__source__.file)))) + return generate_insert_instruction_here(compact, line, settings, ex, source, reverse_affinity) +end + +function generate_insert_instruction_here(compact, line, settings, ex, source, reverse_affinity) isexpr(ex, :(::), 2) || throw(ArgumentError("Expected type-annotated expression, got $ex")) ex, type = ex.args - if isexpr(ex, :call) && isa(ex.args[1], QuoteNode) - # The called "function" is a non-call `Expr` head - ex = Expr(ex.args[1].value, ex.args[2:end]...) - end compact = esc(compact) + settings = esc(settings) line = esc(line) + inst_ex = esc(process_instruction_expr(ex)) type = esc(type) - if isexpr(ex, :return) - inst_ex = :(ReturnNode($(ex.args...))) - else - inst_ex = :(Expr($(QuoteNode(ex.head)), $(ex.args...))) - end - quote - inst = NewInstruction($(esc(inst_ex)), $type, $line) - insert_node_here!($compact, inst, $reverse_affinity) + return :(insert_instruction_here!($compact, $line, $settings, $source, $inst_ex, $type; reverse_affinity = $reverse_affinity)) +end + +function process_instruction_expr(ex) + if isexpr(ex, :call) && isa(ex.args[1], QuoteNode) + # The called "function" is a non-call `Expr` head + ex = Expr(ex.args[1].value, ex.args[2:end]...) end + isa(ex, Symbol) && return ex + isexpr(ex, :return) && return :($ReturnNode($(ex.args...))) + return :(Expr($(QuoteNode(ex.head)), $(ex.args...))) +end + +function insert_instruction_here!(compact::IncrementalCompact, line, settings::Settings, source::LineNumberNode, args...; reverse_affinity::Bool = false) + line = maybe_insert_debuginfo!(compact, settings, source, line, compact.result_idx) + return insert_instruction_here!(compact, line, args...; reverse_affinity) +end + +function insert_instruction_here!(compact::IncrementalCompact, settings::Settings, source::LineNumberNode, inst::NewInstruction; reverse_affinity::Bool = false) + line = maybe_insert_debuginfo!(compact, settings, source, inst.line, compact.result_idx) + inst_with_source = NewInstruction(inst.stmt, inst.type, inst.info, line, inst.flag) + return insert_instruction_here!(compact, inst_with_source; reverse_affinity) +end + +function insert_instruction_here!(compact::IncrementalCompact, line, stmt, @nospecialize(type); reverse_affinity::Bool = false) + inst = NewInstruction(stmt, type, line) + return insert_instruction_here!(compact, inst; reverse_affinity) +end + +function insert_instruction_here!(compact::IncrementalCompact, inst::NewInstruction; reverse_affinity::Bool = false) + return insert_node_here!(compact, inst, reverse_affinity) end """ diff --git a/test/basic.jl b/test/basic.jl index f69b8fd..d904e37 100644 --- a/test/basic.jl +++ b/test/basic.jl @@ -3,6 +3,7 @@ module Basic using Test using DAECompiler using DAECompiler.Intrinsics +using DAECompiler: refresh using Sundials using SciMLBase using OrdinaryDiffEq @@ -24,10 +25,10 @@ sol = solve(DAECProblem(oneeq!, (1,) .=> 1.), IDA()) sol = solve(ODECProblem(oneeq!, (1,) .=> 1.), Rodas5(autodiff=false)) @test all(map((x,y)->isapprox(x[], y, atol=1e-2), sol.u[:, 1], exp.(sol.t))) -# Cover the `debuginfo` rewrite. -sol = solve(DAECProblem(oneeq!, (1,) .=> 1., insert_stmt_debuginfo = true), IDA()) +# Cover the `debuginfo` rewrites. +sol = solve(DAECProblem(oneeq!, (1,) .=> 1., insert_stmt_debuginfo = true, insert_ssa_debuginfo = true), IDA()) @test all(map((x,y)->isapprox(x[], y, atol=1e-2), sol.u[:, 1], exp.(sol.t))) -sol = solve(ODECProblem(oneeq!, (1,) .=> 1., insert_stmt_debuginfo = true), Rodas5(autodiff=false)) +sol = solve(ODECProblem(oneeq!, (1,) .=> 1., insert_stmt_debuginfo = true, insert_ssa_debuginfo = true), Rodas5(autodiff=false)) @test all(map((x,y)->isapprox(x[], y, atol=1e-2), sol.u[:, 1], exp.(sol.t))) #= + parameterized =# diff --git a/test/debugging.jl b/test/debugging.jl index 9bb4cc4..0d4077b 100644 --- a/test/debugging.jl +++ b/test/debugging.jl @@ -3,6 +3,7 @@ module Debugging using Test using DAECompiler using DAECompiler.Intrinsics +using InteractiveUtils: @code_typed using Sundials using SciMLBase using OrdinaryDiffEq @@ -26,24 +27,52 @@ end bt = catch_backtrace() end @test isa(exc, BoundsError) - buffer = IOBuffer() - Base.show_backtrace(buffer, bt) - output = String(take!(seekstart(buffer))) - @test contains(output, "inferred type: SubArray{Float64") + output = sprint(Base.show_backtrace, bt) + @test contains(output, "inferred type: SubArray{Float64") # insert_ssa_debuginfo end # use a short `u0` to trigger an error and get a stacktrace u0 = Float64[0.0] - settings = DAECompiler.Settings(; mode = DAECompiler.ODENoInit, insert_stmt_debuginfo = true) + settings = DAECompiler.Settings(; mode = DAECompiler.ODENoInit, insert_ssa_debuginfo = true) odef, _ = DAECompiler.factory(Val(settings), twoeq!) prob = ODEProblem(odef, u0, (0.0, 1.0)) test_stmt_debuginfo(() -> solve(prob, Rodas5())) - settings = DAECompiler.Settings(; mode = DAECompiler.DAENoInit, insert_stmt_debuginfo = true) + settings = DAECompiler.Settings(; mode = DAECompiler.DAENoInit, insert_ssa_debuginfo = true) daef, differential_vars = DAECompiler.factory(Val(settings), twoeq!) prob = DAEProblem(daef, u0, u0, (0.0, 1.0)) test_stmt_debuginfo(() -> solve(prob, IDA())) end; +@testset "`DebugInfo`" begin + settings = DAECompiler.Settings(; mode = DAECompiler.ODENoInit, insert_ssa_debuginfo = true) + odef, _ = DAECompiler.factory(Val(settings), twoeq!) + src = first(@code_typed debuginfo=:source odef.f(Float64[], Float64[], SciMLBase.NullParameters(), 1.0)) + output = sprint(show, src) + @test contains(output, "inferred type:") + + settings = DAECompiler.Settings(; mode = DAECompiler.DAENoInit, insert_ssa_debuginfo = true) + daef, _ = DAECompiler.factory(Val(settings), twoeq!) + src = first(@code_typed debuginfo=:source daef.f(Float64[], Float64[], Float64[], SciMLBase.NullParameters(), 1.0)) + output = sprint(show, src) + @test contains(output, "inferred type:") + + settings = DAECompiler.Settings(; mode = DAECompiler.ODENoInit, insert_stmt_debuginfo = true) + odef, _ = DAECompiler.factory(Val(settings), twoeq!) + src = first(@code_typed debuginfo=:source odef.f(Float64[], Float64[], SciMLBase.NullParameters(), 1.0)) + output = sprint(show, src) + @test contains(output, "test/debugging.jl") && contains(output, "twoeq!") + @test contains(output, "ode_factory.jl") + @test contains(output, "intrinsics.jl") && contains(output, "continuous") + + settings = DAECompiler.Settings(; mode = DAECompiler.DAENoInit, insert_stmt_debuginfo = true) + daef, _ = DAECompiler.factory(Val(settings), twoeq!) + src = first(@code_typed debuginfo=:source daef.f(Float64[], Float64[], Float64[], SciMLBase.NullParameters(), 1.0)) + output = sprint(show, src) + @test contains(output, "test/debugging.jl") && contains(output, "twoeq!") + @test contains(output, "dae_factory.jl") + @test contains(output, "intrinsics.jl") && contains(output, "continuous") +end; + end