pátek 21. března 2025

Remote kernels - when having multiple network interfaces

For Mathematica Kernels Version 13 and later

kernel = KernelConfiguration["ssh://192.168.213.7", 
     "KernelCommand" -> "/opt/Wolfram/Mathematica/13.1/Executables/MathKernel",
     "KernelCount" -> 10]

Remote kernels

LaunchKernels[kernel];
ParallelEvaluate[{$KernelID, $MachineName, $Version}]

Local kernels

LaunchKernels[4];
ParallelEvaluate[{$KernelID, $MachineName, $Version}] 

Close remote kernels and then close all kernels.

$KernelCount
CloseKernels["RemoteKernels"];
$KernelCount
CloseKernels[]; $KernelCount

For Mathematica Kernels Before Version 13

The Mathematica kernel uses SSH to start the remote kernel by providing the local IP address and two randomly selected ports. These values are passed to the remote kernel(s) as command-line parameters. The remote kernel then attempts to connect back to the specified address and ports.

This setup works only if:

  1. The required ports are open on the firewall.
  2. The local IP address is accessible from the remote machine.

The main difficulty arises when the local machine has multiple IP addresses. In such cases, it is not possible to specify which IP address Mathematica should use for the link, the FrontEnd simly selects one. Then, for example, the address used by local virtual machines (e.g., 192.168.120.xx/24) may not be accessible from the remote machine.

However, it appears that the Mathematica front end selects the IP address of the last interface (alphabetically) when sorted. For instance, if you have:

  • eth1 with 10.0.0.1
  • wifi0 with 192.168.0.2

Then the remote kernel will be launched like this:

ssh 10.0.0.2 MathKernel ... -linkname 46683@192.168.0.2,34039@192.168.0.2 -subkernel

—even though there’s no reason to expect that the remote machine (10.0.0.2) has a route to your local Wi-Fi network.

Solutions (Root Access Required on Local or Remote Machine)

1) [Untested] Add a Route on the Remote Machine

ip route add 192.168.0.1 via 10.0.0.1

2) Rename Interfaces so the Desired One is Last Alphabetically

When running the remote kernel through a VPN (e.g., WireGuard), this renaming can be quite simple.

Alternative: Use a Virtual Interface Bound to a Specific IP

If your connection has multiple IP addresses, you can assign one of them to a dedicated virtual interface using macvlan. This allows you to control how Mathematica selects the IP.

Original State:
3: eno1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether xx:f6:4b brd ff:ff:ff:ff:ff:ff
    altname enp0s31f6
    inet 1.2.3.4/23 brd 1.2.3.255 scope global eno1
       valid_lft forever preferred_lft forever
    inet 192.168.214.5/24 brd 192.168.214.255 scope global eno1
       valid_lft forever preferred_lft forever
Then run:
ip addr del 192.168.214.5/24 dev eno1
ip link add zz1 link eno1 type macvlan mode bridge
ip addr add 192.168.214.5/24 dev zz1
ip link set zz1 up
Resulting Configuration:
3: eno1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether xx:f6:4b brd ff:ff:ff:ff:ff:ff
    altname enp0s31f6
    inet 1.2.3.4/23 brd 1.2.3.255 scope global eno1
       valid_lft forever preferred_lft forever

9: zz1@eno1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether xx:b9:ec brd ff:ff:ff:ff:ff:ff
    inet 192.168.214.5/24 scope global zz1
       valid_lft forever preferred_lft forever

Finally, open the firewall — and voilà!

The code for /etc/network/interfaces

auto zz1
iface zz1 inet static
	address 192.168.214.5/24
        pre-up ip link add zz1 link eno1 type macvlan mode bridge
        post-down ip link delete zz1
#	post-up iptables -A INPUT -i zz1@eno1 -s 192.168.214.5/24 -j ACCEPT

středa 23. srpna 2017

CUDA and Mathematica setup

Mathematica does not see the (installed) CUDA driver:

1. Find the installed  library
me@comp:~> find /usr/ -name libnvidia-tls.so\*

/usr/lib64/nvidia/libnvidia-tls.so.1
/usr/lib64/nvidia/tls/libnvidia-tls.so.1
/usr/lib64/nvidia/tls/libnvidia-tls.so
/usr/lib64/nvidia/tls/libnvidia-tls.so.375.26
/usr/lib64/nvidia/libnvidia-tls.so.375.26

2.  Explicitly specify location of the nvidia library:

me@comp:~>NVIDIA_DRIVER_LIBRARY_PATH=/usr/lib64/nvidia/tls/libnvidia-tls.so mathematica  

(Thanks to this link )

3. If necessary, add  CUDA_LIBRARY_PATH=/usr/lib64/nvidia/libcuda.so

4. Try to reinstall the CUDA paclet from Wolfram Research server

---------------
comments:
. it seems, that Mma installs its own CUDA toolkit, as a paclet. The system wide cuda toolkit is not necessary

in case of problems: check versions of cuda libraries. Mixing versions is not possible. E.g. mixing packaged (rpm) and compiled drivers will cause problems.

středa 4. prosince 2013

NDSolve - backward difference method

There is always a mess in various names of various numerical methods. Mathematica's NDSolve is a highly sophisticated black box. It is quite difficult to uncover the method which is actually used during computation.
However, here I have example solutions of one equation using default and "Backward Difference Formula" of order 1 (i.e. Implicit Euler) Method. As we will see later, the "default" method in this case is "Backward Difference" of higher order.

