int main(void) { double ** matrixA, ** matrixB, ** matrixC, ticks; int size = 1600; matrixA = allocMatrix(size,size); randomMatrix(matrixA, size, size); matrixB = allocMatrix(size,size); randomMatrix(matrixB, size, size); matrixC = allocMatrix(size,size); printf("Two random matricies generated, now multiplying...\n\n"); ticks = clock(); multiplyMatrix(matrixA, matrixB, matrixC, size, size, size); printf("Multiplication of two square matricies of size %d took %g seconds\n",size,(clock() - ticks)/CLOCKS_PER_SEC); freeMatrix(matrixA); freeMatrix(matrixB); freeMatrix(matrixC); return 0; }
int main(int argc, char *argv[]) { unsigned n; int evt; double *A; int i, j; double checksum = 0; double startTime, endTime; long long counter; if (argc < 2) { return -1; } n = atoi(argv[1]); evt = (argc > 2) ? atoi(argv[2]) : -1; A = randomMatrix(n); assert(A != NULL); if (evt == -1) { startTime = dclock(); } else { papi_init(evt); papi_start(); } if (chol(A, n)) { fprintf(stderr, "Error: matrix is either not symmetric or not positive definite.\n"); } else { for (i = 0; i < n; i++) { for (j = i; j < n; j++) { checksum += A[IDX(i, j, n)]; } } printf("Checksum: %f \n", checksum); } if (evt == -1) { endTime = dclock(); fprintf(stderr, "%f\n", endTime - startTime); } else { counter = papi_stop(); fprintf(stderr, "%lld\n", counter); } free(A); return 0; }
int main(int argc, char *argv[]) { if(argc<3) { printf("Usage : %s <taille de la matrice> <filename>\n",argv[0]); exit(1); } srand(time(NULL)); int taille=atoi(argv[1]); Matrix A=newMatrix(taille,taille); A=randomMatrix(A); valeurPropre_gnuplot(A,argv[2]); deleteMatrix(A); return 0; }
static void check_matrix(generator_t &gen, distribution_t &dist) { // check identity { mtx44 m; mtx44Identity(&m); assert(m == glm::mat4()); } for(size_t x = 0; x < 10000; ++x) { // check multiply { mtx44 m1, m2; randomMatrix(m1, gen, dist); randomMatrix(m2, gen, dist); glm::mat4 g1 = loadMatrix(m1); glm::mat4 g2 = loadMatrix(m2); mtx44 result; mtx44Multiply(&result, &m1, &m2); assert(result == g1*g2); } // check translate { mtx44 m; randomMatrix(m, gen, dist); glm::mat4 g = loadMatrix(m); glm::vec3 v = randomVector(gen, dist); mtx44Translate(&m, v.x, v.y, v.z); assert(m == glm::translate(g, v)); } // check scale { mtx44 m; randomMatrix(m, gen, dist); glm::mat4 g = loadMatrix(m); glm::vec3 v = randomVector(gen, dist); mtx44Scale(&m, v.x, v.y, v.z); assert(m == glm::scale(g, v)); } // check rotate { mtx44 m; randomMatrix(m, gen, dist); float r = randomAngle(gen, dist); glm::mat4 g = loadMatrix(m); glm::vec3 v = randomVector(gen, dist); mtx44Rotate(&m, (vec3f){ v.x, v.y, v.z }, r); assert(m == glm::rotate(g, r, v)); } // check rotate X { mtx44 m; randomMatrix(m, gen, dist); float r = randomAngle(gen, dist); glm::mat4 g = loadMatrix(m); mtx44RotateX(&m, r); assert(m == glm::rotate(g, r, x_axis)); } // check rotate Y { mtx44 m; randomMatrix(m, gen, dist); float r = randomAngle(gen, dist); glm::mat4 g = loadMatrix(m); mtx44RotateY(&m, r); assert(m == glm::rotate(g, r, y_axis)); } // check rotate Z { mtx44 m; randomMatrix(m, gen, dist); float r = randomAngle(gen, dist); glm::mat4 g = loadMatrix(m); mtx44RotateZ(&m, r); assert(m == glm::rotate(g, r, z_axis)); } } }
void RandomReductionPlugin::randomReduction(std::ofstream &outStream) { std::cerr << "[INFO] Random reduction (iteration limit: " << m_iterationLimit << ") ... " << std::endl; std::set<IndexType> Trand; // random test set std::set<IndexType> TrandIter; // random test set std::vector<IndexType> randomizedTests; // stores the shuffled test case id-s std::vector<IndexType> randomizedIterTests; // print initial test suite outStream << "Number of procedures: " << m_nrOfCodeElements << std::endl; // initialize the remaining set for(unsigned int i = 0; i < m_nrOfTestCases; i++) { randomizedTests.push_back(i); } unsigned int fullSize = randomizedTests.size(); shuffle(randomizedTests); // make randomized order randomizedIterTests = randomizedTests; // print initial test suite outStream << "Total " << fullSize << " test cases in full test suite." << std::endl; Trand.clear(); TrandIter.clear(); CReductionData randomIterMatrix(m_data->getCoverage(), m_programName + "-RAND-ITER", m_dirPath); CReductionData randomMatrix(m_data->getCoverage(), m_programName + "-RAND", m_dirPath); unsigned int iter = 0; unsigned int numClasses = 1; while (iter < m_iterationLimit) { std::cerr << "[RANDOM] Iteration " << iter + 1 << " (number of classes: " << numClasses << ") " << std::endl; // fill the random matrix if (addRandom(randomizedIterTests, TrandIter, numClasses) != (int)numClasses) { // oops std::cerr << "[RANDOM] random test addition failed (adding 1 test)" << std::endl; numClasses *= 2; iter++; continue; } outStream << "Selected tests in the " << iter + 1 << "th iteration: " << std::endl; outStream << numClasses << " tests added" << std::endl; // create the random matrix randomIterMatrix.add(TrandIter); randomIterMatrix.save(iter + 1); numClasses *= 2; iter++; if (TrandIter.size() >= m_nrOfTestCases) { std::cerr << "[RANDOM] Full test suite size reached, exiting before iteration " << iter + 1 << " ..." << std::endl; break; } } for (int i = 0; i < (int)m_reductionSizes.size(); ++i) { int reductionSize = m_reductionSizes[i]; std::cerr << "[RANDOM] Fixed size " << i << " (number of classes: " << reductionSize << ") " << std::endl; // fill the random matrix if (addRandom(randomizedTests, Trand, reductionSize) != (int)reductionSize) {// oops std::cerr << "[RANDOM] random test addition failed (adding 1 test)" << std::endl; continue; } // create the random matrix randomMatrix.add(Trand); randomMatrix.save(i + 1); if (Trand.size() >= m_nrOfTestCases) { std::cerr << "[RANDOM] Full test suite size reached, exiting before iteration " << iter + 1 << " ..." << std::endl; break; } } unsigned int reducedSize = TrandIter.size(); outStream << "Random reduction ended" << std::endl; // print final test suite: outStream << "Fixed iteration reduction" << std::endl; outStream << "Total " << reducedSize << " test cases in reduced test suite." << std::endl; outStream << "Reduction rate: " << 100.0 * (fullSize - reducedSize) / fullSize << "\%" << std::endl; reducedSize = Trand.size(); outStream << "Fixed size reduction" << std::endl; outStream << "Total " << reducedSize << " test cases in reduced test suite." << std::endl; outStream << "Reduction rate: " << 100.0 * (fullSize - reducedSize) / fullSize << "\%" << std::endl; std::cerr << "done." << std::endl; }
int main(int argc, char * argv[]) { int rank_grid, rank_row, rank_col; int coordinates[2]; int node_total_size; int node_dim_size; int elem_dim_size; int subelem_dim_size; int * scatter_sendcount; int * scatter_displacement; int gridinit_num_dims = 2; int gridinit_dims[2] = {0,0}; int gridinit_periods[2] = {0,0}; int gridinit_reorder = 1; MPI_Comm mpi_comm_grid, mpi_comm_row, mpi_comm_col; MPI_Datatype mpi_type_submatrix, mpi_type_submatrix_vector; MPI_Request fox_send_request, fox_recv_request; int fox_sendto, fox_recfrom, fox_sendtag, fox_rectag; int fox_broadcaster; double *mat_a, *mat_b, *mat_c; double *A_mine, *B_old, *B_new, *C_mine, *A_bcast; double *mat_verify; int i, j, k; int verify = 0; int verbose = 0; MPI_Init(&argc, &argv); MPI_Comm_size(MPI_COMM_WORLD, &node_total_size); double starttime, endtime; starttime = MPI_Wtime(); // Set up cartesian coordinate grid MPI_Dims_create(node_total_size, gridinit_num_dims, gridinit_dims); MPI_Cart_create(MPI_COMM_WORLD, gridinit_num_dims, gridinit_dims, gridinit_periods, gridinit_reorder, &mpi_comm_grid); // ** Get the grid coordinates of this process. MPI_Comm_rank(mpi_comm_grid, &rank_grid); MPI_Cart_coords(mpi_comm_grid, rank_grid, gridinit_num_dims, coordinates); // ** Set up column communicators. MPI_Comm_split(mpi_comm_grid, coordinates[1], coordinates[0], &mpi_comm_col); MPI_Comm_rank(mpi_comm_col, &rank_col); // ** Set up row communicators MPI_Comm_split(mpi_comm_grid, coordinates[0], coordinates[1], &mpi_comm_row); MPI_Comm_rank(mpi_comm_row, &rank_row); // Get the number of processors per dimension in grid. MPI_Comm_size(mpi_comm_row, &node_dim_size); // ******************************************** // ** CHECK SANITY OF AND SET UP ENVIRONMENT ** // ******************************************** // Check that number of parameters is sane. if(argc < 2) { if(rank_grid == 0) printf("Usage: foxmatrix N\n N = randomize NxN matrices.\n"); MPI_Finalize(); return -1; } // Get the number of elements per dimension in matrices from arguments. elem_dim_size = atoi(argv[1]); // Check that number of processors is sane. if(sqrt(node_total_size) != (double) ((int) sqrt(node_total_size))) { if(rank_grid == 0) printf("Not a square number of processors.\n"); MPI_Finalize(); return -1; } // Check that it is possible to split matrix over the processors. if(elem_dim_size % node_dim_size != 0) { if(rank_grid == 0) printf("Cannot split elements evenly over processors.\n"); MPI_Finalize(); return -1; } // Calculate the size (in one dimension) of the submatrices. subelem_dim_size = elem_dim_size / node_dim_size; // Check if the user has given the verify/verbose commands. if(argc == 3 && strcmp(argv[2], "verify") == 0) verify = 1; else if(argc == 3 && strcmp(argv[2], "verbose") == 0) verbose = 1; else if(argc == 4 && strcmp(argv[2], "verbose") == 0 && strcmp(argv[3], "verify") == 0) { verbose = 1; verify = 1; } else if(argc == 4 && strcmp(argv[2], "verify") == 0 && strcmp(argv[3], "verbose") == 0) { verbose = 1; verify = 1; } // Create datatype used for transmitting submatrices. // Idea of using vector+struct taken from http://www.mcs.anl.gov/research/projects/mpi/tutorial/mpiexmpl/src4/scatter/C/solution.html. MPI_Type_vector(subelem_dim_size, subelem_dim_size, elem_dim_size, MPI_DOUBLE, &mpi_type_submatrix_vector); int sm_blocklength[2] = {1, 1}; MPI_Aint sm_displacement[2] = {0, subelem_dim_size * sizeof(double)}; MPI_Datatype sm_types[2] = {mpi_type_submatrix_vector, MPI_UB}; MPI_Type_struct(2, sm_blocklength, sm_displacement, sm_types, &mpi_type_submatrix); MPI_Type_commit(&mpi_type_submatrix); // ** CREATE MATRICES AND SET UP SCATTERV/GATHERV VARIABLES ** if(rank_grid == 0) { // Create matrices on rank 0. mat_a = (double *) malloc(elem_dim_size * elem_dim_size * sizeof(double)); mat_b = (double *) malloc(elem_dim_size * elem_dim_size * sizeof(double)); mat_c = (double *) malloc(elem_dim_size * elem_dim_size * sizeof(double)); // Randomize matrix contents. randomMatrixInit(); randomMatrix(mat_a, elem_dim_size); randomMatrix(mat_b, elem_dim_size); // Allocate memory for storing scattering information. scatter_sendcount = (int *) malloc(node_total_size * sizeof(int)); scatter_displacement = (int *) malloc(node_total_size * sizeof(int)); // Set up scatter/gather arguments. int sit; for(sit = 0; sit < node_total_size; sit++) { scatter_sendcount[sit] = 1; if(sit == 0) scatter_displacement[sit] = 0; else { scatter_displacement[sit] = scatter_displacement[sit - 1] + 1; if(sit % node_dim_size == 0) // At end of line, go to start of next submatrix. scatter_displacement[sit] += node_dim_size * (subelem_dim_size - 1); } } } A_mine = (double *) malloc(subelem_dim_size*subelem_dim_size*sizeof(double)); A_bcast = (double *) malloc(subelem_dim_size*subelem_dim_size*sizeof(double)); B_old = (double *) malloc(subelem_dim_size*subelem_dim_size*sizeof(double)); B_new = (double *) malloc(subelem_dim_size*subelem_dim_size*sizeof(double)); C_mine = (double *) malloc(subelem_dim_size*subelem_dim_size*sizeof(double)); zeroMatrix(C_mine, subelem_dim_size); // ** DISTRIBUTE THE SUBMATRICES TO THE GRID NODES ** MPI_Scatterv(mat_a, scatter_sendcount, scatter_displacement, mpi_type_submatrix, A_mine, subelem_dim_size * subelem_dim_size, MPI_DOUBLE, 0, mpi_comm_grid); MPI_Scatterv(mat_b, scatter_sendcount, scatter_displacement, mpi_type_submatrix, B_new, subelem_dim_size * subelem_dim_size, MPI_DOUBLE, 0, mpi_comm_grid); // ** PERFORM FOX'S ALGORITHM FOR MATRIX MULTIPLICATION ** for(k = 0; k < node_dim_size; k++) { // **** BROADCAST A **** // // Decide who broadcasts this iteration. fox_broadcaster = (k + rank_col) % node_dim_size; // Copy matrix to the broadcast variable of the node that shall broadcast. if(rank_row == fox_broadcaster) copyMatrix(A_bcast, A_mine, subelem_dim_size); // Perform the broadcasting of the A matrix. MPI_Bcast(A_bcast, subelem_dim_size * subelem_dim_size, MPI_DOUBLE, fox_broadcaster, mpi_comm_row); // **** CREATE COPY OF B **** // // Wait for everyone to get their new B. If k = 0 everyone has it scattered. if(k != 0) MPI_Wait(&fox_recv_request, MPI_STATUS_IGNORE); // Make a copy of B so we can overwrite the old one. copyMatrix(B_old, B_new, subelem_dim_size); // **** SHIFT B **** // // Find which node to send to, and which to recieve from (B matrix). fox_recfrom = ((rank_col + 1) % node_dim_size); fox_sendto = ((rank_col - 1) % node_dim_size); if(fox_sendto < 0) fox_sendto = node_dim_size - 1; fox_sendtag = 1000 + fox_sendto; fox_rectag = 1000 + rank_col; // Send the B matrix. MPI_Isend(B_old, subelem_dim_size * subelem_dim_size, MPI_DOUBLE, fox_sendto, fox_sendtag, mpi_comm_col, &fox_send_request); // Receive the B matrix. MPI_Irecv(B_new, subelem_dim_size * subelem_dim_size, MPI_DOUBLE, fox_recfrom, fox_rectag, mpi_comm_col, &fox_recv_request); // Perform matrix multiplication on the local submatrix. naiveMatrixMult(A_bcast, B_old, C_mine, subelem_dim_size); } // ** GATHER DATA ** MPI_Barrier(MPI_COMM_WORLD); // Collect C from submatrices. MPI_Gatherv(C_mine, subelem_dim_size * subelem_dim_size, MPI_DOUBLE, mat_c, scatter_sendcount, scatter_displacement, mpi_type_submatrix, 0, mpi_comm_grid); // ** PRESENT DATA ** if(verbose && !rank_grid) { printf("** Will print matrix C from 0:\n"); printMatrix(mat_c, elem_dim_size); } // ** VERIFICATION OF CORRECTNESS ** if(verify && !rank_grid) { // Allocate memory for verification matrix. mat_verify = (double *) malloc(elem_dim_size * elem_dim_size * sizeof(double)); // Initialize verification matrix to zeroes. zeroMatrix(mat_verify, elem_dim_size); // Do the naive multiplication. naiveMatrixMult(mat_a, mat_b, mat_verify, elem_dim_size); // Print the correct matrix. if(verbose) { printf("** Print correct matrix from 0:\n"); printMatrix(mat_verify, elem_dim_size); } // Check equality between matrices. if(matrixEqual(mat_c, mat_verify, elem_dim_size)) printf("\n Ok!\n\n"); else printf("\n FAIL!\n\n"); // Free the memory used by the verification matrix. free(mat_verify); } // ** FINALIZE MPI ** MPI_Barrier(MPI_COMM_WORLD); if(rank_grid==0) { endtime = MPI_Wtime(); printf("%f\n", endtime - starttime); } MPI_Finalize(); // ** CLEANUP ** if(A_mine) free(A_mine); if(A_bcast) free(A_bcast); if(B_old) free(B_old); if(B_new) free(B_new); if(C_mine) free(C_mine); // Local rank 0 cleanup. if(rank_grid == 0) { free(mat_a); free(mat_b); free(mat_c); } return 0; }
void SpeedTest(FunctionCall fc) { int i, min, max, step, sec=0; int sizeTimeArray, fct; char fnc[MAXSIZE_FCT]; char foutput[256]; struct sigaction action; action.sa_handler = handler; sigemptyset(&action.sa_mask); struct timeval start, end, result; double maxtime = 0; double time; double usec; double* timeArray; Matrix a=NULL, b=NULL, tmp=NULL; E s; int n; TokenizeSpeedTest(fc, fnc, &min, &max, &step, &sec); if (min>0 && max>0 && step>0) { sizeTimeArray = ((max-min)/step)+1; timeArray = (double*)malloc(sizeTimeArray*sizeof(double)); for (i=0; i<sizeTimeArray; i++) timeArray[i] = 0; } usec = (double)sec * 1000000; sprintf(foutput, "speedtest_%s_%d_%d_%d_%d", fnc, min, max, step, sec); fct = GetFunction(fnc); switch (fct) { case NMX : { printf("\t You must specify another function\n"); return; } case ADD : { sigaction(SIGINT, &action, NULL); for (i=min; i<=max; i+=step) { a = randomMatrix(i, i, MIN_E, MAX_E); b = randomMatrix(i, i, MIN_E, MAX_E); gettimeofday(&start, NULL); tmp = addMatricis(a, b); gettimeofday(&end, NULL); timersub(&end, &start, &result); time = (result.tv_sec*1000000)+result.tv_usec; if (maxtime < time) maxtime = time; timeArray[(i-min)/step] = time; printf("\t* %s Size:%5d ;\tTime:%8.0f µs ;\n", fnc, i, time); deleteMatrix(a); deleteMatrix(b); deleteMatrix(tmp); if (usec >= 1000000) { if (time >= usec) { i++; break; } } if (CTRLC) { i++; break; } } CreateGNUPLOTFile(min, i-step, step, timeArray, maxtime, foutput); break; } case SUB : { sigaction(SIGINT, &action, NULL); for (i=min; i<=max; i+=step) { a = randomMatrix(i, i, MIN_E, MAX_E); b = randomMatrix(i, i, MIN_E, MAX_E); gettimeofday(&start, NULL); tmp = substractMatricis(a, b); gettimeofday(&end, NULL); timersub(&end, &start, &result); time = (result.tv_sec*1000000)+result.tv_usec; if (maxtime < time) maxtime = time; timeArray[(i-min)/step] = time; printf("\t* %s Size:%5d ;\tTime:%8.0f µs ;\n", fnc, i, time); deleteMatrix(a); deleteMatrix(b); deleteMatrix(tmp); if (usec >= 1000000) { if (time >= usec) { i++; break; } } if (CTRLC) { i++; break; } } CreateGNUPLOTFile(min, i-step, step, timeArray, maxtime, foutput); break; } case MUL : { sigaction(SIGINT, &action, NULL); for (i=min; i<=max; i+=step) { a = randomMatrix(i, i, MIN_E, MAX_E); b = randomMatrix(i, i, MIN_E, MAX_E); gettimeofday(&start, NULL); tmp = mulMatricis(a, b); gettimeofday(&end, NULL); timersub(&end, &start, &result); time = (result.tv_sec*1000000)+result.tv_usec; if (maxtime < time) maxtime = time; timeArray[(i-min)/step] = time; printf("\t* %s Size:%5d ;\tTime:%8.0f µs ;\n", fnc, i, time); deleteMatrix(a); deleteMatrix(b); deleteMatrix(tmp); if (usec >= 1000000) { if (time >= usec) { i++; break; } } if (CTRLC) { i++; break; } } CreateGNUPLOTFile(min, i-step, step, timeArray, maxtime, foutput); break; } case MSC : { sigaction(SIGINT, &action, NULL); for (i=min; i<=max; i+=step) { a = randomMatrix(i, i, MIN_E, MAX_E); s = mRand(MIN_SCA, MAX_SCA); gettimeofday(&start, NULL); tmp = mult_scal(a, s); gettimeofday(&end, NULL); timersub(&end, &start, &result); time = (result.tv_sec*1000000)+result.tv_usec; if (maxtime < time) maxtime = time; timeArray[(i-min)/step] = time; printf("\t* %s Size:%5d ;\tTime:%8.0f µs ;\n", fnc, i, time); deleteMatrix(a); deleteMatrix(tmp); if (usec >= 1000000) { if (time >= usec) { i++; break; } } if (CTRLC) { i++; break; } } CreateGNUPLOTFile(min, i-step, step, timeArray, maxtime, foutput); break; } case EXP : { sigaction(SIGINT, &action, NULL); for (i=min; i<=max; i+=step) { a = randomMatrix(i, i, MIN_E, MAX_E); n = (int)mRand(MIN_EXP, MAX_EXP); gettimeofday(&start, NULL); tmp = expo(a, n); gettimeofday(&end, NULL); timersub(&end, &start, &result); time = (result.tv_sec*1000000)+result.tv_usec; if (maxtime < time) maxtime = time; timeArray[(i-min)/step] = time; printf("\t* %s Size:%5d ;\tTime:%8.0f µs ;\n", fnc, i, time); deleteMatrix(a); deleteMatrix(tmp); if (usec >= 1000000) { if (time >= usec) { i++; break; } } if (CTRLC) { i++; break; } } CreateGNUPLOTFile(min, i-step, step, timeArray, maxtime, foutput); break; } case TRA : { sigaction(SIGINT, &action, NULL); for (i=min; i<=max; i+=step) { a = randomMatrix(i, i, MIN_E, MAX_E); gettimeofday(&start, NULL); tmp = transposeMatrix(a); gettimeofday(&end, NULL); timersub(&end, &start, &result); time = (result.tv_sec*1000000)+result.tv_usec; if (maxtime < time) maxtime = time; timeArray[(i-min)/step] = time; printf("\t* %s Size:%5d ;\tTime:%8.0f µs ;\n", fnc, i, time); deleteMatrix(a); deleteMatrix(tmp); if (usec >= 1000000) { if (time >= usec) { i++; break; } } if (CTRLC) { i++; break; } } CreateGNUPLOTFile(min, i-step, step, timeArray, maxtime, foutput); break; } case DET : { sigaction(SIGINT, &action, NULL); for (i=min; i<=max; i+=step) { a = randomMatrix(i, i, MIN_E, MAX_E); gettimeofday(&start, NULL); s = determinant(a); gettimeofday(&end, NULL); timersub(&end, &start, &result); time = (result.tv_sec*1000000)+result.tv_usec; if (maxtime < time) maxtime = time; timeArray[(i-min)/step] = time; printf("\t* %s Size:%5d ;\tTime:%8.0f µs ;\n", fnc, i, time); deleteMatrix(a); if (usec >= 1000000) { if (time >= usec) { i++; break; } } if (CTRLC) { i++; break; } } CreateGNUPLOTFile(min, i-step, step, timeArray, maxtime, foutput); break; } case DLU : { sigaction(SIGINT, &action, NULL); for (i=min; i<=max; i+=step) { a = randomMatrix(i, i, MIN_E, MAX_E); b = newMatrix(i, i); tmp = identityMatrix(i); gettimeofday(&start, NULL); decomposition(a, b, tmp); gettimeofday(&end, NULL); timersub(&end, &start, &result); time = (result.tv_sec*1000000)+result.tv_usec; if (maxtime < time) maxtime = time; timeArray[(i-min)/step] = time; printf("\t* %s Size:%5d ;\tTime:%8.0f µs ;\n", fnc, i, time); deleteMatrix(a); deleteMatrix(b); deleteMatrix(tmp); if (usec >= 1000000) { if (time >= usec) { i++; break; } } if (CTRLC) { i++; break; } } CreateGNUPLOTFile(min, i-step, step, timeArray, maxtime, foutput); break; } case SOL : { sigaction(SIGINT, &action, NULL); for (i=min; i<=max; i+=step) { a = randomMatrix(i, i, MIN_E, MAX_E); b = randomMatrix(i, 1, MIN_E, MAX_E); gettimeofday(&start, NULL); tmp = gauss(a, b); gettimeofday(&end, NULL); timersub(&end, &start, &result); time = (result.tv_sec*1000000)+result.tv_usec; if (maxtime < time) maxtime = time; timeArray[(i-min)/step] = time; printf("\t* %s Size:%5d ;\tTime:%8.0f µs ;\n", fnc, i, time); deleteMatrix(a); deleteMatrix(b); deleteMatrix(tmp); if (usec >= 1000000) { if (time >= usec) { i++; break; } } if (CTRLC) { i++; break; } } CreateGNUPLOTFile(min, i-step, step, timeArray, maxtime, foutput); break; } case INV : { sigaction(SIGINT, &action, NULL); for (i=min; i<=max; i+=step) { a = randomMatrix(i, i, MIN_E, MAX_E); gettimeofday(&start, NULL); tmp = invert(a); gettimeofday(&end, NULL); timersub(&end, &start, &result); time = (result.tv_sec*1000000)+result.tv_usec; if (maxtime < time) maxtime = time; timeArray[(i-min)/step] = time; printf("\t* %s Size:%5d ;\tTime:%8.0f µs ;\n", fnc, i, time); deleteMatrix(a); deleteMatrix(tmp); if (usec >= 1000000) { if (time >= usec) { i++; break; } } if (CTRLC) { i++; break; } } CreateGNUPLOTFile(min, i-step, step, timeArray, maxtime, foutput); break; } case RNK : { sigaction(SIGINT, &action, NULL); for (i=min; i<=max; i+=step) { a = randomMatrix(i, i, MIN_E, MAX_E); gettimeofday(&start, NULL); n = rank(a); gettimeofday(&end, NULL); timersub(&end, &start, &result); time = (result.tv_sec*1000000)+result.tv_usec; if (maxtime < time) maxtime = time; timeArray[(i-min)/step] = time; printf("\t* %s Size:%5d ;\tTime:%8.0f µs ;\n", fnc, i, time); deleteMatrix(a); if (usec >= 1000000) { if (time >= usec) { i++; break; } } if (CTRLC) { i++; break; } } CreateGNUPLOTFile(min, i-step, step, timeArray, maxtime, foutput); break; } case VAR : // default case NOF : // default default : { printf("\t%s : Function Not Implemented\n", fnc); fni++; break; } } if (fct!=NOF && fct !=VAR) fni = 0; free(timeArray); CTRLC = 0; sigemptyset(&action.sa_mask); }
int main(int argc, char *argv[]) { int numtasks, rank, dest, source, rc, count, tag=1; MPI_Status Stat; // Seed random number generator. randomMatrixInit(); MPI_Init(&argc,&argv); MPI_Comm_size(MPI_COMM_WORLD, &numtasks); MPI_Comm_rank(MPI_COMM_WORLD, &rank); double *A; double *B; if(argc==1) { printf("Specify matrix size\n"); return 1; } int size=atoi(argv[1]); A = (double*)malloc(sizeof(double)*size*size); B = (double*)malloc(sizeof(double)*size*size); randomMatrix(A,size); randomMatrix(B,size); // int Atest[]={1,2,3,4,5,6,7,8,9}; // int Btest[]={3,2,1,6,5,4,4,3,2}; // A=Atest; // B=Btest; if(numtasks>size*size) numtasks=size*size; int minCells=size*size/(numtasks); int extra=size*size-minCells*(numtasks); int pad=0; if (rank == 0) { dest = 1; source = 1; double *C; C = (double*)malloc(sizeof(double)*size*size); double *ret = (double*)malloc(sizeof(double)*size*size/(numtasks)+1); for(int cell=0; cell<minCells; cell++) { C[cell]=0; for(int j=0; j<size; j++) C[cell]+=A[(cell/size)*size+j]*B[j*size+cell%size]; // printf("Calculating job %d. C[%d]=%d\n", rank, cell, C[cell]); } for(int i=1; i<numtasks; i++) { int noCells=minCells; if(i>=numtasks-extra) { pad=i-numtasks+extra; noCells++; } rc = MPI_Recv(ret, noCells, MPI_DOUBLE, i, tag, MPI_COMM_WORLD, &Stat); for(int j=0; j<noCells; j++) { int cell = minCells*i+pad+j; // if(cell>size*size-1) // printf(" KUK!\n"); C[cell]=ret[j]; // printf("C[%d]=ret[%d]=%d\n",cell, j, ret[j]); } } // printMatrix(A, size); // printf("*\n"); // printMatrix(B, size); // printf("=\n"); // printMatrix(C, size); // printf("\nControl:\n"); double *D; if(argc==3 && strcmp(argv[2],"verify") == 0) { D = (double*)malloc(sizeof(double)*size*size); naiveMatrixMult(A,B,D,size); // printMatrix(D, size); if(matrixEqual(C,D,size)) printf("\n Ok!\n\n"); else printf("\n FAIL!\n\n"); free(D); } free(A); free(B); free(C); } else if (rank+1 <= size*size) { int noCells=minCells; if(rank>=numtasks-extra) { pad=rank-numtasks+extra; noCells++; } // printf("noCells: %d extra: %d rank: %d\n", noCells, extra, rank); double *ret = (double*)calloc(noCells,sizeof(double)); for(int i=0; i<noCells; i++) { ret[i] = 0; int cell=minCells*(rank)+pad+i; for(int j=0; j<size; j++) ret[i]+=A[(cell/size)*size+j]*B[j*size+cell%size]; // printf("Calculating job %d. C[%d]=%d\n", rank, cell, ret[i]); } rc = MPI_Send(ret, noCells, MPI_DOUBLE, 0, tag, MPI_COMM_WORLD); } else { } MPI_Finalize(); return 0; }