moab
ReduceExchangeTags.cpp
Go to the documentation of this file.
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 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines