Jaki jest dobry sposób na uruchomienie badań parametrów w C ++

29

Problem

Obecnie pracuję nad symulacją elementów skończonych Naviera Stokesa i chciałbym zbadać wpływ różnych parametrów. Niektóre parametry są określone w pliku wejściowym lub za pomocą opcji wiersza poleceń; inne parametry są dostarczane jako flagi w pliku Makefile, więc mój kod musi być rekompilowany za każdym razem, gdy zmieniam te opcje. Byłbym zainteresowany, aby uzyskać porady dotyczące dobrego sposobu systematycznego badania przestrzeni parametrów.

  • Czy istnieją przydatne biblioteki / frameworki C ++ / Python, które mogą pomóc w tego typu sprawach? Na przykład odkrywanie boost.Program_options było dużą pomocą, ponieważ możliwe jest przeciążenie opcji pliku wejściowego argumentami wiersza poleceń. Widziałem także, jak niektórzy ludzie dość skutecznie używają pliku zadania opisującego każdy przypadek, a kolega zasugerował, że zapis parametrów w plikach vtu, ponieważ bloki komentarzy mogą również działać.
  • Być może nie warto w to inwestować dużo czasu? Czy to tylko odwrócenie uwagi i drenaż czasu i najlepiej po prostu przećwiczyć proces brutalnej siły i ad hoc?

Kilka myśli

Obecnie robię rzeczy głównie ręcznie i napotkałem następujące problemy:

  • Nazewnictwo przypadków testowych . Próbowałem przechowywać wyniki w folderach o nazwach z parametrami uruchamiania oddzielonymi podkreślnikami, np Re100_dt02_BDF1.... Te szybko stają się długie lub trudne do odczytania / tajemnicze, jeśli są za bardzo skracane. Ponadto parametry liczby rzeczywistej obejmują .niezręczne / brzydkie.
  • Rejestrowanie danych przebiegu . Czasami chciałbym zobaczyć wyniki zapisane w terminalu, a także zapisane w pliku tekstowym. Na przykład odpowiedź StackOverflow jest nieco pomocna, ale rozwiązania wydają się nieco nachalne.
  • Wykreślanie danych według parametru . Zebranie odpowiednich danych z różnych plików dziennika w jednym pliku, który mogę następnie wykreślić, zajmuje sporo czasu. Lepszy system może być łatwiejszy.
  • Nagrywanie komentarzy do danych . Po sprawdzeniu wyników piszę kilka komentarzy w pliku tekstowym, ale utrzymanie synchronizacji z folderami wyników jest czasem trudne.
Matija Kecman
źródło
Wiele zależy od tego, co rozumiesz przez „odkrywaj”. Podaj dokładniej swoje cele.
Arnold Neumaier,

Odpowiedzi:

10

Tylko kilka uwag na temat dwóch twoich punktów:

  • Rejestrowanie danych przebiegu : Najlepszym rozwiązaniem jest przesyłanie danych wyjściowych za pomocą polecenia tee , które powinno być dostępne w większości powłok.

  • Rysowanie danych według parametru : Myślę, że to kwestia gustu, ale kiedy muszę wykonać złożoną agregację danych, przechowuję wyniki w postaci zwykłego tekstu, czytam je w Matlabie jako macierze i wykonuję wszystkie obliczenia, kreślenie, a nawet dane wyjściowe LaTeX stamtąd. Oczywiście, każdy język programowania / skryptów, który znasz najlepiej, daje najlepsze wyniki.

Pedro
źródło
Dzięki, teepolecenie jest bardzo przydatne
Matija Kecman
11

Jeśli chcesz napisać coś ogólnego, możesz to zrobić za pomocą skryptów powłoki, jeśli jest to coś bardzo prostego, jak sugeruje Pedro , lub agregować w matematycznym języku programowania wyższego poziomu, takim jak Python lub MATLAB. Zgadzam się, że pliki zwykłego tekstu są przydatne dla mniejszych ilości danych, ale prawdopodobnie powinieneś przełączyć się na dane binarne dla czegoś większego niż kilka megabajtów.

