summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJunyan He <junyan.he@linux.intel.com>2014-06-10 12:52:45 +0800
committerZhigang Gong <zhigang.gong@intel.com>2014-06-11 11:04:02 +0800
commit91afb05c0f6440ada79a0e6896b64aa0bc3b2ca2 (patch)
tree2b8979e2532414bfca23c7c8b787e7b66a513f3a
parent1edb45bbf0ef831e90bab50fe84a3e800ce4229a (diff)
downloadbeignet-91afb05c0f6440ada79a0e6896b64aa0bc3b2ca2.tar.gz
Add the PrintfSet class into the ir
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@linux.intel.com> Reviewed-by: Zhigang Gong <zhigang.gong@linux.intel.com>
-rw-r--r--backend/src/CMakeLists.txt2
-rw-r--r--backend/src/ir/printf.cpp119
-rw-r--r--backend/src/ir/printf.hpp197
3 files changed, 318 insertions, 0 deletions
diff --git a/backend/src/CMakeLists.txt b/backend/src/CMakeLists.txt
index 67ea371e..0716d357 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 00000000..3729155c
--- /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 00000000..5763a651
--- /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__ */