Fdtd3d: Questions en calcul parallèle

Créé le 8 janv. 2020  ·  9Commentaires  ·  Source: zer011b/fdtd3d

Salut Gleb,

Je suis Chengyi. Merci d'avoir développé ce magnifique projet. C'est vraiment utile pour étudier FDTD et sa simultanéité. Mais j'ai rencontré quelques problèmes dans l'utilisation du calcul MPI/GPU.

  1. Le problème est que lorsque j'appelle le code fdtd3d à l'aide de la commande suivante,
    ./Release/Source/fdtd3d --cmd-from-file ./Examples/vacuum3D_test.txt
    dans lequel j'ai créé "vacuum3D_test.txt" basé sur le "vacuum3D.txt" en insérant le code suivant
--use-cuda
--cuda-buffer-size 1
--cuda-gpus 0
--num-cuda-threads-x 4
--num-cuda-threads-y 4
--num-cuda-threads-z 4

le programme n'affichera que le journal "Loading command line from file ./Examples/vacuum3D_test.txt
" et attendez jusqu'à ce que je le tue. Je me demande simplement s'il y a des configurations que je n'ai pas définies correctement ?
Au fait, voici mes drapeaux cmake au cas où vous en auriez besoin :
cmake .. -DCMAKE_BUILD_TYPE=RelWithDebInfo -DVALUE_TYPE=f -DPRINT_MESSAGE=ON -DCUDA_ENABLED=ON -DCUDA_ARCH_SM_TYPE=sm_60 -DCXX11_ENABLED=ON -DPARALLEL_GRID=ON -DPARALLEL_GRID_DIMENSION=3

  1. De plus, lorsque j'ai simulé le "vacuum3D.txt" par MPI, la scalabilité présentée par fdtd3d n'est pas très idéale. Par exemple, la taille de la grille est de 40 par 40 par 40, ce qui équivaut à 64 000. Et j'ai une puce qui a 18 cœurs. Quand il va avec 1 processus, cela coûtera 67,74 secondes et ce sera environ 11,34 secondes avec 8 processeurs activés. L'accélération est d'environ 6. Et lorsque j'applique plus de processeurs comme 18, la réduction de temps est triviale, disons de 11,34 s à 9,6 s. Est-ce raisonnable ? Puis-je demander s'il existe des configurations de simulation qui peuvent ajuster les performances de calcul parallèle ?

Si vous avez besoin de plus de détails sur la simulation, veuillez me le faire savoir. Merci beaucoup.

Avec mes remerciements et mes souhaits,
Chengyi

Question

Tous les 9 commentaires

  1. Je ne pense pas qu'il soit bloqué, il effectue simplement des calculs, qui sont beaucoup plus lents même en mode RelWithDebInfo . De plus, le journal complet est imprimé à la fin de l'exécution en cas de lancement de Cuda.

