Fdtd3d: Preguntas en computación paralela

Creado en 8 ene. 2020  ·  9Comentarios  ·  Fuente: zer011b/fdtd3d

Hola Gleb,

Soy Chengyi. Gracias por desarrollar este magnífico proyecto. Es realmente útil para estudiar FDTD y su concurrencia. Pero encontré algunos problemas al usar la computación MPI/GPU.

  1. El problema es que cuando llamo al código fdtd3d usando el siguiente comando,
    ./Release/Source/fdtd3d --cmd-from-file ./Examples/vacuum3D_test.txt
    en el que creé "vacuum3D_test.txt" basado en "vacuum3D.txt" insertando el siguiente código
--use-cuda
--cuda-buffer-size 1
--cuda-gpus 0
--num-cuda-threads-x 4
--num-cuda-threads-y 4
--num-cuda-threads-z 4

el programa solo mostrará el registro "Cargando línea de comando desde archivo ./Examples/vacuum3D_test.txt
" y sigue esperando hasta que lo elimine. Me pregunto si hay algunas configuraciones que no configuré correctamente.
Por cierto, este es mi cmake flags en caso de que lo necesites:
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. Además, cuando simulé el "vacuum3D.txt" de MPI, la escalabilidad presentada por fdtd3d no es muy ideal. Por ejemplo, el tamaño de la cuadrícula es de 40 por 40 por 40, lo que equivale a 64000. Y tengo un chip que tiene 18 núcleos. Cuando va con 1 proceso, costará 67,74 segundos y rondará los 11,34 segundos con 8 procesadores habilitados. La aceleración es de alrededor de 6. Y cuando aplico más procesadores como 18, la reducción de tiempo es trivial, digamos de 11,34 s a 9,6 s. ¿Es esto razonable? ¿Puedo preguntar si hay configuraciones de simulación que puedan ajustar el rendimiento de la computación paralela?

Si necesita más detalles de la simulación, hágamelo saber. Muchísimas gracias.

Con muchas gracias y deseos,
Chengyi

Question

Todos 9 comentarios

  1. No creo que esté atascado, solo realiza cálculos, que son mucho más lentos incluso en modo RelWithDebInfo . Además, el registro completo se imprime al final de la ejecución en caso de lanzamientos de Cuda.

Pequeño consejo: es más rápido (en términos de compilación y ejecución) especificar -DSOLVER_DIM_MODES , si sabe exactamente qué modos usará. De forma predeterminada, todos los modos se compilan en binario, lo que aumenta significativamente el tiempo de compilación en el caso de las compilaciones de Cuda. En tu caso -DSOLVER_DIM_MODES=DIM3 sería suficiente.

  1. Hay algunas cosas a tener en cuenta aquí. En primer lugar, el tiempo total de ejecución de cada paso de tiempo es la suma del tiempo computacional y el tiempo compartido. Cuando la red es relativamente pequeña, como en su caso, el tiempo compartido puede ser significativo y se requiere una elección cuidadosa de la topología virtual (fdtd3d muestra la mejor topología virtual para el tamaño de red especificado en su salida).

Sin embargo, en sistemas con memoria compartida, las operaciones de compartir no son necesarias en absoluto (excepto para la sincronización de subprocesos). Es por eso que OpenMP es mucho más aplicable aquí que MPI, y los programas basados ​​en MPI no mostrarán la mejor aceleración. Desafortunadamente, OpenMP aún no es compatible con fdtd3d.

Con todo esto en mente, todavía hay cosas que modificar en fdtd3d.

  • De manera predeterminada, solo el eje Ox se distribuye entre los nodos computacionales, pero puede cambiar esto con -DPARALLEL_BUFFER_DIMENSION=xyz , que dividirá la cuadrícula entre fragmentos en todas las dimensiones. Compruebe la salida de fdtd3d porque aconseja la topología virtual óptima.
  • El tamaño del búfer se puede configurar con --buffer-size B , y la operación de compartir se realizará solo cada B pasos. En este caso, no se garantiza que la topología virtual óptima, recomendada por fdtd3d, sea óptima. Pero puede configurar la topología virtual manualmente con --manual-topology --topology-sizex X --topology-sizey Y --topology-sizez Z .

Tenga en cuenta que cuando el número de procesos no es un divisor del tamaño total de la cuadrícula, tampoco se garantiza que la topología virtual óptima, recomendada por fdtd3d, sea óptima.

Gracias por esta respuesta oportuna.

  1. En cuanto a la computación de GPU única, rehice el fdtd3d con las siguientes banderas

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

