Bu Blogda Ara

7 Şubat 2010 Pazar

send third row of a matrix from process 0 to process 1

/* send_row.c -- send third row of a matrix from process 0 to process 1
*
* Input: none
* Output: the row received by process 1
*
* Note: Program should only be run with 2 processes
*
* See Chap 6, p. 96 in PPMPI
*/
#include
#include "mpi.h"

main(int argc, char* argv[]) {
int p;
int my_rank;
float A[10][10];
MPI_Status status;
int i, j;

MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);

if (my_rank == 0) {
for (i = 0; i < 10; i++)
for (j = 0; j < 10; j++)
A[i][j] = (float) i;
MPI_Send(&(A[2][0]), 10, MPI_FLOAT, 1, 0,
MPI_COMM_WORLD);
} else { /* my_rank = 1 */
MPI_Recv(&(A[2][0]), 10, MPI_FLOAT, 0, 0,
MPI_COMM_WORLD, &status);
for (j = 0; j < 10; j++)
printf("%3.1f ", A[2][j]);
printf("\n");
}

MPI_Finalize();
} /* main */

send column 1 of a matrix on process 0 to row 1 * on process 1.

/* send_col_to_row.c -- send column 1 of a matrix on process 0 to row 1
* on process 1.
*
* Input: none
* Output: The row received by process 1.
*
* Note: This program should only be run with 2 processes
*
* See Chap 6., pp. 98 & ff in PPMPI
*/
#include
#include "mpi.h"

main(int argc, char* argv[]) {
int p;
int my_rank;
float A[10][10];
MPI_Status status;
MPI_Datatype column_mpi_t;
int i, j;

MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);

MPI_Type_vector(10, 1, 10, MPI_FLOAT, &column_mpi_t);
MPI_Type_commit(&column_mpi_t);

if (my_rank == 0) {
for (i = 0; i < 10; i++)
for (j = 0; j < 10; j++)
A[i][j] = (float) i;
MPI_Send(&(A[0][0]), 1, column_mpi_t, 1, 0,
MPI_COMM_WORLD);
} else { /* my_rank = 1 */
for (i = 0; i < 10; i++)
for (j = 0; j < 10; j++)
A[i][j] = 0.0;
MPI_Recv(&(A[0][0]), 10, MPI_FLOAT, 0, 0,
MPI_COMM_WORLD, &status);
for (j = 0; j < 10; j++)
printf("%3.1f ", A[0][j]);
printf("\n");
}

MPI_Finalize();
} /* main */

send the third column of a matrix from process 0 to * process 1

/* send_col.c -- send the third column of a matrix from process 0 to
* process 1
*
* Input: None
* Output: The column received by process 1
*
* Note: This program should only be run with 2 processes
*
* See Chap 6., pp. 96 & ff in PPMPI
*/
#include
#include "mpi.h"

main(int argc, char* argv[]) {
int p;
int my_rank;
float A[10][10];
MPI_Status status;
MPI_Datatype column_mpi_t;
int i, j;

MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);

MPI_Type_vector(10, 1, 10, MPI_FLOAT, &column_mpi_t);
MPI_Type_commit(&column_mpi_t);

if (my_rank == 0) {
for (i = 0; i < 10; i++)
for (j = 0; j < 10; j++)
A[i][j] = (float) j;
MPI_Send(&(A[0][2]), 1, column_mpi_t, 1, 0,
MPI_COMM_WORLD);
} else { /* my_rank = 1 */
MPI_Recv(&(A[0][2]), 1, column_mpi_t, 0, 0,
MPI_COMM_WORLD, &status);
for (i = 0; i < 10; i++)
printf("%3.1f ", A[i][2]);
printf("\n");
}

MPI_Finalize();
} /* main */

Parallel Trapezoidal Rule. Uses MPI_Pack/Unpack in * distribution of input data.

/* get_data4.c -- Parallel Trapezoidal Rule. Uses MPI_Pack/Unpack in
* distribution of input data.
*
* Input:
* a, b: limits of integration.
* n: number of trapezoids.
* Output: Estimate of the integral from a to b of f(x)
* using the trapezoidal rule and n trapezoids.
*
* Notes:
* 1. f(x) is hardwired.
* 2. the number of processes (p) should evenly divide
* the number of trapezoids (n).
*
* See Chap 6., pp. 100 & ff in PPMPI
*/
#include

/* We'll be using MPI routines, definitions, etc. */
#include "mpi.h"