Petite astuce : il est plus rapide (en termes de compilation et d'exécution) de spécifier -DSOLVER_DIM_MODES , si vous savez exactement quels modes vous allez utiliser. Par défaut, tous les modes sont compilés en binaire, ce qui augmente considérablement le temps de compilation en cas de builds Cuda. Dans votre cas, -DSOLVER_DIM_MODES=DIM3 suffiraient.

  1. Il y a peu de choses à garder à l'esprit ici. Tout d'abord, le temps d'exécution global de chaque pas de temps est la somme du temps de calcul et du temps partagé. Lorsque la grille est relativement petite, comme dans votre cas, le temps de partage peut être important et un choix judicieux de la topologie virtuelle est nécessaire (fdtd3d affiche la meilleure topologie virtuelle pour la taille de grille spécifiée dans sa sortie).

Cependant, sur les systèmes avec mémoire partagée, les opérations de partage ne sont pas du tout nécessaires (sauf pour la synchronisation des threads). C'est pourquoi OpenMP est beaucoup plus applicable ici que MPI, et les programmes basés sur MPI n'afficheront pas la meilleure accélération. Malheureusement, OpenMP n'est pas encore pris en charge dans fdtd3d.

Avec tout cela à l'esprit, il y a encore des choses à peaufiner dans fdtd3d.

  • Par défaut, seul l'axe Ox est réparti entre les nœuds de calcul, mais vous pouvez modifier cela avec -DPARALLEL_BUFFER_DIMENSION=xyz , qui divisera la grille entre les morceaux dans toutes les dimensions. Vérifiez la sortie de fdtd3d car elle conseille la topologie virtuelle optimale.
  • La taille du tampon peut être configurée avec --buffer-size B , et l'opération de partage ne sera effectuée qu'à chaque étape B . Dans ce cas, la topologie virtuelle optimale, qui est conseillée par fdtd3d, n'est pas garantie d'être optimale. Mais vous pouvez définir manuellement la topologie virtuelle avec --manual-topology --topology-sizex X --topology-sizey Y --topology-sizez Z .

Notez que lorsque le nombre de processus n'est pas un diviseur de la taille globale de la grille, la topologie virtuelle optimale, conseillée par fdtd3d, n'est pas non plus garantie d'être optimale.

Merci pour cette réponse opportune.

  1. En ce qui concerne le calcul GPU unique, j'ai refait le fdtd3d avec les drapeaux suivants

cmake .. -DCMAKE_BUILD_TYPE=RelWithDebInfo -DVALUE_TYPE=f -DPRINT_MESSAGE=ON -DCUDA_ENABLED=ON -DCXX11_ENABLED=ON -DPARALLEL_GRID=ON -DPARALLEL_GRID_DIMENSION=3 -DSOLVER_DIM_MODES=DIM3 -DPARALLEL_BUFFER_DIMENSION=x

et cela a fonctionné dans mon poste de travail. (BTW, mon poste de travail a quatre Tesla P100 dont l'arche devrait être SM_60)

  1. Quand je veux activer le calcul multi-gpu avec
    mpiexec --mca btl ^openib -n 2 ./Release/Source/fdtd3d --cmd-from-file ./Examples/vacuum3D_test.txt
    et les cmds CUDA
--use-cuda
--cuda-buffer-size 2
--buffer-size 2
--cuda-gpus 0,1
--num-cuda-threads-x 4
--num-cuda-threads-y 4
--num-cuda-threads-z 4

erreur se produit comme indiqué :

Calculating time step 0...
Calculating time step 1...
Fatal error: an illegal memory access was encountered at /home/t00540502/fdtd3d/Source/Scheme/InternalScheme.inc.h:912
*** FAILED - ABORTING
-------------------------------------------------------
Primary job  terminated normally, but 1 process returned
a non-zero exit code.. Per user-direction, the job has been aborted.

Il semble que la première étape était correcte, mais quelque chose n'allait pas avec la fonction InternalSchemeKernelHelpers::calculateFieldStepIterationKernel appelant à la 2ème étape. Je me demande s'il doit y avoir des erreurs que j'ai commises en utilisant MPI + CUDA. Pouvez-vous s'il vous plaît m'apprendre à l'appeler correctement?
Merci beaucoup.

Meilleur

Peut-être que quelque chose ne va pas avec sm_60 arch, je ne l'ai pas testé. L'arche par défaut est sm_20, elle devrait donc fonctionner sur vos cartes. Cependant, j'ai parfois vu illegal memory access lorsque cuda arch ne correspondait pas à la capacité de calcul du GPU.

Les calculs multi-gpu ont une applicabilité limitée. Si toutes les données tiennent dans la mémoire d'un seul GPU, il serait beaucoup plus rapide d'effectuer des calculs sur ce seul GPU sur un seul nœud de calcul (car il n'y aura pas de partage de données intermédiaire entre CPU/GPU et entre différents nœuds de calcul).

Mais lorsque les grilles sont très grandes et ne peuvent pas être localisées en mémoire d'un seul nœud de calcul, il n'y a pas d'autre choix que d'utiliser plusieurs nœuds de calcul, chacun ayant éventuellement un GPU. Dans ce cas, le partage de données CPU-GPU et CPU-CPU sera effectué à chaque B pas, par défaut B=1 . C'est beaucoup plus lent que les calculs simples de tous les pas de temps sur un seul GPU.

Les calculs multi-gpu ne sont pas encore entièrement pris en charge dans fdtd3d, car actuellement fdtd3d s'appuie sur l'utilisateur pour s'assurer que toutes les données tiennent là où elles doivent tenir (ainsi qu'en mode CPU uniquement). Donc, avec de telles limitations, cela devrait fonctionner.

@solotcy Il y avait un bug avec l'arche non définie (voir #140). S'il vous plaît, vérifiez avec sm_60 sur ce PR.

Illegal memory access est lié à l'accès à la variable globale cudaSolverSettings, qui se trouve dans la mémoire de l'appareil (voir INTERNAL_SCHEME_BASE<Type, TCoord, layout_type>::calculateFieldStepIteration ) :

if (SOLVER_SETTINGS.getDoUseTFSF ())

Sur 2 des 3 GPU avec la même capacité de calcul sm_35, sur lesquels j'ai testé fdtd3d, tout fonctionne bien (tous les GPU sont des modèles différents). Cependant, pour une raison quelconque, cudaSolverSettings devient NULL, lors de la saisie de la méthode getDoUseTFSF (c'est-à-dire que ce ptr est NULL). Je n'ai pas été en mesure de comprendre pourquoi cela se produit, mais d'après ce que j'ai trouvé, cela peut se produire en raison d'un dysfonctionnement de l'appareil.

Il semble que vous ayez réussi à lancer fdtd3d au moins sur l'un de vos 4 GPU. Essayez le mode GPU uniquement sur chaque GPU séparément. Parce que tous vos 4 GPU sont exactement les mêmes, il ne devrait y avoir aucune différence dans le comportement de fdtd3d. S'il y a une différence, la cause étant un dysfonctionnement de l'appareil devient plus probable.

Merci beaucoup pour les réponses.

J'ai vérifié le PR #140 et reconstruit fdtd3d avec le drapeau -DCUDA_ARCH_SM_TYPE=sm_60 ajouté. Malheureusement, le même problème se produit.

Cependant, comme vous l'avez mentionné, j'ai rencontré la même erreur lorsque j'ai basculé entre différents GPU en mode GPU unique. Et ce n'est pas au premier pas mais au second, comme avant,

Estimated current size: 1437644553 byte.
Setup blocks:
blockCount:
Coord (X : 1.000000, Y : 1.000000, Z : 1.000000).
blockSize:
Coord (X : 200.000000, Y : 200.000000, Z : 200.000000).
Calculating time step 0...
Calculating time step 1...
Fatal error: an illegal memory access was encountered at ~/fdtd3d/Source/Scheme/InternalScheme.inc.h:912

Et les choses deviennent un peu étranges car cela ne fonctionnait que sur le premier GPU. Pour les trois autres, tout a échoué et avait les mêmes informations d'erreur.

Merci pour vos essais ! J'ai enfin pu comprendre la raison principale de ce problème. PR #141 résout le problème. Maintenant, fdtd3d devrait fonctionner sur tous vos GPU. Le mode multi-gpu semble également fonctionner maintenant.

Merci pour vos réponses et le code modifié. J'ai pu exécuter le programme sur mon poste de travail avec autant de GPU que je le souhaitais. Ensuite, je peux tester l'évolutivité sur les CPU et les GPU.
C'est plutôt cool, merci !!!

N'hésitez pas à rouvrir ce sujet si vous avez d'autres questions.

Cette page vous a été utile?
0 / 5 - 0 notes