h=runExternalM2(fname,func,params)
This function starts a short-lived new (``child'') Macaulay2 process, loads the file fname, runs the function func with the parameters params, captures the value returned by func, and stores it inside h in the original Macaulay2 process. Optionally, strict resource limits may be imposed on the child process from within Macaulay2, or data may be collected about the resources used by the child process.
Since the child is a new Macaulay2 process, it has no defined variables or functions except those defined in fname. Hence, func and anything it needs (e.g., ring definitions) must be defined in the file fname.
The hash table h stores the exit code of the created Macaulay2 process, the return code of the created Macaulay2 process (see run for details; this is usually 256 times the exit code, plus information about any signals received by the child), the wall-clock time used (as opposed to the CPU time), the name of the output file (unless it was deleted), the name of the answer file (unless it was deleted), any statistics recorded about the resource usage, and the value returned by the function func. If the child process terminates abnormally, then usually the exit code is nonzero and the value returned is null.
For example, we can write a few functions to a temporary file:
|
|
|
|
|
and then call them:
|
|
|
|
An abnormal program exit will have a nonzero exit code; also, the value will be null, the output file should exist, but the answer file may not exist unless the routine finished successfully.
|
|
|
|
Here, we use resource limits to limit the routine to 2 seconds of computational time, while the system is asked to use 10 seconds of computational time:
|
|
|
|
We can get quite a lot of detail on the resources used with the KeepStatistics command:
|
|
We can handle most kinds of objects as return values, although MutableMatrix does not work. Here, we use the built-in identity function:
|
|
Some care is required, however:
|
|
|
To view the error message:
|
Keep in mind that the object you are passing must make sense in the context of the file containing your function! For instance, here we need to define the ring:
|
|
This problem can be avoided by following some suggestions for using RunExternalM2.
The objects may unavoidably lose some internal references, though:
|
|
|
|
but this happens because
|
The object runExternalM2 is a function closure.
The source of this document is in RunExternalM2.m2:894:0.