From: Junyan He <[email protected]> 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 <[email protected]> --- 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 _______________________________________________ Beignet mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/beignet
