2015-06-09 8 views
19

mam do czynienia z następującym problemem:Julia programowanie równoległe - Making istniejących funkcji dostępnych dla wszystkich pracowników

Mam funkcji o nazwie TrainModel że biegnie przez bardzo długi czas na jednym wątku. Po zakończeniu obliczeń zwraca funkcję jako argument wyjściowy, nazwijmy ją: f. Kiedy zapytać typ tego f, Julia wraca:

(generic function with 1 method)

(nie jestem pewien tego ostatniego kawałka informacji jest przydatny każdemu, kto czyta ten temat)

Teraz w drugim etapie I należy zastosować funkcję f na bardzo dużej tablicy wartości. To jest krok, który chciałbym przeprowadzić paralelizując. Po uruchomieniu Julii z wieloma procesami, np.

julia -p 4 

idealnie, użyłbym:

pmap(f, my_values) 

czy może:

aux = @parallel (hcat) for ii=1:100000000 
     f(my_values[ii]) 
     end 

Niestety, to nie zadziała. Julia twierdzi, że pracownicy nie są świadomi funkcji f, to mogę dostać messsage:

ERROR: function f not defined on process 2

Jak mogę funkcja f dostępne dla wszystkich pracowników? Oczywiście rozwiązanie „brudne” byłoby uruchomić czasochłonne funkcja TrainModel na wszystkich pracowników, jak to być może:

@everywhere f = TrainModel(...) 

ale to byłoby marnotrawstwo cpu kiedy wszystko czego chcę to, że po prostu wynikiem f jest dostępny dla wszystkich pracowników.

Choć Szukałem postow z podobnymi problemami, jak dotąd nie mogę znaleźć odpowiedzi ...

Z góry dzięki! najlepszym

N.

+0

Czy to jest problem? http://docs.julialang.org/en/release-0.3/manual/parallel-computing/#code-availability-and-loading-packages – Claies

+0

Myślę, że to jest właśnie problem. Rozumiem, jak udostępnić funkcję wszystkim pracownikom, gdy funkcja jest zadeklarowana: na przykład można użyć makro @ wszędzie po zadeklarowaniu funkcji. Również dla zmiennych. Ale w jaki sposób zrobić to samo dla funkcji, które nie znajdują się w module lub zadeklarowane, ale zamiast tego są tworzone podczas wykonywania? – user1438310

+4

To jest dobre pytanie i nie sądzę, aby pomocna była aplikacja OP do dokumentacji Julii. W rzeczywistości bardzo wyraźnie wynika z tego, że OP zapoznał się z odpowiednią sekcją w dokumentach i nie zajmuje się kwestią funkcji generowanych i przekazywanych między różnymi zakresami w czasie wykonywania. Ponadto istnieje dodatkowa uwaga: ponieważ funkcja jest generowana w czasie wykonywania, kompilator może nie być w stanie określić typu wyjściowego (tj. Nie będzie stabilny), co może powodować dodatkowe problemy (prawdopodobnie tylko wydajność związane z). –

Odpowiedz

3

Podejście do powrotu funkcja wydaje się elegancki, ale niestety, w przeciwieństwie do JavaScriptu, Julia nie rozwiąże wszystkich zmiennych podczas tworzenia funkcji. Technicznie, twoja funkcja szkoleniowa może wytworzyć kod źródłowy funkcji z dosłownymi wartościami dla wszystkich wyszkolonych parametrów. Następnie przekaż go do każdego z procesów roboczych, który może przeanalizować go w swoim środowisku do funkcji wywoływalnej.

Proponuję zwrócić strukturę danych zawierającą wszystkie informacje potrzebne do wytworzenia wyszkolonej funkcji: wagi SSN, wektorów wsparcia, reguł decyzyjnych ... Definiować "wyszkoloną" funkcję w procesach roboczych tak, aby wykorzysta wyszkolone parametry. Być może zechcesz mieć możliwość zapisania wyników treningu na dysku, tak abyś mógł łatwo ponownie tworzyć swoje obliczenia.

+0

Dzięki za odpowiedź. Rzeczywiście jest to moja sytuacja: trenuję SSN, a następnie przepowiadam. W MATLAB możliwe jest nawet zapisanie funkcji predykcyjnej zwróconej przez procedurę szkoleniową w pliku MAT, a następnie załadowanie później, a wszystkie zmienne są poprawnie rozwiązane. Wygląda na to, że twoje sugestie to jedyne wyjście. Jednocześnie muszę przyznać, że jest trochę rozczarowujące, że trzeba przejść przez takie obejście w Julii, ale znowu może nadal brakuje mi doświadczenia w Julii, aby docenić problem ... – user1438310

0

Istnieje rozwiązanie uniksowe oparte na pakiecie PTools.jl (https://github.com/amitmurthy/PTools.jl).

Opiera się na równoległości poprzez rozwidlenie zamiast wbudowanego mechanizmu Julii. Rozwidlone procesy są tworzone w tym samym obszarze roboczym co proces główny, więc wszystkie funkcje i zmienne są bezpośrednio dostępne dla pracowników.

Jest to podobne do klastrów Fork w pakiecie równoległym R, więc może być używane jako funkcja mclapply.

Funkcja będąca przedmiotem zainteresowania to pfork (n :: Integer, f :: Function, args ...) i jedną zauważalną różnicą w mclapply w R jest to, że funkcja f musi przyjąć jako pierwszy argument indeks pracownika.

Przykład:

Pkg.add("PTools") 
Pkg.checkout("PTools") #to get the last version, else the package does not build at the time of writing 

using PTools 
f(workid,x) = x[workid] + 1 
pfork(3, f, [1,2,3,4,5]) #Only the three first elements of the array will be computed 

3-element Array{Any,1}: 
2 
3 
4 

Spodziewam się, że interfejs do pfork zostanie zbudowany tak, że pierwszy argument funkcji nie trzeba będzie indeks pracownika, ale na razie nie może być używane do rozwiązania problemu

Powiązane problemy