• Nenhum resultado encontrado

Comunicação Coletiva

N/A
N/A
Protected

Academic year: 2021

Share "Comunicação Coletiva"

Copied!
82
0
0

Texto

(1)

Comunicação Coletiva

● Sempre envolve um grupo de processos; ● Sempre envolve todos os processos de um  comunicador; ● Podem ser implementadas com as rotinas  ponto a ponto (mas é má idéia); ● Implementam os padrões de comunicação  paralela vistos no início do curso! ● Podem (mas não precisam) retornar assim  que sua participação na operação esteja  completa;

(2)

Comunicação Coletiva

● A comunicação é considerada completa  quando é possível reusar os buffers de  comunicação; ● Não significa que os outros processos  completaram a comunicação! ● Não necessariamente uma comunicação  coletiva sincroniza o programa (exceto  MPI_BARRIER); ● Não há interferência entre comunicações  coletivas e comunicações ponto a ponto;

(3)

Rotinas

● MPI_BARRIER; ● MPI_BCAST; ● MPI_GATHER; ● MPI_GATHERV; ● MPI_SCATTER; ● MPI_SCATTERV; ● MPI_ALLGATHER; ● MPI_ALLGATHERV; ● MPI_ALLTOALL; ● MPI_ALLTOALLV; ● MPI_ALLTOALLW; ● MPI_REDUCE; ● MPI_ALLREDUCE; ● MPI_REDUCE_ SCATTER; ● MPI_SCAN; ● MPI_EXSCAN;

(4)
(5)
(6)
(7)
(8)

MPI_COMM_BARRIER

● Sincroniza todos os processos em um 

comunicador, só prosseguem quando  todos chamarem esta rotina;

C: int MPI_Barrier(MPI_Comm comm) Fortran: MPI_BARRIER(COMM, IERROR)

INTEGER COMM, IERROR

(9)

MPI_WTIME

● Retorna o tempo em segundos, a partir de 

um instante no passado;

● Ver também MPI_WTICKS;

C: double MPI_Wtime(void)

Fortran: DOUBLE PRECISION MPI_WTIME() C++: double MPI::Wtime()

(10)

MPI_BCAST

● Implementa o “single node broadcast”: um  processo manda a mesma informação para  todos os processos; ● Um argumento indica quem é a fonte do  broadcast; ● Todos os processos devem chamar a  função com os mesmos argumentos para  “root” e “comm”!;

(11)

MPI_BCAST

C:

int MPI_Bcast(void* buffer, int count,

MPI_Datatype datatype, int root, MPI_Comm comm)

Fortran:

MPI_BCAST(BUFFER, COUNT, DATATYPE, ROOT, COMM, IERROR)

<type> BUFFER(*)

INTEGER COUNT, DATATYPE, ROOT, COMM, IERROR

C++:

void MPI::Comm::Bcast(void* buffer, int count, const MPI::Datatype& datatype, int root) const = 0

(12)
(13)
(14)
(15)
(16)
(17)

MPI_SCATTER

● Implementa o Single Node Scatter; ● Um processo manda informações  diferentes (mas de mesmo tamanho) para  todos os outros; ● Todos os processos devem chamar a  função com a mesma raiz e comunicador; ● É possível evitar a cópia local com buffer  “in place”.

(18)

MPI_SCATTER

C:

int MPI_Scatter(

void* sendbuf, int sendcount, MPI_Datatype sendtype, void* recvbuf, int recvcount,

MPI_Datatype recvtype, int root, MPI_Comm comm)

(19)

MPI_SCATTER

Fortran:

MPI_SCATTER(SENDBUF, SENDCOUNT, SENDTYPE, RECVBUF, RECVCOUNT, RECVTYPE, ROOT, COMM, IERROR)

<type> SENDBUF(*), RECVBUF(*)

INTEGER SENDCOUNT, SENDTYPE, RECVCOUNT INTEGER RECVTYPE, ROOT, COMM, IERROR

(20)

MPI_SCATTER

C++:

void MPI::Comm::Scatter(

const void* sendbuf, int sendcount, const MPI::Datatype& sendtype, void* recvbuf, int recvcount,

const MPI::Datatype& recvtype, int root) const = 0

(21)

MPI_SCATTERV

