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

More flexible module initialization interface #11098

Open
yuyichao opened this issue May 2, 2015 · 5 comments
Open

More flexible module initialization interface #11098

yuyichao opened this issue May 2, 2015 · 5 comments
Labels
Milestone

Comments

@yuyichao
Copy link
Contributor

yuyichao commented May 2, 2015

Currently the runtime-only module initialization is done by defining a single __init__ function in each module. This means that the initialization of a module have to be done in a single function (and file).

However, IMHO, it would be better if the initialization code can be distributed across different position. This can make the organization of the initialization code better (and ppl are already inventing their own way to achieve this in packages e.g. in Nettle.jl).
This should also help macros (or otherwise generated code) to use this function. For example, the deps.jl generated by BinDeps checks the existance of the library as well as returning the path to the library. One of the function (returning the path) needs to be done at compile time while the other needs to be done at runtime. It is probably possible in this case for BinDeps to define a initialization hook to be called by user's __init__ but it can make things much more complicated and such workaround would be hard to implement for a macro.

IMHO this interface can be similar to atexit or atreplinit (i.e. define a function in each module to register the initialization function) or similar to @inline or @generated (to mark the function as a initializer).

@yuyichao yuyichao changed the title For flexible module initialization interface More flexible module initialization interface May 2, 2015
@vtjnash
Copy link
Member

vtjnash commented May 2, 2015

BinDeps provides the flexibility to define an initialization hook (https://github.com/JuliaLang/Gtk.jl/blob/8318ad3481acf30cf4ccecc2f984a27f8ce324a5/deps/build.jl#L42-L51)

i think my only question with an atinit-like function is whether it is possible to run these checks in an arbitrary order, and if not, what order should they run

@yuyichao
Copy link
Contributor Author

yuyichao commented May 2, 2015

AFAICT @checked_lib is not using an initialization hook so that check will always be done at compile time and therefore the preload can only be run a compile time as well. I also didn't find a way to add hooks for system libs.

I think the order to run them should be same with the order they are registered since this is the order they will be run if they were just normal code. If a init hook is registered after the initialization of a module, it should be run immediately so that the author of macros/generated code don't have to deal with this situation..

@cstjean
Copy link
Contributor

cstjean commented Apr 7, 2016

+1 to this. There would be a number of use-cases in PyCall.jl. Common Lisp has eval-when, and while it's not pretty, it does the job.

@timholy
Copy link
Member

timholy commented Apr 8, 2016

See also JuliaImages/Images.jl#443.

@StefanKarpinski StefanKarpinski added this to the 0.6.0 milestone Sep 13, 2016
@StefanKarpinski StefanKarpinski modified the milestones: 1.0, 0.6.0 Dec 15, 2016
@JeffBezanson JeffBezanson modified the milestones: 2.0+, 1.0 May 10, 2017
@simonbyrne
Copy link
Contributor

This would be really useful for a couple of cases I'm working on:

In MPI.jl, I'd like to have a mechanism where package develoers can declare custom MPI datatypes in their own modules, and have it auto-initialize when the module is loaded:

module MyPkg
struct MyType
  ...
end

@mpitype MyType
end

where @mpitype MyType expands to something like

let dt = MPI.Datatype()
   MPI.Datatype(::Type{MyType}) = dt
   atinit() do
      MPI.create!(dt, MyType)
   end
end

Currently there's not a way to do this without requiring package developers to insert hooks into their __init__() functions.

In NVTX.jl, I would like to have a macro which when used returns a module-specific domain, and which is initialized when the module is initialized:

NVTX.@domain

would be something like:

macro domain()
   if !isdefined(__module__, :__nvtx_domain__)
      domain = Domain()
      @eval __module__ begin
          const __nvtx_domain__ = $domain
          atinit() do
               NVTX.init!($domain, $(string(__module__)))
          end
      end
   end
   $__module__.__nvtx_domain__
end

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

Successfully merging a pull request may close this issue.

7 participants