Z drugiej strony, jeśli robisz tylko oszacowanie parametrów, zaleciłbym użycie oprogramowania specjalnie do tego przystosowanego. Kilku badaczy z mojego uniwersytetu miało szczęście z DAKOTA , zestawem narzędzi do określania niepewności z Sandia National Laboratories ( dostępnym na licencji GNU Lesser General Public Licence ).

Oto fragment strony Sandia opisującej DAKOTA:

Zapewniamy różnorodne metody, aby umożliwić użytkownikowi uruchomienie zbioru symulacji komputerowych w celu oceny wrażliwości wyników modelu w odniesieniu do danych wejściowych modelu. Typowe kategorie obejmują badania parametrów, metody pobierania próbek i projektowanie eksperymentów. W badaniach parametrów jeden krok przesuwa niektóre parametry wejściowe przez zakres, utrzymując stałe inne parametry wejściowe i ocenia, jak zmienia się wyjście. W metodach próbkowania generuje się próbki z rozkładu przestrzeni wejściowej i oblicza odpowiedź wyjściową przy wartościach wejściowych. Konkretne metody pobierania próbek dostępne w DAKOTA obejmują Monte Carlo, Latin Hypercube i (wkrótce) quasi-Monte Carlo. Przy projektowaniu eksperymentów dane wyjściowe są oceniane w zestawie wejściowych punktów „projektowych” wybranych do próbkowania przestrzeni w reprezentatywny sposób. Specyficzny projekt metod eksperymentów dostępnych w DAKOTA obejmuje projekty Box-Behnkena, Central Composite i Factorial. Mierniki wrażliwości są matematycznym sposobem wyrażenia zależności wyników od nakładów. W Dakocie dostępnych jest wiele wskaźników wrażliwości, takich jak proste i częściowe współczynniki korelacji oraz korelacje rang. Nasze obecne badania koncentrują się na metodach generowania wskaźników wrażliwości przy minimalnej liczbie przebiegów oraz na optymalnym oszacowaniu parametrów w modelach komputerowych przy użyciu technik analizy bayesowskiej.

Aron Ahmadia
źródło
Kolejnym takim narzędziem jest SUSA opracowany przez GRS w Niemczech. Ale ten nie jest darmowy.
GertVdE
Problem z formatami binarnymi polega na tym, że są one trudniejsze w utrzymaniu, nierzadko ewoluuje format pliku z czasem, dlatego parsowanie i obsługa formatu binarnego może być uciążliwa. Z mojego doświadczenia wynika, że ​​zwykły tekst, kompresja (gzip) i trochę wiersza poleceń lub python do zszywania wszystko działa dobrze nawet na kilkaset GB.
fcruz
1
@fcruz tak, czy bzip2i 7zipktóre oferują nawet lepsze współczynniki kompresji dla tekstu.
Ajasja
8

W mojej pracy doktorskiej napotykam na podobne problemy jak wy. Ponieważ jednak nie używam mojego kodu, nie mam takiej samej elastyczności jak Ty. To powiedziawszy, mam kilka sugestii.

Jak sugerował Pedro, istnieje polecenie tee. Ale jeśli nie jest dostępny lub chciałbyś coś wbudowanego w swoje oprogramowanie, sugeruję zajrzenie do boost::iostreamsbiblioteki. Zapewnia mechanizmy definiowania źródeł wejściowych i ujść wyjściowych, których nie robi standardowa biblioteka. W szczególności istnieje taki, tee_devicektóry pozwala połączyć dwa ujścia wyjściowe ze swoim strumieniem, a inne strumienie mogą działać jak ujścia. Pozwoliłoby to na uzależnienie jednoczesnego wyjścia stdouti konfiguracji pliku dziennika.

