char *test_bad_demensions_2() { struct MATRIX *mA = matrix_create_scalar(4, 8, 4); struct MATRIX *mB = matrix_create_scalar(4, 4, 4); struct MATRIX *mC = matrix_create_scalar(4, 8, 0); float **C_p = matrix_multiply(mA->A, mB->A, mC->A, 4, 4, 8, 4); mu_assert(C_p == NULL, "C_p should be NULL"); matrix_destroy(mA); matrix_destroy(mB); matrix_destroy(mC); return NULL; }
int main(void) { /* clear terminal screen */ system("/usr/bin/clear"); /* initialize system state from user input */ init_state(); /* notify user of status and wait for "O.K." to run the system */ while (getchar() != '\n'); printf("System initialized. To \"run\" the system, press ENTER."); getchar(); /* main program loop */ while (1) { /* clear screen */ system("/usr/bin/clear"); /* allocate resources and display */ allocate_random(); display_allocation(); putchar('\n'); display_need(); putchar('\n'); display_available(); putchar('\n'); /* display result of "safe()" */ if (safe()) printf("System state: SAFE!\n"); else printf("System state: UNSAFE!\n"); /* prompt user to continue or quit */ putchar('\n'); printf("Press Ctrl-C to quit. To \"run\" again, press ENTER."); getchar(); /* if continue, restore the system */ restore(); } /* free dynamically allocated memory, unnecessary here unless user interface is altered to allow the code to reach this point */ vector_destroy(AVAILABLE); matrix_destroy(MAX, NUMBER_OF_PROCESSES); matrix_destroy(ALLOCATION, NUMBER_OF_PROCESSES); matrix_destroy(NEED, NUMBER_OF_PROCESSES); return 0; }
int main(int argc, char** argv) { cc_config_t config; dataset_t* data; clique_list_t* cl; matrix_t* matrix; group_list_t* groups; #ifdef WITH_LIMITS struct rlimit cpu_limit = { 900, 900 }; struct rlimit mem_limit = { 419430400, 419430400}; setrlimit(RLIMIT_CPU, &cpu_limit ); setrlimit(RLIMIT_AS, &mem_limit ); #endif configure(&config, argc, argv); data = dataset_load(config.datfile); cl = clique_list_load(config.clfile); printf("Generate matrix...\n"); matrix = matrix_create(data, cl, sizeof(int), NULL, boolean_connection); /* matrix_print_int(matrix); */ printf("Generate group list...\n"); groups = group_list_from_clique_list(cl); /* group_list_print(groups); */ printf("Merging groups...\n"); group_list_merge(groups, boolean_strength, NULL, matrix); group_list_save(groups, config.grpfile); group_list_destroy(groups); matrix_destroy(matrix); clique_list_destroy(cl); dataset_destroy(&data); return 0; }
static void ref_desc_destroy(ref_desc_t *desc) { if (desc == NULL) return; if (desc->hash != REF_HASH) return; matrix_destroy(&desc->matr); free(desc); }
double lik(POPROT *pop) {/* Function to compute the inverse of the Fisher information matrix of the population protocol pop. Returns the determinant of the matrix, also stored in pop->det. The Fisher information matrix of the population protocol is stored in pop->fisher and the inverse is stored in pop->finv */ int ndim = pop->ndim; int ncase = (int)(ndim*(ndim+1)/2); int i,j,jj,ifail; int *indx; double *col; matrix *xa; double cri; /* POPROT_print(pop,1); PROTOC_print(&prot[7]); */ indx = (int *)calloc(ndim,sizeof(int)); col = (double *)calloc(ndim,sizeof(double)); xa = matrix_create(ndim,ndim); for(i = 0;i<ncase;i++) { pop->fisher[i] = 0; for(j = 0;j<pop->np;j++) { pop->fisher[i] = pop->fisher[i]+pop->freq[j]*pop->pind[j].fisher[i]; } } jj = 0; for(i = 0;i<ndim;i++) { for(j = 0;j<=i;j++) { xa->m[i][j] = pop->fisher[jj]; xa->m[j][i] = pop->fisher[jj]; jj++; } } ifail = ludcmp(xa->m,ndim,indx,&cri); if(ifail==1) return CRI_MAX; for(i = 0;i<ndim;i++) cri = cri*xa->m[i][i]; pop->det = cri; for(i = 0;i<ndim;i++) { for(j = 0;j<ndim;j++) col[j] = 0.0; col[i] = 1.0; lubksb(xa->m,ndim,indx,col); for(j = 0;j<ndim;j++) { jj = i*(i+1)/2+j; pop->finv[jj] = col[j]; /*=xb[j][i] using another matrix*/ } } /* desallocation */ matrix_destroy(xa); free(indx); return cri; }
int main(int argc, char **argv) { int n = (argc > 1) ? atoi(argv[1]) : 100; const char* matr_fname = (argc > 2) ? argv[2] : "l2_default.csr"; const char* pict_fname = (argc > 3) ? argv[3] : NULL; real h = 1. / n; int size = (n - 1) * (n - 1); int nonz = 4 * size; int err; TMatrix_DCSR _m; TMatrix_DCSR *m = &_m; err = matrix_create(m, size, nonz, 1); if (err) PRINT_ERROR_MESSAGE_AND_EXIT(err); for (int i = 1; i <= size; ++i) m->row_ptr[i] = 4 * i; for (int i = 1; i <= n; ++i) { for (int j = 1; j <= n; ++j) { int todo[4] = { ij2k(n, i - 1, j - 1), // bl ij2k(n, i - 1, j - 0), // br ij2k(n, i - 0, j - 1), // tl ij2k(n, i - 0, j - 0), // tr }; for (int ci = 0; ci < 4; ++ci) { int k = todo[ci]; if (k < 0) continue; real coeff = get_coeff(j*h - h/2, i*h - h/2); m->diag[k] += 1 * coeff; for (int cj = 0; cj < 4; ++cj) { int off = loc_off(ci, cj); if (off < 0) continue; m->col_ind[m->row_ptr[k] + off] = todo[cj]; m->val [m->row_ptr[k] + off] -= 0.5 * coeff; } } } } TMatrix_DCSR _l2; TMatrix_DCSR *l2 = &_l2; matrix_copy_fix(m, l2); matrix_destroy(m); if (pict_fname) matrix_portrait(l2, pict_fname, 5., 0, NULL); if (strstr(matr_fname, ".mtx") != NULL) matrix_save_fmc(l2, matr_fname); else matrix_save(l2, matr_fname); return 0; }
char *test_good_demensions_1() { struct MATRIX *mA = matrix_create_scalar(2, 3, 3); struct MATRIX *mB = matrix_create_scalar(2, 3, 3); struct MATRIX *mC = matrix_create_scalar(2, 3, 0); float **C_p = matrix_multiply(mA->A, mB->A, mC->A, 2, 3, 2, 3); mu_assert(C_p != NULL, "C_p should not be NULL"); mu_assert(C_p[0][0] == 18.0, "C_p[0][0] should be 18.0"); mu_assert(C_p[0][1] == 18.0, "C_p[0][1] should be 18.0"); mu_assert(C_p[1][0] == 18.0, "C_p[1][0] should be 18.0"); mu_assert(C_p[1][1] == 18.0, "C_p[1][1] should be 18.0"); matrix_destroy(mA); matrix_destroy(mB); matrix_destroy(mC); return NULL; }
int matrix_gram_schmidt_process(matrix_t *q, matrix_t *p) { int n; matrix_t *tmp; assert(q); assert(p); assert(matrix_get_columns(q) >= matrix_get_columns(p)); assert(matrix_get_rows(q) >= matrix_get_rows(p)); tmp = matrix_new_and_copy(p); n = matrix_self_gram_schmidt_process(tmp, 0, 0, matrix_get_columns(tmp), matrix_get_rows(tmp)); matrix_copy_matrix(q, 0, 0, tmp, 0, 0, n, matrix_get_rows(tmp)); matrix_destroy(tmp); return n; }
matrix_t *matrix_new_and_gram_schmidt_process(matrix_t *p) { int n; matrix_t *tmp, *q; assert(p); tmp = matrix_new_and_copy(p); n = matrix_self_gram_schmidt_process(tmp, 0, 0, matrix_get_columns(tmp), matrix_get_rows(tmp)); if (n == matrix_get_columns(tmp)) return tmp; q = matrix_new(n, matrix_get_rows(tmp), false); matrix_copy_matrix(q, 0, 0, tmp, 0, 0, n, matrix_get_rows(tmp)); matrix_destroy(tmp); return q; }
int main(int argc, char **argv) { const int m = 10000, n = 10000; double tbeg, tend; tbeg = WTime(); struct vector *x = vector_create(n); struct vector *y = vector_create(m); struct vector *y_ref = vector_create(m); struct matrix *A = matrix_create(m, n); // setup values in our test vector and in our reference result setup_test_vectors(x, y_ref); // build a test matrix setup_test_matrix(A); tend = WTime(); printf("setup took %g sec\n", tend - tbeg); // calculate y = Ax tbeg = WTime(); matrix_vector_multiply(y, A, x); tend = WTime(); printf("matrix_vector_multiply() took %g sec\n", tend - tbeg); // the resulting vector for this test should equal our reference result tbeg = WTime(); assert(vector_is_equal(y, y_ref)); tend = WTime(); printf("checking result took %g sec\n", tend - tbeg); // clean up vector_destroy(x); vector_destroy(y); vector_destroy(y_ref); matrix_destroy(A); return 0; }
matrix_t *cmatrix_new_and_gram_schmidt_process(matrix_t *p) { int n; matrix_t *q, *tmp; assert(p); assert(matrix_is_imaginary(p)); tmp = matrix_new_and_copy(p); n = cmatrix_self_gram_schmidt_process(tmp, 0, 0, matrix_get_columns(tmp), matrix_get_rows(tmp)); if (n == matrix_get_columns(tmp)) return tmp; q = matrix_new(n, matrix_get_rows(tmp), true); cmatrix_copy_cmatrix(q, 0, 0, tmp, 0, 0, n, matrix_get_rows(tmp)); matrix_destroy(tmp); return q; }
/*! @brief Function which destroy an object of type matrix_max @param matrix_maxi matrix_max to destroy */ void matrix_max_destroy(struct Matrix_max **matrix_maxi) { // Temporary pointer to ease reading struct Matrix_max *m_matrix_max = NULL; // We check if pointers are valid if (!matrix_maxi) return; if (!*matrix_maxi) return; // Ease reading m_matrix_max = *matrix_maxi; // Destroy vector matrix_destroy(&(m_matrix_max->matrix)); // Destroy allocated instance of matrix_max free(m_matrix_max); // NULL it *matrix_maxi = NULL; }
int main(int argc, char** argv) { wc_config_t config; dataset_t* data; clique_list_t* cl; matrix_t* matrix; group_list_t* groups; wc_data_t wc_data; #ifdef WITH_LIMITS struct rlimit cpu_limit = { 900, 900 }; struct rlimit mem_limit = { 419430400, 419430400}; setrlimit(RLIMIT_CPU, &cpu_limit ); setrlimit(RLIMIT_AS, &mem_limit ); #endif configure(&config, argc, argv); data = dataset_load(config.datfile); cl = clique_list_load(config.clfile); wc_data.emap = enumerated_map_load(config.empfile); wc_data.fi = frequent_itemset_list_load(config.fifile, 0); printf("Generate matrix...\n"); wc_data.threshold = config.threshold; matrix = matrix_create(data, cl, sizeof(double), &wc_data, alignment_amount); /* matrix_print_int(matrix); */ printf("Generate group list...\n"); groups = group_list_from_clique_list(cl); /* group_list_print(groups); */ printf("Merging groups...\n"); wc_data.matrix = matrix; group_list_merge(groups, wc_strength, NULL, &wc_data); group_list_save(groups, config.grpfile); group_list_destroy(groups); matrix_destroy(matrix); enumerated_map_destroy(wc_data.emap); frequent_itemset_list_destroy(wc_data.fi); clique_list_destroy(cl); dataset_destroy(&data); return 0; }
int main(int ac, char** av) { int error = 0; matrix_t* a = NULL; matrix_t* const_a = NULL; vector_t* x = NULL; vector_t* const_b = NULL; vector_t* b = NULL; #if CONFIG_FSUB_SEQ vector_t* bseq = NULL; #endif if (matrix_create_lower(&const_a, CONFIG_ASIZE) == -1) goto on_error; if (matrix_create_empty(&a, CONFIG_ASIZE) == -1) goto on_error; if (vector_create(&const_b, CONFIG_ASIZE) == -1) goto on_error; if (vector_create_empty(&b, CONFIG_ASIZE) == -1) goto on_error; #if CONFIG_FSUB_SEQ if (vector_create_empty(&bseq, CONFIG_ASIZE) == -1) goto on_error; #endif if (vector_create_empty(&x, CONFIG_ASIZE) == -1) goto on_error; #if CONFIG_FSUB_PTHREAD fsub_pthread_initialize(); #endif /* apply forward substitution: ax = b */ size_t i; for (i = 0; i < CONFIG_ITER_COUNT; ++i) { struct timeval tms[4]; matrix_copy(a, const_a); vector_copy(b, const_b); #if CONFIG_FSUB_SEQ vector_copy(bseq, const_b); #endif #if CONFIG_FSUB_PTHREAD gettimeofday(&tms[0], NULL); fsub_pthread_apply(const_a, b); gettimeofday(&tms[1], NULL); timersub(&tms[1], &tms[0], &tms[2]); #elif CONFIG_FSUB_XKAAPI gettimeofday(&tms[0], NULL); fsub_xkaapi_apply(const_a, b); gettimeofday(&tms[1], NULL); timersub(&tms[1], &tms[0], &tms[2]); #endif #if CONFIG_FSUB_GSL fsub_gsl_apply(a, x, const_b); #endif #if CONFIG_FSUB_SEQ gettimeofday(&tms[0], NULL); fsub_seq_apply(a, bseq); gettimeofday(&tms[1], NULL); timersub(&tms[1], &tms[0], &tms[3]); #endif /* report times */ #if CONFIG_TIME #if CONFIG_FSUB_PTHREAD || CONFIG_FSUB_XKAAPI printf("par: %lu\n", tms[2].tv_sec * 1000000 + tms[2].tv_usec); #endif #if CONFIG_FSUB_SEQ printf("seq: %lu\n", tms[3].tv_sec * 1000000 + tms[3].tv_usec); #endif #endif /* check against gsl implm */ #if CONFIG_FSUB_GSL #if CONFIG_FSUB_SEQ if (vector_cmp(bseq, x)) { printf("invalid seq\n"); error = -1; } #endif #if CONFIG_FSUB_PTHREAD || CONFIG_FSUB_XKAAPI if (vector_cmp(b, x)) { printf("invalid parallel\n"); error = -1; } #endif if (error == -1) { vector_print(b); vector_print(x); goto on_error; } #endif } #if CONFIG_FSUB_PTHREAD fsub_pthread_finalize(); #endif on_error: if (a != NULL) matrix_destroy(a); if (const_a != NULL) matrix_destroy(const_a); if (x != NULL) vector_destroy(x); if (b != NULL) vector_destroy(b); if (const_b != NULL) vector_destroy(const_b); #if CONFIG_SEQ if (bseq != NULL) vector_destroy(bseq); #endif return error; }
/*! @brief Invert a matrix @param matrix Matrix for which we want the inverse @return Inverted Matrix */ struct Matrix* matrix_inverse (struct Matrix *matrix) { // Index to browse augmented matrix rref size_t i = 0, j = 0; // Index to browse inverted matrix size_t k = 0; // struct SRet Ret = {0}; // Matrix identity to append struct Matrix *m_identity = NULL; // augmented matrix struct Matrix *m_augmented = NULL; // rref of the augmented matrix struct Matrix *m_rref = NULL; // Inverted matrix struct Matrix *m_inverse = NULL; // determinant int det; // Ret = matrix_det_sarrus(matrix); det = matrix_det_sarrus(matrix); if (!matrix) { // // Ret.ret = ERROR_NULL_POINTER; printf("matrix_inverse: Matrix not allocated\n"); return NULL; } if (matrix->nr != matrix->nc) { // Ret.ret = ERROR_MATRIX_NOTSQUARE; printf("matrix_inverse: Matrix not square\n"); return NULL; } // if (!Ret.ret) if (!det) { printf("matrix_inverse: Matrix not inversible\n"); return NULL; } // We create the working matrix m_identity = matrix_identity(matrix->nr, matrix->nc); m_augmented = matrix_augment(matrix, m_identity); m_rref = matrix_rref_gauss (m_augmented); // We allocate inverted matrix m_inverse = matrix_create(matrix->nr, matrix->nc); // We extract the inverted matrix for (i = 0; i < matrix->nr; i++) { for (j = matrix->nc; j < 2*matrix->nc; j++) { m_inverse->data[i][k] = m_rref->data[i][j]; k++; } k = 0; } // We free all useless used memory matrix_destroy(&m_identity); matrix_destroy(&m_augmented); matrix_destroy(&m_rref); return m_inverse; }
int main(int argc, char *argv[]) { Matrix *A = NULL, *B = NULL, *C = NULL; int ELEMENTS = 0; struct timeval start, finish; char input[BUFFER_SIZE]; int i, count, totalJobs, child = 0; int npes, myrank; double *col_array, *response; char nome[100]; MPI_Init(&argc, &argv); MPI_Comm_size(MPI_COMM_WORLD, &npes); MPI_Comm_rank(MPI_COMM_WORLD, &myrank); gethostname(nome, 100); /*printf("From process %d out of %d, Hello World! (%s)\n", myrank, npes, nome);*/ /* printf("*******************************\n" ); printf("* *\n" ); printf("* Matrix product caculator *\n" ); printf("* *\n" ); printf("*******************************\n" ); /** * Check the user insert the file path from args */ if (myrank == (npes-1)) { if(argc > 2) { strcpy(input, argv[1]); if (!matrix_register(&A, input)) { return 0; } strcpy(input, argv[2]); if(!matrix_register(&B, input)) { return 0; } if(!matrix_result_create(&C, A, B)) { return 0; } ELEMENTS = matrix_get_elements(C); col_array = (double *) malloc(sizeof(double) * ELEMENTS); totalJobs = ((ELEMENTS * ELEMENTS) / (npes-1)) + 2; response = (double *) malloc(sizeof(double)* (totalJobs * 2)); }else{ printf("ERRO: Numero incorreto de argumentos\n"); printf("Usage: ./main <matrix_A> <matrix_B>\n"); return 1; } for (i = 0; i < (npes-1); i++) { MPI_Send(&ELEMENTS, 1, MPI_INT, i, DEFAULT_TAG, MPI_COMM_WORLD); } double *row = get_all_nodes(A); while (matrix_out_of_bounds(C, child)) { MPI_Send(&child, 1, MPI_INT, child%(npes-1), DEFAULT_TAG, MPI_COMM_WORLD); matrix_recieve_col_array(B, col_array, child%ELEMENTS); MPI_Send(&row[(child/ELEMENTS)*ELEMENTS], ELEMENTS, MPI_DOUBLE, child%(npes-1), DEFAULT_TAG, MPI_COMM_WORLD); MPI_Send(col_array, ELEMENTS, MPI_DOUBLE, child%(npes-1), DEFAULT_TAG, MPI_COMM_WORLD); child++; } /* Finalizando todos os processos*/ child = END_TASK; for (i = 0; i < (npes-1); i++) { MPI_Send(&child, 1, MPI_INT, i, DEFAULT_TAG, MPI_COMM_WORLD); } MPI_Status st; int processCount = 0; count = 0; while (processCount < (npes-1)) { MPI_Recv(response, totalJobs * 2, MPI_DOUBLE, processCount, DEFAULT_TAG, MPI_COMM_WORLD, &st); while (response[count] != END_TASK) { if(response[count] != END_TASK) { matrix_set_elements(C, (int) response[count], response[count+1]); count++; count++; }else{ } } processCount++; count = 0; } /*matrix_print(A); matrix_print(B); matrix_print(C);*/ matrix_destroy(A); matrix_destroy(B); matrix_destroy(C); }else{ /** child process */ int position = 0, count = 0, ELEMENTS = 0, totalJobs = 0; double *row, *col; double *response; MPI_Status st; MPI_Recv(&ELEMENTS, 1, MPI_INT, (npes-1), DEFAULT_TAG, MPI_COMM_WORLD, &st); if(ELEMENTS == END_TASK){ MPI_Finalize(); } row = (double * ) malloc (sizeof(double) * ELEMENTS); col = (double * ) malloc (sizeof(double) * ELEMENTS); totalJobs = ((ELEMENTS * ELEMENTS) / (npes-1)) + 2; response = (double *) malloc(sizeof(double) * (totalJobs * 2)); while (position != END_TASK) { MPI_Recv(&position, 1, MPI_INT, (npes-1), DEFAULT_TAG, MPI_COMM_WORLD, &st); if (position != END_TASK) { MPI_Recv(row, ELEMENTS, MPI_DOUBLE, (npes-1), DEFAULT_TAG, MPI_COMM_WORLD, &st); MPI_Recv(col, ELEMENTS, MPI_DOUBLE, (npes-1), DEFAULT_TAG, MPI_COMM_WORLD, &st); response[count++] = position; matrix_multiply_by_segment(row, col, ELEMENTS, &response[count++]); }else{ break; } } response[count++] = END_TASK; response[count++] = END_TASK; MPI_Send(response, totalJobs * 2 , MPI_DOUBLE, (npes-1), DEFAULT_TAG, MPI_COMM_WORLD); } MPI_Finalize(); return 0; }
/* * Accept as parameter: * - input file * - algorithm * - S: serial * - P: Pthread parallel * - O: OpenMP parallel * - verbose (show data in console) * - # of threads * * Main steps * 1. Read matrix from file * 2. Solve linear system using Jacobi Method * 3. Write output * * Output * Result file with statistics */ int main(int argc, char *argv[]) { if ( argc != 5 ) { puts("Inform input file and number of threads!"); exit(1); } //algorithm char algorithm = argv[2][0]; //# of threads int thread_count = strtol(argv[3], NULL, 10); //console output level int verbose = strtol(argv[4], NULL, 10); if (verbose) puts("---BEGIN---"); //prints info if (verbose) printf("Input file: '%s', thread count: %i, algorithm: %c\n\n", argv[1], thread_count, algorithm); //loads matrix matrix *m = matrix_load(argv[1]); //prints matrix if (verbose) matrix_print(m); //starts timer timer* t = start_timer(); jacobi_result* result; switch (algorithm) { case 'P': // pthread parallel result = jacobi_parallel_pthread_better(m, thread_count, verbose); break; case 'O': // OpenMP parallel result = jacobi_parallel_omp(m, thread_count, verbose); break; /* case 'M': // MPI parallel break; */ case 'S': // serial default: result = jacobi_serial(m, verbose); } //Sleep(500); //stops timer stop_timer(t, verbose); //prints result if (verbose) { int i; printf("\nResults: "); for (i = 0; i < m->size && i < 200; i++) { printf("%f, ", result->x[i]); } printf("\nIterations: %i ", result->k); } //saves results write_results(t, argv[1], thread_count, algorithm, m->size); //frees matrix matrix_destroy(m); //frees timer free(t); //frees result //free(result->x); free(result); if (verbose) puts("\n\n---END---"); return EXIT_SUCCESS; }
/* Multi-threaded matrix multiplication. * Runs multiplication in provided T_Pool, by creating set of tasks. * Returns new matrix. * Returns: Matrix* on success, or NULL on fail. */ Matrix * matrix_mult_thread(T_Pool *tpool, const Matrix *mt1, const Matrix *mt2) { if (!tpool) { return NULL; } if (!mt1 || !mt2) return NULL; if (mt1->columns != mt2->lines) { printf("Matrixes can not be multiplicated\n"); return NULL; } /* Transform 2nd matrix for faster operations. */ Matrix *mt2_trans = matrix_transponse(mt2); if (!mt2_trans) return NULL; Matrix *res = matrix_create(mt1->lines, mt2->columns); if (!res) return NULL; size_t i; const long long *v1 = NULL, *v2 = NULL; size_t v_size = mt1->columns; /* Multiply matrixes: * Create set of tasks to perform multiplication in * following order. * 2nd matrix is transposed so multiply * line of 1st matrix(M1) by line of 2nd transposed matrix(M2) and so on. * * In order to decrease cache-misses create tasks in order: * 1st line of M1 by 1st half of M2 * 1st line of M1 by 2nd half of M2 * 2st line of M1 by 1st half of M2 * ...etc * */ /* Number of columns (lines in transposed) * in each half of 2nd matrix */ size_t m2_h1_ln = mt2_trans->lines / 2; size_t m2_h2_ln = mt2_trans->lines / 2 + mt2_trans->lines % 2; /* Size of 1st half of 2nd matrix */ size_t m2_h1_size = m2_h1_ln * mt2_trans->columns; /* Size of 2nd half of 2nd matrix */ size_t m2_h2_size = m2_h2_ln * mt2_trans->columns; /* Create T_Event to count completed tasks. * handle special case when M2 is 1 column. */ T_Event *te = t_event_create(mt1->lines * (mt2_trans->lines == 1 ? 1 : 2)); /* Create tasks; * Lines of M1 x 1st half of M2 */ if (likely(mt2_trans->lines > 1)) { for (i = 0; i < mt1->lines; i++) { v1 = mt1->data + i * v_size; v2 = mt2_trans->data; /* Create task data */ Mult_Data *md = _mult_data_create(v1, v_size, v2, m2_h1_size, v_size, res->data + i * res->columns, te); /* Push task func and task data */ T_Task *tt = t_task_create(_vect_mult_task_func, md); /* Add task pointer to task data in order to free task */ md->task = tt; t_pool_task_insert(tpool, tt); } } /* Create tasks: * Lines of M1 x 2nd half of M2 */ for (i = 0; i < mt1->lines; i++) { v1 = mt1->data + i * v_size; v2 = mt2_trans->data + m2_h1_size; /* Create task data */ Mult_Data *md = _mult_data_create(v1, v_size, v2, m2_h2_size, v_size, res->data + i * res->columns + m2_h1_ln, te); /* Push task func and task data */ T_Task *tt = t_task_create(_vect_mult_task_func, md); /* Add task pointer to task data in order to free task */ md->task = tt; t_pool_task_insert(tpool, tt); } /* Start T_Pool */ t_pool_run(tpool); /* Block until all tasks are finished */ t_event_wait(te); t_event_destroy(te); matrix_destroy(mt2_trans); return res; }
int cos_() { // THREADS pthread_t* const_threads = NULL; // constructor threads constructor_thread_data* const_thread_data = NULL; // constructor threads data pthread_t* comm_threads = NULL; // community threads community_thread_data* comm_thread_data = NULL; // community threads data pthread_attr_t attr; // pthread attribute void *status; // pthread status pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); // FLAGS int m_check = -1; // control flag which verifies matrix_init() int slide_fw = -1; // slide_forward control flag int thread_flag; // thread flag (create and join) // UTILITIES int i=0; // iterators int chunk_rows = 0; // keeps the number of rows being processed during this chunk int rows_processed = 0; // keeps the number of rows processed /*********************************************************************** matrix_init() initializes matrix structure (malloc inside), the second parameter is equal to the number of cliques. ***********************************************************************/ m_check = matrix_init(&m, all_cliques->maximal_cliques_total); if (m_check != 0) { printf("ERROR in matrix_init()!\n"); matrix_destroy(m); m = NULL; return -1; } // If the program is here, m contains the first window /*********************************************************************** Initialization of threads parameters ***********************************************************************/ const_thread_data = (constructor_thread_data*) malloc(sizeof(constructor_thread_data) * NUM_THREADS); for (i = 0; i < NUM_THREADS; i++) { // tell each constructor thread the first index it will start processing the chunk const_thread_data[i].start_from_row = i; } comm_thread_data = (community_thread_data*) malloc(sizeof(community_thread_data) * NUM_THREADS); for (i = 0; i < NUM_THREADS; i++) { // initialize a disjoint set forest specific to each thread. It will use that forest // for processing the overlap between maximal cliques of every k and hence it must // be of maximum size comm_thread_data[i].start_from_row = i; } /*********************************************************************** Initialization of communities structure ***********************************************************************/ // allocate global disjoint set forests for each k between 3 and k_max global_dsf = (dsforest_t**)malloc(sizeof(dsforest_t*) * (k_max - 2)); // allocate space for the mutexes that will assure mutual exclusion // while accessing global_dsf and communities_done global_dsf_mutexes = (pthread_mutex_t*)malloc(sizeof(pthread_mutex_t) * (k_max - 2)); for (i = 0; i < (k_max - 2); i++) { // compute the numer of maximal cliques which belong to at least one community // this number is used for allocating the right number of independent set // data structures. Recall that thread i will compute (i+3)-clique communities unsigned long int disjoint_sets_number; cliques_rows_to_be_read(all_cliques, i+3, &disjoint_sets_number); dsforest_init(&global_dsf[i], disjoint_sets_number); pthread_mutex_init(&global_dsf_mutexes[i], NULL); } int chunk = 0; // chunk counter /**************************************************************** MAIN LOOP BEGINS HERE... ****************************************************************/ do { chunk++; printf("Chunk %d\n", chunk); /**************************************************************** create NUM_THREADS threads which are able to read all_cliques structure and are able to write a part of current window (m) each const_thread has its own data structure ****************************************************************/ const_threads = (pthread_t*) malloc(sizeof(pthread_t) * NUM_THREADS); for (i = 0; i < NUM_THREADS; i++) { // tell the thread the right index from which it has to start processing const_thread_data[i].start_from_row = i + rows_processed; thread_flag = pthread_create(&const_threads[i], &attr, (void*)(&constructor_thread_body), (void*)(&const_thread_data[i])); if (thread_flag != 0) { printf("pthread_create ERROR!\n"); return -1; } } // printf("Waiting for %d constructor threads\n", NUM_THREADS); // WAITING FOR NUM_THREADS CONSTRUCTOR THREAD "ENDINGS" for (i = 0; i < NUM_THREADS; i++) { thread_flag = pthread_join(const_threads[i], &status); if (thread_flag != 0) { printf("pthread_join ERROR!\n"); return -1; } } // DEALLOCATING MEMORY for constructor threads free(const_threads); /**************************************************************** create NUM_THREADS threads which are able to read matrix structure and are able to compute communities each comm_thread has its own data structure ****************************************************************/ comm_threads = (pthread_t*) malloc(sizeof(pthread_t) * NUM_THREADS); for (i = 0; i < NUM_THREADS; i++) { // tell the thread the right index from which it has to start processing comm_thread_data[i].start_from_row = i + rows_processed; thread_flag = pthread_create(&comm_threads[i], &attr, (void*)(&community_thread_body), (void*)(&comm_thread_data[i])); if (thread_flag != 0) { printf("pthread_create ERROR!\n"); return -1; } } // printf("Waiting for %d community threads\n", NUM_THREADS); // WAITING FOR NUM_THREADS COMMUNITY THREAD "ENDINGS" for (i = 0; i < NUM_THREADS; i++) { thread_flag = pthread_join(comm_threads[i],&status); if (thread_flag != 0) { printf("pthread_join ERROR!\n"); return -1; } } // DEALLOCATING MEMORY for community threads free(comm_threads); // before sliding the window forward we have to keep track of // how many rows have yet been processed matrix_get_num_rows_in_window(m, &chunk_rows); debug((DEBUG_NORMAL, "\tchunk_rows: %i", chunk_rows)); rows_processed += chunk_rows; debug((DEBUG_NORMAL, "\trows_processed: %i", rows_processed)); slide_fw = matrix_slide_forward(m); } while ( slide_fw != I_END_OF_MATRIX_REACHED ); printf("Done processing matrix chunks...\n"); // write out found communities write_found_communities_to_file(); // deallocate memory used for disjoint set forests for(i=0; i < (k_max - 2); i++){ dsforest_destroy(global_dsf[i]); pthread_mutex_destroy(&global_dsf_mutexes[i]); } free(global_dsf); free(global_dsf_mutexes); // DEALLOCATING MEMORY for thread parameters free(const_thread_data); free(comm_thread_data); pthread_attr_destroy(&attr); return 0; }