(como) escrever simulações que são mais rápidas?

16

Comecei a usar python como a linguagem de programação para realizar todas as minhas tarefas no CFD. Eu tenho uma experiência muito pequena em programação. Sou formado em engenharia mecânica e estou cursando o ensino superior em engenharia aeroespacial.

Às vezes, o aspecto computacional do CFD se torna mais tedioso do que manipular as equações ou fazer as contas.

Quais são as diretrizes gerais que tornam o programa mais rápido? Quais são os truques para fazer as coisas paralelamente? Como escrever os códigos que correm mais rápido?

Onde obtenho recursos (fáceis de entender para um leigo como eu) que respondem às perguntas acima?

Subodh
fonte
@ Dan, acho que não. Estou solicitando 'qualquer' recurso possível que ajude a entender as táticas de programação mais recentes. Não tenho requisitos ou condições específicas impostas. Mais especificamente, estou solicitando os recursos que ajudarão a tornar os códigos mais elegantes.
Subodh
Você está consertado em python ou consideraria C ++? Nesse caso, sugiro duas coisas: aprenda C ++, encontre uma biblioteca de código-fonte aberto (no meu caso, OpenFOAM), não desenvolva coisas do zero, mas aprenda, vasculhe um pedaço de código avançado, aprenda sobre seu aspecto, mude e experimento, tudo conduzido com um objetivo específico: no seu caso, por exemplo, simulações aerodinâmicas.
tmaric
@ tomislav-maric, muito obrigado. Eu não sou um 'pythoniano' estrito. De fato, sendo um novato em campo, acho que tenho muitas opções disponíveis à minha frente. Também estou aprendendo o OpenFOAM. Então, eu concordo com a sua opinião de que se deve começar a trabalhar em um projeto e aprender com isso (ou, em suma, sujar as mãos), que é precisamente o que devo fazer!
Subodh
@smj btw, eu também venho de um bacharelado em engenharia mecânica e agora sou um estudante de pós-graduação em ciências da computação (a mech. engenharia não me preparou para isso) ... Se você estiver trabalhando com OF, procure o livro C ++ lista no estouro de pilha e comece a aprender. Você precisa de três coisas: C ++, OpenFOAM e conhecimento da ciência da computação. OpenFOAM e ciência da computação, você pode aprender de uma maneira dendrítica: encontre uma tarefa e faça-a, aprendendo o que você precisa. Ter algo terminado irá motivá-lo. Quanto ao C ++: comece com o C ++ Primer e aprenda-o. Boa sorte! :)
tmaric

Respostas:

19

Tentarei responder à sua pergunta, considerando que você está solicitando especificamente o Python. Descreverei meu próprio método de resolver um problema de simulação. Estratégias para simulações mais rápidas são fornecidas nesta descrição.

Primeiro, protótipo de novas simulações em Python. Obviamente, tento usar o NumPy e o SciPy o máximo possível. Enquanto o NumPy fornece um tipo de dados de matriz adequado para simulações numéricas, o SciPy oferece diversas rotinas numéricas trabalhando com matrizes NumPy.

Depois que os protótipos funcionam mais ou menos, tento aprender quais partes do programa ou script são o gargalo. Existem candidatos típicos para isso:

  • Os loops em Python são lentos. Muito devagar.
  • Como o Python usa digitação de pato , as funções de chamada podem ser lentas.

Eu uso uma estratégia simples de criação de perfil para saber onde é gasto todo o tempo de execução. Usando o shell IPython (que não posso recomendar o suficiente), eu executo meu script com

%timeit script.py

Este "comando mágico" fará a criação de perfil (usando timeit ) para você e apresentará uma lista com os horários após o término do script. Use esta lista para descobrir onde seu código está muito lento.

Depois de definir as partes que precisam ser aceleradas, considere o uso de idiomas compilados. Vou apontar para duas soluções.

