Giter Club home page Giter Club logo

Comments (10)

ChrisRackauckas avatar ChrisRackauckas commented on August 17, 2024

This is not a good test case for it. Or at least the title is not correct. Julia's dead code elimination is performed at the lock level. So if you want to determine what code is actually run you need to check the post optimization llvm. But llvm's dce is very robust so I would be surprised if there is a problem there.

Now your example would not dce because your code mutates a global and thus the compiler is not allowed to delete that as it would clearly change the code behavior. So your test case, if changed to not have a side effect, would get erased in the llvm layer

But finally, it isn't optimal to drop all of the observed in there and rely on dce. While it would make 0 difference in runtime, it could make a difference in compile time. It would be good to actually measure that and see if it's an noticable effect. Since dce is prior to the most expensive passes I would be surprised if that was the case though

from modelingtoolkit.jl.

ctessum avatar ctessum commented on August 17, 2024

Does this work as a test case:

function f(t)
    @info "evaluating unnecessary observed function"
    return sin(t)
end

It gives a similar result, printing 9 lines of log messages.

from modelingtoolkit.jl.

ChrisRackauckas avatar ChrisRackauckas commented on August 17, 2024

No, logging is again mutating a global so DCE is not allowed to delete it since it would change how code is run. It would have to be something like

julia> function f(t)
           a = 1+1
           return sin(t)
       end
f (generic function with 1 method)

julia> @code_llvm(f(1.0))
;  @ REPL[4]:1 within `f`
; Function Attrs: uwtable
define double @julia_f_1898(double %0) #0 {
top:
;  @ REPL[4]:3 within `f`
  %1 = call double @j_sin_1900(double %0)
  ret double %1
}

You can see DCE removed the extraneous computation in the LLVM.

from modelingtoolkit.jl.

ctessum avatar ctessum commented on August 17, 2024

OK, I see the miscommunication here. The problem that I have is not that there is extraneous code running in the function, it's that that function is running at all. So, in other words, the desired behavior in this case would be that f(t) is never called, because the variable on the right-hand-side of that equation, y, is never used for anything.

from modelingtoolkit.jl.

ChrisRackauckas avatar ChrisRackauckas commented on August 17, 2024

That will be deleted by DCE though, so it won't be actually called. Can you show me the LLVM where it's called and it's not needed?

from modelingtoolkit.jl.

ctessum avatar ctessum commented on August 17, 2024
using ModelingToolkit, DifferentialEquations
using ModelingToolkit: t_nounits as t, D_nounits as D
using Test
using InteractiveUtils

@variables x(t)=1 y(t)=1

function f(t)
    return sin(t)
end
@register_symbolic f(t)

@named sys = ODESystem([
    D(x) ~ 1,
    y ~ f(t)
], t)

sys = structural_simplify(sys)

prob = ODEProblem(sys, [], (0.0, 1.0), [])

@code_llvm(prob.f([0.0, 0.0], 0.0, 0.0))
;  @ within `ODEFunction`
define nonnull {}* @julia_ODEFunction_3351({ [1 x i8], { { i64, {}*, { {}*, i8, {}*, {}*, {}*, {}*, {}*, i32 }, {}*, {}*, {}*, {}*, {}*, {}*, {}*, {}*, {}*, {}*, {}*, {}*, {}*, {}*, {}*, {}*, {}*, {}*, {}*, {}*, {}*, {}*, {}*, {}*, {}*, {}*, {}*, {}*, i8, {}*, {}*, {}*, {}*, {}* }, {}*, i8, i8, {}* }, { i64, {}*, { {}*, i8, {}*, {}*, {}*, {}*, {}*, i32 }, {}*, {}*, {}*, {}*, {}*, {}*, {}*, {}*, {}*, {}*, {}*, {}*, {}*, {}*, {}*, {}*, {}*, {}*, {}*, {}*, {}*, {}*, {}*, {}*, {}*, {}*, {}*, {}*, i8, {}*, {}*, {}*, {}*, {}* } }* nocapture noundef nonnull readonly align 8 dereferenceable(736) %0, {}* noundef nonnull align 16 dereferenceable(40) %1, double %2, double %3) #0 {
top:
; ┌ @ .julia/packages/ModelingToolkit/3AmNp/src/systems/diffeqs/abstractodesystem.jl:335 within `f`
; │┌ @/.julia/packages/RuntimeGeneratedFunctions/M9ZX8/src/RuntimeGeneratedFunctions.jl:150 within `RuntimeGeneratedFunction`
; ││┌ @ none within `generated_callfunc`
; │││┌ @ none within `macro expansion` @ /RuntimeGeneratedFunctions/M9ZX8/src/RuntimeGeneratedFunctions.jl:163 @ .julia/packages/SymbolicUtils/EGhOJ/src/code.jl:375
; ││││┌ @ /test.jl:8 within `f`
       %4 = call double @j_sin_3353(double %2)
