[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