Laboratório de Programação Paralela 2017.2
Laboratório 1 - Introdução ao MPI
Neste laboratório, voce irá programar utilizando o padrão MPI (Message Passing Interface).
Este padrão possui várias implementações e usaremos a implementação Open MPI .
Os programas deverão ser codificados na linguagem C.
Dicas de uso das rotinas MPI
- Um programa MPI deve seguir a seguinte estrutura:
- Todo programa MPI escrito em C deve incluir a diretiva
#include "mpi.h"
- Todas as chamadas das rotinas MPI, começam com o nome MPI_ e variáveis e funções do programa não devem iniciar com MPI_ ou PMPI_ .
- MPI usa objetos chamados comunicadores e grupos para definir quais processos podem se comunicar uns com os outros.
A maioria das rotinas MPI requer que seja especificado um comunicador como um argumento. Por enquanto, basta usar MPI_COMM_WORLD sempre que um comunicador for necessário - é o comunicador predefinido que inclui todos os seus processos MPI.
- Dentro de um comunicador, cada processo tem seu próprio identificador que é um número inteiro atribuído pelo sistema quando o processo é inicializado.
Rotinas para gerenciar o ambiente
Estas rotinas são usadas para verificar e configurar o ambiente de execução MPI.
Algumas das mais utilizadas são:
- MPI_Init (&argc,&argv)
Inicializa o ambiente de execução MPI. Esta função deve ser chamada em cada programa MPI, antes de qualquer outra função MPI e apenas uma vez em um programa MPI. Pode ser usada para passar os argumentos de linha de comando para todos os processos, embora isso não seja exigido pelo padrão e dependa da implementação.
- MPI_Comm_size (comm,&size)
Retorna o número total de processos MPI em um comunicador específico. Se o comunicador for MPI_COMM_WORLD, esta função retorna o número de tarefas MPI disponíveis para a aplicação.
- MPI_Comm_rank (comm,&rank)
Retorna o número de rank do processo MPI que chama esta rotina dentro do comunicador especificado. Inicialmente, a cada processo será atribuído um único inteiro entre 0 e número de tarefas - 1 dentro do comunicador MPI_COMM_WORLD. Se um processo se torna associado com outros comunicadores, ele terá uma classificação única dentro de cada um destes comunicadores.
- MPI_Abort (comm,errorcode)
Finaliza todos os processos MPI associados ao comunicador. Na maioria das implementações MPI, ele encerra TODOS os processos independentemente do comunicador especificado.
- MPI_Get_processor_name (&name,&resultlength)
Retorna o nome do processador. Também retorna o comprimento do nome. O buffer para "name" deve ter, a capacidade de armazenar pelo menos MPI_MAX_PROCESSOR_NAME caracteres.
- MPI_Get_version (&version,&subversion)
Retorna a versão e a subversão do padrão MPI implementado pela biblioteca.
- MPI_Wtime ()
Retorna um tempo de relógio de parede decorrido em segundos (precisão dupla) no processador que fez a chamada da rotina.
- MPI_Finalize ()
Termina o ambiente de execução MPI. Esta função deve ser a última rotina MPI chamada em cada programa MPI - nenhuma outra rotina MPI pode ser chamada depois dela.
Dicas de compilação e execução
Exercício 1
- Crie um programa MPI que seja SPMD e realize os seguintes passos:
- Incluir o arquivo header apropriado
- Identificar a tarefa de rank igual a 0 como a tarefa "MESTRE"
- Inicializar o ambiente MPI
- Obter o número total de tarefas
- Obter o ranking da tarefa
- Verificar se a quantidade de tarefas é um número par e terminar o programa caso não seja.
- Todas as tarefas devem definir uma outra tarefa para enviar uma mensagem bloqueante que será recebida de forma bloqueante pela outra tarefa.
Para definir a tarefa destino, a tarefa fonte verifica se o ranking dela é menor que a metade do número de tarefas.
Em caso positivo, a tarefa destino será definida como a tarefa que tenha o ranking igual ao valor dado pela metade das tarefas somado com o identificador da tarefa fonte.
Em caso negativo, a tarefa destino será definida como a tarefa que tenha o ranking igual ao valor dado pela metade das tarefas subtraído do identificador da tarefa fonte.
- Cada tarefa deve enviar à sua tarefa destino uma única mensagem contendo um número inteiro indicando seu ranking
- Cada tarefa destino recebe da sua tarefa fonte uma única mensagem de inteiro com o ranking da tarefa fonte
- Após o envio / recepção, cada tarefa imprime algo como "Tarefa ## enviou tarefa para **" onde ## é o identificador da tarefa fonte e ** é o identificador da tarefa destino.
- Teste o seu programa variando o número de processadores
- Relate os acertos e erros ocorridos e suas observações em relação à execução do programa variando o número de processadores.
Exercício 2
- Implemente o programa anterior utilizando funções de envio e recebimento não bloqueantes.
- Teste o seu programa variando o número de processadores
- Relate os acertos e erros ocorridos e suas observações em relação à execução do programa variando o número de processadores.
Exercício 3
- Crie um programa MPI que seja SPMD e realize os seguintes passos:
- A tarefa MESTRE inicializa um vetor como no programa ser_array.c e, em seguida, distribui uma parcela igual desse vetor para as outras tarefas.
- Depois que as outras tarefas recebem sua parte do vetor, elas e a tarefa MESTRE executam a operação realizada em ser_array para cada elemento do vetor recebido e, calculam a soma dos novos elementos calculados da sua parte do vetor.
- Todas as tarefas mantêm o resultado obtido para a sua porção do vetor.
- Quando uma tarefa conclui suas operações, ela envia os novos elementos da sua parte do vetor para a tarefa MESTRE, com exceção da tarefa MESTRE.
- Uma chamada de comunicação coletiva MPI deve ser usada para coletar e somar as somas mantidas por cada tarefa.
- No final, a tarefa mestre deve exibir os cinco primeiros elementos de cada parte do vetor que foi enviada para uma tarefa e a soma global de todos os elementos do vetor.
- Teste o seu programa variando o número de processadores.Verifique as máquinas em que estão sendo executadas as tarefas e
o comportamento do programa em relação ao conjunto de máquinas.
- Faça testes utilizando a opção "slots=X" ao lado do nome de cada máquina no arquivo hostfile para indicar o número de cores que
devem ser usados em cada máquina.
- Relate os acertos e erros ocorridos e suas observações em relação à execução do programa variando o número de processadores, de slots e localização das máquinas.