[C++] dump di struttura dati se il programma termina male

Linguaggi di programmazione: php, perl, python, C, bash e tutti gli altri.
Scrivi risposta
Avatar utente
vaeVictis
Imperturbabile Insigne
Imperturbabile Insigne
Messaggi: 4703
Iscrizione: venerdì 27 luglio 2012, 17:58
Desktop: Gnome
Distribuzione: Ubuntu 20.04 64bit

[C++] dump di struttura dati se il programma termina male

Messaggio da vaeVictis »

Ciao a tutti.
Nella speranza di aver indicato correttamente il problema nel titolo, passo rapidamente a spiegare quello che dovrei risolvere.

Sto facendo alcune simulazioni su un cluster.
Quando si lancia la simulazione, va specificato al cluster il tempo macchina che servirà. Questo tempo macchina può essere stimato a priori, ma capita che invece serva più tempo.
Se l'esecuzione del programma sfora dai tempi "richiesti", il sistema operativo del cluster termina "brute force" la simulazione.
Questo comporta la spiacevole, e non poco frequente situazione, in cui una simulazione venga terminata a poco dalla fine (dove per poco si intende che il programma ha quasi finito di fare quello che deve fare).

Ora... la simulazione riguarda l'elaborazione di una struttura dati (un vector di vector) ed è perfettamente deterministica, nel senso che conoscendo la struttura dati nel momento in cui la simulazione viene "terminata" si può far ripartire da dove è defunta.
Mi sto pertanto chiedendo come istruire il programma per poter fare un dump di questa struttura dati, prima di terminare quando gli arriva il "segnale di morte" da parte del sistema operativo (bsd) che gira sul cluster.
Per dump io intendo che la struttura dati venga scritta "in qualche modo" da "qualche parte" e che possa essere poi letta nuovamente in un secondo momento.

Vorrei pertanto qualche consiglio a riguardo.
In caso, ditemi anche se devo chiedere qualche ulteriore informazione all'amministratore del cluster.

Grazie in anticipo
:ciao:
Pirates arrrrrrrrrrr awesome!!!
«I fear not the man who has practiced 10000 kicks once,
but I fear the man who has practiced one kick 10000 times.»
Avatar utente
bite
Imperturbabile Insigne
Imperturbabile Insigne
Messaggi: 3798
Iscrizione: sabato 19 maggio 2007, 22:10

Re: [C++] dump di struttura dati se il programma termina mal

Messaggio da bite »

Facendo l'ipotesi che bsd (non lo conosco) segua lo standard posix dei segnali:

- se ti manda SIGTERM (o SIGINT, o SIGABRT) potresti fare un handler che scrive i dati su file prima di terminare:

- se invece ti manda SIGKILL, che non si lascia menare per il naso, l'unica possibilità che vedo è di scrivere periodicamente i dati parziali, in modo che alla terminazione forzata tu perda solo il lavoro fatto dall'ultima volta che li hai scritti.
Avatar utente
vaeVictis
Imperturbabile Insigne
Imperturbabile Insigne
Messaggi: 4703
Iscrizione: venerdì 27 luglio 2012, 17:58
Desktop: Gnome
Distribuzione: Ubuntu 20.04 64bit

Re: [C++] dump di struttura dati se il programma termina mal

Messaggio da vaeVictis »

Ciao bite!
È davvero un piacere leggerti! :)

Ho parlato oggi con l'admin e pare che l'opzione migliore sia proprio la seconda che indichi.
La piattaforma è MPI e sembra che non si possa intercettare nulla, anche se io in realtà pensavo non tanto di intercettare i segnali (mi sono espresso male) ma di usare qualche funzione di quelle che (se non ricordo male) servono per fare pulizia quando un programma è chiuso "male" (sto rimembrando cose lette sul gapil che al momento non ho sotto mano).

Pare invece che la soluzione sia quella di mettere un controllo "temporale" internamente allo script bash che lancia il programma in c++.
Quando lo script si accorge dell'imminente e inevitabile conclusione del tempo a disposizione, lancia lui un segnale appropriato che poi verrà gestito internamente.

Dal momento che sto psicofisicamente provato, per oggi è tutto.
Domani vorrei approfittare della tua disponibilità per chiederti qualche consiglio su come gestire al meglio alcuni "piccoli" dettagli ;)

