[Beignet] [PATCH 2/6 OpenCL-1.2] Add the PrintfSet class into the ir

junyan.he at inbox.com junyan.he at inbox.com
Tue Jun 3 23:03:23 PDT 2014


From: Junyan He <junyan.he at linux.intel.com>

The PrintfSet will be used to collect all the infomation in
the kernel. After the kernel executed, it will be used
to generate the according printf output.

Signed-off-by: Junyan He <junyan.he at linux.intel.com>
---
 backend/src/CMakeLists.txt |   2 +
 backend/src/ir/printf.cpp  | 118 +++++++++++++++++++++++++++
 backend/src/ir/printf.hpp  | 197 +++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 317 insertions(+)
 create mode 100644 backend/src/ir/printf.cpp
 create mode 100644 backend/src/ir/printf.hpp

diff --git a/backend/src/CMakeLists.txt b/backend/src/CMakeLists.txt
index 528595f..1dca0e0 100644
--- a/backend/src/CMakeLists.txt
+++ b/backend/src/CMakeLists.txt
@@ -135,6 +135,8 @@ else (GBE_USE_BLOB)
     ir/value.hpp
     ir/lowering.cpp
     ir/lowering.hpp
+    ir/printf.cpp
+    ir/printf.hpp
     backend/context.cpp
     backend/context.hpp
     backend/program.cpp
