[Beignet] [PATCH 2/2] Backend: add debugwait function

Yang, Rong R rong.r.yang at intel.com
Tue Nov 3 18:05:26 PST 2015



> -----Original Message-----
> From: Pan, Xiuli
> Sent: Tuesday, November 3, 2015 17:23
> To: Yang, Rong R; beignet at lists.freedesktop.org
> Subject: RE: [Beignet] [PATCH 2/2] Backend: add debugwait function
> 
> 1. I will look into the side effect and the scheduling. And the backend part is
> used part of the existed barrier wait inst, may need some change.
> 
> 2.The sel.WAIT(1); is not for the execwidth,  it is used for select the different
> reg used for host-thread from the barrier host-host reg.

What's I mean is the wait instruction's Restriction:
Execution size must be 1 as the notification registers are scalar.

You must set the execwidth to 1, disable predicate and enable nomask.


> 
> -----Original Message-----
> From: Yang, Rong R
> Sent: Tuesday, November 3, 2015 12:23 PM
> To: Pan, Xiuli <xiuli.pan at intel.com>; beignet at lists.freedesktop.org
> Cc: Pan, Xiuli <xiuli.pan at intel.com>
> Subject: RE: [Beignet] [PATCH 2/2] Backend: add debugwait function
> 
> Two comments.
> 
> > -----Original Message-----
> > From: Beignet [mailto:beignet-bounces at lists.freedesktop.org] On Behalf
> > Of Pan Xiuli
> > Sent: Friday, October 23, 2015 11:22
> > To: beignet at lists.freedesktop.org
> > Cc: Pan, Xiuli
> > Subject: [Beignet] [PATCH 2/2] Backend: add debugwait function
> >
> > Use wait function to extend a debug function:
> >     void debugwait(void)
> > This function can hang the gpu unless gpu reset or host send something
> > to let it go.
> > EXTREMELY DANGEROUS for machines turn off hangcheck
> >
> > Signed-off-by: Pan Xiuli <xiuli.pan at intel.com>
> > ---
> >  backend/src/backend/gen_context.cpp        |  2 +-
> >  backend/src/backend/gen_insn_selection.cpp | 25
> > ++++++++++++++++++++++---
> > backend/src/backend/gen_insn_selection.hpp |  1 +
> >  backend/src/ir/instruction.cpp             | 29
> > +++++++++++++++++++++++++++++
> >  backend/src/ir/instruction.hpp             |  9 +++++++++
> >  backend/src/ir/instruction.hxx             |  1 +
> >  backend/src/libocl/include/ocl_sync.h      |  1 +
> >  backend/src/libocl/src/ocl_barrier.ll      |  6 ++++++
> >  backend/src/libocl/src/ocl_sync.cl         |  1 +
> >  backend/src/llvm/llvm_gen_backend.cpp      |  6 ++++++
> >  backend/src/llvm/llvm_gen_ocl_function.hxx |  2 ++
> >  11 files changed, 79 insertions(+), 4 deletions(-)
> >
> > diff --git a/backend/src/backend/gen_context.cpp
> > b/backend/src/backend/gen_context.cpp
> > index baf3897..56ce253 100644
> > --- a/backend/src/backend/gen_context.cpp
> > +++ b/backend/src/backend/gen_context.cpp
> > @@ -1804,7 +1804,7 @@ namespace gbe
> >    }
> >
> >    void GenContext::emitWaitInstruction(const SelectionInstruction &insn) {
> > -    p->WAIT();
> > +    p->WAIT(insn.extra.waitType);
> >    }
> >
> >    void GenContext::emitBarrierInstruction(const SelectionInstruction
> > &insn) { diff --git a/backend/src/backend/gen_insn_selection.cpp
> > b/backend/src/backend/gen_insn_selection.cpp
> > index 1711ab6..8c71baf 100644
> > --- a/backend/src/backend/gen_insn_selection.cpp
> > +++ b/backend/src/backend/gen_insn_selection.cpp
> > @@ -618,7 +618,7 @@ namespace gbe
> >      /*! No-op */
> >      void NOP(void);
> >      /*! Wait instruction (used for the barrier) */
> > -    void WAIT(void);
> > +    void WAIT(uint32_t n = 0);
> >      /*! Atomic instruction */
> >      void ATOMIC(Reg dst, uint32_t function, uint32_t srcNum, Reg
> > src0, Reg src1, Reg src2, GenRegister bti, vector<GenRegister> temps);
> >      /*! Read 64 bits float/int array */ @@ -1282,7 +1282,11 @@
> > namespace gbe
> >
> >    void Selection::Opaque::EOT(void) { this->appendInsn(SEL_OP_EOT, 0,
> 0); }
> >    void Selection::Opaque::NOP(void) { this->appendInsn(SEL_OP_NOP, 0,
> > 0); }
> > -  void Selection::Opaque::WAIT(void) { this->appendInsn(SEL_OP_WAIT,
> > 0, 0); }
> > +  void Selection::Opaque::WAIT(uint32_t n)  {
> > +    SelectionInstruction *insn = this->appendInsn(SEL_OP_WAIT, 0, 0);
> > +    insn->extra.waitType = n;
> > +  }
> >
> >    void Selection::Opaque::READ64(Reg addr,
> >                                   const GenRegister *dst, @@ -1834,7
> > +1838,8 @@ namespace gbe
> >    bool Selection::Opaque::isRoot(const ir::Instruction &insn) const {
> >      if (insn.hasSideEffect() ||
> >          insn.isMemberOf<ir::BranchInstruction>() ||
> > -        insn.isMemberOf<ir::LabelInstruction>())
> > +        insn.isMemberOf<ir::LabelInstruction>() ||
> > +        insn.isMemberOf<ir::WaitInstruction>())
> Wait is similar with barrier, it is better to set hasSideEffect to true. And you
> also need take care of it in scheduling.
> 
> >      return true;
> >
> >      // No side effect, not a branch and no destination? Impossible @@
> > -3331,6
> > +3336,19 @@ namespace gbe
> >      DECL_CTOR(SyncInstruction, 1,1);
> >    };
> >
> > +  /*! Wait instruction */
> > +  DECL_PATTERN(WaitInstruction)
> > +  {
> > +    INLINE bool emitOne(Selection::Opaque &sel, const
> > + ir::WaitInstruction
> > &insn, bool &markChildren) const
> > +    {
> > +      using namespace ir;
> > +      sel.WAIT(1);
> Must the wait's execwidth be 1?
> 
> > +      return true;
> > +    }
> > +
> > +    DECL_CTOR(WaitInstruction, 1,1);
> > +  };
> > +
> >    INLINE uint32_t getByteScatterGatherSize(Selection::Opaque &sel,
> > ir::Type
> > type) {
> >      using namespace ir;
> >      switch (type) {
> > @@ -5543,6 +5561,7 @@ namespace gbe
> >      this->insert<SimdShuffleInstructionPattern>();
> >      this->insert<IndirectMovInstructionPattern>();
> >      this->insert<NullaryInstructionPattern>();
> > +    this->insert<WaitInstructionPattern>();
> >
> >      // Sort all the patterns with the number of instructions they output
> >      for (uint32_t op = 0; op < ir::OP_INVALID; ++op) diff --git
> > a/backend/src/backend/gen_insn_selection.hpp
> > b/backend/src/backend/gen_insn_selection.hpp
> > index 275eb9c..7e6ce96 100644
> > --- a/backend/src/backend/gen_insn_selection.hpp
> > +++ b/backend/src/backend/gen_insn_selection.hpp
> > @@ -130,6 +130,7 @@ namespace gbe
> >          bool     isUniform;
> >        };
> >        uint32_t barrierType;
> > +      uint32_t waitType;
> >        bool longjmp;
> >        uint32_t indirect_offset;
> >      } extra;
> > diff --git a/backend/src/ir/instruction.cpp
> > b/backend/src/ir/instruction.cpp index f93c528..d378f64 100644
> > --- a/backend/src/ir/instruction.cpp
> > +++ b/backend/src/ir/instruction.cpp
> > @@ -818,6 +818,21 @@ namespace ir {
> >        Register dst[0], src[0];
> >      };
> >
> > +    /*! Wait instructions */
> > +    class ALIGNED_INSTRUCTION WaitInstruction :
> > +      public BasePolicy,
> > +      public NSrcPolicy<LabelInstruction, 0>,
> > +      public NDstPolicy<LabelInstruction, 0>
> > +    {
> > +    public:
> > +      WaitInstruction(Opcode opcode) {
> > +        this->opcode = opcode;
> > +      }
> > +      INLINE bool wellFormed(const Function &fn, std::string &why) const;
> > +      INLINE void out(std::ostream &out, const Function &fn) const;
> > +      Register dst[0], src[0];
> > +    };
> > +
> >  #undef ALIGNED_INSTRUCTION
> >
> >
> > //////////////////////////////////////////////////////////////////////
> > ///
> > @@ -1115,6 +1130,8 @@ namespace ir {
> >      { return true; }
> >      INLINE bool GetImageInfoInstruction::wellFormed(const Function
> > &fn, std::string &why) const
> >      { return true; }
> > +    INLINE bool WaitInstruction::wellFormed(const Function &fn,
> > + std::string
> > &why) const
> > +    { return true; }
> >
> >
> >      // Ensure that types and register family match @@ -1361,6 +1378,9
> > @@ namespace ir {
> >            out << "." << syncStr[field];
> >      }
> >
> > +    INLINE void WaitInstruction::out(std::ostream &out, const
> > + Function &fn)
> > const {
> > +      this->outOpcode(out);
> > +    }
> >
> >    } /* namespace internal */
> >
> > @@ -1502,6 +1522,10 @@ START_INTROSPECTION(LabelInstruction)
> >  #include "ir/instruction.hxx"
> >  END_INTROSPECTION(LabelInstruction)
> >
> > +START_INTROSPECTION(WaitInstruction)
> > +#include "ir/instruction.hxx"
> > +END_INTROSPECTION(WaitInstruction)
> > +
> >  #undef END_INTROSPECTION
> >  #undef START_INTROSPECTION
> >  #undef DECL_INSN
> > @@ -1940,6 +1964,11 @@ DECL_MEM_FN(GetImageInfoInstruction,
> uint8_t,
> > getImageIndex(void), getImageIndex
> >      return internal::GetImageInfoInstruction(infoType, dst,
> > imageIndex, infoReg).convert();
> >    }
> >
> > +  // WAIT
> > +  Instruction WAIT(void) {
> > +    return internal::WaitInstruction(OP_WAIT).convert();
> > +  }
> > +
> >    std::ostream &operator<< (std::ostream &out, const Instruction &insn) {
> >      const Function &fn = insn.getFunction();
> >      const BasicBlock *bb = insn.getParent(); diff --git
> > a/backend/src/ir/instruction.hpp b/backend/src/ir/instruction.hpp
> > index
> > 3f3c655..e3cc5d4 100644
> > --- a/backend/src/ir/instruction.hpp
> > +++ b/backend/src/ir/instruction.hpp
> > @@ -548,6 +548,13 @@ namespace ir {
> >      static bool isClassOf(const Instruction &insn);
> >    };
> >
> > +  /*! Indirect Move instruction */
> > +  class WaitInstruction : public Instruction {
> > +  public:
> > +    /*! Return true if the given instruction is an instance of this class */
> > +    static bool isClassOf(const Instruction &insn);  };
> > +
> >    /*! Specialize the instruction. Also performs typechecking first based on
> the
> >     *  opcode. Crashes if it fails
> >     */
> > @@ -760,6 +767,8 @@ namespace ir {
> >    Instruction GET_IMAGE_INFO(int infoType, Register dst, uint8_t
> > imageIndex, Register infoReg);
> >    /*! label labelIndex */
> >    Instruction LABEL(LabelIndex labelIndex);
> > +  /*! wait */
> > +  Instruction WAIT(void);
> >
> >  } /* namespace ir */
> >  } /* namespace gbe */
> > diff --git a/backend/src/ir/instruction.hxx
> > b/backend/src/ir/instruction.hxx index 81548c9..51c110d 100644
> > --- a/backend/src/ir/instruction.hxx
> > +++ b/backend/src/ir/instruction.hxx
> > @@ -106,3 +106,4 @@ DECL_INSN(IF, BranchInstruction)
> DECL_INSN(ENDIF,
> > BranchInstruction)  DECL_INSN(ELSE, BranchInstruction)
> > DECL_INSN(WHILE,
> > BranchInstruction)
> > +DECL_INSN(WAIT, WaitInstruction)
> > diff --git a/backend/src/libocl/include/ocl_sync.h
> > b/backend/src/libocl/include/ocl_sync.h
> > index 18090d5..1d90cae 100644
> > --- a/backend/src/libocl/include/ocl_sync.h
> > +++ b/backend/src/libocl/include/ocl_sync.h
> > @@ -31,5 +31,6 @@ OVERLOADABLE void barrier(cl_mem_fence_flags
> flags);
> > void mem_fence(cl_mem_fence_flags flags);  void
> > read_mem_fence(cl_mem_fence_flags flags);  void
> > write_mem_fence(cl_mem_fence_flags flags);
> > +OVERLOADABLE void debugwait(void);
> >
> >  #endif  /* __OCL_SYNC_H__ */
> > diff --git a/backend/src/libocl/src/ocl_barrier.ll
> > b/backend/src/libocl/src/ocl_barrier.ll
> > index 2765a71..9416f80 100644
> > --- a/backend/src/libocl/src/ocl_barrier.ll
> > +++ b/backend/src/libocl/src/ocl_barrier.ll
> > @@ -12,6 +12,7 @@ declare i32 @_get_global_mem_fence() nounwind
> > alwaysinline  declare void @__gen_ocl_barrier_local() nounwind
> > alwaysinline noduplicate  declare void @__gen_ocl_barrier_global()
> > nounwind alwaysinline noduplicate  declare void
> > @__gen_ocl_barrier_local_and_global() nounwind alwaysinline
> > noduplicate
> > +declare void @__gen_ocl_debugwait() nounwind alwaysinline
> noduplicate
> >
> >  define void @_Z7barrierj(i32 %flags) nounwind noduplicate alwaysinline {
> >    %1 = icmp eq i32 %flags, 3
> > @@ -40,3 +41,8 @@ barrier_global:
> >  done:
> >    ret void
> >  }
> > +
> > +define void @_Z9debugwaitv() nounwind noduplicate alwaysinline {
> > +  call void @__gen_ocl_debugwait()
> > +  ret void
> > +}
> > diff --git a/backend/src/libocl/src/ocl_sync.cl
> > b/backend/src/libocl/src/ocl_sync.cl
> > index d008639..70d6f26 100644
> > --- a/backend/src/libocl/src/ocl_sync.cl
> > +++ b/backend/src/libocl/src/ocl_sync.cl
> > @@ -20,6 +20,7 @@
> >  void __gen_ocl_barrier_local(void);
> >  void __gen_ocl_barrier_global(void);
> >  void __gen_ocl_barrier_local_and_global(void);
> > +void __gen_ocl_debugwait(void);
> >
> >  void mem_fence(cl_mem_fence_flags flags) {  } diff --git
> > a/backend/src/llvm/llvm_gen_backend.cpp
> > b/backend/src/llvm/llvm_gen_backend.cpp
> > index 3d76265..c42737f 100644
> > --- a/backend/src/llvm/llvm_gen_backend.cpp
> > +++ b/backend/src/llvm/llvm_gen_backend.cpp
> > @@ -3544,6 +3544,7 @@ namespace gbe
> >          this->newRegister(&I);
> >          break;
> >        case GEN_OCL_PRINTF:
> > +      case GEN_OCL_DEBUGWAIT:
> >          break;
> >        case GEN_OCL_NOT_FOUND:
> >        default:
> > @@ -4249,6 +4250,11 @@ namespace gbe
> >              ctx.SIMD_SHUFFLE(getType(ctx, I.getType()), dst, src0, src1);
> >              break;
> >            }
> > +          case GEN_OCL_DEBUGWAIT:
> > +          {
> > +            ctx.WAIT();
> > +            break;
> > +          }
> >            default: break;
> >          }
> >        }
> > diff --git a/backend/src/llvm/llvm_gen_ocl_function.hxx
> > b/backend/src/llvm/llvm_gen_ocl_function.hxx
> > index cabb225..0f81b46 100644
> > --- a/backend/src/llvm/llvm_gen_ocl_function.hxx
> > +++ b/backend/src/llvm/llvm_gen_ocl_function.hxx
> > @@ -170,3 +170,5 @@ DECL_LLVM_GEN_FUNCTION(REGION,
> > __gen_ocl_region)
> >
> >  // printf function
> >  DECL_LLVM_GEN_FUNCTION(PRINTF, __gen_ocl_printf)
> > +// debug wait function
> > +DECL_LLVM_GEN_FUNCTION(DEBUGWAIT, __gen_ocl_debugwait)
> > --
> > 2.1.4
> >
> > _______________________________________________
> > Beignet mailing list
> > Beignet at lists.freedesktop.org
> > http://lists.freedesktop.org/mailman/listinfo/beignet


More information about the Beignet mailing list