//sucin int sucin (p_TMatrix ptm1, p_TMatrix ptm2) { int code, i = 0, j = 0, k = 0; if (ptm1->m != ptm2->n) return RET_INP; TMatrix tmp; tmp.n = ptm1->n; tmp.m = ptm2->m; if ((code = allocMat (&tmp)) != RET_OK) return code; zeroMat (&tmp); for (i = 0; i < tmp.n; i++) for (j = 0; j < tmp.m; j++) for (k = 0; k < ptm1->m; k++) tmp.add[i][j] += (ptm1->add[i][k] * ptm2->add[k][j]); vypisMat (&tmp); freeMat (&tmp); return RET_OK; }
//krizova rotacia int crot (p_TMatrix ptm1) { int code, i = 0, j = 0; int l; TMatrix tmp1; tmp1.n = ptm1->n; tmp1.m = ptm1->m; //pomocna matica 1 if ((code = allocMat (&tmp1)) != RET_OK) return code; zeroMat (&tmp1); //spravnim indexovanim naplnime pomocnu maticu posunutymi riadkami for (i = 0; i < tmp1.n; i++) { l = ptm1->add[i][0]; l = l % (ptm1->m); for (j = 0; j < ptm1->m; j++) tmp1.add[i][j] = ptm1->add[i][(j - l + ptm1->m) % (ptm1->m)]; } //podobne posunieme stlpce TMatrix tmp2; tmp2.n = ptm1->n; tmp2.m = ptm1->m; if ((code = allocMat (&tmp2)) != RET_OK) return code; zeroMat (&tmp2); for (i = 0; i < tmp1.m; i++) { l = tmp1.add[0][i]; l = l % (ptm1->n); for (j = 0; j < ptm1->n; j++) tmp2.add[j][i] = tmp1.add[(j - l + ptm1->n) % (ptm1->n)][i]; } vypisMat (&tmp2); freeMat (&tmp1); freeMat (&tmp2); return RET_OK; }
void slave(int rank, int size) { int numProcs, count, start, stop; int testRuns = 10; //How long calculation will take double wallTime = 0.0; //Dynamic allocation of arrays int* matA = allocMat(size); int* matB = allocMat(size); int* matC = allocMat(size); MPI_Comm_size(MPI_COMM_WORLD, &numProcs); //Rum this test 10 times // for (int i = 0; i < testRuns; i++) //{ //Broadcast matrix A MPI_Barrier(MPI_COMM_WORLD); MPI_Bcast(matA, size * size, MPI_INT, 0, MPI_COMM_WORLD); //Broadcast matrix B MPI_Barrier(MPI_COMM_WORLD); MPI_Bcast(matB, size * size, MPI_INT, 0, MPI_COMM_WORLD); //Calculate which part of matrix A is to be used start = rank * (size / numProcs); stop = (rank + 1) * (size / numProcs); count = size * (size / numProcs); //Calculate part of matrix C subMatrixCal(matA, matB, matC, size, start, stop); //Send part of matrix C back to Master MPI_Gather(matC, count, MPI_INT, matC, count, MPI_INT, 0, MPI_COMM_WORLD); //Send the calculation time MPI_Send(&wallTime, 1, MPI_DOUBLE, 0, 0, MPI_COMM_WORLD); // } deleteMat(matA, size); deleteMat(matB, size); deleteMat(matC, size); }
int setOrder(matrix *mat) { char param[BUFSIZE + 1]; int order; if (!getNextParam(param)) return 0; /* Parameter auslesen */ if ((order = atol(param)) < 1) return 0; freeMat(mat); mat = allocMat(order, order); /* Neue Matrix mit eingegebenen Rang erstellen */ return 1; }
//sucet matic int sucet (p_TMatrix ptm1, p_TMatrix ptm2) { int code, i = 0, j = 0; if (ptm1->n != ptm2->n || ptm1->m != ptm2->m) return RET_INP; TMatrix tmp; tmp.n = ptm1->n; tmp.m = ptm1->m; if ((code = allocMat (&tmp)) != RET_OK) return code; for (i = 0; i < ptm1->n; i++) for (j = 0; j < ptm1->m; j++) tmp.add[i][j] = ptm1->add[i][j] + ptm2->add[i][j]; vypisMat (&tmp); freeMat (&tmp); return RET_OK; }
void master(int size) { //Number of process, number of rows, start and stop rows, remainding row int numProcs, count, start, stop, remainder; //Averages double avgTotal = 0.0, avgCT = 0.0, seqTime = 0.0; //How long calculation will take double wallTime = 0.0; //The status of our receiver MPI_Status status; int testRuns = 10; struct timeval startTT, startCT; //Allocation of matrix int* matA = allocMat(size); int* matB = allocMat(size); int* matC = allocMat(size); MPI_Comm_size(MPI_COMM_WORLD, &numProcs); //This test 10 times // for (int i = 0; i < testRuns; i++) // { double totalTime = 0.0, calcTime = 0.0, remTime = 0.0; initMatrix(matA, matB, size); //Start total time gettimeofday(&startTT, NULL); //Broadcast matrix A MPI_Barrier(MPI_COMM_WORLD); MPI_Bcast(matA, size * size, MPI_INT, 0, MPI_COMM_WORLD); //Broadcast matrix B MPI_Barrier(MPI_COMM_WORLD); MPI_Bcast(matB, size * size, MPI_INT, 0, MPI_COMM_WORLD); start = 0; // rows/thread stop = size / numProcs; //area/thread count = size * (size / numProcs); //Start calculation timer gettimeofday(&startCT, NULL); subMatrixCal(matA, matB, matC, size, start, stop); //Stop calculation timer calcTime = getElapsed(&startCT); MPI_Gather(matC, count, MPI_INT, matC, count, MPI_INT, 0, MPI_COMM_WORLD); //Wall time = the slowest computation time for (int idx = 1; idx < numProcs; idx++) { MPI_Recv(&wallTime, 1, MPI_DOUBLE, idx, 0, MPI_COMM_WORLD, &status); if (wallTime > calcTime) { calcTime = wallTime; } } remainder = size % numProcs; if (remainder > 0) { //Start remainder timer gettimeofday(&startCT, NULL); remMatrixCal(matA, matB, matC, size, remainder); //Stop remainder timer remTime = getElapsed(&startCT); } //Add remainder time and calculation time calcTime += remTime; //Stop total time totalTime = getElapsed(&startTT); //Running total for average total and cal time avgTotal += totalTime; avgCT += calcTime; // } //Average total and cal time avgTotal /= testRuns; avgCT /= testRuns; //Start sequential timer gettimeofday(&startCT, NULL); calMatrix(matA, matB, size); //Stop sequential timer seqTime = getElapsed(&startCT); //Find speed up and efficiency double speedUp = seqTime / avgCT; double efficiency = speedUp / numProcs; //Print stats printf("Size: %d x %d\n", size, size); printf("Speed up: %f\n", speedUp); printf("Efficiency: %f\n", efficiency); printf("Average Total Time: %f s\n", avgTotal); printf("Average Sequential time: %f s\n", seqTime); printf("Average Parallel time: %f s\n", avgCT); printf("Average Communication time: %f s\n\n", avgTotal - avgCT); deleteMat(matA, size); deleteMat(matB, size); deleteMat(matC, size); }
int readandallocMat (FILE * fp, p_TMatrix ptm) { int i, j; int code; int c; int already = 0; //nacitame rozmery if ((fscanf (fp, "%d %d", &i, &j)) != 2) return RET_INP; //ak sa za nimy nachadza nieco ine ako novy riadok vrat chybu while ((c = fgetc (fp)) != '\n') if (c != ' ' && c != '\t') return RET_INP; //chybne rozmery if (i <= 0 || j <= 0) { return RET_INP; } ptm->n = i; ptm->m = j; //alokuj maticu if ((code = allocMat (ptm)) != RET_OK) return code; //nacitaj hodnoty do pola for (i = 0; i < ptm->n; i++) { for (j = 0; j < ptm->m; j++) { if (((code = fscanf (fp, "%d", &(ptm->add[i][j]))) == EOF) || (code != 1)) return RET_FILE; } //kontrola konca riadku matice if ((c = fgetc (fp)) != '\n') { if (c == EOF && i == ptm->n - 1) return RET_OK; fscanf (fp, "%*[^\n]"); if (already != 1) { fprintf (stderr, "Varovanie: Vstupna matica obsahuje viac hodnot nez kolko je uvedene v rozsahu\n"); already = 1; } } } return RET_OK; }
int plough (p_TMatrix ptm1) { int code = 0, i = 0, j = 0, k = 0, l = 0; TMatrix tmp; tmp.n = ptm1->n; tmp.m = ptm1->m; //Alokacia pomocnej matice if ((code = allocMat (&tmp)) != RET_OK) return code; zeroMat (&tmp); code = start; /* v zdrojovej matici sa pohybujeme premennymi k,l v kazdej iteracii zistujeme ci nedoslo k zmene podmienky daneho stavu ak ano prepneme na novy smer */ for (i = 0; i < ptm1->n; i++) for (j = 0; j < ptm1->m; j++) if (!((k == ptm1->n - 1) && (l == ptm1->m - 1))) { switch (code) { case start: tmp.add[i][j] = ptm1->add[k][l]; code = right; break; case right: l++; tmp.add[i][j] = ptm1->add[k][l]; if (k == 0) code = down_left; if (k == ptm1->n - 1) code = up_right; break; case down_left: k++; l--; tmp.add[i][j] = ptm1->add[k][l]; if ((k == ptm1->n - 1)) code = right; else if ((l == 0) && (k != ptm1->n - 1)) code = down; else code = down_left; break; case down: k++; tmp.add[i][j] = ptm1->add[k][l]; if (l == 0) code = up_right; if (l == ptm1->m - 1) code = down_left; break; case up_right: k--; l++; tmp.add[i][j] = ptm1->add[k][l]; if ((l == ptm1->m - 1)) code = down; else if ((k == 0) && (k != ptm1->m - 1)) code = right; else code = up_right; break; } } vypisMat (&tmp); freeMat (&tmp); return RET_OK; }
int main(int argc, char** argv){ struct timeval start,finish; double t; double **a,**b,**c; int i,j,k,N; N = 1000; a = allocMat(1000,1000); b = allocMat(1000,1000); c = allocMat(1000,1000); for (i = 0; i < N; i++) { for (j = 0; j < N; j++) { a[i][j] = rand() % 100; b[i][j] = rand() % 100; c[i][j] = 0; } } /*------------------------ CAZ DE BAZA ------------------------*/ gettimeofday(&start,0); for (i = 0; i < N; i++){ for (j = 0; j < N; j++){ c[i][j] = 0.0; for (k = 0; k < N; k++){ c[i][j] += a[i][k] * b[k][j]; } } } gettimeofday(&finish,0); t = (finish.tv_sec - start.tv_sec) + (double)(finish.tv_usec - start.tv_usec) / 1000000.0; printf("Timp CAZ DE BAZA = %lf\n", t); /*------------------------ CAZ DE BAZA ------------------------*/ for (i = 0; i < N; i++) for (j = 0; j < N; j++) c[i][j]=0; /*------------------------ CAZ 3 b ------------------------*/ gettimeofday(&start,0); int z = 4; for (i=0;i<N/z;i++){ for (j=0;j<N/z;j++){ for (k=0;k<N/z;k++){ c[i][j] += a[i][k]*b[k][j]; } } } gettimeofday(&finish,0); t = (finish.tv_sec - start.tv_sec) + (double)(finish.tv_usec - start.tv_usec) / 1000000.0; printf("Timp CAZ 3 b = %lf\n", t); /*------------------------ CAZ 3 b ------------------------*/ return 0; }