   bool wireframe = false;
   bool recreate_context = true;
   bool indexed = true;
+
+  enum LogLevels {
+    ALWAYS = 0,
+    ERROR = 1,
+    WARNING = 2,
+    INFO = 3,
+    DEBUG = 4,
+    TRACE = 5
+  };
+  uint32_t loglevel = 4;
+
+#define LOG_ALWAYS(msg, ...) do { fputs("[A] ", stderr); fprintf(stderr, msg, ##__VA_ARGS__); fputc('\n', stderr); } while (0)
+#define LOG_ERROR(msg, ...) do { if(ERROR <= loglevel) {  fputs("[E] ", stderr); fprintf(stderr, msg, ##__VA_ARGS__); fputc('\n', stderr);} } while (0)
+#define LOG_WARNING(msg, ...) do { if(WARNING <= loglevel) {  fputs("[W] ", stderr); fprintf(stderr, msg, ##__VA_ARGS__); fputc('\n', stderr);} } while (0)
+#define LOG_INFO(msg, ...) do { if(INFO <= loglevel) {  fputs("[I] ", stderr); fprintf(stderr, msg, ##__VA_ARGS__); fputc('\n', stderr);} } while (0)
+#define LOG_DEBUG(msg, ...) do { if(DEBUG <= loglevel) {  fputs("[D] ", stderr); fprintf(stderr, msg, ##__VA_ARGS__); fputc('\n', stderr);} } while (0)
+#define LOG_TRACE(msg, ...) do { if(TRACE <= loglevel) {  fputs("[T] ", stderr); fprintf(stderr, msg, ##__VA_ARGS__); fputc('\n', stderr);} } while (0)
+
   float threshold = 0.f;
 
   std::vector<char> scalarField_host;
 
   void onGLFWError(int error, const char* what)
   {
-    fprintf(stderr, "GLFW Error: %s\n", what);
+    LOG_ERROR("GLFW Error: %s", what);
   }
 
   void onKey(GLFWwindow* window, int key, int scancode, int action, int mods)

      fprintf(stderr, "    -nx  int    Set number of samples in z direction.\n");
      fprintf(stderr, "    -n   int    Set uniform number of samples in x,y,z directions.\n");
      fprintf(stderr, "    -i   float  Set iso-value to extract surface for.\n");
      fprintf(stderr, "    -b          Enable benchmark mode without OpenGL interop.\n");
      fprintf(stderr, "\nDataset:\n");
      fprintf(stderr, "    cayley    Built-in algebraic surface.\n");

    int i = devices[k];
    cudaDeviceProp dev_prop;
    cudaGetDeviceProperties(&dev_prop, i);
    LOG_INFO("%c[%i] %s cap=%d.%d", i == deviceIndex ? '*' : ' ', i, dev_prop.name, dev_prop.major, dev_prop.minor);
    if (i == deviceIndex) {
      found = true;
    }
  }
  if (!found) {
    LOG_ERROR("Illegal CUDA device index %d", deviceIndex);
    return EXIT_FAILURE;
  }
  cudaSetDevice(deviceIndex);
