• No results found

Hardware Accelerated Rendering

In document Efficient Shadow Map Filtering (sider 41-44)

Na última seção vimos algumas descrições das subrotinas MPI que serão utilizadas em nosso código de paralelismo. Logicamente, a biblioteca MPI apresenta um número bem maior de subrotinas, mas para o nosso objetivo essas são suficientes. Nesta seção, implementaremos o código paralelo do problema teste devido este ser um problema simples e de fácil controle. Após o código ser testado faremos as modificações pertinentes à implementação paralela do MCSEM 3D. Esta metodologia é semelhante àquela desenvolvida nos capítulos 3 e 4.

O objetivo do problema teste é calcular a solução numérica por meio dos elementos finitos para a seguinte equação

∇2u − τ2u = f (5.1)

em que ∇2 é o operador laplaciano, τ2 = α + iβ é uma constante complexa e o termo fonte f é dado por

f (x, y, z) = −3τ2+ (α/β)2sen(τ x) cos(τ y)eiαβz. (5.2)

Observamos que para a equação do termo fonte, os valores de α e β são escolhidos li- vremente. A idéia do paralelismo é executar um código paralelo para vários α’s e β’s. O Programa 5.5 mostra como usamos o paradigma servidor cliente para este caso.

Como as entradas só podem ser feitas para o processador raiz, que no MPI é identificado por rank 0, esse nó envia os parâmetros de entradaa aos outros nós do processo. Isto pode ser feito através das duas funções sendfrom_pr0 e recvfrom_pr0 apresentadas no Porgrama 5.5. Neste, verificamos que os valores de α’s e β’s estão armazenados em vetores e seus componentes são enviados pelo processo 0 para os demais my_proc-1, onde my_proc é o número total de processadores envolvidos.

Programa 5.5 Enviando e recebendo dados F u n c t i o n s e n d f r o m _ p r 0 Result( srderr ) I m p l i c i t None I n t e g e r :: srderr If ( m y _ r a n k ==0) Then ierr = g e t _ d a t a I N P U T () ; Do dest =1 , my_proc -1 tag =0;

Call M P I _ S e n d( v e c _ a l p h a( dest ) ,1 , M P I _ D o u b l e _ P r ec is io n ,& dest , tag , M P I _ C o m m_ World , srderr ) ;

tag =1;

Call M P I _ S e n d( v e c _ b e t a( dest ) ,1 , M P I _ D o u b l e _ P re ci si on ,& dest , tag , M P I _ C o m m_ World , srderr ) ;

End Do End If End F u n c t i o n s e n d f r o m _ p r 0 F u n c t i o n r e c v f r o m _ p r 0 Result( srderr ) I m p l i c i t None I n t e g e r :: srderr If ( m y _ r a n k /=0 ) Then tag =0;

Call M P I _ R e c v( alpha ,1 , M P I _ D o u b l e _ P r ec is io n , source ,& tag , M P I _ C o m m_ World ,status, srderr ) ; tag =1;

Call M P I _ R e c v( beta ,1 , M P I _ D o u b l e _ P re ci si on , source ,& tag , M P I _ C o m m_ World ,status, srderr ) ;

Call A l l o c a t e _ d a t a _ m e s h () ;

End If

End F u n c t i o n r e c v f r o m _ p r 0

Após enviarmos os α’s e β’s aos seus processadores via uma comunicação ponto a ponto, podemos enviar as entradas que são comuns a todos os processos usando comunicação co- letiva. O Programa 5.6 mostra esse processo através da subrotina MPI_Bcast, que envia as variáveis ntetra_hex, toler e n_source do processador raiz para todo os demais pro- cessadores pertencentes ao comunicador padrão do MPI, o MPI_Comm_World. A variável ntetra_hex indica se o hexaedros da malha 3D são formados por 5 ou 6 tetraedros, já a variável toler é a tolerância da convergência do gradiente biconjugado na solução do sis- tema linear, tipicamente seu valor é de 10−12. A variável n_source é apenas um indicador do número total de processos, que é repassado a todos os processadores do comunicador.

O mesmo procedimento é realizado para as variáveis que controlam a construção da malha. As variáveis N_divx, N_divy e N_divz representam o número total da discretização nas coordenadas x, y e z. A variável NUnknowns significa o número total de icógnitas do sistema linear.

Num problema tridimensional, a discretização da malha deve ser flexivel, afim de com- portar mais racionalmente a memória utilizada. No trecho do Programa 5.6, as variáveis grupo_divx, grupo_divy e grupo_divz representam o número de grupos em que as co- ordenadas x, y e z estão dividos, para este problema, usamos apenas 1 grupo para cada coordenada. Com isso, intf_coordx, intf_coordy e intf_coordz que descrevem as inter- faces desse grupos serão formadas pelos pontos que limitam os domínios em x, y e z, ou seja, o vetor [0 1].

