Mik*_*ley 9 parallel-processing asynchronous wolfram-mathematica
有时当我在Mathematica中编写实验代码时,我很担心是否应该对它进行评估,因为它可能最终导致我的系统陷入困境.
作为一个人为的例子,如果您尝试在64位计算机上运行以下代码片段,它很可能会导致系统在耗尽所有内存后完全停止.
junk = Table[{x, x}, {10^9}]; (* nom nom nom memory. Please don't run this. *)
Run Code Online (Sandbox Code Playgroud)
当然,你可以抛出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]
Run Code Online (Sandbox Code Playgroud)
然后你可以继续做一些事情:
SafeEvaluate[Table[{x, x}, {1024^3}]]
Run Code Online (Sandbox Code Playgroud)
Mathematica会优雅地回复$Aborted告诉你内存不足.通过在单独的内核中进行评估,我们可以将代码沙箱放入其自己的并行内核中.如果出现问题,那么我们的主内核不会受到影响.
这让我想到了我的主要观点:如何在Mathematica中实现异步评估?
我现在所做的工作,但它完全阻止任何进一步的用户输入.我不能随便设置,忘记和检查.
有什么想法吗?
我对Mathematica中的并行计算没有经验,所以这可能不是最好的方法,但这是我设法从文档中挖掘的:
启动内核:
In[1]:= LaunchKernels[1]
Out[1]= KernelObject[1, "local"]
Run Code Online (Sandbox Code Playgroud)
提交一些很长的工作:
In[2]:= job =
ParallelSubmit[First@SingularValueList[RandomReal[1, {2000, 2000}]]]
Run Code Online (Sandbox Code Playgroud)

开始工作:
In[3]:= Parallel`Developer`QueueRun[]
Out[3]= True
Run Code Online (Sandbox Code Playgroud)
现在这项工作在后台并行运行......

......我们可以自由地在主内核中做任何我们想做的事情.如果我理解你的问题,这就是你需要的.我们可以Parallel`Developer`QueueRun[]再次运行以检查哪些并行评估已完成(评估对象的显示将动态更新).
In[4]:= 1 + 1
Out[4]= 2
Run Code Online (Sandbox Code Playgroud)
等到评估结束(如果还没有)并收集结果:
In[5]:= WaitAll[job]
Out[5]= 1000.23
Run Code Online (Sandbox Code Playgroud)