Primeiro, há a linguagem Cython . Cython é uma linguagem de programação muito semelhante ao Python (de fato, o código Python também é frequentemente um código Python válido); no entanto, o compilador Cython converte os arquivos Cython em código C, que pode ser compilado em um módulo utilizável no Python. Cython entende matrizes NumPy. Existem duas maneiras pelas quais o uso do Cython pode ajudá-lo: primeiro, você pode introduzir tipos de dados. Isso irá acelerar as chamadas de função. Além disso, se você iterar sobre matrizes, seu loop será executado mais rapidamente (na verdade, se você digitar a variável dummy e a matriz, obterá um loop C simples!). Segundo, em meus experimentos, mesmo os scripts sem tipo são executados um pouco mais rápido, devido ao fato de serem compilados em vez de interpretados.

A outra linguagem compilada que será útil para você é o Fortran. Existem diferentes maneiras de usar o Fortran com o Python ( f2py , fortwrap , Cython ). Quanto a mim, pessoalmente, o f2py parece ser a maneira mais fácil, descreverei rapidamente o que ele faz. O f2py pode compilar o código Fortran nos módulos Python. Isso permitirá que você use matrizes NumPy como variáveis ​​de entrada e saída do espaço Python. No espaço Fortran, essas serão matrizes Fortran comuns. Você pode operar com a velocidade máxima de Fortran.

Pessoalmente, costumo usar o Cython, onde o número de chamadas de função é o gargalo. Para coisas com loop pesado, prefiro o f2py (talvez porque possua um forte histórico de Fortran).

Em nota adicional no Fortran: o Fortran moderno lê e escreve muito semelhante ao NumPy - a sintaxe está muito próxima. Isso facilita a conversão do código NumPy para o código Fortran.

Observe que o Cython e o f2py suportam o paralleismo de alguma forma. Para Cython, você encontrará ajuda aqui , enquanto para Fortran, existem técnicas padrão como OpenMP ou MPI. Além disso, também existem wrappers P ython para MPI . Pessoalmente, eu uso o mpi4py no nível Python, bem como o OpenMP no Fortran.

Deixe-me recomendar um pouco de literatura: o livro Python Scripting For Computational Science de H.-P. Langtangen é um ótimo recurso no Python em geral, bem como em estratégias para tornar o Python um pouco mais rápido. Infelizmente, AFAIR, ele não menciona nada no Cython. Como segundo recurso, você pode olhar para esses slides . Eles dão exemplos de tudo o que mencionei neste post (veja também o código e as fontes aqui ). Existem muitos outros bons conjuntos de slides na internet.

Se você tiver perguntas mais específicas, teremos todo o gosto em ajudar!

AlexE
fonte
11
Veja também palestras sobre otimização de código para obter uma visão geral dos criadores de perfil de Python.
Denis #
7

Para CFD + Python, existe uma solução: http://pythonflu.wikidot.com/ Essas são ligações do Python no topo do OpenFOAM (que já foram mencionadas nos comentários das perguntas). Essas ligações permitem a programação no "nível do solucionador" (há exemplos em que os solucionadores originais do OpenFOAM são replicados em Python e não são mais lentos que os originais - os loops lentos mencionados em outra resposta não são um problema aqui, pois os "loops internos" acontecem no código C ++ do OpenFOAM).

A vantagem dessas ligações também é que toda a paralelização no OpenFOAM acontece abaixo do nível do solucionador, para que você não precise se preocupar com isso (assim como com outras coisas que o núcleo do OpenFOAM cuida: entrada / saída, solucionador linear, discretização do operador)

Portanto, se você deseja apenas escrever um novo solucionador e não adicionar novos recursos ao núcleo OF (condições de contorno, solucionador linear, etc.), o PythonFlu pode ser suficiente para você e evitar o C ++ (que tem uma cura de aprendizado muito maior do que Pitão)

PS: originalmente queria adicionar isso como um comentário à discussão da pergunta original, mas minha reputação não me permite isso

bgschaid
fonte
Olá Bernhard! Bem-vindo ao scicomp! :)
tmaric