; ││││└
; ││││ @ none within `macro expansion` @ /.julia/packages/RuntimeGeneratedFunctions/M9ZX8/src/RuntimeGeneratedFunctions.jl:163 @ /.julia/packages/SymbolicUtils/EGhOJ/src/code.jl:468
; ││││┌ @ /.julia/packages/SymbolicUtils/EGhOJ/src/code.jl:498 within `create_array`
; │││││┌ @ array.jl:163 within `vect`
; ││││││┌ @ boot.jl:477 within `Array`
         %5 = call nonnull {}* inttoptr (i64 4315363904 to {}* ({}*, i64)*)({}* inttoptr (i64 4762507712 to {}*), i64 1)
; ││││││└
; ││││││ @ array.jl:165 within `vect`
; ││││││┌ @ array.jl:1026 within `__inbounds_setindex!`
         %6 = bitcast {}* %5 to double**
         %arrayptr4 = load double*, double** %6, align 8
         store double 1.000000e+00, double* %arrayptr4, align 8
; ││││└└└
; ││││ @ none within `macro expansion`
      ret {}* %5
; └└└└

from modelingtoolkit.jl.

ctessum avatar ctessum commented on August 17, 2024

It's the %4 = call double @j_sin_3353(double %2), right?

from modelingtoolkit.jl.

ChrisRackauckas avatar ChrisRackauckas commented on August 17, 2024

Try @code_llvm optimize=true f(x)

from modelingtoolkit.jl.

ctessum avatar ctessum commented on August 17, 2024

Still there:

@code_llvm optimize=true prob.f([0.0, 0.0], 0.0, 0.0)
  @ //.julia/packages/SciMLBase/hq1ku/src/scimlfunctions.jl:2299 within `ODEFunction`
define nonnull {}* @julia_ODEFunction_2895({ [1 x i8], { { i64, {}*, { {}*, i8, {}*, {}*, {}*, {}*, {}*, i32 }, {}*, {}*, {}*, {}*, {}*, {}*, {}*, {}*, {}*, {}*, {}*, {}*, {}*, {}*, {}*, {}*, {}*, {}*, {}*, {}*, {}*, {}*, {}*, {}*, {}*, {}*, {}*, {}*, i8, {}*, {}*, {}*, {}*, {}* }, {}*, i8, i8, {}* }, { i64, {}*, { {}*, i8, {}*, {}*, {}*, {}*, {}*, i32 }, {}*, {}*, {}*, {}*, {}*, {}*, {}*, {}*, {}*, {}*, {}*, {}*, {}*, {}*, {}*, {}*, {}*, {}*, {}*, {}*, {}*, {}*, {}*, {}*, {}*, {}*, {}*, {}*, i8, {}*, {}*, {}*, {}*, {}* } }* nocapture noundef nonnull readonly align 8 dereferenceable(736) %0, {}* noundef nonnull align 16 dereferenceable(40) %1, double %2, double %3) #0 {
top:
; ┌ @ /.julia/packages/ModelingToolkit/3AmNp/src/systems/diffeqs/abstractodesystem.jl:335 within `f`
; │┌ @ /.julia/packages/RuntimeGeneratedFunctions/M9ZX8/src/RuntimeGeneratedFunctions.jl:150 within `RuntimeGeneratedFunction`
; ││┌ @ none within `generated_callfunc`
; │││┌ @ none within `macro expansion` @ //.julia/packages/RuntimeGeneratedFunctions/M9ZX8/src/RuntimeGeneratedFunctions.jl:163 @ /.julia/packages/SymbolicUtils/EGhOJ/src/code.jl:375
; ││││┌ @ /test.jl:9 within `f`
       %4 = call double @j_sin_2897(double %2)
; ││││└
; ││││ @ none within `macro expansion` @ /.julia/packages/RuntimeGeneratedFunctions/M9ZX8/src/RuntimeGeneratedFunctions.jl:163 @ /.julia/packages/SymbolicUtils/EGhOJ/src/code.jl:468
; ││││┌ @ /.julia/packages/SymbolicUtils/EGhOJ/src/code.jl:498 within `create_array`
; │││││┌ @ array.jl:163 within `vect`
; ││││││┌ @ boot.jl:477 within `Array`
         %5 = call nonnull {}* inttoptr (i64 4353620544 to {}* ({}*, i64)*)({}* inttoptr (i64 4800764352 to {}*), i64 1)
; ││││││└
; ││││││ @ array.jl:165 within `vect`
; ││││││┌ @ array.jl:1026 within `__inbounds_setindex!`
         %6 = bitcast {}* %5 to double**
         %arrayptr4 = load double*, double** %6, align 8
         store double 1.000000e+00, double* %arrayptr4, align 8
; ││││└└└
; ││││ @ none within `macro expansion`
      ret {}* %5
; └└└└
}

from modelingtoolkit.jl.

ChrisRackauckas avatar ChrisRackauckas commented on August 17, 2024

@gbaraldi is this because we cannot prove sin doesn't have side effects? I thought the effects system would have solved that?

from modelingtoolkit.jl.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.