1 #include <mpi.h> 2 #include <stdio.h> 3 #include <stdlib.h> 4 #include <cassert> 5 #include <cstring> 6 #include <string> 7 #include <sstream> 8 #include "phIO.h" 9 #include "phComm.h" 10 #include "phio_base.h" 11 #include "ph_mpi_help.h" 12 13 14 #ifndef PHASTAIO_TIMERS_ON 15 #define PHASTAIO_TIMERS_ON 0 16 #endif 17 struct phastaio_stats { 18 double readTime; 19 double writeTime; 20 double openTime; 21 double closeTime; 22 size_t readBytes; 23 size_t writeBytes; 24 }; 25 phastaio_stats phio_global_stats; 26 27 namespace { 28 inline double getTime() { 29 return MPI_Wtime(); 30 } 31 inline size_t getSize(const char* t) { 32 std::string type(t); 33 if(type == "integer") 34 return sizeof(int); 35 else if(type == "double") 36 return sizeof(double); 37 else { 38 assert(0); 39 exit(EXIT_FAILURE); 40 } 41 } 42 } 43 44 #define PHIO_TRACING 0 45 namespace { 46 void trace(const char* key, const char* aux="", void* obj=NULL) { 47 if(PHIO_TRACING) 48 fprintf(stderr, "PHIO_TRACE entering %s %s %p\n", key, aux, obj); 49 } 50 void printMinMaxAvg(const char* key, size_t v) { 51 int val = static_cast<int>(v); 52 int min = ph_min_int(val); 53 int max = ph_max_int(val); 54 long tot = ph_add_long(static_cast<long>(val)); 55 double avg = tot/static_cast<double>(ph_peers()); 56 if(!ph_self()) 57 fprintf(stderr, "phio_%s min max avg %d %d %f\n", 58 key, min, max, avg); 59 } 60 61 void printMinMaxAvg(const char* key, double v) { 62 double min = ph_min_double(v); 63 double max = ph_max_double(v); 64 double tot = ph_add_double(v); 65 double avg = tot/ph_peers(); 66 if(!ph_self()) 67 fprintf(stderr, "phio_%s min max avg %f %f %f\n", 68 key, min, max, avg); 69 } 70 } 71 72 #ifdef __cplusplus 73 extern "C" { 74 #endif 75 76 void phio_printStats() { 77 const int mebi=1024*1024; 78 printMinMaxAvg("readTime (s)",phio_getReadTime()); 79 printMinMaxAvg("writeTime (s)", phio_getWriteTime()); 80 printMinMaxAvg("openTime (s)", phio_getOpenTime()); 81 printMinMaxAvg("closeTime (s)", phio_getCloseTime()); 82 printMinMaxAvg("readBytes (B)", phio_getReadBytes()); 83 printMinMaxAvg("writeBytes (B)", phio_getWriteBytes()); 84 printMinMaxAvg("readBandwidth (MiB/s)", 85 (phio_getReadBytes()/phio_getReadTime())/mebi); 86 printMinMaxAvg("writeBandwidth (MiB/s)", 87 (phio_getWriteBytes()/phio_getWriteTime())/mebi); 88 } 89 90 void phio_initStats() { 91 phio_global_stats.readTime = 0; 92 phio_global_stats.writeTime = 0; 93 phio_global_stats.openTime = 0; 94 phio_global_stats.closeTime = 0; 95 phio_global_stats.readBytes = 0; 96 phio_global_stats.writeBytes = 0; 97 } 98 99 double phio_getReadTime() { 100 return phio_global_stats.readTime; 101 } 102 103 double phio_getWriteTime() { 104 return phio_global_stats.writeTime; 105 } 106 107 double phio_getOpenTime() { 108 return phio_global_stats.openTime; 109 } 110 111 double phio_getCloseTime() { 112 return phio_global_stats.closeTime; 113 } 114 115 size_t phio_getReadBytes() { 116 return phio_global_stats.readBytes; 117 } 118 119 size_t phio_getWriteBytes() { 120 return phio_global_stats.writeBytes; 121 } 122 123 void phio_readheader( 124 phio_fp f, 125 const char keyphrase[], 126 void* valueArray, 127 int* nItems, 128 const char datatype[], 129 const char iotype[] ) { 130 const double t0 = getTime(); 131 f->ops->readheader(f->file, keyphrase, valueArray, 132 nItems, datatype, iotype); 133 phio_global_stats.readBytes += (*nItems)*getSize(datatype); 134 phio_global_stats.readTime += getTime()-t0; 135 } 136 void phio_writeheader( 137 phio_fp f, 138 const char keyphrase[], 139 const void* valueArray, 140 const int* nItems, 141 const int* ndataItems, 142 const char datatype[], 143 const char iotype[] ) { 144 const double t0 = getTime(); 145 f->ops->writeheader(f->file, keyphrase, valueArray, 146 nItems, ndataItems, datatype, iotype); 147 phio_global_stats.writeBytes += (*nItems)*getSize(datatype); 148 phio_global_stats.writeTime += getTime()-t0; 149 } 150 void phio_readdatablock( 151 phio_fp f, 152 const char keyphrase[], 153 void* valueArray, 154 int* nItems, 155 const char datatype[], 156 const char iotype[] ) { 157 const double t0 = getTime(); 158 f->ops->readdatablock(f->file, keyphrase, valueArray, 159 nItems, datatype, iotype); 160 phio_global_stats.readBytes += (*nItems)*getSize(datatype); 161 phio_global_stats.readTime += getTime()-t0; 162 } 163 void phio_writedatablock( 164 phio_fp f, 165 const char keyphrase[], 166 const void* valueArray, 167 const int* nItems, 168 const char datatype[], 169 const char iotype[]) { 170 const double t0 = getTime(); 171 f->ops->writedatablock(f->file, keyphrase, valueArray, 172 nItems, datatype, iotype); 173 phio_global_stats.writeBytes += (*nItems)*getSize(datatype); 174 phio_global_stats.writeTime += getTime()-t0; 175 } 176 177 void phio_constructName( 178 phio_fp f, 179 const char inName[], 180 char* outName) { 181 f->ops->constructname(inName, outName); 182 } 183 184 void phio_openfile( 185 const char filename[], 186 phio_fp f) { 187 const double t0 = getTime(); 188 trace("openfile",filename,f); 189 f->ops->openfile(filename, f); 190 phio_global_stats.openTime += getTime()-t0; 191 } 192 193 void phio_closefile(phio_fp f) { 194 const double t0 = getTime(); 195 trace("closefile","unknown",f); 196 f->ops->closefile(f); 197 phio_global_stats.closeTime += getTime()-t0; 198 } 199 200 void phio_appendInt(char* dest, int v) { 201 std::stringstream ss; 202 ss << dest << v << '.'; 203 std::string s = ss.str(); 204 strcpy(dest, s.c_str()); 205 } 206 207 #ifdef __cplusplus 208 } 209 #endif 210