[Beignet] [PATCH 2/2] Backend: add debugwait function
Pan, Xiuli
xiuli.pan at intel.com
Tue Nov 3 01:23:26 PST 2015
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.
-----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