WICHTIG: Der Betrieb von goMatlab.de wird privat finanziert fortgesetzt. - Mehr Infos...

Mein MATLAB Forum - goMatlab.de

Mein MATLAB Forum

 
Gast > Registrieren       Autologin?   

Partner:




Forum
      Option
[Erweitert]
  • Diese Seite per Mail weiterempfehlen
     


Gehe zu:  
Neues Thema eröffnen Neue Antwort erstellen

netcdf - Out of Memory

 

mb005
Forum-Anfänger

Forum-Anfänger


Beiträge: 27
Anmeldedatum: 05.03.09
Wohnort: Rostock
Version: ---
     Beitrag Verfasst am: 04.07.2012, 15:28     Titel: netcdf - Out of Memory
  Antworten mit Zitat      
Hallo Leute ich habe ein netcdf file mit etwa 3.5GB Größe.
Aus diesem File lade ich eine Variable mit 180 x 330 x 8500 Werten. Das laden dauert etwas klappt aber. Bei der weiteren Verarbeitung kommt dann aber out of memory

Code:
function sohip2
%Erzeugung der Variablen im netcdf Format
nccreate('Ergebnis.nc','JMW','Dimensions',{'xlines',331, 'ylines',181, 'zlines',55},'Datatype','single');
nccreate('Ergebnis.nc','JZMW','Dimensions',{'xlines',331, 'ylines',181, 'zlines',55},'Datatype','single');

for z=1:2;

Hs=input('Befehl, Dateiname, Variable:');
% z.B. ncread('SOHIP-V4-1984.nc','hsign');

%Berechnung Jahresmittelwert
%Hs = ncread('test.nc','Hs2');
    for xlines = 1:331;
        for ylines = 1:181;
        Jahresmittel(xlines,ylines)=mean(Hs(xlines,ylines,:));
        end
    end
JM(:,:,z)=(Jahresmittel);
ncwrite('Ergebnis.nc','JMW',JM);


%Berechnung Jahreszeitenmittelwert
 Winter1 = Hs(:,:,1:1416);
 Winter1laenge=length(Winter1);
 Winter2 = Hs(:,:,2004:2784);  
 Winter2laenge=length(Winter2);
 Gesamtlaenge=(Winter1laenge+Winter2laenge-1);
 Winter(:,:,1:Winter1laenge)=Winter1;
 Winter(:,:,Winter1laenge:Gesamtlaenge)=Winter2;

    for xlines = 1:331;
        for ylines = 1:181;
        Wintermittel(xlines,ylines) = mean(Winter(xlines,ylines,:));
        end
    end
JZM_W(:,:,z)=(Wintermittel);
ncwrite('Ergebnis.nc','JZMW',JZM_W);


clear
end


Wenn ich nur 5000 Werte einlese läuft das ganze durch. Ansosnten sagt er in der Zeile
Winter(:,:,1:Winter1laenge)=Winter1;

out of memory.

Habt Ihr ne Idee wie ich das Problem lösen kann ohne die Anzahl der eingelesenen Werte zu verringern?
Ich arbeite mit Matlab 2011b 32 Bit auf einem Remotedesktop von dem ich aktuell nicht weiß mit welcher Rechenleistung er ausgestattet ist. Da es aber der Remoteserver unseres Universitätsrechnezentrums ist gehe ich davon aus, das es doch angemessen sein wird.

Vielen Dank im voraus.

MfG Marcus

edit by denny: bitte die Code-Umgebung nutzen
Private Nachricht senden Benutzer-Profile anzeigen


Jan S
Moderator

Moderator


Beiträge: 11.057
Anmeldedatum: 08.07.10
Wohnort: Heidelberg
Version: 2009a, 2016b
     Beitrag Verfasst am: 05.07.2012, 14:34     Titel: Re: netcdf - Out of Memory
  Antworten mit Zitat      
Hallo mb005,

Das magische Wort heißt "Pre-allocation":

Code:
function sohip2
...
%Berechnung Jahresmittelwert
%Hs = ncread('test.nc','Hs2');
    Jahresmittel = zeros(331, 181);  % Pre-allcoate!
    for xlines = 1:331;
        for ylines = 1:181;
        Jahresmittel(xlines,ylines)=mean(Hs(xlines,ylines,:));
        end
    end

... usw

Wenn man eine Variable in jeder Iteration wachsen läßt, muss Matlab jedes mal Speicherplatz für ein neues Array reservieren und die alten Daten kopieren. Für ein [331x181] Array werden dann nicht 331*181 DOUBLEs reserviert, sondern sum(1:331)*181 und sum(2:331)*181 DOUBLEs kopiert.
Hilft das bereits?

