Skip to content

Commit 0c19b88

Browse files
author
Sergey Kanaev
committed
[SYCL] Fix review comments.
Signed-off-by: Sergey Kanaev <[email protected]>
1 parent 5495889 commit 0c19b88

File tree

2 files changed

+34
-6
lines changed

2 files changed

+34
-6
lines changed

sycl/include/CL/sycl/detail/kernel_program_cache.hpp

+7-1
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,15 @@ namespace detail {
2525
class context_impl;
2626
class KernelProgramCache {
2727
public:
28+
/// Denotes build error data. The data is filled in from cl::sycl::exception
29+
/// class instance.
2830
struct BuildError {
2931
std::string Msg;
30-
cl_int Code;
32+
pi_int32 Code;
33+
34+
/// Equals to true if the Msg and Code are initialized. This flag is added
35+
/// due to possibility of Code equal to zero even if there is a
36+
/// cl::sycl::exception thrown
3137
bool FilledIn;
3238
};
3339

sycl/source/detail/program_manager/program_manager.cpp

+27-5
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,8 @@ DeviceImage &ProgramManager::getDeviceImage(OSModuleHandle M,
111111

112112
template <typename ExceptionT, typename RetT>
113113
RetT *waitUntilBuilt(KernelProgramCache &Cache,
114-
KernelProgramCache::BuildResult<RetT> *BuildResult) {
114+
KernelProgramCache::BuildResult<RetT> *BuildResult,
115+
bool &TryAgain) {
115116
// any thread which will find nullptr in cache will wait until the pointer
116117
// is not null anymore
117118
Cache.waitUntilBuilt([BuildResult]() {
@@ -127,7 +128,9 @@ RetT *waitUntilBuilt(KernelProgramCache &Cache,
127128

128129
RetT *Result = BuildResult->Ptr.load();
129130

130-
assert(Result && "An exception should have been thrown");
131+
// if the result is still null then there was no SYCL exception and we may try
132+
// to build kernel/program once more to generate the original exception
133+
TryAgain = !Result;
131134

132135
return Result;
133136
}
@@ -170,10 +173,29 @@ RetT *getOrBuild(KernelProgramCache &KPCache, const KeyT &CacheKey,
170173
// no insertion took place, thus some other thread has already inserted smth
171174
// in the cache
172175
if (!InsertionTookPlace) {
173-
return waitUntilBuilt<ExceptionT>(KPCache, BuildResult);
176+
bool TryAgain = false;
177+
178+
for (;;) {
179+
RetT *Result = waitUntilBuilt<ExceptionT>(KPCache, BuildResult, TryAgain);
180+
181+
if (TryAgain) {
182+
// Previous build is failed. There was no SYCL exception though.
183+
// We might try to build once more.
184+
int Expected = BS_Failed;
185+
int Desired = BS_InProgress;
186+
187+
if (BuildResult->State.compare_exchange_strong(Expected, Desired)) {
188+
// this thread is the building thread now
189+
break;
190+
}
191+
192+
continue;
193+
} else // no need to try once more
194+
return Result;
195+
}
174196
}
175197

176-
// only the building thread will run this, and only once.
198+
// only the building thread will run this
177199
try {
178200
RetT *Desired = Build();
179201

@@ -184,7 +206,7 @@ RetT *getOrBuild(KernelProgramCache &KPCache, const KeyT &CacheKey,
184206
// We've got a funny story here
185207
assert(false && "We've build an entity that is already have been built.");
186208
#else
187-
WithState->Ptr.store(Desired);
209+
BuildResult->Ptr.store(Desired);
188210
#endif
189211

190212
BuildResult->State.store(BS_Done);

0 commit comments

Comments
 (0)