[MOAB-dev] r3713 - MOAB/trunk/tools

kraftche at cae.wisc.edu kraftche at cae.wisc.edu
Thu Mar 25 16:53:00 CDT 2010


Author: kraftche
Date: 2010-03-25 16:53:00 -0500 (Thu, 25 Mar 2010)
New Revision: 3713

Modified:
   MOAB/trunk/tools/mbmem.cpp
Log:
Add test mode (-T) to mbmem.

Test mode prints memory statistics after incremental changes to the 
database.  The driver code does not end up calling into any external 
libraries (e.g. file I/O) or allocating any large chunks of memory.
This allows the output to be used to observe how MOAB's estimate of 
its memory use corresponds to the value reported by the system.



Modified: MOAB/trunk/tools/mbmem.cpp
===================================================================
--- MOAB/trunk/tools/mbmem.cpp	2010-03-25 21:43:10 UTC (rev 3712)
+++ MOAB/trunk/tools/mbmem.cpp	2010-03-25 21:53:00 UTC (rev 3713)
@@ -17,11 +17,13 @@
 void usage( const char* argv0 )
 {
   std::cerr << "Usage: " << argv0 << " [-h|-b|-k|-m] <filename> [<filename> ...]" << std::endl
+            << "Usage: " << argv0 << " [-h|-b|-k|-m] -T" << std::endl
             << "  -h : human readable units" << std::endl
             << "  -b : bytes" << std::endl
             << "  -k : kilobytes (1 kB == 1024 bytes)" << std::endl
             << "  -m : megabytes (1 MB == 1024 kB)" << std::endl
             << "  -g : gigabytes (1 GB == 1024 MB)" << std::endl
+            << "  -T : test mode" << std::endl
             << std::endl;
   std::exit(1);
 }
@@ -30,15 +32,22 @@
 Units UNITS = HUMAN;
 
   // The core functionality of this example
-void print_memory_stats( moab::Interface& mb );
+void print_memory_stats( moab::Interface& mb,
+                         bool per_type = true,
+                         bool per_tag = true,
+                         bool totals = true,
+                         bool sysstats = true );
   
+  // Generate a series of meshes for testing
+void do_test_mode();
+  
   // main routine: read any specified files and call print_memory_stats
 int main( int argc, char* argv[] )
 {
-  moab::Core mbcore;
-  moab::Interface& mb = mbcore;
   moab::ErrorCode rval;
   bool no_more_flags = false;
+  bool test_mode = false;
+  std::vector<int> input_file_list;
 
     // load each file specified on command line
   for (int i = 1; i < argc; ++i) {
@@ -53,23 +62,40 @@
         UNITS = MEGABYTES;
       else if(!strcmp(argv[i],"-g"))
         UNITS = GIGABYTES;
+      else if(!strcmp(argv[i],"-T"))
+        test_mode = true;
       else if(!strcmp(argv[i],"--"))
         no_more_flags = true;
       else
         usage(argv[0]);
     }
     else {
-      rval = mb.load_file(argv[i]);
+      input_file_list.push_back(i);
+    }
+  }
+  
+  if (test_mode) {
+    do_test_mode();
+    if (input_file_list.empty())
+      return 0;
+  }
 
-        // if file load failed, print some info and exit
-      if (moab::MB_SUCCESS != rval) {
-        std::string message;
-        mb.get_last_error( message );
-        std::cerr << mb.get_error_string(rval) << ": " << message << std::endl
-                  << argv[i] << ": Failed to read file." << std::endl;
-        return 1;
-      }
+  moab::Core mbcore;
+  moab::Interface& mb = mbcore;
+  for (std::vector<int>::iterator it = input_file_list.begin(); 
+       it != input_file_list.end(); ++it) {
+    rval = mb.load_file(argv[*it]);
+
+      // if file load failed, print some info and exit
+    if (moab::MB_SUCCESS != rval) {
+      std::string message;
+      mb.get_last_error( message );
+      std::cerr << mb.get_error_string(rval) << ": " << message << std::endl
+                << argv[*it] << ": Failed to read file." << std::endl;
+      return 1;
     }
+    
+    std::cout << "Loaded file: " << argv[*it] << std::endl;
   }
   
     // print summary of MOAB's memory use
@@ -110,7 +136,11 @@
   // Center
 std::string center( const char* str, size_t width );
 
