Qual é uma boa maneira de executar estudos de parâmetros em C ++


29

O problema

Atualmente, estou trabalhando em uma simulação de Elementos Finitos de Navier Stokes e gostaria de investigar os efeitos de vários parâmetros. Alguns parâmetros são especificados em um arquivo de entrada ou através de opções de linha de comando; outros parâmetros são fornecidos como sinalizadores em um Makefile para que meu código precise ser recompilado sempre que eu alterar essas opções. Gostaria de obter alguns conselhos sobre uma boa maneira de explorar sistematicamente o espaço de parâmetros.

  • Existem bibliotecas / estruturas C ++ / Python úteis que podem ajudar com esse tipo de coisa? Por exemplo, descobrir boost.Program_options foi uma grande ajuda, pois é possível sobrecarregar as opções de arquivo de entrada com argumentos de linha de comando. Também vi algumas pessoas usarem um arquivo de trabalho descrevendo cada caso com bastante eficiência e um colega sugeriu que a gravação de parâmetros em arquivos vtu como blocos de comentários também funcionasse.
  • Talvez não valha a pena investir muito tempo nisso? É apenas uma distração e uma perda de tempo, e é melhor se concentrar no processo de teste de força bruta e ad hoc?

Alguns pensamentos

Atualmente, estou fazendo as coisas principalmente à mão e encontrei os seguintes problemas:

  • Nomeando casos de teste . Tentei armazenar resultados em pastas nomeadas com os parâmetros de execução separados por sublinhados, por exemplo Re100_dt02_BDF1.... Elas rapidamente se tornam longas ou difíceis de ler / criptografadas se forem abreviadas demais. Além disso, os parâmetros de números reais incluem um .que é estranho / feio.
  • Registrando dados executados . Às vezes, gostaria de ver os resultados gravados no terminal e também salvos em um arquivo de texto. Esta resposta do StackOverflow, por exemplo, é um pouco útil, mas as soluções parecem um pouco intrusivas.
  • Plotando dados de acordo com o parâmetro . Leva algum tempo para coletar dados relevantes de uma variedade de arquivos de log em um único arquivo que eu possa plotar, com um sistema melhor, talvez isso se torne mais fácil.
  • Gravando comentários nos dados . Depois de examinar os resultados, escrevo alguns comentários em um arquivo de texto, mas às vezes é difícil manter a sincronização com as pastas de resultados.

Depende muito do que você quer dizer com "explorar". Indique seus objetivos com mais precisão.
Arnold Neumaier

Respostas:


10

Apenas alguns comentários sobre dois de seus pontos:

  • Registro de dados de execução : sua melhor aposta é provavelmente canalizar a saída através do comando tee , que deve estar disponível na maioria dos shells.

  • Plotando dados de acordo com o parâmetro : acho que é uma questão de gosto, mas quando tenho que fazer agregação de dados complexos, armazeno os resultados em texto sem formatação, leio-os no Matlab como matrizes e faço todos os cálculos, plotagens e até a saída LaTeX de lá. Obviamente, qualquer linguagem de programação / script com a qual você esteja familiarizado fornecerá melhores resultados.


Graças, o teecomando é muito útil
Matija Kecman

11

Se você deseja escrever algo de uso geral, você pode fazê-lo com scripts de shell se for algo muito simples, como Pedro sugere , ou agregar em uma linguagem de programação matemática de nível superior, como Python ou MATLAB. Concordo que os arquivos de texto sem formatação são úteis para quantidades menores de dados, mas você provavelmente deve mudar para dados binários para algo maior que alguns megabytes.

Por outro lado, se você está apenas fazendo uma estimativa de parâmetros, eu recomendaria o uso de um software especificamente adequado para isso. Vários pesquisadores da minha universidade tiveram boa sorte com o DAKOTA , uma caixa de ferramentas de quantificação de incerteza dos Sandia National Laboratories ( disponível sob uma licença pública geral menor GNU ).

Aqui está um trecho da página Sandia que descreve o DAKOTA:

