-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
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
Allowing driver and worker processes to load different modules #5775
Conversation
Ah, I did just discover that the following works on
So this is not necessary. I guess there's still a question of how easy we can/want to make this kind of thing. I can imagine syntax something like this:
|
I think something like |
It's not quite sufficient on its own, because you get errors like these:
The problem seems to be that the caller's module becomes part of the serialized data sent to the worker, and that name is not defined on the worker. (This is the same issue that forces you to wrap However, I've come up with one solution that seems promising; I've updated the code and even written some tests (which, naturally, demonstrate how to use this version). To me this seems much easier to use than anything yet considered, so I'm reopening. |
The test passed with clang; the gcc error seems to be due to the fact that it didn't even seem to try to get a build started. I didn't find a way to force it to try again. |
I'd use
which creates a new commit identical to the previous one but with a different sha1 (assuming you didn't |
I don't fully see what is not working but in Julietta I use the approach:
When I call the |
@carlobaldassi, thanks for the tip. I will use that in the future. I think I came up with a better name for the macro anyway. @tknopp, not sure I fully understand what you're doing, but what I want to do is the following: process |
Ok I see. And actually I am doing the same and now I understand why my "driver side" cannot be in a module (see https://github.com/tknopp/Julietta.jl/blob/master/src/Julietta.jl line 1,2) So it seems that when you remove the module scope from |
You'd also need to remove the module scope from One thing to note is that your
The fact that there are two warnings is evidence that both know about What I'm shooting for here is the ability to have complete separation. While my motivation was purely to decrease load times, another potential application is that if I have code that I'm not willing to share but willing to let you test-drive, I could open a TCP/IP port on one of my servers and allow you to execute my code remotely. |
Was not aware of that. I thought the module would be only loaded locally and one would need |
@tknopp reminder: |
Mostly a feature, I think. But sometimes you want more fine-grained control. |
…parate code on workers
Ah, now I get it. The entire problem is the reference to the enclosing module that the serialized closure has. The closure needs to be "rebased" on top of Some of the issues can be avoided by avoiding closures. For example Constructs like |
In usage this is proving more fragile than I expected, so if you know how to do this... |
(I keep getting "cannot serialize a pointer" errors, and can't figure out why) |
You need to write a custom serialize/deserialize for one of your types maybe? Like this - https://github.com/JuliaLang/julia/pull/5788/files |
6c7c7e3
to
1a4c02f
Compare
this was one of the hardest parts of tricking the parallel tests into not depending on being run from |
I think we've now addressed some of these points now (with |
On a single machine, I have a driver process that needs to interact with the user; it makes use of several graphics/plotting packages & modules. This driver process delegates its computational work to several worker processes, each of which relies on quite a large number of compute-focused packages & modules. Loading all this code into a single process takes approximately 1 minute, which is a large barrier to entry. But in principle, there's no reason the driver process needs to load the compute packages, and there's no reason the worker processes need to load the graphics packages. So it seems this time could be shaved down quite a bit by some partitioning.
I did some experiments trying to get this working, and with current
master
the strategy I found seems a bit sub-optimal (this PR may improve matters). The main challenge is that the driver needs to call functions inside modules that it knows nothing about. C permits this by allowing you to declare a function without defining it, but I'm not aware of anything similar in Julia. So the solution seems to be to rely oneval
inside ofMain
.With current
master
, here are the various files I needed:Then run this as follows (I'm using
include
to avoid any possible funny business withrequire
loading things on all workers):and you get back
16
.In an ideal world, I'd even put these first two lines inside
MyDriver.main()
; it seems better not to have to bother the user with spawning new processes and loading code on them. But it seems hard to get Glue into MyDriver after-the-fact.With this PR, in addition to
MyWorker.jl
, here's what you need:I don't (yet!) have a good understanding of how
multi.jl
works, so this should be viewed as a first attempt.