Zgadzam się, że boost::program_optionsmoże być bardzo pomocny w konfiguracji twojego oprogramowania. Ma jednak kilka wad, które mogą mieć wpływ na to, jak robisz różne rzeczy. Po pierwsze, jeśli potrzebujesz konfiguracji hierarchicznej, to pliki są bolesnym sposobem jej osiągnięcia. Po drugie, a co ważniejsze, nie ma możliwości wyjścia, więc nie można zapisać stanu jako pliku konfiguracyjnego do późniejszej kontroli lub wznowienia zatrzymanego kodu. Jako alternatywę sugerowałbym użycie, które obsługuje hierarchiczne pliki konfiguracyjne i zapisanie drzew do późniejszego ponownego wykorzystania. Ma to tę dodatkową zaletę, że jeśli musisz sprawdzić punkt kontrolny swojego kodu, możesz zapisać jego aktualny stan jako dane wejściowe po ponownym uruchomieniu.1iniboost::program_optionsboost::property_tree

Aby zebrać dane z różnych obliczeń, zapętlam wszystkie pliki danych, które chciałbym dołączyć do zestawu, a następnie używam awk do utworzenia pojedynczej linii w pliku i umieszczam wszystkie wyniki w moich wynikach. Może to potrwać kilka minut, ale niestety nie mam lepszej metody.

Jeśli chodzi o przetwarzanie / komentowanie twoich danych, nie mogę wystarczająco podkreślić użyteczności formatu notatnika Mathematica. Pozwala mi to organizować obserwacje, spekulacje i wizualizacje w jednym miejscu. Moje notebooki mają jednak zwykle 100 MB. Na wszelki wypadek Mathematica radzi sobie równie dobrze jak Matlab w zadaniach macierzowych. Ponadto można go używać do robienia notatek z pełnym formatowaniem matematycznym w czasie rzeczywistym.

Chciałbym mieć lepsze rozwiązanie problemu nazewnictwa i jest to dość szkodliwe. Z tego powodu warto rozważyć przesłanie niektórych danych do bazy danych. Jeśli jednak nie chcesz tego zrobić, rozważ użycie rozszerzonych atrybutów w XFS, aby przechwycić pełniejsze informacje na temat symulacji i zapisz plik konfiguracyjny z danymi, które zostały użyte do wygenerowania.

1. Jako przykład, w którym potrzebne są hierarchiczne pliki konfiguracyjne, mój przyjaciel badał wpływ różnych geometrii końcówek w AFM, a każda geometria miała inny zestaw parametrów. Oprócz tego testował kilka schematów obliczeniowych, aby mógł je porównać z eksperymentem, a miały one bardzo różne parametry.

rcollyer
źródło
1
To, co ostatnio robię, to to, że prowadzę symulację z Mathematica. Zamiast używać plików konfiguracyjnych, plików wejściowych itp. I uczynić symulację programem wiersza poleceń, po prostu definiuję interfejs LibraryLink do Mathematica. W ten sposób mogę przekazywać parametry lub dane w uporządkowany sposób i mogę uniknąć bólu związanego z obsługą różnego rodzaju opcji wiersza poleceń / formatów plików wejściowych / wyjściowych. Otrzymuję natychmiastowy dostęp do wizualizacji / kreślenia i mogę łatwo zautomatyzować uruchamianie symulacji dla różnych parametrów dla złożonych scenariuszy.
Szabolcs
(W ten sposób dostosowuję się do kwestii adaptacyjnego próbkowania . Gdybym wywoływał mój program z wiersza poleceń, implementacja czegoś takiego to po prostu zbyt dużo pracy i zbyt wiele problemów, aby zacząć działać bez bardzo dobrego powodu. Pomysł nie jest prawdopodobnie z czystego eksperymentowania. Zastosowanie systemu wysokiego poziomu, takiego jak Mathematica, sprawiło, że eksperymentowanie stało się na tyle łatwe, że pomysł przyszedł naturalnie. Myślę, że można użyć innych systemów wysokiego poziomu w ten sam sposób.)
Szabolcs
Dziękuję za przydatną odpowiedź, przyjrzę się boost::property_tree. Innym problemem boost::program_optionsjest to, że wydaje się być bezużyteczna jako biblioteka zawierająca tylko nagłówki, co jest niewygodne, jeśli chcesz, aby aplikacja działała na maszynie, która ma tylko nagłówki zwiększające. Nawiasem mówiąc, czy ktoś wie, dlaczego tak jest? Najwyraźniej i tak jest to dość mała biblioteka. (Być może lepiej opublikować to na liście użytkowników doładowania)
Matija Kecman
@ mk527 Nie wiem, co jest wymagane, boost::program_optionsaby wymusić przekształcenie go w bibliotekę. Jednak czy spojrzałeś na narzędzie bcp do wyodrębnienia podzbioru wzmocnienia?
rcollyer
3