● MPI_SCATTER, com dados de tamanho  diferente; ● Começa a ficar complicado quando os  tipos de dados são complexos; ● É necessário indicar de onde começa o  dado destinado a cada processo; ● Também pode ser usado buffer “in place”; ● “No overlap!”

(22)

MPI_SCATTERV

0 1 2 3 4 5 6 7 2 1 2 3 0 2 3 5 SendBuff Sendcounts Displacements

(23)

MPI_SCATTERV

C:

int MPI_Scatter(

void* sendbuf, int sendcount, MPI_Datatype sendtype,

void* recvbuf, int recvcount, MPI_Datatype recvtype,

(24)

MPI_SCATTERV

Fortran:

MPI_SCATTER(SENDBUF, SENDCOUNT, SENDTYPE, RECVBUF, RECVCOUNT, RECVTYPE, ROOT, COMM, IERROR)

<type> SENDBUF(*), RECVBUF(*)

INTEGER SENDCOUNT, SENDTYPE, RECVCOUNT INTEGER RECVTYPE, ROOT, COMM, IERROR

(25)

MPI_SCATTERV

C++:

void MPI::Comm::Scatter(

const void* sendbuf, int sendcount, const MPI::Datatype& sendtype,

void* recvbuf, int recvcount,

const MPI::Datatype& recvtype, int root) const = 0

(26)

MPI_GATHER

● Operação “dual” ao MPI_SCATTER; ● Cada processo manda uma informação  diferente para o mesmo processo raiz; ● Todos os processos devem chamar com o  mesmo argumento para raiz e  comunicador; ● Pode ser usada comunicação “in place”.

(27)

MPI_GATHER

C:

int MPI_Gather(

void* sendbuf, int sendcount, MPI_Datatype sendtype,

void* recvbuf, int recvcount,

MPI_Datatype recvtype, int root, MPI_Comm comm)

(28)

MPI_GATHER

Fortran:

MPI_GATHER(

SENDBUF, SENDCOUNT, SENDTYPE, RECVBUF, RECVCOUNT, RECVTYPE, ROOT, COMM, IERROR)

<type> SENDBUF(*), RECVBUF(*)

INTEGER SENDCOUNT, SENDTYPE, RECVCOUNT INTEGER RECVTYPE, ROOT, COMM, IERROR

(29)

MPI_GATHER

C++:

void MPI::Comm::Gather(

const void* sendbuf, int sendcount, const MPI::Datatype& sendtype,

void* recvbuf, int recvcount,

const MPI::Datatype& recvtype, int root) const = 0

(30)

MPI_GATHERV

● “Dual” de MPI_SCATTERV;

● Análogo com comprimento variável a 

(31)

MPI_GATHERV

C:

int MPI_Gatherv(

void* sendbuf, int sendcount, MPI_Datatype sendtype,

void* recvbuf, int *recvcounts, int *displs,

MPI_Datatype recvtype, int root, MPI_Comm comm)

(32)

MPI_GATHERV

Fortran:

MPI_GATHERV(

SENDBUF, SENDCOUNT, SENDTYPE, RECVBUF, RECVCOUNTS, DISPLS, RECVTYPE, ROOT, COMM, IERROR) <type> SENDBUF(*), RECVBUF(*)

INTEGER SENDCOUNT, SENDTYPE

INTEGER RECVCOUNTS(*), DISPLS(*)

(33)

MPI_GATHERV

C++:

void MPI::Comm::Gatherv(

const void* sendbuf, int sendcount, const MPI::Datatype& sendtype, void* recvbuf, const int recvcounts[],

const int displs[],

const MPI::Datatype& recvtype, int root) const = 0

(34)

MPI_ALLGATHER

● Equivalente a “size” MPI_GATHER's  simultâneos, com a raiz em cada um dos  processos; ● (ou MPI_GATHER + MPI_BCAST); ● Pode usar comunicação “in place”;

(35)

MPI_ALLGATHER

C:

int MPI_Allgather(

void* sendbuf, int sendcount, MPI_Datatype sendtype,

void* recvbuf, int recvcount, MPI_Datatype recvtype,

(36)

MPI_ALLGATHER

Fortran:

MPI_ALLGATHER(

SENDBUF, SENDCOUNT, SENDTYPE, RECVBUF, RECVCOUNT, RECVTYPE, COMM, IERROR)

<type> SENDBUF(*), RECVBUF(*) INTEGER SENDCOUNT, SENDTYPE INTEGER RECVCOUNT, RECVTYPE INTEGER COMM, IERROR

(37)

MPI_ALLGATHER

C++:

void MPI::Comm::Allgather(

const void* sendbuf, int sendcount, const MPI::Datatype& sendtype,

void* recvbuf, int recvcount,

const MPI::Datatype& recvtype) const = 0

(38)

MPI_ALLGATHERV

● Como MPI_ALLGATHER, com dados de  tamanhos variáveis; ● Normalmente, é necessário enviar os  tamanhos antes de enviar os dados de  interesse; ● Também pode ser “in place”.

(39)

MPI_ALLGATHERV

C:

int MPI_Allgatherv(

void* sendbuf, int sendcount, MPI_Datatype sendtype,

void* recvbuf, int *recvcounts, int *displs,

MPI_Datatype recvtype, MPI_Comm comm)

(40)

MPI_ALLGATHERV

Fortran:

MPI_ALLGATHERV(

SENDBUF, SENDCOUNT, SENDTYPE, RECVBUF, RECVCOUNTS, DISPLS, RECVTYPE, COMM, IERROR)

<type> SENDBUF(*), RECVBUF(*) INTEGER SENDCOUNT, SENDTYPE

INTEGER RECVCOUNTS(*), DISPLS(*) INTEGER RECVTYPE, COMM

(41)

MPI_ALLGATHERV

C++:

void MPI::Comm::Allgatherv(

const void* sendbuf, int sendcount, const MPI::Datatype& sendtype,

void* recvbuf, const int recvcounts[], const int displs[],

const MPI::Datatype& recvtype) const = 0

(42)

MPI_ALLTOALL

● Cada processo manda dados diferentes  para todos os outros processos; ● “Total Exchange”; ● Não há opção para comunicação “in­ place”;

(43)

MPI_ALLTOALL

C:

int MPI_Alltoall(

void* sendbuf, int sendcount, MPI_Datatype sendtype,

void* recvbuf, int recvcount, MPI_Datatype recvtype,

(44)

MPI_ALLTOALL

Fortran:

MPI_ALLTOALL(

SENDBUF, SENDCOUNT, SENDTYPE, RECVBUF, RECVCOUNT, RECVTYPE, COMM, IERROR)

<type> SENDBUF(*), RECVBUF(*) INTEGER SENDCOUNT, SENDTYPE INTEGER RECVCOUNT, RECVTYPE INTEGER COMM, IERROR

(45)

MPI_ALLTOALL

C++:

void MPI::Comm::Alltoall(

const void* sendbuf, int sendcount, const MPI::Datatype& sendtype,

void* recvbuf, int recvcount,

const MPI::Datatype& recvtype) const = 0

(46)

MPI_ALLTOALLV

● MPI_ALLTOALL com tamanho de  mensagem variável; ● Quase o mais genérico possível; ● Normalmente, o tamanho das mensagens  é enviado primeiro, com um  MPI_ALLTOALL; ● Não há opção “in place”;

(47)

MPI_ALLTOALLV

C:

int MPI_Alltoallv(

void* sendbuf, int *sendcounts, int *sdispls,

MPI_Datatype sendtype,

void* recvbuf, int *recvcounts, int *rdispls,

MPI_Datatype recvtype, MPI_Comm comm)

(48)

MPI_ALLTOALLV

Fortran:

MPI_ALLTOALLV(

SENDBUF, SENDCOUNTS, SDISPLS, SENDTYPE,

RECVBUF, RECVCOUNTS, RDISPLS, RECVTYPE, COMM, IERROR)

<type> SENDBUF(*), RECVBUF(*)

INTEGER SENDCOUNTS(*), SDISPLS(*), SENDTYPE INTEGER RECVCOUNTS(*), RDISPLS(*), RECVTYPE INTEGER COMM, IERROR

(49)

MPI_ALLTOALLV

C++:

void MPI::Comm::Alltoallv( const void* sendbuf,

const int sendcounts[], const int sdispls[],

const MPI::Datatype& sendtype,

void* recvbuf, const int recvcounts[], const int rdispls[],

const MPI::Datatype& recvtype) const = 0

(50)

MPI_REDUCE

● Acumulação global; ● Combina elementos de cada processo com  uma operação binária fornecida pelo  usuário; ● Deve ser chamada por todos os membros  do grupo com argumentos compatíveis; ● Pode ser aplicada a vetores de elementos,  e a operação é aplicada aos elementos  correspondentes; ● Pode usar comunicação “in place”;

(51)

MPI_REDUCE

● As operações são sempre associativas; ● As operações pré­definidas são também  comutativas; ● O usuário pode definir operações, que não  precisam ser comutativas; – Neste caso, a ordem de avaliação é a  ordem dos ranks dos processos; ● Curiosidade: operações de ponto flutuante  não são estritamente associativas e  comutativas!

(52)

MPI_REDUCE - Operações

● MPI_MAX ● MPI_MIN ● MPI_SUM ● MPI_PROD ● MPI_LAND ● MPI_BAND ● MPI_LOR ● MPI_BOR ● MPI_LXOR ● MPI_BXOR ● MPI_MAXLOC ● MPI_MINLOC

(53)
(54)

MPI_REDUCE

C:

int MPI_Reduce(

void* sendbuf, void* recvbuf,

int count, MPI_Datatype datatype, MPI_Op op, int root, MPI_Comm comm)

(55)

MPI_REDUCE

Fortran:

MPI_REDUCE(

SENDBUF, RECVBUF, COUNT, DATATYPE, OP,

ROOT, COMM, IERROR)

<type> SENDBUF(*), RECVBUF(*) INTEGER COUNT, DATATYPE, OP INTEGER ROOT, COMM, IERROR

(56)

MPI_REDUCE

C++:

void MPI::Comm::Reduce(

const void* sendbuf, void* recvbuf, int count,

const MPI::Datatype& datatype, const MPI::Op& op, int root)

(57)

MPI_{MIN,MAX}LOC

● Calculam o mínimo (máximo) e um índice  associado; ● Normalmente, a posição em um vetor, ou o  rank do processo; ● Usa tipos de dados especiais, os índices  são sempre inteiros e os elementos podem  ter tipos variados;

(58)
(59)

MPI_OP_CREATE

● Usuário pode criar funções de redução; ● Deve ser associativa, e pode ou não ser  comutativa; – Neste caso, a ordem aplicada é a ordem  padrão, crescente no rank; ● Esta função associa uma função escrita  pelo programador a uma variável que pode  ser usada como operação em  MPI_REDUCE;

(60)

MPI_OP_CREATE

C: int MPI_Op_create( MPI_User_function *function, int commute, MPI_Op *op)

(61)

MPI_OP_CREATE

Fortran: MPI_OP_CREATE(FUNCTION, COMMUTE, OP, IERROR) EXTERNAL FUNCTION LOGICAL COMMUTE

(62)

MPI_OP_CREATE

C++:

void MPI::Op::Init(

MPI::User_function* function, bool commute)

(63)

MPI_OP_CREATE

● Claro que a função tem que obedecer a um  protótipo; ● Os argumentos desta função são vetores, o  que permite eficiência na aplicação; ● Não é permitido chamar funções de  comunicação do MPI dentro desta função! ● É permitido chamar MPI_ABORT em caso  de erros;

(64)

MPI_OP_CREATE – Protótipo

C:

typedef void MPI_User_function( void *invec, void *inoutvec, int *len,

(65)

MPI_OP_CREATE – Protótipo

Fortran:

SUBROUTINE

USER_FUNCTION(INVEC, INOUTVEC, LEN, TYPE)

<type> INVEC(LEN), INOUTVEC(LEN) INTEGER LEN, TYPE

(66)

MPI_OP_CREATE – Protótipo

C++:

typedef void MPI::User_function( const void* invec,

void *inoutvec, int len, const Datatype& datatype);

(67)

MPI_ALLREDUCE

● MPI_REDUCE, com resultado em todos os  processadores; ● Normalmente é exatamente o que  interessa; ● Mesmas características e facilidades que  MPI_REDUCE; ● Suporta comunicação “in place”

(68)

MPI_ALLREDUCE

C:

int MPI_Allreduce(

void* sendbuf, void* recvbuf, int count,

MPI_Datatype datatype, MPI_Op op,

(69)

MPI_ALLREDUCE

Fortran: MPI_ALLREDUCE( SENDBUF, RECVBUF, COUNT, DATATYPE, OP, COMM, IERROR)

<type> SENDBUF(*), RECVBUF(*) INTEGER COUNT, DATATYPE

(70)

MPI_ALLREDUCE

C++:

void MPI::Comm::Allreduce( const void* sendbuf, void* recvbuf,

int count,

const MPI::Datatype& datatype, const MPI::Op& op) const = 0

(71)

MPI_REDUCE_SCATTER

● Executa a redução em um vetor, depois  envia partes de tamanho diferente deste  vetor para os processos do grupo; ● Equivalente a MPI_REDUCE (com um  vetor) seguido de MPI_SCATTERV; ● Suporta comunicação “in place”;

(72)

MPI_REDUCE_SCATTER

C: int MPI_Reduce_scatter( void* sendbuf, void* recvbuf, int *recvcounts, MPI_Datatype datatype, MPI_Op op, MPI_Comm comm)

(73)

MPI_REDUCE_SCATTER

Fortran:

MPI_REDUCE_SCATTER(

SENDBUF, RECVBUF, RECVCOUNTS, DATATYPE, OP, COMM,

IERROR)

<type> SENDBUF(*), RECVBUF(*)

INTEGER RECVCOUNTS(*), DATATYPE INTEGER OP, COMM, IERROR

(74)

MPI_REDUCE_SCATTER

C++:

void MPI::Comm::Reduce_scatter( const void* sendbuf,

void* recvbuf, int recvcounts[], const MPI::Datatype& datatype, const MPI::Op& op) const = 0

(75)

MPI_SCAN

● Operação de Prefixo Inclusivo: o  processador i obtém o resultado da  redução dos processos 0 até i; ● Todo o resto como MPI_REDUCE; ● Há opção “in place”;

(76)

MPI_SCAN

C: int MPI_Scan( void* sendbuf, void* recvbuf, int count, MPI_Datatype datatype, MPI_Op op, MPI_Comm comm )

(77)

MPI_SCAN

Fortran:

MPI_SCAN(

SENDBUF, RECVBUF, COUNT, DATATYPE,

OP, COMM, IERROR)

<type> SENDBUF(*), RECVBUF(*) INTEGER COUNT, DATATYPE

(78)

MPI_SCAN

C++:

void MPI::Intracomm::Scan( const void* sendbuf, void* recvbuf,

int count,

const MPI::Datatype& datatype, const MPI::Op& op) const

(79)

MPI_EXSCAN

● Operação de Prefixo Exclusivo: o  processador i recebe o resultado da  redução dos processos de 0 a i­1; ● No processo 0 o resultado é indefinido; ● Todo o resto análogo a MPI_REDUCE; ● Não há opção “in place”;

(80)

MPI_EXSCAN

C: int MPI_Exscan( void* sendbuf, void* recvbuf, int count, MPI_Datatype datatype, MPI_Op op, MPI_Comm comm )

(81)

MPI_EXSCAN

Fortran:

MPI_EXSCAN(

SENDBUF, RECVBUF, COUNT, DATATYPE,

OP, COMM, IERROR)

<type> SENDBUF(*), RECVBUF(*) INTEGER COUNT, DATATYPE

(82)

MPI_EXSCAN

C++:

void MPI::Intracomm::Exscan( const void* sendbuf,

void* recvbuf, int count,

const MPI::Datatype& datatype, const MPI::Op& op) const

Referências

Documentos relacionados

• O módulo principal.v serve para correr todos os módulos acima descritos aquando da simulação em Veriwell, iniciando as variáveis enable, reset e tecla; de seguida evoca os

Parece assim que os cardiologistas portugueses têm uma percec¸ão globalmente adequada da utilidade clínica da angio-TC, identificando os doentes que mais beneficiam da

INTEGER COUNT, DATATYPE, DEST, IERROR INTEGER SENDTAG, SOURCE, RECVTAG, COMM

Contudo, temos a convicção de que este Dossiê, ao se propor a uma tarefa tão audaciosa, reúne contribuições relevantes e de alta qualidade intelectual originárias

[r]

Os psicólogos ajudam diariamente muitas pessoas de todas as ida- des e com todos os tipos de problemas que buscam os conhecimentos da psicologia para ajudá-las a terem uma melhor

Haveria agora algo que dizer -e haverá muito mais que estudar, pois não têm sido regiões que tenham merecido particular atenção por parte dos historiadores- sobre certas

[r]