main(int argc, char** argv) {
int my_rank; /* My process rank */
int p; /* The number of processes */
float a; /* Left endpoint */
float b; /* Right endpoint */
int n; /* Number of trapezoids */
float h; /* Trapezoid base length */
float local_a; /* Left endpoint my process */
float local_b; /* Right endpoint my process */
int local_n; /* Number of trapezoids for */
/* my calculation */
float integral; /* Integral over my interval */
float total; /* Total integral */
int source; /* Process sending integral */
int dest = 0; /* All messages go to 0 */
int tag = 0;
MPI_Status status;

void Get_data4(float* a_ptr, float* b_ptr, int* n_ptr, int my_rank);
float Trap(float local_a, float local_b, int local_n,
float h); /* Calculate local integral */

/* Let the system do what it needs to start up MPI */
MPI_Init(&argc, &argv);

/* Get my process rank */
MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);

/* Find out how many processes are being used */
MPI_Comm_size(MPI_COMM_WORLD, &p);

Get_data4(&a, &b, &n, my_rank);

h = (b-a)/n; /* h is the same for all processes */
local_n = n/p; /* So is the number of trapezoids */

/* Length of each process' interval of
* integration = local_n*h. So my interval
* starts at: */
local_a = a + my_rank*local_n*h;
local_b = local_a + local_n*h;
integral = Trap(local_a, local_b, local_n, h);

/* Add up the integrals calculated by each process */
MPI_Reduce(&integral, &total, 1, MPI_FLOAT,
MPI_SUM, 0, MPI_COMM_WORLD);

/* Print the result */
if (my_rank == 0) {
printf("With n = %d trapezoids, our estimate\n",
n);
printf("of the integral from %f to %f = %f\n",
a, b, total);
}

/* Shut down MPI */
MPI_Finalize();
} /* main */


/********************************************************************/
void Get_data4(
float* a_ptr /* out */,
float* b_ptr /* out */,
int* n_ptr /* out */,
int my_rank /* in */) {

char buffer[100]; /* Store data in buffer */
int position; /* Keep track of where data is */
/* in the buffer */

if (my_rank == 0){
printf("Enter a, b, and n\n");
scanf("%f %f %d", a_ptr, b_ptr, n_ptr);

/* Now pack the data into buffer. Position = 0 */
/* says start at beginning of buffer. */
position = 0;

/* Position is in/out */
MPI_Pack(a_ptr, 1, MPI_FLOAT, buffer, 100,
&position, MPI_COMM_WORLD);
/* Position has been incremented: it now refer- */
/* ences the first free location in buffer. */

MPI_Pack(b_ptr, 1, MPI_FLOAT, buffer, 100,
&position, MPI_COMM_WORLD);
/* Position has been incremented again. */

MPI_Pack(n_ptr, 1, MPI_INT, buffer, 100,
&position, MPI_COMM_WORLD);
/* Position has been incremented again. */

/* Now broadcast contents of buffer */
MPI_Bcast(buffer, 100, MPI_PACKED, 0,
MPI_COMM_WORLD);
} else {
MPI_Bcast(buffer, 100, MPI_PACKED, 0,
MPI_COMM_WORLD);

/* Now unpack the contents of buffer */
position = 0;
MPI_Unpack(buffer, 100, &position, a_ptr, 1,
MPI_FLOAT, MPI_COMM_WORLD);
/* Once again position has been incremented: */
/* it now references the beginning of b. */

MPI_Unpack(buffer, 100, &position, b_ptr, 1,
MPI_FLOAT, MPI_COMM_WORLD);
MPI_Unpack(buffer, 100, &position, n_ptr, 1,
MPI_INT, MPI_COMM_WORLD);
}
} /* Get_data4 */


/********************************************************************/
float Trap(
float local_a /* in */,
float local_b /* in */,
int local_n /* in */,
float h /* in */) {

float integral; /* Store result in integral */
float x;
int i;

float f(float x); /* function we're integrating */

integral = (f(local_a) + f(local_b))/2.0;
x = local_a;
for (i = 1; i <= local_n-1; i++) {
x = x + h;
integral = integral + f(x);
}
integral = integral*h;
return integral;
} /* Trap */


/********************************************************************/
float f(float x) {
float return_val;
/* Calculate f(x). */
/* Store calculation in return_val. */
return_val = x*x;
return return_val;
} /* f */

Parallel Trapezoidal Rule. Builds a derived type * for use with the distribution of the input data.

/* get_data3.c -- Parallel Trapezoidal Rule. Builds a derived type
* for use with the distribution of the input data.
*
* Input:
* a, b: limits of integration.
* n: number of trapezoids.
* Output: Estimate of the integral from a to b of f(x)
* using the trapezoidal rule and n trapezoids.
*
* Notes:
* 1. f(x) is hardwired.
* 2. the number of processes (p) should evenly divide
* the number of trapezoids (n).
*
* See Chap 6, pp. 90 & ff in PPMPI
*/
#include

