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