@@ -1925,20 +1925,27 @@ static pi_result SetKernelParamsAndLaunch(
1925
1925
// The function is used as argument to piEnqueueNativeKernel which requires
1926
1926
// that the passed function takes one void* argument.
1927
1927
void DispatchNativeKernel (void *Blob) {
1928
- // First value is a pointer to Corresponding CGExecKernel object.
1929
- CGExecKernel *HostTask = *(CGExecKernel **)Blob;
1930
- bool ShouldDeleteCG = static_cast <void **>(Blob)[1 ] != nullptr ;
1928
+ void **CastedBlob = (void **)Blob;
1929
+
1930
+ std::vector<Requirement *> *Reqs =
1931
+ static_cast <std::vector<Requirement *> *>(CastedBlob[0 ]);
1932
+
1933
+ std::unique_ptr<HostKernelBase> *HostKernel =
1934
+ static_cast <std::unique_ptr<HostKernelBase> *>(CastedBlob[1 ]);
1935
+
1936
+ NDRDescT *NDRDesc = static_cast <NDRDescT *>(CastedBlob[2 ]);
1931
1937
1932
1938
// Other value are pointer to the buffers.
1933
- void **NextArg = static_cast < void **>(Blob) + 2 ;
1934
- for (detail::Requirement *Req : HostTask-> MRequirements )
1939
+ void **NextArg = CastedBlob + 3 ;
1940
+ for (detail::Requirement *Req : *Reqs )
1935
1941
Req->MData = *(NextArg++);
1936
- HostTask->MHostKernel ->call (HostTask->MNDRDesc , nullptr );
1937
1942
1938
- // The command group will (if not already was) be released in scheduler.
1939
- // Hence we're free to deallocate it here.
1940
- if (ShouldDeleteCG)
1941
- delete HostTask;
1943
+ (*HostKernel)->call (*NDRDesc, nullptr );
1944
+
1945
+ // The ownership of these objects have been passed to us, need to cleanup
1946
+ delete Reqs;
1947
+ delete HostKernel;
1948
+ delete NDRDesc;
1942
1949
}
1943
1950
1944
1951
cl_int enqueueImpKernel (
@@ -2118,15 +2125,26 @@ cl_int ExecCGCommand::enqueueImp() {
2118
2125
2119
2126
// piEnqueueNativeKernel takes arguments blob which is passes to user
2120
2127
// function.
2121
- // Reserve extra space for the pointer to CGExecKernel to restore context.
2122
- std::vector<void *> ArgsBlob (HostTask->MArgs .size () + 2 );
2123
- ArgsBlob[0 ] = (void *)HostTask;
2124
- {
2125
- std::intptr_t ShouldDeleteCG =
2126
- static_cast <std::intptr_t >(MDeps.size () == 0 && MUsers.size () == 0 );
2127
- ArgsBlob[1 ] = reinterpret_cast <void *>(ShouldDeleteCG);
2128
- }
2129
- void **NextArg = ArgsBlob.data () + 2 ;
2128
+ // Need the following items to restore context in the host task.
2129
+ // Make a copy on heap to "dettach" from the command group as it can be
2130
+ // released before the host task completes.
2131
+ std::vector<void *> ArgsBlob (HostTask->MArgs .size () + 3 );
2132
+
2133
+ std::vector<Requirement *> *CopyReqs =
2134
+ new std::vector<Requirement *>(HostTask->MRequirements );
2135
+
2136
+ // Not actually a copy, but move. Should be OK as it's not expected that
2137
+ // MHostKernel will be used elsewhere.
2138
+ std::unique_ptr<HostKernelBase> *CopyHostKernel =
2139
+ new std::unique_ptr<HostKernelBase>(std::move (HostTask->MHostKernel ));
2140
+
2141
+ NDRDescT *CopyNDRDesc = new NDRDescT (HostTask->MNDRDesc );
2142
+
2143
+ ArgsBlob[0 ] = (void *)CopyReqs;
2144
+ ArgsBlob[1 ] = (void *)CopyHostKernel;
2145
+ ArgsBlob[2 ] = (void *)CopyNDRDesc;
2146
+
2147
+ void **NextArg = ArgsBlob.data () + 3 ;
2130
2148
2131
2149
if (MQueue->is_host ()) {
2132
2150
for (ArgDesc &Arg : HostTask->MArgs ) {
0 commit comments