diff options
author | Junyan He <junyan.he@linux.intel.com> | 2014-06-10 12:52:45 +0800 |
---|---|---|
committer | Zhigang Gong <zhigang.gong@intel.com> | 2014-06-11 11:04:02 +0800 |
commit | 91afb05c0f6440ada79a0e6896b64aa0bc3b2ca2 (patch) | |
tree | 2b8979e2532414bfca23c7c8b787e7b66a513f3a /backend | |
parent | 1edb45bbf0ef831e90bab50fe84a3e800ce4229a (diff) |
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>
Diffstat (limited to 'backend')
-rw-r--r-- | backend/src/CMakeLists.txt | 2 | ||||
-rw-r--r-- | backend/src/ir/printf.cpp | 119 | ||||
-rw-r--r-- | backend/src/ir/printf.hpp | 197 |
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__ */ |