Poznaję PyTables podczas instalacji PETSC. I wydaje mi się, że metoda tabeli (lub bazy danych) jest odpowiednia do eksploracji przestrzeni parametrów, chociaż jeszcze nie próbowałem. Możemy zarejestrować każdy przebieg z określonymi parametrami, a następnie możemy skonsultować wszelkie agregacje spełniające określone warunki, powiedzmy, możemy naprawić dt, BDF1 i wyszukać wszystkie odpowiednie rekordy, aby zbadać zmienność z powodu innych parametrów.

Chciałbym usłyszeć od osób, które faktycznie używają metody tabeli (lub bazy danych) do eksploracji przestrzeni parametrów. Będę wdzięczny za szczegółowe przykłady.

Hui Zhang
źródło
3

Badanie przestrzeni parametrów, tak jak próbujesz, może bardzo szybko stać się nieporęczne. Jest tak wiele różnych sposobów, aby to zrobić, że nie ma jednego prawdziwego rozwiązania.

Zwykle po osiągnięciu tego limitu w pracy warto zbadać hierarchiczne formaty danych HDF5 . HDF5 pozwala przechowywać złożone dane wyjściowe symulacji w dobrze zdefiniowanym formacie pliku. Zaletą jest to, że dane są przechowywane w jednym dobrze zdefiniowanym formacie pliku. Możesz dodać do pliku wiele przebiegów symulacji, oznaczonych różnymi parametrami, a następnie nimi manipulować. Dane można skompresować i można je dość łatwo wyodrębnić za pomocą różnych narzędzi. Można łatwo obsługiwać c / c ++ / python itp. Oraz wiele narzędzi wiersza poleceń do manipulowania plikami. Wadą jest to, że pisanie na hdf5 nie jest tak proste jak pisanie na konsolę. Istnieje wiele przykładowych programów na przykładach HDF5 .

tcb
źródło
2

Chcesz zachować indeksowaną tabelę wartości zmiennych. Indeks odpowiada folderowi, w którym przechowywane są dane wejściowe i wyjściowe symulacji. Jest to więc tylko indeks i nie musisz się martwić konwencją nazewnictwa lub hierarchią folderów, ponieważ będziesz sprawdzać, jakie wartości parametrów odpowiadają każdemu folderowi.

Teraz możesz używać tej tabeli do organizowania przetwarzania końcowego, kreślenia (analizy), rejestrowania i komentowania. Tabela ma kluczowe znaczenie dla przepływu pracy.

To jest podstawowy pomysł i opisuję, co możesz zrobić tylko koncepcyjnie. W pierwszej odpowiedzi zasugerowałem przyjrzenie się opracowanemu przeze mnie frameworkowi. Niedawno odkryłem Sumatrę . Jest znacznie bardziej rozwinięty niż mój indywidualnie opracowany, zmagający się ze studentem grad, i nowy w pythonowym wysiłku, ale myślę, że próbuje zrobić zbyt wiele. Koncentruje się na informacjach o pochodzeniu, podczas gdy mój framework koncentruje się na wydajności przepływu pracy. Jest też Jobman , Sacred i Lencet .

