#include #include #include #include "Ttiming.h" #include #include using namespace std; void array_alloc(long **&arr, long arrsize) { try { arr = new long* [arrsize]; arr[0] = new long [arrsize*arrsize]; for(long i = 1; i < arrsize; ++i) arr[i] = arr[i-1] + arrsize; } catch (bad_alloc& ex) { cerr << "Could not allocate memory for array" << endl; exit(1); } } void vect_alloc(long *&arr, long arrsize) { try { arr = new long [arrsize]; } catch (bad_alloc& ex) { cerr << "Could not allocate memory for vector" << endl; exit(1); } } void array_destroy(long **arr) { delete [] arr[0]; delete [] arr; } int main(int argc, char *argv[]) { long **A=NULL, **B=NULL, **C=NULL, *B_rot=NULL, *vect=NULL, *vect_c=NULL, *C_rot=NULL; long rozmiar=0, porcja_new=0; char *endptr; TTiming tt; long i; MPI::Status status; if (argc < 2) { cerr << "Usage: " << argv[0] << " " << endl; exit(1); } rozmiar = strtol(argv[1], &endptr, 10); if (*endptr) { cerr << "Invalid array size format" << endl; exit(1); } if (rozmiar <= 0 || rozmiar > 2000) { cerr << "The number of matrix dimension must be in range [1,2000]" << endl; exit(1); } MPI::Init(argc, argv); int taskid = MPI::COMM_WORLD.Get_rank(); int ntasks = MPI::COMM_WORLD.Get_size(); //alokacja macierzy array_alloc(A, rozmiar); if (taskid == 0) { array_alloc(B, rozmiar); vect_alloc(B_rot, rozmiar*rozmiar); vect_alloc(C_rot, rozmiar*rozmiar); } // porcja - ile wektorów dostaje jeden proces do liczenia // jeżeli liczba procesów większa od wektorów - każdy proces dostaje po jednym, niektóre wcale long porcja = (rozmiar>=ntasks) ? (long)round(rozmiar*1.0/ntasks) : 1; porcja *= rozmiar; //porcję mnożymy przez ilość elementów w jednym wektorze porcja_new = porcja; array_alloc(C, rozmiar); vect_alloc(vect, porcja); vect_alloc(vect_c, porcja); if (taskid == 0) { // wypełnienie macierzy A liczbami "losowymi" for (long i=0; i=ntasks) ? 0 : ntasks-rozmiar); // // część licząca --------------------------------------------------------------------------------- // MPI::COMM_WORLD.Barrier(); if (taskid == 0) tt.Begin(); if (taskid == ntasks -1) //przelicz porcję dla ostatniego procesu (w przypadku dzielenia z resztą) { porcja_new = (rozmiar - (porcja/rozmiar)*(ntasks-1))*rozmiar; // myk jest taki, że muszę podać jakąś niezerową porcję do gathera, // mimo, że proces nie ma żadnych (sensownych) danych do przetworzenia if (porcja_new > 0) porcja = porcja_new; } for (i=0; i