Suppose I want to run Mathematica on a WSL kernel, but use a Windows installation of Mathematica as its front end. (For any purpose that requires a Mathematica installation on Linux, there are still many reasons I might want to do this; if I only have one Mathematica license, for example, or if I need an environment that can access external programs and libraries on both "sides" of the machine at once.) What's the simplest way to achieve this, without having to set up something like an extraneous microserver or manually/with an external script create ssh tunnels between two parts of the same machine?
It turns out that while figuring out the solution is hard (way too little documentation, and what documentation exists dates to around 2006), the solution itself is easy. As such I'm documenting the solution I found here so that I, if nobody else, can find it later.
WolframEngine and install it on WSL, manually run
/usr/local/WolframKernel to activate it with keys found at https://www.wolframcloud.com/users/user-current/activationkeys, and then under
Evaluation > Kernel Configuration Options just
Add a new
Local Machine configuration, with the
Advanced Options field
Arguments to MLOpen set to
-LinkMode Launch -LinkName "wsl -- WolframKernel -wstp" -LinkProtocol TCPIP.
You're done; make a new notebook and select your new kernel configuration under
Evaluation > Notebook's Kernel to use it. (You may need to reboot first to get fancier rendering working.)
Explanation of the above:
First, assuming that you're in the same position I was in where you would really like two copies of Mathematica but only have one license, you should be made aware that Wolfram actually hands out two free Wolfram kernel keys to everyone, under the product name WolframEngine. The major limitation is that WolframEngine includes only the Wolfram kernel; there is no front end beyond an interactive command line, so you're missing out on all the visualization features and so on. However, if you already have a copy of the full program anyway, then this isn't an issue.
For some reason, WolframEngine had issues activating itself on WSL. It clearly had some sort of internet connection (because when it asked for my username and password, it could tell when I got them wrong), but even so, it claimed it
couldn't connect to https://www.wolframcloud.com. As a workaround, following this answer to The Wolfram Kernel must be activated for WolframScript to use it, I got the raw activation keys from https://www.wolframcloud.com/users/user-current/activationkeys, tracked down my actual
WolframKernel executable (it turned out to be under /usr/local/Wolfram), and directly ran that to activate using the key instead.
Once that was done, actually connecting the kernel to the FrontEnd is best done by going to
Evaluation > Kernel Configuration Options,
Adding a new configuration (I named mine
WSL2), and selecting
Local Machine under
Basic Options, but stealing much of the configuration settings from the
Advanced Options of the
Remote Machine configuration. Specifically, under
Advanced Options, in the field
Arguments to MLOpen put
-LinkMode Launch -LinkName "wsl -- WolframKernel -wstp" -LinkProtocol TCPIP
-LinkMode Launchmeans that Mathematica will both launch the kernel and then connect to it. Unlike the Remote Machine version, though (which uses
Listenand ssh), the launched kernel on the WSL side is considered a subprocess of Mathematica; it will show up there in Task Manager and will get automatically closed and cleaned up when Mathematica is closed. Handy for avoiding resource leaks.
-LinkName "wsl -- WolframKernel -wstp"-- In Launch mode, the LinkName pulls double duty as the shell command used to start the kernel -- it's usually used to specify an executable. In our case, our executable is on the Linux subsystem, so we need to use Microsoft's new(ish, as of 2023) feature that allows the
wslcommand to directly invoke Linux-side binaries.
--tells it to use the default shell and pass it all further commands, in this case
WolframKernel -wstp. (Obviously, you'll need to add
WolframKernelto your PATH for this to work.)
-LinkProtocol TCPIP-- Automatically acquires the necessary ports and configures both ends to use them to communicate over TCP/IP; no
tunnel.shrequired or fiddling around with manual configuration required.
- (Optional) Every remote-kernel guide I've managed to find adds the flag
-LinkOptions MLDontInteract, but nobody explains why. I can sort of guess, especially after finding a production server with
MLDontBrowse-- it's something like, "there's no user on the other side so don't bother trying to interact with one" -- but I don't really know for sure, and I'm not in the habit of using options I don't understand, so I've left it out.
- (Optional) I also selected
Append Name to In/Out prompts, because I like being reminded that the kernel isn't where it usually is.
And that's basically it, just use
Evaluation > Notebook's Kernel > WSL2 (or whatever you named it) to use it. For my use case, I was able to use
FindExternalEvaluators to find a python environment that only existed on WSL, and directly use that environment in a way that felt like I was interacting with the Windows side (and not with a fairly primitive X11 setup like most WSL GUIs are at the moment.)
The first time I tried this, fancier rendering like formatted tables or
Plot functions didn't really work -- just made red boxes instead -- but after a reboot or two (and possibly removing the
MLDontInteract option, but I didn't do a controlled test) the connection seems to have sorted itself out.
Hopefully, this will be useful to somebody, but if nothing else it'll be useful to me at some point I'm sure!