diff --git a/backend/src/ir/printf.cpp b/backend/src/ir/printf.cpp
new file mode 100644
index 0000000..a841af7
--- /dev/null
+++ b/backend/src/ir/printf.cpp
@@ -0,0 +1,118 @@
+/*
+ * Copyright © 2012 Intel Corporation
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+/**
+ * \file sampler.cpp
+ *
+ */
+
+#include <stdarg.h>
+#include "printf.hpp"
+#include "ocl_common_defines.h"
+
+namespace gbe
+{
+  namespace ir
+  {
+    uint32_t PrintfSet::append(PrintfFmt* fmt, Unit& unit)
+    {
+      fmts.push_back(*fmt);
+
+      for (auto &f : fmts.back()) {
+        if (f.type == PRINTF_SLOT_TYPE_STRING)
+          continue;
+
+        slots.push_back(&f);
+      }
+
+      /* Update the total size of size. */
+      sizeOfSize = slots.back()->state->out_buf_sizeof_offset
+                   + getPrintfBufferElementSize(slots.size() - 1);
+
+      return (uint32_t)fmts.size();
+    }
+
+    /* ugly here. We can not build the va_list dynamically:(
+       And I have tried
+       va_list arg; arg = some_ptr;
+       This works very OK on 32bits platform but can not even
+       pass the compiling in the 64bits platform.
+       sizeof(arg) = 4 in 32bits platform but
+       sizeof(arg) = 24 in 64bits platform.
+       We can not assume the platform here. */
+    void vfprintf_wrap(std::string& fmt, vector<int>& contents)
+    {
+      int* ptr = NULL;
+      size_t num = contents.size() < 16 ? contents.size() : 16;
+      ptr = (int *)calloc(16, sizeof(int)); //should be enough
+      for (size_t i = 0; i < num; i++) {
+        ptr[i] = contents[i];
+      }
+
+      printf(fmt.c_str(), ptr[0], ptr[1], ptr[2], ptr[3], ptr[4], ptr[5], ptr[6], ptr[7],
+             ptr[8], ptr[9], ptr[10], ptr[11], ptr[12], ptr[13], ptr[14], ptr[15]);
+      free(ptr);
+    }
+
+    void PrintfSet::outputPrintf(void* index_addr, void* buf_addr, size_t global_wk_sz0,
+                                 size_t global_wk_sz1, size_t global_wk_sz2)
+    {
+      size_t i, j, k;
+      std::string pf_str;
+      vector<int>* contents = NULL;
+      for (auto &pf : fmts) {
+        for (i = 0; i < global_wk_sz0; i++) {
+          for (j = 0; j < global_wk_sz0; j++) {
+            for (k = 0; k < global_wk_sz0; k++) {
+              std::string pf_str;
+              int flag = ((int *)index_addr)[k*global_wk_sz0*global_wk_sz1 + j*global_wk_sz0 + i];
+              if (flag) {
+                contents = new vector<int>();
+                for (auto &slot : pf) {
+                  if (slot.type == PRINTF_SLOT_TYPE_STRING) {
+                    pf_str = pf_str + std::string(slot.str);
+                    continue;
+                  }
+                  assert(slot.type == PRINTF_SLOT_TYPE_STATE);
+
+                  switch (slot.state->conversion_specifier) {
+                    case PRINTF_CONVERSION_D:
+                    case PRINTF_CONVERSION_I:
+
+                      contents->push_back(((int *)((char *)buf_addr + slot.state->out_buf_sizeof_offset
+                                                   * global_wk_sz0 * global_wk_sz1 * global_wk_sz2))
+                                          [k*global_wk_sz0*global_wk_sz1 + j*global_wk_sz0 + i]);
+                      pf_str = pf_str + std::string("%d");
+                      break;
+                    default:
+                      assert(0);
+                      return;
+                  }
+                }
+
+                vfprintf_wrap(pf_str, *contents);
+                delete contents;
+              }
+            }
+          }
+        }
+      }
+    }
+  } /* namespace ir */
+} /* namespace gbe */
+
diff --git a/backend/src/ir/printf.hpp b/backend/src/ir/printf.hpp
new file mode 100644
index 0000000..5763a65
--- /dev/null
+++ b/backend/src/ir/printf.hpp
@@ -0,0 +1,197 @@
+/*
+ * Copyright © 2012 Intel Corporation
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+/**
+ * \file printf.hpp
+ *
+ */
+#ifndef __GBE_IR_PRINTF_HPP__
+#define __GBE_IR_PRINTF_HPP__
+
+#include <string.h>
+#include "sys/map.hpp"
+#include "sys/vector.hpp"
+#include "unit.hpp"
+
+namespace gbe
+{
+  namespace ir
+  {
+
+    /* Things about printf info. */
+    enum {
+      PRINTF_LM_HH,
+      PRINTF_LM_H,
+      PRINTF_LM_L,
+      PRINTF_LM_HL,
+    };
+
+    enum {
+      PRINTF_CONVERSION_INVALID,
+      PRINTF_CONVERSION_D,
+      PRINTF_CONVERSION_I,
+      PRINTF_CONVERSION_O,
+      PRINTF_CONVERSION_U,
+      PRINTF_CONVERSION_X,
+      PRINTF_CONVERSION_x,
+      PRINTF_CONVERSION_F,
+      PRINTF_CONVERSION_f,
+      PRINTF_CONVERSION_E,
+      PRINTF_CONVERSION_e,
+      PRINTF_CONVERSION_G,
+      PRINTF_CONVERSION_g,
+      PRINTF_CONVERSION_A,
+      PRINTF_CONVERSION_a,
+      PRINTF_CONVERSION_C,
+      PRINTF_CONVERSION_S,
+      PRINTF_CONVERSION_P
+    };
+
+    struct PrintfState {
+      char left_justified;
+      char sign_symbol; //0 for nothing, 1 for sign, 2 for space.
+      char alter_form;
+      char zero_padding;
+      char vector_n;
+      int min_width;
+      int precision;
+      int length_modifier;
+      char conversion_specifier;
+      int out_buf_sizeof_offset;  // Should *global_total_size to get the full offset.
+    };
+
+    enum {
+      PRINTF_SLOT_TYPE_NONE,
+      PRINTF_SLOT_TYPE_STRING,
+      PRINTF_SLOT_TYPE_STATE
+    };
+
+    struct PrintfSlot {
+      int type;
+      union {
+        char* str;
+        PrintfState* state;
+        void *ptr;
+      };
+
+      PrintfSlot(void) {
+        type = PRINTF_SLOT_TYPE_NONE;
+        ptr = NULL;
+      }
+
+      PrintfSlot(const char * s) {
+        type = PRINTF_SLOT_TYPE_STRING;
+        int len = strlen(s);
+        str = (char*)malloc((len + 1) * sizeof(char));
+        memcpy(str, s, (len + 1) * sizeof(char));
+        str[len] = 0;
+      }
+
+      PrintfSlot(PrintfState * st) {
+        type = PRINTF_SLOT_TYPE_STATE;
+        state = (PrintfState *)malloc(sizeof(PrintfState));
+        memcpy(state, st, sizeof(PrintfState));
+      }
+
+      PrintfSlot(const PrintfSlot & other) {
+        if (other.type == PRINTF_SLOT_TYPE_STRING) {
+          int len = strlen(other.str);
+          str = (char*)malloc((len + 1) * sizeof(char));
+          memcpy(str, other.str, (len + 1) * sizeof(char));
+          str[len] = 0;
+          type = PRINTF_SLOT_TYPE_STRING;
+        } else if (other.type == PRINTF_SLOT_TYPE_STATE) {
+          type = PRINTF_SLOT_TYPE_STATE;
+          state = (PrintfState *)malloc(sizeof(PrintfState));
+          memcpy(state, other.state, sizeof(PrintfState));
+        } else {
+          type = PRINTF_SLOT_TYPE_NONE;
+          ptr = NULL;
+        }
+      }
+
+      PrintfSlot(PrintfSlot && other) {
+        void *p = other.ptr;
+        type = other.type;
+        other.ptr = ptr;
+        ptr = p;
+
+      }
+
+      ~PrintfSlot(void) {
+        if (ptr)
+          free(ptr);
+      }
+    };
+
+    class Context;
+
+    class PrintfSet //: public Serializable
+    {
+    public:
+      PrintfSet(const PrintfSet& other) {
+        for (auto &f : other.fmts) {
+          fmts.push_back(f);
+        }
+
+        for (auto &s : other.slots) {
+          slots.push_back(s);
+        }
+
+        sizeOfSize = other.sizeOfSize;
+      }
+
+      PrintfSet(void) = default;
+
+      typedef vector<PrintfSlot> PrintfFmt;
+      uint32_t append(PrintfFmt* fmt, Unit &unit);
+
+      uint32_t getPrintfNum(void) const {
+        return fmts.size();
+      }
+
+      uint32_t getPrintfSizeOfSize(void) const {
+        return sizeOfSize;
+      }
+
+      uint32_t getPrintfBufferElementSize(uint32_t i) {
+        PrintfSlot* slot = slots[i];
+        switch (slot->state->conversion_specifier) {
+          case PRINTF_CONVERSION_I:
+          case PRINTF_CONVERSION_D:
+            return (uint32_t)sizeof(int);
+          default:
+            break;
+        }
+        assert(0);
+        return 0;
+      }
+
+      void outputPrintf(void* index_addr, void* buf_addr, size_t global_wk_sz0,
+                        size_t global_wk_sz1, size_t global_wk_sz2);
+
+    private:
+      vector<PrintfFmt> fmts;
+      vector<PrintfSlot*> slots;
+      uint32_t sizeOfSize; // Total sizeof size.
+      GBE_CLASS(PrintfSet);
+    };
+  } /* namespace ir */
+} /* namespace gbe */
+
+#endif /* __GBE_IR_PRINTF_HPP__ */
-- 
1.8.3.2



More information about the Beignet mailing list