/* We'll be using MPI routines, definitions, etc. */
#include "mpi.h"

void Build_derived_type(
float* a_ptr /* in */,
float* b_ptr /* in */,
int* n_ptr /* in */,
MPI_Datatype* mesg_mpi_t_ptr /* out */);

main(int argc, char** argv) {
int my_rank; /* My process rank */
int p; /* The number of processes */
float a; /* Left endpoint */
float b; /* Right endpoint */
int n; /* Number of trapezoids */
float h; /* Trapezoid base length */
float local_a; /* Left endpoint my process */
float local_b; /* Right endpoint my process */
int local_n; /* Number of trapezoids for */
/* my calculation */
float integral; /* Integral over my interval */
float total; /* Total integral */
int source; /* Process sending integral */
int dest = 0; /* All messages go to 0 */
int tag = 0;
MPI_Status status;

void Get_data3(float* a_ptr, float* b_ptr, int* n_ptr, int my_rank);
float Trap(float local_a, float local_b, int local_n,
float h); /* Calculate local integral */

/* Let the system do what it needs to start up MPI */
MPI_Init(&argc, &argv);

/* Get my process rank */
MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);

/* Find out how many processes are being used */
MPI_Comm_size(MPI_COMM_WORLD, &p);

Get_data3(&a, &b, &n, my_rank);

h = (b-a)/n; /* h is the same for all processes */
local_n = n/p; /* So is the number of trapezoids */

/* Length of each process' interval of
* integration = local_n*h. So my interval
* starts at: */
local_a = a + my_rank*local_n*h;
local_b = local_a + local_n*h;
integral = Trap(local_a, local_b, local_n, h);

/* Add up the integrals calculated by each process */
MPI_Reduce(&integral, &total, 1, MPI_FLOAT,
MPI_SUM, 0, MPI_COMM_WORLD);

/* Print the result */
if (my_rank == 0) {
printf("With n = %d trapezoids, our estimate\n",
n);
printf("of the integral from %f to %f = %f\n",
a, b, total);
}

/* Shut down MPI */
MPI_Finalize();
} /* main */


/********************************************************************/
void Build_derived_type(
float* a_ptr /* in */,
float* b_ptr /* in */,
int* n_ptr /* in */,
MPI_Datatype* mesg_mpi_t_ptr /* out */) {
/* pointer to new MPI type */

/* The number of elements in each "block" of the */
/* new type. For us, 1 each. */
int block_lengths[3];

/* Displacement of each element from start of new */
/* type. The "d_i's." */
/* MPI_Aint ("address int") is an MPI defined C */
/* type. Usually an int. */
MPI_Aint displacements[3];

/* MPI types of the elements. The "t_i's." */
MPI_Datatype typelist[3];

/* Use for calculating displacements */
MPI_Aint start_address;
MPI_Aint address;

block_lengths[0] = block_lengths[1]
= block_lengths[2] = 1;

/* Build a derived datatype consisting of */
/* two floats and an int */
typelist[0] = MPI_FLOAT;
typelist[1] = MPI_FLOAT;
typelist[2] = MPI_INT;

/* First element, a, is at displacement 0 */
displacements[0] = 0;

/* Calculate other displacements relative to a */
MPI_Address(a_ptr, &start_address);

/* Find address of b and displacement from a */
MPI_Address(b_ptr, &address);
displacements[1] = address - start_address;

/* Find address of n and displacement from a */
MPI_Address(n_ptr, &address);
displacements[2] = address - start_address;

/* Build the derived datatype */
MPI_Type_struct(3, block_lengths, displacements,
typelist, mesg_mpi_t_ptr);

/* Commit it -- tell system we'll be using it for */
/* communication. */
MPI_Type_commit(mesg_mpi_t_ptr);
} /* Build_derived_type */


/********************************************************************/
void Get_data3(
float* a_ptr /* out */,
float* b_ptr /* out */,
int* n_ptr /* out */,
int my_rank /* in */) {
MPI_Datatype mesg_mpi_t; /* MPI type corresponding */
/* to 3 floats and an int */

if (my_rank == 0){
printf("Enter a, b, and n\n");
scanf("%f %f %d", a_ptr, b_ptr, n_ptr);
}

Build_derived_type(a_ptr, b_ptr, n_ptr, &mesg_mpi_t);
MPI_Bcast(a_ptr, 1, mesg_mpi_t, 0, MPI_COMM_WORLD);
} /* Get_data3 */