-void print_memory_stats( moab::Interface& mb )
+void print_memory_stats( moab::Interface& mb,
+                         bool per_type,
+                         bool per_tag,
+                         bool totals,
+                         bool sysstats )
 {
   moab::ErrorCode rval;
   const char ANON_TAG_NAME[] = "(anonymous)";
@@ -123,152 +153,163 @@
 
     // per-entity-type table header
   MemStats stats;
-  std::cout.fill(' ');
-  std::cout << std::left << std::setw(TYPE_WIDTH) << "Type" << ' '
-            << center("Total",MEM2_WIDTH) << ' '
-            << center("Entity",MEM2_WIDTH) << ' '
-            << center("Adjacency",MEM2_WIDTH) << ' '
-            << center("Tag",MEM2_WIDTH) << ' '
-            << std::endl << std::setw(TYPE_WIDTH) << " ";
-  for (int i = 0; i < 4; ++i)
-    std::cout << ' ' << std::left << std::setw(MEM_WIDTH) << "Used"
-              << ' ' << std::left << std::setw(MEM_WIDTH) << "Alloc";
-  std::cout << std::endl;
-  std::cout.fill('-');
-  std::cout << std::setw(TYPE_WIDTH) << '-';
-  for (int i = 0; i < 8; ++i)
-    std::cout << ' ' << std::setw(MEM_WIDTH) << '-';
-  std::cout.fill(' ');
-  std::cout << std::endl;
   
-    // per-entity-type memory use
-  for (moab::EntityType t = moab::MBVERTEX; t != moab::MBMAXTYPE; ++t) {
-    get_mem_stats( mb, stats, t );
-    if (is_zero(stats)) continue;  // skip types with no allocated memory
-    
-    std::cout << std::left << std::setw(TYPE_WIDTH) << moab::CN::EntityTypeName(t) << ' '
-              << std::right << std::setw(MEM_WIDTH) << memstr(stats.total_storage) << ' '
-              << std::right << std::setw(MEM_WIDTH) << memstr(stats.total_amortized) << ' '
-              << std::right << std::setw(MEM_WIDTH) << memstr(stats.entity_storage) << ' '
-              << std::right << std::setw(MEM_WIDTH) << memstr(stats.entity_amortized) << ' '
-              << std::right << std::setw(MEM_WIDTH) << memstr(stats.adjacency_storage) << ' '
-              << std::right << std::setw(MEM_WIDTH) << memstr(stats.adjacency_amortized) << ' '
-              << std::right << std::setw(MEM_WIDTH) << memstr(stats.tag_storage) << ' '
-              << std::right << std::setw(MEM_WIDTH) << memstr(stats.tag_amortized) << std::endl;
-  }
+  if (per_type) {
   
-    // get list of tags
-  std::vector<moab::Tag> tags;
-  std::vector<moab::Tag>::const_iterator ti;
-  mb.tag_get_tags( tags );
-  
-    // figure out required field with to fit longest tag name 
-  unsigned maxlen = MIN_TAG_NAME_WIDTH;
-  for (ti = tags.begin(); ti != tags.end(); ++ti) {
-    std::string name;
-    rval = mb.tag_get_name( *ti, name );
-    if (moab::MB_SUCCESS != rval)
-      continue;
-    if (name.size() > maxlen)
-      maxlen = name.size();
-  }
-  
-    // print header for per-tag data
-  if (!tags.empty()) {
     std::cout.fill(' ');
-    std::cout << std::endl
-              << std::left << std::setw(maxlen) << "Tag Name" << ' '
-              << std::left << std::setw(DTYPE_WIDTH) << "Type" << ' '
-              << std::left << std::setw(STORAGE_WIDTH) << "Storage" << ' '
-              << std::left << std::setw(MEM_WIDTH) << "Used" << ' '
-              << std::left << std::setw(MEM_WIDTH) << "Alloc" << std::endl;
+    std::cout << std::left << std::setw(TYPE_WIDTH) << "Type" << ' '
+              << center("Total",MEM2_WIDTH) << ' '
+              << center("Entity",MEM2_WIDTH) << ' '
+              << center("Adjacency",MEM2_WIDTH) << ' '
+              << center("Tag",MEM2_WIDTH) << ' '
+              << std::endl << std::setw(TYPE_WIDTH) << " ";
+    for (int i = 0; i < 4; ++i)
+      std::cout << ' ' << std::left << std::setw(MEM_WIDTH) << "Used"
+                << ' ' << std::left << std::setw(MEM_WIDTH) << "Alloc";
+    std::cout << std::endl;
     std::cout.fill('-');
-    std::cout << std::setw(maxlen) << '-' << ' '
-              << std::setw(DTYPE_WIDTH) << '-' << ' '
-              << std::setw(STORAGE_WIDTH) << '-' << ' '
-              << std::setw(MEM_WIDTH) << '-' << ' '
-              << std::setw(MEM_WIDTH) << '-' << std::endl;
+    std::cout << std::setw(TYPE_WIDTH) << '-';
+    for (int i = 0; i < 8; ++i)
+      std::cout << ' ' << std::setw(MEM_WIDTH) << '-';
     std::cout.fill(' ');
-  }
-              
-    // print per-tag memory use
-  for (ti = tags.begin(); ti != tags.end(); ++ti) {
-    std::string name;
-    rval = mb.tag_get_name( *ti, name );
-    if (moab::MB_SUCCESS != rval || name.empty())
-      name = ANON_TAG_NAME;
-    
-    unsigned long occupied, allocated;
-    mb.estimated_memory_use( 0, 0, 0, 0, 0, 0, 0, 0, &*ti, 1, &occupied, &allocated );
-    
-    std::cout << std::left << std::setw(maxlen) << name << ' '
-              << std::right << std::setw(DTYPE_WIDTH) << tag_type_string(mb,*ti) <<  ' '
-              << std::right << std::setw(STORAGE_WIDTH) << tag_storage_string(mb,*ti) << ' '
-              << std::right << std::setw(MEM_WIDTH) << memstr(occupied) << ' '
-              << std::right << std::setw(MEM_WIDTH) << memstr(allocated) << std::endl;
-  }
+    std::cout << std::endl;
+
+      // per-entity-type memory use
+    for (moab::EntityType t = moab::MBVERTEX; t != moab::MBMAXTYPE; ++t) {
+      get_mem_stats( mb, stats, t );
+      if (is_zero(stats)) continue;  // skip types with no allocated memory
+
+      std::cout << std::left << std::setw(TYPE_WIDTH) << moab::CN::EntityTypeName(t) << ' '
+                << std::right << std::setw(MEM_WIDTH) << memstr(stats.total_storage) << ' '
+                << std::right << std::setw(MEM_WIDTH) << memstr(stats.total_amortized) << ' '
+                << std::right << std::setw(MEM_WIDTH) << memstr(stats.entity_storage) << ' '
+                << std::right << std::setw(MEM_WIDTH) << memstr(stats.entity_amortized) << ' '
+                << std::right << std::setw(MEM_WIDTH) << memstr(stats.adjacency_storage) << ' '
+                << std::right << std::setw(MEM_WIDTH) << memstr(stats.adjacency_amortized) << ' '
+                << std::right << std::setw(MEM_WIDTH) << memstr(stats.tag_storage) << ' '
+                << std::right << std::setw(MEM_WIDTH) << memstr(stats.tag_amortized) << std::endl;
+    }
+  } // end per_type
   
-    // print summary of overall memory use
-  get_mem_stats( mb, stats );
-  std::cout << std::endl
-            << "TOTAL: (Used/Allocated)" << std::endl
-            << "memory:    " << memstr(stats.total_storage) << "/" << memstr(stats.total_amortized) << std::endl
-            << "entity:    " << memstr(stats.entity_storage) << "/" << memstr(stats.entity_amortized) << std::endl
-            << "adjacency: " << memstr(stats.adjacency_storage) << "/" << memstr(stats.adjacency_amortized) << std::endl
-            << "tag:       " << memstr(stats.tag_storage) << "/" << memstr(stats.tag_amortized) << std::endl
-            << std::endl;
+  if (per_tag) {
+      // get list of tags
+    std::vector<moab::Tag> tags;
+    std::vector<moab::Tag>::const_iterator ti;
+    mb.tag_get_tags( tags );
 
-  std::FILE* filp = std::fopen("/proc/self/stat", "r");
-  unsigned long vsize, rss;
-  if (filp && 2 == std::fscanf(filp,
-                "%*d " // pid
-                "%*s " // comm
-                "%*c " // state
-                "%*d " // ppid
-                "%*d " // pgrp
-                "%*d " // session
-                "%*d " // tty_nr
-                "%*d " // tpgid
-                "%*u " // flags
-                "%*u " // minflt
-                "%*u " // cminflt
-                "%*u " // majflt
-                "%*u " // cmajflt
-                "%*u " // utime
-                "%*u " // stime
-                "%*d " // cutime
-                "%*d " // cstime
-                "%*d " // priority
-                "%*d " // nice
-                "%*d " // num_threads
-                "%*d " // itrealvalue
-                "%*u " // starttime
-                "%lu " // vsize
-                "%ld", // rss
-                &vsize, &rss )) {
-#ifndef _MSC_VER
-    rss *= getpagesize();
-#endif
-    std::cout << std::endl << "SYSTEM:" 
-              << std::endl << "Virtual memory:    " << memstr(vsize)
-              << std::endl << "Resident set size: " << memstr(rss)
+      // figure out required field with to fit longest tag name 
+    unsigned maxlen = MIN_TAG_NAME_WIDTH;
+    for (ti = tags.begin(); ti != tags.end(); ++ti) {
+      std::string name;
+      rval = mb.tag_get_name( *ti, name );
+      if (moab::MB_SUCCESS != rval)
+        continue;
+      if (name.size() > maxlen)
+        maxlen = name.size();
+    }
+
+      // print header for per-tag data
+    if (!tags.empty()) {
+      std::cout.fill(' ');
+      std::cout << std::endl
+                << std::left << std::setw(maxlen) << "Tag Name" << ' '
+                << std::left << std::setw(DTYPE_WIDTH) << "Type" << ' '
+                << std::left << std::setw(STORAGE_WIDTH) << "Storage" << ' '
+                << std::left << std::setw(MEM_WIDTH) << "Used" << ' '
+                << std::left << std::setw(MEM_WIDTH) << "Alloc" << std::endl;
+      std::cout.fill('-');
+      std::cout << std::setw(maxlen) << '-' << ' '
+                << std::setw(DTYPE_WIDTH) << '-' << ' '
+                << std::setw(STORAGE_WIDTH) << '-' << ' '
+                << std::setw(MEM_WIDTH) << '-' << ' '
+                << std::setw(MEM_WIDTH) << '-' << std::endl;
+      std::cout.fill(' ');
+    }
+
+      // print per-tag memory use
+    for (ti = tags.begin(); ti != tags.end(); ++ti) {
+      std::string name;
+      rval = mb.tag_get_name( *ti, name );
+      if (moab::MB_SUCCESS != rval || name.empty())
+        name = ANON_TAG_NAME;
+
+      unsigned long occupied, allocated;
+      mb.estimated_memory_use( 0, 0, 0, 0, 0, 0, 0, 0, &*ti, 1, &occupied, &allocated );
+
+      std::cout << std::left << std::setw(maxlen) << name << ' '
+                << std::right << std::setw(DTYPE_WIDTH) << tag_type_string(mb,*ti) <<  ' '
+                << std::right << std::setw(STORAGE_WIDTH) << tag_storage_string(mb,*ti) << ' '
+                << std::right << std::setw(MEM_WIDTH) << memstr(occupied) << ' '
+                << std::right << std::setw(MEM_WIDTH) << memstr(allocated) << std::endl;
+    }
+  } // end per_tag
+  
+  if (totals) {
+      // print summary of overall memory use
+    get_mem_stats( mb, stats );
+    std::cout << std::endl
+              << "TOTAL: (Used/Allocated)" << std::endl
+              << "memory:    " << memstr(stats.total_storage) << "/" << memstr(stats.total_amortized) << std::endl
+              << "entity:    " << memstr(stats.entity_storage) << "/" << memstr(stats.entity_amortized) << std::endl
+              << "adjacency: " << memstr(stats.adjacency_storage) << "/" << memstr(stats.adjacency_amortized) << std::endl
+              << "tag:       " << memstr(stats.tag_storage) << "/" << memstr(stats.tag_amortized) << std::endl
               << std::endl;
-  }
-  else {
-#ifndef _MSC_VER
-    struct rusage sysdata;
-    if (getrusage( RUSAGE_SELF, &sysdata )) {
-      std::cerr << "getrusage failed" << std::endl;
-    }
-    else {
-      unsigned long rss = sysdata.ru_maxrss;
+
+  } // end totals
+
+  if (sysstats) {
+    std::FILE* filp = std::fopen("/proc/self/stat", "r");
+    unsigned long vsize, rss;
+    if (filp && 2 == std::fscanf(filp,
+                  "%*d " // pid
+                  "%*s " // comm
+                  "%*c " // state
+                  "%*d " // ppid
+                  "%*d " // pgrp
+                  "%*d " // session
+                  "%*d " // tty_nr
+                  "%*d " // tpgid
+                  "%*u " // flags
+                  "%*u " // minflt
+                  "%*u " // cminflt
+                  "%*u " // majflt
+                  "%*u " // cmajflt
+                  "%*u " // utime
+                  "%*u " // stime
+                  "%*d " // cutime
+                  "%*d " // cstime
+                  "%*d " // priority
+                  "%*d " // nice
+                  "%*d " // num_threads
+                  "%*d " // itrealvalue
+                  "%*u " // starttime
+                  "%lu " // vsize
+                  "%ld", // rss
+                  &vsize, &rss )) {
+  #ifndef _MSC_VER
       rss *= getpagesize();
-      std::cerr << std::endl << "SYSTEM:"
-                << std::endl << "Resident set size: " << memstr(rss) 
+  #endif
+      std::cout << std::endl << "SYSTEM:" 
+                << std::endl << "Virtual memory:    " << memstr(vsize)
+                << std::endl << "Resident set size: " << memstr(rss)
                 << std::endl;
     }
-#endif
-  }
+    else {
+  #ifndef _MSC_VER
+      struct rusage sysdata;
+      if (getrusage( RUSAGE_SELF, &sysdata )) {
+        std::cerr << "getrusage failed" << std::endl;
+      }
+      else {
+        unsigned long rss = sysdata.ru_maxrss;
+        rss *= getpagesize();
+        std::cerr << std::endl << "SYSTEM:"
+                  << std::endl << "Resident set size: " << memstr(rss) 
+                  << std::endl;
+      }
+  #endif
+    }
+  } // end sysstats
 }
 
 
@@ -433,3 +474,137 @@
   return s.str();
 }
 