Fornecemos uma variedade de métodos para permitir que um usuário execute uma coleção de simulações de computador para avaliar a sensibilidade das saídas do modelo em relação às entradas do modelo. Categorias comuns incluem estudos de parâmetros, métodos de amostragem e desenho de experimentos. Nos estudos de parâmetros, alguns parâmetros de entrada são percorridos em uma faixa, mantendo outros parâmetros de entrada fixos e avaliando como a saída varia. Nos métodos de amostragem, gera-se amostras a partir de uma distribuição de espaço de entrada e calcula a resposta de saída nos valores de entrada. Métodos de amostragem específicos disponíveis no DAKOTA incluem Monte Carlo, Latin Hypercube e (em breve) quase-Monte Carlo. No design de experimentos, a saída é avaliada em um conjunto de pontos de "design" de entrada escolhidos para amostrar o espaço de maneira representativa. O design específico dos métodos experimentais disponíveis no DAKOTA inclui projetos Box-Behnken, Central Composite e fatorial. As métricas de sensibilidade são uma maneira matemática de expressar a dependência das saídas nas entradas. Uma variedade de métricas de sensibilidade está disponível no Dakota, como coeficientes de correlação simples e parciais e correlações de classificação. Nossa pesquisa atual se concentra em métodos para gerar métricas de sensibilidade com um número mínimo de execuções e na estimativa ideal de parâmetros em modelos de computador usando técnicas de análise bayesiana.


Outra ferramenta como essa é o SUSA, desenvolvido pela GRS na Alemanha. Mas este não é gratuito.
GertVdE

O problema com os formatos binários é que eles são mais difíceis de manter, não é incomum que um formato de arquivo evolua com o tempo, portanto, analisar e dar suporte a um formato binário pode ser um problema. Na minha experiência, texto sem formatação, compactação (gzip) e um pouco de linha de comando ou python para colar todos funcionam bem, mesmo para algumas centenas de GB.
fcruz 26/07/12

11
@fcruz yes, ou bzip2e 7zipque oferecem taxas de compressão ainda melhores para o texto.
precisa saber é o seguinte

8

No meu trabalho de doutorado, estou enfrentando problemas semelhantes aos seus. Como não estou usando meu código, porém, não tenho a mesma flexibilidade que você. Dito isto, tenho algumas sugestões.

Como Pedro sugeriu, existe o comando tee. Mas, se não estiver disponível, ou se você quiser algo incorporado ao seu software, sugiro consultar a boost::iostreamsbiblioteca. Ele fornece mecanismos para definir fontes de entrada e coletores de saída que a biblioteca padrão não executa. Em particular, existe o tee_deviceque permite conectar dois coletores de saída ao seu fluxo, e outros fluxos podem atuar como coletores. Isso permitiria que você stdoutdependesse da saída simultânea e da configuração do arquivo de log.

Concordo que boost::program_optionspode ser muito útil na configuração do seu software. No entanto, existem algumas falhas que podem afetar a maneira como você faz as coisas. Primeiro, se você precisa de uma configuração hierárquica, , em seguida, os arquivos são uma forma dolorosa de realizá-la. Segundo, e mais significativamente, não possui recursos de saída; portanto, você não pode salvar seu estado como um arquivo de configuração para inspeção posterior ou retomar um código parado. Como alternativa, sugiro usar o que suporta arquivos de configuração hierárquica e salvar as árvores para reutilização posterior. Isso tem o benefício adicional de que, se você precisar verificar seu código, poderá salvar seu estado atual como entrada ao reiniciar.1iniboost::program_optionsboost::property_tree

Para reunir os dados dos diferentes cálculos, faço um loop em todos os arquivos de dados que gostaria de incluir em um conjunto, depois uso o awk para produzir uma única linha no arquivo e canalize todos os resultados para a minha saída. Isso pode levar alguns minutos, mas, infelizmente, não tenho um método melhor.

Quanto ao processamento / comentário de seus dados, não posso enfatizar a utilidade do formato do notebook Mathematica o suficiente. Isso me permite organizar minhas observações, especulações e visualizações em um só lugar. Porém, meus notebooks costumam ter 100 MB. Por uma boa medida, o Mathematica tem um desempenho tão bom quanto o Matlab em tarefas de matriz. Além disso, ele pode ser usado para fazer anotações com formatação matemática completa em tempo real.

Eu gostaria de ter uma solução melhor para o problema de nomeação, e é bastante pernicioso. Pode valer a pena considerar a saída de alguns de seus dados em um banco de dados por causa disso. No entanto, se você não desejar fazer isso, considere usar os atributos estendidos no XFS para capturar informações mais completas sobre sua simulação e armazene seu arquivo de configuração com os dados que foram usados ​​para gerar.

