12
$\begingroup$

I have written a Mathematica script that is to be run periodically on a Raspberry Pi. The code takes about 3 seconds to execute if I test it in a CLI Mathematica session. However, when I execute the script with

wolfram -script script.w > out.csv

it takes more than 10 seconds. The output of the script is a single String three ASCII characters long, so writing output to file does not take a significat part of the time. I thus assume most of the extra time comes from kernel initialization.

I'd like to initialize Mathematica kernel once and then run my script periodically without needing to initialize the kernel every time. Is this possible?


UPDATE

Following the answer from this related question I tried to make it work like this:

mkfifo mmpipe
tail -f mmpipe | wolfram -noprompt &

However, when I pipe a command that contains a file-importing function like ReadList, it stays in interactive mode and does not exit to shell:

echo 'ReadList["/home/pi2/data.csv","String"]'>mmpipe
{ ... , "2014/02/05 21:35:02,0.28", "2014/02/05 21:40:02,0.00", "2014/02/05 21:50:02,0.00"}
_

So I can't use it in an automated process.

$\endgroup$
10
  • $\begingroup$ Probably you could keep the kernel running and send the scripts using MathLink. $\endgroup$
    – rhermans
    Commented Feb 5, 2014 at 15:44
  • 1
    $\begingroup$ You could use the scheduled tasks functionality of Mathematica, and set up a task to be run every 30 minutes. I.e. don't schedule this using an external tool. Schedule it within Mathematica. Does this help? $\endgroup$
    – Szabolcs
    Commented Feb 5, 2014 at 16:17
  • $\begingroup$ Is .w the recommended extension for packages/scripts now? :-/ $\endgroup$
    – Szabolcs
    Commented Feb 5, 2014 at 16:17
  • 1
    $\begingroup$ Found a closely related question: mathematica.stackexchange.com/questions/23217/… $\endgroup$
    – shrx
    Commented Feb 5, 2014 at 19:57
  • 1
    $\begingroup$ @shrx MathLink is a communication protocol used by Mathematica and a corresponding API (has ready-made bindings for C/C++/Java/.NET). The kernel and the front end communicate through MathLink. The main kernel and subkernels used in parallel calculations also communicate through MathLink. You could theoretically write alternative front ends using MathLink. Some people have: there's something Emacs-based and two shell-based ones: jmath and mash. I never tried these. But if you were to ... $\endgroup$
    – Szabolcs
    Commented Feb 6, 2014 at 21:07

1 Answer 1

3
$\begingroup$

Alright, I managed to make a clunky working script with the help from @Szabolcs' answer here and some testing of the fifo procedure:

#!/bin/bash

pipe=/home/pi2/mmpipe

# check if pipe exists; if not, create it
if [[ ! -p $pipe ]]; then
    mkfifo $pipe
fi

# check if kernel is running; if not, start it and define functions
if [ $(ps aux | grep WolframKernel | grep -v grep | wc -l) -eq 0 ]; then
	tail -f $pipe | wolfram -noprompt &
    sleep 6 # this is needed; functions need to wait for the kernel to initialize
    echo 'function1[]:=...'>$pipe
	sleep 1 # this is also needed; kernel needs some time with each new definition
	echo 'function2[]:=...'>$pipe
fi

echo 'run main mathematica code here;'>$pipe

This solution works only if Mathematica code does not output anything. Every line needs to end with ; and Print[] should not be used. Otherwise the script stays in interactive mode and does not exit to shell. Mathematica output can be saved with Export[], though.


UPDATE

I'm having some trouble with this solution. After some time of working without problems, the second defined function (I have only two) is no longer evaluated. Running echo '?function2'>$pipe returns only "Global`function2" like its definition was somehow unset. I have managed to incorporate the second function in the main code and leave it out from the initial definitions, but this method proves to be really unreliable.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.