Gruß, Jan
Private Nachricht senden Benutzer-Profile anzeigen
 
mb005
Themenstarter

Forum-Anfänger

Forum-Anfänger


Beiträge: 27
Anmeldedatum: 05.03.09
Wohnort: Rostock
Version: ---
     Beitrag Verfasst am: 16.07.2012, 11:03     Titel:
  Antworten mit Zitat      
Hallo,
vielen Dank für den Vorschlag.
Leider hilft das Zero Array nicht.
Gibt es noch andere Möglichkeiten der Pre Allocation bzw. Speicherzuweisung?

Zu meinem bedauern wurde mir auch mitgeteil, dass der zur Verfügung stehende Arbeitsspeicher doch nicht wirklich groß ist.
Wie groß konnte ich noch immer nicht in Erfahrung bringen.

MfG Marcus
Private Nachricht senden Benutzer-Profile anzeigen
 
Harald
Forum-Meister

Forum-Meister


Beiträge: 24.448
Anmeldedatum: 26.03.09
Wohnort: Nähe München
Version: ab 2017b
     Beitrag Verfasst am: 16.07.2012, 11:32     Titel:
  Antworten mit Zitat      
Hallo,

mir scheint, dass die Daten hier unnötig mehrfach im Speicher liegen.

Statt
Code:
Winter1 = Hs(:,:,1:1416);
Winter2 = Hs(:,:,2004:2784);  
Winter(:,:,1:Winter1laenge)=Winter1;
Winter(:,:,Winter1laenge:Gesamtlaenge)=Winter2;


könnte man wohl das schreiben:
Code:
Winter = Hs(:,:, [1:1416, 2004:2784])


Wenn das alte Hs nicht mehr gebraucht wird, wäre das noch effizienter:
Code:
Hs = Hs(:,:, [1:1416, 2004:2784])

und dann mit Hs weiterarbeiten.

Zudem kann man die geschachtelten for-Schleifen wohl auch durch einen einzigen Aufruf von MEAN ersetzen:
Code:
Jahresmittel = mean(Winter, 3)


Schau dir im Workspace genau an, welche Variablen du hast und wie groß sie sind. Nicht mehr benötigte temporäre Variablen können auch mit CLEAR gelöscht werden.

Grüße,
Harald
Private Nachricht senden Benutzer-Profile anzeigen
 
mb005
Themenstarter

Forum-Anfänger

Forum-Anfänger


Beiträge: 27
Anmeldedatum: 05.03.09
Wohnort: Rostock
Version: ---
     Beitrag Verfasst am: 02.08.2012, 17:07     Titel:
  Antworten mit Zitat      
Hey Leute, eigentlich schien mir das Problem als gelöst und meine Berechnung lief sauber durch, aber nun scheint es wieder ein Memoryproblem zu geben, von dem ich nicht weiß, wie man es schlanker lösen kann.

Hier ein paar Zeilen Quellcode:
Code:

function sohip
%Erzeugung der Variablen im netcdf Format
nccreate('Ergebnis.nc','JM','Dimensions',{'xlines',331, 'ylines',181, 'zlines',55},'Datatype','single');
nccreate('Ergebnis.nc','JZM_F','Dimensions',{'xlines',331, 'ylines',181, 'zlines',55},'Datatype','single');
nccreate('Ergebnis.nc','JZM_S','Dimensions',{'xlines',331, 'ylines',181, 'zlines',55},'Datatype','single');
nccreate('Ergebnis.nc','JZM_H','Dimensions',{'xlines',331, 'ylines',181, 'zlines',55},'Datatype','single');
nccreate('Ergebnis.nc','JZM_W','Dimensions',{'xlines',331, 'ylines',181, 'zlines',55},'Datatype','single');

%Preallocation der Arrays zur Minimierung des Speichebedarfs in den Schleifen
%JM = zeros (331,181,55);

JZM_F = zeros (331,181,55);
%JZM_S = zeros (331,181,55);
%JZM_H = zeros (331,181,55);
%JZM_W = zeros (331,181,55);

for z=1:2;

Hs=input('Befehl, Dateiname, Variable:');
% z.B. ncread('SOHIP-V4-1984.nc','hsign');

%Berechnung Jahresmittelwert
Jahresmittel=mean(Hs,3);
JM(:,:,z)=(Jahresmittel);
ncwrite('Ergebnis.nc','JM',JM);
clear Jahresmittel

