|
|
|
![]() |
|
Strumenti |
![]() |
#1 |
Senior Member
Iscritto dal: Nov 2002
Messaggi: 6029
|
[C] Problema MPI e matrici trasposte
Salve,
sto facendo un programma che fa la matrice trasposta in modo parallelo. A tal proposito, ho definito una matrice 8x8 ed un'altra 2x8. Uso 4 processori: Codice:
float**matrice_nativa; float**matrice_nativa_locale; matrice_nativa= malloc(8*sizeof(float*)); matrice_nativa_locale=malloc(2*sizeof(float*)); for(i=0; i<2;i++) { matrice_nativa_locale[i]=malloc(8*sizeof(float)); } for(i=0; i<8;i++) { matrice_nativa[i]=malloc(8*sizeof(float)); } Codice:
if(me==0) { for(i=0;i<4;i++) { MPI_Send(&matrice_nativa[i*2][0],16,MPI_REAL,i,0,MPI_COMM_WORLD); } } MPI_Recv(&matrice_nativa_locale[0][0],16,MPI_REAL,0,0,MPI_COMM_WORLD,&status); Codice:
Matrice nativa : [ 3.0 6.0 17.0 15.0 13.0 15.0 6.0 12.0 ] [ 9.0 1.0 2.0 7.0 10.0 19.0 3.0 6.0 ] [ 0.0 6.0 12.0 16.0 11.0 8.0 7.0 9.0 ] [ 2.0 10.0 2.0 3.0 7.0 15.0 9.0 2.0 ] [ 2.0 18.0 9.0 7.0 13.0 16.0 11.0 2.0 ] [ 9.0 13.0 1.0 19.0 4.0 17.0 18.0 4.0 ] [ 15.0 10.0 13.0 6.0 11.0 0.0 16.0 13.0 ] [ 2.0 10.0 16.0 1.0 5.0 5.0 4.0 7.0 ] Codice:
Matrice nativa locale dal processore : 0 [ 3.0 6.0 17.0 15.0 13.0 15.0 6.0 12.0 ] [ 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 ] Matrice nativa locale dal processore : 2 [ 2.0 18.0 9.0 7.0 13.0 16.0 11.0 2.0 ] [ 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 ] Matrice nativa locale dal processore : 1 [ 0.0 6.0 12.0 16.0 11.0 8.0 7.0 9.0 ] [ 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 ] Matrice nativa locale dal processore : 3 [ 15.0 10.0 13.0 6.0 11.0 0.0 16.0 13.0 ] [ 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 ] Il programma in realtà è parametrico, non lavora ssolo su matrici 8x8, ma quadrate. Ho messo un numero secco per evitare di scrivere troppe cose, tanto il problema si presenta anche in questo caso. grazie a chiunque mi aiuti. Ultima modifica di Unrue : 01-01-2007 alle 17:55. |
![]() |
![]() |
![]() |
#2 |
Senior Member
Iscritto dal: May 2006
Città: Wursteland
Messaggi: 1749
|
scusa ma tu con questa istruzione
Codice:
MPI_Send(&matrice_nativa[i*2][0],16,MPI_REAL,i,0,MPI_COMM_WORLD); Infatti gli passi il puntatore alla riga e il numero di valori (16) ... come fa la funzione a sapere che sono 8 valori per riga ???
__________________
Nintendo WIII 4d Turbo Intercooler - Sestium X 666 99,312 GHz - 6.984 Ram Σ(9999) MHz - HDD SATA 97e^(10) bytes 93³ rpm - ATI biberon X900z ∞Mb - Win Eight SP (1 > yours) 16 Valve |
![]() |
![]() |
![]() |
#3 | |
Senior Member
Iscritto dal: Nov 2002
Messaggi: 6029
|
Quote:
Ultima modifica di Unrue : 02-01-2007 alle 10:15. |
|
![]() |
![]() |
![]() |
#4 | |
Senior Member
Iscritto dal: May 2006
Città: Wursteland
Messaggi: 1749
|
Quote:
Io non mi azzarderei a passare 16 elementi che sono divisi in 2 righe allocate dinamicamente ad una funzione che vuole un indirizzo iniziale e il numero di elementi come parametri.
__________________
Nintendo WIII 4d Turbo Intercooler - Sestium X 666 99,312 GHz - 6.984 Ram Σ(9999) MHz - HDD SATA 97e^(10) bytes 93³ rpm - ATI biberon X900z ∞Mb - Win Eight SP (1 > yours) 16 Valve |
|
![]() |
![]() |
![]() |
#5 | |
Senior Member
Iscritto dal: Nov 2002
Messaggi: 6029
|
Quote:
Ultima modifica di Unrue : 02-01-2007 alle 11:07. |
|
![]() |
![]() |
![]() |
#6 | |
Senior Member
Iscritto dal: May 2006
Città: Wursteland
Messaggi: 1749
|
Quote:
Infatti compila questo : Codice:
#include <stdio.h> #include <sys/types.h> #include <unistd.h> int main() { float **matrice_nativa; int i, j; matrice_nativa = malloc(8*sizeof(float*)); for( i = 0; i < 8; i++) matrice_nativa[i] = malloc(8*sizeof(float)); for( i = 0; i < 8; i++) for( j = 0; j < 8; j++) matrice_nativa[i][j] = i * j; for( i = 0;i < 4; i++ ) MPI_Send(&matrice_nativa[i*2][0],16,MPI_REAL,i,0,MPI_COMM_WORLD); for( i = 0; i < 8; i++) free(matrice_nativa[i]); free(matrice_nativa); return 0; } void MPI_Send( float *ppM, int Count ) { int i; for (i = 0; i < Count; i++ ) printf( "<%.0f> ", ppM[i] ); puts(""); }
__________________
Nintendo WIII 4d Turbo Intercooler - Sestium X 666 99,312 GHz - 6.984 Ram Σ(9999) MHz - HDD SATA 97e^(10) bytes 93³ rpm - ATI biberon X900z ∞Mb - Win Eight SP (1 > yours) 16 Valve |
|
![]() |
![]() |
![]() |
#7 |
Senior Member
Iscritto dal: Nov 2002
Messaggi: 6029
|
Dunque, le righe in c sono contigue in memoria, però ovviamente il c sa dove inizia e finisce una, quindi l'aritmetica dei puntatori è salva. Riguardo MPI_Send, è una funzione propria di MPI, non l'ho definita io. A me pare di ricordare che si possa fare come ho fatto io, altrimenti sarebbe un enorme spreco, in quanto si dovrebbe fare una MPi_Send per ogni riga della matrice, anche per inviare più righe allo stesso processore.
|
![]() |
![]() |
![]() |
#8 | |
Senior Member
Iscritto dal: May 2006
Città: Wursteland
Messaggi: 1749
|
Quote:
Infatti ecco l'output del mio esempio: Codice:
< 1> < 1> < 1> < 1> < 1> < 1> < 1> < 1> < 2> < 2> < 2> < 2> < 2> < 2> < 2> < 2> < 3> < 3> < 3> < 3> < 3> < 3> < 3> < 3> < 4> < 4> < 4> < 4> < 4> < 4> < 4> < 4> < 5> < 5> < 5> < 5> < 5> < 5> < 5> < 5> < 6> < 6> < 6> < 6> < 6> < 6> < 6> < 6> < 7> < 7> < 7> < 7> < 7> < 7> < 7> < 7> < 8> < 8> < 8> < 8> < 8> < 8> < 8> < 8> < 1> < 1> < 1> < 1> < 1> < 1> < 1> < 1> < 0> < 0> < 2> < 2> < 2> < 2> < 2> < 2> < 3> < 3> < 3> < 3> < 3> < 3> < 3> < 3> < 0> < 0> < 4> < 4> < 4> < 4> < 4> < 4> < 5> < 5> < 5> < 5> < 5> < 5> < 5> < 5> < 0> < 0> < 6> < 6> < 6> < 6> < 6> < 6> < 7> < 7> < 7> < 7> < 7> < 7> < 7> < 7> < 0> < 0> < 8> < 8> < 8> < 8> < 8> < 8> La seconda stampa come fai tu. Una riga ogni 2 ma 16 elementi. Puoi ben vedere che non corrisponde perfettamente. Gli elementi ci sono ma spostati Ma puoi risolvere il problema facendo una matrice 4 X 16 ![]()
__________________
Nintendo WIII 4d Turbo Intercooler - Sestium X 666 99,312 GHz - 6.984 Ram Σ(9999) MHz - HDD SATA 97e^(10) bytes 93³ rpm - ATI biberon X900z ∞Mb - Win Eight SP (1 > yours) 16 Valve |
|
![]() |
![]() |
![]() |
#9 |
Senior Member
Iscritto dal: Nov 2002
Messaggi: 6029
|
Grazie del chiarimento, però non capisco da cosa sia dato il numero di 0 che sono presenti tra una riga e l'altra e sopratutto perchè la MPI_Send invii solo una riga, e non due spostate come nel tuo esempio.
Ultima modifica di Unrue : 02-01-2007 alle 13:24. |
![]() |
![]() |
![]() |
#10 | |
Senior Member
Iscritto dal: May 2006
Città: Wursteland
Messaggi: 1749
|
Quote:
![]() visto che lavori abbastanza a basso livello ti potrebbe servire questo che mi son fatto per analizzare buffers e aree di memoria: Codice:
#include <stdio.h> #include <ctype.h> #include <stdlib.h> #define WRAP_MSG_LEN 96 #define USAGE_STR "\n\n" \ "Visualizza un buffer (anche binario) nel seguente formato:\n" \ "\n" \ "¤···½····1····½· numero colonna\n" \ "----------------\n" \ " AbCd-+GhIjK carattere (se stampabile)\n" \ "----------------\n" \ "3333446462246464 carattere in\n" \ "CDEF01234DB789AB esadecimale\n\n" \ " trallallero 20 Gennaio 2005\n" /* *\ "LOGGA" UN BUFFER pBuf (ANCHE BINARIO) NEL SEGUENTE FORMATO: ¤···½····1····½· NUMERO COLONNA ---------------- ABCDEFGHIJK CARATTERE (SE STAMPABILE) ---------------- 3333444444444444 CARATTERE IN CDEF0123456789AB ESADECIMALE \* */ int HexAlphaLogger( unsigned char *pBuf ) { int i, c, Len, IsLong = strlen(pBuf) > WRAP_MSG_LEN; unsigned char pS[WRAP_MSG_LEN + 1]; if ( IsLong ) strncpy( (char *)pS, pBuf, WRAP_MSG_LEN ); else strcpy ( (char *)pS, pBuf ); pS[WRAP_MSG_LEN] = 0x00; Len = strlen( pS ); putchar( '\n' ); /* STAMPO I NUMERI */ for ( i = 1, c = 1; i < Len; i++ ) if ( i == 1 ) putchar( '¹' /*'¤'*/ ); else if ( i % 10 == 0 ) putchar( c++ + 48 ); else if ( i % 5 == 0 ) putchar( '½' ); else putchar( '·' ); putchar( '\n' ); /* STAMPO IL DIVISORIO */ for ( i = 0; i < Len; i++) printf( "-" ); putchar( '\n' ); /* STAMPO IL CARATTERE SE ALPHA */ for ( i = 0; i < Len; i++) printf( "%c", (isalpha(pS[i])) ? pS[i] : ' ' ); putchar( '\n' ); /* STAMPO IL DIVISORIO */ for ( i = 0; i < Len; i++) printf( "-" ); putchar( '\n' ); /* STAMPO GLI ESADECIMALI IN VERT. */ for ( c = 0; c < 2; c++ ) { for ( i = 0; i < Len; i++ ) { unsigned int n = (unsigned int)pS[i]; unsigned char s[3]; sprintf( (char *)s, "%02X", n ); putchar( c ? s[1] : s[0] ); } putchar( '\n' ); } /* STAMPO IL DIVISORIO */ for ( i = 0; i < Len; i++) printf( "-" ); putchar( '\n' ); /* STAMPO GLI ESADECIMALI IN VERT. */ for ( c = 0; c < 2; c++ ) { for ( i = 0; i < Len; i++ ) { unsigned int n = (unsigned int)pS[i]; unsigned char s[3]; sprintf( (char *)s, "%02i", n ); putchar( c ? s[1] : s[0] ); } putchar( '\n' ); } /* RICORSIONE SE MSG LUNGO */ if ( IsLong ) HexAlphaLogger( pBuf + WRAP_MSG_LEN ); putchar( '\n' ); } /*------------------------------*\ \*------------------------------*/ void main( int argc, char **argv ) { if ( argc == 1 ) printf( "%s SINTASSI: <%s> <buffer> %s", argv[0], argv[0], USAGE_STR ); else { int i = 1; while ( i < argc ) HexAlphaLogger( (unsigned char *)argv[i++] ); } } ![]()
__________________
Nintendo WIII 4d Turbo Intercooler - Sestium X 666 99,312 GHz - 6.984 Ram Σ(9999) MHz - HDD SATA 97e^(10) bytes 93³ rpm - ATI biberon X900z ∞Mb - Win Eight SP (1 > yours) 16 Valve Ultima modifica di trallallero : 02-01-2007 alle 13:31. |
|
![]() |
![]() |
![]() |
#11 |
Senior Member
Iscritto dal: Nov 2002
Messaggi: 6029
|
Grazie infinite, gli darò un'occhiata. Nel frattempo seguo il tuo consiglio sulla matrice 4x16
![]() |
![]() |
![]() |
![]() |
#12 | |
Senior Member
Iscritto dal: Nov 2002
Messaggi: 6029
|
Quote:
Ultima modifica di Unrue : 02-01-2007 alle 14:54. |
|
![]() |
![]() |
![]() |
#13 | |
Senior Member
Iscritto dal: May 2006
Città: Wursteland
Messaggi: 1749
|
Quote:
![]()
__________________
Nintendo WIII 4d Turbo Intercooler - Sestium X 666 99,312 GHz - 6.984 Ram Σ(9999) MHz - HDD SATA 97e^(10) bytes 93³ rpm - ATI biberon X900z ∞Mb - Win Eight SP (1 > yours) 16 Valve |
|
![]() |
![]() |
![]() |
#14 |
Member
Iscritto dal: Apr 2004
Messaggi: 130
|
Sulla falsariga del codice di Trallallero:
Codice:
[qu@ker tmp]$ ./allineamento < 1> < 1> < 1> < 1> < 1> < 1> < 1> < 1> indirizzo iniziale: 0x601060 < 2> < 2> < 2> < 2> < 2> < 2> < 2> < 2> indirizzo iniziale: 0x601090 < 3> < 3> < 3> < 3> < 3> < 3> < 3> < 3> indirizzo iniziale: 0x6010c0 < 4> < 4> < 4> < 4> < 4> < 4> < 4> < 4> indirizzo iniziale: 0x6010f0 < 5> < 5> < 5> < 5> < 5> < 5> < 5> < 5> indirizzo iniziale: 0x601120 < 6> < 6> < 6> < 6> < 6> < 6> < 6> < 6> indirizzo iniziale: 0x601150 < 7> < 7> < 7> < 7> < 7> < 7> < 7> < 7> indirizzo iniziale: 0x601180 < 8> < 8> < 8> < 8> < 8> < 8> < 8> < 8> indirizzo iniziale: 0x6011b0 |00| |04| |08| |0c| |10| |14| |18| |1c| |20| |24| |28| |2c| |30| < 1> < 1> < 1> < 1> < 1> < 1> < 1> < 1> < 0> < 0> < 0> < 0> < 2> < 2> < 2> < 2> < 3> < 3> < 3> < 3> < 3> < 3> < 3> < 3> < 0> < 0> < 0> < 0> < 4> < 4> < 4> < 4> < 5> < 5> < 5> < 5> < 5> < 5> < 5> < 5> < 0> < 0> < 0> < 0> < 6> < 6> < 6> < 6> < 7> < 7> < 7> < 7> < 7> < 7> < 7> < 7> < 0> < 0> < 0> < 0> < 8> < 8> < 8> < 8> [qu@ker tmp]$ uname -m x86_64 [qu@ker tmp]$ info libc Aligned 2>&1 | sed -ne '5,9p' 3.2.2.7 Allocating Aligned Memory Blocks ........................................ The address of a block returned by `malloc' or `realloc' in the GNU system is always a multiple of eight (or sixteen on 64-bit systems). [qu@ker tmp]$ |
![]() |
![]() |
![]() |
#15 | |
Senior Member
Iscritto dal: May 2006
Città: Wursteland
Messaggi: 1749
|
Quote:
__________________
Nintendo WIII 4d Turbo Intercooler - Sestium X 666 99,312 GHz - 6.984 Ram Σ(9999) MHz - HDD SATA 97e^(10) bytes 93³ rpm - ATI biberon X900z ∞Mb - Win Eight SP (1 > yours) 16 Valve |
|
![]() |
![]() |
![]() |
#16 |
Member
Iscritto dal: Apr 2004
Messaggi: 130
|
Scusa, ho postato il pezzo sbagliato!
![]() Codice:
[qu@ker tmp]$ ./allin < 1> < 1> < 1> < 1> < 1> < 1> < 1> < 1> indirizzo iniziale: 0x601060 spazio utilizzabile: 40 (0x28) < 2> < 2> < 2> < 2> < 2> < 2> < 2> < 2> indirizzo iniziale: 0x601090 spazio utilizzabile: 40 (0x28) < 3> < 3> < 3> < 3> < 3> < 3> < 3> < 3> indirizzo iniziale: 0x6010c0 spazio utilizzabile: 40 (0x28) < 4> < 4> < 4> < 4> < 4> < 4> < 4> < 4> indirizzo iniziale: 0x6010f0 spazio utilizzabile: 40 (0x28) < 5> < 5> < 5> < 5> < 5> < 5> < 5> < 5> indirizzo iniziale: 0x601120 spazio utilizzabile: 40 (0x28) < 6> < 6> < 6> < 6> < 6> < 6> < 6> < 6> indirizzo iniziale: 0x601150 spazio utilizzabile: 40 (0x28) < 7> < 7> < 7> < 7> < 7> < 7> < 7> < 7> indirizzo iniziale: 0x601180 spazio utilizzabile: 40 (0x28) < 8> < 8> < 8> < 8> < 8> < 8> < 8> < 8> indirizzo iniziale: 0x6011b0 spazio utilizzabile: 40 (0x28) |00| |04| |08| |0c| |10| |14| |18| |1c| |20| |24| |28| |2c| |30| < 1> < 1> < 1> < 1> < 1> < 1> < 1> < 1> < 0> < 0> < 0> < 0> < 2> < 2> < 2> < 2> < 3> < 3> < 3> < 3> < 3> < 3> < 3> < 3> < 0> < 0> < 0> < 0> < 4> < 4> < 4> < 4> < 5> < 5> < 5> < 5> < 5> < 5> < 5> < 5> < 0> < 0> < 0> < 0> < 6> < 6> < 6> < 6> < 7> < 7> < 7> < 7> < 7> < 7> < 7> < 7> < 0> < 0> < 0> < 0> < 8> < 8> < 8> < 8> [qu@ker tmp]$ |
![]() |
![]() |
![]() |
#17 | |
Senior Member
Iscritto dal: May 2006
Città: Wursteland
Messaggi: 1749
|
Quote:
![]() però c'è qualcosa che non capisco sulla quantità di memoria allocata, visto che sono float ![]() ma per evitare di dire stronzate, visto che son parecchio stanco, rimando a domani mattina ... in pratica la stronzata la dirò domani ![]()
__________________
Nintendo WIII 4d Turbo Intercooler - Sestium X 666 99,312 GHz - 6.984 Ram Σ(9999) MHz - HDD SATA 97e^(10) bytes 93³ rpm - ATI biberon X900z ∞Mb - Win Eight SP (1 > yours) 16 Valve |
|
![]() |
![]() |
![]() |
#18 |
Senior Member
Iscritto dal: Nov 2002
Messaggi: 6029
|
Infatti è strano quel 40.. Riguardo le righe contigue invece torna:l'indirizzo iniziale della prima riga è 0x601060, della seconda è indirizzo iniziale: 0x601090 . La differenza è di 30 in esadecimadecimale, ovvero 48 byte. Se fossero contigue,ovrebbe essere, 4 bytes*8 =32 bytes . I 16 Bytes in più sono dati dai 4 zeri( 4 double) che inserisce lui tra una riga e l'altra
Ultima modifica di Unrue : 03-01-2007 alle 21:54. |
![]() |
![]() |
![]() |
#19 | |
Senior Member
Iscritto dal: May 2006
Città: Wursteland
Messaggi: 1749
|
Quote:
Forse quei 4 in piú li aggiunge in automatico per i programmatori piú distratti che hanno il vizio di sforare gli array ![]() PS: da me i double sono 8 bytes quindi penso tu intendessi 4 floats ![]()
__________________
Nintendo WIII 4d Turbo Intercooler - Sestium X 666 99,312 GHz - 6.984 Ram Σ(9999) MHz - HDD SATA 97e^(10) bytes 93³ rpm - ATI biberon X900z ∞Mb - Win Eight SP (1 > yours) 16 Valve |
|
![]() |
![]() |
![]() |
#20 |
Senior Member
Iscritto dal: Nov 2002
Messaggi: 6029
|
Si si volevo dire floats, era tardi anche per me
![]() Ultima modifica di Unrue : 04-01-2007 alle 13:06. |
![]() |
![]() |
![]() |
Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 20:34.