Configura la comunicación de tareas con una biblioteca MPI

En este documento, se explica cómo configurar un trabajo por lotes con tareas fuertemente acopladas que se comunican entre sí a través de diferentes VMs con una biblioteca de interfaz de transmisión de mensajes (MPI).

En el caso de los trabajos por lotes, la acoplación describe las tareas de interdependencia. Esto influye en la forma en que configuras la cantidad de tareas que se pueden ejecutar en paralelo (en lugar de de forma secuencial) con el campo parallelism de un trabajo. Las tareas se pueden describir con los siguientes tipos de acoplamiento:

  • Tareas con acoplamiento bajo: Tareas que se pueden ejecutar de forma independiente.
  • Tareas con acoplamiento alto: Tareas que dependen una de otra para ejecutarse.

De manera opcional, puedes crear un trabajo que use una biblioteca de MPI para permitir que las tareas fuertemente acopladas se comuniquen entre sí en diferentes instancias de VM. Un caso de uso común para MPI son las cargas de trabajo de computación de alto rendimiento (HPC) estrechamente vinculadas.

Antes de comenzar

  1. Si nunca usaste Batch, consulta Cómo comenzar a usar Batch y habilita Batch completando los requisitos previos para proyectos y usuarios.
  2. Para obtener los permisos que necesitas para crear un trabajo, pídele a tu administrador que te otorgue los siguientes roles de IAM:

    Para obtener más información sobre cómo otorgar roles, consulta Administra el acceso a proyectos, carpetas y organizaciones.

    También puedes obtener los permisos necesarios mediante roles personalizados o cualquier otro rol predefinido.

  3. Si especificas la red para esta tarea, asegúrate de que tenga una regla de firewall que permita las conexiones entre las VMs de la tarea. Obtén más información para configurar reglas de firewall de VPC para casos de uso comunes.

Crea y ejecuta un trabajo que use MPI para tareas estrechamente vinculadas

En esta sección, se proporcionan ejemplos para crear un trabajo que pueda usar MPI. En particular, el trabajo de ejemplo tiene 3 elementos ejecutables:

  • El primer elemento ejecutable es una secuencia de comandos que prepara el trabajo para MPI inhabilitando el multiprocesamiento simultáneo y instalando Intel MPI.
  • El segundo objeto ejecutable es un objeto ejecutable de barrera vacío (con formato { "barrier": {} }), que garantiza que todas las tareas terminen de configurar MPI antes de continuar con los objetos ejecutables futuros.
  • El tercer elemento ejecutable (y cualquier elemento ejecutable posterior) está disponible para la carga de trabajo del trabajo.

Puedes crear un trabajo que use MPI para tareas estrechamente vinculadas con la CLI de gcloud o la API de Batch.

gcloud

Para crear un trabajo de secuencia de comandos que use MPI para tareas estrechamente vinculadas con la CLI de gcloud, haz lo siguiente:

  1. Crea un archivo de configuración JSON con el siguiente contenido:

    {
        "taskGroups": [
            {
                "taskSpec": {
                    "runnables": [
                        {
                            "script": {
                                "text": "google_mpi_tuning --nosmt; google_install_mpi --intel_mpi;"
                            }
                        },
                        { "barrier": {} },
                        {
                            "script": {
                                SCRIPT
                            }
                        }
                    ]
                },
                "taskCount": TASK_COUNT,
                "taskCountPerNode": TASK_COUNT_PER_NODE,
                "requireHostsFile": REQUIRE_HOSTS_FILE,
                "permissiveSsh": PERMISSIVE_SSH
            }
        ]
    }
    

    Reemplaza lo siguiente:

    • SCRIPT: Es una secuencia de comandos ejecutable para una carga de trabajo que usa MPI.
    • TASK_COUNT: Es la cantidad de tareas del trabajo. El valor debe ser un número entero entre 1 y el límite de tareas por grupo de tareas. Para usar las bibliotecas MPI que proporciona Batch, este campo es obligatorio y debe establecerse en 2 o un valor superior.
    • TASK_COUNT_PER_NODE: Es la cantidad de tareas que puede ejecutar una tarea de forma simultánea en una instancia de VM. Para usar las bibliotecas MPI que proporciona Batch, este campo es obligatorio y debe establecerse en 1, lo que equivale a ejecutar una instancia de VM por tarea.
    • REQUIRE_HOSTS_FILE: Cuando se establece en true, el trabajo crea un archivo con una lista de las instancias de VM que se ejecutan en un grupo de tareas. La ruta de acceso del archivo se almacena en la variable de entorno BATCH_HOSTS_FILE. Para usar las bibliotecas de MPI que proporciona Batch, este campo debe establecerse como verdadero.
    • PERMISSIVE_SSH: Cuando se establece en true, Batch configura SSH para permitir la comunicación sin contraseña entre las instancias de VM que se ejecutan en un grupo de tareas. Para usar las bibliotecas MPI que proporciona Batch, este campo debe establecerse como verdadero.
  2. Para crear el trabajo, usa el comando gcloud batch jobs submit.

    gcloud batch jobs submit JOB_NAME \
      --location LOCATION \
      --config JSON_CONFIGURATION_FILE
    

    Reemplaza lo siguiente:

    • JOB_NAME: Es el nombre del trabajo.
    • LOCATION: Es la ubicación del trabajo.
    • JSON_CONFIGURATION_FILE: Es la ruta de acceso a un archivo JSON con los detalles de configuración de la tarea.

De manera opcional, puedes aumentar el rendimiento de las bibliotecas MPI que proporciona Batch haciendo lo siguiente:

