MOAB: Mesh Oriented datABase  (version 5.4.1)
partcheck.cpp
Go to the documentation of this file.
00001 #include "moab/Core.hpp"
00002 #include "moab/Range.hpp"
00003 #include "moab/ParallelComm.hpp"
00004 #include "moab/Skinner.hpp"
00005 #include "moab/CN.hpp"
00006 
00007 #include <iostream>
00008 #include <sstream>
00009 #include <limits>
00010 #include <string>
00011 #include <ctime>
00012 
00013 #include "moab_mpi.h"
00014 
00015 const char PARTTAG[]           = "PARALLEL_PARTITION";
00016 const char READ_DEL_OPT[]      = "READ_DELETE";
00017 const char BCAST_DEL_OPT[]     = "BCAST_DELETE";
00018 const char READ_PART_OPT[]     = "READ_PART";
00019 const char* const DEFAULT_MODE = READ_PART_OPT;
00020 
00021 const char USAGE[] = " [-v <n>] [-R] [-p <parttag>[=val]] [-D|-B|-P] <input_file>";
00022 
00023 static void usage( const char* argv0 )
00024 {
00025     std::cerr << "Usage: " << argv0 << USAGE << std::endl << "       " << argv0 << " -h" << std::endl;
00026     exit( 1 );
00027 }
00028 
00029 static const char* defstr( const char* mode )
00030 {
00031     static const char s[] = " (default)";
00032     int len               = ( mode == DEFAULT_MODE ) ? 0 : sizeof( s ) - 1;
00033     return s + len;
00034 }
00035 
00036 static void help( const char* argv0 )
00037 {
00038     std::cout << "Usage: " << argv0 << USAGE << std::endl
00039               << "  -v  : debug output level (DEBUG_IO option)" << std::endl
00040               << "  -R  : do not resolve shared entities" << std::endl
00041               << "  -p  : partition tag, with optional '=' value" << std::endl
00042               << "          (default = \"" << PARTTAG << "\")" << std::endl
00043               << "  -D  : read mode as \"" << READ_DEL_OPT << "\"" << defstr( READ_DEL_OPT ) << std::endl
00044               << "  -B  : read mode as \"" << BCAST_DEL_OPT << "\"" << defstr( READ_DEL_OPT ) << std::endl
00045               << "  -P  : read mode as \"" << READ_PART_OPT << "\"" << defstr( READ_PART_OPT ) << std::endl;
00046     exit( 0 );
00047 }
00048 
00049 using namespace moab;
00050 
00051 int check_parallel_read( Interface& mb, ParallelComm* pcomm, bool shared_ents );
00052 
00053 int main( int argc, char* argv[] )
00054 {
00055     const char* read_mode_opt  = DEFAULT_MODE;
00056     const char* part_tag_opt   = PARTTAG;
00057     bool resolve_shared        = true;
00058     const char* input_file     = 0;
00059     const char* debug_flag_str = 0;
00060     bool no_more_flags         = false;
00061 
00062     MPI_Init( &argc, &argv );
00063 
00064     // process command line arguments
00065 
00066     for( int i = 1; i < argc; ++i )
00067     {
00068         if( !no_more_flags && argv[i][0] == '-' )
00069         {
00070             const char* opts = argv[i] + 1;
00071             for( int j = 0; opts[j]; ++j )
00072             {
00073                 switch( opts[j] )
00074                 {
00075                     case '-':
00076                         no_more_flags = true;
00077                         break;
00078                     case 'v':
00079                         if( ++i == argc ) usage( argv[0] );
00080                         debug_flag_str = argv[i];
00081                         break;
00082                     case 'R':
00083                         resolve_shared = false;
00084                         break;
00085                     case 'p':
00086                         if( ++i == argc ) usage( argv[0] );
00087                         part_tag_opt = argv[i];
00088                         break;
00089                     case 'D':
00090                         read_mode_opt = READ_DEL_OPT;
00091                         break;
00092                     case 'B':
00093                         read_mode_opt = BCAST_DEL_OPT;
00094                         break;
00095                     case 'P':
00096                         read_mode_opt = READ_PART_OPT;
00097                         break;
00098                     case 'h':
00099                         help( argv[0] );
00100                         break;
00101                     default:
00102                         usage( argv[0] );
00103                 }
00104             }
00105         }
00106         else if( !input_file )
00107         {
00108             input_file = argv[i];
00109         }
00110         else
00111         {
00112             usage( argv[0] );
00113         }
00114     }
00115 
00116     if( !input_file )
00117     {
00118         std::cerr << argv[0] << ": no input file specified" << std::endl;
00119         usage( argv[0] );
00120     }
00121 
00122     // build options string
00123 
00124     std::ostringstream opts;
00125     opts << "PARALLEL=" << read_mode_opt;
00126 
00127     std::string part_opt( part_tag_opt );
00128     size_t p = part_opt.find_last_of( '=' );
00129     if( p == std::string::npos )
00130     {
00131         opts << ";PARTITION=" << part_opt;
00132     }
00133     else
00134     {
00135         char* endptr = 0;
00136         long n       = strtol( part_opt.c_str() + p + 1, &endptr, 0 );
00137         if( *endptr || p == part_opt.size() - 1 )
00138         {
00139             std::cerr << "Warning: partition tag option contains an '=' followed "
00140                          "         by a non-integer value.  Assuming tag name is "
00141                          "         \""
00142                       << part_opt << "\"" << std::endl;
00143             opts << ";PARTITION=" << part_opt;
00144         }
00145         else
00146         {
00147             opts << ";PARTITION=" << part_opt.substr( 0, p );
00148             opts << ";PARTITION_VAL=" << n;
00149         }
00150     }
00151 
00152     if( resolve_shared )
00153     {
00154         opts << ";PARALLEL_RESOLVE_SHARED_ENTS";
00155     }
00156 
00157     if( debug_flag_str )
00158     {
00159         char* endptr = 0;
00160         long n       = strtol( debug_flag_str, &endptr, 0 );
00161         if( *endptr || n < 0 || !*debug_flag_str ) usage( argv[0] );
00162         opts << ";DEBUG_IO=" << n;
00163     }
00164 
00165     Core moab;
00166     Interface& mb       = moab;
00167     ParallelComm* pcomm = new ParallelComm( &mb, MPI_COMM_WORLD );
00168     if( pcomm->rank() == 0 )
00169         std::cout << "Loading file: \"" << input_file << "\" with options \"" << opts.str() << '"' << std::endl;
00170     opts << ";PARALLEL_COMM=" << pcomm->get_id();
00171 
00172     clock_t init_time = clock();
00173     ErrorCode rval    = mb.load_file( input_file, 0, opts.str().c_str() );
00174     if( MB_SUCCESS != rval )
00175     {
00176         std::cerr << input_file << " : file read failed (" << mb.get_error_string( rval ) << ")" << std::endl;
00177         return 1;
00178     }
00179 
00180     clock_t t = clock();
00181     double sec;
00182     if( t < init_time )
00183         sec =
00184             ( std::numeric_limits< clock_t >::max() - init_time ) / (double)CLOCKS_PER_SEC + t / (double)CLOCKS_PER_SEC;
00185     else
00186         sec = ( t - init_time ) / (double)CLOCKS_PER_SEC;
00187     double allsec;
00188     MPI_Reduce( &sec, &allsec, 1, MPI_DOUBLE, MPI_MAX, 0, pcomm->comm() );
00189     if( pcomm->rank() == 0 )
00190     {
00191         std::cout << "Read completed in " << allsec << " seconds" << std::endl;
00192     }
00193 
00194     int result = check_parallel_read( mb, pcomm, resolve_shared );
00195 
00196     if( MB_SUCCESS != pcomm->check_all_shared_handles( false ) ) ++result;
00197 
00198     MPI_Finalize();
00199     return result;
00200 }
00201 
00202 int check_parallel_read( Interface& mb, ParallelComm* pcomm, bool /*shared_ents*/ )
00203 {
00204     int error_count = 0;
00205 
00206     const Range& parts = pcomm->partition_sets();
00207     if( parts.empty() ) std::cout << "No parts for process " << pcomm->rank() << std::endl;
00208 
00209     // get all entities from parts
00210     Range part_ents;
00211     for( Range::iterator i = parts.begin(); i != parts.end(); ++i )
00212         mb.get_entities_by_handle( *i, part_ents );
00213 
00214     int dim = 3;
00215     if( part_ents.empty() )
00216         std::cout << "No partitioned entities for process " << pcomm->rank() << std::endl;
00217     else
00218     {
00219         dim = CN::Dimension( mb.type_from_handle( part_ents.back() ) );
00220         if( !part_ents.all_of_dimension( dim ) )
00221             std::cout << "Partitioned ents of mixed dimension for process " << pcomm->rank() << std::endl;
00222     }
00223 
00224     Range all_ents;
00225     mb.get_entities_by_dimension( 0, dim, all_ents );
00226     if( !subtract( all_ents, part_ents ).empty() )
00227     {
00228         std::cerr << "Process " << pcomm->rank() << " has entities of dimension " << dim
00229                   << " that are not contained in any part" << std::endl;
00230         ++error_count;
00231     }
00232 
00233     if( dim == 0 )
00234     {
00235         std::cout << "Skipping further tests because mesh is vertex-partitioned" << std::endl;
00236         return error_count;
00237     }
00238 
00239     Range part_verts;
00240     mb.get_connectivity( part_ents, part_verts );
00241     Range all_verts;
00242     mb.get_entities_by_dimension( 0, 0, all_verts );
00243     if( !subtract( all_verts, part_verts ).empty() )
00244     {
00245         std::cerr << "Process " << pcomm->rank() << " has vertices "
00246                   << " that are not contained in any partitioned element" << std::endl;
00247         ++error_count;
00248     }
00249 
00250     // if (!shared_ents) {
00251     //  std::cout << "Skipping further tests because shared entities were not resolved" <<
00252     //  std::endl; return error_count;
00253     //}
00254 
00255     return error_count;
00256 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines