@@ -154,6 +154,8 @@ runKernelWithArg(KernelType KernelName, ArgType Arg) {
154154// The pure virtual class aimed to store lambda/functors of any type.
155155class HostKernelBase {
156156public:
157+ // NOTE: InstatitateKernelOnHost() should not be called.
158+ virtual void InstatitateKernelOnHost () = 0;
157159 // Return pointer to the lambda object.
158160 // Used to extract captured variables.
159161 virtual char *getPtr () = 0;
@@ -172,6 +174,50 @@ class HostKernel : public HostKernelBase {
172174public:
173175 HostKernel (KernelType Kernel) : MKernel(Kernel) {}
174176
177+ // This function is needed for host-side compilation to keep kernels
178+ // instantitated. This is important for debuggers to be able to associate
179+ // kernel code instructions with source code lines.
180+ // NOTE: InstatitateKernelOnHost() should not be called.
181+ void InstatitateKernelOnHost () override {
182+ if constexpr (std::is_same_v<KernelArgType, void >) {
183+ runKernelWithoutArg (MKernel);
184+ } else if constexpr (std::is_same_v<KernelArgType, sycl::id<Dims>>) {
185+ sycl::id ID = InitializedVal<Dims, id>::template get<0 >();
186+ runKernelWithArg<const KernelArgType &>(MKernel, ID);
187+ } else if constexpr (std::is_same_v<KernelArgType, item<Dims, true >> ||
188+ std::is_same_v<KernelArgType, item<Dims, false >>) {
189+ constexpr bool HasOffset =
190+ std::is_same_v<KernelArgType, item<Dims, true >>;
191+ KernelArgType Item = IDBuilder::createItem<Dims, HasOffset>(
192+ InitializedVal<Dims, range>::template get<1 >(),
193+ InitializedVal<Dims, id>::template get<0 >());
194+ runKernelWithArg<KernelArgType>(MKernel, Item);
195+ } else if constexpr (std::is_same_v<KernelArgType, nd_item<Dims>>) {
196+ sycl::range<Dims> Range = InitializedVal<Dims, range>::template get<1 >();
197+ sycl::id<Dims> ID = InitializedVal<Dims, id>::template get<0 >();
198+ sycl::group<Dims> Group =
199+ IDBuilder::createGroup<Dims>(Range, Range, Range, ID);
200+ sycl::item<Dims, true > GlobalItem =
201+ IDBuilder::createItem<Dims, true >(Range, ID, ID);
202+ sycl::item<Dims, false > LocalItem =
203+ IDBuilder::createItem<Dims, false >(Range, ID);
204+ KernelArgType NDItem =
205+ IDBuilder::createNDItem<Dims>(GlobalItem, LocalItem, Group);
206+ runKernelWithArg<const KernelArgType>(MKernel, NDItem);
207+ } else if constexpr (std::is_same_v<KernelArgType, sycl::group<Dims>>) {
208+ sycl::range<Dims> Range = InitializedVal<Dims, range>::template get<1 >();
209+ sycl::id<Dims> ID = InitializedVal<Dims, id>::template get<0 >();
210+ KernelArgType Group =
211+ IDBuilder::createGroup<Dims>(Range, Range, Range, ID);
212+ runKernelWithArg<KernelArgType>(MKernel, Group);
213+ } else {
214+ // Assume that anything else can be default-constructed. If not, this
215+ // should fail to compile and the implementor should implement a generic
216+ // case for the new argument type.
217+ runKernelWithArg<KernelArgType>(MKernel, KernelArgType{});
218+ }
219+ }
220+
175221 char *getPtr () override { return reinterpret_cast <char *>(&MKernel); }
176222
177223 ~HostKernel () = default ;
0 commit comments