Por ejemplo, para crear un trabajo de secuencia de comandos a partir de una plantilla de instancia que use MPI y haga que 1 tarea muestre el nombre de host de las 3 tareas del grupo de tareas, haz lo siguiente:

  1. Crea un archivo JSON en el directorio actual llamado example-job-uses-mpi.json con el siguiente contenido:

    {
        "taskGroups": [
            {
                "taskSpec": {
                    "runnables": [
                        {
                            "script": {
                                "text": "google_mpi_tuning --nosmt; google_install_mpi --intel_mpi;"
                            }
                        },
                        { "barrier": {} },
                        {
                            "script": {
                                "text":
                                    "if [ $BATCH_TASK_INDEX = 0 ]; then
                                    mpirun -hostfile $BATCH_HOSTS_FILE -np 3 hostname;
                                    fi"
                            }
                        },
                        { "barrier": {} }
                    ]
                },
                "taskCount": 3,
                "taskCountPerNode": 1,
                "requireHostsFile": true,
                "permissiveSsh": true
            }
        ],
        "allocationPolicy": {
            "instances": [
                {
                    "instanceTemplate": "example-template-job-uses-mpi"
                }
            ]
        },
        "logsPolicy": {
            "destination": "CLOUD_LOGGING"
        }
    }
    
  2. Ejecuta el siguiente comando:

    gcloud batch jobs submit example-template-job-uses-mpi \
      --location us-central1 \
      --config example-job-uses-mpi.json
    

API

Para crear un trabajo de secuencia de comandos que use un MPI para tareas fuertemente acopladas con la API de Batch, usa el método jobs.create y especifica los campos permissiveSsh, requireHostsFile, taskCount y taskCountPerNode.

POST https://batch.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/jobs?job_id=JOB_ID

{
    "taskGroups": [
        {
            "taskSpec": {
                "runnables": [
                    {
                        "script": {
                            "text": "google_mpi_tuning --nosmt; google_install_mpi --intel_mpi;"
                        }
                    },
                    { "barrier": {} },
                    {
                        "script": {
                            SCRIPT
                        }
                    }
                ]
            },
            "taskCount": TASK_COUNT,
            "taskCountPerNode": TASK_COUNT_PER_NODE,
            "requireHostsFile": REQUIRE_HOSTS_FILE,
            "permissiveSsh": PERMISSIVE_SSH
        }
    ]
}

Reemplaza lo siguiente:

  • PROJECT_ID: Es el ID del proyecto de tu proyecto.
  • LOCATION: Es la ubicación del trabajo.
  • JOB_NAME: Es el nombre del trabajo.
  • SCRIPT: Es la secuencia de comandos ejecutable para una carga de trabajo que usa MPI.
  • TASK_COUNT: Es la cantidad de tareas del trabajo. El valor debe ser un número entero entre 1 y el límite de tareas por grupo de tareas. Para usar las bibliotecas MPI que proporciona Batch, este campo es obligatorio y debe establecerse en 2 o un valor superior.
  • TASK_COUNT_PER_NODE: Es la cantidad de tareas que un trabajo puede ejecutar de forma simultánea en una instancia de VM. Para usar las bibliotecas MPI que proporciona Batch, este campo es obligatorio y debe establecerse en 1, lo que equivale a ejecutar una instancia de VM por tarea.
  • REQUIRE_HOSTS_FILE: Cuando se establece en true, la tarea crea un archivo en el que se enumeran las instancias de VM que se ejecutan en un grupo de tareas. La ruta de acceso del archivo se almacena en la variable de entorno BATCH_HOSTS_FILE. Para usar las bibliotecas MPI que proporciona Batch, este campo debe establecerse como verdadero.
  • PERMISSIVE_SSH: Cuando se establece en true, Batch configura SSH para permitir la comunicación sin contraseña entre las instancias de VM que se ejecutan en un grupo de tareas. Para usar las bibliotecas MPI que proporciona Batch, este campo debe establecerse como verdadero.

De manera opcional, puedes aumentar el rendimiento de las bibliotecas MPI que proporciona Batch haciendo lo siguiente:

Por ejemplo, para crear un trabajo de secuencia de comandos a partir de una plantilla de instancias que use MPI y haga que 1 tarea muestre el nombre de host de las 3 tareas del grupo de tareas, usa la siguiente solicitud:

POST https://batch.googleapis.com/v1/projects/PROJECT_ID/locations/us-central1/jobs?job_id=example-template-job-uses-mpi

{
    "taskGroups": [
        {
            "taskSpec": {
                "runnables": [
                    {
                        "script": {
                            "text": "google_mpi_tuning --nosmt; google_install_mpi --intel_mpi;"
                        }
                    },
                    { "barrier": {} },
                    {
                        "script": {
                            "text":
                                "if [ $BATCH_TASK_INDEX = 0 ]; then
                                mpirun -hostfile $BATCH_HOSTS_FILE -np 3 hostname;
                                fi"
                        }
                    },
                    { "barrier": {} }
                ]
            },
            "taskCount": 3,
            "taskCountPerNode": 1,
            "requireHostsFile": true,
            "permissiveSsh": true
        }
    ],
    "allocationPolicy": {
        "instances": [
            {
                "instanceTemplate": "example-template-job-uses-mpi"
            }
        ]
    },
    "logsPolicy": {
        "destination": "CLOUD_LOGGING"
    }
}

En el ejemplo anterior, PROJECT_ID es el ID del proyecto.

¿Qué sigue?