%Berechnung Jahreszeitenmittelwert
%Fruehlingmittel = mean (Hs(:,:,1416:3611),3);
%a=length(Fruehlingmittel);
%JZM_F(:,:,z) = (Fruehlingmittel);
JZM_F(:,:,z) = (mean (Hs(:,:,1416:3611),3));
ncwrite('Ergebnis.nc','JZM_F',JZM_F);
 


Das Problem entsteht im letzten Absatz. In der vorletzten Zeile steigt Matlab mit Out of Memory aus.
Wenn ich den ausgewählten Bereich verkleinere (auf 2000 Werte) funktioniert es noch. Ab 2030 Werten Out of Memory.

Ich habe versucht sämtliche Dopplungen der Daten zu vermeiden, aber ich muss ja die Rechenoperation durchführen, bevor ich deren Inhalt in die netcdf Datei schreibe oder nicht?

Auch der Versuch in die netcdf zu schreiben ohne die Variable vorher separate zu erzeugen :
Code:

ncwrite('Ergebnis.nc','JZM_F',(mean (Hs(:,:,1416:3611),3)));

scheitert an out of Memory.

Ich bin ein wenig ratlos.
Der zur Verfügung stehende Speicher sollte ausreichen.
Hat jemand von Euch einen Vorschlag was ich machen könnte?

Gruß Marcus
Private Nachricht senden Benutzer-Profile anzeigen
 
Harald
Forum-Meister

Forum-Meister


Beiträge: 24.448
Anmeldedatum: 26.03.09
Wohnort: Nähe München
Version: ab 2017b
     Beitrag Verfasst am: 02.08.2012, 22:21     Titel:
  Antworten mit Zitat      
Hallo,

Vorschläge:
- die Variable JM löschen
- Hs mit dem Ausschnitt von Hs überschreiben, wenn du du das Original nicht mehr brauchst (siehe Vorschlag zuvor)

Viel dürfte das aber nicht helfen; dann brauchst du entweder mehr Speicher oder musst die Daten "irgendwie" paketweise verarbeiten. Ich kenne mich nicht mit netcdf aus und kann daher nicht sagen wie.

Grüße,
Harald
Private Nachricht senden Benutzer-Profile anzeigen
 
mb005
Themenstarter

Forum-Anfänger

Forum-Anfänger


Beiträge: 27
Anmeldedatum: 05.03.09
Wohnort: Rostock
Version: ---
     Beitrag Verfasst am: 13.08.2012, 11:01     Titel:
  Antworten mit Zitat      
Hey Leute,
also alles Pre-allokieren hat nichts genützt, auch das Vermeiden von doppelt abgelegtem Inhalt reichte nicht aus, out of Memory kam immer wieder.
Aus diesem Grund habe ich das ganze so gelöst, dass nur eine Jahreszeit eingelesen wird, also nur 1/4 des Datenumfangs und dann alle Rechenoperationen mit der Jahreszeit durchgeführt werden und diese dann anschließend gelöscht wird.

Im Matlabcode sieht das folgendermaßen aus:
Code:
%FRÜHLING
%Mittelwert
Hs = ncread(['SOHIP-V4-19',y,'.nc'],'hsign',[1 1 1416],[331 181 2195]);
a=length(Hs);
JZM_F(:,:,z) = (mean (Hs,3));
ncwrite('Ergebnis.nc','JZM_F',JZM_F);
%Relative Eintrittshäufigkeit für Hs = 0.5m / 1.0m / 1.5m
E05F(:,:,z)=(sum((Hs>=0.5),3))/a;
ncwrite('Ergebnis.nc','E05F',E05F);
E10F(:,:,z)=(sum((Hs>=1.0),3))/a;
ncwrite('Ergebnis.nc','E10F',E10F);
E15F(:,:,z)=(sum((Hs>=1.5),3))/a;
ncwrite('Ergebnis.nc','E15F',E15F);
clear Hs
 


So kommt man ohne out of memory durch die Schleifen. Ob das jetzt die beste Lösung ist weiß ich nicht, auf jeden Fall läuft es durch.
Da ich nicht weiß inwiefern die Einlesezeit der 4 Jahreszeiten dem Einlesen des gesamten Jahres entsprict kann ich nichts zur Geschwindigkeitsveränderung der Rechnung durch die AUfteilung sagen.
Naja und wenn es anders nicht funktioniert, nehme ich natürlich auch eine etwas längere Rechenzeit in Kauf.
DAnke für Eure hilfe

MfG Marcus
Private Nachricht senden Benutzer-Profile anzeigen
 