y funcionó en mi estación de trabajo. (Por cierto, mi estación de trabajo tiene cuatro Tesla P100 de los cuales el arco debería ser SM_60)

  1. Cuando quiero habilitar la computación multi-gpu con
    mpiexec --mca btl ^openib -n 2 ./Release/Source/fdtd3d --cmd-from-file ./Examples/vacuum3D_test.txt
    y los comandos 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

se produce un error como se muestra:

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.

Parece que el primer paso estuvo bien, pero hubo algún problema con la llamada de la función InternalSchemeKernelHelpers::calculateFieldStepIterationKernel en el segundo paso. Me pregunto si debe haber algunos errores que cometí al usar MPI+CUDA. ¿Puedes por favor enseñarme cómo llamarlo correctamente?
Muchas gracias.

Mejor

Tal vez algo esté mal con sm_60 arch, no lo he probado. El arco predeterminado es sm_20, por lo que debería funcionar en sus tarjetas. Sin embargo, a veces he visto illegal memory access cuando cuda arch no coincidía con la capacidad de cómputo de la GPU.

Los cálculos multi-gpu tienen una aplicabilidad limitada. Si todos los datos caben en la memoria de una sola GPU, sería mucho más rápido realizar cálculos en esta única GPU en un solo nodo computacional (porque no habrá intercambio de datos intermedios entre CPU/GPU y entre diferentes nodos computacionales).

Pero cuando las cuadrículas son muy grandes y no se pueden ubicar en la memoria de un solo nodo computacional, no hay más remedio que usar múltiples nodos computacionales, cada uno posiblemente con una GPU. En este caso, el intercambio de datos CPU-GPU y CPU-CPU se realizará cada B pasos, por defecto B=1 . Esto es mucho más lento que los cálculos simples de todos los pasos de tiempo en una sola GPU.

Los cálculos multi-gpu aún no son totalmente compatibles con fdtd3d, porque actualmente fdtd3d confía en que el usuario se asegure de que todos los datos encajen donde deberían (así como en el modo de solo CPU). Entonces, con tales limitaciones, debería funcionar.

@solotcy Hubo un error con el arco no configurado (ver #140). Por favor, consulte con sm_60 en ese PR.

Illegal memory access está relacionado con el acceso a la variable global cudaSolverSettings, que se encuentra en la memoria del dispositivo (consulte INTERNAL_SCHEME_BASE<Type, TCoord, layout_type>::calculateFieldStepIteration ):

if (SOLVER_SETTINGS.getDoUseTFSF ())

En 2 de 3 GPU con la misma capacidad de cómputo sm_35, en las que probé fdtd3d, todo funciona bien (todas las GPU son modelos diferentes). Sin embargo, en uno, por alguna razón, cudaSolverSettings se convierte en NULL, al ingresar el método getDoUseTFSF (es decir, este ptr es NULL). No he podido entender por qué sucede esto, pero por lo que he encontrado, esto puede suceder debido a un mal funcionamiento del dispositivo.

Parece que ha podido iniciar fdtd3d con éxito al menos en una de sus 4 GPU. Pruebe el modo solo GPU en cada GPU por separado. Debido a que sus 4 GPU son exactamente iguales, no debería haber ninguna diferencia en el comportamiento de fdtd3d. Si hay una diferencia, entonces la causa es un mal funcionamiento del dispositivo se vuelve más probable.

Muchas gracias por sus respuestas.

Revisé el PR #140 y reconstruí fdtd3d con el indicador -DCUDA_ARCH_SM_TYPE=sm_60 agregado. Desafortunadamente, ocurre el mismo problema.

Sin embargo, como mencionó, me encontré con el mismo error cuando cambié entre diferentes GPU en el modo de GPU única. Y no es en el primer paso sino en el segundo, como antes,

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

Y las cosas se vuelven un poco extrañas ya que solo funcionó en la primera GPU. Para otros tres, todo falló y tenía la misma información de error.

¡Gracias por tus pruebas! Finalmente pude descubrir la razón principal de este problema. PR #141 soluciona el problema. Ahora fdtd3d debería funcionar en todas sus GPU. El modo multi-gpu parece funcionar también ahora.

Gracias por sus respuestas y el código modificado. He podido ejecutar el programa en mi estación de trabajo con tantas GPU como quiero. Entonces puedo probar la escalabilidad tanto en CPU como en GPU.
Esta muy bien, gracias!!!

Siéntase libre de reabrir este problema si tiene más preguntas.

¿Fue útil esta página
0 / 5 - 0 calificaciones

Temas relacionados

Tvangeste picture Tvangeste  ·  3Comentarios

node2013 picture node2013  ·  3Comentarios

AndreaOrru picture AndreaOrru  ·  3Comentarios

Xaroth picture Xaroth  ·  3Comentarios

ghost picture ghost  ·  3Comentarios