Иногда, когда я пишу экспериментальный код в системе 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?
То, что у меня сейчас есть, работает, но полностью блокирует любой дальнейший ввод пользователя. Я не могу просто установить, забыть и проверить позже.
Есть мысли?