Swarm-NG  1.1
lprintf.h
Go to the documentation of this file.
1 /***************************************************************************
2  * Copyright (C) 2010 by Mario Juric *
3  * mjuric@cfa.harvard.EDU *
4  * *
5  * This program is free software; you can redistribute it and/or modify *
6  * it under the terms of the GNU General Public License as published by *
7  * the Free Software Foundation; either version 3 of the License, or *
8  * (at your option) any later version. *
9  * *
10  * This program is distributed in the hope that it will be useful, *
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13  * GNU General Public License for more details. *
14  * *
15  * You should have received a copy of the GNU General Public License *
16  * along with this program; if not, write to the *
17  * Free Software Foundation, Inc., *
18  * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
19  ***************************************************************************/
20 
27 #ifndef lprintf_h__
28 #define lprintf_h__
29 
30 #include <cstring>
31 #include "gpulog.h"
32 
37 #if 0
38  template<typename T> __device__ __host__ inline const T& f2d_fun(const T &v) { return v; }
40  __device__ inline double f2d_fun(const float &v) // specialization for cast of float to double (used by printf)
41  {
42  return v;
43  }
44 
45 #define f2d(T, x) f2d_fun(x)
46 #else
47  template<typename T> struct f2dstruct
49  {
50  typedef const T& cTref;
51  __host__ __device__ static cTref cvt(cTref v) { return v; }
52  };
53  template<> struct f2dstruct<float>
54  {
55  __host__ __device__ static double cvt(const float &v) { return v; }
56  };
57 
58 #define f2d(T, x) f2dstruct<T>::cvt(x)
59 #endif
60 
61 #if 0
62  template<typename L, int N, typename T1, typename T2, typename T3>
63  __host__ __device__ inline void lprintf(L &log, const char (&fmt)[N], const T1 &v1, const T2 &v2, const T3 &v3)
64  {
65  log.write(MSG_PRINTF, fmt, f2d(v1), f2d(v2), f2d(v3));
66  }
67 #else
68 #include "bits/gpulog_printf.h"
69 #endif
70 
71 
72 #if !__CUDACC__
73  inline std::string run_printf(gpulog::logrecord &lr)
75  {
76  using namespace gpulog;
77 
78  std::string res;
79  if(lr.msgid() != MSG_PRINTF)
80  {
81  return "";
82  }
83 
84  // slurp up the format string
85  char fmtbuf[1024], *fmt = fmtbuf;
86  lr >> fmt;
87 
88  double data_double;
89  int data_int;
90  char data_str[1024];
91 
92  // Now run through it, printing everything we can. We must
93  // run to every % character, extract only that, and use printf
94  // to format it.
95  char buf[1024];
96  std::ostringstream out;
97  char *p = strchr ( fmt, '%' );
98  while ( p != NULL )
99  {
100  // Print up to the % character
101  *p = '\0';
102  out << fmt;
103  *p = '%'; // Put back the %
104 
105  // Now handle the format specifier
106  char *format = p++; // Points to the '%'
107  p += strcspn ( p, "%cdiouxXeEfgGaAnps" );
108  if ( *p == '\0' ) // If no format specifier, print the whole thing
109  {
110  fmt = format;
111  break;
112  }
113 
114  char specifier = *p++;
115  char c = *p; // Store for later
116  *p = '\0';
117  switch ( specifier )
118  {
119  // These all take integer arguments
120  case 'c':
121  case 'd':
122  case 'i':
123  case 'o':
124  case 'u':
125  case 'x':
126  case 'X':
127  case 'p':
128  lr >> data_int;
129  sprintf(buf, format, data_int);
130  out << buf;
131  break;
132 
133  // These all take double arguments
134  case 'e':
135  case 'E':
136  case 'f':
137  case 'g':
138  case 'G':
139  case 'a':
140  case 'A':
141  lr >> data_double;
142  sprintf(buf, format, data_double);
143  out << buf;
144  break;
145 
146  // Strings are handled in a special way
147  case 's':
148  lr >> data_str;
149  sprintf(buf, format, data_str);
150  out << buf;
151  break;
152 
153  // % is special
154  case '%':
155  out << "%%";
156  break;
157 
158  // Everything else is just printed out as-is
159  default:
160  out << format;
161  break;
162  }
163  *p = c; // Restore what we removed
164  fmt = p; // Adjust fmt string to be past the specifier
165  p = strchr(fmt,'%'); // and get the next specifier
166  }
167 
168  // Print out the last of the string
169  out << fmt;
170  return out.str();
171  }
172 
174  inline int replay_printf(std::ostream &out, gpulog::ilogstream &ls)
175  {
176  using namespace gpulog;
177 
178  logrecord lr;
179  int count = 0;
180  while(lr = ls.next())
181  {
182  if(lr.msgid() != MSG_PRINTF) { continue; }
183 
184  // process the printf...
185  out << run_printf(lr);
186  count++;
187  }
188  return count;
189  }
191  inline int replay_printf(std::ostream &out, const gpulog::host_log &log)
192  {
193  gpulog::ilogstream ls(log);
194  return replay_printf(out, ls);
195  }
196  #endif
197 
198 
199 
200 #endif // lprintf_h__