1. Como um exemplo em que os arquivos de configuração hierárquica são necessários, um amigo meu estava examinando os efeitos de diferentes geometrias de ponta no AFM e cada geometria tinha um conjunto diferente de parâmetros. Além disso, além disso, ele estava testando vários esquemas de cálculo para compará-los à experiência, e eles tinham parâmetros muito diferentes.


11
O que faço recentemente é que eu conduzo a simulação do Mathematica. Em vez de usar arquivos de configuração, arquivos de entrada, etc. e tornar a simulação um programa de linha de comando, apenas defino uma interface LibraryLink para o Mathematica. Dessa maneira, posso passar parâmetros ou dados de maneira estruturada e evitar o trabalho de lidar com todos os tipos de opções de linha de comando / formatos de arquivo de entrada e saída. Eu tenho acesso instantâneo à visualização / plotagem e posso automatizar facilmente a execução da simulação para diferentes parâmetros para cenários complexos.
Szabolcs

(É assim que eu começo com a coisa de amostragem adaptativa . Se eu estivesse chamando meu programa pela linha de comando, implementar algo como isso é muito trabalho e muito trabalho para começar a funcionar sem uma boa razão. A idéia não é propensos a sair de experimentação pura Usando um sistema de alto nível como Mathematica feita a experimentação fácil o suficiente para que a idéia veio naturalmente eu acho que pode-se usar outros sistemas de alto nível da mesma forma)...
Szabolcs

Obrigado pela sua resposta útil, vou dar uma olhada boost::property_tree. Outro problema boost::program_optionsé que parece inutilizável como uma biblioteca somente de cabeçalho, o que é um pouco complicado se você quiser que seu aplicativo seja executado em uma máquina que apenas aumenta os cabeçalhos. Aliás, alguém sabe por que isso é? Aparentemente, é uma biblioteca bastante pequena de qualquer maneira. (Talvez seja melhor para postar isso na lista de usuários Boost)
Matija Kecman

@ mk527 Não sei o que é necessário boost::program_optionspara forçá-lo a ser transformado em uma biblioteca. No entanto, você olhou para o utilitário bcp para extrair um subconjunto de impulso?
rcollyer

3

Conheço o PyTables ao instalar o PETSC. E acho que o método da tabela (ou banco de dados) é adequado para explorar o espaço dos parâmetros, embora ainda não tenha tentado. Podemos gravar todas as execuções com parâmetros específicos e, em seguida, podemos consultar quaisquer agregações que satisfaçam algumas condições, por exemplo, podemos corrigir dt, BDF1 e procurar todos os registros relevantes para estudar a variação devido a outros parâmetros.

Eu gostaria de ouvir pessoas que realmente estão usando o método de tabela (ou banco de dados) para explorar o espaço dos parâmetros. Eu aprecio por exemplos detalhados.


3

Explorar o espaço dos parâmetros como você está tentando fazer pode rapidamente se tornar pesado. Existem tantas maneiras diferentes de fazer isso que não existe uma solução real.

Geralmente, quando você atinge esse limite em seu trabalho, convém investigar os formatos de dados hierárquicos HDF5 . O HDF5 permite armazenar resultados complexos de sua simulação em um formato de arquivo bem definido. As vantagens são que seus dados são armazenados em um único formato de arquivo bem definido. Você pode adicionar várias execuções de simulação, identificadas por diferentes parâmetros, ao seu arquivo e manipulá-las posteriormente. Os dados podem ser compactados e é bastante fácil de extrair usando uma variedade de ferramentas. É fácil apis para c / c ++ / python etc e diversas ferramentas de linha de comando para manipular os arquivos. Uma desvantagem é que gravar no hdf5 não é tão simples quanto gravar no console. Existem muitos programas de exemplo nos exemplos do HDF5 .


2

Você deseja manter uma tabela indexada de valores de variáveis. O índice corresponde a uma pasta onde você mantém cada entrada e saída de simulação. Portanto, é apenas um índice e você não precisa se preocupar com convenções de nomenclatura ou hierarquias de pastas, porque procurará quais valores de parâmetros correspondem a cada pasta.

Portanto, agora você pode usar esta tabela para organizar seu pós-processamento, plotagem (análise), registro e comentários. A tabela é central para o fluxo de trabalho.

