[Beignet] [PATCH 2/6] Add the PrintfSet class into the ir
junyan.he at inbox.com
junyan.he at inbox.com
Mon Jun 9 21:52:45 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 | 119 +++++++++++++++++++++++++++
backend/src/ir/printf.hpp | 197 +++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 318 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 67ea371..0716d35 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..3729155
--- /dev/null
+++ b/backend/src/ir/printf.cpp
@@ -0,0 +1,119 @@
+/*
+ * 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() < 32 ? contents.size() : 32;
+ ptr = (int *)calloc(32, 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], ptr[16],
+ ptr[17], ptr[18], ptr[19], ptr[20], ptr[21], ptr[22], ptr[23], ptr[24], ptr[25],
+ ptr[26], ptr[27], ptr[28], ptr[29], ptr[30], ptr[31]);
+ 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_sz1; j++) {
+ for (k = 0; k < global_wk_sz2; k++) {
+ int flag = ((int *)index_addr)[k*global_wk_sz0*global_wk_sz1 + j*global_wk_sz0 + i];
+ if (flag) {
+ pf_str = "";
+ 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