A veces, cuando estoy escribiendo código experimental en Mathematica, soy cauteloso sobre si debería evaluarlo o no, porque puede terminar llevando mi sistema a sus rodillas.Evaluación asíncrona en Mathematica
Como ejemplo artificioso si se intenta ejecutar el siguiente fragmento de código en una máquina de 64 bits, lo más probable es hacer que el sistema para moler a un alto completo después de que se consume toda la memoria.
junk = Table[{x, x}, {10^9}]; (* nom nom nom memory. Please don't run this. *)
Claro, usted puede simplemente tirar MemoryConstrained
a ella y esperar lo mejor, pero a veces no desea que el bloqueo de ninguna entrada adicional. Con ese fin, la forma en que pensé que sería mejor lograr un término medio fue realizar la evaluación en un núcleo separado.
Eso era bastante bastante fácil de hacer:
ClearAll[GetAvailableKernel];
GetAvailableKernel[] := Block[{i, kernels},
kernels = Kernels[];
If[[email protected] != 0,
For[i = 1, i <= [email protected], i++,
If[kernels[[i, 1, 2]] > 0, [email protected][[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]
A continuación, sólo puede seguir adelante y hacer algo en la línea de:
SafeEvaluate[Table[{x, x}, {1024^3}]]
y Mathematica volvería con gracia $Aborted
le dice que corrió sin memoria. Al evaluar en un kernel por separado, podemos codificar sandbox en su propio kernel paralelo. Si algo sale mal, nuestro kernel principal no se verá afectado.
Esto me lleva a mi punto principal: ¿Cómo puedo lograr Evaluación asíncrona dentro de Mathematica?
Lo que tengo ahora funciona, pero bloquea por completo cualquier entrada de usuario. No puedo simplemente establecer, olvidar y verificar más tarde.
¿Alguna idea?
Se describe detalladamente 'SafeEvaluate' sin embargo, que pasan unas palabras en su real pregunta y me queda adivinar su significado. ¿Está buscando una manera de evaluar una expresión en una celda, dejar ejecutándose la evaluación y evaluar una expresión en una segunda celda, obteniendo potencialmente el resultado antes de que se complete la evaluación de la primera? –
@ Mr.Wizard Esa es mi lectura de la pregunta. Lo primero que pensé fue que esto es imposible porque cualquier evaluación cambiará el estado del kernel. Por lo tanto, dos evaluaciones paralelas cambiarían simulaimente el estado del kernel: Mike en realidad está pidiendo multithreading, con todas las dificultades y sutilezas que trae aparejadas. (Incluso con kernels paralelos, algunos de los estados se comparten para obtener los resultados). Pero luego pensé en 'Dynamic [f [i]]', 'Table [Pause [1]; i, {i, 10}] '(pruébalo --- es como' Monitor'). De hecho, esto es evaluar cosas en paralelo, en un solo kernel. – Szabolcs
@Szabolcs ¿dónde dice que quiere una evaluación paralela dentro de un kernel único? –