Parfor pour Python
Je suis à la recherche d'une réponse définitive à MATLAB parfor pour Python (Scipy, Numpy).
Est-il une solution similaire à parfor? Si non, quelle est la complication pour la création d'une?
Mise à JOUR: Voici un exemple typique du calcul numérique de code que j'ai besoin d'accélérer
import numpy as np
N = 2000
output = np.zeros([N,N])
for i in range(N):
for j in range(N):
output[i,j] = HeavyComputationThatIsThreadSafe(i,j)
Un exemple d'un lourd fonction de calcul est:
import scipy.optimize
def HeavyComputationThatIsThreadSafe(i,j):
n = i * j
return scipy.optimize.anneal(lambda x: np.sum((x-np.arange(n)**2)), np.random.random((n,1)))[0][0,0]
Vous devez vous connecter pour publier un commentaire.
Il y a beaucoup de Python cadres pour le calcul parallèle. Celui que j'aime le plus est IPython, mais je ne sais pas trop sur les autres. Dans IPython, un analogue de parfor serait
client.MultiEngineClient.map()
ou d'autres constructions dans la documentation sur rapide et facile parallélisme.Celui intégré à python serait
multiprocessing
docs sont ici. J'ai toujours utilisermultiprocessing.Pool
avec autant de travailleurs que les processeurs. Alors à chaque fois que j'ai besoin de faire une boucle for comme structure-je utiliserPool.imap
Aussi longues que le corps de votre fonction ne dépend pas d'une itération précédente alors vous devriez avoir près de vitesse linéaire-up. Cela implique aussi que les entrées et les sorties sont
pickle
-mesure, mais c'est assez facile à assurer pour les types standard.Mise à JOUR:
Un peu de code pour la mise à jour de votre fonction juste pour montrer combien il est facile:
output[ind]
paroutput.flat[ind]
pour rendre le code du travail. (output
est un tableau à deux dimensions et aurait besoin de deux indices.)J'ai toujours utilisé des En Parallèle Python mais ce n'est pas un analogue complète car je crois qu'il utilise généralement des processus distincts qui peuvent être coûteux sur certains systèmes d'exploitation. Encore, si le corps de votre boucles sont chunky assez alors ce ne sera pas grave et peut avoir certains avantages.
Jupyter Portable
Pour voir un exemple de considérer que vous voulez écrire l'équivalence de ce code Matlab en Python
La façon dont on peut écrire cela en python en particulier dans jupyter ordinateur portable. Vous devez créer une fonction dans le répertoire de travail (je l'ai appelé FunForParFor.py) qui est la suivante
Puis-je aller à mon Jupyter portable et d'écrire le code suivant
Cela a fonctionné pour moi! Je voulais juste le partager ici, pour vous donner un exemple particulier.
Cela peut se faire en toute élégance avec Ray, un système qui vous permet de paralléliser et distribuer votre code Python.
Pour paralléliser votre exemple, vous devez définir vos fonctions avec le
@ray.remote
décorateur, puis d'appeler avec.remote
.Il y a un certain nombre d'avantages de l'utilisation de Rayons sur la multitraitement module. En particulier, la même code sera exécuté sur une seule machine ainsi que sur un cluster de machines. Pour plus d'avantages de Ray voir ce poste.
Remarque: Un point à garder à l'esprit est que chaque fonction est exécutée dans un processus distinct, éventuellement sur une autre machine, et donc la distance de la fonction de calcul devrait prendre plus de l'invocation d'une fonction à distance. En règle générale, une distance de la fonction de calcul devrait prendre au moins quelques 10s de ms à amortir la planification et le démarrage de surcharge d'une fonction à distance.
J'ai essayé toutes les solutions ici, mais a constaté que la façon la plus simple et la plus proche équivalent à matlabs parfor est numba de l' prange.
Essentiellement, vous de changer une seule lettre dans votre boucle, la gamme de prange: