int test(){ int ret = 0; write_cstr(1, ">>> test >>>\n"); struct arr *a = arr_alloc(4); arr_insert(a, 0, "this", 4); ret |= test_print_eq(a, "this", "arr 0"); arr_insert(a, a->c, " is", 3); test_print_eq(a, "this is", "arr 0.1"); arr_insert(a, 0, "hi ", 3); test_print_eq(a, "hi this is", "arr 0.2"); arr_insert(a, 0, "this is a big string being added. ", strlen("this is a big string being added. ")); test_print_eq(a, "this is a big string being added. hi this is", "arr 1"); struct arr *b = arr_alloc(4); arr_insert(b, 0, "starting:", strlen("starting:")); test_print_eq(b, "starting:", "arr 2"); arr_append_int_str(b, 3); test_print_eq(b, "starting:3", "arr 3"); arr_append_int_str(b, 40012); ret |= test_print_eq(b, "starting:340012", "arr 4"); struct arr *c = arr_alloc(4); arr_append(c, "h"); arr_append(c, "i"); test_print_eq(c, "hi", "arr 5"); write(1, "\n", 1); return ret; }
/* ** This function will prepare the global _omegas_ structure for ** encoding / decoding observations. It should be called as soon as ** the rest of the structure is initialized. It will create a key ** to be used in the coding process, and will intialize the _num_ciphers_ ** field as the number of ints in the coded observation array. */ void cipher_omegas(sdglobal_type* sd_global) { /* ** Need one key for every random variable, so you know where and ** how each one has been encoded in the cipher array. */ sd_global->omegas.key = arr_alloc(sd_global->omegas.num_omega, one_key); /* Temporary array to use when encoding / decoding omega indices */ sd_global->omegas.indices = arr_alloc(sd_global->omegas.num_omega, sd_small); /* Now form a key based on the range of each random variable in omegas */ sd_global->omegas.num_cipher = form_key(sd_global->omegas.key, sd_global->omegas.num_vals, sd_global->omegas.num_omega); }
int * matrix_multiblication(int* A, int* B, int A_r, int A_c, int B_r, int B_c){ int *C; int C_r= A_r, C_c= B_c; //allocat C arr_alloc(&C,C_r,C_c); //multiblaication operation int i=0; for (i = 0; i < C_r; ++i) { int j=0; for (j = 0; j < C_c; ++j) { int k=0,sum=0; for (k = 0; k < A_c; ++k) { int A_cell =A[ i * A_c + k ], B_cell =B[ k * B_r + j ]; sum+=( A_cell * B_cell ); } //store result C[i*C_c+j]=sum; } } //printMatrix(C,C_r,C_c); return C; }
void arr_alloc_file_input(FILE *file,int** arr_addres, int r,int c){ //allocation arr_alloc(arr_addres,r,c); //input arr_file_input(file,*arr_addres,r,c); }
void arr_alloc_input(int** arr_addres, int r,int c){ //allocation arr_alloc(arr_addres,r,c); //input arr_input(*arr_addres,r,c); }
int test_uarr(){ int ret = 0; write_cstr(1, ">>> test_uarr >>>\n"); int l; /* test insert & append */ struct arr *msg = arr_alloc(16); struct uarr *p = uarr_alloc(4, sizeof(int)); int iarr[] = {1,2,3,4}; uarr_insert(p, uarr_count(p), &iarr[0], 1); uarr_insert(p, uarr_count(p), &iarr[1], 1); uarr_append(p, &iarr[2]); uarr_append(p, &iarr[3]); int *ip = (int *)p->v; l = uarr_count(p); while(l--){ arr_append_int_str(msg, *ip); arr_insert(msg, msg->c, ",", 1); ip++; } ret |= test_print_eq(msg, "1,2,3,4,", "uarr 1"); arr_free(msg); uarr_free(p); write(1, "\n", 1); /* test append */ struct arr *msg2 = arr_alloc(16); struct uarr *p2 = uarr_alloc(4, sizeof(int)); int iarr2[] = {1,2,3,4}; uarr_append(p2, &iarr2[0]); uarr_append(p2, &iarr2[1]); uarr_append(p2, &iarr2[2]); uarr_append(p2, &iarr2[3]); int *ip2 = (int *)p2->v; l = uarr_count(p2); while(l--){ arr_append_int_str(msg2, *ip2); arr_insert(msg2, msg2->c, ",", 1); ip2++; } ret |= test_print_eq(msg2, "1,2,3,4,", "uarr 2"); arr_free(msg2); uarr_free(p2); write(1, "\n", 1); ret |= test_uarr_ptr(); return ret; }
int test_print_eq(struct arr *a, char *s, char *title){ struct arr *msg = arr_alloc(4); int r; if((r = str_eq(a->v, s, a->c)) == 0){ arr_insert(msg, msg->c, ".", 1); write(1, msg->v, msg->c); return 0; }else{ /* arr_append_cstr(msg, "fail - "); arr_append_cstr(msg, title); arr_append_cstr(msg, ":"); arr_append_int_str(msg, r); arr_append_cstr(msg, ":"); */ write(1, msg->v, msg->c); write(1, a->v, a->c); return 123; } }
int test_uarr_ptr(){ int ret = 0, l, ip; struct arr *msg = arr_alloc(16); struct uarr *p = uarr_alloc(2, sizeof(char *)); char *carr[] = {"hi","there","alpha","beta"}; uarr_append(p, &carr[0]); uarr_append(p, &carr[1]); uarr_append(p, &carr[2]); uarr_append(p, &carr[3]); char **cp = (char **)p->v; l = uarr_count(p); while(l--){ arr_insert(msg, msg->c, *cp, strlen(*cp)); arr_insert(msg, msg->c, ",", 1); cp++; } ret |= test_print_eq(msg, "hi,there,alpha,beta,", "uarr ptr 1"); arr_free(msg); uarr_free(p); write(1, "\n", 1); return ret; }
void arr_alloc_intit(int** arr_addres, int r, int c, int init){ //allocation arr_alloc(arr_addres,r,c); //initialize arr_init(*arr_addres,r,c,init); }
int main(int argc, char *argv[]) { int my_rank; int size ; int tag; int source; int dest ; MPI_Status status; MPI_Init(&argc,&argv); MPI_Comm_size(MPI_COMM_WORLD, &size); MPI_Comm_rank(MPI_COMM_WORLD , &my_rank); if (size<3) { printf("Need at least Three MPI tasks. Quitting...\n"); MPI_Abort(MPI_COMM_WORLD, 0); exit(1); } int input = 0 ; int A_r = 0, A_c = 0, B_r = 0, B_c = 0; int *A,*B,*C; if(my_rank==0){ printf("Welcome to vector Matrix multiplication program!\n"); printf("if you want program input matrices from file Enter 1\n"); printf("if you want program input matrices from console Enter 2\n"); scanf("%d",&input); if (input==1){ // read form file printf("Reading From File\n"); char path[100]; /**getting File name*/ printf("Give a File Name: "); // Max length of 99 characters; puts a null terminated string in path, thus 99 chars + null is the max scanf("%99s", path); printf("This is your path: %s\n", path); FILE *file= fopen(path,"r+"); //readFromFile if(file!=NULL){ fscanf(file,"%d%d",&A_r,&A_c); fscanf(file,"%d%d",&B_r,&B_c); if(A_c==B_r){ arr_alloc_file_input(file,&A,A_r,A_c); arr_alloc_file_input(file,&B,B_r,B_c); //printf("Multiblication\n"); //printf("Result\n"); //printMatrix(C,A_r,B_c); }else{ printf("A_c!=B_r"); } fclose(file); }else{ printf("unable to open file"); } }else if (input==2){ // read form console printf("Please enter the first matrix dimensions elements: "); printf("A_row?");scanf("%d",&A_r); printf("A_col?");scanf("%d",&A_c); do { printf("Please enter the second matrix dimensions elements: "); printf("B_row?");scanf("%d",&B_r); printf("B_col?");scanf("%d",&B_c); } while (A_c!=B_r); printf("Reading From Consol\n"); printf("Please enter the first matrix elements:"); arr_alloc_input(&A,A_r,A_c); printf("Please enter the first matrix elements:"); arr_alloc_input(&B,B_r,B_c); } printf("------ A ---------\n"); printMatrix(A , A_r ,A_c); printf("------ B ---------\n"); printMatrix(B , B_r ,B_c); /*this not valid result*/C = matrix_multiblication(A,B,A_r,A_c,B_r,B_c); } /* Bcast dimentions*/ MPI_Bcast (&A_c, 1, MPI_INT, 0, MPI_COMM_WORLD); MPI_Bcast (&A_r, 1, MPI_INT, 0, MPI_COMM_WORLD); MPI_Bcast (&B_c, 1, MPI_INT, 0, MPI_COMM_WORLD); MPI_Bcast (&B_r, 1, MPI_INT, 0, MPI_COMM_WORLD); // allocations if (my_rank!=0) { arr_alloc(&A,A_r,A_c); arr_alloc(&B,B_r,B_c); arr_alloc(&C,A_r,B_c); } /* Bcast B and Scatter A*/ MPI_Bcast (B, B_r*B_c, MPI_INT, 0, MPI_COMM_WORLD); /* Scater A rows * 1. calculate # of rows for each process then send with scatter * 2. collect with all gather * 3. calculate remaing rows then send with send and recive * 4. collect with recive * * **/ int nRow = A_r / size ; int remaing = A_r % size ; // scattring int *subA,*subC; arr_alloc(&subA,nRow,A_c); arr_alloc(&subC,nRow,B_c); //MPI_Scatter (A, SIZE, MPI_INT, small A, small A size, MPI_INT, 0, MPI_COMM_WORLD); MPI_Scatter(A,nRow*A_c,MPI_INT,subA,nRow*A_c,MPI_INT,0,MPI_COMM_WORLD); // printf("------ subA ->%d -------\n",my_rank); // printMatrix(subA , nRow ,A_c); // do sub multiplicaion int r = 0 ; for( r ; r <nRow;++r){ int c2 = 0 ; for (c2 = 0; c2< B_c; ++c2) { int c1= 0 , sum=0;; for ( c1 = 0; c1 < A_c; ++c1 ) { sum = sum + (subA[r*A_c+c1]*B[c1*B_c+c2]) ; /** * accessing B as 2d * fist column : 2nd colmn * 0 + 0c : 1 + 0c * 0 + 1c : 1 + 1c * 0 + 2c : 1 + 2c * 0 + 3c : 1 + 3c */ // printf("[%d] * [%d ] sum+= %d\n",subA[r*A_c+c1],B[c1*B_c+c2] , sum); } // printf("p%d:%d\n",my_rank,sum ); subC [r*A_c+c2] =sum ; } } //MPI_Gather (C[from], SIZE*SIZE/P, MPI_INT, C, SIZE*SIZE/P, MPI_INT, 0, MPI_COMM_WORLD); MPI_Gather(subC ,nRow*B_c ,MPI_INT , C , nRow*B_c, MPI_INT, 0, MPI_COMM_WORLD ); /* if (my_rank==0) { printf("------Gather C-------\n"); printMatrix( C, A_r,B_c); } */ // handle remaining rows =D /** * remaining rows < size * send for each process 1 row if process can get row else donot recive or send * **/ if (my_rank==0) // send remaing rows { int i = 1 ; for ( i ; i < size; ++i) { if ((i+(nRow*size))<=A_r) // send row to work with { //printf("$$$$$ sneding sub to p:%d\n", i); MPI_Send(&A[((i-1)+(nRow*size))*A_c], A_c, MPI_INT, i,0, MPI_COMM_WORLD); } } } int *subRow,*subRowResult; arr_alloc(&subRow,1,A_c+1); arr_alloc(&subRowResult,1,B_c); if (my_rank!=0 && (my_rank+(nRow*size))<=A_r) // i should have row to work with { // recive and do work then send result //printf("$$$$$ reciving sub from master to p:%d\n", my_rank); MPI_Recv(subRow, A_c, MPI_INT, 0, 0, MPI_COMM_WORLD, &status); //printf("$$$$$ recivied sub from master to ---- p:%d, %d , %d\n", subRow[0], subRow[1], subRow[2]); } // make one row multiblication if(my_rank!=0 && (my_rank+(nRow*size))<=A_r) // i send resilt tot master { int c2 = 0 ; for (c2 = 0; c2< B_c; ++c2) { int c1= 0 , sum=0;; for ( c1 = 0; c1 < A_c; ++c1 ) { sum = sum + (subRow[c1]*B[c1*B_c+c2]) ; /** * accessing B as 2d * fist column : 2nd colmn * 0 + 0c : 1 + 0c * 0 + 1c : 1 + 1c * 0 + 2c : 1 + 2c * 0 + 3c : 1 + 3c */ // printf("[%d] * [%d ] sum+= %d\n",subA[r*A_c+c1],B[c1*B_c+c2] , sum); } // printf("p%d:%d\n",my_rank,sum ); subRowResult [c2] =sum ; //printf("#> %d\n", sum); } // recive and do work then send result //printf("))))))))) sending to master %d\n",my_rank ); MPI_Send(subRowResult, B_c, MPI_INT, 0,0, MPI_COMM_WORLD); //printf("OOOOOOOO sent to master %d\n",my_rank ); //MPI_Recv(subRow, A_c, MPI_INT, 0, 0, MPI_COMM_WORLD, &status); } // // master reciving results if (my_rank==0) // send remaing rows { int i = 1 ; for ( i ; i < size; ++i) { if ((i+(nRow*size))<=A_r) // send row to work with { //MPI_Send(A[(i+(nRow*size))*A_c], A_c, MPI_INT, i,0, MPI_COMM_WORLD); //printf("))))))))) master reciving %d\n",i ); MPI_Recv(&C[((nRow*size)+i-1)*B_c], B_c, MPI_INT, i, 0, MPI_COMM_WORLD, &status); //MPI_Recv(subRowResult, B_c, MPI_INT, i, 0, MPI_COMM_WORLD, &status); //printf("UUUUUUUUUU master recived %d\n",i ); } } } if (my_rank==0) { printf("------ C-------\n"); printMatrix( C, A_r,B_c); //printMatrix(subRowResult ,1,B_c); } MPI_Finalize(); return 0; }
/** * if A[n*n],B[n*1],C[n*1] is Matrices and AC=B then C=A^-1*B * get input one Matrix of (A^-1*B) of size [n*(n+1)] * scatter the Matrix between process * collect B in each Process * GatherAll B in each Process * do Multiblication **/ int main(int argc, char *argv[]) { int my_rank; int size ; int tag; int source; int dest ; MPI_Status status; MPI_Init(&argc,&argv); MPI_Comm_size(MPI_COMM_WORLD, &size); MPI_Comm_rank(MPI_COMM_WORLD , &my_rank); int input = 0 ; int A_r = 0, A_c = 0, B_r = 0, B_c = 0; int *A,*B,*C; int N ; if(my_rank==0){ printf("Welcome to vector Matrix multiplication program! Allgather\n"); FILE *file= fopen("test.txt","r+"); //readFromFile if(file!=NULL){ fscanf(file,"%d",&N); A_r = N ;A_c = N ; B_r = N ;B_c = 1 ; // check dimnsions of matrix is divisable by # of process if (A_c%size != 0) { printf("# of MPI tasks Must Divisble by Matrix dimentions. Quitting...\n"); MPI_Abort(MPI_COMM_WORLD, 0); exit(1); } // check that A [n*n], B [n*1] if(A_c==B_r && A_c==A_r && B_c == 1){ arr_alloc_file_input(file,&A,N,(N+1)); arr_alloc(&C,A_r,B_c); }else{ printf("not Valid Matrix dimentions"); MPI_Abort(MPI_COMM_WORLD, 0); exit(1); } fclose(file); }else{printf("unable to open file");} printf("------ A ---------\n"); printMatrix(A , N ,N+1); //scanf("%d",&N); } /* Bcast dimentions*/ MPI_Bcast (&A_c, 1, MPI_INT, 0, MPI_COMM_WORLD); MPI_Bcast (&A_r, 1, MPI_INT, 0, MPI_COMM_WORLD); MPI_Bcast (&B_c, 1, MPI_INT, 0, MPI_COMM_WORLD); MPI_Bcast (&B_r, 1, MPI_INT, 0, MPI_COMM_WORLD); // allocations if (my_rank!=0){arr_alloc(&A,A_r,(A_r+1));} // all process allocate B to make GatherAll on it arr_alloc(&B,B_r,B_c); // n is dimention int n = A_r ; /** * Scatter A smallA and collect smallB from smallA * * smallA.size = nRows*n * nRows = n/size ; * * smallB.size = n/size ; **/ //allocate int *smallA , *smallB; int nRows = n/size ; int smallA_size = nRows*(n+1); int smallB_size = n/size ; arr_alloc(&smallA, smallA_size, 1); arr_alloc(&smallB, smallB_size, 1); //Scatter A MPI_Scatter(A,smallA_size,MPI_INT,smallA,smallA_size,MPI_INT,0,MPI_COMM_WORLD); // collect smallB in each process // index : smallB index in smallA int j , index=n ; for ( j = 0; j <= nRows; ++j) { smallB[j] = smallA[index]; index+= (n+1) ; } // printf("\n---------P%d-----smallA-------\n",my_rank); // printMatrix(smallA, 1, smallA_size); // printf("\n---------P%d-----smallB-------\n",my_rank); // printMatrix(smallB, 1, smallB_size); /** * make each process AllGather it smallB then all process have the B * prebare matrix B to AllGather the smallB * * prebare matrix smallC to store the result * smallC.size = smallB.size = n/size ; * **/ // allocation int *smallC ,smallC_size=n/size; arr_alloc(&smallC, smallC_size, 1); arr_init(smallC, smallC_size, 1, 0); MPI_Allgather( smallB , smallB_size,MPI_INT,B,smallB_size,MPI_INT,MPI_COMM_WORLD); if (my_rank==0) { printf("\n---------B after Allgather-------\n",my_rank); printMatrix(B, 1, n); } j = 0 ; for ( j ; j < nRows; ++j) // for each row in smallA { int sum = 0 ; int j2 = 0 ; for ( j2 = 0; j2 < n; ++j2) { sum+=(smallA[j2+(j*(n+1))] * B[j2]); /* smalA[j2+(j*(n+1))] j2 -> go in cloumn (j*(n+1)) -> go in row and skip merged B */ //printf("P%d: [%d - %d]\n",my_rank,smallA[j2+(j*(n+1))], B[j2] ); } smallC[j] = sum ; } // collect smallC MPI_Gather(smallC , smallC_size , MPI_INT , C , smallC_size , MPI_INT , 0 , MPI_COMM_WORLD); if (my_rank==0) { printf("------ Final C -------\n"); printMatrix( C, A_r,B_c); } MPI_Finalize(); return 0; }