moab
|
00001 00028 #include "moab/ParallelComm.hpp" 00029 #include "MBParallelConventions.h" 00030 #include "moab/Core.hpp" 00031 #include <iostream> 00032 #include <string> 00033 #include <sstream> 00034 00035 using namespace moab; 00036 00037 // Error routines for use with MOAB API 00038 #define CHKERR(CODE, MSG) \ 00039 do { \ 00040 if (MB_SUCCESS != (CODE)) { \ 00041 std::string errstr; mbi->get_last_error(errstr); \ 00042 std::cerr << errstr << std::endl; \ 00043 std::cerr << MSG << std::endl; \ 00044 MPI_Finalize(); \ 00045 } \ 00046 } while(false) 00047 00048 // Error routines for use with MPI API 00049 #define MPICHKERR(CODE, MSG) \ 00050 do { \ 00051 if (0 != CODE) { \ 00052 std::cerr << MSG << std::endl; \ 00053 MPI_Finalize(); \ 00054 } \ 00055 } while(false) 00056 00057 #define dbgprint(MSG) \ 00058 do { \ 00059 if (!rank) std::cerr << MSG << std::endl; \ 00060 } while(false) 00061 00062 #define dbgprintall(MSG) \ 00063 do { \ 00064 std::cerr << "[" << rank << "]: " << MSG << std::endl; \ 00065 } while(false) 00066 00067 00068 // Function to parse input parameters 00069 ErrorCode get_file_options(int argc, char **argv, 00070 std::string& filename, 00071 std::string& tagName, 00072 double& tagValues) 00073 { 00074 // get mesh filename 00075 if (argc > 1) filename = std::string(argv[1]); 00076 else filename = std::string(MESH_DIR) + std::string("/64bricks_1khex.h5m"); 00077 00078 // get tag selection options 00079 if (argc > 2) tagName = std::string(argv[2]); 00080 else tagName = "USERTAG"; 00081 00082 if (argc > 3) tagValues = atof(argv[3]); 00083 else tagValues = 1.0; 00084 00085 return MB_SUCCESS; 00086 } 00087 00088 // 00089 // Start of main test program 00090 // 00091 int main(int argc, char **argv) 00092 { 00093 ErrorCode err; 00094 int ierr, rank; 00095 std::string filename, tagName; 00096 double tagValue; 00097 MPI_Comm comm = MPI_COMM_WORLD; 00107 std::string read_options = "PARALLEL=READ_PART;PARTITION=PARALLEL_PARTITION;PARALLEL_RESOLVE_SHARED_ENTS;PARTITION_DISTRIBUTE;PARALLEL_GHOSTS=3.0.1;PARALLEL_COMM=0"; 00108 00109 // Print usage if not enough arguments 00110 if (argc < 1) { 00111 std::cerr << "Usage: "; 00112 std::cerr << argv[0] << " <file_name> <tag_name> <tag_value>" << std::endl; 00113 std::cerr << "file_name : mesh file name" << std::endl; 00114 std::cerr << "tag_name : name of tag to add to mesh" << std::endl; 00115 std::cerr << "tag_value : a double valued string to set for highest-dimensional entities in the mesh for the named tag" << std::endl; 00116 00117 ierr = MPI_Finalize(); 00118 MPICHKERR(ierr, "MPI_Finalize failed; Aborting"); 00119 00120 return 1; 00121 } 00122 00123 // Initialize MPI first 00124 ierr = MPI_Init(&argc, &argv); 00125 MPICHKERR(ierr, "MPI_Init failed"); 00126 00127 ierr = MPI_Comm_rank(MPI_COMM_WORLD, &rank); 00128 MPICHKERR(ierr, "MPI_Comm_rank failed"); 00129 00130 dbgprint( "********** reduce_exchange_tags **********\n" ); 00131 00132 // Create the moab instance 00133 Interface *mbi = new Core(); 00134 CHKERR(NULL == mbi, "MOAB constructor failed"); 00135 00136 // Get the input options 00137 err = get_file_options(argc, argv, filename, tagName, tagValue); 00138 CHKERR(err, "get_file_options failed"); 00139 00140 // Print out the input parameters 00141 dbgprint( " Input Parameters - " ); 00142 dbgprint( " Filenames: " << filename ); 00143 dbgprint( " Tag: Name=" << tagName << " Value=" << tagValue << std::endl ); 00144 00145 // Create root sets for each mesh. Then pass these 00146 // to the load_file functions to be populated. 00147 EntityHandle rootset, partnset; 00148 err = mbi->create_meshset(MESHSET_SET, rootset); 00149 CHKERR(err, "Creating root set failed"); 00150 err = mbi->create_meshset(MESHSET_SET, partnset); 00151 CHKERR(err, "Creating partition set failed"); 00152 00153 // Create the parallel communicator object with the partition handle associated with MOAB 00154 ParallelComm *parallel_communicator = ParallelComm::get_pcomm( mbi, partnset, &comm ); 00155 00156 // Load the file from disk with given options 00157 err = mbi->load_file( filename.c_str(), &rootset, read_options.c_str() ); 00158 CHKERR(err, "MOAB::load_file failed"); 00159 00160 // Create two tag handles: Exchange and Reduction operations 00161 dbgprint( "-Creating tag handle " << tagName << "..." ); 00162 Tag tagReduce, tagExchange; 00163 { 00164 std::stringstream sstr; 00165 // Create the exchange tag: default name = USERTAG_EXC 00166 sstr << tagName << "_EXC"; 00167 err = mbi->tag_get_handle(sstr.str().c_str(), 1, MB_TYPE_INTEGER, tagExchange, MB_TAG_CREAT|MB_TAG_DENSE, &tagValue); 00168 CHKERR(err, "Retrieving tag handles failed"); 00169 00170 // Create the exchange tag: default name = USERTAG_RED 00171 sstr.str(""); sstr << tagName << "_RED"; 00172 err = mbi->tag_get_handle(sstr.str().c_str(), 1, MB_TYPE_DOUBLE, tagReduce, MB_TAG_CREAT|MB_TAG_DENSE, &tagValue); 00173 CHKERR(err, "Retrieving tag handles failed"); 00174 } 00175 00176 // Perform exchange tag data 00177 dbgprint( "-Exchanging tags between processors " ); 00178 { 00179 Range partEnts, dimEnts; 00180 for (int dim = 0; dim <= 3; dim++) { 00181 // Get all entities of dimension = dim 00182 err = mbi->get_entities_by_dimension(rootset, dim, dimEnts, false); 00183 00184 std::vector<int> tagValues(dimEnts.size(), static_cast<int>(tagValue)*(rank+1)*(dim+1)); 00185 // Set local tag data for exchange 00186 err = mbi->tag_set_data(tagExchange, dimEnts, &tagValues[0]); 00187 CHKERR(err, "Setting local tag data failed during exchange phase"); 00188 // Merge entities into parent set 00189 partEnts.merge(dimEnts); 00190 } 00191 00192 // Exchange tags between processors 00193 err = parallel_communicator->exchange_tags(tagExchange, partEnts); 00194 CHKERR(err, "Exchanging tags between processors failed"); 00195 } 00196 00197 // Perform reduction of tag data 00198 dbgprint( "-Reducing tags between processors " ); 00199 { 00200 Range partEnts; 00201 // Get all higher dimensional entities belonging to current partition 00202 err = parallel_communicator->get_part_entities(partEnts); 00203 CHKERR(err, "ParallelComm::get_part_entities failed"); 00204 00205 // Output what is in current partition sets 00206 dbgprintall( "Number of Partitioned entities: " << partEnts.size() ); 00207 MPI_Barrier(comm); 00208 00209 // Set local tag data for reduction 00210 std::vector<double> tagValues(partEnts.size(), tagValue*(rank+1)); 00211 err = mbi->tag_set_data(tagReduce, partEnts, &tagValues[0]); 00212 CHKERR(err, "Setting local tag data failed during reduce phase"); 00213 00214 Range dummy; 00215 // Reduce tag data using MPI_SUM on the interface between partitions 00216 err = parallel_communicator->reduce_tags(tagReduce, MPI_SUM, dummy/*partEnts*/); 00217 CHKERR(err, "Reducing tags between processors failed"); 00218 } 00219 // Write out to output file to visualize reduction/exchange of tag data 00220 mbi->write_file("test.h5m", "H5M", "PARALLEL=WRITE_PART"); 00221 00222 // Done, cleanup 00223 delete mbi; 00224 00225 dbgprint( "\n********** reduce_exchange_tags DONE! **********" ); 00226 MPI_Finalize(); 00227 return 0; 00228 }