|
|||||||
|
|
|
![]() |
|
|
Strumenti |
|
|
#1 |
|
Senior Member
Iscritto dal: Nov 2002
Messaggi: 6512
|
[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 18: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: 6512
|
Quote:
Ultima modifica di Unrue : 02-01-2007 alle 11: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: 6512
|
Quote:
Ultima modifica di Unrue : 02-01-2007 alle 12: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: 6512
|
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: 6512
|
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 14: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 14:31. |
|
|
|
|
|
|
#11 |
|
Senior Member
Iscritto dal: Nov 2002
Messaggi: 6512
|
Grazie infinite, gli darò un'occhiata. Nel frattempo seguo il tuo consiglio sulla matrice 4x16
|
|
|
|
|
|
#12 | |
|
Senior Member
Iscritto dal: Nov 2002
Messaggi: 6512
|
Quote:
Ultima modifica di Unrue : 02-01-2007 alle 15: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: 6512
|
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 22: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: 6512
|
Si si volevo dire floats, era tardi anche per me
Ultima modifica di Unrue : 04-01-2007 alle 14:06. |
|
|
|
|
| Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 18:56.





















