Initial commit.
This commit is contained in:
Executable
+26
@@ -0,0 +1,26 @@
|
||||
########################################################################
|
||||
# Target
|
||||
########################################################################
|
||||
|
||||
PROGRAM_ppu64 = ../../matmult
|
||||
|
||||
|
||||
########################################################################
|
||||
# Local Defines
|
||||
########################################################################
|
||||
|
||||
INCLUDE = -I../../../../include/ppu
|
||||
LDFLAGS = -L../../../../lib/ppu
|
||||
IMPORTS = -lmoc_ppu -lspe2 ../spu/matmult_spu.a
|
||||
|
||||
|
||||
########################################################################
|
||||
# buildutils/make.footer
|
||||
########################################################################
|
||||
|
||||
ifdef CELL_TOP
|
||||
include $(CELL_TOP)/buildutils/make.footer
|
||||
else
|
||||
include /opt/cell/sdk/buildutils/make.footer
|
||||
endif
|
||||
|
||||
Executable
+263
@@ -0,0 +1,263 @@
|
||||
#include <moc.h>
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <sys/time.h>
|
||||
|
||||
extern spe_program_handle_t matmult_spu;
|
||||
|
||||
#define MASTER 0
|
||||
|
||||
void initMatrix(double** M, int x, int y, double value)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
for (i = 0; i < x; i++)
|
||||
{
|
||||
for (j = 0; j < y; j++)
|
||||
M[i][j] = value;
|
||||
}
|
||||
}
|
||||
|
||||
void initMatrixInc(double** M, int x, int y, double value, int offset)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
for (i = 0; i < x; i++)
|
||||
{
|
||||
for (j = 0; j < y; j++)
|
||||
M[i][j] = (i+1) * value +( double)offset;
|
||||
}
|
||||
}
|
||||
|
||||
int getChunkSize(int processes, int rank, int lines)
|
||||
{
|
||||
int result = lines/processes;
|
||||
|
||||
if (lines%processes > rank)
|
||||
result++;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
int getOffset(int processes, int rank, int lines)
|
||||
{
|
||||
int result = 0;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < rank; i++)
|
||||
result += getChunkSize(processes, i, lines);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
double vecMult(double* vec1, double* vec2, int size)
|
||||
{
|
||||
double result = 0.0;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < size; i++)
|
||||
result += vec1[i] * vec2[i];
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void printMatrix(double** M, int from_line, int to_line, int elements, int rank)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
for (i = from_line; i <= to_line; i++)
|
||||
{
|
||||
printf("RANK[%d] line %d", rank, i);
|
||||
|
||||
for (j = 0; j < elements; j++)
|
||||
{
|
||||
printf("%6.1f ", M[i][j]);
|
||||
//printf("[(%d, %d) %f] ", i, j, M[i][j]);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
struct timeval t;
|
||||
struct timezone z;
|
||||
|
||||
double sec = 0.0;
|
||||
|
||||
gettimeofday(&t, &z);
|
||||
sec =( double)t.tv_usec/1e6 + t.tv_sec;
|
||||
|
||||
int n, m, p; //dimensions (m x n) * (n x p) = (m x p)
|
||||
int i, j, k; //indeces
|
||||
|
||||
int offset;
|
||||
|
||||
double** A; // matrices
|
||||
double** B;
|
||||
double** C;
|
||||
|
||||
int countNode,chunklastnode;
|
||||
int testFlag;
|
||||
int np, myrank, chunksize, mspu, aspu;
|
||||
MOC_Status status;
|
||||
int sendchunksize;
|
||||
double startTime, computeTime, tmpTime, communicationTime;
|
||||
|
||||
communicationTime = 0.0;
|
||||
computeTime = 0.0;
|
||||
chunklastnode=0;
|
||||
|
||||
if (MOC_Get_max_spu_count(&mspu))
|
||||
{
|
||||
printf("An error occured during MOC_Get_max_spu_count\n");
|
||||
return 0;
|
||||
}
|
||||
if (MOC_Get_avail_spu_count(&aspu))
|
||||
{
|
||||
printf("An error occured during MOC_Get_avail_spu_count\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
printf("\nThere are %i of %i SPUs available.\n\n", aspu, mspu);
|
||||
|
||||
MOC_Add_spu_thread ( &matmult_spu, NULL );
|
||||
MOC_Add_spu_thread ( &matmult_spu, NULL );
|
||||
MOC_Add_spu_thread ( &matmult_spu, NULL );
|
||||
MOC_Add_spu_thread ( &matmult_spu, NULL );
|
||||
MOC_Add_spu_thread ( &matmult_spu, NULL );
|
||||
MOC_Add_spu_thread ( &matmult_spu, NULL );
|
||||
|
||||
MOC_Set_buffer_size ( 500000 );
|
||||
|
||||
MOC_Init(NULL, NULL);
|
||||
startTime = MOC_Wtime();
|
||||
|
||||
MOC_Comm_size(MOC_COMM_WORLD, &np); /*get #(processors)*/
|
||||
MOC_Comm_rank(MOC_COMM_WORLD, &myrank);/*find rank of this process*/
|
||||
|
||||
m=n=p=150;
|
||||
|
||||
// B allocation each column is a vector!!!!
|
||||
B = (double**)malloc( p * sizeof(double*) );
|
||||
|
||||
for(i = 0; i < p; i++ )
|
||||
{
|
||||
B[i] = (double*)malloc( n * sizeof(double) );
|
||||
}
|
||||
|
||||
initMatrix(B, p, n, 0.0);
|
||||
|
||||
chunksize = getChunkSize(np, myrank, m);
|
||||
|
||||
if( myrank == MASTER )///////////////////-- MASTER --////////////////////////
|
||||
|
||||
{
|
||||
|
||||
initMatrix(B, p, n, 1.0);
|
||||
printf("RANK[%d]: Adresse von b ist %d\n",myrank,B);
|
||||
|
||||
for(countNode = 1; countNode < 7;countNode++)
|
||||
{
|
||||
|
||||
for(i = 0; i < p;i++) //broadcast B to SLAVES
|
||||
|
||||
{
|
||||
tmpTime = MOC_Wtime();
|
||||
|
||||
testFlag = MOC_Send(B[i], n, MOC_DOUBLE, countNode, MASTER, MOC_COMM_WORLD);
|
||||
if(testFlag != 0)
|
||||
i--;
|
||||
|
||||
communicationTime += MOC_Wtime() - tmpTime;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
A = (double**)malloc( m * sizeof(double*) );
|
||||
C = (double**)malloc( m * sizeof(double*) );
|
||||
|
||||
for(i = 0; i < m; i++)
|
||||
{
|
||||
A[i] = (double*)malloc( n * sizeof(double));
|
||||
C[i] = (double*)malloc( p * sizeof(double));
|
||||
}
|
||||
|
||||
initMatrixInc(A, m, n, 1.0, 0); //init A with some values
|
||||
initMatrix(C, m, p, 0.0); // init C with 0.0
|
||||
|
||||
for(i = 1; i < np; i++) // distribute A to SLAVES
|
||||
|
||||
{
|
||||
offset = getOffset(np, i, m);
|
||||
sendchunksize = getChunkSize(np, i, m);
|
||||
|
||||
for(k = 0; k < sendchunksize;k++)
|
||||
{
|
||||
tmpTime = MOC_Wtime();
|
||||
|
||||
testFlag = MOC_Send(A[k + offset], n,MOC_DOUBLE,i,i,MOC_COMM_WORLD);
|
||||
|
||||
if(testFlag != 0)
|
||||
k--;
|
||||
communicationTime += MOC_Wtime() - tmpTime;
|
||||
}
|
||||
}
|
||||
|
||||
computeTime = MOC_Wtime();
|
||||
|
||||
for(i = 0; i < chunksize; i++) //compute
|
||||
|
||||
{
|
||||
for(j = 0; j < p; j++)
|
||||
C[i][j] = vecMult(A[i], B[j], n);
|
||||
}
|
||||
|
||||
computeTime = MOC_Wtime() - computeTime;
|
||||
|
||||
for(i = 1; i < np; i++) //gather C chunks from SLAVES
|
||||
|
||||
{
|
||||
offset = getOffset(np, i, m);
|
||||
sendchunksize = getChunkSize(np, i, m);
|
||||
|
||||
for(k = 0; k < sendchunksize;k++)
|
||||
{
|
||||
tmpTime = MOC_Wtime();
|
||||
|
||||
MOC_Recv(C[k + offset], p, MOC_DOUBLE, i, i,MOC_COMM_WORLD,&status);
|
||||
|
||||
communicationTime += MOC_Wtime() - tmpTime;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
for(i = 0; i < m; i++)
|
||||
free(A[i]);
|
||||
free(A);
|
||||
|
||||
for(i = 0; i < m; i++)
|
||||
free(C[i]);
|
||||
free(C);
|
||||
|
||||
}
|
||||
|
||||
for(i = 0; i < p; i++)
|
||||
free(B[i]);
|
||||
|
||||
free(B);
|
||||
|
||||
printf("RANK[%d] Communication Time: %f\n", myrank, communicationTime);
|
||||
printf("RANK[%d] Computation Time: %f\n", myrank, computeTime);
|
||||
|
||||
MOC_Finalize();
|
||||
|
||||
gettimeofday(&t, &z);
|
||||
sec = (double)t.tv_usec/1e6 + t.tv_sec - sec;
|
||||
|
||||
printf("RANK[%d] Complete time = %f\n",myrank, sec);
|
||||
|
||||
return 0;
|
||||
}
|
||||
Executable
+29
@@ -0,0 +1,29 @@
|
||||
########################################################################
|
||||
# Target
|
||||
########################################################################
|
||||
|
||||
PROGRAMS_spu := matmult_spu
|
||||
LIBRARY_embed64 := matmult_spu.a
|
||||
|
||||
|
||||
########################################################################
|
||||
# Local Defines
|
||||
########################################################################
|
||||
|
||||
INCLUDE += -I../../../../include/spu
|
||||
LDFLAGS += -L../../../../lib/spu
|
||||
IMPORTS += -lmoc_spu
|
||||
|
||||
# Only necessary if the SPU-Decrementer is used as Time-Source for the SPUs
|
||||
#LDFLAGS += -L/opt/cell/sysroot/opt/cell/sdk/prototype/usr/spu/lib
|
||||
#IMPORTS += -lsputimer
|
||||
|
||||
########################################################################
|
||||
# buildutils/make.footer
|
||||
########################################################################
|
||||
|
||||
ifdef CELL_TOP
|
||||
include $(CELL_TOP)/buildutils/make.footer
|
||||
else
|
||||
include /opt/cell/sdk/buildutils/make.footer
|
||||
endif
|
||||
Executable
+209
@@ -0,0 +1,209 @@
|
||||
#include <moc.h>
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <sys/time.h>
|
||||
|
||||
#define MASTER 0
|
||||
|
||||
void initMatrix(double** M, int x, int y, double value)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
for (i = 0; i < x; i++)
|
||||
{
|
||||
for (j = 0; j < y; j++)
|
||||
M[i][j] = value;
|
||||
}
|
||||
}
|
||||
|
||||
void initMatrixInc(double** M, int x, int y, double value, int offset)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
for (i = 0; i < x; i++)
|
||||
{
|
||||
for (j = 0; j < y; j++)
|
||||
M[i][j] = (i+1) * value +( double)offset;
|
||||
}
|
||||
}
|
||||
|
||||
int getChunkSize(int processes, int rank, int lines)
|
||||
{
|
||||
int result = lines/processes;
|
||||
|
||||
if (lines%processes > rank)
|
||||
result++;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
int getOffset(int processes, int rank, int lines)
|
||||
{
|
||||
int result = 0;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < rank; i++)
|
||||
result += getChunkSize(processes, i, lines);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
double vecMult(double* vec1, double* vec2, int size)
|
||||
{
|
||||
double result = 0.0;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < size; i++)
|
||||
result += vec1[i] * vec2[i];
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
struct timeval t;
|
||||
struct timezone z;
|
||||
|
||||
double sec = 0.0;
|
||||
|
||||
gettimeofday(&t, &z);
|
||||
sec =( double)t.tv_usec/1e6 + t.tv_sec;
|
||||
|
||||
int testFlag;
|
||||
|
||||
int n, m, p; //dimensions (m x n) * (n x p) = (m x p)
|
||||
int i, j, k; //indeces
|
||||
|
||||
int offset;
|
||||
|
||||
double** A; // matrices
|
||||
double** B;
|
||||
double** C;
|
||||
|
||||
int np, myrank, chunksize;
|
||||
MOC_Status status;
|
||||
|
||||
double startTime, computeTime, tmpTime, communicationTime;
|
||||
|
||||
communicationTime = 0.0;
|
||||
computeTime = 0.0;
|
||||
|
||||
MOC_Init( 0, 0, NULL);
|
||||
|
||||
startTime = MOC_Wtime();
|
||||
|
||||
MOC_Comm_size(MOC_COMM_WORLD, &np); /*get #(processors)*/
|
||||
MOC_Comm_rank(MOC_COMM_WORLD, &myrank);/*find rank of this process*/
|
||||
|
||||
m = n = p = 150;
|
||||
|
||||
// B allocation, each column is a vector!!!!
|
||||
B = (double**)malloc( p * sizeof(double*) );
|
||||
|
||||
for(i = 0; i < p; i++ )
|
||||
{
|
||||
B[i] = (double*)malloc( n * sizeof(double) );
|
||||
}
|
||||
|
||||
initMatrix(B, p, n, 0.0);
|
||||
|
||||
chunksize = getChunkSize(np, myrank, m);
|
||||
printf("RANK[%d] chunksize: %d\n", myrank, chunksize);
|
||||
|
||||
if(myrank > 0)
|
||||
{
|
||||
|
||||
tmpTime = MOC_Wtime();
|
||||
|
||||
communicationTime += MOC_Wtime() - tmpTime;
|
||||
|
||||
for(i = 0; i < p;i++) //get Matrix B from MASTER
|
||||
|
||||
{
|
||||
tmpTime = MOC_Wtime();
|
||||
MOC_Recv(B[i], n ,MOC_DOUBLE,MASTER,MASTER,MOC_COMM_WORLD,&status);
|
||||
communicationTime += MOC_Wtime() - tmpTime;
|
||||
}
|
||||
|
||||
printf("RANK[%d] has Matrix B\n", myrank);
|
||||
|
||||
A = (double**)malloc(chunksize * sizeof(double)); //a chunk of A
|
||||
for(i = 0; i < chunksize; i++)
|
||||
A[i] = (double*)malloc(n * sizeof(double));
|
||||
|
||||
C = (double**)malloc(chunksize * sizeof(double)); //a chunk of A
|
||||
for(i = 0; i < chunksize; i++)
|
||||
C[i] = (double*)malloc(p * sizeof(double));
|
||||
|
||||
offset = getOffset(np, myrank, m);
|
||||
|
||||
initMatrix(A, chunksize, n, 0.0);
|
||||
initMatrix(C, chunksize, p, 0.0);
|
||||
|
||||
printf("RANK[%d] empfange daten\n",myrank);
|
||||
|
||||
for(k=0; k < chunksize; k++) // Recv chunk of A
|
||||
|
||||
{
|
||||
tmpTime = MOC_Wtime();
|
||||
|
||||
MOC_Recv(A[k],n ,MOC_DOUBLE,MASTER,myrank,MOC_COMM_WORLD,&status);
|
||||
|
||||
communicationTime += MOC_Wtime() - tmpTime;
|
||||
}
|
||||
|
||||
computeTime = MOC_Wtime();
|
||||
printf("RANK[%d] bearbeite daten\n",myrank);
|
||||
for(i = 0; i < chunksize; i++) // compute
|
||||
|
||||
{
|
||||
for(j = 0; j < p; j++)
|
||||
{
|
||||
C[i][j] = vecMult(A[i], B[j], n);
|
||||
}
|
||||
}
|
||||
|
||||
computeTime = MOC_Wtime() - computeTime;
|
||||
|
||||
printf("RANK[%d] sende daten\n",myrank);
|
||||
for(k = 0; k < chunksize;k++)
|
||||
{
|
||||
tmpTime = MOC_Wtime();
|
||||
|
||||
testFlag = MOC_Send(C[k], p, MOC_DOUBLE, MASTER, myrank, MOC_COMM_WORLD);
|
||||
if(testFlag != 0)
|
||||
{
|
||||
k--;
|
||||
}
|
||||
communicationTime += MOC_Wtime() - tmpTime;
|
||||
}
|
||||
|
||||
for(i = 0; i < chunksize; i++)
|
||||
free(A[i]);
|
||||
free(A);
|
||||
|
||||
for(i = 0; i < chunksize; i++)
|
||||
free(C[i]);
|
||||
free(C);
|
||||
|
||||
}
|
||||
|
||||
for(i = 0; i < chunksize; i++)
|
||||
free(B[i]);
|
||||
|
||||
free(B);
|
||||
|
||||
printf("RANK[%d] Communication Time: %f\n", myrank, communicationTime);
|
||||
printf("RANK[%d] Computation Time: %f\n", myrank, computeTime);
|
||||
|
||||
MOC_Finalize();
|
||||
|
||||
gettimeofday(&t, &z);
|
||||
sec = (double)t.tv_usec/1e6 + t.tv_sec - sec;
|
||||
|
||||
printf("RANK[%d] Complete time = %f\n",myrank, sec);
|
||||
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user