This patch LGTM, thanks.
On Tue, Jun 10, 2014 at 12:52:45PM +0800, [email protected] wrote: > 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 | 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 > > _______________________________________________ > Beignet mailing list > [email protected] > http://lists.freedesktop.org/mailman/listinfo/beignet _______________________________________________ Beignet mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/beignet
