DPC++ Runtime
Runtime libraries for oneAPI DPC++
kernel_program_cache.hpp
Go to the documentation of this file.
1 //==--- kernel_program_cache.hpp - Cache for kernel and program -*- C++-*---==//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #pragma once
10 
11 #include <detail/platform_impl.hpp>
12 #include <sycl/detail/common.hpp>
13 #include <sycl/detail/locked.hpp>
14 #include <sycl/detail/os_util.hpp>
15 #include <sycl/detail/pi.hpp>
16 #include <sycl/detail/util.hpp>
17 
18 #include <atomic>
19 #include <condition_variable>
20 #include <map>
21 #include <mutex>
22 #include <type_traits>
23 
24 // For testing purposes
25 class MockKernelProgramCache;
26 
27 namespace sycl {
29 namespace detail {
30 class context_impl;
32 public:
35  struct BuildError {
36  std::string Msg;
38 
39  bool isFilledIn() const { return !Msg.empty(); }
40  };
41 
46  template <typename T> struct BuildResult {
47  std::atomic<T *> Ptr;
48  std::atomic<int> State;
50 
61  std::condition_variable MBuildCV;
63  std::mutex MBuildResultMutex;
64 
65  BuildResult(T *P, int S) : Ptr{P}, State{S}, Error{"", 0} {}
66  };
67 
68  using PiProgramT = std::remove_pointer<RT::PiProgram>::type;
69  using PiProgramPtrT = std::atomic<PiProgramT *>;
71  using ProgramCacheKeyT = std::pair<std::pair<SerializedObj, std::uintptr_t>,
72  std::pair<RT::PiDevice, std::string>>;
73  using ProgramCacheT = std::map<ProgramCacheKeyT, ProgramWithBuildStateT>;
75 
76  using PiKernelT = std::remove_pointer<RT::PiKernel>::type;
77 
78  using PiKernelPtrT = std::atomic<PiKernelT *>;
80  using KernelByNameT = std::map<std::string, KernelWithBuildStateT>;
81  using KernelCacheT = std::map<RT::PiProgram, KernelByNameT>;
82 
84  std::tuple<SerializedObj, OSModuleHandle, RT::PiDevice, std::string,
85  std::string>;
87  std::tuple<RT::PiKernel, std::mutex *, RT::PiProgram>;
88  using KernelFastCacheT = std::map<KernelFastCacheKeyT, KernelFastCacheValT>;
89 
91 
92  void setContextPtr(const ContextPtr &AContext) { MParentContext = AContext; }
93 
95  return {MCachedPrograms, MProgramCacheMutex};
96  }
97 
99  return {MKernelsPerProgramCache, MKernelsPerProgramCacheMutex};
100  }
101 
102  template <typename T, class Predicate>
103  void waitUntilBuilt(BuildResult<T> &BR, Predicate Pred) const {
104  std::unique_lock<std::mutex> Lock(BR.MBuildResultMutex);
105 
106  BR.MBuildCV.wait(Lock, Pred);
107  }
108 
109  template <typename T> void notifyAllBuild(BuildResult<T> &BR) const {
110  BR.MBuildCV.notify_all();
111  }
112 
113  template <typename KeyT>
115  std::unique_lock<std::mutex> Lock(MKernelFastCacheMutex);
116  auto It = MKernelFastCache.find(CacheKey);
117  if (It != MKernelFastCache.end()) {
118  return It->second;
119  }
120  return std::make_tuple(nullptr, nullptr, nullptr);
121  }
122 
123  template <typename KeyT, typename ValT>
124  void saveKernel(KeyT &&CacheKey, ValT &&CacheVal) {
125  std::unique_lock<std::mutex> Lock(MKernelFastCacheMutex);
126  // if no insertion took place, thus some other thread has already inserted
127  // smth in the cache
128  MKernelFastCache.emplace(CacheKey, CacheVal);
129  }
130 
134  void reset() {
135  MCachedPrograms = ProgramCacheT{};
136  MKernelsPerProgramCache = KernelCacheT{};
137  MKernelFastCache = KernelFastCacheT{};
138  }
139 
140 private:
141  std::mutex MProgramCacheMutex;
142  std::mutex MKernelsPerProgramCacheMutex;
143 
144  ProgramCacheT MCachedPrograms;
145  KernelCacheT MKernelsPerProgramCache;
146  ContextPtr MParentContext;
147 
148  std::mutex MKernelFastCacheMutex;
149  KernelFastCacheT MKernelFastCache;
150  friend class ::MockKernelProgramCache;
151 };
152 } // namespace detail
153 } // __SYCL_INLINE_VER_NAMESPACE(_V1)
154 } // namespace sycl
std::pair< std::pair< SerializedObj, std::uintptr_t >, std::pair< RT::PiDevice, std::string > > ProgramCacheKeyT
std::map< RT::PiProgram, KernelByNameT > KernelCacheT
std::remove_pointer< RT::PiProgram >::type PiProgramT
std::map< KernelFastCacheKeyT, KernelFastCacheValT > KernelFastCacheT
std::map< std::string, KernelWithBuildStateT > KernelByNameT
std::tuple< SerializedObj, OSModuleHandle, RT::PiDevice, std::string, std::string > KernelFastCacheKeyT
std::atomic< PiProgramT * > PiProgramPtrT
std::remove_pointer< RT::PiKernel >::type PiKernelT
void setContextPtr(const ContextPtr &AContext)
std::tuple< RT::PiKernel, std::mutex *, RT::PiProgram > KernelFastCacheValT
Locked< KernelCacheT > acquireKernelsPerProgramCache()
void notifyAllBuild(BuildResult< T > &BR) const
KernelFastCacheValT tryToGetKernelFast(KeyT &&CacheKey)
Locked< ProgramCacheT > acquireCachedPrograms()
void waitUntilBuilt(BuildResult< T > &BR, Predicate Pred) const
std::map< ProgramCacheKeyT, ProgramWithBuildStateT > ProgramCacheT
void saveKernel(KeyT &&CacheKey, ValT &&CacheVal)
Represents a reference to value with appropriate lock acquired.
Definition: locked.hpp:23
#define __SYCL_INLINE_VER_NAMESPACE(X)
::pi_device PiDevice
Definition: pi.hpp:110
constexpr tuple< Ts... > make_tuple(Ts... Args)
Definition: tuple.hpp:36
std::vector< unsigned char > SerializedObj
Definition: util.hpp:68
intptr_t OSModuleHandle
Uniquely identifies an operating system module (executable or a dynamic library)
Definition: os_util.hpp:48
---— Error handling, matching OpenCL plugin semantics.
Definition: access.hpp:14
int32_t pi_int32
Definition: pi.h:102
C++ wrapper of extern "C" PI interfaces.
Denotes pointer to some entity with its general state and build error.
std::mutex MBuildResultMutex
A mutex to be employed along with MBuildCV.
std::condition_variable MBuildCV
Condition variable to signal that build result is ready.