Melhores metodologias para gerenciar uma malha na computação paralela por elementos finitos?

11

Atualmente, estou desenvolvendo um método de decomposição de domínio para a solução do problema de espalhamento. Basicamente, estou resolvendo um sistema de Helmholtz BVPs iterativamente. Discreto as equações usando o método dos elementos finitos sobre malhas triangulares ou tetraédricas. Estou desenvolvendo o código para minha tese de doutorado. Estou ciente de algumas das bibliotecas de elementos finitos existentes no mercado, como deal.ii ou DUNE, e embora elas sejam ótimas, com design inspirador e API, para fins de aprendizado, eu queria desenvolver meu próprio aplicativo a partir do zero.

Estou em um ponto em que tenho minhas versões seriais em execução e agora quero paralelizá-las. Afinal, é um dos pontos fortes da estrutura de decomposição de domínio formular algoritmos fáceis de paralelizar, pelo menos em princípio. Na prática, porém, há muitos detalhes que se deve considerar. O gerenciamento de malha é um deles. Se os aplicativos atingirem alta resolução enquanto escalam bem para muitas CPUs, a replicação de uma malha inteira em cada CPU é ineficiente.

Eu queria perguntar aos desenvolvedores que trabalham em aplicativos semelhantes em ambientes de computação de alto desempenho como eles lidam com esse problema.

Existe uma biblioteca p4est para gerenciamento de malha distribuída. Eu não preciso de AMR, portanto pode ser um exagero, pois estou interessado apenas em usar malhas uniformes e não tenho certeza se ele pode refinar malhas triangulares. Eu também poderia simplesmente criar uma malha uniforme, depois alimentá-la em um dos particionadores de malha e fazer algum processamento posterior da saída.

A abordagem mais simples parece criar um arquivo separado para cada partição que contém informações de malha relevantes apenas para essa partição específica. Esse arquivo seria lido por uma única CPU, responsável pela montagem do sistema discreto naquela parte da malha. Obviamente, algumas informações de conectividade / vizinhança da partição global também precisariam ser armazenadas em um arquivo lido por todas as CPUs para comunicação entre processos.

Que outras abordagens existem por aí? Se alguns de vocês pudessem compartilhar, quais são algumas das metodologias mais usadas no setor ou nas instituições governamentais de pesquisa relacionadas ao tratamento desse problema? Eu sou muito novo na programação de um solucionador de elementos finitos paralelo e queria ter uma idéia se estou pensando ou não sobre esse problema corretamente e como os outros estão se aproximando. Qualquer conselho ou indicação de artigos de pesquisa relevantes seria muito apreciado!

Desde já, obrigado!

midurad
fonte
Se você está procurando um particionador de malha - o METIS seria uma boa escolha. Veja também o ParMETIS. O gerenciamento de malhas é outra história, o ITAPS iMesh pode ser a solução para você. Verifique também as respostas da minha pergunta aqui: scicomp.stackexchange.com/questions/4750/…
Krzysztof Bzowski,
@KrzysztofBzowski: você também usou a biblioteca escocesa? Eu queria saber qual é a diferença entre Scotch e Metis quando se trata de elementos finitos. O projeto iMesh parece muito interessante. Vou ler mais sobre isso nos próximos dias. Eu sei sobre deal.II e DUNE. Lembro-me de olhar para o openMesh há algum tempo, mas achei que seria mais fácil implementar a funcionalidade que eu precisava do zero. Para malhas seqüenciais, basicamente adaptei a estrutura de dados de meia borda / face apresentada neste link de artigo Obrigado!
midurad

Respostas:

7

Se você não estiver usando AMR e não quiser escalar além dos núcleos 1K-4K, basta fazer isso.

  1. A classificação 0 lê toda a malha e a particiona usando METIS / Scotch etc. (Nota: Esta é uma operação serial).

  2. O posto 0 transmite as informações de particionamento de elemento / nó para todos os outros níveis e libera a memória (usada para armazenar a malha)

  3. Todas as classificações leem os nós / elementos que possuem (incluindo nós fantasmas) do mesmo arquivo de entrada (Nota: as classificações de 2000 que acessam o mesmo arquivo de entrada podem parecer lentas, mas não são práticas, embora possam ser ruins para o sistema de arquivos, mas nós estão fazendo isso apenas uma vez).

  4. Todos os níveis precisam criar mapeamentos de nó / elemento / dof local para global para aplicação de BCs e montagem de matrizes e renumerar os nós.

Depois de tudo dito e feito, todos os dados em uma classificação serão locais, portanto, você poderá escalar bem (em memória). Eu faço tudo isso em cerca de 100 linhas (veja as linhas 35-132 aqui ) em um pequeno código meu.

Agora, se sua malha é muito grande (por exemplo,> 100-250 milhões de elementos), você não pode particioná-la usando o METIS em um único nó e precisa do ParMETIS / PT-Scotch, então você tem o trabalho adicional de particioná-la em paralelo antes de todos os núcleos / fileiras podem lê-lo. Nesse cenário, pode ser mais fácil manter a fase de particionamento separada do código principal por razões logísticas.

Btw AMR libs geralmente não fazem tets. O PETSc também é uma boa opção para paralelização do seu código.

Edit: Veja também aqui e aqui .

