Zalecenia dotyczące lekkiego / bezinstalacyjnego gęstego solwera algebry liniowej opartego na C lub C ++

9

Większość mojego programowania to jednorazowe kody badawcze w C na własny użytek. Nigdy nie rozpowszechniałem żadnego kodu poza bliskimi współpracownikami. Opracowałem algorytm, który publikuję w czasopiśmie naukowym. Chcę podać kod źródłowy i być może kod wykonywalny w internetowym suplemencie do artykułu. Kolega poprosił mnie o uogólnienie algorytmu, który wymagał ode mnie pisania w C ++ (ack!) I który wymaga rozwiązania małych gęstych układów liniowych. Jeśli uda mi się zdobyć bazę użytkowników dla algorytmu, będzie to częściowo spowodowane tym, że pasek wprowadzania do korzystania z niego jest niski (jak na podłodze). Potencjalni użytkownicy nie będą instalować bibliotek itp. W celu korzystania z kodu. Chcę, aby kod był w pełni samodzielny i nie był obciążony żadną licencją. Mógłbym po prostu napisać własny solver, biorąc coś z Goluba i van Loana, ale wolałbym użyć waniliowego solvera, który napisał już ktoś inny, jeśli taki istnieje. Sugestie docenione. Dzięki!

jep
źródło
Drogi jep, witaj na forum. Twoje pytanie jest bardzo podobne do pytania tutaj: scicomp.stackexchange.com/questions/351/…
GertVdE
Rozwiązania bibliotek są zwykle złożone i duże ze względu na solidność, wydajność i ogólność. Jeśli twoje problemy są bardzo małe i dość dobrze uwarunkowane, proponuję napisać własną mini-implementację.
Stefano M
@GertVdE, dziękuję za szybką odpowiedź na to pytanie. Niekomfortowo łączę się z pytaniem „Rekomendacje ...”, ponieważ zarówno pytanie, jak i główna odpowiedź są zbyt ogólne, aby udzielać pomocy w takich sytuacjach. Jeśli chcesz to omówić dalej, sugeruję, abyśmy zabrali to do pokoju rozmów scicomp .
Aron Ahmadia
@AronAhmadia: Myślę, że jedynym sposobem, aby rozpocząć rozstrzyganie niektórych z tych debat, jest rozpoczęcie chrestomathy programowania komputerowego, która zależy zarówno od języka, jak i biblioteki. Jeśli kod jest czysty, a problemy z konfiguracją można rozwiązać (używając skryptu powłoki, szefa kuchni lub kukiełki), wówczas można zająć się (lub skonkretyzować) debatami na temat wydajności, uruchamiając kod i mierząc czas na maszyna referencyjna. Debaty na temat przejrzystości można rozwiązać (a przynajmniej uszczegółowić), patrząc na kod. W przeciwnym razie będziemy mieć te same argumenty.
Geoff Oxberry

Odpowiedzi:

7

Sugerowałbym dokładnie skopiować interfejs Lapacka do funkcji, której potrzebujesz, najprawdopodobniej potrzebujesz dgesv. W ten sposób ludzie, którzy mają zainstalowany Lapack, mogą po prostu połączyć się z nim i po prostu będzie działać. Dla osób, które nie mają zainstalowanego Lapacka, udostępniasz własną prostą implementację tej funkcji lub ewentualnie implementujesz ją za pomocą Eigen lub FLENS, jak sugerują inni.

W krainie Fortran biblioteka Lapacka jest takim standardem, że większość ludzi po prostu z niej korzysta i to wszystko, zamiast udostępniać własne implementacje.

