# Can output of one kernel be called from another on the same PC?

I have two instances of Mathematica running on the same PC. Can I call the output of one from the other?

For example if Out[100] is on kernel1 how do I refer to it on kernel2?

Update

This answer doesn't require the remote kernel to do anything, in contrast I believe to the linked answers as well as @b3m2a1's answer. For example, if the remote kernel is computing something, it will not be able to send results to the inspecting kernel.

(multiple Mathematica sessions)

If you indeed have multiple Mathematica sessions, then the Front End will not have access to both kernels. In this case you may use the Channel or Socket frameworks to communicate between the kernels, but I won't bother with this unless the question is clarified.

Also, I cleaned up the function a bit, so that it is simpler, and so that it can work with arbitrary expressions (not just Out).

SetAttributes[RemoteValue, HoldFirst]
RemoteValue[expr_, kernel_] := Uncompress @ First @ FrontEndExecute @ ExportPacket[
BoxData @ DynamicBox[Compress @ expr, Evaluator->kernel],
"PlainText"
]


And, the same example as before:

RemoteValue[Out[28], "Local 2"]
% + 1


1596

1597

There is probably a much simpler method, but here is one possibility:

RemoteValue[line_, kernel_] := Uncompress @ First @ FrontEndExecute @ ExportPacket[
Cell[
BoxData @ ToBoxes @ Dynamic[Compress @ Out[line], Evaluator -> kernel],
"Output"
],
"PlainText"
]


It's hard to simulate multiple kernels in an answer, but this is what I get when I use the above:

RemoteValue[28, "Local 2"]
% + 1


1596

1597

where the input in the "Local 2" kernel was 798 2, and the second line shows that the actual value is available.

Another possibility if you just want to see the output is to use Dynamic:

r = Dynamic[Out[28], Evaluator->"Local 2"]


1596

but in this case the actual value is not available:

Head @ r


Dynamic

• Clever to use the boxes as a transfer protocol. There ought to be a way to make a single call into something like MathLinkCallFrontEndHeld[FrontEndValue["expr"]] I feel and specify the Evaluator... – b3m2a1 Dec 6 at 5:44

### Update

Here's how we'd do this for your case specifically. Assuming we created and connected a tunnel called "shuttle". First we do this on kernel 1:

TunnelWrite["shuttle", Evaluate@Out[32]]


And then on kernel 2:

TunnelRead["shuttle", Hold]

{Hold[{1, 2, 3, 9}]}


The hold is optional. I just added it for flavor.

### Original

Here's another option that works directly at the MathLink level and so has more efficient data transport.

I wrote a layer or five on top of LinkCreate and friends to help ease some of the dangers and difficulties of using Links for inter-kernel communication.

The package is called KernelTunnels. Here's an example:

We can see I create a tunnel with TunnelCreate in the first kernel (just a link+metadata) called "shuttle". The tunnel data is written to a temporary .mx file so as to allow good unified interprocess communication.

In the second kernel I then connect to the same tunnel with TunnelConnect. At this point the two are attached to each other and can communicate freely.

TunnelWrite will write to the LinkObject and TunnelRead will drain everything off the link, wrapping it in the head passed as the second argument first. Note that TunnelWrite writes the unevaluated expression by default, so you'll need to use Evaluate if you want to circumvent this behavior.

There's also some stuff in there for adding handlers for TunnelRead (it can be different on both ends).

If this is useful I can properly document the API, but these functions are the heart of it.

• Doesn't OP mean two MMAs as opposed to two kernels under the same FE? – Kuba Dec 6 at 8:00
• Unclear...that case is just fundamentally impossible without dumping to disk, though, I think. Although LinkConnect might work just without the shared memory argument. – b3m2a1 Dec 6 at 8:47