mb005
Themenstarter

Forum-Anfänger

Forum-Anfänger


Beiträge: 27
Anmeldedatum: 05.03.09
Wohnort: Rostock
Version: ---
     Beitrag Verfasst am: 17.08.2012, 14:31     Titel:
  Antworten mit Zitat      
Hallo Leute,eigentlich hatte ich ja mein Memory Problem gelöst, aber es ist noch ein neues dazu gekommen.

Zu beginn erzeuge ich die Variablen im net cdf Format, danach die Matritzen für die Schleifendurchgänge und Fülle diese mit Nullen. Anschließend lese ich die recht große Datei ein.

Code:
%Schleifen für die einzelnen Jahre von 1948 - 1999
tic
for z=1:52;
y=1947+z;
y=num2str(y);
tic
Hs = ncread(['SOHIP-V4-',y,'.nc'],'hsign');

%Jahresmittelwert
Jahresmittel=mean(Hs,3);
JM(:,:,z)=(Jahresmittel);
ncwrite('Ergebnis.nc','JM',JM);
clear Jahresmittel
 


an dieser Stelle lösche ich Jahresmittel wieder und die Anzahl und der Umfang der Variablen ist wie vor der Jahresmittelwertbestimmung, außer das in JM(:,:,1) keine Nullen mehr stehen sondern errechnete Werte.

Jetzt will ich das Jahresmaximum berechnen und an der Stelle steigt Matlab wieder mit out of memory aus
Code:

Jahresmaximum=max(Hs,3);
JMX(:,:,z)=(Jahresmaximum);
ncwrite('Ergebnis.nc','JMX',JMX);
clear Jahresmaximum
clear Hs
 


Nun meine Frage: Wieso funktioniert es für den Jahresmittelwert und nicht für das Jahresmaximum, obwohl der Variablenumfang identisch ist?

Hat einer von Euch ne Idee warum das passiert?
Ich könnte Hs löschen, neu laden und dann das Maximum berechnen, aber das ist ja nu wirklich total blöd oder nich?

Besten Dank schönen Gruß
Marcus
Private Nachricht senden Benutzer-Profile anzeigen
 
Harald
Forum-Meister

Forum-Meister


Beiträge: 24.448
Anmeldedatum: 26.03.09
Wohnort: Nähe München
Version: ab 2017b
     Beitrag Verfasst am: 17.08.2012, 20:27     Titel:
  Antworten mit Zitat      
Hallo,

du hältst dich vermutlich ganz nah an den Grenzen des verfügbaren Speichers auf. Wenn du wirklich nur MEAN durch MAX ersetzt hast, dann würde das wohl heißen, dass MAX intern temporär aus welchen Gründen auch immer mehr Speicher verbraucht als MEAN.

Eine Lösung für das Problem habe ich nicht, außer mit mehr Speicher oder weniger Daten zu arbeiten.

Grüße,
Harald
Private Nachricht senden Benutzer-Profile anzeigen
 
mb005
Themenstarter

Forum-Anfänger

Forum-Anfänger


Beiträge: 27
Anmeldedatum: 05.03.09
Wohnort: Rostock
Version: ---
     Beitrag Verfasst am: 20.08.2012, 15:54     Titel:
  Antworten mit Zitat      
Hallo Ihr,
danke für die Hilfe. Ich habe eine Lösung für das Problem gefunden.
Der Befehl
Code:


arbeitet anders als
Code:


Code:

schreibt nicht das maximum der Matrix b über die dritte Dimension (z-Achse) in eine Matrix mit nur einer z-Ebene, sondern eine Matrix in der selben Dimension wie b gefüllt mit der Zahl 3.
Aus diesem Grund wird eine zweite Matrix von erheblichem Ausmaß erzeugt, was auch der Grund für das Out of Memory an dieser Stelle ist.
Die Lösung des Problems liegt in der richtigen Anwendung von max. Der Befehl sieht dann so aus
Code:


Dann gibts auch kein out of memory und alle sind glücklich.

Bis demnächst,
Gruß Marcus
Private Nachricht senden Benutzer-Profile anzeigen
 
Neues Thema eröffnen Neue Antwort erstellen



Einstellungen und Berechtigungen
Beiträge der letzten Zeit anzeigen:

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
.





 Impressum  | Nutzungsbedingungen  | Datenschutz | FAQ | goMatlab RSS Button RSS

Hosted by:


Copyright © 2007 - 2024 goMatlab.de | Dies ist keine offizielle Website der Firma The Mathworks

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.