Cokolwiek wybierzesz, zdecydowanie polecam Pythona do radzenia sobie z tego typu zadaniami, ponieważ możesz zarządzać całym przepływem pracy za pomocą Pythona. Krótko mówiąc, widziałem, jak moi koledzy pracują z DAKOTA, bash, GNUplot, konwencjami nazewnictwa plików, oktawą sed / awk ... itd. wykonywać swoją pracę obliczeniową. Każde z tych narzędzi działa samodzielnie, ale moc Pythona jako integrującego języka kleju naprawdę świeci, gdy używasz Pythona do zarządzania pracą wraz ze stosem naukowym Pythona. Miałem dosłownie zero problemów z zarządzaniem pracą obliczeniową po tym, jak opracowałem swój framework.

/ moja pierwsza odpowiedź następuje /

Myślę, że rozwiązałem ten problem za pomocą Pythona. Myślałem o wszystkich tych kwestiach.

Sprawdź moje repozytorium http://msdresearch.blogspot.com/2012/01/parameter-study-management-with-python.html

Na razie jednak pracuję nad lepszym udokumentowaniem mojego frameworka. (jest to bardziej zaangażowane niż wypełnianie readme!)

-Majid alDosari

majidaldosari
źródło
1
Cześć Majid, dziękuję za wkład i witamy w SciComp. Ogólnie strony StackExchange odradzają odsyłanie do stron zewnętrznych i zachęcają do szczegółowych odpowiedzi na stronie. Odsyłacze z pojedynczym linkiem są zdecydowanie odradzane. Sugeruję zmianę lub usunięcie tej odpowiedzi, ponieważ prawdopodobnie nie zostanie dobrze odebrana w obecnej formie.
Aron Ahmadia
zrozumiany. po prostu nie wierzę, że rozwiązanie można podać w formie postu. problem jest dość ogólny.
majidaldosari
1
Czy mógłbyś przynajmniej streścić swoje podejście do tych problemów, o których myślałeś?
Christian Clason
1

Zgadzam się na następujące wdrożenie, które opracowałem w trakcie mojej pracy dochodzeniowej, co można znaleźć tutaj , tutaj i tutaj .

Aby przekazać zmienne do programu i móc je zmienić, używam paradygmatu używania skryptu bash, w którym definiuję

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

a następnie użyj w C / C ++

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

aValue = atoi(env_aValue)
...

Dużą zaletą tego jest to, że:

  • można uzyskać do niego dostęp w zasięgu globalnym,
  • jest przenośny do silnika słonecznego (klastry),
  • można łatwo zmienić w skrypcie bash,
  • jest niezależny od platformy,
  • liczba parametrów może być bardzo duża (potencjalnie nieskończona)

Poza tym zawsze przekazuję idName, na której każdy plik zapisany przez ten plik wykonywalny będzie miał jego wstępną identyfikację (jeśli chcesz, mogą to być inne parametry), a także otrzymają katalog eksportu = idName, który jest tworzony na skrypt bash i wszystkie pliki tego pliku wykonywalnego są na nim zapisane. W ten sposób wyniki są uporządkowane według katalogów (opcjonalnie).

Jorge Leitao
źródło
0

Możesz sprawdzić sfepy, który jest programem elementów skończonych, prawie całkowicie zakodowanym w Pythonie. Ma również przykładowy problem Naviera Stokesa. Procedura obsługi sfepy jest bardzo łatwa.

Wojownik Cienia
źródło
1
Nie wydaje mi się, żeby ta odpowiedź odpowiadała na pytanie. Plakat ma symulację; Mam wrażenie, że chce owinąć ramę wokół swojej istniejącej symulacji, zamiast całkowicie przerobić swoją symulację w innym oprogramowaniu.
Geoff Oxberry
sfepy działa również jako framework, można go użyć jako solvera PDE czarnej skrzynki. Ale myślę, że masz rację, ponieważ plakat poświęcił już sporo czasu na kodowanie.
ShadowWarrior
0

Czy myślałeś o użyciu bazy danych MySQL? Nigdy tego nie robiłem, ale mogę sobie wyobrazić, że można bardzo dobrze sprawdzać ten system! Być może inne systemy, takie jak MongoDB, są lepsze. To tylko pomysł.

vanCompute
źródło