LCOV - code coverage report
Current view: top level - src/parallel - ReadParallel.cpp (source / functions) Hit Total Coverage
Test: coverage_sk.info Lines: 229 370 61.9 %
Date: 2020-12-16 07:07:30 Functions: 8 8 100.0 %
Branches: 269 1255 21.4 %

           Branch data     Line data    Source code
       1                 :            : #include "ReadParallel.hpp"
       2                 :            : #include "moab/Core.hpp"
       3                 :            : #include "moab/ProcConfig.hpp"
       4                 :            : #include "moab/FileOptions.hpp"
       5                 :            : #include "moab/Error.hpp"
       6                 :            : #include "moab/ReaderWriterSet.hpp"
       7                 :            : #include "moab/ReadUtilIface.hpp"
       8                 :            : #include "moab/ParallelComm.hpp"
       9                 :            : #include "MBParallelConventions.h"
      10                 :            : 
      11                 :            : #include <iostream>
      12                 :            : #include <iomanip>
      13                 :            : #include <iterator>
      14                 :            : #include <sstream>
      15                 :            : #include <algorithm>
      16                 :            : #include <assert.h>
      17                 :            : 
      18                 :            : namespace moab
      19                 :            : {
      20                 :            : 
      21                 :            : const bool debug = false;
      22                 :            : 
      23                 :            : const char* ReadParallel::ParallelActionsNames[] = { "PARALLEL READ",
      24                 :            :                                                      "PARALLEL READ PART",
      25                 :            :                                                      "PARALLEL BROADCAST",
      26                 :            :                                                      "PARALLEL DELETE NONLOCAL",
      27                 :            :                                                      "PARALLEL CHECK_GIDS_SERIAL",
      28                 :            :                                                      "PARALLEL GET_FILESET_ENTS",
      29                 :            :                                                      "PARALLEL RESOLVE_SHARED_ENTS",
      30                 :            :                                                      "PARALLEL EXCHANGE_GHOSTS",
      31                 :            :                                                      "PARALLEL RESOLVE_SHARED_SETS",
      32                 :            :                                                      "PARALLEL_AUGMENT_SETS_WITH_GHOSTS",
      33                 :            :                                                      "PARALLEL PRINT_PARALLEL",
      34                 :            :                                                      "PARALLEL_CREATE_TRIVIAL_PARTITION",
      35                 :            :                                                      "PARALLEL_CORRECT_THIN_GHOST_LAYERS" };
      36                 :            : 
      37                 :            : const char* ReadParallel::parallelOptsNames[] = { "NONE", "BCAST", "BCAST_DELETE", "READ_DELETE", "READ_PART", "", 0 };
      38                 :            : 
      39                 :         21 : ReadParallel::ReadParallel( Interface* impl, ParallelComm* pc )
      40                 :         21 :     : mbImpl( impl ), myPcomm( pc ), myDebug( "ReadPara", std::cerr )
      41                 :            : {
      42         [ +  + ]:         21 :     if( !myPcomm )
      43                 :            :     {
      44         [ +  - ]:          2 :         myPcomm = ParallelComm::get_pcomm( mbImpl, 0 );
      45 [ -  + ][ #  # ]:          2 :         if( NULL == myPcomm ) myPcomm = new ParallelComm( mbImpl, MPI_COMM_WORLD );
                 [ #  # ]
      46                 :            :     }
      47 [ +  - ][ +  - ]:         21 :     myDebug.set_rank( myPcomm->proc_config().proc_rank() );
                 [ +  - ]
      48                 :            :     if( debug )  // For backwards compatibility, enable all debug output if constant is true
      49                 :            :         myDebug.set_verbosity( 10 );
      50                 :            : 
      51         [ +  - ]:         21 :     impl->query_interface( mError );
      52                 :         21 : }
      53                 :            : 
      54                 :         21 : ErrorCode ReadParallel::load_file( const char** file_names, const int num_files, const EntityHandle* file_set,
      55                 :            :                                    const FileOptions& opts, const ReaderIface::SubsetList* subset_list,
      56                 :            :                                    const Tag* file_id_tag )
      57                 :            : {
      58                 :            :     int tmpval;
      59 [ +  - ][ -  + ]:         21 :     if( MB_SUCCESS == opts.get_int_option( "DEBUG_PIO", 1, tmpval ) )
      60                 :            :     {
      61         [ #  # ]:          0 :         myDebug.set_verbosity( tmpval );
      62         [ #  # ]:          0 :         myPcomm->set_debug_verbosity( tmpval );
      63                 :            :     }
      64         [ +  - ]:         21 :     myDebug.tprint( 1, "Setting up...\n" );
      65                 :            : 
      66                 :            :     // Get parallel settings
      67                 :            :     int parallel_mode;
      68         [ +  - ]:         21 :     ErrorCode result = opts.match_option( "PARALLEL", parallelOptsNames, parallel_mode );
      69 [ -  + ][ #  # ]:         21 :     if( MB_FAILURE == result ) { MB_SET_ERR( MB_FAILURE, "Unexpected value for 'PARALLEL' option" ); }
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
      70         [ -  + ]:         21 :     else if( MB_ENTITY_NOT_FOUND == result )
      71                 :            :     {
      72                 :          0 :         parallel_mode = 0;
      73                 :            :     }
      74                 :            : 
      75                 :            :     // Get partition setting
      76                 :            :     bool distrib;
      77         [ +  - ]:         21 :     std::string partition_tag_name;
      78         [ +  - ]:         21 :     result = opts.get_option( "PARTITION", partition_tag_name );
      79         [ -  + ]:         21 :     if( MB_ENTITY_NOT_FOUND == result )
      80                 :            :     {
      81                 :          0 :         distrib            = false;
      82         [ #  # ]:          0 :         partition_tag_name = "";
      83                 :            :     }
      84                 :            :     else
      85                 :            :     {
      86                 :         21 :         distrib = true;
      87 [ -  + ][ #  # ]:         21 :         if( partition_tag_name.empty() ) partition_tag_name = PARALLEL_PARTITION_TAG_NAME;
      88                 :            : 
      89                 :            :         // Also get deprecated PARTITION_DISTRIBUTE option
      90                 :            :         // so that higher-level code doesn't return an error
      91                 :            :         // due to an unrecognized option
      92         [ +  - ]:         21 :         opts.get_null_option( "PARTITION_DISTRIBUTE" );
      93                 :            :     }
      94                 :            : 
      95                 :            :     // Get partition tag value(s), if any, and whether they're to be
      96                 :            :     // distributed or assigned
      97         [ +  - ]:         42 :     std::vector< int > partition_tag_vals;
      98         [ +  - ]:         21 :     opts.get_ints_option( "PARTITION_VAL", partition_tag_vals );
      99                 :            : 
     100                 :            :     // see if partition tag name is "TRIVIAL", if the tag exists
     101                 :         21 :     bool create_trivial_partition = false;
     102 [ +  - ][ +  - ]:         21 :     if( partition_tag_name == std::string( "TRIVIAL" ) )
                 [ -  + ]
     103                 :            :     {
     104                 :            :         Tag ttag;  // see if the trivial tag exists
     105         [ #  # ]:          0 :         result = mbImpl->tag_get_handle( partition_tag_name.c_str(), ttag );
     106         [ #  # ]:          0 :         if( MB_TAG_NOT_FOUND == result ) create_trivial_partition = true;
     107                 :            :     }
     108                 :            :     // See if we need to report times
     109                 :         21 :     bool cputime = false;
     110         [ +  - ]:         21 :     result       = opts.get_null_option( "CPUTIME" );
     111         [ -  + ]:         21 :     if( MB_SUCCESS == result ) cputime = true;
     112                 :            : 
     113                 :            :     // See if we need to report times
     114                 :         21 :     bool print_parallel = false;
     115         [ +  - ]:         21 :     result              = opts.get_null_option( "PRINT_PARALLEL" );
     116         [ -  + ]:         21 :     if( MB_SUCCESS == result ) print_parallel = true;
     117                 :            : 
     118                 :            :     // Get ghosting options
     119         [ +  - ]:         42 :     std::string ghost_str;
     120                 :         21 :     int bridge_dim, ghost_dim = -1, num_layers, addl_ents = 0;
     121         [ +  - ]:         21 :     result = opts.get_str_option( "PARALLEL_GHOSTS", ghost_str );
     122         [ -  + ]:         21 :     if( MB_TYPE_OUT_OF_RANGE == result )
     123                 :            :     {
     124                 :          0 :         ghost_dim  = 3;
     125                 :          0 :         bridge_dim = 0;
     126                 :          0 :         num_layers = 1;
     127                 :            :     }
     128         [ -  + ]:         21 :     else if( MB_SUCCESS == result )
     129                 :            :     {
     130                 :          0 :         int num_fields = sscanf( ghost_str.c_str(), "%d.%d.%d.%d", &ghost_dim, &bridge_dim, &num_layers, &addl_ents );
     131 [ #  # ][ #  # ]:          0 :         if( 3 > num_fields ) { MB_SET_ERR( MB_FAILURE, "Didn't read 3 fields from PARALLEL_GHOSTS string" ); }
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     132                 :            :     }
     133                 :            : 
     134                 :            :     // Get resolve_shared_ents option
     135         [ +  - ]:         42 :     std::string shared_str;
     136                 :         21 :     int resolve_dim = -2, shared_dim = -1;
     137         [ +  - ]:         21 :     result = opts.get_str_option( "PARALLEL_RESOLVE_SHARED_ENTS", shared_str );
     138         [ +  - ]:         21 :     if( MB_TYPE_OUT_OF_RANGE == result )
     139                 :            :     {
     140                 :         21 :         resolve_dim = -1;
     141                 :         21 :         shared_dim  = -1;
     142                 :            :     }
     143         [ #  # ]:          0 :     else if( MB_SUCCESS == result )
     144                 :            :     {
     145                 :          0 :         int num_fields = sscanf( shared_str.c_str(), "%d.%d", &resolve_dim, &shared_dim );
     146         [ #  # ]:          0 :         if( 2 != num_fields )
     147 [ #  # ][ #  # ]:          0 :         { MB_SET_ERR( MB_FAILURE, "Didn't read 2 fields from PARALLEL_RESOLVE_SHARED_ENTS string" ); }
         [ #  # ][ #  # ]
                 [ #  # ]
     148                 :            :     }
     149                 :            : 
     150                 :            :     // Get skip augmenting with ghosts option
     151                 :         21 :     bool skip_augment = false;
     152         [ +  - ]:         21 :     result            = opts.get_null_option( "SKIP_AUGMENT_WITH_GHOSTS" );
     153         [ -  + ]:         21 :     if( MB_SUCCESS == result ) skip_augment = true;
     154                 :            : 
     155                 :         21 :     bool correct_thin_ghosts = false;
     156         [ +  - ]:         21 :     result                   = opts.get_null_option( "PARALLEL_THIN_GHOST_LAYER" );
     157         [ -  + ]:         21 :     if( MB_SUCCESS == result ) correct_thin_ghosts = true;
     158                 :            : 
     159                 :            :     // Get MPI IO processor rank
     160                 :            :     int reader_rank;
     161         [ +  - ]:         21 :     result = opts.get_int_option( "MPI_IO_RANK", reader_rank );
     162         [ +  - ]:         21 :     if( MB_ENTITY_NOT_FOUND == result )
     163                 :         21 :         reader_rank = 0;
     164         [ #  # ]:          0 :     else if( MB_SUCCESS != result )
     165                 :            :     {
     166 [ #  # ][ #  # ]:          0 :         MB_SET_ERR( MB_FAILURE, "Unexpected value for 'MPI_IO_RANK' option" );
         [ #  # ][ #  # ]
                 [ #  # ]
     167                 :            :     }
     168                 :            : 
     169                 :            :     // Now that we've parsed all the parallel options, make an instruction queue
     170         [ +  - ]:         42 :     std::vector< int > pa_vec;
     171 [ +  - ][ +  - ]:         21 :     bool is_reader = ( reader_rank == (int)myPcomm->proc_config().proc_rank() );
     172                 :            : 
     173                 :         21 :     bool partition_by_rank = false;
     174 [ +  - ][ -  + ]:         21 :     if( MB_SUCCESS == opts.get_null_option( "PARTITION_BY_RANK" ) )
     175                 :            :     {
     176                 :          0 :         partition_by_rank = true;
     177         [ #  # ]:          0 :         if( !partition_tag_vals.empty() )
     178 [ #  # ][ #  # ]:          0 :         { MB_SET_ERR( MB_FAILURE, "Cannot specify both PARTITION_VALS and PARTITION_BY_RANK" ); }
         [ #  # ][ #  # ]
                 [ #  # ]
     179                 :            :     }
     180                 :            : 
     181                 :            :     double factor_seq;
     182 [ +  - ][ -  + ]:         21 :     if( MB_SUCCESS == opts.get_real_option( "PARALLEL_SEQUENCE_FACTOR", factor_seq ) )
     183                 :            :     {
     184 [ #  # ][ #  # ]:          0 :         if( factor_seq < 1. ) MB_SET_ERR( MB_FAILURE, "cannot have sequence factor less than 1." );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     185         [ #  # ]:          0 :         mbImpl->set_sequence_multiplier( factor_seq );
     186                 :            :     }
     187   [ -  -  +  +  :         21 :     switch( parallel_mode )
                      - ]
     188                 :            :     {
     189                 :            :         case POPT_BCAST:
     190         [ #  # ]:          0 :             myDebug.print( 1, "Read mode is BCAST\n" );
     191         [ #  # ]:          0 :             if( is_reader )
     192                 :            :             {
     193         [ #  # ]:          0 :                 pa_vec.push_back( PA_READ );
     194         [ #  # ]:          0 :                 pa_vec.push_back( PA_CHECK_GIDS_SERIAL );
     195         [ #  # ]:          0 :                 pa_vec.push_back( PA_GET_FILESET_ENTS );
     196                 :            :             }
     197         [ #  # ]:          0 :             pa_vec.push_back( PA_BROADCAST );
     198 [ #  # ][ #  # ]:          0 :             if( !is_reader ) pa_vec.push_back( PA_GET_FILESET_ENTS );
     199                 :          0 :             break;
     200                 :            : 
     201                 :            :         case POPT_BCAST_DELETE:
     202         [ #  # ]:          0 :             myDebug.print( 1, "Read mode is BCAST_DELETE\n" );
     203         [ #  # ]:          0 :             if( is_reader )
     204                 :            :             {
     205         [ #  # ]:          0 :                 pa_vec.push_back( PA_READ );
     206         [ #  # ]:          0 :                 pa_vec.push_back( PA_CHECK_GIDS_SERIAL );
     207         [ #  # ]:          0 :                 pa_vec.push_back( PA_GET_FILESET_ENTS );
     208 [ #  # ][ #  # ]:          0 :                 if( create_trivial_partition ) pa_vec.push_back( PA_CREATE_TRIVIAL_PARTITION );
     209                 :            :             }
     210         [ #  # ]:          0 :             pa_vec.push_back( PA_BROADCAST );
     211 [ #  # ][ #  # ]:          0 :             if( !is_reader ) pa_vec.push_back( PA_GET_FILESET_ENTS );
     212         [ #  # ]:          0 :             pa_vec.push_back( PA_DELETE_NONLOCAL );
     213                 :          0 :             break;
     214                 :            : 
     215                 :            :         case POPT_DEFAULT:
     216                 :            :         case POPT_READ_DELETE:
     217         [ +  - ]:         19 :             myDebug.print( 1, "Read mode is READ_DELETE\n" );
     218         [ +  - ]:         19 :             pa_vec.push_back( PA_READ );
     219         [ +  - ]:         19 :             pa_vec.push_back( PA_CHECK_GIDS_SERIAL );
     220         [ +  - ]:         19 :             pa_vec.push_back( PA_GET_FILESET_ENTS );
     221         [ +  - ]:         19 :             pa_vec.push_back( PA_DELETE_NONLOCAL );
     222                 :         19 :             break;
     223                 :            : 
     224                 :            :         case POPT_READ_PART:
     225         [ +  - ]:          2 :             myDebug.print( 1, "Read mode is READ_PART\n" );
     226         [ +  - ]:          2 :             pa_vec.push_back( PA_READ_PART );
     227                 :          2 :             break;
     228                 :            : 
     229                 :            :         default:
     230 [ #  # ][ #  # ]:          0 :             MB_SET_ERR( MB_FAILURE, "Unexpected parallel read mode" );
         [ #  # ][ #  # ]
                 [ #  # ]
     231                 :            :     }
     232                 :            : 
     233 [ +  - ][ +  - ]:         21 :     if( -2 != resolve_dim ) pa_vec.push_back( PA_RESOLVE_SHARED_ENTS );
     234                 :            : 
     235 [ -  + ][ #  # ]:         21 :     if( -1 != ghost_dim ) pa_vec.push_back( PA_EXCHANGE_GHOSTS );
     236                 :            : 
     237         [ +  - ]:         21 :     if( -2 != resolve_dim )
     238                 :            :     {
     239         [ +  - ]:         21 :         pa_vec.push_back( PA_RESOLVE_SHARED_SETS );
     240 [ -  + ][ #  # ]:         21 :         if( -1 != ghost_dim && !skip_augment ) pa_vec.push_back( PA_AUGMENT_SETS_WITH_GHOSTS );
                 [ #  # ]
     241 [ -  + ][ #  # ]:         21 :         if( -1 != ghost_dim && correct_thin_ghosts ) pa_vec.push_back( PA_CORRECT_THIN_GHOSTS );
                 [ #  # ]
     242                 :            :     }
     243                 :            : 
     244 [ -  + ][ #  # ]:         21 :     if( print_parallel ) pa_vec.push_back( PA_PRINT_PARALLEL );
     245                 :            : 
     246                 :            :     result = load_file( file_names, num_files, file_set, parallel_mode, partition_tag_name, partition_tag_vals, distrib,
     247                 :            :                         partition_by_rank, pa_vec, opts, subset_list, file_id_tag, reader_rank, cputime, resolve_dim,
     248 [ +  - ][ +  + ]:         21 :                         shared_dim, ghost_dim, bridge_dim, num_layers, addl_ents );MB_CHK_ERR( result );
         [ +  - ][ +  - ]
     249                 :            : 
     250 [ -  + ][ #  # ]:         19 :     if( parallel_mode == POPT_BCAST_DELETE && !is_reader ) opts.mark_all_seen();
                 [ #  # ]
     251                 :            : 
     252                 :         40 :     return MB_SUCCESS;
     253                 :            : }
     254                 :            : 
     255                 :         21 : ErrorCode ReadParallel::load_file( const char** file_names, const int num_files, const EntityHandle* file_set_ptr,
     256                 :            :                                    int /*parallel_mode*/, std::string& partition_tag_name,
     257                 :            :                                    std::vector< int >& partition_tag_vals, bool distrib, bool partition_by_rank,
     258                 :            :                                    std::vector< int >& pa_vec, const FileOptions& opts,
     259                 :            :                                    const ReaderIface::SubsetList* subset_list, const Tag* file_id_tag,
     260                 :            :                                    const int reader_rank, const bool cputime, const int resolve_dim,
     261                 :            :                                    const int shared_dim, const int ghost_dim, const int bridge_dim,
     262                 :            :                                    const int num_layers, const int addl_ents )
     263                 :            : {
     264                 :         21 :     ErrorCode result = MB_SUCCESS;
     265 [ -  + ][ #  # ]:         21 :     if( myPcomm == NULL ) myPcomm = new ParallelComm( mbImpl, MPI_COMM_WORLD );
                 [ #  # ]
     266                 :            : 
     267         [ +  - ]:         21 :     Range entities;
     268                 :         21 :     Tag file_set_tag = 0;
     269                 :         21 :     int other_sets   = 0;
     270         [ +  - ]:         21 :     ReaderWriterSet::iterator iter;
     271 [ +  - ][ +  - ]:         42 :     Range other_file_sets, file_sets;
     272         [ -  + ]:         21 :     Core* impl = dynamic_cast< Core* >( mbImpl );
     273                 :            : 
     274         [ +  - ]:         42 :     std::vector< double > act_times( pa_vec.size() + 1 );
     275                 :         21 :     std::vector< int >::iterator vit;
     276                 :            :     int i, j;
     277 [ +  - ][ +  - ]:         21 :     act_times[0] = MPI_Wtime();
     278                 :            : 
     279                 :            :     // Make a new set for the parallel read
     280                 :            :     EntityHandle file_set;
     281 [ +  + ][ -  + ]:         21 :     if( !file_set_ptr || !( *file_set_ptr ) )
     282                 :            :     {
     283 [ +  - ][ -  + ]:         19 :         result = mbImpl->create_meshset( MESHSET_SET, file_set );MB_CHK_SET_ERR( result, "Trouble creating file set" );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     284                 :            :     }
     285                 :            :     else
     286                 :          2 :         file_set = *file_set_ptr;
     287                 :            : 
     288                 :         21 :     bool i_read     = false;
     289                 :         21 :     Tag id_tag      = 0;
     290                 :         21 :     bool use_id_tag = false;
     291         [ +  - ]:         42 :     Range ents;
     292                 :            : 
     293 [ +  - ][ +  - ]:        135 :     for( i = 1, vit = pa_vec.begin(); vit != pa_vec.end(); ++vit, i++ )
                 [ +  + ]
     294                 :            :     {
     295                 :        116 :         ErrorCode tmp_result = MB_SUCCESS;
     296 [ +  - ][ +  +  :        116 :         switch( *vit )
          +  -  -  +  +  
          +  -  +  -  -  
                   -  - ]
     297                 :            :         {
     298                 :            :                 //==================
     299                 :            :             case PA_READ:
     300                 :         19 :                 i_read = true;
     301                 :            : 
     302         [ +  + ]:         38 :                 for( j = 0; j < num_files; j++ )
     303                 :            :                 {
     304         [ +  - ]:         19 :                     myDebug.tprintf( 1, "Reading file: \"%s\"\n", file_names[j] );
     305                 :            : 
     306                 :            :                     EntityHandle new_file_set;
     307 [ +  - ][ -  + ]:         19 :                     result = mbImpl->create_meshset( MESHSET_SET, new_file_set );MB_CHK_SET_ERR( result, "Trouble creating file set" );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     308         [ +  - ]:         19 :                     tmp_result = impl->serial_load_file( file_names[j], &new_file_set, opts, subset_list, file_id_tag );
     309         [ -  + ]:         19 :                     if( MB_SUCCESS != tmp_result ) break;
     310                 :            : 
     311                 :            :                     // Put the contents of each file set for the reader into the
     312                 :            :                     // file set for the parallel read
     313         [ -  + ]:         19 :                     assert( 0 != new_file_set );
     314         [ +  - ]:         19 :                     Range all_ents;
     315         [ +  - ]:         19 :                     tmp_result = mbImpl->get_entities_by_handle( new_file_set, all_ents );
     316         [ -  + ]:         19 :                     if( MB_SUCCESS != tmp_result ) break;
     317         [ +  - ]:         19 :                     all_ents.insert( new_file_set );
     318         [ +  - ]:         19 :                     tmp_result = mbImpl->add_entities( file_set, all_ents );
     319 [ -  + ][ +  - ]:         19 :                     if( MB_SUCCESS != tmp_result ) break;
     320                 :         19 :                 }
     321         [ -  + ]:         19 :                 if( MB_SUCCESS != tmp_result ) break;
     322                 :            : 
     323                 :            :                 // Mark the file set for this parallel reader
     324                 :            :                 tmp_result = mbImpl->tag_get_handle( "__file_set", 1, MB_TYPE_INTEGER, file_set_tag,
     325         [ +  - ]:         19 :                                                      MB_TAG_SPARSE | MB_TAG_CREAT );
     326         [ -  + ]:         19 :                 if( MB_SUCCESS != tmp_result ) break;
     327                 :            : 
     328         [ +  - ]:         19 :                 tmp_result = mbImpl->tag_set_data( file_set_tag, &file_set, 1, &other_sets );
     329                 :         19 :                 break;
     330                 :            : 
     331                 :            :                 //==================
     332                 :            :             case PA_READ_PART: {
     333         [ +  - ]:          2 :                 myDebug.tprintf( 1, "Reading file: \"%s\"\n", file_names[0] );
     334                 :            : 
     335                 :          2 :                 i_read = true;
     336         [ -  + ]:          2 :                 if( num_files != 1 )
     337 [ #  # ][ #  # ]:          0 :                 { MB_SET_ERR( MB_NOT_IMPLEMENTED, "Multiple file read not supported for READ_PART" ); }
         [ #  # ][ #  # ]
                 [ #  # ]
     338                 :            : 
     339                 :            :                 // If we're going to resolve shared entities, then we need
     340                 :            :                 // to ask the file reader to populate a tag with unique ids
     341                 :            :                 // (typically file ids/indices/whatever.)
     342 [ +  - ][ +  - ]:          2 :                 if( std::find( pa_vec.begin(), pa_vec.end(), PA_RESOLVE_SHARED_ENTS ) != pa_vec.end() )
                 [ +  - ]
     343                 :            :                 {
     344                 :          2 :                     use_id_tag = true;
     345         [ +  - ]:          2 :                     if( !file_id_tag )
     346                 :            :                     {
     347                 :            :                         // This tag is really used for resolving shared entities with crystal router
     348                 :            :                         // In the end, this is an identifier that gets converted to long
     349                 :            :                         // In hdf5 file reader, we also convert from hdf5 file id type to long
     350                 :            :                         tmp_result = mbImpl->tag_get_handle( "", sizeof( long ), MB_TYPE_OPAQUE, id_tag,
     351         [ +  - ]:          2 :                                                              MB_TAG_DENSE | MB_TAG_CREAT );
     352         [ -  + ]:          4 :                         if( MB_SUCCESS != tmp_result ) break;
     353                 :          2 :                         file_id_tag = &id_tag;
     354                 :            :                     }
     355                 :            :                 }
     356                 :            : 
     357                 :          2 :                 ReaderIface::IDTag parts = { partition_tag_name.c_str(), 0, 0 };
     358                 :            :                 ReaderIface::SubsetList sl;
     359                 :          2 :                 sl.num_parts = 0;
     360         [ +  - ]:          2 :                 int rank     = myPcomm->rank();
     361         [ -  + ]:          2 :                 if( partition_by_rank )
     362                 :            :                 {
     363         [ #  # ]:          0 :                     assert( partition_tag_vals.empty() );
     364                 :          0 :                     parts.tag_values     = &rank;
     365                 :          0 :                     parts.num_tag_values = 1;
     366                 :            :                 }
     367                 :            :                 else
     368                 :            :                 {
     369         [ +  - ]:          2 :                     sl.num_parts   = myPcomm->size();
     370         [ +  - ]:          2 :                     sl.part_number = myPcomm->rank();
     371         [ -  + ]:          2 :                     if( !partition_tag_vals.empty() )
     372                 :            :                     {
     373         [ #  # ]:          0 :                         parts.tag_values     = &partition_tag_vals[0];
     374                 :          0 :                         parts.num_tag_values = partition_tag_vals.size();
     375                 :            :                     }
     376                 :            :                 }
     377         [ +  - ]:          2 :                 std::vector< ReaderIface::IDTag > subset;
     378         [ -  + ]:          2 :                 if( subset_list )
     379                 :            :                 {
     380                 :            :                     std::vector< ReaderIface::IDTag > tmplist( subset_list->tag_list,
     381         [ #  # ]:          0 :                                                                subset_list->tag_list + subset_list->tag_list_length );
     382         [ #  # ]:          0 :                     tmplist.push_back( parts );
     383                 :          0 :                     subset.swap( tmplist );
     384         [ #  # ]:          0 :                     sl.tag_list        = &subset[0];
     385                 :          0 :                     sl.tag_list_length = subset.size();
     386                 :            :                 }
     387                 :            :                 else
     388                 :            :                 {
     389                 :          2 :                     sl.tag_list        = &parts;
     390                 :          2 :                     sl.tag_list_length = 1;
     391                 :            :                 }
     392         [ +  - ]:          2 :                 tmp_result = impl->serial_load_file( *file_names, &file_set, opts, &sl, file_id_tag );
     393         [ +  - ]:          2 :                 if( MB_SUCCESS != tmp_result ) break;
     394                 :            : 
     395         [ #  # ]:          0 :                 if( !partition_tag_name.empty() )
     396                 :            :                 {
     397                 :            :                     Tag part_tag;
     398         [ #  # ]:          0 :                     tmp_result = impl->tag_get_handle( partition_tag_name.c_str(), 1, MB_TYPE_INTEGER, part_tag );
     399         [ #  # ]:          0 :                     if( MB_SUCCESS != tmp_result ) break;
     400                 :            : 
     401                 :            :                     tmp_result = impl->get_entities_by_type_and_tag( file_set, MBENTITYSET, &part_tag, 0, 1,
     402 [ #  # ][ #  # ]:          2 :                                                                      myPcomm->partition_sets() );
                 [ -  + ]
     403                 :          0 :                 }
     404                 :            :             }
     405                 :          0 :             break;
     406                 :            : 
     407                 :            :                 //==================
     408                 :            :             case PA_GET_FILESET_ENTS:
     409         [ +  - ]:         19 :                 myDebug.tprint( 1, "Getting fileset entities.\n" );
     410                 :            : 
     411                 :            :                 // Get entities in the file set, and add actual file set to it;
     412                 :            :                 // mark the file set to make sure any receiving procs know which it is
     413         [ +  - ]:         19 :                 tmp_result = mbImpl->get_entities_by_handle( file_set, entities );
     414         [ -  + ]:         19 :                 if( MB_SUCCESS != tmp_result )
     415                 :            :                 {
     416         [ #  # ]:          0 :                     entities.clear();
     417                 :          0 :                     break;
     418                 :            :                 }
     419                 :            : 
     420                 :            :                 // Add actual file set to entities too
     421         [ +  - ]:         19 :                 entities.insert( file_set );
     422                 :         19 :                 break;
     423                 :            :                 //==================
     424                 :            :             case PA_CREATE_TRIVIAL_PARTITION: {
     425         [ #  # ]:          0 :                 myDebug.tprint( 1, "create trivial partition, for higher dim entities.\n" );
     426                 :            :                 // get high dim entities (2 or 3)
     427         [ #  # ]:          0 :                 Range hi_dim_ents = entities.subset_by_dimension( 3 );
     428 [ #  # ][ #  # ]:          0 :                 if( hi_dim_ents.empty() ) hi_dim_ents = entities.subset_by_dimension( 2 );
         [ #  # ][ #  # ]
     429 [ #  # ][ #  # ]:          0 :                 if( hi_dim_ents.empty() ) hi_dim_ents = entities.subset_by_dimension( 1 );
         [ #  # ][ #  # ]
     430 [ #  # ][ #  # ]:          0 :                 if( hi_dim_ents.empty() ) MB_SET_ERR( MB_FAILURE, "there are no elements of dim 1-3" );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     431                 :            : 
     432         [ #  # ]:          0 :                 size_t num_hi_ents     = hi_dim_ents.size();
     433         [ #  # ]:          0 :                 unsigned int num_parts = myPcomm->size();
     434                 :            : 
     435                 :            :                 // create first the trivial partition tag
     436                 :          0 :                 int dum_id = -1;
     437                 :            :                 Tag ttag;  // trivial tag
     438                 :            :                 tmp_result = mbImpl->tag_get_handle( partition_tag_name.c_str(), 1, MB_TYPE_INTEGER, ttag,
     439 [ #  # ][ #  # ]:          0 :                                                      MB_TAG_CREAT | MB_TAG_SPARSE, &dum_id );MB_CHK_SET_ERR( tmp_result, "Can't create trivial partition tag" );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     440                 :            : 
     441                 :            :                 // Compute the number of high dim entities on each part
     442                 :          0 :                 size_t nPartEnts = num_hi_ents / num_parts;
     443                 :            : 
     444                 :            :                 // Number of extra entities after equal split over parts
     445                 :          0 :                 int iextra          = num_hi_ents % num_parts;
     446         [ #  # ]:          0 :                 Range::iterator itr = hi_dim_ents.begin();
     447 [ #  # ][ #  # ]:          0 :                 for( int k = 0; k < (int)num_parts; k++ )
     448                 :            :                 {
     449                 :            :                     // create a mesh set, insert a subrange of entities
     450                 :            :                     EntityHandle part_set;
     451 [ #  # ][ #  # ]:          0 :                     tmp_result = mbImpl->create_meshset( MESHSET_SET, part_set );MB_CHK_SET_ERR( tmp_result, "Can't create part set" );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     452         [ #  # ]:          0 :                     entities.insert( part_set );
     453                 :            : 
     454 [ #  # ][ #  # ]:          0 :                     tmp_result = mbImpl->tag_set_data( ttag, &part_set, 1, &k );MB_CHK_SET_ERR( tmp_result, "Can't set trivial partition tag" );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     455         [ #  # ]:          0 :                     Range subrange;
     456                 :          0 :                     size_t num_ents_in_part = nPartEnts;
     457         [ #  # ]:          0 :                     if( i < iextra ) num_ents_in_part++;
     458 [ #  # ][ #  # ]:          0 :                     for( size_t i1 = 0; i1 < num_ents_in_part; i1++, itr++ )
     459 [ #  # ][ #  # ]:          0 :                         subrange.insert( *itr );
     460 [ #  # ][ #  # ]:          0 :                     tmp_result = mbImpl->add_entities( part_set, subrange );MB_CHK_SET_ERR( tmp_result, "Can't add entities to trivial part " << k );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     461         [ #  # ]:          0 :                     myDebug.tprintf( 1, "create trivial part %d with %lu entities \n", k, num_ents_in_part );
     462 [ #  # ][ #  # ]:          0 :                     tmp_result = mbImpl->add_entities( file_set, &part_set, 1 );MB_CHK_SET_ERR( tmp_result, "Can't add trivial part to file set " << k );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     463                 :          0 :                 }
     464                 :            :             }
     465                 :            : 
     466                 :          0 :             break;
     467                 :            :                 //==================
     468                 :            :             case PA_BROADCAST:
     469                 :            :                 // Do the actual broadcast; if single-processor, ignore error
     470         [ #  # ]:          0 :                 myDebug.tprint( 1, "Broadcasting mesh.\n" );
     471                 :            : 
     472 [ #  # ][ #  # ]:          0 :                 if( myPcomm->proc_config().proc_size() > 1 )
                 [ #  # ]
     473                 :            :                 {
     474         [ #  # ]:          0 :                     tmp_result = myPcomm->broadcast_entities( reader_rank, entities );
     475         [ #  # ]:          0 :                     if( MB_SUCCESS != tmp_result ) break;
     476                 :            :                 }
     477                 :            : 
     478                 :            :                 if( debug )
     479                 :            :                 {
     480                 :            :                     std::cerr << "Bcast done; entities:" << std::endl;
     481                 :            :                     mbImpl->list_entities( 0, 0 );
     482                 :            :                 }
     483                 :            : 
     484                 :            :                 // Add the received entities to this fileset if I wasn't the reader
     485 [ #  # ][ #  # ]:          0 :                 if( !i_read && MB_SUCCESS == tmp_result ) tmp_result = mbImpl->add_entities( file_set, entities );
                 [ #  # ]
     486                 :            : 
     487                 :          0 :                 break;
     488                 :            : 
     489                 :            :                 //==================
     490                 :            :             case PA_DELETE_NONLOCAL:
     491         [ +  - ]:         19 :                 myDebug.tprint( 1, "Deleting nonlocal entities.\n" );
     492                 :            : 
     493         [ +  - ]:         19 :                 tmp_result = delete_nonlocal_entities( partition_tag_name, partition_tag_vals, distrib, file_set );
     494                 :            :                 if( debug )
     495                 :            :                 {
     496                 :            :                     std::cerr << "Delete nonlocal done; entities:" << std::endl;
     497                 :            :                     mbImpl->list_entities( 0, 0 );
     498                 :            :                 }
     499                 :            : 
     500 [ +  - ][ +  - ]:         19 :                 if( MB_SUCCESS == tmp_result ) tmp_result = create_partition_sets( partition_tag_name, file_set );
     501                 :            : 
     502                 :         19 :                 break;
     503                 :            : 
     504                 :            :                 //==================
     505                 :            :             case PA_CHECK_GIDS_SERIAL:
     506         [ +  - ]:         19 :                 myDebug.tprint( 1, "Checking global IDs.\n" );
     507                 :            : 
     508         [ +  - ]:         19 :                 tmp_result = myPcomm->check_global_ids( file_set, 0, 1, true, false );
     509                 :         19 :                 break;
     510                 :            : 
     511                 :            :                 //==================
     512                 :            :             case PA_RESOLVE_SHARED_ENTS:
     513         [ +  - ]:         19 :                 myDebug.tprint( 1, "Resolving shared entities.\n" );
     514                 :            : 
     515 [ +  - ][ +  - ]:         19 :                 if( 1 == myPcomm->size() )
     516                 :         19 :                     tmp_result = MB_SUCCESS;
     517                 :            :                 else
     518                 :            :                     tmp_result =
     519 [ #  # ][ #  # ]:          0 :                         myPcomm->resolve_shared_ents( file_set, resolve_dim, shared_dim, use_id_tag ? file_id_tag : 0 );
     520         [ -  + ]:         19 :                 if( MB_SUCCESS != tmp_result ) break;
     521                 :            : 
     522                 :            : #ifndef NDEBUG
     523                 :            :                 // check number of owned vertices through pcomm's public interface
     524         [ +  - ]:         19 :                 tmp_result = mbImpl->get_entities_by_type( 0, MBVERTEX, ents );
     525         [ +  - ]:         19 :                 if( MB_SUCCESS == tmp_result )
     526         [ +  - ]:         19 :                     tmp_result = myPcomm->filter_pstatus( ents, PSTATUS_NOT_OWNED, PSTATUS_NOT );
     527         [ +  - ]:         19 :                 if( MB_SUCCESS == tmp_result )
     528         [ +  - ]:         19 :                     myDebug.tprintf( 1, "Proc %u reports %lu owned vertices.\n", myPcomm->proc_config().proc_rank(),
     529 [ +  - ][ +  - ]:         38 :                                      ents.size() );
                 [ +  - ]
     530                 :            : #endif
     531                 :         19 :                 break;
     532                 :            : 
     533                 :            :                 //==================
     534                 :            :             case PA_EXCHANGE_GHOSTS:
     535         [ #  # ]:          0 :                 myDebug.tprint( 1, "Exchanging ghost entities.\n" );
     536                 :            : 
     537                 :            :                 tmp_result = myPcomm->exchange_ghost_cells( ghost_dim, bridge_dim, num_layers, addl_ents, true, true,
     538         [ #  # ]:          0 :                                                             &file_set );
     539                 :          0 :                 break;
     540                 :            : 
     541                 :            :                 //==================
     542                 :            :             case PA_RESOLVE_SHARED_SETS:
     543         [ +  - ]:         19 :                 myDebug.tprint( 1, "Resolving shared sets.\n" );
     544                 :            : 
     545 [ +  - ][ +  - ]:         19 :                 if( 1 == myPcomm->size() )
     546                 :         19 :                     tmp_result = MB_SUCCESS;
     547                 :            :                 else
     548 [ #  # ][ #  # ]:          0 :                     tmp_result = myPcomm->resolve_shared_sets( file_set, use_id_tag ? file_id_tag : 0 );
     549                 :         19 :                 break;
     550                 :            : 
     551                 :            :                 //==================
     552                 :            :             case PA_AUGMENT_SETS_WITH_GHOSTS:
     553         [ #  # ]:          0 :                 myDebug.tprint( 1, "Augmenting sets with ghost entities.\n" );
     554                 :            : 
     555 [ #  # ][ #  # ]:          0 :                 if( 1 == myPcomm->size() )
     556                 :          0 :                     tmp_result = MB_SUCCESS;
     557                 :            :                 else
     558         [ #  # ]:          0 :                     tmp_result = myPcomm->augment_default_sets_with_ghosts( file_set );
     559                 :          0 :                 break;
     560                 :            :                 //==================
     561                 :            :             case PA_CORRECT_THIN_GHOSTS:
     562         [ #  # ]:          0 :                 myDebug.tprint( 1, "correcting thin ghost layers.\n" );
     563 [ #  # ][ #  # ]:          0 :                 if( 2 >= myPcomm->size() )  // it is a problem only for multi-shared entities
     564                 :          0 :                     tmp_result = MB_SUCCESS;
     565                 :            :                 else
     566         [ #  # ]:          0 :                     tmp_result = myPcomm->correct_thin_ghost_layers();
     567                 :          0 :                 break;
     568                 :            :             case PA_PRINT_PARALLEL:
     569         [ #  # ]:          0 :                 myDebug.tprint( 1, "Printing parallel information.\n" );
     570                 :            : 
     571         [ #  # ]:          0 :                 tmp_result = myPcomm->list_entities( 0, -1 );
     572                 :          0 :                 break;
     573                 :            : 
     574                 :            :                 //==================
     575                 :            :             default:
     576 [ #  # ][ #  # ]:          0 :                 MB_SET_ERR( MB_FAILURE, "Unexpected parallel action" );
         [ #  # ][ #  # ]
                 [ #  # ]
     577                 :            :         }  // switch (*vit)
     578                 :            : 
     579 [ +  + ][ +  - ]:        116 :         if( MB_SUCCESS != tmp_result ) { MB_SET_ERR( MB_FAILURE, "Failed in step " << ParallelActionsNames[*vit] ); }
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
     580                 :            : 
     581 [ -  + ][ #  # ]:        114 :         if( cputime ) act_times[i] = MPI_Wtime();
                 [ #  # ]
     582                 :            :     }  // for (i = 1, vit = pa_vec.begin(); vit != pa_vec.end(); ++vit, i++)
     583                 :            : 
     584         [ -  + ]:         19 :     if( use_id_tag )
     585                 :            :     {
     586 [ #  # ][ #  # ]:          0 :         result = mbImpl->tag_delete( id_tag );MB_CHK_SET_ERR( result, "Trouble deleting id tag" );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     587                 :            :     }
     588                 :            : 
     589         [ -  + ]:         19 :     if( cputime )
     590                 :            :     {
     591         [ #  # ]:          0 :         for( i = pa_vec.size(); i > 0; i-- )
     592 [ #  # ][ #  # ]:          0 :             act_times[i] -= act_times[i - 1];
     593                 :            : 
     594                 :            :         // Replace initial time with overall time
     595 [ #  # ][ #  # ]:          0 :         act_times[0] = MPI_Wtime() - act_times[0];
                 [ #  # ]
     596                 :            :         // Get the maximum over all procs
     597 [ #  # ][ #  # ]:          0 :         if( 0 != myPcomm->proc_config().proc_rank() )
                 [ #  # ]
     598                 :            :         {
     599         [ #  # ]:          0 :             MPI_Reduce( &act_times[0], 0, pa_vec.size() + 1, MPI_DOUBLE, MPI_MAX, 0,
     600 [ #  # ][ #  # ]:          0 :                         myPcomm->proc_config().proc_comm() );
                 [ #  # ]
     601                 :            :         }
     602                 :            :         else
     603                 :            :         {
     604                 :            : #if( MPI_VERSION >= 2 )
     605         [ #  # ]:          0 :             MPI_Reduce( MPI_IN_PLACE, &act_times[0], pa_vec.size() + 1, MPI_DOUBLE, MPI_MAX, 0,
     606 [ #  # ][ #  # ]:          0 :                         myPcomm->proc_config().proc_comm() );
                 [ #  # ]
     607                 :            : #else
     608                 :            :             // Note, extra comm-size allocation is required
     609                 :            :             std::vector< double > act_times_tmp( pa_vec.size() + 1 );
     610                 :            :             MPI_Reduce( &act_times[0], &act_times_tmp[0], pa_vec.size() + 1, MPI_DOUBLE, MPI_MAX, 0,
     611                 :            :                         myPcomm->proc_config().proc_comm() );
     612                 :            :             act_times = act_times_tmp;  // extra copy here too
     613                 :            : #endif
     614 [ #  # ][ #  # ]:          0 :             std::cout << "Parallel Read times: " << std::endl;
     615 [ #  # ][ #  # ]:          0 :             for( i = 1, vit = pa_vec.begin(); vit != pa_vec.end(); ++vit, i++ )
                 [ #  # ]
     616 [ #  # ][ #  # ]:          0 :                 std::cout << "  " << act_times[i] << " " << ParallelActionsNames[*vit] << std::endl;
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     617 [ #  # ][ #  # ]:          0 :             std::cout << "  " << act_times[0] << " PARALLEL TOTAL" << std::endl;
         [ #  # ][ #  # ]
                 [ #  # ]
     618                 :            :         }
     619                 :            :     }
     620                 :            : 
     621                 :         40 :     return MB_SUCCESS;
     622                 :            : }
     623                 :            : 
     624                 :         19 : ErrorCode ReadParallel::delete_nonlocal_entities( std::string& ptag_name, std::vector< int >& ptag_vals,
     625                 :            :                                                   bool distribute, EntityHandle file_set )
     626                 :            : {
     627         [ +  - ]:         19 :     Range partition_sets;
     628                 :            : 
     629                 :            :     Tag ptag;
     630 [ +  - ][ -  + ]:         19 :     ErrorCode result = mbImpl->tag_get_handle( ptag_name.c_str(), 1, MB_TYPE_INTEGER, ptag );MB_CHK_SET_ERR( result, "Failed getting tag handle in delete_nonlocal_entities" );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     631                 :            : 
     632 [ +  - ][ +  - ]:         19 :     result = mbImpl->get_entities_by_type_and_tag( file_set, MBENTITYSET, &ptag, NULL, 1, myPcomm->partition_sets() );MB_CHK_SET_ERR( result, "Failed to get sets with partition-type tag" );
         [ -  + ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     633                 :            : 
     634 [ +  - ][ +  - ]:         19 :     int proc_sz = myPcomm->proc_config().proc_size();
     635 [ +  - ][ +  - ]:         19 :     int proc_rk = myPcomm->proc_config().proc_rank();
     636                 :            : 
     637         [ -  + ]:         19 :     if( !ptag_vals.empty() )
     638                 :            :     {
     639                 :            :         // Values input, get sets with those values
     640         [ #  # ]:          0 :         Range tmp_sets;
     641 [ #  # ][ #  # ]:          0 :         std::vector< int > tag_vals( myPcomm->partition_sets().size() );
         [ #  # ][ #  # ]
     642 [ #  # ][ #  # ]:          0 :         result = mbImpl->tag_get_data( ptag, myPcomm->partition_sets(), &tag_vals[0] );MB_CHK_SET_ERR( result, "Failed to get tag data for partition vals tag" );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     643 [ #  # ][ #  # ]:          0 :         for( std::vector< int >::iterator pit = tag_vals.begin(); pit != tag_vals.end(); ++pit )
                 [ #  # ]
     644                 :            :         {
     645 [ #  # ][ #  # ]:          0 :             std::vector< int >::iterator pit2 = std::find( ptag_vals.begin(), ptag_vals.end(), *pit );
     646 [ #  # ][ #  # ]:          0 :             if( pit2 != ptag_vals.end() ) tmp_sets.insert( myPcomm->partition_sets()[pit - tag_vals.begin()] );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     647                 :            :         }
     648                 :            : 
     649 [ #  # ][ #  # ]:          0 :         myPcomm->partition_sets().swap( tmp_sets );
                 [ #  # ]
     650                 :            :     }
     651                 :            : 
     652         [ +  - ]:         19 :     if( distribute )
     653                 :            :     {
     654                 :            :         // For now, require that number of partition sets be greater
     655                 :            :         // than number of procs
     656 [ +  - ][ +  - ]:         19 :         if( myPcomm->partition_sets().size() < (unsigned int)proc_sz )
                 [ -  + ]
     657                 :            :         {
     658 [ #  # ][ #  # ]:          0 :             MB_SET_ERR( MB_FAILURE, "Too few parts; P = " << proc_rk << ", tag = " << ptag
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     659                 :            :                                                           << ", # sets = " << myPcomm->partition_sets().size() );
     660                 :            :         }
     661                 :            : 
     662         [ +  - ]:         19 :         Range tmp_sets;
     663                 :            :         // Distribute the partition sets
     664 [ +  - ][ +  - ]:         19 :         unsigned int num_sets     = myPcomm->partition_sets().size() / proc_sz;
     665 [ +  - ][ +  - ]:         19 :         unsigned int num_leftover = myPcomm->partition_sets().size() % proc_sz;
     666                 :         19 :         int begin_set             = 0;
     667         [ -  + ]:         19 :         if( proc_rk < (int)num_leftover )
     668                 :            :         {
     669                 :          0 :             num_sets++;
     670                 :          0 :             begin_set = num_sets * proc_rk;
     671                 :            :         }
     672                 :            :         else
     673                 :         19 :             begin_set = proc_rk * num_sets + num_leftover;
     674                 :            : 
     675         [ +  + ]:         38 :         for( unsigned int i = 0; i < num_sets; i++ )
     676 [ +  - ][ +  - ]:         19 :             tmp_sets.insert( myPcomm->partition_sets()[begin_set + i] );
                 [ +  - ]
     677                 :            : 
     678 [ +  - ][ +  - ]:         19 :         myPcomm->partition_sets().swap( tmp_sets );
     679                 :            :     }
     680                 :            : 
     681 [ +  - ][ +  - ]:         19 :     myDebug.print( 1, "My partition sets: ", myPcomm->partition_sets() );
     682                 :            : 
     683 [ +  - ][ -  + ]:         19 :     result = delete_nonlocal_entities( file_set );MB_CHK_ERR( result );
         [ #  # ][ #  # ]
     684                 :            : 
     685                 :         19 :     return MB_SUCCESS;
     686                 :            : }
     687                 :            : 
     688                 :         19 : ErrorCode ReadParallel::create_partition_sets( std::string& ptag_name, EntityHandle file_set )
     689                 :            : {
     690 [ +  - ][ +  - ]:         19 :     int proc_rk      = myPcomm->proc_config().proc_rank();
     691                 :         19 :     ErrorCode result = MB_SUCCESS;
     692                 :            : 
     693                 :            :     Tag ptag;
     694                 :            : 
     695                 :            :     // Tag the partition sets with a standard tag name
     696 [ -  + ][ #  # ]:         19 :     if( ptag_name.empty() ) ptag_name = PARALLEL_PARTITION_TAG_NAME;
     697                 :         19 :     bool tag_created = false;
     698                 :            :     result = mbImpl->tag_get_handle( ptag_name.c_str(), 1, MB_TYPE_INTEGER, ptag, MB_TAG_SPARSE | MB_TAG_CREAT, 0,
     699 [ +  - ][ -  + ]:         19 :                                      &tag_created );MB_CHK_SET_ERR( result, "Trouble getting PARALLEL_PARTITION tag" );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     700                 :            : 
     701         [ +  - ]:         19 :     if( !tag_created )
     702                 :            :     {
     703                 :            :         // This tag already exists; better check to see that tagged sets
     704                 :            :         // agree with this partition
     705         [ +  - ]:         19 :         Range tagged_sets;
     706                 :         19 :         int* proc_rk_ptr = &proc_rk;
     707                 :            :         result = mbImpl->get_entities_by_type_and_tag( file_set, MBENTITYSET, &ptag, (const void* const*)&proc_rk_ptr,
     708 [ +  - ][ -  + ]:         19 :                                                        1, tagged_sets );MB_CHK_SET_ERR( result, "Trouble getting tagged sets" );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     709 [ +  - ][ +  - ]:         19 :         if( !tagged_sets.empty() && tagged_sets != myPcomm->partition_sets() )
         [ +  - ][ +  - ]
         [ -  + ][ -  + ]
     710                 :            :         {
     711 [ #  # ][ #  # ]:          0 :             result = mbImpl->tag_delete_data( ptag, tagged_sets );MB_CHK_SET_ERR( result, "Trouble deleting data of PARALLEL_PARTITION tag" );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     712                 :            :         }
     713 [ +  - ][ +  - ]:         19 :         else if( tagged_sets == myPcomm->partition_sets() )
                 [ +  - ]
     714         [ -  + ]:         19 :             return MB_SUCCESS;
     715                 :            :     }
     716                 :            : 
     717                 :            :     // If we get here, we need to assign the tag
     718 [ #  # ][ #  # ]:          0 :     std::vector< int > values( myPcomm->partition_sets().size() );
                 [ #  # ]
     719 [ #  # ][ #  # ]:          0 :     for( unsigned int i = 0; i < myPcomm->partition_sets().size(); i++ )
                 [ #  # ]
     720         [ #  # ]:          0 :         values[i] = proc_rk;
     721 [ #  # ][ #  # ]:          0 :     result = mbImpl->tag_set_data( ptag, myPcomm->partition_sets(), &values[0] );MB_CHK_SET_ERR( result, "Trouble setting data to PARALLEL_PARTITION tag" );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     722                 :            : 
     723                 :         19 :     return MB_SUCCESS;
     724                 :            : }
     725                 :            : 
     726                 :         19 : ErrorCode ReadParallel::delete_nonlocal_entities( EntityHandle file_set )
     727                 :            : {
     728                 :            :     // Get partition entities and ents related to/used by those
     729                 :            :     // get ents in the partition
     730                 :            :     ReadUtilIface* read_iface;
     731         [ +  - ]:         19 :     mbImpl->query_interface( read_iface );
     732 [ +  - ][ +  - ]:         38 :     Range partition_ents, all_sets;
     733                 :            : 
     734         [ +  - ]:         19 :     myDebug.tprint( 2, "Gathering related entities.\n" );
     735                 :            : 
     736 [ +  - ][ +  - ]:         19 :     ErrorCode result = read_iface->gather_related_ents( myPcomm->partition_sets(), partition_ents, &file_set );MB_CHK_SET_ERR( result, "Failure gathering related entities" );
         [ -  + ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     737                 :            : 
     738                 :            :     // Get pre-existing entities
     739         [ +  - ]:         38 :     Range file_ents;
     740 [ +  - ][ -  + ]:         19 :     result = mbImpl->get_entities_by_handle( file_set, file_ents );MB_CHK_SET_ERR( result, "Couldn't get pre-existing entities" );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     741                 :            : 
     742 [ +  - ][ +  - ]:         19 :     if( 0 == myPcomm->proc_config().proc_rank() ) { myDebug.print( 2, "File entities: ", file_ents ); }
         [ +  - ][ +  - ]
     743                 :            : 
     744                 :            :     // Get deletable entities by subtracting partition ents from file ents
     745         [ +  - ]:         38 :     Range deletable_ents = subtract( file_ents, partition_ents );
     746                 :            : 
     747                 :            :     // Cache deletable vs. keepable sets
     748         [ +  - ]:         38 :     Range deletable_sets = deletable_ents.subset_by_type( MBENTITYSET );
     749 [ +  - ][ +  - ]:         38 :     Range keepable_sets  = subtract( file_ents.subset_by_type( MBENTITYSET ), deletable_sets );
     750                 :            : 
     751         [ +  - ]:         19 :     myDebug.tprint( 2, "Removing deletable entities from keepable sets.\n" );
     752                 :            : 
     753                 :            :     // Remove deletable ents from all keepable sets
     754 [ +  - ][ +  - ]:         76 :     for( Range::iterator rit = keepable_sets.begin(); rit != keepable_sets.end(); ++rit )
         [ +  - ][ +  - ]
                 [ +  + ]
     755                 :            :     {
     756 [ +  - ][ +  - ]:         57 :         result = mbImpl->remove_entities( *rit, deletable_ents );MB_CHK_SET_ERR( result, "Failure removing deletable entities" );
         [ -  + ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     757                 :            :     }
     758 [ +  - ][ -  + ]:         19 :     result = mbImpl->remove_entities( file_set, deletable_ents );MB_CHK_SET_ERR( result, "Failure removing deletable entities" );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     759                 :            : 
     760         [ +  - ]:         19 :     myDebug.tprint( 2, "Deleting deletable entities.\n" );
     761                 :            : 
     762 [ +  - ][ +  - ]:         19 :     if( 0 == myPcomm->proc_config().proc_rank() ) { myDebug.print( 2, "Deletable sets: ", deletable_sets ); }
         [ +  - ][ +  - ]
     763                 :            : 
     764                 :            :     // Delete sets, then ents
     765 [ +  - ][ -  + ]:         19 :     if( !deletable_sets.empty() )
     766                 :            :     {
     767 [ #  # ][ #  # ]:          0 :         result = mbImpl->delete_entities( deletable_sets );MB_CHK_SET_ERR( result, "Failure deleting sets in delete_nonlocal_entities" );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     768                 :            :     }
     769                 :            : 
     770         [ +  - ]:         19 :     deletable_ents -= deletable_sets;
     771                 :            : 
     772 [ +  - ][ +  - ]:         19 :     if( 0 == myPcomm->proc_config().proc_rank() ) { myDebug.print( 2, "Deletable entities: ", deletable_ents ); }
         [ +  - ][ +  - ]
     773                 :            : 
     774 [ +  - ][ -  + ]:         19 :     if( !deletable_ents.empty() )
     775                 :            :     {
     776 [ #  # ][ #  # ]:          0 :         result = mbImpl->delete_entities( deletable_ents );MB_CHK_SET_ERR( result, "Failure deleting entities in delete_nonlocal_entities" );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     777                 :            :     }
     778                 :            : 
     779                 :         38 :     return MB_SUCCESS;
     780                 :            : }
     781                 :            : 
     782 [ +  - ][ +  - ]:        228 : }  // namespace moab

Generated by: LCOV version 1.11