[Beignet] [PATCH 2/6] Add the PrintfSet class into the ir
Zhigang Gong
zhigang.gong at linux.intel.com
Tue Jun 10 17:23:43 PDT 2014
This patch LGTM, thanks.
On Tue, Jun 10, 2014 at 12:52:45PM +0800, junyan.he at inbox.com wrote:
> 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
>
> _______________________________________________
> Beignet mailing list
> Beignet at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/beignet
More information about the Beignet
mailing list