Value Function Iteration mit GPU Parallelisierung lösen
Kaja
Gast
Beiträge: ---
Anmeldedatum: ---
Wohnort: ---
Version: ---
Verfasst am: 28.11.2019, 14:09
Titel: Value Function Iteration mit GPU Parallelisierung lösen
Hallo zusammen
Ich würde gerne eine simple Matlab Funktion schreiben, welche Value Function Iteration
parallelisiert auf dem GPU berechnen kann.
Ich möchte, ungefähr, diesen Code für Julia auf Matlab replizieren:
https://github.com/giob1994/GPU-Ope.....under%20Uncertainty.ipynb
Dabei habe ich besonders Problem zu verstehen, wie man diesen Teil des Codes auf Matlab implementiert:
Code:
# Write kernel for GPU manually:
gpu_call(grid, (grid, V, policy, z, P, Float32(alpha), Float32(beta), Float32(delta), Float32(sigma), UInt32(SIZE_GRID), UInt32(SIZE_Z)))
do state, grid, V, policy, z, P, alpha, beta, delta, sigma, SIZE_GRID, SIZE_Z
# Each kernel executes for one value of the capital grid:
idx = @linearidx grid
% each kernel executes for one value of the capital grid
%idx = @linearidx grid
for i_z = 1:size_z_grid
F = -Inf;
pol_i = uint(1) for i_k = 1_size_k_grid
c = z_grid_G(i_z)*k_grid_G(idx)^alpha + (1-delta)*k_grid_G(idx) - k_grid_G(i_k)M
if c>0
F0 = ((c)^(1-eta)-1)/(1-eta) for j = 1:size_z_grid
F1 = F0 + beta*pi_z_G(i_z,j)*V(i_k,j);
end end if F1 > F
F = F1;
pol_i = uint64(i_k);
end end
V(idx,i_z) = F;
pol(idx,i_z) = pol_i;
für elementweise Operationen auf der GPU würde ich
arrayfun
empfehlen.
Dazu muss man nur die Daten anfangs auf die GPU bringen, wie du das ja schon gemacht hast. Der Rest geht "automatisch" auf der GPU.
Grüße,
Harald
_________________
1.) Ask MATLAB Documentation
2.) Search gomatlab.de, google.de or MATLAB Answers
3.) Ask Technical Support of MathWorks
4.) Go mad, your problem is unsolvable ;)
Kaja
Gast
Beiträge: ---
Anmeldedatum: ---
Wohnort: ---
Version: ---
Verfasst am: 28.11.2019, 15:02
Titel:
Hallo Harald
Danke vielmals für die rasche Antwort.
Ich bin mir nicht ganz sicher, wie ich arrayfun hier richtig brauchen würde.
Wäre dies so richtig:
1. Im main.m vor der VFI-Funktion:
2. Die Funktion rufen als arrayfun:
[V,policy]=arrayfun(VFI_own_attempt, V0, V, alpha,beta,delta,eta,z_grid,k_grid,pi_z,tol)
3. Die VFI_own_attempt.m Funktion wäre dann die selbe wie ohne GPU, alles Zuweisungen zum GPU ('gpuArray') geschehen ausserhalb der Funktion.
Was ich nicht genau verstehe:
Bei der Dokumentation für arrayfun werden Beispiele für die Funktion immer mit syms gezeigt.
genau, alles in der äußeren for-Schleife muss in die Funktion für arrayfun.
arrayfun hat an sich nichts mit syms zu tun, und ich finde auch keine Seite, die das kombiniert. Die Seite, nach der du dich richten solltest, ist diese hier:
1.) Ask MATLAB Documentation
2.) Search gomatlab.de, google.de or MATLAB Answers
3.) Ask Technical Support of MathWorks
4.) Go mad, your problem is unsolvable ;)
Kaja
Gast
Beiträge: ---
Anmeldedatum: ---
Wohnort: ---
Version: ---
Verfasst am: 28.11.2019, 16:38
Titel:
Danke vielmals!
Ich habe das jetzt einmal versucht so zu implementieren.
Leider stoppt Matlab wenn die Linie mit arrayfun aufgerufen wird mit:
Zitat:
Error using gpuArray/arrayfun
Matrix dimensions must agree.
% Not using Tauchen but some transition matrix with 3 grid points for stochastic process
z_grid = [0.4,0.8,1.2];
pi_z = [0.7,0.2,0.1;0.1,0.8,0.1;0.05,0.1,0.85];
die Schleifen und auch das y_k müssen auf jeden Fall aus der Funktion raus. Das komponentenweise Anwenden übernimmt ja arrayfun. y_k sollte Input sein, auf dem elementweise gearbeitet wird.
Grüße,
Harald
_________________
1.) Ask MATLAB Documentation
2.) Search gomatlab.de, google.de or MATLAB Answers
3.) Ask Technical Support of MathWorks
4.) Go mad, your problem is unsolvable ;)
Kaja
Gast
Beiträge: ---
Anmeldedatum: ---
Wohnort: ---
Version: ---
Verfasst am: 28.11.2019, 17:25
Titel:
Hm, danke für den Hinweis.
Ich bekommen immernoch den selben Fehlerhinweis.
Den Code habe ich so angepasst:
Code:
while diff>tol
V0 = V;
y_k = (k.^alpha)'*z+ (1-delta)*k(ones(1,size_z),:)';
if(k(high_k) > y_k(i_k,i_z))
high_k = high_k -1;
end
N_k = high_k;
[V,pol]= arrayfun(@VFI_own_gpu_attempt1, V0,y_k,i_k,i_z,high_k,low_k, alpha, beta, delta, eta,size_k, size_z,z,k,pi_z_G) diff=max(max(V-V0));
end end end
sorry, das war wohl unklar: die Schleifen über i_k und i_z müssen komplett weg. Der if-Teil muss dagegen in die Funktion rein.
Meine Empfehlung wäre, den Versuch mit arrayfun zunächst auf der CPU zu testen. Dort hast du bessere Debugging-Möglichkeiten.
Grüße,
Harald
_________________
1.) Ask MATLAB Documentation
2.) Search gomatlab.de, google.de or MATLAB Answers
3.) Ask Technical Support of MathWorks
4.) Go mad, your problem is unsolvable ;)
Kaja
Gast
Beiträge: ---
Anmeldedatum: ---
Wohnort: ---
Version: ---
Verfasst am: 28.11.2019, 21:35
Titel:
Danke für die Tipps!
Auf dem CPU habe ichs zum Laufen gebracht (ist aber irgendwo noch ein Fehler).
Wenn ich aber diesen CPU Code:
Ich verstehe nicht wirklich wie die Matrixdimensionen im CPU-Fall aufgehen können aber im GPU-Fall nicht. Scheint mathematisch nicht wirklich aufzugehen.
der Punkt ist, arrayfun auf der CPU zu verwenden und das zu debuggen.
Und bitte die Ratschläge beachten:
Zitat:
die Schleifen über i_k und i_z müssen komplett weg
(wenn du arrayfun verwenden willst)
Grüße,
Harald
_________________
1.) Ask MATLAB Documentation
2.) Search gomatlab.de, google.de or MATLAB Answers
3.) Ask Technical Support of MathWorks
4.) Go mad, your problem is unsolvable ;)
Kaja
Gast
Beiträge: ---
Anmeldedatum: ---
Wohnort: ---
Version: ---
Verfasst am: 28.11.2019, 22:13
Titel:
Hallo Harald
Entschuldigung, da habe ich dich wirklich falsch verstanden. (Ich dachte, du meinst "weg aus der Funktion".)
Meinst du mit "arrayfun auf CPU ausführen":
- die Funktion gleich behalten
- die Objekte (k_grid,z_grid, etc.) **nicht** als normales double lassen?
Wie kann ich die beiden for-schleifen entfernen?
Mit Vektorization?
Das ist doch genau der Punkt an arrayfun, dass du dann eben keine Schleifen mehr brauchst, weil arrayfun die Funktion automatisch elementweise ausführt.
Grüße,
Harald
_________________
1.) Ask MATLAB Documentation
2.) Search gomatlab.de, google.de or MATLAB Answers
3.) Ask Technical Support of MathWorks
4.) Go mad, your problem is unsolvable ;)
Kaja
Gast
Beiträge: ---
Anmeldedatum: ---
Wohnort: ---
Version: ---
Verfasst am: 28.11.2019, 23:55
Titel:
Ja, habe realisiert, dass ich nicht verstehe, wie arrayfun funktioniert. Dachte es sei eine auf GPU spezialisiert Funktion.
Konnte mit Hilfe der Dokumentation nicht wirklich verstehen, wie **arrayfun** korrekt zu gebrauchen ist. Es gibt sehr wenig kurze Beispielcodes oder Erklärvideos zu dieser Funktion.
Ich informier mich morgen noch einmal mehr.
Kaja
Gast
Beiträge: ---
Anmeldedatum: ---
Wohnort: ---
Version: ---
Verfasst am: 29.11.2019, 12:48
Titel:
Hallo Harald
Ich habe den Code jetzt so gut wie möglich abgeändert:
% Not using Tauchen but some transition matrix with 3 grid points for stochastic process
z_grid = [0.4,0.8,1.2];
pi_z = [0.7,0.2,0.1;0.1,0.8,0.1;0.05,0.1,0.85];
Gibt es einen Trick, wie ich nun pi_z_G, z und k auch in die arrayfun einspeisen kann?
Irgendwie mit z=repmat(z,1000)?
Bin mir nicht sicher ob dies funktioniert und mathematisch aufgeht.
Du kannst Beiträge in dieses Forum schreiben. Du kannst auf Beiträge in diesem Forum antworten. Du kannst deine Beiträge in diesem Forum nicht bearbeiten. Du kannst deine Beiträge in diesem Forum nicht löschen. Du kannst an Umfragen in diesem Forum nicht mitmachen. Du kannst Dateien in diesem Forum posten Du kannst Dateien in diesem Forum herunterladen
MATLAB, Simulink, Stateflow, Handle Graphics, Real-Time Workshop, SimBiology, SimHydraulics, SimEvents, and xPC TargetBox are registered trademarks and The MathWorks, the L-shaped membrane logo, and Embedded MATLAB are trademarks of The MathWorks, Inc.