123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351 |
- #include "stencil.h"
- #include <math.h>
- static struct block_description *blocks;
- static unsigned sizex, sizey, sizez;
- static unsigned nbz;
- static unsigned *block_sizes_z;
- static starpu_tag_t tag_common(int z, int dir, int type)
- {
- return (((((starpu_tag_t)type) << 4) | ((dir+1)/2)) << 32)|(starpu_tag_t)z;
- }
- starpu_tag_t TAG_FINISH(int z)
- {
- z = (z + nbz)%nbz;
- starpu_tag_t tag = tag_common(z, 0, 1);
- return tag;
- }
- starpu_tag_t TAG_START(int z, int dir)
- {
- z = (z + nbz)%nbz;
- starpu_tag_t tag = tag_common(z, dir, 2);
- return tag;
- }
- static int mpi_tag_common(int z, int iter, int dir, int buffer)
- {
- return (((((iter << 12)|z)<<4) | ((1+dir)/2))<<4)|buffer;
- }
- int MPI_TAG0(int z, int iter, int dir)
- {
- z = (z + nbz)%nbz;
- int tag = mpi_tag_common(z, iter, dir, 0);
- return tag;
- }
- int MPI_TAG1(int z, int iter, int dir)
- {
- z = (z + nbz)%nbz;
- int tag = mpi_tag_common(z, iter, dir, 1);
- return tag;
- }
- static void compute_block_sizes(void)
- {
- block_sizes_z = (unsigned *) malloc(nbz*sizeof(unsigned));
- STARPU_ASSERT(block_sizes_z);
-
- unsigned default_block_size = (sizez+nbz-1)/nbz;
- unsigned remaining = sizez;
- unsigned b;
- for (b = 0; b < nbz; b++)
- {
- block_sizes_z[b] = MIN(default_block_size, remaining);
- remaining -= block_sizes_z[b];
- }
- STARPU_ASSERT(remaining == 0);
- }
- unsigned get_block_size(int bz)
- {
- return block_sizes_z[bz];
- }
- struct block_description *get_block_description(int z)
- {
- z = (z + nbz)%nbz;
- STARPU_ASSERT(&blocks[z]);
- return &blocks[z];
- }
- unsigned get_block_mpi_node(int z)
- {
- z = (z + nbz)%nbz;
- return blocks[z].mpi_node;
- }
- void create_blocks_array(unsigned _sizex, unsigned _sizey, unsigned _sizez, unsigned _nbz)
- {
-
- nbz = _nbz;
- sizex = _sizex;
- sizey = _sizey;
- sizez = _sizez;
-
- blocks = (struct block_description *) calloc(nbz, sizeof(struct block_description));
- STARPU_ASSERT(blocks);
-
- compute_block_sizes();
- unsigned bz;
- for (bz = 0; bz < nbz; bz++)
- {
- struct block_description * block =
- get_block_description(bz);
-
- block->bz = bz;
-
- block->boundary_blocks[B] = get_block_description((bz-1+nbz)%nbz);
- block->boundary_blocks[T] = get_block_description((bz+1)%nbz);
- }
- }
- void assign_blocks_to_workers(int rank)
- {
- unsigned bz;
-
-
-
-
- unsigned nblocks = 0;
- for (bz = 0; bz < nbz; bz++)
- {
- struct block_description *block =
- get_block_description(bz);
- if (block->mpi_node == rank)
- nblocks++;
- }
-
-
-
- unsigned attributed = 0;
- for (bz = 0; bz < nbz; bz++)
- {
- struct block_description *block =
- get_block_description(bz);
- if (block->mpi_node == rank)
- {
- unsigned workerid;
-
- #if 0
- #if 1
-
- if (attributed < 3*18)
- workerid = attributed / 18;
- else
- workerid = 3+ (attributed - 3*18) / 2;
- #else
-
- if ((attributed % 20) <= 1)
- workerid = 3 + attributed / 20;
- else if (attributed < 60)
- workerid = attributed / 20;
- else
- workerid = (attributed - 60)/2 + 6;
- #endif
- #else
-
- workerid = (attributed / 21) % 3;
- #endif
-
- block->preferred_worker = workerid;
- attributed++;
- }
- }
- }
- void assign_blocks_to_mpi_nodes(int world_size)
- {
- unsigned nzblocks_per_process = (nbz + world_size - 1) / world_size;
- unsigned bz;
- for (bz = 0; bz < nbz; bz++)
- {
- struct block_description *block =
- get_block_description(bz);
- block->mpi_node = bz / nzblocks_per_process;
- }
- }
- static size_t allocated = 0;
- static void allocate_block_on_node(starpu_data_handle_t *handleptr, TYPE **ptr, unsigned nx, unsigned ny, unsigned nz)
- {
- int ret;
- size_t block_size = nx*ny*nz*sizeof(TYPE);
-
- #if 1
- ret = starpu_malloc((void **)ptr, block_size);
- STARPU_ASSERT(ret == 0);
- #else
- *ptr = malloc(block_size);
- STARPU_ASSERT(*ptr);
- #endif
- allocated += block_size;
-
- memset(*ptr, 0, block_size);
-
- starpu_block_data_register(handleptr, 0, (uintptr_t)*ptr, nx, nx*ny, nx, ny, nz, sizeof(TYPE));
- }
- void display_memory_consumption(int rank)
- {
- fprintf(stderr, "%lu MB of memory were allocated on node %d\n", allocated/(1024*1024), rank);
- }
- void allocate_memory_on_node(int rank)
- {
- unsigned bz;
- for (bz = 0; bz < nbz; bz++)
- {
- struct block_description *block = get_block_description(bz);
- unsigned node = block->mpi_node;
- unsigned size_bz = block_sizes_z[bz];
-
-
- if (node == rank)
- {
- allocate_block_on_node(&block->layers_handle[0], &block->layers[0],
- (sizex + 2*K), (sizey + 2*K), (size_bz + 2*K));
- #ifdef LIFE
- unsigned x, y, z;
- unsigned sum = 0;
- for (x = 0; x < sizex; x++)
- for (y = 0; y < sizey; y++)
- for (z = 0; z < size_bz; z++)
-
- sum += block->layers[0][(K+x)+(K+y)*(sizex + 2*K)+(K+z)*(sizex+2*K)*(sizey+2*K)] = (int)((x/7.+y/13.+(bz*size_bz + z)/17.) * 10.) % 2;
- #endif
- allocate_block_on_node(&block->layers_handle[1], &block->layers[1],
- (sizex + 2*K), (sizey + 2*K), (size_bz + 2*K));
- }
-
- unsigned top_node = block->boundary_blocks[T]->mpi_node;
- if ((node == rank) || (top_node == rank))
- {
- allocate_block_on_node(&block->boundaries_handle[T][0], &block->boundaries[T][0],
- (sizex + 2*K), (sizey + 2*K), K);
- allocate_block_on_node(&block->boundaries_handle[T][1], &block->boundaries[T][1],
- (sizex + 2*K), (sizey + 2*K), K);
- }
-
- unsigned bottom_node = block->boundary_blocks[B]->mpi_node;
- if ((node == rank) || (bottom_node == rank))
- {
- allocate_block_on_node(&block->boundaries_handle[B][0], &block->boundaries[B][0],
- (sizex + 2*K), (sizey + 2*K), K);
- allocate_block_on_node(&block->boundaries_handle[B][1], &block->boundaries[B][1],
- (sizex + 2*K), (sizey + 2*K), K);
- }
- }
- }
- void check(int rank)
- {
- unsigned bz;
- for (bz = 0; bz < nbz; bz++)
- {
- struct block_description *block = get_block_description(bz);
- unsigned node = block->mpi_node;
-
- if (node == rank)
- {
- unsigned size_bz = block_sizes_z[bz];
- #ifdef LIFE
- unsigned x, y, z;
- unsigned sum = 0;
- for (x = 0; x < sizex; x++)
- for (y = 0; y < sizey; y++)
- for (z = 0; z < size_bz; z++)
- sum += block->layers[0][(K+x)+(K+y)*(sizex + 2*K)+(K+z)*(sizex+2*K)*(sizey+2*K)];
- printf("block %d got %d/%d alive\n", bz, sum, sizex*sizey*size_bz);
- #endif
- }
- }
- }
|