Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature request: support @showprogress for function type #116

Open
johnnychen94 opened this issue Oct 15, 2018 · 1 comment
Open

Feature request: support @showprogress for function type #116

johnnychen94 opened this issue Oct 15, 2018 · 1 comment

Comments

@johnnychen94
Copy link
Sponsor Contributor

johnnychen94 commented Oct 15, 2018

Currently, @showprogress doesn't work for functions, e.g.,

function foo(n)
    for i in 1:n
        sleep(0.1)
    end
end
@showprogress foo(50) # The ideal usage, doesn't work

Why we need this?

  • In some situations one does need a silent execution, and in some situations one doesn't.
  • Some package authors don't intend to give any additional execution information other than the results

At present, we could manually do something like this... Not complicated, but this requires some document reading, and when the real kernel function is nested deeply, this requires a bunch of modifications on the APIs.

function foo(n; quite = true)
    p = quite ? nothing : Progress(n)
    for i in 1:n
        sleep(0.1)
        quite ? nothing : next!(p)
    end
end

Take the case of this foo, I think the reason @showprogress won't work for this is because we can't directly get the definition of foo when calling it so that unable to parse the expression. (Ref: JuliaLang/julia#2625, JuliaLang/julia#24347)


I'm wondering if the following alternative procedure is practical to support this feature. (please excuse me for my current status of lacking of experiences in macros, I'm just plotting the general idea)

1. use a @progress macro to generate two functions: a wrapper and a kernel

Let

@progress function foo(n)
    for i in 1:n
        sleep(0.1)
    end
end

generate

function foo_(n)
   quote 
        for i in 1:$n
            sleep(0.1)
        end
    end
end
foo(n) = eval(foo_(n))

By doing this, calling foo(n) is still works as usual -- no Progress is involved. But this gives the possibility to parse the function expressions.

2. write a parser to foo_

Let parse(foo_(50)) returns

quote 
    @showprogress for i in 1:50
        sleep(0.1)
    end
end

3. modify @showprogress to support calling of parse(foo_(50))

let @showprogress foo(50) actually calling eval(parse(foo_(50))), so that this feature is supported


As a summary,

the package author can simply add a @progress notation to support the feature

@progress function foo(n)
# some definitions...
end

and the package user uses @showprogress notation to plot progress

@showprogress foo(50)

This's a solution I think is possible. However, since I'm currently not very familiar with macro writing, I'm not very sure of it.

@martinholters
Copy link
Collaborator

I'd propose a slightly different implementation:

@progress function foo(args...)
#...
end

expands to the normal definition of foo and another one, say foo#with_progress with PogressMeter instrumentation added. Then @showprogress foo(50) just becomes foo#with_progress(50) (possibly with some code to check foo#with_progress is defined provide a useful error message if not.)

Note that this (like the original proposal) solves

  • In some situations one does need a silent execution, and in some situations one doesn't.

but does not solve

  • Some package authors don't intend to give any additional execution information other than the results

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants