1 // WorkGroup.h (Oclgrind)
2 // Copyright (c) 2013-2019, James Price and Simon McIntosh-Smith,
3 // University of Bristol. All rights reserved.
4 //
5 // This program is provided under a three-clause BSD license. For full
6 // license terms please see the LICENSE file distributed with this
7 // source code.
8 
9 #include "common.h"
10 
11 #define CLK_LOCAL_MEM_FENCE (1 << 0)
12 #define CLK_GLOBAL_MEM_FENCE (1 << 1)
13 
14 namespace oclgrind
15 {
16 class Context;
17 class Memory;
18 class Kernel;
19 class KernelInvocation;
20 class WorkItem;
21 
22 class WorkGroup
23 {
24 public:
25   enum AsyncCopyType
26   {
27     GLOBAL_TO_LOCAL,
28     LOCAL_TO_GLOBAL
29   };
30 
31 private:
32   // Comparator for ordering work-items
33   struct WorkItemCmp
34   {
35     bool operator()(const WorkItem* lhs, const WorkItem* rhs) const;
36   };
37   std::set<WorkItem*, WorkItemCmp> m_running;
38 
39   struct AsyncCopy
40   {
41     const llvm::Instruction* instruction;
42     AsyncCopyType type;
43     size_t dest;
44     size_t src;
45     size_t size;
46     size_t num;
47     size_t srcStride;
48     size_t destStride;
49 
50     size_t event;
51   };
52 
53   struct Barrier
54   {
55     const llvm::Instruction* instruction;
56     std::set<WorkItem*, WorkItemCmp> workItems;
57 
58     uint64_t fence;
59     std::list<size_t> events;
60   };
61 
62 public:
63   WorkGroup(const KernelInvocation* kernelInvocation, Size3 wgid);
64   WorkGroup(const KernelInvocation* kernelInvocation, Size3 wgid, Size3 size);
65   virtual ~WorkGroup();
66 
67   size_t async_copy(const WorkItem* workItem,
68                     const llvm::Instruction* instruction, AsyncCopyType type,
69                     size_t dest, size_t src, size_t size, size_t num,
70                     size_t srcStride, size_t destStride, size_t event);
71   void clearBarrier();
72   const llvm::Instruction* getCurrentBarrier() const;
73   Size3 getGroupID() const;
74   size_t getGroupIndex() const;
75   Size3 getGroupSize() const;
76   Memory* getLocalMemory() const;
77   size_t getLocalMemoryAddress(const llvm::Value* value) const;
78   WorkItem* getNextWorkItem() const;
79   WorkItem* getWorkItem(Size3 localID) const;
80   bool hasBarrier() const;
81   void notifyBarrier(WorkItem* workItem, const llvm::Instruction* instruction,
82                      uint64_t fence,
83                      std::list<size_t> events = std::list<size_t>());
84   void notifyFinished(WorkItem* workItem);
85 
86 private:
87   size_t m_groupIndex;
88   Size3 m_groupID;
89   Size3 m_groupSize;
90   const Context* m_context;
91 
92   Memory* m_localMemory;
93   std::map<const llvm::Value*, size_t> m_localAddresses;
94 
95   std::vector<WorkItem*> m_workItems;
96 
97   Barrier* m_barrier;
98   size_t m_nextEvent;
99   std::list<std::pair<AsyncCopy, std::set<const WorkItem*>>> m_asyncCopies;
100   std::map<size_t, std::list<AsyncCopy>> m_events;
101 };
102 } // namespace oclgrind
103