8 votes

Comment utiliser le résultat de numpy einsum_path ?

J'effectue une opération assez complexe sur un tenseur à 3 et 4 dimensions en utilisant numpy einsum.

Mon code actuel est le suivant

np.einsum('oij,imj,mjkn,lnk,plk->op',phi,B,Suu,B,phi)

Il fait ce que je veux qu'il fasse.

En utilisant einsum_path, le résultat est le suivant :

>>> path = np.einsum_path('oij,imj,mjkn,lnk,plk->op',phi,B,Suu,B,phi)

>>> print(path[0])
['einsum_path', (0, 1), (0, 3), (0, 1), (0, 1)]

>>> print(path[1])
  Complete contraction:  oij,imj,mjkn,lnk,plk->op
         Naive scaling:  8
     Optimized scaling:  5
      Naive FLOP count:  2.668e+07
  Optimized FLOP count:  1.340e+05
   Theoretical speedup:  199.136
  Largest intermediate:  7.700e+02 elements
--------------------------------------------------------------------------
scaling                  current                                remaining
--------------------------------------------------------------------------
   4                imj,oij->moj                     mjkn,lnk,plk,moj->op
   5               moj,mjkn->nok                          lnk,plk,nok->op
   4                plk,lnk->npk                              nok,npk->op
   4                 npk,nok->op                                   op->op

Cela indique une accélération théorique d'environ 200x.

Comment puis-je utiliser ce résultat pour accélérer mon code ? Comment puis-je "mettre en oeuvre" ce que einsum_path me dit ?

8voto

hpaulj Points 6132

Effectuer des tests de temps

path = np.einsum_path('oij,imj,mjkn,lnk,plk->op',phi,B,Suu,B,phi)

np.einsum('oij,imj,mjkn,lnk,plk->op',phi,B,Suu,B,phi, optimize=False)
np.einsum('oij,imj,mjkn,lnk,plk->op',phi,B,Suu,B,phi, optimize=True)         
np.einsum('oij,imj,mjkn,lnk,plk->op',phi,B,Suu,B,phi, optimize=path[0])

Dans mes tests, les deux autres fonctionnent à la même vitesse. Pour un petit problème optimize=False est plus rapide, probablement parce que l'analyse et le réarrangement prennent du temps. Pour un problème de grande taille, avec un gain de vitesse théorique plus important, le gain de vitesse réel de True peut être plus important que la théorie. On peut supposer que la gestion de la mémoire ralentit l'exécution de l'opération. False cas.

Les theoretical speedup n'est qu'une estimation basée sur le nombre de FLOPS. Cela ne sera vrai que dans la mesure où les FLOPS dominent le calcul.

Vous pouvez également chronométrer la path calc. La taille du problème déterminera si son temps représente une petite ou une grande partie du temps total.

0voto

Edeki Okoh Points 1504

Extrait du code source

Theoretical Speedup = speedup = naive_cost / opt_cost
naive_cost = _flop_count(idx_contract, idx_removed, len(input_sets), idx_dict)

Par conséquent, pour accélérer le processus, il vous faudrait obtenir votre FLOPS (opérations en virgule flottante par seconde) abaissé. Comme le coût naïf est le coût de l'expression non optimisée, vous devez réécrire votre expression de manière à supprimer tout "bric-à-brac" associé à l'expression tout en laissant inchangée la structure sous-jacente de l'expression.

À en juger par votre question, qui indique que vous effectuez des expressions complexes, il se peut que cela ne soit pas possible. Mais pour répondre à votre question, essayez de réécrire votre expression d'une manière plus compacte afin d'obtenir une vitesse théorique plus faible.

Vous pourriez essayer d'utiliser un chemin différent, ce qui réduirait votre FLOPS.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X