Grazie per l'interessamento
Pirates arrrrrrrrrrr awesome!!!
«I fear not the man who has practiced 10000 kicks once,
but I fear the man who has practiced one kick 10000 times.»
Avatar utente
bite
Imperturbabile Insigne
Imperturbabile Insigne
Messaggi: 3798
Iscrizione: sabato 19 maggio 2007, 22:10

Re: [C++] dump di struttura dati se il programma termina mal

Messaggio da bite »

vaeVictis [url=http://forum.ubuntu-it.org/viewtopic.php?p=4569658#p4569658][img]http://forum.ubuntu-it.org/images/icons/icona-cita.gif[/img][/url] ha scritto: Domani vorrei approfittare della tua disponibilità per chiederti qualche consiglio su come gestire al meglio alcuni "piccoli" dettagli ;)
Farò un salto da queste parti. :)
Ikitt
Entusiasta Emergente
Entusiasta Emergente
Messaggi: 1816
Iscrizione: mercoledì 24 ottobre 2007, 12:05

Re: [C++] dump di struttura dati se il programma termina mal

Messaggio da Ikitt »

vedi anche se atexit() puo` fare al caso tuo.
antex
Prode Principiante
Messaggi: 85
Iscrizione: mercoledì 14 marzo 2012, 20:59

Re: [C++] dump di struttura dati se il programma termina mal

Messaggio da antex »

Non credo (neanche su BSD) che gli handler registrati con atexit vengano eseguiti se il programma termina a causa di un segnale. O no?
Avatar utente
vaeVictis
Imperturbabile Insigne
Imperturbabile Insigne
Messaggi: 4703
Iscrizione: venerdì 27 luglio 2012, 17:58
Desktop: Gnome
Distribuzione: Ubuntu 20.04 64bit

Re: [C++] dump di struttura dati se il programma termina mal

Messaggio da vaeVictis »

A dire il vero era proprio quello a cui stavo pensando per i vaghi ricordi di quanto avevo appunto letto sul gapil.
Parlando con l'admin è venuto fuori un secondo approccio (descritto sopra) che sembra più semplice da inserire nel codice già esistente.
Vorrei quindi provare entrambe le strade, anche per scopi prettamente didattici. Sebbene penso che la soluzione sarà quanto discusso con l'admin.

Ho però una domanda che si applica ad entrambi i metodi.
Io ho una "struttura dati" da salvare in qualche modo.
Le due quantità sono un array di array (o un vector di vector a seconda della simulazione che sto facendo girare), che rappresenta "quello che evolve" nel tempo, più un unsigned long int che rappresenta il tempo.
Devo salvarli entrambi per poter poi riavviare il tutto leggendo lo stato a cui si è arrivati con l'evoluzione e il tempo a cui si è arrivati.

Quale è il modo migliore per salvare queste due quantità? Su file? Salvo tutti i valori? Comprimo in qualche modo?
Aspetto dritte! :)
Pirates arrrrrrrrrrr awesome!!!
«I fear not the man who has practiced 10000 kicks once,
but I fear the man who has practiced one kick 10000 times.»
Avatar utente
bite
Imperturbabile Insigne
Imperturbabile Insigne
Messaggi: 3798
Iscrizione: sabato 19 maggio 2007, 22:10

Re: [C++] dump di struttura dati se il programma termina mal

Messaggio da bite »

Quanto sono grossi?

Dubito comunque che valga la pena comprimere. Più i dati somigliano a numeri casuali, meno si comprimono

Con questo non voglio dire che i risultati della tua simulazione sono casuali, eh :)
Avatar utente
vaeVictis
Imperturbabile Insigne
Imperturbabile Insigne
Messaggi: 4703
Iscrizione: venerdì 27 luglio 2012, 17:58
Desktop: Gnome
Distribuzione: Ubuntu 20.04 64bit

Re: [C++] dump di struttura dati se il programma termina mal

Messaggio da vaeVictis »

È una matrice quadrata di numeri in virgila mobile di dimensione "notevole", anche 1000x1000. Sebbene io in realtà ne utilizzi solo uno spicchio, devo salvarla tutta per poi rileggerla, insieme ad un altro singolo valore intero.
La matrice è composta di numeri che, localmente, sono quasi uguali. Su grande scala variano. Ma localmente sono molto vicini l'uno all'altro.
Questa condizione però non è detto che sia sempre verificata. Quindi... è una matrice di float quadrata e di dimensione molto grande :)

Come mi consigli di salvarla?
Pirates arrrrrrrrrrr awesome!!!
«I fear not the man who has practiced 10000 kicks once,
but I fear the man who has practiced one kick 10000 times.»
Avatar utente
bite
Imperturbabile Insigne
Imperturbabile Insigne
Messaggi: 3798
Iscrizione: sabato 19 maggio 2007, 22:10

Re: [C++] dump di struttura dati se il programma termina mal

Messaggio da bite »

Un milione di double fa 8 Mb se salvati in binario, non è poi la fine del mondo. Non starei a cercare arzigogoli tipo salvare la differenza tra numeri contigui mettendola in meno di 8 byte.

Com'è allocata la matrice? Tutta contigua? Contigua per riga? Contigua per colonna? Se fosse garantito che è contigua per riga (ad esempio se è un vector<vector<double> >) potresti salvarla per righe dando a write o fwrite l'indirizzo del primo elemento della riga e specificando la dimensione opportuna.
Avatar utente
vaeVictis
Imperturbabile Insigne
Imperturbabile Insigne
Messaggi: 4703
Iscrizione: venerdì 27 luglio 2012, 17:58
Desktop: Gnome
Distribuzione: Ubuntu 20.04 64bit

Re: [C++] dump di struttura dati se il programma termina mal

Messaggio da vaeVictis »

Risposta breve
La "cosa" da salvare è il primo elemento di questo "pair":

Codice: Seleziona tutto

      std::pair<std::vector<std::vector<long double> >, std::vector<std::vector<long double> > > mat
Risposta articolata (che non so se può esserti utile)
Allora, la "coppia di matrici" mat, di cui devo salvare la prima, è definita come membro nella classe densMat.
L'header della classe è:

Codice: Seleziona tutto

#ifndef densMat_H
#define densMat_H

#include <utility>
#include <vector>

class densMat {
	public:
		typedef std::vector<long double> ldVec;
		unsigned long halfSide;
		double dens_o, meanDens;
		unsigned long gridDim; 
		long double initialGridParts;
		std::pair<std::vector<ldVec>, std::vector<ldVec> > mat;
		densMat(const unsigned long &, const long double &, const long double &);
		void update();
};

#endif
Tenendo quindi in considerazione che ho ridefinito i tipi di dato:

Codice: Seleziona tutto

		typedef std::vector<long double> ldVec;
il costruttore é:

Codice: Seleziona tutto

densMat::densMat(const unsigned long &bound,
                 const long double &trapDens,
                 const long double &gridDens): 
halfSide(bound), dens_o(trapDens), meanDens(gridDens),
gridDim((2 * halfSide + 1)),
initialGridParts(meanDens * ((gridDim)*(gridDim) - 1)),
mat(vector< ldVec >(gridDim + 2, ldVec(gridDim + 2, meanDens)), 
    vector< ldVec >(gridDim + 2, ldVec(gridDim + 2, meanDens)))
{
	mat.first[halfSide+1][halfSide+1] = dens_o;
	mat.second[halfSide+1][halfSide+1] = dens_o;
}
e io devo fare il dump del primo elemento di questa coppia di matrici:

Codice: Seleziona tutto

mat(vector< ldVec >(gridDim + 2, ldVec(gridDim + 2, meanDens)), 
    vector< ldVec >(gridDim + 2, ldVec(gridDim + 2, meanDens)))
{
	mat.first[halfSide+1][halfSide+1] = dens_o;
	mat.second[halfSide+1][halfSide+1] = dens_o;
}
... in quanto le altre "cose" inizializzate nel costruttore non vengono toccate, quindi io so quanto valevano.

Riavvolgendo il nastro :) il dato da salvare è il primo elemento di questo pair:

Codice: Seleziona tutto

		std::pair<std::vector<std::vector<long double> >, std::vector<std::vector<long double> > > mat
Aspetto tue nuove :)
:ciao:

p.s.:
Anche se credo di non avere enormi difficoltà a comprendere di cosa si tratti, faccio presente che non ho mai salvato su file binario e sono totalmente ignorante in merito.

p.p.s.:
Dopo aver capito quale sia il modo migliore per fare questo dump, con il fine di poter poi rileggere la matrice salvata, vorrei anche farti un'ulteriore paio di domandine sempre su questo problema. O meglio, sulla lettura.
Pirates arrrrrrrrrrr awesome!!!
«I fear not the man who has practiced 10000 kicks once,
but I fear the man who has practiced one kick 10000 times.»
Avatar utente
bite
Imperturbabile Insigne
Imperturbabile Insigne
Messaggi: 3798
Iscrizione: sabato 19 maggio 2007, 22:10

Re: [C++] dump di struttura dati se il programma termina mal

Messaggio da bite »

Capisco bene, le matrici sono due?

Inoltre mi confermi quel che avevo dato per scontato e cioé che non si tratta di matrici sparse (con la maggioranza degli elementi identicamente nulli)?

I metodi potrebbero essere questi:

Codice: Seleziona tutto

int densMat::dump (const char * pathname)
{
  int fd = open (pathname, O_CREAT | O_TRUNC | O_WRONLY | O_SYNC, S_IRWXU);
  if (fd < 0) return -1;
  ssize_t outcome;
  outcome = write (fd, &halfSide, sizeof(halfSide));
  if (outcome <= 0) {
  	close (fd);
  	unlink (pathname);
  	return -1;
  }
  size_t count = sizeof (long double) * (gridDim + 2);
  for (unsigned long row = 0; row < gridDim + 2; row++) {
  	outcome = write (fd, &mat.first[row][0],	count);
		if (outcome < count) {
			close (fd);
			unlink (pathname);
			return -1;
		}
  }
  for (unsigned long row = 0; row < gridDim + 2; row++) {
  	outcome = write (fd, &mat.second[row][0], count);
		if (outcome < count) {
			close (fd);
			unlink (pathname);
			return -1;
		}
  }
  return 0;
}

int densMat::load (const char * pathname)
{
  int fd = open (pathname, O_RDONLY);
  if (fd < 0) return -1;
  ssize_t outcome;
  outcome = read (fd, &halfSide, sizeof(halfSide));
  if (outcome <= 0) {
  	close (fd);
  	unlink (pathname);
  	return -1;
  }
  gridDim = 2 * halfSide + 1;
  size_t count = sizeof (long double) * (gridDim + 2);
  for (unsigned long row = 0; row < gridDim + 2; row++) {
  	outcome = read (fd, &mat.first[row][0],	count);
		if (outcome < count) {
			close (fd);
			return -1;
		}
  }
  for (unsigned long row = 0; row < gridDim + 2; row++) {
  	outcome = read (fd, &mat.second[row][0], count);
		if (outcome < count) {
			close (fd);
			return -1;
		}
  }
  close (fd);
  return 0;
}
Se ritornano -1 devi controllare errno.
S_IRWXU presume che il file dati non debba essere reso accessibile ad altri.

Ti conviene fare una prova di scrittura e rilettura in locale prima di mandarlo nel cluster.

Curiosità: perché passi parametri long double e poi li metti dentro a double?

Ciao
Avatar utente
bite
Imperturbabile Insigne
Imperturbabile Insigne
Messaggi: 3798
Iscrizione: sabato 19 maggio 2007, 22:10

Re: [C++] dump di struttura dati se il programma termina mal

Messaggio da bite »

Ah scusa, vedo adesso che devi salvare solo il primo elemento del pair. Beh, basta togliere il secondo for.
Avatar utente
vaeVictis
Imperturbabile Insigne
Imperturbabile Insigne
Messaggi: 4703
Iscrizione: venerdì 27 luglio 2012, 17:58
Desktop: Gnome
Distribuzione: Ubuntu 20.04 64bit

Re: [C++] dump di struttura dati se il programma termina mal

Messaggio da vaeVictis »

bite [url=http://forum.ubuntu-it.org/viewtopic.php?p=4573070#p4573070][img]http://forum.ubuntu-it.org/images/icons/icona-cita.gif[/img][/url] ha scritto:Ah scusa, vedo adesso che devi salvare solo il primo elemento del pair. Beh, basta togliere il secondo for.
Ci mancherebbe!
Colpa mia: ho rieditato un paio di volte il messaggio precedente perché mi ero accorto di non essere stato per niente chiaro :)

Provo, elucubro e mi rifaccio vivo.
Grazie mille per la disponibilità.

p.s.:
Rispondo a tutto domani, massimo dopodomani.
Sto cerebralmente accartocciato.
Pirates arrrrrrrrrrr awesome!!!
«I fear not the man who has practiced 10000 kicks once,
but I fear the man who has practiced one kick 10000 times.»
Scrivi risposta

Ritorna a “Programmazione”

Chi c’è in linea

Visualizzano questa sezione: Google [Bot] e 2 ospiti