Ondřej Čertík
źródło
+1 Dodaj do tego fakt, że większość dystrybucji Linuksa (przynajmniej opartych na Debianie) ma pakiety binarne w repozytorium, a wszystkie biblioteki matematyczne dostarczone przez dostawcę (MKL, SunPerf, ACML, ESSL itp.) To niosą. Powinieneś zawsze korzystać ze standardowych bibliotek w jak największym stopniu, chociaż jeśli jesteś na Windowsie / Macu, lepiej jest mieć coś opartego na C, ponieważ instalacja na nich darmowego kompilatora Fortran (gfortran) to trochę pracy, a przynajmniej tak słyszałem.
stali
Wielokrotnie korzystałem z lacka, ale nie jestem obecnie w krainie Fortran. Spodziewam się, że rozkład statystyczny platform, na których działa moja baza użytkowników, będzie podobny do rozkładu całego świata, co oznacza głównie okna, mniejszy odsetek komputerów Mac i jeszcze mniejszy odsetek * nix. Moje wrażenia z korzystania z systemu Windows są minimalne i wolę, aby tak było. To jest powód, dla którego chcę samodzielny kod C ++. Myślę, że będę musiał zapewnić niektórym użytkownikom pomoc w skompilowaniu i uruchomieniu kodu. Muszę zminimalizować pracę potrzebną do tego.
jep
Jeśli twoją bazą użytkowników są systemy Windows / Mac, lepiej skorzystaj z prostej implementacji opartej na języku C (być może nawet własnej). Pakiet, który jest trudny do zainstalowania lub zależy od 5 innych bibliotek, szczególnie gdy nie ma dostępnego repozytorium pakietów binarnych pierwszej klasy (jak Debian), na długo wyłączy użytkowników. Pamiętaj, że większość użytkowników Windows / Mac jest przyzwyczajona do instalacji jednym kliknięciem. Łatwość użycia zwycięża wszystko inne.
stali
5

Bardzo wczesnym błędem popełnianym przez wiele osób przy rozpoczynaniu pracy w środowisku naukowym jest założenie, że musisz napisać cały kod w tym samym języku. Myślę, że dzieje się tak głównie z przyczyn historycznych, kiedy nie było jasne, jak zmusić skompilowane programy do komunikowania się ze sobą nawet w różnych wersjach tego samego kompilatora. To powiedziawszy, w tym przypadku, jeśli i tak zamierzasz używać C ++, istnieje kilka bardzo dobrych bibliotek szablonów tylko w C ++, które mogą pasować do twoich potrzeb.

Ponieważ rozpowszechniasz swój kod ze względów akademickich i chciałbyś osadzić w swoim programie gęsty solver algebry liniowej, zdecydowanie zalecamy rozważenie Eigen . Eigen jest licencjonowany na licencji publicznej Mozilla i jest biblioteką tylko nagłówków. Oznacza to, że możesz dystrybuować Eigen ze swoim kodem w formie źródłowej (nie nakłada to żadnych ograniczeń licencyjnych na Twój kod), a otrzymasz dostęp do jego ogólnych możliwości, w tym wyjątkowo wydajnych gęstych liniowych solverów. Jak wspomina GertVdE, masz kilka innych opcji .

Aron Ahmadia
źródło
Miałem nadzieję na pojedynczy plik. Od dłuższego czasu zajmuję się programowaniem naukowym. Mam dość mieszane języki, takie jak C i fortran, ale naprawdę potrzebuję tylko jednego pliku zawierającego cały mój kod źródłowy. Podejrzewam, że mógłbym umieścić solver C w kodzie C ++, co nie byłoby wielkim problemem. Przede wszystkim chcę, aby kod był tak prosty, jak to możliwe. LU z obrotem powinny być odpowiednie. Spojrzę na Eigen. Dzięki!
jep
@jep, możesz również spróbować wybrać procedury CLAPACK, jeśli naprawdę nie zależy ci na wydajności.
Aron Ahmadia,
Istnieją dobre powody, aby pisać cały zależny kod w tym samym języku, w szczególności w środowiskach HPC, masz dziwne problemy z kompilatorem / łączeniem i problemy z interfejsem 32/64-bitowym. Na przykład, skąd mam poznać szerokość liczby całkowitej dla bibliotek wbudowanych? Skąd mam wiedzieć na pewno, jakiego kompilatora użyto do wbudowanej biblioteki i czy mogę połączyć się z nim za pomocą tego innego kompilatora? Posiadanie wszystkiego w jednym języku upraszcza wiele z tych problemów. I tak, powinna być dostarczona dokumentacja przez opiekunów klastra, ale przez większość czasu nie.
Victor Liu,
@VictorLiu - problemy, o których mówisz, są ściślej powiązane z implementacjami niż z językami. Miejsce na komentarze to kiepskie miejsce na poważną dyskusję, ale cieszę się, że mogę zaangażować cię w czat lub gdzie indziej, jeśli chcesz, żebym rozwinął moje przemyślenia na ten temat.
Aron Ahmadia,
4