+void do_test_mode() 
+{
+  const char prefix[] = "****************";
+  moab::Core mbcore;
+  moab::Interface& mb = mbcore;
+  moab::ErrorCode rval;
+  moab::Range handles;
+  moab::EntityHandle h;
+  moab::Range::iterator jt, it;
+  const unsigned N = 1000;
+  
+  // creating some vertices
+  const double coords[3] = { 1, 2, 3 };
+  for (unsigned i = 0; i < N; ++i) 
+    mb.create_vertex( coords, h );
+  std::cout << std::endl << prefix << "Created " << N << " vertices" << std::endl;
+  print_memory_stats( mb, true, false, true, true );
+  
+  for (unsigned i = 0; i < N; ++i) 
+    mb.create_vertex( coords, h );
+  std::cout << std::endl << prefix << "Created another " << N << " vertices" << std::endl;
+  print_memory_stats( mb, true, false, true, true );
+  
+  for (int i = 0; i < 100; ++i) {      
+    for (unsigned j = 0; j < N; ++j) 
+      mb.create_vertex( coords, h );
+  }
+  std::cout << std::endl << prefix << "Created another " << 100*N << " vertices" << std::endl;
+  print_memory_stats( mb, true, false, true, true );
+  
+  // create some elements
+  handles.clear();
+  mb.get_entities_by_type( 0, moab::MBVERTEX, handles );
+  it = handles.begin();
+  for (unsigned i = 0; i < N-2; ++i, ++it) {
+    jt = it;
+    moab::EntityHandle conn[3];
+    conn[0] = *jt; ++jt;
+    conn[1] = *jt; ++jt;
+    conn[2] = *jt; ++jt;
+    mb.create_element( moab::MBTRI, conn, 3, h );
+  }
+  std::cout << std::endl << prefix << "Created " << N-2 << " triangles" << std::endl;
+  print_memory_stats( mb, true, false, true, true );
+  
+  it = handles.begin();
+  for (unsigned i = 0; i < N-3; ++i, ++it) {
+    jt = it;
+    moab::EntityHandle conn[4];
+    conn[0] = *jt; ++jt;
+    conn[1] = *jt; ++jt;
+    conn[2] = *jt; ++jt;
+    conn[3] = *jt; ++jt;
+    mb.create_element( moab::MBQUAD, conn, 4, h );
+  }
+  std::cout << std::endl << prefix << "Created " << N-3 << " quads" << std::endl;
+  print_memory_stats( mb, true, false, true, true );
+  
+  for (int i = 0; i < 100; ++i) {
+    it = handles.begin();
+    for (unsigned j = 0; j < N-3; ++j, ++it) {
+      jt = it;
+      moab::EntityHandle conn[4];
+      conn[0] = *jt; ++jt;
+      conn[1] = *jt; ++jt;
+      conn[2] = *jt; ++jt;
+      conn[3] = *jt; ++jt;
+      mb.create_element( moab::MBQUAD, conn, 4, h );
+    }
+  }
+  std::cout << std::endl << prefix << "Created another " << 100*(N-3) << " quads" << std::endl;
+  print_memory_stats( mb, true, false, true, true );
+
+  // set global ID
+  moab::Tag tag;
+  rval = mb.tag_get_handle( "GLOBAL_ID", tag );
+  if (moab::MB_SUCCESS != rval) {
+    std::cerr << "Failed to get GLOBAL_ID tag handle" << std::endl;
+    return;
+  }
+  handles.clear();
+  mb.get_entities_by_type( 0, moab::MBVERTEX, handles );
+  int id = 1;
+  for (it = handles.begin(); it != handles.end(); ++it) {
+    mb.tag_set_data( tag, &*it, 1, &id );
+    ++id;
+  }
+  std::cout << std::endl << prefix << "Set global ID tag on " << handles.size() << " vertices" << std::endl;
+  print_memory_stats( mb, true, true, true, true );
+  
+  handles.clear();
+  mb.get_entities_by_type( 0, moab::MBQUAD, handles );
+  id = 1;
+  for (it = handles.begin(); it != handles.end(); ++it) {
+    mb.tag_set_data( tag, &*it, 1, &id );
+    ++id;
+  }
+  std::cout << std::endl << prefix << "Set global ID tag on " << handles.size() << " quads" << std::endl;
+  print_memory_stats( mb, true, true, true, true );
+  
+  // create and set a sparse tag
+  mb.tag_create( "mem_test_tag", 3*sizeof(double), moab::MB_TAG_SPARSE, moab::MB_TYPE_DOUBLE, tag, 0 );
+  handles.clear();
+  mb.get_entities_by_type( 0, moab::MBVERTEX, handles );
+  for (it = handles.begin(); it != handles.end(); ++it) {
+    double coords[3];
+    mb.get_coords( &*it, 1, coords );
+    mb.tag_set_data( tag, &*it, 1, coords );
+  }
+  std::cout << std::endl << prefix << "Copied vertex coords to sparse tag for " << handles.size() << " vertices" << std::endl;
+  print_memory_stats( mb, true, true, true, true );
+  
+  // create and set bit tag
+  mb.tag_create( "mem_test_bit", 1, moab::MB_TAG_BIT, moab::MB_TYPE_BIT, tag, 0 );
+  handles.clear();
+  mb.get_entities_by_type( 0, moab::MBTRI, handles );
+  for (it = handles.begin(); it != handles.end(); ++it) {
+    char byte = '\001';
+    mb.tag_set_data( tag, &*it, 1, &byte );
+  }
+  std::cout << std::endl << prefix << "Set 1-bit tag for " << handles.size() << " triangles" << std::endl;
+  print_memory_stats( mb, true, true, true, true );
+  
+  // create vertex to element adjacency data
+  handles.clear();
+  mb.get_entities_by_type( 0, moab::MBVERTEX, handles );
+  std::vector<moab::EntityHandle> adj_vec;
+  mb.get_adjacencies( &*handles.begin(), 1, 2, false, adj_vec );
+  std::cout << std::endl << prefix << "Created vertex-to-element adjacencies" << std::endl;
+  print_memory_stats( mb, true, false, true, true );
+  std::cout << std::endl;
+}
+
+  



More information about the moab-dev mailing list