stali
fonte
Obrigado por compartilhar seu código! Provavelmente vou seguir a rota que você descreveu acima. Parece o menos complicado e eu já tenho uma idéia de como fazer isso. Além disso, será um bom exercício de programação MPI. Você mencionou que as bibliotecas AMR geralmente não lidam com tets. Seria porque um refinamento ingênuo, por exemplo, de um quadrilátero de malhas triangulares poderia levar a uma malha de má qualidade? O quadrilátero de refino parece fácil, mas dividir um tet em quatro parece difícil se alguém quiser preservar a qualidade. Existe um wrapper C ++ para PETSc, talvez? Eu posso usar C, mas C ++ seria melhor.
midurad
@midurad Se você prefere C ++ a C, considere o Trilinos, que é uma biblioteca C ++ comparável ao PETSc. Além disso, o Trilinos possui um pacote (Zoltan) que você pode usar para realizar o particionamento de malha.
Dr_Sam
@midurad Você só precisa de muito poucas chamadas MPI se usar o PETSc. Refinar as notas deve ser fácil, mas lidar (com eficiência) com as estruturas de dados dinâmicas associadas pode exigir algum pensamento e trabalho. Você deve poder usar o PETSc com C ++, mas, considerando seus requisitos, libmesh pode ser uma opção viável (acho que suporta AMR e tets).
stali
Obrigado a todos pela informação. Isso foi muito útil.
midurad
2

Isso pode não ser uma surpresa para você, uma vez que desenvolvo um acordo.II, mas eis a minha perspectiva: quando falo com os alunos, normalmente digo a eles que desenvolvam seu próprio protótipo no começo para que possam ver como é feito. Mas então, uma vez que eles têm algo pequeno em execução, eu os faço usar uma biblioteca que lhes permite ir muito mais longe, porque eles não precisam reinventar a roda com basicamente todos os passos que dão.

No seu caso, você já viu como implementar um simples solucionador de Helmholtz. Mas você passará os próximos 6 meses escrevendo o código necessário para fazê-lo em paralelo; você passará outros 3 meses se desejar usar geometrias mais complicadas. Você passará mais 6 meses se quiser um solucionador eficiente. E todo esse tempo você está escrevendo um código que já foi escrito por outra pessoa e que, em certo sentido, não o aproxima do que realmente precisa fazer pelo seu doutorado: desenvolva algo novo que não foi feito antes. Se você seguir esse caminho, passará de 2 a 3 anos do seu doutorado refazendo o que outros fizeram e talvez 1 ano fazendo algo novo.

A alternativa é que agora você passa 6 meses aprendendo uma das bibliotecas existentes, mas depois disso você terá 2-3 anos em que realmente faz coisas novas, coisas em que a cada duas semanas você pode entrar no escritório do consultor e mostrar-lhe / ela é algo verdadeiramente novo, que funciona em escalas massivamente grandes, ou é muito legal em outros aspectos. Eu acho que você provavelmente já vê onde estou indo com isso agora.

Wolfgang Bangerth
fonte
3
Pergunta honesta, já que você é claramente uma autoridade nisso: quem escreverá a próxima geração de estruturas como deal.ii se ninguém na atual safra de estudantes de doutorado enfrentar problemas como esse? Já estamos vendo uma tendência problemática de estudantes de doutorado que nunca compilaram um programa. É um pouco preocupante para mim que as habilidades médias em desenvolvimento de código pareçam estar em um declínio contínuo nos cientistas da computação.
Aurelius
1
É uma pergunta justa. Você precisa de estudantes de graduação tão obstinados e teimosos quanto eu :-) Mas minha resposta é que só porque provavelmente precisamos de algumas pessoas que o fazem, isso não significa que devemos incentivar todos a passar anos de suas vidas repetindo o que outros já implementaram.
Wolfgang Bangerth 14/03
2
Sim, é justo. A IMO, a maior coisa que reteve o mundo da pesquisa em CFD nos últimos 20 anos, foi a falta de talento em engenharia de software e a rejeição das práticas modernas de software pelos barbudos. Estruturas à parte, muitos estudantes de doutorado são impedidos por códigos herdados ruins e pela incapacidade de construir rapidamente as peças complexas de software necessárias para métodos numéricos modernos em hardware moderno.
21714 Aurelius
Não discordo da afirmação sobre os barbas cinzentas (embora a minha também esteja ficando cinza hoje em dia ...). Mas eles também veem que você precisa escolher entre códigos herdados ou reinventar a roda quando tiver um novo aluno de graduação. Pouquíssimas pessoas gostam de ter sucesso com o software que escrevem (não obstante o autor atual), e você não deseja enviar um estudante de graduação promissor por esse caminho, se não souber que ele pode fazer carreira nele.
precisa saber é o seguinte
0

Esta não é uma resposta completa.

Para a implementação de métodos de decomposição de domínio paralelo, encontrei algumas complicações. Primeiro, pode-se usar muitos processadores para um subdomínio ou alimentar um processador com muitos subdomínios e pode-se implementar dois paradigmas. Segundo, a forma subestruturada de métodos de decomposição de domínio requer a separação de faces, arestas e vértices dos subdomínios (não dos elementos). Eu não acho que essas complicações sejam prontamente incluídas no gerenciamento de malha paralela. A situação se torna mais simples se você considerar um processador para um subdomínio e usar o método RAS / RASHO sobreposto. Mesmo nesse caso, você gerenciaria melhor seu layout paralelo,

Hui Zhang
fonte