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;
}
Beispiel #2
0
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; 
}
Beispiel #3
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;
}
Beispiel #4
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);
}
Beispiel #5
0
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;
}
Beispiel #6
0
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;
}
Beispiel #8
0
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;
}
Beispiel #9
0
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;
}
Beispiel #11
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;
}
Beispiel #12
0
/*! @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;
}
Beispiel #13
0
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;
} 
Beispiel #14
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;
}
Beispiel #15
0
/*! @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;
}
Beispiel #16
0
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;
}
Beispiel #17
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;
}
Beispiel #19
0
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;
}