O YGM é uma biblioteca de comunicação assíncrona projetada para padrões irregulares de comunicação. Ele é construído com uma abstração do comunicador, assim como o MPI, mas a comunicação é tratada de forma assíncrona e é iniciada pelos remetentes sem nenhuma interação com os receptores. Recursos YGM
async . Essa função será concluída na classificação de destino em um horário não especificado no futuro, mas a YGM não torna explicitamente o remetente ciente dessa conclusão.for_all que executam uma função fornecida pelo usuário em todos os objetos armazenados ou, quando uma localização de um determinado dados é conhecida, visit as operações do tipo que desempenham uma função fornecida pelo usuário apenas nos dados desejados. Esses recipientes são encontrados aqui.O YGM é uma biblioteca somente para cabeçalho que é fácil de incorporar em um projeto através do CMake. Adicionar o seguinte ao cmakelists.txt instalará o YGM e suas dependências como parte do seu projeto:
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 ()
Aqui vamos percorrer um programa YGM básico de "Hello World". O diretório exemplos contém vários outros exemplos, incluindo muitos usando os contêineres de armazenamento da YGM.
Para começar, são necessários cabeçalhos para um comunicador YGM
# include < ygm/comm.hpp > No início do programa, um comunicador YGM deve ser construído. Ele receberá argc e argv como MPI_Init e possui um terceiro argumento opcional que especifica o tamanho agregado (em bytes) permitido para todos os buffers de envio antes que o YGM comece a descartar envios. Aqui, faremos um buffer com 32 MB de espaço agregado de enviar buffer.
ygm::comm world (&argc, &argv, 32 * 1024 * 1024 );Em seguida, precisamos de um lambda para enviar através do YGM. Faremos um tipo simples de lambda hello_world.
auto hello_world_lambda = []( const std::string &name) {
std::cout << " Hello " << name << std::endl;
}; Finalmente, usamos esse lambda dentro de nossas chamadas async . Nesse caso, teremos a classificação 0 enviar uma mensagem para a classificação 1, dizendo para cumprimentar o mundo
if (world.rank0()) {
world. async ( 1 , hello_world_lambda, std::string ( " world " ));
}A versão completa e compilável deste exemplo é encontrada aqui. Executar imprime um único "Hello World".
Existem duas classes distintas de lambdas que podem ser dadas ao YGM: lambdas remotos e lambdas locais , cada um dos quais tem requisitos diferentes.
Um lambda remoto é qualquer lambda que possa ser executado em uma classificação diferente. Esses lambdas são identificados como sendo os dados a um ygm::comm ou a qualquer um dos contêineres de armazenamento por meio de uma função prefixada pelo async_ .
A característica definidora dos lambdas remotos é que eles não devem capturar nenhuma variável; Todas as variáveis devem ser fornecidas como argumentos. Essa limitação se deve à falta de capacidade de YGM inspecionar e extrair esses argumentos ao serializar mensagens a serem enviadas para outras fileiras.
Um Lambda local é qualquer lambda que seja garantido que não seja enviado para uma classificação remota. Esses lambdas são identificados como sendo os dados a uma operação for_all em um contêiner de armazenamento.
A característica definidora dos lambdas locais é que todos os argumentos além do que é armazenado no contêiner devem ser capturados. Internamente, esses lambdas podem ser dados a um std::for_each que itera sobre os elementos do contêiner armazenados localmente em cada classificação.
O YGM é distribuído sob a licença do MIT.
Todas as novas contribuições devem ser feitas sob a licença do MIT.
Consulte a licença-mit, aviso e direitos autorais para obter detalhes.
SPDX-LICense-Identificador: MIT
LLNL-Code-789122