Mathematica中的异步评估

时间:2011-12-15 06:35:34

标签: asynchronous wolfram-mathematica parallel-processing

有时当我在Mathematica中编写实验代码时,我对是否应该对其进行评估持谨慎态度,因为它可能最终导致我的系统陷入困境。

如果您尝试在64位计算机上运行以下代码段,那么作为一个人为的示例,它很可能会导致系统在耗尽所有内存后完全停止运行。

junk = Table[{x, x}, {10^9}]; (* nom nom nom memory. Please don't run this. *)

当然,你可以把MemoryConstrained扔到它上面并希望最好,但有时你不希望它阻止任何进一步的输入。为此,我认为实现中间立场的最佳方式是在单独的内核中执行评估。

这很容易做到:

ClearAll[GetAvailableKernel];
GetAvailableKernel[] := Block[{i, kernels},
  kernels = Kernels[];
  If[Length@kernels !=  0,
   For[i = 1, i <= Length@kernels, i++,
    If[kernels[[i, 1, 2]] > 0, Return@kernels[[i]]]
    ]
   ];
  LaunchKernels[1]]

ClearAll[SafeEvaluate];
SetAttributes[SafeEvaluate, HoldFirst];
Options[SafeEvaluate] = {"EvaluationKernel" -> Null, 
   "ConstrainMemory" -> True, "MaxMemory" -> 2 1024^3};

SafeEvaluate[expr_, OptionsPattern[]] := Block[{evalkernel, result},
  If[OptionValue["EvaluationKernel"] != Null,
   evalkernel = OptionValue["EvaluationKernel"],
   evalkernel = GetAvailableKernel[]
   ];

  result  = If[OptionValue["ConstrainMemory"],
    With[{memory = OptionValue["MaxMemory"]},
     ParallelEvaluate[MemoryConstrained[expr, memory], evalkernel]],
    ParallelEvaluate[expr, evalkernel]];
  result]

然后你可以继续做下面的事情:

SafeEvaluate[Table[{x, x}, {1024^3}]]

Mathematica会优雅地返回$Aborted告诉你内存不足。通过在单独的内核中进行评估,我们可以将代码沙箱放入其自己的并行内核中。如果出现问题,那么我们的主内核不会受到影响。


这让我想到了我的要点:如何在Mathematica中实现异步评估?

我现在所拥有的功能,但它完全阻止了任何进一步的用户输入。我不能随便设置,忘记和检查。

有什么想法吗?

4 个答案:

答案 0 :(得分:7)

我在Mathematica中几乎没有使用并行计算的经验,所以这可能不是最好的方法,但这是我设法挖掘的from the docs

启动内核:

In[1]:= LaunchKernels[1]

Out[1]= KernelObject[1, "local"]

提交一些长期工作:

In[2]:= job = 
 ParallelSubmit[First@SingularValueList[RandomReal[1, {2000, 2000}]]]

Mathematica graphics

开始工作:

In[3]:= Parallel`Developer`QueueRun[]

Out[3]= True

现在作业在后台并行运行......

Mathematica graphics

...我们可以自由地在主内核中做任何我们想做的事情。如果我理解你的问题,这就是你需要的。我们可以再次运行Parallel`Developer`QueueRun[]来检查哪些并行评估已完成(评估对象的显示将动态更新)。

In[4]:= 1 + 1

Out[4]= 2

等到评估结束(如果还没有)并收集结果:

In[5]:= WaitAll[job]

Out[5]= 1000.23

Mathematica graphics

答案 1 :(得分:3)

经常发生的事情是你的系统会耗尽内存并开始交换。交换将使系统死亡缓慢。在Linux上这就是我做的事情

alias m804='ulimit -v 3800000; /usr/local/bin/math8.0.4/mathematica'

系统然后只是给出内存不足消息并在它进入交换之前退出。否则就像往常一样。

答案 2 :(得分:1)

我不认为这个功能在 9 年前被问到这个问题时就存在了。但是对于任何在 Mathematica 12 及更高版本中寻找解决方案的人,您只需使用 SessionSubmit[]。因此,在这种情况下,您需要 SessionSubmit[SafeEvaluate[Table[{x, x}, {1024^3}]]].

SessionSubmit[] 函数创建一个新任务并在当前会话中异步运行它。或者,LocalSubmit[] 可用于在单独的内核中异步运行命令,因此在较新版本的 Mathematica 中甚至不需要 SafeEvaluate 函数。可以在 SessionSubmitLocalSubmit 的文档页面上找到更多信息。此外,阅读 Task Objects 的文档页面也可能很有用。

答案 3 :(得分:0)

很久以前,我使用过Mathematica,但我有一个想法。据我所知,您可以在加载Mathematica文档时设置功能的自动评估。无法使用Mathematica创建一个文档,其SafeEvaluate [function]为“run on loading”,并在后台使用此文档启动另一个Mathematica流程。然后你仍然可以使用你看到的输入。当然,那么你必须汇集该进程以查看它是否结束,或者让评估的函数保存您汇集的结果文件。