/* ----------------------------------------------------------------------- */ /* * file: mpi-cart.c * compilation: mpicc -Wall -Wextra mpi-cart.c -o mpi-cart * invocation: mpirun -n 8 mpi-cart */ /* ----------------------------------------------------------------------- */ /* Studying MPI functions related to the Cartesian topologies */ /* ----------------------------------------------------------------------- */ #include <stdio.h> #include <stdlib.h> /* ----------------------------------------------------------------------- */ #include <mpi.h> /* ----------------------------------------------------------------------- */ typedef struct MPI_Data_s { MPI_Comm comm; int size; int rank; int root; } MPI_Data; /* ----------------------------------------------------------------------- */ #define CART2D_NDIMS 2 typedef struct MPI_Cart2D_Data_s { MPI_Data mpi_data; int ndims; int dims[CART2D_NDIMS]; int periods[CART2D_NDIMS]; int coords[CART2D_NDIMS]; } MPI_Cart2D_Data; /* ----------------------------------------------------------------------- */ #define CART4D_NDIMS 4 typedef struct MPI_Cart4D_Data_s { MPI_Data mpi_data; int ndims; int dims[CART4D_NDIMS]; int periods[CART4D_NDIMS]; int coords[CART4D_NDIMS]; } MPI_Cart4D_Data; /* ----------------------------------------------------------------------- */ void Create_2D_Subcomms(MPI_Cart4D_Data *cart4d, int *remain_dims, MPI_Cart2D_Data *cart2d) { MPI_Cart_sub(cart4d->mpi_data.comm, remain_dims, &(cart2d->mpi_data.comm) ); MPI_Comm_size(cart2d->mpi_data.comm, &(cart2d->mpi_data.size)); MPI_Comm_rank(cart2d->mpi_data.comm, &(cart2d->mpi_data.rank)); cart2d->mpi_data.root = 0; cart2d->ndims = CART2D_NDIMS; MPI_Cart_get(cart2d->mpi_data.comm, cart2d->ndims, cart2d->dims, cart2d->periods, cart2d->coords); } /* ----------------------------------------------------------------------- */ int main(int argc, char **argv) { /* Some variables */ MPI_Data world; MPI_Cart4D_Data cart4d; int remain_dims[CART4D_NDIMS]; MPI_Cart2D_Data cart2d_01, cart2d_12; /* Beginning of the program */ MPI_Init(&argc, &argv); /* Fill-in MPI_COMM_WORLD data */ world.comm = MPI_COMM_WORLD; MPI_Comm_size(world.comm, &(world.size)); MPI_Comm_rank(world.comm, &(world.rank)); world.root = 0; /* Create a division of processors in a 4D Cartesian grid */ cart4d.ndims = CART4D_NDIMS; cart4d.dims[0] = 0; cart4d.dims[1] = 0; cart4d.dims[2] = 0; cart4d.dims[3] = 1; MPI_Dims_create(world.size, cart4d.ndims, cart4d.dims); if (world.rank == world.root) printf("cart4d dims: <%d, %d, %d, %d>\n", cart4d.dims[0], cart4d.dims[1], cart4d.dims[2], cart4d.dims[3] ); /* Create a new communicator with 4D Cartesian topology attached */ cart4d.periods[0] = 0; cart4d.periods[1] = 0; cart4d.periods[2] = 0; cart4d.periods[3] = 0; MPI_Cart_create(world.comm, cart4d.ndims, cart4d.dims, cart4d.periods, 1, &(cart4d.mpi_data.comm) ); /* Fill-in 4D Cartesian communicator data */ MPI_Comm_size(cart4d.mpi_data.comm, &(cart4d.mpi_data.size)); MPI_Comm_rank(cart4d.mpi_data.comm, &(cart4d.mpi_data.rank)); cart4d.mpi_data.root = 0; MPI_Cart_coords(cart4d.mpi_data.comm, cart4d.mpi_data.rank, cart4d.ndims, cart4d.coords ); /* Create 2D subcommunicators and fill-in associated data */ remain_dims[0] = 1; remain_dims[1] = 1; remain_dims[2] = 0; remain_dims[3] = 0; Create_2D_Subcomms(&cart4d, remain_dims, &cart2d_01); remain_dims[0] = 0; remain_dims[1] = 1; remain_dims[2] = 1; remain_dims[3] = 0; Create_2D_Subcomms(&cart4d, remain_dims, &cart2d_12); /* Print info on communicators */ printf("world: %d; cart4d: %d, (%d, %d, %d, %d); " "cart2d_01: %d, (%d, %d); cart2d_12: %d, (%d, %d)\n", world.rank, cart4d.mpi_data.rank, cart4d.coords[0], cart4d.coords[1], cart4d.coords[2], cart4d.coords[3], cart2d_01.mpi_data.rank, cart2d_01.coords[0], cart2d_01.coords[1], cart2d_12.mpi_data.rank, cart2d_12.coords[0], cart2d_12.coords[1] ); /* End of the program */ MPI_Finalize(); return EXIT_SUCCESS; } /* ----------------------------------------------------------------------- */
Tuesday, November 30, 2010
MPI and Cartesian communicators
Thursday, November 25, 2010
libiniparser sample
Ini-file:
# File: hpc-poisson.ini # # The file was created to examine what is libiniparser. # # The need to parse ini-files comes from the problem of testing # Poisson's equation solver for various grids and number of processors. # # Note, that keywords and names of sections are lowercased. # Some comments here look stupid - their purpose is demonstrate # what is comment in ini-file. [Test1] ; Test #1 N1 = 64 ; Number of grid intervals in each direction N2 = 128 N3 = 256 L1 = 1.0 ; The length of the domain in each direction L2 = 2.0 L3 = 4.0 [TEST2] ; Test #2 n1 = 640 n2 = 1280 n3 = 2560 l1 = 1.5 l2 = 2.5 l3 = 4.5
Source code:
/* File: main.c */ /* gcc -Wall -Wextra main.c -liniparser */ #include <stdio.h> #include <stdlib.h> #include <assert.h> #include <iniparser.h> int main() { const char *ini_fname; dictionary *dict; int num_secs; /* Number of sections in ini file */ int curr_sec; /* Index of current section */ ini_fname = "hpc-poisson.ini"; dict = iniparser_load(ini_fname); assert(dict); num_secs = iniparser_getnsec(dict); printf("{number of sections: %d}\n", num_secs); for (curr_sec = 0; curr_sec < num_secs; ++curr_sec) { char *section; const char *keyword; char *key; /* The value of this var is constructed as "section:keyword" */ int val; /* Get name of the current section */ section = iniparser_getsecname(dict, curr_sec); assert(section); printf("[%s]\n", section); /* Construct key[] */ keyword = "n2"; key = malloc( (strlen(section) + strlen(":") + strlen(keyword) + strlen("\0")) * sizeof(key[0]) ); sprintf(key, "%s:%s", section, keyword); /* Get value associated with the key */ val = iniparser_getint(dict, key, -1); printf("%s=%d\n", keyword, val); free(key); } iniparser_freedict(dict); return EXIT_SUCCESS; }
Subscribe to:
Posts (Atom)