[MOAB-dev] r3709 - in MOAB/trunk: . tools
kraftche at cae.wisc.edu
kraftche at cae.wisc.edu
Thu Mar 25 11:56:32 CDT 2010
Author: kraftche
Date: 2010-03-25 11:56:32 -0500 (Thu, 25 Mar 2010)
New Revision: 3709
Added:
MOAB/trunk/tools/mbmem.cpp
Modified:
MOAB/trunk/configure.ac
MOAB/trunk/tools/Makefile.am
Log:
add tool to read in a file and print moab memory usage stats
Modified: MOAB/trunk/configure.ac
===================================================================
--- MOAB/trunk/configure.ac 2010-03-24 21:09:22 UTC (rev 3708)
+++ MOAB/trunk/configure.ac 2010-03-25 16:56:32 UTC (rev 3709)
@@ -470,6 +470,7 @@
MB_OPTIONAL_TOOL([mbsize], [yes])
MB_OPTIONAL_TOOL([mbskin], [yes])
MB_OPTIONAL_TOOL([mbtagprop], [yes])
+MB_OPTIONAL_TOOL([mbmem], [yes])
MB_OPTIONAL_TOOL([mcnpmit], [no])
MB_OPTIONAL_TOOL([mbcoupler], [$ENABLE_mcnpmit] )
MB_OPTIONAL_TOOL([spheredecomp], [yes])
Modified: MOAB/trunk/tools/Makefile.am
===================================================================
--- MOAB/trunk/tools/Makefile.am 2010-03-24 21:09:22 UTC (rev 3708)
+++ MOAB/trunk/tools/Makefile.am 2010-03-25 16:56:32 UTC (rev 3709)
@@ -53,6 +53,10 @@
doc_DATA += README.mbtagprop
endif
+if ENABLE_mbmem
+ bin_PROGRAMS += mbmem
+endif
+
if ENABLE_spheredecomp
bin_PROGRAMS += spheredecomp
doc_DATA += README.spheredecomp
Added: MOAB/trunk/tools/mbmem.cpp
===================================================================
--- MOAB/trunk/tools/mbmem.cpp (rev 0)
+++ MOAB/trunk/tools/mbmem.cpp 2010-03-25 16:56:32 UTC (rev 3709)
@@ -0,0 +1,435 @@
+#include "moab/Core.hpp"
+#include "moab/Range.hpp"
+#include "moab/CN.hpp"
+
+#include <iostream>
+#include <iomanip>
+#include <sstream>
+#include <string>
+#include <cstdio>
+#include <cstdlib>
+
+#ifndef _MSC_VER
+#include <sys/times.h>
+#include <sys/resource.h>
+#endif
+
+void usage( const char* argv0 )
+{
+ std::cerr << "Usage: " << argv0 << " [-h|-b|-k|-m] <filename> [<filename> ...]" << 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
+ << std::endl;
+ std::exit(1);
+}
+
+enum Units { HUMAN, BYTES, KILOBYTES, MEGABYTES, GIGABYTES };
+Units UNITS = HUMAN;
+
+ // The core functionality of this example
+void print_memory_stats( moab::Interface& mb );
+
+ // 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;
+
+ // load each file specified on command line
+ for (int i = 1; i < argc; ++i) {
+ if (!no_more_flags && argv[i][0] == '-') {
+ if (!strcmp(argv[i],"-h"))
+ UNITS = HUMAN;
+ else if(!strcmp(argv[i],"-b"))
+ UNITS = BYTES;
+ else if(!strcmp(argv[i],"-k"))
+ UNITS = KILOBYTES;
+ else if(!strcmp(argv[i],"-m"))
+ UNITS = MEGABYTES;
+ else if(!strcmp(argv[i],"-g"))
+ UNITS = GIGABYTES;
+ else if(!strcmp(argv[i],"--"))
+ no_more_flags = true;
+ else
+ usage(argv[0]);
+ }
+ else {
+ rval = mb.load_file(argv[i]);
+
+ // 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;
+ }
+ }
+ }
+
+ // print summary of MOAB's memory use
+ print_memory_stats(mb);
+ return 0;
+}
+
+ // struct to store memory stats
+struct MemStats {
+ unsigned long total_storage;
+ unsigned long total_amortized;
+ unsigned long entity_storage;
+ unsigned long entity_amortized;
+ unsigned long adjacency_storage;
+ unsigned long adjacency_amortized;
+ unsigned long tag_storage;
+ unsigned long tag_amortized;
+};
+
+ // test if MemStats object indicates no memory
+bool is_zero( const MemStats& stats );
+
+ // populdate a MemStats structg by calling
+ // moab::Interface::estimated_memory_use
+void get_mem_stats( moab::Interface& mb,
+ MemStats& data,
+ moab::EntityType type = moab::MBMAXTYPE );
+
+ // Formatted string representation of memory size value
+std::string memstr( unsigned long val );
+
+ // Get string describing tag data type
+std::string tag_type_string( moab::Interface& mb, moab::Tag tag );
+
+ // Get string representation of tag storage type
+std::string tag_storage_string( moab::Interface& mb, moab::Tag tag );
+
+ // Center
+std::string center( const char* str, size_t width );
+
+void print_memory_stats( moab::Interface& mb )
+{
+ moab::ErrorCode rval;
+ const char ANON_TAG_NAME[] = "(anonymous)";
+ const int TYPE_WIDTH = 10;
+ const int MEM_WIDTH = 7;
+ const int MEM2_WIDTH = 2*MEM_WIDTH+1;
+ const int MIN_TAG_NAME_WIDTH = strlen(ANON_TAG_NAME);
+ const int DTYPE_WIDTH = 12;
+ const int STORAGE_WIDTH = 8;
+
+ // 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;
+ }
+
+ // 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.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;
+ }
+
+ // 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;
+
+ 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)
+ << 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;
+ rss *= getpagesize();
+ std::cerr << std::endl << "SYSTEM:"
+ << std::endl << "Resident set size: " << memstr(rss)
+ << std::endl;
+ }
+#endif
+ }
+}
+
+
+bool is_zero( const MemStats& stats ) { return stats.total_amortized == 0; }
+
+void get_mem_stats( moab::Interface& mb,
+ MemStats& data,
+ moab::EntityType type )
+{
+ if (type != moab::MBMAXTYPE) {
+ moab::Range range;
+ mb.get_entities_by_type( 0, type, range );
+ mb.estimated_memory_use( range,
+ &data.total_storage,
+ &data.total_amortized,
+ &data.entity_storage,
+ &data.entity_amortized,
+ &data.adjacency_storage,
+ &data.adjacency_amortized,
+ 0, 0,
+ &data.tag_storage,
+ &data.tag_amortized );
+ }
+ else {
+ mb.estimated_memory_use( 0, 0,
+ &data.total_storage,
+ &data.total_amortized,
+ &data.entity_storage,
+ &data.entity_amortized,
+ &data.adjacency_storage,
+ &data.adjacency_amortized,
+ 0, 0,
+ &data.tag_storage,
+ &data.tag_amortized );
+ }
+}
+
+// rounded division
+unsigned long rdiv( unsigned long num, unsigned long den )
+{
+ return (num + den/2) / den;
+}
+
+std::string memstr( unsigned long val )
+{
+ const unsigned long kb = 1024;
+ const unsigned long mb = kb*kb;
+ const unsigned long gb = kb*mb;
+ const unsigned long tb = kb*gb;
+
+ std::ostringstream s;
+ if (UNITS == HUMAN) {
+ if (val >= 10*tb)
+ s << rdiv( val, tb ) << "TB";
+ else if (val >= 10*gb)
+ s << rdiv( val, gb ) << "GB";
+ else if (val >= 10*mb)
+ s << rdiv( val, mb ) << "MB";
+ else if (val >= 10*kb)
+ s << rdiv( val, kb ) << "kB";
+ else if (val > 0)
+ s << val << " B";
+ else
+ s << "0 ";
+ }
+ else {
+ unsigned long den;
+ switch (UNITS) {
+ case BYTES: den = 1; break;
+ case KILOBYTES: den = kb; break;
+ case MEGABYTES: den = mb; break;
+ case GIGABYTES: den = gb; break;
+ case HUMAN: break; // handled above, list here to suppress warning
+ }
+
+ s << rdiv( val, den );
+ }
+ return s.str();
+}
+
+std::string tag_type_string( moab::Interface& mb, moab::Tag tag )
+{
+ moab::ErrorCode rval;
+ std::ostringstream s;
+
+ moab::DataType type;
+ rval = mb.tag_get_data_type( tag, type );
+ if (moab::MB_SUCCESS != rval)
+ return std::string();
+
+ int typesize;
+ std::string typestr;
+ switch (type) {
+ case moab::MB_TYPE_INTEGER:
+ typestr = "int";
+ typesize = sizeof(int);
+ break;
+ case moab::MB_TYPE_DOUBLE:
+ typestr = "double";
+ typesize = sizeof(double);
+ break;
+ case moab::MB_TYPE_HANDLE:
+ typestr = "handle";
+ typesize = sizeof(moab::EntityHandle);
+ break;
+ case moab::MB_TYPE_BIT:
+ typesize = 1;
+ typestr = "bits";
+ break;
+ case moab::MB_TYPE_OPAQUE:
+ typesize = 1;
+ typestr = "bytes";
+ break;
+ default:
+ typesize = 1;
+ typestr = "???";
+ break;
+ }
+
+ int size;
+ rval = mb.tag_get_size( tag, size );
+ if (moab::MB_VARIABLE_DATA_LENGTH == rval)
+ s << "VAR " << typestr;
+ else if (moab::MB_SUCCESS == rval)
+ s << size/typesize << " " << typestr;
+ // else do nothing
+
+ return s.str();
+}
+
+std::string tag_storage_string( moab::Interface& mb, moab::Tag tag )
+{
+ moab::ErrorCode rval;
+ moab::TagType type;
+ rval = mb.tag_get_type( tag, type );
+ if (moab::MB_SUCCESS != rval)
+ return std::string();
+
+ switch (type) {
+ case moab::MB_TAG_DENSE: return "dense";
+ case moab::MB_TAG_SPARSE: return "sparse";
+ case moab::MB_TAG_BIT: return "bit";
+ default: return "(none)";
+ }
+}
+
+
+std::string center( const char* str, size_t width )
+{
+ std::string text(str);
+ if (text.size() >= width)
+ return text;
+
+ width -= text.size();
+ if (1u == width) {
+ text += " ";
+ return text;
+ }
+
+ std::ostringstream s;
+ s << std::setw(width/2) << ' ' << text << std::setw(width/2 + width%2) << ' ';
+ return s.str();
+}
+
More information about the moab-dev
mailing list