Programa 5.6 Enviando dados coletivos

...

! Número de t e t r a e d r o s f o r m a d o r e s dos h e x a e d r o s.

Call M P I _ B c a s t( ntetra_hex ,1 , MPI_Intgeger ,0 , M P I _ C o m m_ World , mpierr ) ; ! T o l e r â n c i a da s o l u ç ã o n u m é r i c a do s i s t e m a.

Call M P I _ B c a s t( toler ,1 , M P I _ D o u b l e _ P re ci so n ,0 , M P I _ C o m m _Wo rld , mpierr ) ; ! Número total de alpha ’ s e beta ’ s

Call M P I _ B c a s t( n_source ,1 , MPI_Integer ,0 , M P I _ C o m m _Worl d , mpierr ) ; ! V a r i á v e i s da c o n s t r u ç ã o da malha

Call M P I _ B c a s t( N_divx ,1 , MPI_Integer ,0 , M P I _ C o m m _Wo rld , mpierr ) ;

Call M P I _ B c a s t( N_divy ,1 , MPI_Integer ,0 , M P I _ C o m m _Wo rld , mpierr ) ;

Call M P I _ B c a s t( N_divz ,1 , MPI_Integer ,0 , M P I _ C o m m _Wo rld , mpierr ) ;

Call M P I _ B c a s t( NUnknowns ,1 , MPI_Integer ,0 , M P I _ C o m m _Wor ld , mpierr ) ;

Call M P I _ B c a s t( grupo_divx ,Size( g r u p o _ d i v x) , MPI_Integer ,0 , M P I _ C o m m _Worl d , mpierr ) ;

Call M P I _ B c a s t( grupo_divy ,Size( g r u p o _ d i v y) , MPI_Integer ,0 , M P I _ C o m m _Worl d , mpierr ) ;

Call M P I _ B c a s t( grupo_divz ,Size( g r u p o _ d i v z) , MPI_Integer ,0 , M P I _ C o m m _Worl d , mpierr ) ;

Call M P I _ B c a s t( intf_coordx ,Size( i n t f _ c o o r d x ) , M P I _ D o u b l e _ Pr ec is on ,0 , M P I _ C o m m _Wo rld , mpierr ) ;

Call M P I _ B c a s t( intf_coordy ,Size( i n t f _ c o o r d y ) , M P I _ D o u b l e _ Pr ec is on ,0 , M P I _ C o m m _Wo rld , mpierr ) ;

Call M P I _ B c a s t( intf_coordz ,Size( i n t f _ c o o r d z ) , M P I _ D o u b l e _ Pr ec is on ,0 , M P I _ C o m m _Wo rld , mpierr ) ;

Call M P I _ B c a s t( fat_geomx ,Size( f a t _ g e o m x) , M P I _ D o u b l e _ Pr eci so n ,0 , M P I _ C o m m _Wo rld , mpierr ) ;

Call M P I _ B c a s t( fat_geomy ,Size( f a t _ g e o m y) , M P I _ D o u b l e _ Pr eci so n ,0 , M P I _ C o m m _Wo rld , mpierr ) ;

Call M P I _ B c a s t( fat_geomz ,Size( f a t _ g e o m z) , M P I _ D o u b l e _ Pr eci so n ,0 , M P I _ C o m m _Wo rld , mpierr ) ;

...

Em nosso algoritmo, temos a facilidade de discretizar regularmente ou não cada grupo de coordenada. As variáveis fat_geomx, fat_geomy e fat_geomz controlam se as discreti- zações no domínio são regulares ou não. Para a simulação do problema teste usamos uma

discretização regular para as três coordenadas.

É importante dizer que, todas as variáveis da construção da malha foram primeiramente calculadas no nó 0 e depois enviadas para os demais processos, aliviando, deste modo, a carga computacional nos nós que efetivamente resolverão o códio numérico.

Após as entradas para cada processo terem sido enviadas via mensagem ponto a ponto ou coletiva, o processamento do problema teste é executado em cada nó com os seus resultados enviados ao processador 0, como ilustra o Programa 5.7, em que a comunicação ponto a ponto é novamente utilizada.

Programa 5.7 Recebendo dados dos processos

S u b r o u t i n e g e t _ r e s u l t () I m p l i c i t None I n t e g e r :: j , grerr If ( m y _ r a n k ==0)Then A l l o c a t e( b u f f e r _ r e s u l t ( N U n k n o w n s * n _ s o u r c e) , STAT= grerr ) b u f f e r _ r e s u l t =(0. d0 ,0. d0 ) ; End If If( m y _ r a n k /=0)Then tag =3;