eqn=-u0 \[Omega]^2 Sin[t \[Omega]] + (g x[t])/r + 2 b x'[t] + x''[t];
vals = {b -> 0.001, r -> 0.42578125, g -> 9.81, u0 -> 0.01}; 
 
ns1 = NDSolve[{0 == eqn /. vals /. \[Omega] -> 3.14, 
    x[0] == 0.001, x'[0] == 0.001}, x, {t, 0, 200}][[1]];
 
ns2 = NDSolve[{0 == eqn /. vals /. \[Omega] -> 3.14, 
    x[0] == 0.001, x'[0] == 0.001}, x, {t, 0, 200}, 
   Method -> {"BDF", "MaxDifferenceOrder" -> 1}, MaxSteps -> 10^6, 
   PrecisionGoal -> 5, AccuracyGoal -> Automatic][[1]]
 
Plot[{x[t] /. ns1, x[t] /. ns2}, {t, 100, 120}, AspectRatio -> 1/5, 
  ImageSize -> 800, PlotStyle -> {Green,Red}]

Here is the result: green is the default solution, red is the 1st order BDF.

I have a similar plot, where the blue and red curves come from numerical solutions using gsl routines implementing so called Gear's stepping method: gsl_odeiv_step_gear1 and gsl_odeiv_step_gear2 (it seems, that the current version of gsl has abandoned these routines, it uses gsl_odeiv2_step_msbdf instead, see docs). Blue is the second order solution (together with points of accepted solution), red is the fisrt order solution (there was too many small steps to show them). The green line of the "default" Mathematica solution line hides behind the blue "gear2" curve.

StepMonitor and InterpolationFunction

One could assume that InterpolatingFunction resulting from a numerical algorithm like NDSolve would have the same node distribution as the algorithm.
And it seems to be true.

{s, steps} = 
  Reap[NDSolve[{y'[x] == y[x] Cos[x + y[x]], y[0] == 1}, 
    y, {x, 0, .05}, StepMonitor :> Sow[{x, y[x]}][[1]]]];

Needs["DifferentialEquations`InterpolatingFunctionAnatomy`"];
coords = First[InterpolatingFunctionCoordinates[y /. s[[1]]]]
steps[[1, All, 1]]

The both coords and steps give the same values:
{5.13196*10^-6, 0.0000102639, 0.00339028, 0.00677029, 0.0101503, 
0.0151503, 0.0201503, 0.0251503, 0.0301503, 0.0351503, 0.0401503, 
0.0450752, 0.05}

However, the Mesh option of Plot shows another set of points (green):
stpl = ListPlot[steps, 
   PlotStyle -> Directive[PointSize[Large], Red]];
Show[
 Plot[Evaluate[y[x] /. s], {x, 0, .016}, Mesh -> All, 
  MeshStyle -> Directive[PointSize[Medium], Green]], stpl]


And it seems that the Mesh directive has no connection with the structure of InterpolatingFunction. Let's make larger Plot and cut of a part which corresponds to the previous figure:
stpl = ListPlot[steps, 
   PlotStyle -> Directive[PointSize[Large], Red]];
Show[
 Plot[Evaluate[y[x] /. s], {x, 0, .05}, Mesh -> All, 
  MeshStyle -> Directive[PointSize[Large], Green]], stpl, 
 PlotRange -> {{0, 0.016}, {1, 1.0085}}]

Plot axes labels, legends, fonts etc

Insert text into plot using Epilog command - here y comes to the vertical axis, \omega to horizontal axis and some legend to the right upper corner of the figure:

Epilog -> {
  Text["y", Scaled[{0.05, .95}], Background -> White,
                                 BaseStyle -> {FontSize -> 11, Bold}],
  Text["\[Omega]", Scaled[{0.95, .1}], 
                                 Background -> White, 
                                 BaseStyle -> {FontSize -> 11, Bold}],
  Text["b=" <> ToString[b] <> ",u=" <> ToString[u], 
                        Scaled[.98 {1, 1}], {1, 1}, Background -> White]
 }

Alternatively, use the Text's align feature, but this does not work well at the y axis:
Epilog -> {
  Text[" \[Xi] ", Scaled[{0.025, 1}], {-1, 1.2}, 
   Background -> White],
  Text[" \[Omega] ", Scaled[{1, 0}], 1.2 {1, -1}, Background -> White,
    BaseStyle -> {FontSize -> 14}],
  Text["\[Beta]=" <> 
    ToString[b], Scaled[.98 {1, 1}], {1, 1}, Background -> White]
  }

Setting up the default style for texts in Plots:

bst = {FontSize -> 12, 
            FontFamily -> "Helvetica", 
            FontWeight -> Bold, 
            FontSlant -> Italic};
SetOptions[Plot,BaseStyle->bst];
SetOptions[ListPlot,BaseStyle->bst];
SetOptions[Text, BaseStyle -> bst];

Align axes in several plots: It is necessary to manually allocate space for axes labels via , ImagePadding -> {{left, right}, {bottom, top}}
 
{
GraphicsColumn[{Plot[Sin[x], {x, 0, 2 \[Pi]}], 
                Plot[10^-3 Sin[x], {x, 0, 2 \[Pi]}]}],
ip = {{40, 0}, {5, 5}};
GraphicsColumn[{Plot[Sin[x], {x, 0, 2 \[Pi]}, ImagePadding -> ip], 
                Plot[10^-3 Sin[x], {x, 0, 2 \[Pi]}, ImagePadding -> ip]}]
}