Exemple #1
0
int main (int argc, char ** argv) {
	int radius, ret;
	int xsize, ysize, colmax, i;
	struct timespec stime, etime;

	double w[MAX_RAD];

	pixel *src = (pixel*) malloc(sizeof(pixel)*MAX_PIXELS);
	pixel *dst = (pixel*) malloc(sizeof(pixel)*MAX_PIXELS);
	/* Take care of the arguments */
	if (argc != 5) {
		fprintf(stderr, "Usage: %s num_threads radius infile outfile\n", argv[0]);
		exit_prog(src, dst, 1);
	}

	int num_threads = atoi(argv[1]);
	radius = atoi(argv[2]);
	if((radius > MAX_RAD) || (radius < 1)) {
		fprintf(stderr, "Radius (%d) must be greater than zero and less then %d\n",
				radius, MAX_RAD);
		exit_prog(src, dst, 1);
	}

	/* read file */
	if(read_ppm (argv[3], &xsize, &ysize, &colmax, (char *) src) != 0){
		exit_prog(src, dst, 1);
	}

	if( num_threads < 1 || num_threads > ysize){
		fprintf(stderr, "Number of threads needs to be bigger than 0 and smaller than ysize of image\n");
		exit_prog(src, dst, 1);
	}

	if (colmax > 255) {
		fprintf(stderr, "Too large maximum color-component value\n");
		exit_prog(src, dst, 1);
	}

	pthread_t threads[num_threads];
	blur_data *pdata[num_threads];

	int l_ysize = ysize/num_threads;

	// Calculate gauss weights
	get_gauss_weights(radius, w);

	printf("Calling filter\n");

	clock_gettime(CLOCK_REALTIME, &stime);

	for(i=0;i<num_threads;i++){
		pdata[i] = malloc(sizeof(blur_data));
		pdata[i]->xsize = xsize;
		pdata[i]->ysize = l_ysize;
		if(i == num_threads - 1){
			pdata[i]->ysize += ysize - l_ysize*num_threads;
		}
		pdata[i]->src = src + i*l_ysize*xsize;
		pdata[i]->dst = dst + i*l_ysize*xsize;
		pdata[i]->radius = radius;
		pdata[i]->w = w;
		// Number of rows above the threads part of the image
		pdata[i]->rows_up = i*l_ysize;
		// Number of rows below the threads part of the image
		pdata[i]->rows_down = ysize - l_ysize - pdata[i]->rows_up;
		ret = pthread_create(&threads[i], NULL, blurfilter_x, (void*)pdata[i]);
		if(ret){
			fprintf(stderr, "ERROR creating thread\n");
                        free(pdata[i]);
			exit_prog(src, dst, 1);
		}
	}

        for(i=0;i<num_threads;i++){
                pthread_join(threads[i], NULL);
        }

        for(i=0;i<num_threads;i++){
		ret = pthread_create(&threads[i], NULL, blurfilter_y, (void*)pdata[i]);
		if(ret){
			fprintf(stderr, "ERROR creating thread\n");
                        free(pdata[i]);
			exit_prog(src, dst, 1);
		}
        }

        for(i=0;i<num_threads;i++){
                pthread_join(threads[i], NULL);
        }

	clock_gettime(CLOCK_REALTIME, &etime);

	printf("Filtering took: %g secs\n", (etime.tv_sec  - stime.tv_sec) +
			1e-9*(etime.tv_nsec  - stime.tv_nsec)) ;

	/* write result */
	printf("Writing output file\n");

	if(write_ppm (argv[4], xsize, ysize, (char *)src) != 0){
		exit_prog(src, dst, 1);
	}

	free(src);
	free(dst);

	return 0;
}
Exemple #2
0
int main (int argc, char ** argv)
{
    int radius;
    int xsize, ysize, colmax, np, me;
    pixel * src = malloc (MAX_PIXELS * sizeof(pixel));
    double w[MAX_RAD];
    
    /* MPI INITIALIZATION */
    MPI_Init( &argc, &argv );
    MPI_Comm_size( MPI_COMM_WORLD, &np );
    MPI_Comm_rank( MPI_COMM_WORLD, &me );
    
    /* Take care of the arguments */
    if(me ==  MASTER){
        if (argc != 4) {
            fprintf(stderr, "Usage: %s radius infile outfile\n", argv[0]);
            exit(1);
        }
        radius = atoi(argv[1]);
        if((radius > MAX_RAD) || (radius < 1)) {
            fprintf(stderr, "Radius (%d) must be greater than zero and less then %d\n", radius, MAX_RAD);
            exit(1);
        }
        /* read file */
        if(read_ppm (argv[2], &xsize, &ysize, &colmax, (char *) src) != 0)
            exit(1);

        if (colmax > 255) {
            fprintf(stderr, "Too large maximum color-component value\n");
            exit(1);
        }
        /* filter */
        get_gauss_weights(radius, w);

        printf("Has read the image and generated Coefficients\n");
    }

    // BROADCASTING RADIUS
    MPI_Bcast( &radius, 1, MPI_INT, MASTER, MPI_COMM_WORLD );
    // BROADCASTING W
    MPI_Bcast( w, MAX_RAD, MPI_DOUBLE, MASTER, MPI_COMM_WORLD );
    // BROADCASTING XSIZE
    MPI_Bcast( &xsize, 1, MPI_INT, MASTER, MPI_COMM_WORLD );
    // BROADCASTING YSIZE
    MPI_Bcast( &ysize, 1, MPI_INT, MASTER, MPI_COMM_WORLD );
    
    /* MPI_DATATYPE : mpi_pixel_type */
    const int nitems=3;
    int          blocklengths[3] = {1,1,1};
    MPI_Datatype types[3] = {MPI_UNSIGNED_CHAR, MPI_UNSIGNED_CHAR, MPI_UNSIGNED_CHAR};
    MPI_Datatype mpi_pixel_type;
    MPI_Aint     offsets[3];

    offsets[0] = 0;
    offsets[1] = 1;
    offsets[2] = 2;
    MPI_Type_create_struct(nitems, blocklengths, offsets, types, &mpi_pixel_type);
    MPI_Type_commit(&mpi_pixel_type);


    /* COMPUTE THE AREA TO BE EXECUTED BY EACH PROCESSOR*/
    int * sendcounts, * displace;

    sendcounts = malloc(sizeof(int)*np);
    displace = malloc(sizeof(int)*np);


    int * line_starts      = malloc (np * sizeof(int)),
        * line_ends        = malloc (np * sizeof(int)),
        * line_send_starts = malloc (np * sizeof(int)),
        * line_send_ends   = malloc (np * sizeof(int)),
        * sizes            = malloc (np * sizeof(int)),
        * n_starts         = malloc (np * sizeof(int)),
        * n_sizes          = malloc (np * sizeof(int));

    int line, rem, line_sum = 0;

    int i;

    line = ysize / np;
    rem  = ysize % np;

    for (i = 0; i < np; i++) {

        sizes       [i] = (rem > i) ? line + 1: line;
        line_starts [i] = line_sum;
        line_ends   [i] = line_sum + sizes [i];
        n_starts    [i] = xsize * line_starts [i];
        n_sizes     [i] = xsize * sizes [i];

        line_send_starts [i] = ((line_starts [i] - radius) < 0)     ? 0     : line_starts [i] - radius;
        line_send_ends   [i] = ((line_ends   [i] + radius) > ysize) ? ysize : line_ends   [i] + radius;

        sendcounts [i] = (line_send_ends [i] - line_send_starts [i]) * xsize;

        displace [i] = line_send_starts [i] * xsize;

        line_sum += sizes [i];

        if (me == MASTER) {
            printf("P%d: starting from line %d to line %d (%d lines) and sending from line %d to %d (%d lines)\n",
                   i, line_starts [i],     line_ends[i],      line_ends[i]      - line_starts [i],
                      line_send_starts[i], line_send_ends[i], line_send_ends[i] - line_send_starts[i]);
        }
    }

    pixel * buffer_receiver = malloc (sizeof(pixel) * sendcounts[me]);
    
    double start, end;

    start = MPI_Wtime();
    /* DIVIDE THE IMAGE FOR THE COMPUTATION BY EACH PROCESSOR */
    MPI_Scatterv( src, sendcounts , displace, mpi_pixel_type , buffer_receiver, sendcounts[me], mpi_pixel_type , MASTER, MPI_COMM_WORLD );

    int local_ysize = line_send_ends [me] - line_send_starts [me],
        local_start = line_starts    [me] - line_send_starts [me],
        local_end   = local_start + sizes [me];

    /* COMPUTE THE BLUR FILTER */
    blurfilter_bordered(xsize, local_ysize, local_start, local_end, buffer_receiver, radius, w);

    /* GET THE PROCESSED SUBIMAGES AND MERGE THEM */
    MPI_Gatherv (buffer_receiver + local_start * xsize, n_sizes [me],
                 mpi_pixel_type, src, n_sizes, n_starts, mpi_pixel_type, MASTER , MPI_COMM_WORLD);

    end = MPI_Wtime()-start;
    
    if (me == MASTER){
		//printf("Main Master Filtering took: %g sec, s\n", (etime.tv_sec  - stime.tv_sec) + 1e-9*(etime.tv_nsec  - stime.tv_nsec)) ;
		end = MPI_Wtime()-start;
		printf("MASTER mpi time: %g sec\n",end);
		
		//print the time on the file
		FILE * fp;
		char * f;
		f = "measures.csv";
		fp = fopen(f, "a");// "w" means that we are going to write on this file, "a" appends
		fprintf(fp,"%g\n",end); // just write down the elapsed seconds: we'll make only copy&paste to the excel :)
		fclose(fp);
		
		
		/* write result */
		printf("Writing output file\n");
		if(write_ppm (argv[3], xsize, ysize,  (char *)src) != 0)
			exit(1);
	 	printf("Image written on %s\n",argv[3]);
	}

    MPI_Finalize();
    return(0);
}
Exemple #3
0
int main (int argc, char ** argv) {
   int taskid, ntasks;

    int xsize, ysize, colmax;
    pixel src[MAX_PIXELS];
    double w[MAX_RAD];

    struct timespec stime, etime;
    struct timespec tstime, tetime;

    MPI_Init(&argc, &argv);
    MPI_Comm_rank(MPI_COMM_WORLD, &taskid);
    MPI_Comm_size(MPI_COMM_WORLD, &ntasks);

    // Create a custom MPI datatype for pixel
    pixel item;
    MPI_Datatype pixel_mpi;
    MPI_Datatype type[3] = { MPI_UNSIGNED_CHAR, MPI_UNSIGNED_CHAR, MPI_UNSIGNED_CHAR };
    int blocklen[] = { 1, 1, 1 };
    MPI_Aint start, disp[3];

    MPI_Address( &item, &start );
    MPI_Address( &item.r, &disp[0] );
    MPI_Address( &item.g, &disp[1] );
    MPI_Address( &item.b, &disp[2] );

    disp[0] -= start;
    disp[1] -= start;
    disp[2] -= start;

    MPI_Type_struct(3, blocklen, disp, type, &pixel_mpi);
    MPI_Type_commit(&pixel_mpi);

    int buffsize, radius, startY, endY;

    /* Take care of the arguments */
    if (argc != 4) {
        fprintf(stderr, "Usage: %s radius infile outfile\n", argv[0]);
        exit(1);
    }
    radius = atoi(argv[1]);
    if((radius > MAX_RAD) || (radius < 1)) {
        fprintf(stderr, "Radius (%d) must be greater than zero and less then %d\n", radius, MAX_RAD);
        exit(1);
    }

    if (taskid == ROOT) {
        /* read file */
        if(read_ppm (argv[2], &xsize, &ysize, &colmax, (char *) src) != 0)
            exit(1);

        if (colmax > 255) {
            fprintf(stderr, "Too large maximum color-component value\n");
            exit(1);
        }

        /* filter */
        printf("Has read the image, generating coefficients\n");
        get_gauss_weights(radius, w);
    }

    // Broadcast the gaussian weight vector
    MPI_Bcast(w, MAX_RAD, MPI_DOUBLE, ROOT, MPI_COMM_WORLD);
    // Broadcast image dimensions
    MPI_Bcast(&xsize, 1, MPI_INT, ROOT, MPI_COMM_WORLD);
    MPI_Bcast(&ysize, 1, MPI_INT, ROOT, MPI_COMM_WORLD);

    // Calculate chunk size
    buffsize = ceil((float)ysize / (float)ntasks) * xsize;
    pixel recvbuff[MAX_PIXELS];

    int sendcnts[ntasks], displs[ntasks], result_write_starts[ntasks], recievecounts[ntasks];
    int i;
    // Generate sendcount and displacement vectors for Scatterv
    for (i = 0; i < ntasks; i++) {
        // Send enought neighbors to make it possible to also calculate
        // blur in the edges of the chunk
        sendcnts[i] = buffsize + 2 * radius * xsize;
        displs[i] = max(0, i * buffsize);
    }

    clock_gettime(CLOCK_REALTIME, &tstime);

    // Send the image in chunks to all nodes
    MPI_Scatterv(src, sendcnts, displs,
                 pixel_mpi, recvbuff, buffsize + 2 * radius * xsize,
                 pixel_mpi, ROOT, MPI_COMM_WORLD);

    clock_gettime(CLOCK_REALTIME, &stime);

    // Run the filter on the recieved chunk
    blurfilter(xsize, (ysize / ntasks) + 2 * radius, recvbuff, radius, w, taskid);

    clock_gettime(CLOCK_REALTIME, &etime);
    printf("Filtering at %i took: %g secs\n", taskid, (etime.tv_sec  - stime.tv_sec) +
        1e-9*(etime.tv_nsec  - stime.tv_nsec));

    // Generate sendcount and displacement vectors for Scatterv
    for (i = 0; i < ntasks; i++) {
        result_write_starts[i] = i * buffsize + xsize * radius;
        // Only send as much of the chunk that is really useful data
        recievecounts[i] = buffsize;
    }

    // Start writing from the beginning of the buffer if root
    result_write_starts[0] = 0;

    // Since the root node has no overlap in the beginning, we need to
    // send a little bit more from that node than from the rest.
    recievecounts[0] = buffsize + xsize * radius;

    pixel* result_read_start;
    if(taskid==ROOT) {
        // Root-node has no duplicated data in the beginning
        result_read_start = recvbuff;
    } else {
        // Jump over the duplicated data in the beginning of each chunk
        result_read_start = recvbuff + xsize * radius;
    }

    MPI_Gatherv(result_read_start, recievecounts[taskid], pixel_mpi,
                src, recievecounts, result_write_starts,
                pixel_mpi, ROOT, MPI_COMM_WORLD);

    clock_gettime(CLOCK_REALTIME, &tetime);

    MPI_Finalize();


    /* write result */
    if (taskid == ROOT) {
        printf("Everything took: %g secs\n", (tetime.tv_sec  - tstime.tv_sec) +
           1e-9*(tetime.tv_nsec  - tstime.tv_nsec));


        printf("Writing output file\n");

        if(write_ppm (argv[3], xsize, ysize, (char *)src) != 0)
          exit(1);
    }

    return(0);
}