Call M P I _ S E N D( sol (1: N U n k n o w n s) , NUnknowns , M P I _ D O U B L E _C OM PLE X ,& 0 , tag , M P I _ C O M M _WO RLD , grerr ) ;

End If

If( m y _ r a n k ==0)Then

tag =3

Do source =1 , n _ s o u r c e

j =( source -1) * N U n k n o w n s +1;

Call M P I _ R E C V( b u f f e r _ r e s u l t ( j : N U n k n o w n s* source ) ,& NUnknowns , M P I _ D O U B L E _ CO MP LEX , source ,& tag , M P I _ C O M M _WO RLD ,status, grerr ) ;

End Do End If

End S u b r o u t i n e g e t _ r e s u l t

5.4.1 Resultados

O cluster disponível para os nosso experimentos possui 11 nós, cada um contendo 2 processadores e 2 Gbytes de RAM num ambiente Linux Red Hat. Como a memória disponível por nó é relativamente baixa, podemos executar modelos de pequenos a médio porte.

O objetivo de usarmos o problema teste é verificar o código paralelo desenvolvido, que será a base para o paralelismo do MCSEM 3D. Em nosso experimento para o problema teste as coordenadas x, y e z variam de 0 a 1 e são discretizadas em 31 pontos. Os resultados em perfis em z para x = 0.5 e y = 0.5 de dois processos estão ilustrados abaixo pela Figura 5.2.

O número total de processos executados foi igual a 11 e os valores dos vetores de entrada que reprentando os α e β foram dados por: α= 2, 2, 2, 2, 2, 2, 1, 3, 5 e 7 e β= -1, 1, 2, 3, -2, 4, 1, 3, 5 e 7. Como observamos a Figura 5.2, a solução e o erro entre os valores numérico e exato quando α = 2 e β = −1 foram muito bons como ilustram as Figuras (5.2a) e (5.2b). Resultado também conseguido para α = 2 e β = 1 mostrados pelas Figuras (5.2c) e (5.2d).

0 0.2 0.4 0.6 0.8 1 −0.8 −0.6 −0.4 −0.2 0 0.2 0.4 0.6 Coordenada z S ol . M E F × S ol . E x at a

Sol. Exata (real) Sol. Exata (imag.) Sol. MEF (real) Sol. MEF (imag.)

(a) Solução para α = 2 e β = −1

0 0.2 0.4 0.6 0.8 1 −2 −1.5 −1 −0.5 0 0.5 1x 10 −4 Coordenada z E rr o d a S ol . M E F Erro (real) Erro (imag.) (b) Erro para α = 2 e β = −1 0 0.2 0.4 0.6 0.8 1 −0.3 −0.2 −0.1 0 0.1 0.2 0.3 0.4 0.5 0.6 Coordenada z S ol . M E F × S ol . E x at a

Sol. Exata (real) Sol. Exata (imag.) Sol. MEF (real) Sol. MEF (imag.)

(c) Solução para α = 2 e β = 1 0 0.2 0.4 0.6 0.8 1 −0.5 0 0.5 1 1.5 2 2.5x 10 −4 Coordenada z E rr o d a S ol . M E F Erro (real) Erro (imag.) (d) Erro para α = 2 e β = 1

Figura 5.2. Comparações entre as soluções exatas e numéricas do problema teste para x = 0.5 e y = 0.5, obtidos em processamento paralelo. Fonte: elaborado pelo Autor.

Para compilarmos os programas em MPI, usamos a diretiva mpif90, Se todos os arquivos fontes estivessem no formato fixo (.for), deveríamos usar a diretiva mpif77. Após a com- pilação e a geração do arquivo executável, por exemplo toy.x. podemos executá-lo usando o seguinte comando no “prompt” do terminal :

Esta diretiva diz que o MPI deve ser executado em 11 nós. Para o nó 0, o nó administrador, os cálculos não são computados. Isto é feito através de uma simples tomada de decisão, como ilustra o fragmento de Programa 5.8.

Programa 5.8 Execução dos programas para os processos de 1 a np−1

... If( m y _ r a n k /= 0)Then Call s e t _ m e s h _ f e m () ; Call s e t _ m a t r i x _ l s () ; Call Solve () ; Call d e a l l o c a t e _ l s () ; End If ...

Após a execução do programa em cada processo devemos sincronizar os resultados a fim de enviar os resultados para o nó 0, que é o nó acessivel aos arquivos de saida. A sincronização é feita pela chamada da subrotina Call MPI_Barrier(MPI_Comm_World,mpierr), e o envio deve ser feito através de uma comunicação ponto a ponto.

In document Efficient Shadow Map Filtering (sider 41-44)