Essa é a ideia básica e estou descrevendo o que você pode querer fazer apenas conceitualmente. Na minha resposta inicial, sugeri examinar a estrutura que desenvolvi. Mais recentemente, descobri Sumatra . É muito mais desenvolvido do que o meu aluno de pós-graduação desenvolvido individualmente e com dificuldades e é novo no esforço de python, mas acho que ele tenta fazer muito. É focado em informações de proveniência, enquanto minha estrutura se concentra na eficiência do fluxo de trabalho. Há também jobman , sagrado e lencet .

Qualquer que seja a sua escolha, recomendo fortemente o python para lidar com esses tipos de tarefas, pois você pode gerenciar todo o seu fluxo de trabalho com o python. Como uma pequena história, vi meus colegas trabalharem com DAKOTA, bash, GNUplot, convenções de nomeação de arquivos, oitava sed / awk ... etc. para fazer o trabalho computacional. Cada uma dessas ferramentas é adequada por si só, mas o poder do python como uma linguagem de cola de integração realmente brilha quando você usa o python para gerenciar seu trabalho junto com a pilha científica do python. Eu literalmente não tive problemas ao gerenciar meu trabalho computacional depois de desenvolver minha estrutura.

/ minha resposta inicial segue /

Acredito que resolvi esse problema usando python. Eu pensei em todas essas questões.

Confira meu repo http://msdresearch.blogspot.com/2012/01/parameter-study-management-with-python.html

No momento, estou trabalhando para documentar melhor minha estrutura. (é mais envolvido do que preencher um leia-me!)

-Majid alDosari


11
Olá Majid, obrigado pela contribuição e bem-vindo ao SciComp. Em geral, os sites StackExchange desencorajam o link para páginas externas e incentivam respostas detalhadas no próprio site. Os "anúncios" de link único são fortemente desencorajados. Sugiro revisar ou excluir esta resposta, pois ela provavelmente não será bem recebida em sua forma atual.
Aron Ahmadia

Entendido. Só não acredito que a solução possa ser fornecida na forma de um post. o problema é bastante geral.
majidaldosari

11
Você poderia ao menos resumir sua abordagem desses problemas em que pensou?
Christian Clason

1

Costumo concordar com a implementação a seguir, que desenvolvi no decorrer do meu trabalho de investigação, como pode ser encontrado aqui , aqui e aqui .

Para passar variáveis ​​para o programa e poder mudar, uso o paradigma de usar um script bash em que defino

export aValue=10
export bValue=2
export idName=test

e depois use em C / C ++

char *env_aValue = getenv("aValue");
char *env_bValue = getenv("bValue");
char *env_idName = getenv("idName");

aValue = atoi(env_aValue)
...

As grandes vantagens disso são as seguintes:

  • pode ser acessado em um escopo global,
  • é portátil ao mecanismo de grade solar (clusters),
  • pode ser facilmente alterado no script bash,
  • é independente de plataforma,
  • o número de parâmetros pode ser muito grande (potencialmente infinito)

Além disso, sempre passo um idName, no qual todos os arquivos gravados por esse executável terão uma identificação inicial (podem ser seguidos por outros parâmetros, se desejar), e eles também recebem um diretório de exportação = idName, criado no diretório script bash e todos os arquivos desse executável são salvos nele. Dessa forma, os resultados são organizados por diretórios (opcional).


0

Você pode conferir o sfepy, que é um programa de elementos finitos quase inteiramente codificado em python. Ele também tem um exemplo do problema de Navier Stokes. O procedimento operacional do sfepy é muito fácil.


11
Não acho que essa resposta responda à pergunta. O pôster possui uma simulação; Tenho a impressão de que ele deseja envolver uma estrutura em torno de sua simulação existente, em vez de refazer completamente sua simulação em diferentes softwares.
Geoff Oxberry

sfepy também funciona como uma estrutura, pode-se usar isso como um solucionador de PDE de caixa preta. Mas acho que você está certo, pois o pôster já passou uma quantidade significativa de tempo na codificação.
ShadowWarrior

0

Você já pensou em usar um banco de dados MySQL? Eu nunca fiz isso, mas eu poderia imaginar, que você pode consultar este sistema muito bem! Talvez outros sistemas como o MongoDB sejam melhores. Então, isso é apenas uma ideia.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.