# getBlocksOfEntitiesPartition.c

Aller à la documentation de ce fichier.

    00001 /*  This file is part of MED.
    00002  *
    00003  *  COPYRIGHT (C) 1999 - 2012  EDF R&D, CEA/DEN
    00004  *  MED is free software: you can redistribute it and/or modify
    00005  *  it under the terms of the GNU Lesser General Public License as published by
    00006  *  the Free Software Foundation, either version 3 of the License, or
    00007  *  (at your option) any later version.
    00008  *
    00009  *  MED is distributed in the hope that it will be useful,
    00010  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
    00011  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    00012  *  GNU Lesser General Public License for more details.
    00013  *
    00014  *  You should have received a copy of the GNU Lesser General Public License
    00015  *  along with MED.  If not, see <http://www.gnu.org/licenses/>.
    00016  */
    00017
    00018
    00019 #include <med.h>
    00020 #define MESGERR 1
    00021 #include "med_utils.h"
    00022
    00023
    00024 #include "getBlocksOfEntitiesPartition.h"
    00025
    00026
    00027 void getContinuousBlocksOfEntities(const int myrank, const int nproc, const int nentities,
    00028                                     med_size * const start, med_size * const stride, med_size * const count, med_size * blocksize,
    00029                                     int * const lastusedrank, med_size * const lastblocksize ) {
    00030
    00031     int      _nusedproc      = nproc;
    00032     int      _lastusedrank   = 0;
    00033     med_size _blocksize      = nentities/nproc;
    00034     /* _nblocks_pproc vaut 1 ou 0 si l'on utilise pas tous les processus */
    00035     int      _nblocks_pproc  = 0;
    00036
    00037
    00038     /*Tant que la taille des blocks est nulle on diminue le
    00039       nombre de processus utilisé jusqu'au minimum d'un processus
    00040     */
    00041     for (; (_blocksize < 1) && ( _nusedproc > 1 ) ; ) {
    00042       SSCRUTE("NOT USING ALL PROCESS");
    00043       --_nusedproc;
    00044       _blocksize = nentities/_nusedproc;
    00045     }
    00046     _lastusedrank   = _nusedproc-1;
    00047
    00048     if ( myrank < _nusedproc)
    00049       _nblocks_pproc = 1;
    00050     else
    00051       _blocksize = 0;
    00052
    00053 /*     if ( _blocksize == 0 ) { */
    00054 /*       if (myrank == 0 ) { _nblocks_pproc=1;_blocksize=nentities;} */
    00055 /*       _lastusedrank = 0; */
    00056 /*       _nusedproc = 1; */
    00057 /*       _blocksize    = nentities; */ /*TODO : essayer de l'enlever maintenant : Ajouté pour symétrie des opération MPI_File, *count == 0*/
    00058 /*     } else { */
    00059 /*       _nblocks_pproc = 1; */
    00060 /*     } */
    00061
    00062     *start         = myrank*_nblocks_pproc*_blocksize;
    00063     *stride        = _blocksize;
    00064     *count         = _nblocks_pproc;
    00065     *lastblocksize = 0;
    00066
    00067     if ( myrank == _lastusedrank ) {
    00068       *blocksize = nentities+_blocksize*(1-_nusedproc);
    00069     } else {
    00070       *blocksize =_blocksize;
    00071     }
    00072     ++(*start);
    00073     *lastusedrank=_lastusedrank;
    00074     printf("My rank %d , start %l , stride %l , blocksize %l , count %l , lastblocksize %l\n",
    00075            myrank,*start,*stride,*blocksize,*count,*lastblocksize);
    00076     return;
    00077 }
    00078
    00079 void getCyclicBlocksOfEntities(const int myrank, const int nproc, const int nentities,
    00080                                med_size * const start, med_size * const stride,  med_size * const io_count, med_size * blocksize,
    00081                                int * const lastusedrank, med_size * const lastblocksize ) {
    00082
    00083     int      _nusedproc      = nproc;
    00084     int      _lastusedrank   = nproc-1;
    00085     int      _nblocks_pproc  = *io_count;
    00086     int      _nblocks        = _nblocks_pproc*nproc;
    00087     med_size _blocksize      = 0;
    00088
    00089     if (_nblocks) _blocksize=nentities/_nblocks;
    00090
    00091     /*Tant que la taille des block est nulle on diminue le
    00092      nombre de blocks affecté par processus jusqu'au minimum
    00093      d'un block par processus
    00094     */
    00095     for (; (_blocksize < 1) && ( _nblocks_pproc > 1 ) ; ) {
    00096       --_nblocks_pproc;
    00097       _nblocks   = _nblocks_pproc*nproc;
    00098       _blocksize = nentities/_nblocks;
    00099     }
    00100
    00101 /*     ISCRUTE(_nblocks_pproc); */
    00102 /*     ISCRUTE(_blocksize); */
    00103
    00104     /*Si la taille des blocks est toujours nulle,
    00105       c'est qu'il y a trop de processus pour le nombre d'entités :
    00106       -> On effectue alors une répartition par block contigüs qui prend
    00107       en compte la possible non affectation de certains processus.
    00108     */
    00109     if ( _blocksize == 0 ) {
    00110       MESSAGE("Downcasting getCyclicBlocksOfEntities to getContinuousBlocksOfEntities");
    00111       getContinuousBlocksOfEntities(myrank, nproc, nentities,
    00112                                     start, stride, io_count, blocksize, lastusedrank, lastblocksize );
    00113       return;
    00114     }
    00115
    00116     /* A partir d'ici on est en mesure de calculer une répartition cyclique par block*/
    00117     *blocksize     = _blocksize;
    00118     *stride        = _blocksize*nproc;
    00119     *start         = _blocksize*myrank;
    00120     *io_count      = _nblocks_pproc;
    00121
    00122     if (myrank == _lastusedrank) {
    00123       *lastblocksize = nentities + _blocksize*(1-nproc*_nblocks_pproc);
    00124       /*Dans le cas _nblocks_pproc==1 on a en fait une répartition contigüe des blocks
    00125        lastblocksize vaut alors 0 car il n'est pas utilisé.*/
    00126       if ( _nblocks_pproc == 1 ) {*blocksize=*lastblocksize;*lastblocksize=0;}
    00127     } else
    00128       *lastblocksize=0;
    00129
    00130     ++(*start);
    00131     *lastusedrank=_lastusedrank;
    00132 /*     printf("My rank %d, start %d, stride %d, blocksize %d, io_count %d, lastblocksize %d\n",myrank,*start,*stride,*blocksize,*io_count,*lastblocksize); */
    00133     return;
    00134 }
    00135
    00136
    00137
    00138
    00139
    00140