Jeśli potrzebujesz niezawodnego rozwiązania dla układów równań liniowych, poleciłbym FLENS . Zawiera dokładną ponowną implementację LAPACK (odtwarza nawet te same błędy zaokrągleń, co LAPACK, jeśli używana jest jednowątkowa implementacja BLAS). Dotyczy to wszystkich funkcji FLENS-LAPACK (wraz z funkcjami narzędziowymi około 100 procedur).

FLENS jest objęty licencją BSD, a zatem pozwala na włączenie do produktów zastrzeżonych.

FLENS jest tylko nagłówkiem i jeśli potrzebujesz tylko podzestawu FLENS, mogę dać ci uproszczoną wersję zawierającą tylko te funkcje, których potrzebujesz. FLENS ma własną referencyjną implementację BLAS. Ale opcjonalnie użytkownicy mogą łączyć się ze zoptymalizowanymi bibliotekami BLAS, takimi jak ATLAS, OpenBLAS lub GotoBALS. W przypadku dużych matryc daje to wzrost wydajności o około 40% w porównaniu do Eigen.

I tak, Eigen używa również zestawu testów LAPACK do sprawdzania ich wyników. Robią to dla 3 funkcji (Lu, Cholesky i Wartości własne / wektory macierzy symetrycznej). Jednak ich obliczenie wartości / wektorów własnych macierzy niesymetrycznej zawiódłoby zestaw testów LAPACK.

Oświadczenie: Tak, FLENS to moje dziecko! Oznacza to, że kodowałem około 95%, a każda linia kodu była tego warta.

Michael Lehn
źródło
1
Michael - Uważaj to za przyjazne ostrzeżenie, że musisz postępować zgodnie z zasadą dotyczącą ujawniania powiązań .
Aron Ahmadia
Jasne, ale możesz też ponownie sformułować swoje posty z „Gorąco polecam rozważenie Eigen” na coś takiego jak „istnieje na przykład Eigen”. W tym przypadku usuwam moje uwagi na temat Eigen (chociaż wszystkie okazały się prawdziwe), w tym tę.
Michael Lehn
1
Wasze uwagi na temat Eigen nie są tutaj przedmiotem dyskusji (choć wydają mi się nie na temat). Jesteś głównym programistą FLENS. Jeśli zamierzasz polecić go w odpowiedzi tutaj, musisz ujawnić swoją przynależność jako programista projektu.
Aron Ahmadia
Ach, więc dobrze. Pomyślałem, że to jest domyślnie jasne przez „... mogę ci dać ...”. Czy ujawnienie w tej formie jest prawidłowe?
Michael Lehn
2
Chcę tylko podziękować za to; Miałem podobne plany ponownego wdrożenia dużej części Lapacka w C ++. Wydaje się jednak, że w przypadku większości zaawansowanych procedur (wartość własna) po prostu odkładasz dzwonienie do Lapacka, więc jest to trochę fałszywa reklama, mówiąc, że re-implementujesz całość. Z drugiej strony faktycznie przeniosłem źródło ZGEEV do C ++ w RNP , aczkolwiek niektóre części nadal są indeksowane w oparciu o 1 z automatycznej konwersji.
Victor Liu,