YGM es una biblioteca de comunicación asincrónica diseñada para patrones de comunicación irregular. Se basa en una abstracción del comunicador, al igual que MPI, pero la comunicación se maneja de manera asincrónica y es iniciada por los remitentes sin ninguna interacción con los receptores. Características de YGM
async . Esta función se completará en el rango de destino en un momento no especificado en el futuro, pero YGM no hace que el remitente consciente de esta finalización.for_all que ejecutan una función proporcionada por el usuario en cada objeto almacenado, o, cuando se conoce la ubicación de una pieza de datos particular, visit operaciones de tipo que realizan una función proporcionada por el usuario solo en los datos deseados. Estos contenedores se encuentran aquí.YGM es una biblioteca solo de encabezado que es fácil de incorporar en un proyecto a través de CMake. Agregar lo siguiente a cmakelists.txt instalará YGM y sus dependencias como parte de su proyecto:
set(DESIRED_YGM_VERSION 0.4)
find_package(ygm ${DESIRED_YGM_VERSION} CONFIG)
if (NOT ygm_FOUND)
FetchContent_Declare(
ygm
GIT_REPOSITORY https://github.com/LLNL/ygm
GIT_TAG v${DESIRED_YGM_VERSION}
)
FetchContent_GetProperties(ygm)
if (ygm_POPULATED)
message(STATUS "Found already populated ygm dependency: "
${ygm_SOURCE_DIR}
)
else ()
set(JUST_INSTALL_YGM ON)
set(YGM_INSTALL ON)
FetchContent_Populate(ygm)
add_subdirectory(${ygm_SOURCE_DIR} ${ygm_BINARY_DIR})
message(STATUS "Cloned ygm dependency " ${ygm_SOURCE_DIR})
endif ()
else ()
message(STATUS "Found installed ygm dependency " ${ygm_DIR})
endif ()
Aquí caminaremos por un programa básico de YGM "Hello World". El directorio de ejemplos contiene varios otros ejemplos, incluidos muchos utilizando los contenedores de almacenamiento de YGM.
Para comenzar, se necesitan encabezados para un comunicador YGM
# include < ygm/comm.hpp > Al comienzo del programa, se debe construir un comunicador YGM. Se le dará argc y argv como MPI_Init , y tiene un tercer argumento opcional que especifica el tamaño agregado (en bytes) permitido para todos los buffers de envío antes de que YGM comience a los envíos de descarga. Aquí, haremos un búfer con 32 MB de espacio de búfer de envío agregado.
ygm::comm world (&argc, &argv, 32 * 1024 * 1024 );A continuación, necesitamos un Lambda para enviar a través de YGM. Haremos un simple tipo de lambda de hello_world.
auto hello_world_lambda = []( const std::string &name) {
std::cout << " Hello " << name << std::endl;
}; Finalmente, usamos este lambda dentro de nuestras llamadas async . En este caso, tendremos el rango 0 Enviar un mensaje al rango 1, diciéndole que salude al mundo
if (world.rank0()) {
world. async ( 1 , hello_world_lambda, std::string ( " world " ));
}La versión completa y compilable de este ejemplo se encuentra aquí. Ejecutarlo imprime un solo "Hello World".
Hay dos clases distintas de lambdas que se pueden dar a YGM: lambdas remotas y lambdas locales , cada una de las cuales tiene diferentes requisitos.
Una lambda remota es cualquier lambda que potencialmente puede ejecutarse en un rango diferente. Estos lambdas se identifican como los que se dan a un ygm::comm o cualquiera de los contenedores de almacenamiento a través de una función prefijada por async_ .
La característica definitoria de Lambdas remotas es que no deben capturar ninguna variable; Todas las variables deben proporcionarse como argumentos. Esta limitación se debe a la falta de capacidad para que YGM inspeccione y extraiga estos argumentos al serializar los mensajes que se enviarán a otros rangos.
Una lambda local es cualquier lambda que esté garantizado que no se envíe a un rango remoto. Estos lambdas se identifican como los que se dan a una operación for_all en un contenedor de almacenamiento.
La característica definitoria de Lambdas locales es que todos los argumentos además de lo que se almacena en el contenedor debe ser capturado. Internamente, estos lambdas se pueden dar a un std::for_each que itera sobre los elementos del contenedor almacenados localmente en cada rango.
YGM se distribuye bajo la licencia MIT.
Todas las nuevas contribuciones deben hacerse bajo la licencia MIT.
Consulte License-Mit, Aviso y Copyright para más detalles.
Identificador SPDX-license: MIT
LLNL-Code-789122