JuliaInterop / MATLAB.jl

Calling MATLAB in Julia through MATLAB Engine
MIT License
275 stars 64 forks source link

Multiple sessions doesn't seem to work on Windows #151

Open rcnlee opened 6 years ago

rcnlee commented 6 years ago
using MATLAB
s1 = MSession()
s2 = MSession()
put_variable(s1, :y, 1)
put_variable(s2, :y, 2)
jvalue(get_mvariable(s1, :y)  #output1
jvalue(get_mvariable(s2, :y)  #output2

I'm expecting output1=1 and output2=2. Works on mac. However, it doesn't seem to work on Windows, where I get output1=output2=2.

Anyone know what's going on? I see there's some special handling of persistent sessions for Windows, but it looks like the code should work.

rcnlee commented 6 years ago

This thread seems to suggest that the fix should be opening the dummy persistent session with engOpenSingleUse. However, in the code, I don't see that being called. It looks like it is just calling MSession(0) which uses engOpen. On Windows, this leads to a shared global context.

rcnlee commented 6 years ago

All sessions that use engOpen share a global context. My interest is actually in multiple parallel processes, so it seems like I need engOpenSingleUse for all my MSessions.

musm commented 6 years ago

I'm not sure what is a good solution in this case.

rcnlee commented 6 years ago

I got it to work for parallel processes using engOpenSingleUse for all sessions. However, startup is very very slow. For large jobs, the parallelization still outweighs the startup cost. In thinking about it though, only the global variables are shared. Function calls are still local. So as long as the parallelism only relies on function calls, there is no need to change anything.

rcnlee commented 6 years ago

Maybe just let the user decide by adding a keyword argument to the constructor of the session: MSession(; single_use::Bool=false) and default it to the current behavior.

Myrddinlefou commented 5 years ago

I use julia on windows and I have the same problem.

Did a solution is developped ?

rcnlee commented 5 years ago

I eventually did fine a workaround, although I don't have the exact code with me to check. I believe the workaround was to add a keyword argument single_use to MSession which defaults to false. Then do an if-else on the ccall to eng_open. If single_use is true, call eng_open_single_use, otherwise call eng_open. You might need to adjust the exact arguments in the ccall. Then when you go to use it, start the first sessionwith single_use=false and the other ones with single_use=true.