asynchronous wolfram-mathematica parallel-processing

asynchronous - Evaluación asincrónica en Mathematica



wolfram-mathematica parallel-processing (3)

Fue hace mucho tiempo que utilicé Mathematica pero tuve una idea. Por lo que sé, puede establecer una evaluación automática de la función cuando carga un documento de Mathematica. No sería posible usar Mathematica para crear un documento con su SafeEvaluate [función] como "ejecutar al cargar" e iniciar otro proceso de Mathematica en el fondo con este documento. Entonces todavía puedes usar el que ves para la entrada. Por supuesto, entonces tendrá que agrupar ese proceso para ver si terminó, o tener la función que evalúa guardar un archivo de resultados que haya agrupado.

A veces, cuando estoy escribiendo un código experimental en Mathematica, tengo dudas sobre si debo evaluarlo o no, porque puede terminar llevando mi sistema a sus rodillas.

Como un ejemplo artificial si intenta ejecutar el siguiente fragmento de código en una máquina de 64 bits, lo más probable es que provoque que su sistema se detenga por completo una vez que consuma toda su memoria.

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

Claro, puedes MemoryConstrained en él y esperar lo mejor, pero a veces no quieres que bloquee 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 fue decentemente lo suficientemente fácil de hacer:

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]

Entonces podrías seguir adelante y hacer algo como:

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

Y Mathematica devolvería graciosamente $Aborted diciéndole que se había quedado 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 una evaluación asincrónica dentro de Mathematica?

Lo que tengo ahora funciona, pero bloquea completamente cualquier entrada de usuario adicional. No puedo simplemente establecer, olvidar y verificar más tarde.

¿Alguna idea?


Muy a menudo lo que sucede es que su sistema se quedará sin memoria y comenzará a intercambiar. Y el intercambio hará que el sistema muera lentamente. En Linux aquí es lo que hago

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

El sistema simplemente da el mensaje de falta de memoria y se cierra antes de pasar al intercambio. De lo contrario, se comporta como de costumbre.


Tengo casi cero experiencia en computación paralela en Mathematica, así que esta podría no ser la mejor manera, pero esto es lo que logré extraer de los documentos :

Lanza un kernel:

In[1]:= LaunchKernels[1] Out[1]= KernelObject[1, "local"]

Presentar un trabajo largo para terminar:

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

Comenzar trabajo

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

Ahora el trabajo se ejecuta en paralelo en segundo plano ...

... y somos libres de hacer lo que queramos en el kernel principal. Si entiendo tu pregunta, esto es lo que necesitabas. Podemos ejecutar Parallel`Developer`QueueRun[] nuevamente para verificar qué evaluaciones paralelas han finalizado (la visualización del objeto de evaluación se actualizará dinámicamente).

In[4]:= 1 + 1 Out[4]= 2

Espere hasta que finalice la evaluación (si aún no lo ha hecho) y recopile el resultado:

In[5]:= WaitAll[job] Out[5]= 1000.23