/********************************************************************/
float Trap(
float local_a /* in */,
float local_b /* in */,
int local_n /* in */,
float h /* in */) {

float integral; /* Store result in integral */
float x;
int i;

float f(float x); /* function we're integrating */

integral = (f(local_a) + f(local_b))/2.0;
x = local_a;
for (i = 1; i <= local_n-1; i++) {
x = x + h;
integral = integral + f(x);
}
integral = integral*h;
return integral;
} /* Trap */


/********************************************************************/
float f(float x) {
float return_val;
/* Calculate f(x). */
/* Store calculation in return_val. */
return_val = x*x;
return return_val;
} /* f */

send a subvector from process 0 to process 1

/* count.c -- send a subvector from process 0 to process 1
*
* Input: none
* Output: contents of vector received by process 1
*
* Note: Program should only be run with 2 processes.
*
* See Chap 6, pp. 89 & ff. in PPMPI
*/
#include
#include "mpi.h"

main(int argc, char* argv[]) {
float vector[100];
MPI_Status status;
int p;
int my_rank;
int i;

MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &p);
MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);

/* Initialize vector and send */
if (my_rank == 0) {
for (i = 0; i < 50; i++)
vector[i] = 0.0;
for (i = 50; i < 100; i++)
vector[i] = 1.0;
MPI_Send(vector+50, 50, MPI_FLOAT, 1, 0,
MPI_COMM_WORLD);
} else { /* my_rank == 1 */
MPI_Recv(vector+50, 50, MPI_FLOAT, 0, 0,
MPI_COMM_WORLD, &status);
for (i = 50; i < 100; i++)
printf("%3.1f ",vector[i]);
printf("\n");
}

MPI_Finalize();
} /* main */

test basic topology functions

/* top_fcns.c -- test basic topology functions
*
* Input: none
* Output: results of calls to various functions testing topology
* creation
*
* Algorithm:
* 1. Build a 2-dimensional Cartesian communicator from
* MPI_Comm_world
* 2. Print topology information for each process
* 3. Use MPI_Cart_sub to build a communicator for each
* row of the Cartesian communicator
* 4. Carry out a broadcast across each row communicator
* 5. Print results of broadcast
* 6. Use MPI_Cart_sub to build a communicator for each
* column of the Cartesian communicator
* 7. Carry out a broadcast across each column communicator
* 8. Print results of broadcast
*
* Note: Assumes the number of processes, p, is a perfect square
*
* See Chap 7, pp. 121 & ff in PPMPI
*/
#include
#include "mpi.h"
#include

main(int argc, char* argv[]) {
int p;
int my_rank;
int q;
MPI_Comm grid_comm;
int dim_sizes[2];
int wrap_around[2];
int reorder = 1;
int coordinates[2];
int my_grid_rank;
int grid_rank;
int free_coords[2];
MPI_Comm row_comm;
MPI_Comm col_comm;
int row_test;
int col_test;


MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &p);
MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);

q = (int) sqrt((double) p);

dim_sizes[0] = dim_sizes[1] = q;
wrap_around[0] = wrap_around[1] = 1;
MPI_Cart_create(MPI_COMM_WORLD, 2, dim_sizes,
wrap_around, reorder, &grid_comm);

MPI_Comm_rank(grid_comm, &my_grid_rank);
MPI_Cart_coords(grid_comm, my_grid_rank, 2,
coordinates);

MPI_Cart_rank(grid_comm, coordinates, &grid_rank);

printf("Process %d > my_grid_rank = %d, coords = (%d,%d), grid_rank = %d\n",
my_rank, my_grid_rank, coordinates[0], coordinates[1], grid_rank);

free_coords[0] = 0;
free_coords[1] = 1;
MPI_Cart_sub(grid_comm, free_coords, &row_comm);
if (coordinates[1] == 0)
row_test = coordinates[0];
else
row_test = -1;
MPI_Bcast(&row_test, 1, MPI_INT, 0, row_comm);
printf("Process %d > coords = (%d,%d), row_test = %d\n",
my_rank, coordinates[0], coordinates[1], row_test);

free_coords[0] = 1;
free_coords[1] = 0;
MPI_Cart_sub(grid_comm, free_coords, &col_comm);
if (coordinates[0] == 0)
col_test = coordinates[1];
else
col_test = -1;
MPI_Bcast(&col_test, 1, MPI_INT, 0, col_comm);
printf("Process %d > coords = (%d,%d), col_test = %d\n",
my_rank, coordinates[0], coordinates[1], col_test);

MPI_Finalize();
} /* main */