diff --git a/opencl/source/command_queue/command_queue_hw.h b/opencl/source/command_queue/command_queue_hw.h index 03a30a4a8c..92dc5f397e 100644 --- a/opencl/source/command_queue/command_queue_hw.h +++ b/opencl/source/command_queue/command_queue_hw.h @@ -344,42 +344,42 @@ class CommandQueueHw : public CommandQueue { cl_int flush() override; template - void enqueueHandler(Surface **surfacesForResidency, - size_t numSurfaceForResidency, - bool blocking, - const MultiDispatchInfo &dispatchInfo, - cl_uint numEventsInWaitList, - const cl_event *eventWaitList, - cl_event *event); + cl_int enqueueHandler(Surface **surfacesForResidency, + size_t numSurfaceForResidency, + bool blocking, + const MultiDispatchInfo &dispatchInfo, + cl_uint numEventsInWaitList, + const cl_event *eventWaitList, + cl_event *event); template - void enqueueHandler(Surface *(&surfacesForResidency)[size], - bool blocking, - const MultiDispatchInfo &dispatchInfo, - cl_uint numEventsInWaitList, - const cl_event *eventWaitList, - cl_event *event) { - enqueueHandler(surfacesForResidency, size, blocking, dispatchInfo, numEventsInWaitList, eventWaitList, event); + cl_int enqueueHandler(Surface *(&surfacesForResidency)[size], + bool blocking, + const MultiDispatchInfo &dispatchInfo, + cl_uint numEventsInWaitList, + const cl_event *eventWaitList, + cl_event *event) { + return enqueueHandler(surfacesForResidency, size, blocking, dispatchInfo, numEventsInWaitList, eventWaitList, event); } template - void enqueueHandler(Surface *(&surfacesForResidency)[size], - bool blocking, - Kernel *kernel, - cl_uint workDim, - const size_t globalOffsets[3], - const size_t workItems[3], - const size_t *localWorkSizesIn, - const size_t *enqueuedWorkSizes, - cl_uint numEventsInWaitList, - const cl_event *eventWaitList, - cl_event *event); + cl_int enqueueHandler(Surface *(&surfacesForResidency)[size], + bool blocking, + Kernel *kernel, + cl_uint workDim, + const size_t globalOffsets[3], + const size_t workItems[3], + const size_t *localWorkSizesIn, + const size_t *enqueuedWorkSizes, + cl_uint numEventsInWaitList, + const cl_event *eventWaitList, + cl_event *event); template - void dispatchBcsOrGpgpuEnqueue(MultiDispatchInfo &dispatchInfo, Surface *(&surfaces)[surfaceCount], EBuiltInOps::Type builtInOperation, cl_uint numEventsInWaitList, const cl_event *eventWaitList, cl_event *event, bool blocking, CommandStreamReceiver &csr); + cl_int dispatchBcsOrGpgpuEnqueue(MultiDispatchInfo &dispatchInfo, Surface *(&surfaces)[surfaceCount], EBuiltInOps::Type builtInOperation, cl_uint numEventsInWaitList, const cl_event *eventWaitList, cl_event *event, bool blocking, CommandStreamReceiver &csr); template - void enqueueBlit(const MultiDispatchInfo &multiDispatchInfo, cl_uint numEventsInWaitList, const cl_event *eventWaitList, cl_event *event, bool blocking, CommandStreamReceiver &bcsCsr); + cl_int enqueueBlit(const MultiDispatchInfo &multiDispatchInfo, cl_uint numEventsInWaitList, const cl_event *eventWaitList, cl_event *event, bool blocking, CommandStreamReceiver &bcsCsr); template CompletionStamp enqueueNonBlocked(Surface **surfacesForResidency, diff --git a/opencl/source/command_queue/command_queue_hw_base.inl b/opencl/source/command_queue/command_queue_hw_base.inl index 45ea931a23..38e3119df5 100644 --- a/opencl/source/command_queue/command_queue_hw_base.inl +++ b/opencl/source/command_queue/command_queue_hw_base.inl @@ -91,13 +91,18 @@ cl_int CommandQueueHw::enqueueMarkerForReadWriteOperation(MemObj *memObj MultiDispatchInfo multiDispatchInfo; NullSurface s; Surface *surfaces[] = {&s}; - enqueueHandler( + const auto enqueueResult = enqueueHandler( surfaces, blocking == CL_TRUE, multiDispatchInfo, numEventsInWaitList, eventWaitList, event); + + if (enqueueResult != CL_SUCCESS) { + return enqueueResult; + } + if (event) { auto pEvent = castToObjectOrAbort(*event); pEvent->setCmdType(commandType); diff --git a/opencl/source/command_queue/enqueue_barrier.h b/opencl/source/command_queue/enqueue_barrier.h index a5258a8959..0df85d38fd 100644 --- a/opencl/source/command_queue/enqueue_barrier.h +++ b/opencl/source/command_queue/enqueue_barrier.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018-2021 Intel Corporation + * Copyright (C) 2018-2022 Intel Corporation * * SPDX-License-Identifier: MIT * @@ -24,12 +24,12 @@ cl_int CommandQueueHw::enqueueBarrierWithWaitList( cl_event *event) { NullSurface s; Surface *surfaces[] = {&s}; - enqueueHandler(surfaces, - false, - MultiDispatchInfo(), - numEventsInWaitList, - eventWaitList, - event); - return CL_SUCCESS; + return enqueueHandler(surfaces, + false, + MultiDispatchInfo(), + numEventsInWaitList, + eventWaitList, + event); } + } // namespace NEO diff --git a/opencl/source/command_queue/enqueue_common.h b/opencl/source/command_queue/enqueue_common.h index 62adace52e..2e25880dd4 100644 --- a/opencl/source/command_queue/enqueue_common.h +++ b/opencl/source/command_queue/enqueue_common.h @@ -8,6 +8,7 @@ #pragma once #include "shared/source/built_ins/built_ins.h" #include "shared/source/command_stream/command_stream_receiver.h" +#include "shared/source/command_stream/wait_status.h" #include "shared/source/helpers/array_count.h" #include "shared/source/helpers/engine_node_helper.h" #include "shared/source/helpers/local_work_size.h" @@ -48,17 +49,17 @@ namespace NEO { template template -void CommandQueueHw::enqueueHandler(Surface *(&surfaces)[surfaceCount], - bool blocking, - Kernel *kernel, - cl_uint workDim, - const size_t globalOffsets[3], - const size_t workItems[3], - const size_t *localWorkSizesIn, - const size_t *enqueuedWorkSizes, - cl_uint numEventsInWaitList, - const cl_event *eventWaitList, - cl_event *event) { +cl_int CommandQueueHw::enqueueHandler(Surface *(&surfaces)[surfaceCount], + bool blocking, + Kernel *kernel, + cl_uint workDim, + const size_t globalOffsets[3], + const size_t workItems[3], + const size_t *localWorkSizesIn, + const size_t *enqueuedWorkSizes, + cl_uint numEventsInWaitList, + const cl_event *eventWaitList, + cl_event *event) { BuiltInOwnershipWrapper builtInLock; KernelObjsForAuxTranslation kernelObjsForAuxTranslation; MultiDispatchInfo multiDispatchInfo(kernel); @@ -92,7 +93,7 @@ void CommandQueueHw::enqueueHandler(Surface *(&surfaces)[surfaceCount builder->buildDispatchInfos(multiDispatchInfo, kernel, workDim, workItems, enqueuedWorkSizes, globalOffsets); if (multiDispatchInfo.size() == 0) { - return; + return CL_SUCCESS; } } @@ -104,25 +105,29 @@ void CommandQueueHw::enqueueHandler(Surface *(&surfaces)[surfaceCount setupBlitAuxTranslation(multiDispatchInfo); } - enqueueHandler(surfaces, blocking, multiDispatchInfo, numEventsInWaitList, eventWaitList, event); + return enqueueHandler(surfaces, blocking, multiDispatchInfo, numEventsInWaitList, eventWaitList, event); } template template -void CommandQueueHw::enqueueHandler(Surface **surfacesForResidency, - size_t numSurfaceForResidency, - bool blocking, - const MultiDispatchInfo &multiDispatchInfo, - cl_uint numEventsInWaitList, - const cl_event *eventWaitList, - cl_event *event) { +cl_int CommandQueueHw::enqueueHandler(Surface **surfacesForResidency, + size_t numSurfaceForResidency, + bool blocking, + const MultiDispatchInfo &multiDispatchInfo, + cl_uint numEventsInWaitList, + const cl_event *eventWaitList, + cl_event *event) { if (multiDispatchInfo.empty() && !isCommandWithoutKernel(commandType)) { - enqueueHandler(nullptr, 0, blocking, multiDispatchInfo, - numEventsInWaitList, eventWaitList, event); + const auto enqueueResult = enqueueHandler(nullptr, 0, blocking, multiDispatchInfo, + numEventsInWaitList, eventWaitList, event); + if (enqueueResult != CL_SUCCESS) { + return enqueueResult; + } + if (event) { castToObjectOrAbort(*event)->setCmdType(commandType); } - return; + return CL_SUCCESS; } TagNodeBase *hwTimeStamps = nullptr; @@ -357,22 +362,35 @@ void CommandQueueHw::enqueueHandler(Surface **surfacesForResidency, queueOwnership.unlock(); if (blocking) { + auto waitStatus = WaitStatus::Ready; auto &builtinOpParams = multiDispatchInfo.peekBuiltinOpParams(); if (builtinOpParams.userPtrForPostOperationCpuCopy) { - waitForAllEngines(blockQueue, (blockQueue ? nullptr : printfHandler.get()), false); + waitStatus = waitForAllEngines(blockQueue, (blockQueue ? nullptr : printfHandler.get()), false); + if (waitStatus == WaitStatus::GpuHang) { + return CL_OUT_OF_RESOURCES; + } + auto hostPtrAlloc = builtinOpParams.transferAllocation; UNRECOVERABLE_IF(nullptr == hostPtrAlloc); auto size = hostPtrAlloc->getUnderlyingBufferSize(); [[maybe_unused]] int cpuCopyStatus = memcpy_s(builtinOpParams.userPtrForPostOperationCpuCopy, size, hostPtrAlloc->getUnderlyingBuffer(), size); DEBUG_BREAK_IF(cpuCopyStatus != 0); - waitForAllEngines(blockQueue, (blockQueue ? nullptr : printfHandler.get()), true); + + waitStatus = waitForAllEngines(blockQueue, (blockQueue ? nullptr : printfHandler.get()), true); } else { - waitForAllEngines(blockQueue, (blockQueue ? nullptr : printfHandler.get()), true); + waitStatus = waitForAllEngines(blockQueue, (blockQueue ? nullptr : printfHandler.get()), true); + } + + if (waitStatus == WaitStatus::GpuHang) { + return CL_OUT_OF_RESOURCES; } } + if (migratedMemory) { computeCommandStreamReceiver.flushBatchedSubmissions(); } + + return CL_SUCCESS; } template @@ -1067,7 +1085,7 @@ size_t CommandQueueHw::calculateHostPtrSizeForImage(const size_t *reg template template -void CommandQueueHw::enqueueBlit(const MultiDispatchInfo &multiDispatchInfo, cl_uint numEventsInWaitList, const cl_event *eventWaitList, cl_event *event, bool blocking, CommandStreamReceiver &bcsCsr) { +cl_int CommandQueueHw::enqueueBlit(const MultiDispatchInfo &multiDispatchInfo, cl_uint numEventsInWaitList, const cl_event *eventWaitList, cl_event *event, bool blocking, CommandStreamReceiver &bcsCsr) { auto bcsCommandStreamReceiverOwnership = bcsCsr.obtainUniqueOwnership(); EventsRequest eventsRequest(numEventsInWaitList, eventWaitList, event); @@ -1159,17 +1177,22 @@ void CommandQueueHw::enqueueBlit(const MultiDispatchInfo &multiDispat bcsCommandStreamReceiverOwnership.unlock(); if (blocking) { - waitForAllEngines(blockQueue, nullptr); + const auto waitStatus = waitForAllEngines(blockQueue, nullptr); + if (waitStatus == WaitStatus::GpuHang) { + return CL_OUT_OF_RESOURCES; + } } + + return CL_SUCCESS; } template template -void CommandQueueHw::dispatchBcsOrGpgpuEnqueue(MultiDispatchInfo &dispatchInfo, Surface *(&surfaces)[surfaceCount], EBuiltInOps::Type builtInOperation, cl_uint numEventsInWaitList, const cl_event *eventWaitList, cl_event *event, bool blocking, CommandStreamReceiver &csr) { +cl_int CommandQueueHw::dispatchBcsOrGpgpuEnqueue(MultiDispatchInfo &dispatchInfo, Surface *(&surfaces)[surfaceCount], EBuiltInOps::Type builtInOperation, cl_uint numEventsInWaitList, const cl_event *eventWaitList, cl_event *event, bool blocking, CommandStreamReceiver &csr) { const bool blit = EngineHelpers::isBcs(csr.getOsContext().getEngineType()); if (blit) { - enqueueBlit(dispatchInfo, numEventsInWaitList, eventWaitList, event, blocking, csr); + return enqueueBlit(dispatchInfo, numEventsInWaitList, eventWaitList, event, blocking, csr); } else { auto &builder = BuiltInDispatchBuilderOp::getBuiltinDispatchInfoBuilder(builtInOperation, this->getClDevice()); @@ -1177,7 +1200,7 @@ void CommandQueueHw::dispatchBcsOrGpgpuEnqueue(MultiDispatchInfo &dis builder.buildDispatchInfos(dispatchInfo); - enqueueHandler( + return enqueueHandler( surfaces, blocking, dispatchInfo, diff --git a/opencl/source/command_queue/enqueue_copy_buffer.h b/opencl/source/command_queue/enqueue_copy_buffer.h index 01183ec514..7a180942ae 100644 --- a/opencl/source/command_queue/enqueue_copy_buffer.h +++ b/opencl/source/command_queue/enqueue_copy_buffer.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018-2021 Intel Corporation + * Copyright (C) 2018-2022 Intel Corporation * * SPDX-License-Identifier: MIT * @@ -51,8 +51,8 @@ cl_int CommandQueueHw::enqueueCopyBuffer( MemObjSurface s1(srcBuffer); MemObjSurface s2(dstBuffer); Surface *surfaces[] = {&s1, &s2}; - dispatchBcsOrGpgpuEnqueue(dispatchInfo, surfaces, eBuiltInOpsType, numEventsInWaitList, eventWaitList, event, false, csr); - return CL_SUCCESS; + return dispatchBcsOrGpgpuEnqueue(dispatchInfo, surfaces, eBuiltInOpsType, numEventsInWaitList, eventWaitList, event, false, csr); } + } // namespace NEO diff --git a/opencl/source/command_queue/enqueue_copy_buffer_rect.h b/opencl/source/command_queue/enqueue_copy_buffer_rect.h index 3a20ce3aa1..7a3a1111ec 100644 --- a/opencl/source/command_queue/enqueue_copy_buffer_rect.h +++ b/opencl/source/command_queue/enqueue_copy_buffer_rect.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018-2021 Intel Corporation + * Copyright (C) 2018-2022 Intel Corporation * * SPDX-License-Identifier: MIT * @@ -58,8 +58,7 @@ cl_int CommandQueueHw::enqueueCopyBufferRect( dc.dstSlicePitch = dstSlicePitch; MultiDispatchInfo dispatchInfo(dc); - dispatchBcsOrGpgpuEnqueue(dispatchInfo, surfaces, eBuiltInOps, numEventsInWaitList, eventWaitList, event, false, csr); - - return CL_SUCCESS; + return dispatchBcsOrGpgpuEnqueue(dispatchInfo, surfaces, eBuiltInOps, numEventsInWaitList, eventWaitList, event, false, csr); } + } // namespace NEO diff --git a/opencl/source/command_queue/enqueue_copy_buffer_to_image.h b/opencl/source/command_queue/enqueue_copy_buffer_to_image.h index 35f3151234..9279f06148 100644 --- a/opencl/source/command_queue/enqueue_copy_buffer_to_image.h +++ b/opencl/source/command_queue/enqueue_copy_buffer_to_image.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018-2021 Intel Corporation + * Copyright (C) 2018-2022 Intel Corporation * * SPDX-License-Identifier: MIT * @@ -57,14 +57,13 @@ cl_int CommandQueueHw::enqueueCopyBufferToImage( MultiDispatchInfo dispatchInfo(dc); builder.buildDispatchInfos(dispatchInfo); - enqueueHandler( + return enqueueHandler( surfaces, false, dispatchInfo, numEventsInWaitList, eventWaitList, event); - - return CL_SUCCESS; } + } // namespace NEO diff --git a/opencl/source/command_queue/enqueue_copy_image.h b/opencl/source/command_queue/enqueue_copy_image.h index 965f2d1f4c..13c14a9349 100644 --- a/opencl/source/command_queue/enqueue_copy_image.h +++ b/opencl/source/command_queue/enqueue_copy_image.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018-2021 Intel Corporation + * Copyright (C) 2018-2022 Intel Corporation * * SPDX-License-Identifier: MIT * @@ -55,8 +55,7 @@ cl_int CommandQueueHw::enqueueCopyImage( MultiDispatchInfo dispatchInfo(dc); - dispatchBcsOrGpgpuEnqueue(dispatchInfo, surfaces, EBuiltInOps::CopyImageToImage3d, numEventsInWaitList, eventWaitList, event, false, csr); - - return CL_SUCCESS; + return dispatchBcsOrGpgpuEnqueue(dispatchInfo, surfaces, EBuiltInOps::CopyImageToImage3d, numEventsInWaitList, eventWaitList, event, false, csr); } + } // namespace NEO diff --git a/opencl/source/command_queue/enqueue_copy_image_to_buffer.h b/opencl/source/command_queue/enqueue_copy_image_to_buffer.h index dbcbfc8247..d098950d3b 100644 --- a/opencl/source/command_queue/enqueue_copy_image_to_buffer.h +++ b/opencl/source/command_queue/enqueue_copy_image_to_buffer.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018-2021 Intel Corporation + * Copyright (C) 2018-2022 Intel Corporation * * SPDX-License-Identifier: MIT * @@ -56,14 +56,13 @@ cl_int CommandQueueHw::enqueueCopyImageToBuffer( MultiDispatchInfo dispatchInfo(dc); builder.buildDispatchInfos(dispatchInfo); - enqueueHandler( + return enqueueHandler( surfaces, false, dispatchInfo, numEventsInWaitList, eventWaitList, event); - - return CL_SUCCESS; } + } // namespace NEO diff --git a/opencl/source/command_queue/enqueue_fill_buffer.h b/opencl/source/command_queue/enqueue_fill_buffer.h index 88c887f491..837aeb432b 100644 --- a/opencl/source/command_queue/enqueue_fill_buffer.h +++ b/opencl/source/command_queue/enqueue_fill_buffer.h @@ -81,7 +81,7 @@ cl_int CommandQueueHw::enqueueFillBuffer( GeneralSurface s2(patternAllocation); Surface *surfaces[] = {&s1, &s2}; - enqueueHandler( + const auto enqueueResult = enqueueHandler( surfaces, false, dispatchInfo, @@ -92,6 +92,6 @@ cl_int CommandQueueHw::enqueueFillBuffer( auto storageForAllocation = getGpgpuCommandStreamReceiver().getInternalAllocationStorage(); storageForAllocation->storeAllocationWithTaskCount(std::unique_ptr(patternAllocation), REUSABLE_ALLOCATION, taskCount); - return CL_SUCCESS; + return enqueueResult; } } // namespace NEO diff --git a/opencl/source/command_queue/enqueue_fill_image.h b/opencl/source/command_queue/enqueue_fill_image.h index dadd5232c2..fffee07cc5 100644 --- a/opencl/source/command_queue/enqueue_fill_image.h +++ b/opencl/source/command_queue/enqueue_fill_image.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018-2021 Intel Corporation + * Copyright (C) 2018-2022 Intel Corporation * * SPDX-License-Identifier: MIT * @@ -47,14 +47,12 @@ cl_int CommandQueueHw::enqueueFillImage( builder.buildDispatchInfos(di); - enqueueHandler( + return enqueueHandler( surfaces, false, di, numEventsInWaitList, eventWaitList, event); - - return CL_SUCCESS; } } // namespace NEO diff --git a/opencl/source/command_queue/enqueue_kernel.h b/opencl/source/command_queue/enqueue_kernel.h index a86176888c..1c303d1ebc 100644 --- a/opencl/source/command_queue/enqueue_kernel.h +++ b/opencl/source/command_queue/enqueue_kernel.h @@ -135,7 +135,7 @@ cl_int CommandQueueHw::enqueueKernel( return CL_INVALID_WORK_GROUP_SIZE; } - enqueueHandler( + return enqueueHandler( surfaces, false, &kernel, @@ -147,7 +147,6 @@ cl_int CommandQueueHw::enqueueKernel( numEventsInWaitList, eventWaitList, event); - - return CL_SUCCESS; } + } // namespace NEO diff --git a/opencl/source/command_queue/enqueue_marker.h b/opencl/source/command_queue/enqueue_marker.h index 7305edb1f0..592c300be0 100644 --- a/opencl/source/command_queue/enqueue_marker.h +++ b/opencl/source/command_queue/enqueue_marker.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018-2021 Intel Corporation + * Copyright (C) 2018-2022 Intel Corporation * * SPDX-License-Identifier: MIT * @@ -26,12 +26,12 @@ cl_int CommandQueueHw::enqueueMarkerWithWaitList( NullSurface s; Surface *surfaces[] = {&s}; - enqueueHandler(surfaces, - false, - MultiDispatchInfo(), - numEventsInWaitList, - eventWaitList, - event); - return CL_SUCCESS; + return enqueueHandler(surfaces, + false, + MultiDispatchInfo(), + numEventsInWaitList, + eventWaitList, + event); } + } // namespace NEO diff --git a/opencl/source/command_queue/enqueue_migrate_mem_objects.h b/opencl/source/command_queue/enqueue_migrate_mem_objects.h index 9f65b4cc83..29f383b64c 100644 --- a/opencl/source/command_queue/enqueue_migrate_mem_objects.h +++ b/opencl/source/command_queue/enqueue_migrate_mem_objects.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018-2021 Intel Corporation + * Copyright (C) 2018-2022 Intel Corporation * * SPDX-License-Identifier: MIT * @@ -26,13 +26,12 @@ cl_int CommandQueueHw::enqueueMigrateMemObjects(cl_uint numMemObjects NullSurface s; Surface *surfaces[] = {&s}; - enqueueHandler(surfaces, - false, - MultiDispatchInfo(), - numEventsInWaitList, - eventWaitList, - event); - - return CL_SUCCESS; + return enqueueHandler(surfaces, + false, + MultiDispatchInfo(), + numEventsInWaitList, + eventWaitList, + event); } + } // namespace NEO diff --git a/opencl/source/command_queue/enqueue_read_buffer.h b/opencl/source/command_queue/enqueue_read_buffer.h index 2b21dfbdce..f19d12c802 100644 --- a/opencl/source/command_queue/enqueue_read_buffer.h +++ b/opencl/source/command_queue/enqueue_read_buffer.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018-2021 Intel Corporation + * Copyright (C) 2018-2022 Intel Corporation * * SPDX-License-Identifier: MIT * @@ -115,8 +115,8 @@ cl_int CommandQueueHw::enqueueReadBuffer( context->providePerformanceHint(CL_CONTEXT_DIAGNOSTICS_LEVEL_BAD_INTEL, CL_ENQUEUE_READ_BUFFER_DOESNT_MEET_ALIGNMENT_RESTRICTIONS, ptr, size, MemoryConstants::pageSize, MemoryConstants::pageSize); } } - dispatchBcsOrGpgpuEnqueue(dispatchInfo, surfaces, eBuiltInOps, numEventsInWaitList, eventWaitList, event, blockingRead, csr); - return CL_SUCCESS; + return dispatchBcsOrGpgpuEnqueue(dispatchInfo, surfaces, eBuiltInOps, numEventsInWaitList, eventWaitList, event, blockingRead, csr); } + } // namespace NEO diff --git a/opencl/source/command_queue/enqueue_read_buffer_rect.h b/opencl/source/command_queue/enqueue_read_buffer_rect.h index dd9b292268..42f4463a89 100644 --- a/opencl/source/command_queue/enqueue_read_buffer_rect.h +++ b/opencl/source/command_queue/enqueue_read_buffer_rect.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018-2021 Intel Corporation + * Copyright (C) 2018-2022 Intel Corporation * * SPDX-License-Identifier: MIT * @@ -102,7 +102,10 @@ cl_int CommandQueueHw::enqueueReadBufferRect( dc.dstSlicePitch = hostSlicePitch; MultiDispatchInfo dispatchInfo(dc); - dispatchBcsOrGpgpuEnqueue(dispatchInfo, surfaces, eBuiltInOps, numEventsInWaitList, eventWaitList, event, blockingRead, csr); + const auto dispatchResult = dispatchBcsOrGpgpuEnqueue(dispatchInfo, surfaces, eBuiltInOps, numEventsInWaitList, eventWaitList, event, blockingRead, csr); + if (dispatchResult != CL_SUCCESS) { + return dispatchResult; + } if (context->isProvidingPerformanceHints()) { context->providePerformanceHintForMemoryTransfer(CL_COMMAND_READ_BUFFER_RECT, true, static_cast(buffer), ptr); diff --git a/opencl/source/command_queue/enqueue_read_image.h b/opencl/source/command_queue/enqueue_read_image.h index 4b86d4592e..d84deb1d17 100644 --- a/opencl/source/command_queue/enqueue_read_image.h +++ b/opencl/source/command_queue/enqueue_read_image.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018-2021 Intel Corporation + * Copyright (C) 2018-2022 Intel Corporation * * SPDX-License-Identifier: MIT * @@ -119,7 +119,10 @@ cl_int CommandQueueHw::enqueueReadImage( auto eBuiltInOps = EBuiltInOps::CopyImage3dToBuffer; MultiDispatchInfo dispatchInfo(dc); - dispatchBcsOrGpgpuEnqueue(dispatchInfo, surfaces, eBuiltInOps, numEventsInWaitList, eventWaitList, event, blockingRead == CL_TRUE, csr); + const auto dispatchResult = dispatchBcsOrGpgpuEnqueue(dispatchInfo, surfaces, eBuiltInOps, numEventsInWaitList, eventWaitList, event, blockingRead == CL_TRUE, csr); + if (dispatchResult != CL_SUCCESS) { + return dispatchResult; + } if (context->isProvidingPerformanceHints()) { if (!isL3Capable(ptr, hostPtrSize)) { diff --git a/opencl/source/command_queue/enqueue_resource_barrier.h b/opencl/source/command_queue/enqueue_resource_barrier.h index 33173c9c0a..5ed463002c 100644 --- a/opencl/source/command_queue/enqueue_resource_barrier.h +++ b/opencl/source/command_queue/enqueue_resource_barrier.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019-2021 Intel Corporation + * Copyright (C) 2019-2022 Intel Corporation * * SPDX-License-Identifier: MIT * @@ -25,13 +25,13 @@ cl_int CommandQueueHw::enqueueResourceBarrier(BarrierCommand *resourc const cl_event *eventWaitList, cl_event *event) { MultiDispatchInfo multiDispatch; - enqueueHandler(resourceBarrier->surfacePtrs.begin(), - resourceBarrier->numSurfaces, - false, - multiDispatch, - numEventsInWaitList, - eventWaitList, - event); - return CL_SUCCESS; + return enqueueHandler(resourceBarrier->surfacePtrs.begin(), + resourceBarrier->numSurfaces, + false, + multiDispatch, + numEventsInWaitList, + eventWaitList, + event); } + } // namespace NEO diff --git a/opencl/source/command_queue/enqueue_svm.h b/opencl/source/command_queue/enqueue_svm.h index 0171ae62ff..ebf50f21f4 100644 --- a/opencl/source/command_queue/enqueue_svm.h +++ b/opencl/source/command_queue/enqueue_svm.h @@ -84,26 +84,23 @@ cl_int CommandQueueHw::enqueueSVMMap(cl_bool blockingMap, context->providePerformanceHint(CL_CONTEXT_DIAGNOSTICS_LEVEL_GOOD_INTEL, CL_ENQUEUE_SVM_MAP_DOESNT_REQUIRE_COPY_DATA, svmPtr); } - enqueueHandler(surfaces, - blocking, - MultiDispatchInfo(), - numEventsInWaitList, - eventWaitList, - event); - - return CL_SUCCESS; + return enqueueHandler(surfaces, + blocking, + MultiDispatchInfo(), + numEventsInWaitList, + eventWaitList, + event); } else { auto svmOperation = context->getSVMAllocsManager()->getSvmMapOperation(svmPtr); if (svmOperation) { NullSurface s; Surface *surfaces[] = {&s}; - enqueueHandler(surfaces, - blocking, - MultiDispatchInfo(), - numEventsInWaitList, - eventWaitList, - event); - return CL_SUCCESS; + return enqueueHandler(surfaces, + blocking, + MultiDispatchInfo(), + numEventsInWaitList, + eventWaitList, + event); } CsrSelectionArgs csrSelectionArgs{CL_COMMAND_READ_BUFFER, &svmData->gpuAllocations, {}, device->getRootDeviceIndex(), &size}; @@ -128,7 +125,10 @@ cl_int CommandQueueHw::enqueueSVMMap(cl_bool blockingMap, dc.unifiedMemoryArgsRequireMemSync = externalAppCall; MultiDispatchInfo dispatchInfo(dc); - dispatchBcsOrGpgpuEnqueue(dispatchInfo, surfaces, EBuiltInOps::CopyBufferToBuffer, numEventsInWaitList, eventWaitList, event, blocking, csr); + const auto dispatchResult = dispatchBcsOrGpgpuEnqueue(dispatchInfo, surfaces, EBuiltInOps::CopyBufferToBuffer, numEventsInWaitList, eventWaitList, event, blocking, csr); + if (dispatchResult != CL_SUCCESS) { + return dispatchResult; + } if (event) { castToObjectOrAbort(*event)->setCmdType(CL_COMMAND_SVM_MAP); @@ -156,38 +156,36 @@ cl_int CommandQueueHw::enqueueSVMUnmap(void *svmPtr, if (svmData->gpuAllocations.getAllocationType() == AllocationType::SVM_ZERO_COPY) { NullSurface s; Surface *surfaces[] = {&s}; - enqueueHandler(surfaces, - false, - MultiDispatchInfo(), - numEventsInWaitList, - eventWaitList, - event); - - return CL_SUCCESS; + return enqueueHandler(surfaces, + false, + MultiDispatchInfo(), + numEventsInWaitList, + eventWaitList, + event); } else { auto svmOperation = context->getSVMAllocsManager()->getSvmMapOperation(svmPtr); if (!svmOperation) { NullSurface s; Surface *surfaces[] = {&s}; - enqueueHandler(surfaces, - false, - MultiDispatchInfo(), - numEventsInWaitList, - eventWaitList, - event); - return CL_SUCCESS; + return enqueueHandler(surfaces, + false, + MultiDispatchInfo(), + numEventsInWaitList, + eventWaitList, + event); } if (svmOperation->readOnlyMap) { NullSurface s; Surface *surfaces[] = {&s}; - enqueueHandler(surfaces, - false, - MultiDispatchInfo(), - numEventsInWaitList, - eventWaitList, - event); + const auto enqueueResult = enqueueHandler(surfaces, + false, + MultiDispatchInfo(), + numEventsInWaitList, + eventWaitList, + event); + context->getSVMAllocsManager()->removeSvmMapOperation(svmPtr); - return CL_SUCCESS; + return enqueueResult; } CsrSelectionArgs csrSelectionArgs{CL_COMMAND_READ_BUFFER, {}, &svmData->gpuAllocations, device->getRootDeviceIndex(), &svmOperation->regionSize}; @@ -213,7 +211,10 @@ cl_int CommandQueueHw::enqueueSVMUnmap(void *svmPtr, dc.unifiedMemoryArgsRequireMemSync = externalAppCall; MultiDispatchInfo dispatchInfo(dc); - dispatchBcsOrGpgpuEnqueue(dispatchInfo, surfaces, EBuiltInOps::CopyBufferToBuffer, numEventsInWaitList, eventWaitList, event, false, csr); + const auto dispatchResult = dispatchBcsOrGpgpuEnqueue(dispatchInfo, surfaces, EBuiltInOps::CopyBufferToBuffer, numEventsInWaitList, eventWaitList, event, false, csr); + if (dispatchResult != CL_SUCCESS) { + return dispatchResult; + } if (event) { castToObjectOrAbort(*event)->setCmdType(CL_COMMAND_SVM_UNMAP); @@ -249,12 +250,22 @@ cl_int CommandQueueHw::enqueueSVMFree(cl_uint numSvmPointers, NullSurface s; Surface *surfaces[] = {&s}; - enqueueHandler(surfaces, - false, - MultiDispatchInfo(), - numEventsInWaitList, - eventWaitList, - retEvent); + const auto enqueueResult = enqueueHandler(surfaces, + false, + MultiDispatchInfo(), + numEventsInWaitList, + eventWaitList, + retEvent); + if (enqueueResult != CL_SUCCESS) { + delete pFreeData; + + if (ownsEventDeletion) { + castToObjectOrAbort(*retEvent)->release(); + retEvent = nullptr; + } + + return enqueueResult; + } auto eventObject = castToObjectOrAbort(*retEvent); eventObject->addCallback(freeSvmEventClb, CL_COMPLETE, pFreeData); @@ -346,6 +357,7 @@ cl_int CommandQueueHw::enqueueSVMMemcpy(cl_bool blockingCopy, BuiltinOpParams operationParams; Surface *surfaces[2]; cl_command_type cmdType; + cl_int dispatchResult = CL_SUCCESS; if (copyType == SvmToHost) { CsrSelectionArgs csrSelectionArgs{CL_COMMAND_SVM_MEMCPY, srcAllocation, {}, device->getRootDeviceIndex(), &size}; @@ -366,8 +378,7 @@ cl_int CommandQueueHw::enqueueSVMMemcpy(cl_bool blockingCopy, surfaces[1] = &dstHostPtrSurf; dispatchInfo.setBuiltinOpParams(operationParams); - dispatchBcsOrGpgpuEnqueue(dispatchInfo, surfaces, builtInType, numEventsInWaitList, eventWaitList, event, blockingCopy, csr); - + dispatchResult = dispatchBcsOrGpgpuEnqueue(dispatchInfo, surfaces, builtInType, numEventsInWaitList, eventWaitList, event, blockingCopy, csr); } else if (copyType == HostToSvm) { CsrSelectionArgs csrSelectionArgs{CL_COMMAND_SVM_MEMCPY, {}, dstAllocation, device->getRootDeviceIndex(), &size}; CommandStreamReceiver &csr = selectCsrForBuiltinOperation(csrSelectionArgs); @@ -387,8 +398,7 @@ cl_int CommandQueueHw::enqueueSVMMemcpy(cl_bool blockingCopy, surfaces[1] = &srcHostPtrSurf; dispatchInfo.setBuiltinOpParams(operationParams); - dispatchBcsOrGpgpuEnqueue(dispatchInfo, surfaces, builtInType, numEventsInWaitList, eventWaitList, event, blockingCopy, csr); - + dispatchResult = dispatchBcsOrGpgpuEnqueue(dispatchInfo, surfaces, builtInType, numEventsInWaitList, eventWaitList, event, blockingCopy, csr); } else if (copyType == SvmToSvm) { CsrSelectionArgs csrSelectionArgs{CL_COMMAND_SVM_MEMCPY, srcAllocation, dstAllocation, device->getRootDeviceIndex(), &size}; CommandStreamReceiver &csr = selectCsrForBuiltinOperation(csrSelectionArgs); @@ -400,8 +410,7 @@ cl_int CommandQueueHw::enqueueSVMMemcpy(cl_bool blockingCopy, surfaces[1] = &dstSvmSurf; dispatchInfo.setBuiltinOpParams(operationParams); - dispatchBcsOrGpgpuEnqueue(dispatchInfo, surfaces, builtInType, numEventsInWaitList, eventWaitList, event, blockingCopy, csr); - + dispatchResult = dispatchBcsOrGpgpuEnqueue(dispatchInfo, surfaces, builtInType, numEventsInWaitList, eventWaitList, event, blockingCopy, csr); } else { CsrSelectionArgs csrSelectionArgs{CL_COMMAND_SVM_MEMCPY, &size}; CommandStreamReceiver &csr = selectCsrForBuiltinOperation(csrSelectionArgs); @@ -423,13 +432,14 @@ cl_int CommandQueueHw::enqueueSVMMemcpy(cl_bool blockingCopy, surfaces[1] = &dstHostPtrSurf; dispatchInfo.setBuiltinOpParams(operationParams); - dispatchBcsOrGpgpuEnqueue(dispatchInfo, surfaces, builtInType, numEventsInWaitList, eventWaitList, event, blockingCopy, csr); + dispatchResult = dispatchBcsOrGpgpuEnqueue(dispatchInfo, surfaces, builtInType, numEventsInWaitList, eventWaitList, event, blockingCopy, csr); } if (event) { auto pEvent = castToObjectOrAbort(*event); pEvent->setCmdType(CL_COMMAND_SVM_MEMCPY); } - return CL_SUCCESS; + + return dispatchResult; } template @@ -508,7 +518,7 @@ cl_int CommandQueueHw::enqueueSVMMemFill(void *svmPtr, GeneralSurface s2(patternAllocation); Surface *surfaces[] = {&s1, &s2}; - enqueueHandler( + const auto enqueueResult = enqueueHandler( surfaces, false, dispatchInfo, @@ -518,7 +528,7 @@ cl_int CommandQueueHw::enqueueSVMMemFill(void *svmPtr, storageWithAllocations->storeAllocationWithTaskCount(std::unique_ptr(patternAllocation), REUSABLE_ALLOCATION, taskCount); - return CL_SUCCESS; + return enqueueResult; } template @@ -532,13 +542,12 @@ cl_int CommandQueueHw::enqueueSVMMigrateMem(cl_uint numSvmPointers, NullSurface s; Surface *surfaces[] = {&s}; - enqueueHandler(surfaces, - false, - MultiDispatchInfo(), - numEventsInWaitList, - eventWaitList, - event); - - return CL_SUCCESS; + return enqueueHandler(surfaces, + false, + MultiDispatchInfo(), + numEventsInWaitList, + eventWaitList, + event); } + } // namespace NEO diff --git a/opencl/source/command_queue/enqueue_write_buffer.h b/opencl/source/command_queue/enqueue_write_buffer.h index 8aeeef1c07..b3d822ba54 100644 --- a/opencl/source/command_queue/enqueue_write_buffer.h +++ b/opencl/source/command_queue/enqueue_write_buffer.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018-2021 Intel Corporation + * Copyright (C) 2018-2022 Intel Corporation * * SPDX-License-Identifier: MIT * @@ -100,7 +100,10 @@ cl_int CommandQueueHw::enqueueWriteBuffer( dc.transferAllocation = mapAllocation ? mapAllocation : hostPtrSurf.getAllocation(); MultiDispatchInfo dispatchInfo(dc); - dispatchBcsOrGpgpuEnqueue(dispatchInfo, surfaces, eBuiltInOps, numEventsInWaitList, eventWaitList, event, blockingWrite, csr); + const auto dispatchResult = dispatchBcsOrGpgpuEnqueue(dispatchInfo, surfaces, eBuiltInOps, numEventsInWaitList, eventWaitList, event, blockingWrite, csr); + if (dispatchResult != CL_SUCCESS) { + return dispatchResult; + } if (context->isProvidingPerformanceHints()) { context->providePerformanceHint(CL_CONTEXT_DIAGNOSTICS_LEVEL_NEUTRAL_INTEL, CL_ENQUEUE_WRITE_BUFFER_REQUIRES_COPY_DATA, static_cast(buffer)); diff --git a/opencl/source/command_queue/enqueue_write_buffer_rect.h b/opencl/source/command_queue/enqueue_write_buffer_rect.h index 5c4b31b1f6..e10924ceec 100644 --- a/opencl/source/command_queue/enqueue_write_buffer_rect.h +++ b/opencl/source/command_queue/enqueue_write_buffer_rect.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018-2021 Intel Corporation + * Copyright (C) 2018-2022 Intel Corporation * * SPDX-License-Identifier: MIT * @@ -102,7 +102,10 @@ cl_int CommandQueueHw::enqueueWriteBufferRect( dc.dstSlicePitch = bufferSlicePitch; MultiDispatchInfo dispatchInfo(dc); - dispatchBcsOrGpgpuEnqueue(dispatchInfo, surfaces, eBuiltInOps, numEventsInWaitList, eventWaitList, event, blockingWrite, csr); + const auto dispatchResult = dispatchBcsOrGpgpuEnqueue(dispatchInfo, surfaces, eBuiltInOps, numEventsInWaitList, eventWaitList, event, blockingWrite, csr); + if (dispatchResult != CL_SUCCESS) { + return dispatchResult; + } if (context->isProvidingPerformanceHints()) { context->providePerformanceHint(CL_CONTEXT_DIAGNOSTICS_LEVEL_NEUTRAL_INTEL, CL_ENQUEUE_WRITE_BUFFER_RECT_REQUIRES_COPY_DATA, static_cast(buffer)); diff --git a/opencl/source/command_queue/enqueue_write_image.h b/opencl/source/command_queue/enqueue_write_image.h index 6481cbe7b3..66edca0347 100644 --- a/opencl/source/command_queue/enqueue_write_image.h +++ b/opencl/source/command_queue/enqueue_write_image.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018-2021 Intel Corporation + * Copyright (C) 2018-2022 Intel Corporation * * SPDX-License-Identifier: MIT * @@ -96,7 +96,10 @@ cl_int CommandQueueHw::enqueueWriteImage( auto eBuiltInOps = EBuiltInOps::CopyBufferToImage3d; MultiDispatchInfo dispatchInfo(dc); - dispatchBcsOrGpgpuEnqueue(dispatchInfo, surfaces, eBuiltInOps, numEventsInWaitList, eventWaitList, event, blockingWrite == CL_TRUE, csr); + const auto dispatchResult = dispatchBcsOrGpgpuEnqueue(dispatchInfo, surfaces, eBuiltInOps, numEventsInWaitList, eventWaitList, event, blockingWrite == CL_TRUE, csr); + if (dispatchResult != CL_SUCCESS) { + return dispatchResult; + } if (context->isProvidingPerformanceHints()) { context->providePerformanceHint(CL_CONTEXT_DIAGNOSTICS_LEVEL_NEUTRAL_INTEL, CL_ENQUEUE_WRITE_IMAGE_REQUIRES_COPY_DATA, static_cast(dstImage)); diff --git a/opencl/test/unit_test/command_queue/blit_enqueue_tests.cpp b/opencl/test/unit_test/command_queue/blit_enqueue_tests.cpp index 109942a1ee..0f8094abbb 100644 --- a/opencl/test/unit_test/command_queue/blit_enqueue_tests.cpp +++ b/opencl/test/unit_test/command_queue/blit_enqueue_tests.cpp @@ -1330,6 +1330,28 @@ HWTEST_TEMPLATED_F(BlitEnqueueFlushTests, givenNonBlockedQueueWhenBlitEnqueuedTh EXPECT_EQ(2u, myUltBcsCsr->latestFlushedCounter); } +HWTEST_TEMPLATED_F(BlitEnqueueFlushTests, givenGpuHangAndBlockingCallAndNonBlockedQueueWhenBlitEnqueuedThenOutOfResourcesIsReturned) { + DebugManager.flags.MakeEachEnqueueBlocking.set(true); + + auto buffer = createBuffer(1, false); + buffer->forceDisallowCPUCopy = true; + int hostPtr = 0; + + uint32_t flushCounter = 0; + + auto myUltGpgpuCsr = static_cast *>(gpgpuCsr); + myUltGpgpuCsr->flushCounter = &flushCounter; + auto myUltBcsCsr = static_cast *>(bcsCsr); + myUltBcsCsr->flushCounter = &flushCounter; + + auto mockCommandQueue = static_cast *>(commandQueue.get()); + mockCommandQueue->waitForAllEnginesReturnValue = WaitStatus::GpuHang; + + const auto enqueueResult = mockCommandQueue->enqueueWriteBuffer(buffer.get(), CL_FALSE, 0, 1, &hostPtr, nullptr, 0, nullptr, nullptr); + EXPECT_EQ(CL_OUT_OF_RESOURCES, enqueueResult); + EXPECT_EQ(1, mockCommandQueue->waitForAllEnginesCalledCount); +} + HWTEST_TEMPLATED_F(BlitEnqueueFlushTests, givenBlockedQueueWhenBlitEnqueuedThenFlushGpgpuCsrFirst) { auto buffer = createBuffer(1, false); buffer->forceDisallowCPUCopy = true; diff --git a/opencl/test/unit_test/command_queue/command_queue_hw_tests.cpp b/opencl/test/unit_test/command_queue/command_queue_hw_tests.cpp index 0955c97569..346fdc2b14 100644 --- a/opencl/test/unit_test/command_queue/command_queue_hw_tests.cpp +++ b/opencl/test/unit_test/command_queue/command_queue_hw_tests.cpp @@ -1190,7 +1190,9 @@ HWTEST_F(CommandQueueHwTest, GivenBuiltinKernelWhenBuiltinDispatchInfoBuilderIsP EXPECT_FALSE(builder.wasBuildDispatchInfosWithBuiltinOpParamsCalled); EXPECT_FALSE(builder.wasBuildDispatchInfosWithKernelParamsCalled); + cmdQHw->template enqueueHandler(surfaces, false, mockKernelToSend.mockKernel, 1, off, gws, lws, lws, 0, nullptr, nullptr); + EXPECT_FALSE(builder.wasBuildDispatchInfosWithBuiltinOpParamsCalled); EXPECT_TRUE(builder.wasBuildDispatchInfosWithKernelParamsCalled); diff --git a/opencl/test/unit_test/command_queue/enqueue_barrier_tests.cpp b/opencl/test/unit_test/command_queue/enqueue_barrier_tests.cpp index 5e3f1fa70c..d5df8cabbb 100644 --- a/opencl/test/unit_test/command_queue/enqueue_barrier_tests.cpp +++ b/opencl/test/unit_test/command_queue/enqueue_barrier_tests.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018-2021 Intel Corporation + * Copyright (C) 2018-2022 Intel Corporation * * SPDX-License-Identifier: MIT * @@ -7,6 +7,7 @@ #include "shared/source/command_stream/command_stream_receiver.h" #include "shared/test/common/cmd_parse/gen_cmd_parse.h" +#include "shared/test/common/helpers/debug_manager_state_restore.h" #include "shared/test/common/test_macros/test.h" #include "opencl/source/command_queue/command_queue_hw.h" @@ -121,6 +122,28 @@ HWTEST_F(BarrierTest, GivenEventWhenEnqueingBarrierWithWaitListThenEventIsSetupC } } +HWTEST_F(BarrierTest, GivenGpuHangAndBlockingCallWhenEnqueingBarrierWithWaitListThenOutOfResourcesIsReturned) { + DebugManagerStateRestore stateRestore; + DebugManager.flags.MakeEachEnqueueBlocking.set(true); + + std::unique_ptr device(new MockClDevice{MockClDevice::createWithNewExecutionEnvironment(nullptr)}); + cl_queue_properties props = {}; + + MockCommandQueueHw mockCommandQueueHw(context, device.get(), &props); + mockCommandQueueHw.waitForAllEnginesReturnValue = WaitStatus::GpuHang; + + cl_uint numEventsInWaitList = 0; + const cl_event *eventWaitList = nullptr; + + const auto enqueueResult = mockCommandQueueHw.enqueueBarrierWithWaitList( + numEventsInWaitList, + eventWaitList, + nullptr); + + EXPECT_EQ(CL_OUT_OF_RESOURCES, enqueueResult); + EXPECT_EQ(1, mockCommandQueueHw.waitForAllEnginesCalledCount); +} + HWTEST_F(BarrierTest, WhenEnqueingBarrierWithWaitListThenReturnedEventShouldHaveEqualDepth) { auto pCmdQ = this->pCmdQ; auto &commandStreamReceiver = pDevice->getUltCommandStreamReceiver(); diff --git a/opencl/test/unit_test/command_queue/enqueue_command_without_kernel_tests.cpp b/opencl/test/unit_test/command_queue/enqueue_command_without_kernel_tests.cpp index 341e9a24af..464dc37775 100644 --- a/opencl/test/unit_test/command_queue/enqueue_command_without_kernel_tests.cpp +++ b/opencl/test/unit_test/command_queue/enqueue_command_without_kernel_tests.cpp @@ -396,7 +396,8 @@ HWTEST_F(EnqueueHandlerTest, GivenCommandStreamWithoutKernelAndZeroSurfacesWhenE mockCmdQ->commandRequireCacheFlush = true; MultiDispatchInfo multiDispatch; - mockCmdQ->template enqueueHandler(nullptr, 0, false, multiDispatch, 0, nullptr, nullptr); + const auto enqueueResult = mockCmdQ->template enqueueHandler(nullptr, 0, false, multiDispatch, 0, nullptr, nullptr); + EXPECT_EQ(CL_SUCCESS, enqueueResult); auto requiredCmdStreamSize = alignUp(MemorySynchronizationCommands::getSizeForPipeControlWithPostSyncOperation( pDevice->getHardwareInfo()), @@ -417,7 +418,9 @@ HWTEST_F(EnqueueHandlerTest, givenTimestampPacketWriteEnabledAndCommandWithCache cl_event event; MultiDispatchInfo multiDispatch; - mockCmdQ->template enqueueHandler(nullptr, 0, false, multiDispatch, 0, nullptr, &event); + const auto enqueueResult = mockCmdQ->template enqueueHandler(nullptr, 0, false, multiDispatch, 0, nullptr, &event); + EXPECT_EQ(CL_SUCCESS, enqueueResult); + auto node1 = mockCmdQ->timestampPacketContainer->peekNodes().at(0); EXPECT_NE(nullptr, node1); clReleaseEvent(event); @@ -434,7 +437,9 @@ HWTEST_F(EnqueueHandlerTest, givenTimestampPacketWriteDisabledAndCommandWithCach cl_event event; MultiDispatchInfo multiDispatch; - mockCmdQ->template enqueueHandler(nullptr, 0, false, multiDispatch, 0, nullptr, &event); + const auto enqueueResult = mockCmdQ->template enqueueHandler(nullptr, 0, false, multiDispatch, 0, nullptr, &event); + EXPECT_EQ(CL_SUCCESS, enqueueResult); + auto container = mockCmdQ->timestampPacketContainer.get(); EXPECT_EQ(nullptr, container); clReleaseEvent(event); diff --git a/opencl/test/unit_test/command_queue/enqueue_copy_buffer_rect_tests.cpp b/opencl/test/unit_test/command_queue/enqueue_copy_buffer_rect_tests.cpp index 8766bb4c3c..f9d79f8220 100644 --- a/opencl/test/unit_test/command_queue/enqueue_copy_buffer_rect_tests.cpp +++ b/opencl/test/unit_test/command_queue/enqueue_copy_buffer_rect_tests.cpp @@ -1,12 +1,14 @@ /* - * Copyright (C) 2018-2021 Intel Corporation + * Copyright (C) 2018-2022 Intel Corporation * * SPDX-License-Identifier: MIT * */ #include "shared/source/built_ins/built_ins.h" +#include "shared/source/command_stream/wait_status.h" #include "shared/source/helpers/constants.h" +#include "shared/test/common/helpers/debug_manager_state_restore.h" #include "shared/test/common/libult/ult_command_stream_receiver.h" #include "shared/test/common/test_macros/test.h" @@ -15,6 +17,7 @@ #include "opencl/test/unit_test/command_queue/enqueue_copy_buffer_rect_fixture.h" #include "opencl/test/unit_test/gen_common/gen_commands_common_validation.h" #include "opencl/test/unit_test/mocks/mock_buffer.h" +#include "opencl/test/unit_test/mocks/mock_command_queue.h" #include "reg_configs_common.h" @@ -94,6 +97,39 @@ HWTEST_F(EnqueueCopyBufferRectTest, GivenValidParametersWhenCopyingBufferRectThe EXPECT_EQ(CL_SUCCESS, retVal); } +HWTEST_F(EnqueueCopyBufferRectTest, GivenGpuHangAndBlockingCallAndValidParametersWhenCopyingBufferRectThenOutOfResourcesIsReturned) { + DebugManagerStateRestore stateRestore; + DebugManager.flags.MakeEachEnqueueBlocking.set(true); + + std::unique_ptr device(new MockClDevice{MockClDevice::createWithNewExecutionEnvironment(nullptr)}); + cl_queue_properties props = {}; + + MockCommandQueueHw mockCommandQueueHw(context, device.get(), &props); + mockCommandQueueHw.waitForAllEnginesReturnValue = WaitStatus::GpuHang; + + size_t srcOrigin[] = {0, 0, 0}; + size_t dstOrigin[] = {0, 0, 0}; + size_t region[] = {1, 1, 1}; + + const auto enqueueResult = clEnqueueCopyBufferRect( + &mockCommandQueueHw, + srcBuffer, + dstBuffer, + srcOrigin, + dstOrigin, + region, + 10, + 0, + 10, + 0, + 0, + nullptr, + nullptr); + + EXPECT_EQ(CL_OUT_OF_RESOURCES, enqueueResult); + EXPECT_EQ(1, mockCommandQueueHw.waitForAllEnginesCalledCount); +} + HWTEST_F(EnqueueCopyBufferRectTest, WhenCopyingBufferRect2DThenTaskCountIsAlignedWithCsr) { //this test case assumes IOQ auto &csr = pDevice->getUltCommandStreamReceiver(); diff --git a/opencl/test/unit_test/command_queue/enqueue_copy_buffer_tests.cpp b/opencl/test/unit_test/command_queue/enqueue_copy_buffer_tests.cpp index 66da28a409..1dcab3b522 100644 --- a/opencl/test/unit_test/command_queue/enqueue_copy_buffer_tests.cpp +++ b/opencl/test/unit_test/command_queue/enqueue_copy_buffer_tests.cpp @@ -7,6 +7,7 @@ #include "shared/source/built_ins/built_ins.h" #include "shared/source/helpers/ptr_math.h" +#include "shared/test/common/helpers/debug_manager_state_restore.h" #include "shared/test/common/helpers/unit_test_helper.h" #include "shared/test/common/libult/ult_command_stream_receiver.h" #include "shared/test/common/test_macros/test.h" @@ -20,6 +21,7 @@ #include "opencl/test/unit_test/command_queue/enqueue_fixture.h" #include "opencl/test/unit_test/gen_common/gen_commands_common_validation.h" #include "opencl/test/unit_test/mocks/mock_buffer.h" +#include "opencl/test/unit_test/mocks/mock_command_queue.h" #include "reg_configs_common.h" @@ -179,6 +181,31 @@ HWTEST_F(EnqueueCopyBufferTest, WhenCopyingBufferThenCommandsAreAdded) { EXPECT_NE(usedCmdBufferBefore, pCS->getUsed()); } +HWTEST_F(EnqueueCopyBufferTest, GivenGpuHangAndBlockingCallWhenCopyingBufferThenOutOfResourcesIsReturned) { + DebugManagerStateRestore stateRestore; + DebugManager.flags.MakeEachEnqueueBlocking.set(true); + + std::unique_ptr device(new MockClDevice{MockClDevice::createWithNewExecutionEnvironment(nullptr)}); + cl_queue_properties props = {}; + + MockCommandQueueHw mockCommandQueueHw(&context, device.get(), &props); + mockCommandQueueHw.waitForAllEnginesReturnValue = WaitStatus::GpuHang; + + const auto enqueueResult = EnqueueCopyBufferHelper::enqueueCopyBuffer( + &mockCommandQueueHw, + srcBuffer, + dstBuffer, + 0, + 0, + sizeof(float), + 0, + nullptr, + nullptr); + + EXPECT_EQ(CL_OUT_OF_RESOURCES, enqueueResult); + EXPECT_EQ(1, mockCommandQueueHw.waitForAllEnginesCalledCount); +} + HWTEST_F(EnqueueCopyBufferTest, WhenCopyingBufferThenIndirectDataGetsAdded) { auto dshBefore = pDSH->getUsed(); auto iohBefore = pIOH->getUsed(); diff --git a/opencl/test/unit_test/command_queue/enqueue_copy_buffer_to_image_tests.cpp b/opencl/test/unit_test/command_queue/enqueue_copy_buffer_to_image_tests.cpp index 601ed44d35..e8d0aab246 100644 --- a/opencl/test/unit_test/command_queue/enqueue_copy_buffer_to_image_tests.cpp +++ b/opencl/test/unit_test/command_queue/enqueue_copy_buffer_to_image_tests.cpp @@ -5,6 +5,7 @@ * */ +#include "shared/test/common/helpers/debug_manager_state_restore.h" #include "shared/test/common/helpers/unit_test_helper.h" #include "shared/test/common/libult/ult_command_stream_receiver.h" #include "shared/test/common/mocks/mock_builtins.h" @@ -327,6 +328,32 @@ HWTEST_F(EnqueueCopyBufferToImageStatelessTest, givenBigBufferWhenCopyingBufferT EXPECT_EQ(CL_SUCCESS, retVal); } +HWTEST_F(EnqueueCopyBufferToImageStatelessTest, givenGpuHangAndBlockingCallAndBigBufferWhenCopyingBufferToImageStatelessThenOutOfResourcesIsReturned) { + DebugManagerStateRestore stateRestore; + DebugManager.flags.MakeEachEnqueueBlocking.set(true); + + std::unique_ptr device(new MockClDevice{MockClDevice::createWithNewExecutionEnvironment(nullptr)}); + cl_queue_properties props = {}; + + MockCommandQueueHw mockCommandQueueHw(context.get(), device.get(), &props); + mockCommandQueueHw.waitForAllEnginesReturnValue = WaitStatus::GpuHang; + + srcBuffer.size = static_cast(bigSize); + + const auto enqueueResult = mockCommandQueueHw.enqueueCopyBufferToImage( + &srcBuffer, + dstImage.get(), + static_cast(bigOffset), + dstOrigin, + region, + 0, + nullptr, + nullptr); + + EXPECT_EQ(CL_OUT_OF_RESOURCES, enqueueResult); + EXPECT_EQ(1, mockCommandQueueHw.waitForAllEnginesCalledCount); +} + using EnqueueCopyBufferToImageStatefulTest = EnqueueCopyBufferToImageHw; HWTEST_F(EnqueueCopyBufferToImageStatefulTest, givenBigBufferWhenCopyingBufferToImageStatefulThenSuccessIsReturned) { diff --git a/opencl/test/unit_test/command_queue/enqueue_copy_image_tests.cpp b/opencl/test/unit_test/command_queue/enqueue_copy_image_tests.cpp index a3ba3dab6d..3a1a29a603 100644 --- a/opencl/test/unit_test/command_queue/enqueue_copy_image_tests.cpp +++ b/opencl/test/unit_test/command_queue/enqueue_copy_image_tests.cpp @@ -71,6 +71,22 @@ HWTEST_F(EnqueueCopyImageTest, WhenCopyingImageThenTaskCountIsAlignedWithCsr) { EXPECT_EQ(csr.peekTaskLevel(), pCmdQ->taskLevel + 1); } +HWTEST_F(EnqueueCopyImageTest, GivenGpuHangAndBlockingCallWhenCopyingImageThenOutOfResourcesIsReturned) { + DebugManagerStateRestore stateRestore; + DebugManager.flags.MakeEachEnqueueBlocking.set(true); + + std::unique_ptr device(new MockClDevice{MockClDevice::createWithNewExecutionEnvironment(nullptr)}); + cl_queue_properties props = {}; + + MockCommandQueueHw mockCommandQueueHw(context, device.get(), &props); + mockCommandQueueHw.waitForAllEnginesReturnValue = WaitStatus::GpuHang; + + const auto enqueueResult = EnqueueCopyImageHelper<>::enqueueCopyImage(&mockCommandQueueHw, srcImage, dstImage); + + EXPECT_EQ(CL_OUT_OF_RESOURCES, enqueueResult); + EXPECT_EQ(1, mockCommandQueueHw.waitForAllEnginesCalledCount); +} + HWTEST_F(EnqueueCopyImageTest, WhenCopyingImageThenTaskLevelIsIncremented) { auto taskLevelBefore = pCmdQ->taskLevel; diff --git a/opencl/test/unit_test/command_queue/enqueue_copy_image_to_buffer_tests.cpp b/opencl/test/unit_test/command_queue/enqueue_copy_image_to_buffer_tests.cpp index b8125e904b..406ed27403 100644 --- a/opencl/test/unit_test/command_queue/enqueue_copy_image_to_buffer_tests.cpp +++ b/opencl/test/unit_test/command_queue/enqueue_copy_image_to_buffer_tests.cpp @@ -5,6 +5,7 @@ * */ +#include "shared/test/common/helpers/debug_manager_state_restore.h" #include "shared/test/common/helpers/unit_test_helper.h" #include "shared/test/common/libult/ult_command_stream_receiver.h" #include "shared/test/common/mocks/mock_builtins.h" @@ -17,6 +18,7 @@ #include "opencl/test/unit_test/gen_common/gen_commands_common_validation.h" #include "opencl/test/unit_test/mocks/mock_buffer.h" #include "opencl/test/unit_test/mocks/mock_builtin_dispatch_info_builder.h" +#include "opencl/test/unit_test/mocks/mock_command_queue.h" #include "reg_configs_common.h" @@ -319,6 +321,32 @@ HWTEST_F(EnqueueCopyImageToBufferHwStatelessTest, givenBigBufferWhenCopyingImage EXPECT_EQ(CL_SUCCESS, retVal); } +HWTEST_F(EnqueueCopyImageToBufferHwStatelessTest, givenGpuHangAndBlockingCallAndBigBufferWhenCopyingImageToBufferStatelessThenOutOfResourcesIsReturned) { + DebugManagerStateRestore stateRestore; + DebugManager.flags.MakeEachEnqueueBlocking.set(true); + + std::unique_ptr device(new MockClDevice{MockClDevice::createWithNewExecutionEnvironment(nullptr)}); + cl_queue_properties props = {}; + + MockCommandQueueHw mockCommandQueueHw(context.get(), device.get(), &props); + mockCommandQueueHw.waitForAllEnginesReturnValue = WaitStatus::GpuHang; + + dstBuffer.size = static_cast(bigSize); + + const auto enqueueResult = mockCommandQueueHw.enqueueCopyImageToBuffer( + srcImage.get(), + &dstBuffer, + srcOrigin, + region, + static_cast(bigOffset), + 0, + nullptr, + nullptr); + + EXPECT_EQ(CL_OUT_OF_RESOURCES, enqueueResult); + EXPECT_EQ(1, mockCommandQueueHw.waitForAllEnginesCalledCount); +} + using EnqueueCopyImageToBufferStatefulTest = EnqueueCopyImageToBufferHw; HWTEST_F(EnqueueCopyImageToBufferStatefulTest, givenBufferWhenCopyingImageToBufferStatefulThenSuccessIsReturned) { diff --git a/opencl/test/unit_test/command_queue/enqueue_fill_buffer_negative_tests.cpp b/opencl/test/unit_test/command_queue/enqueue_fill_buffer_negative_tests.cpp index 5ebf3b5ca6..02842a321f 100644 --- a/opencl/test/unit_test/command_queue/enqueue_fill_buffer_negative_tests.cpp +++ b/opencl/test/unit_test/command_queue/enqueue_fill_buffer_negative_tests.cpp @@ -1,14 +1,16 @@ /* - * Copyright (C) 2018-2021 Intel Corporation + * Copyright (C) 2018-2022 Intel Corporation * * SPDX-License-Identifier: MIT * */ #include "shared/source/helpers/ptr_math.h" +#include "shared/test/common/helpers/debug_manager_state_restore.h" #include "opencl/source/command_queue/command_queue.h" #include "opencl/test/unit_test/command_queue/enqueue_fill_buffer_fixture.h" +#include "opencl/test/unit_test/mocks/mock_command_queue.h" #include "gtest/gtest.h" @@ -99,6 +101,26 @@ TEST_F(EnqueueFillBuffer, GivenEventListAndNumEventsZeroWhenFillingBufferThenInv EXPECT_EQ(CL_INVALID_EVENT_WAIT_LIST, retVal); } + +HWTEST_F(EnqueueFillBuffer, GivenGpuHangAndBlockingCallWhenFillingBufferThenOutOfResourcesIsReturned) { + DebugManagerStateRestore stateRestore; + DebugManager.flags.MakeEachEnqueueBlocking.set(true); + + std::unique_ptr device(new MockClDevice{MockClDevice::createWithNewExecutionEnvironment(nullptr)}); + cl_queue_properties props = {}; + + MockCommandQueueHw mockCommandQueueHw(&context, device.get(), &props); + mockCommandQueueHw.waitForAllEnginesReturnValue = WaitStatus::GpuHang; + + cl_uint numEventsInWaitList = 0; + const cl_event *eventWaitList = nullptr; + + const auto enqueueResult = EnqueueFillBufferHelper<>::enqueueFillBuffer(&mockCommandQueueHw, buffer, numEventsInWaitList, eventWaitList, nullptr); + + EXPECT_EQ(CL_OUT_OF_RESOURCES, enqueueResult); + EXPECT_EQ(1, mockCommandQueueHw.waitForAllEnginesCalledCount); +} + } // namespace ULT namespace ULT { diff --git a/opencl/test/unit_test/command_queue/enqueue_fill_image_tests.cpp b/opencl/test/unit_test/command_queue/enqueue_fill_image_tests.cpp index 04dc3e2f7b..03d0517b69 100644 --- a/opencl/test/unit_test/command_queue/enqueue_fill_image_tests.cpp +++ b/opencl/test/unit_test/command_queue/enqueue_fill_image_tests.cpp @@ -5,6 +5,7 @@ * */ +#include "shared/test/common/helpers/debug_manager_state_restore.h" #include "shared/test/common/helpers/unit_test_helper.h" #include "shared/test/common/libult/ult_command_stream_receiver.h" #include "shared/test/common/mocks/mock_gmm_resource_info.h" @@ -90,12 +91,30 @@ HWTEST_F(EnqueueFillImageTest, WhenFillingImageThenCommandsAreAdded) { EXPECT_NE(usedCmdBufferBefore, pCS->getUsed()); } +HWTEST_F(EnqueueFillImageTest, GivenGpuHangAndBlockingCallWhenFillingImageThenOutOfResourcesIsReturned) { + DebugManagerStateRestore stateRestore; + DebugManager.flags.MakeEachEnqueueBlocking.set(true); + + std::unique_ptr device(new MockClDevice{MockClDevice::createWithNewExecutionEnvironment(nullptr)}); + cl_queue_properties props = {}; + + MockCommandQueueHw mockCommandQueueHw(context, device.get(), &props); + mockCommandQueueHw.waitForAllEnginesReturnValue = WaitStatus::GpuHang; + + const auto enqueueResult = EnqueueFillImageHelper<>::enqueueFillImage(&mockCommandQueueHw, image); + + EXPECT_EQ(CL_OUT_OF_RESOURCES, enqueueResult); + EXPECT_EQ(1, mockCommandQueueHw.waitForAllEnginesCalledCount); +} + HWTEST_F(EnqueueFillImageTest, WhenFillingImageThenIndirectDataGetsAdded) { auto dshBefore = pDSH->getUsed(); auto iohBefore = pIOH->getUsed(); auto sshBefore = pSSH->getUsed(); - EnqueueFillImageHelper<>::enqueueFillImage(pCmdQ, image); + const auto enqueueResult = EnqueueFillImageHelper<>::enqueueFillImage(pCmdQ, image); + EXPECT_EQ(CL_SUCCESS, enqueueResult); + EXPECT_TRUE(UnitTestHelper::evaluateDshUsage(dshBefore, pDSH->getUsed(), nullptr, rootDeviceIndex)); EXPECT_NE(iohBefore, pIOH->getUsed()); EXPECT_NE(sshBefore, pSSH->getUsed()); diff --git a/opencl/test/unit_test/command_queue/enqueue_handler_tests.cpp b/opencl/test/unit_test/command_queue/enqueue_handler_tests.cpp index 532f0f04f9..e25de8d126 100644 --- a/opencl/test/unit_test/command_queue/enqueue_handler_tests.cpp +++ b/opencl/test/unit_test/command_queue/enqueue_handler_tests.cpp @@ -82,8 +82,8 @@ HWTEST_F(EnqueueHandlerTest, givenEnqueueHandlerWithKernelSplitWhenAubCsrIsActiv auto mockCmdQ = std::unique_ptr>(new MockCommandQueueHw(context, pClDevice, 0)); MockMultiDispatchInfo multiDispatchInfo(pClDevice, std::vector({kernel1.mockKernel, kernel2.mockKernel})); - mockCmdQ->template enqueueHandler(nullptr, 0, true, multiDispatchInfo, 0, nullptr, nullptr); - + const auto enqueueResult = mockCmdQ->template enqueueHandler(nullptr, 0, true, multiDispatchInfo, 0, nullptr, nullptr); + EXPECT_EQ(CL_SUCCESS, enqueueResult); EXPECT_TRUE(aubCsr->addAubCommentCalled); EXPECT_EQ(2u, aubCsr->aubCommentMessages.size()); @@ -380,13 +380,14 @@ HWTEST_F(EnqueueHandlerTest, WhenEnqueuingBlockedWithoutReturnEventThenVirtualEv auto initialRefCountInternal = mockCmdQ->getRefInternalCount(); bool blocking = false; - mockCmdQ->template enqueueHandler(nullptr, - 0, - blocking, - multiDispatchInfo, - 0, - nullptr, - nullptr); + const auto enqueueResult = mockCmdQ->template enqueueHandler(nullptr, + 0, + blocking, + multiDispatchInfo, + 0, + nullptr, + nullptr); + EXPECT_EQ(CL_SUCCESS, enqueueResult); EXPECT_NE(nullptr, mockCmdQ->virtualEvent); @@ -412,13 +413,14 @@ HWTEST_F(EnqueueHandlerTest, WhenEnqueuingBlockedThenVirtualEventIsSetAsCurrentC mockCmdQ->taskLevel = CompletionStamp::notReady; bool blocking = false; - mockCmdQ->template enqueueHandler(nullptr, - 0, - blocking, - multiDispatchInfo, - 0, - nullptr, - nullptr); + const auto enqueueResult = mockCmdQ->template enqueueHandler(nullptr, + 0, + blocking, + multiDispatchInfo, + 0, + nullptr, + nullptr); + EXPECT_EQ(CL_SUCCESS, enqueueResult); ASSERT_NE(nullptr, mockCmdQ->virtualEvent); @@ -436,13 +438,15 @@ HWTEST_F(EnqueueHandlerTest, WhenEnqueuingWithOutputEventThenEventIsRegistered) auto mockCmdQ = new MockCommandQueueHw(context, pClDevice, 0); bool blocking = false; - mockCmdQ->template enqueueHandler(nullptr, - 0, - blocking, - multiDispatchInfo, - 0, - nullptr, - &outputEvent); + const auto enqueueResult = mockCmdQ->template enqueueHandler(nullptr, + 0, + blocking, + multiDispatchInfo, + 0, + nullptr, + &outputEvent); + EXPECT_EQ(CL_SUCCESS, enqueueResult); + ASSERT_NE(nullptr, outputEvent); Event *event = castToObjectOrAbort(outputEvent); ASSERT_NE(nullptr, event); @@ -514,13 +518,15 @@ HWTEST_F(EnqueueHandlerTest, givenExternallySynchronizedParentEventWhenRequestin bool blocking = false; MultiDispatchInfo emptyDispatchInfo; - mockCmdQ->template enqueueHandler(nullptr, - 0, - blocking, - emptyDispatchInfo, - 1U, - &inEv, - &outEv); + const auto enqueueResult = mockCmdQ->template enqueueHandler(nullptr, + 0, + blocking, + emptyDispatchInfo, + 1U, + &inEv, + &outEv); + EXPECT_EQ(CL_SUCCESS, enqueueResult); + Event *ouputEvent = castToObject(outEv); ASSERT_NE(nullptr, ouputEvent); EXPECT_EQ(0U, ouputEvent->peekTaskCount()); @@ -539,13 +545,14 @@ HWTEST_F(EnqueueHandlerTest, givenEnqueueHandlerWhenSubCaptureIsOffThenActivateS auto mockCmdQ = new MockCommandQueueHw(context, pClDevice, 0); - mockCmdQ->template enqueueHandler(nullptr, - 0, - false, - multiDispatchInfo, - 0, - nullptr, - nullptr); + const auto enqueueResult = mockCmdQ->template enqueueHandler(nullptr, + 0, + false, + multiDispatchInfo, + 0, + nullptr, + nullptr); + EXPECT_EQ(CL_SUCCESS, enqueueResult); EXPECT_FALSE(pDevice->getUltCommandStreamReceiver().checkAndActivateAubSubCaptureCalled); mockCmdQ->release(); @@ -561,13 +568,14 @@ HWTEST_F(EnqueueHandlerTest, givenEnqueueHandlerWhenSubCaptureIsOnThenActivateSu auto mockCmdQ = new MockCommandQueueHw(context, pClDevice, 0); - mockCmdQ->template enqueueHandler(nullptr, - 0, - false, - multiDispatchInfo, - 0, - nullptr, - nullptr); + const auto enqueueResult = mockCmdQ->template enqueueHandler(nullptr, + 0, + false, + multiDispatchInfo, + 0, + nullptr, + nullptr); + EXPECT_EQ(CL_SUCCESS, enqueueResult); EXPECT_TRUE(pDevice->getUltCommandStreamReceiver().checkAndActivateAubSubCaptureCalled); mockCmdQ->release(); @@ -596,13 +604,14 @@ HWTEST_F(EnqueueHandlerTest, givenEnqueueHandlerWhenClSetKernelExecInfoAlreadySe ); auto mockCmdQ = new MockCommandQueueHw(context, pClDevice, 0); - mockCmdQ->template enqueueHandler(nullptr, - 0, - false, - multiDispatchInfo, - 0, - nullptr, - nullptr); + const auto enqueueResult = mockCmdQ->template enqueueHandler(nullptr, + 0, + false, + multiDispatchInfo, + 0, + nullptr, + nullptr); + EXPECT_EQ(CL_SUCCESS, enqueueResult); EXPECT_EQ(getNewKernelArbitrationPolicy(euThreadSetting), pDevice->getUltCommandStreamReceiver().streamProperties.stateComputeMode.threadArbitrationPolicy.value); @@ -632,13 +641,14 @@ HWTEST_F(EnqueueHandlerTest, givenEnqueueHandlerWhenNotSupportedPolicyChangeThen EXPECT_EQ(CL_INVALID_DEVICE, retVal); auto mockCmdQ = new MockCommandQueueHw(context, pClDevice, 0); - mockCmdQ->template enqueueHandler(nullptr, - 0, - false, - multiDispatchInfo, - 0, - nullptr, - nullptr); + const auto enqueueResult = mockCmdQ->template enqueueHandler(nullptr, + 0, + false, + multiDispatchInfo, + 0, + nullptr, + nullptr); + EXPECT_EQ(CL_SUCCESS, enqueueResult); EXPECT_NE(getNewKernelArbitrationPolicy(euThreadSetting), pDevice->getUltCommandStreamReceiver().streamProperties.stateComputeMode.threadArbitrationPolicy.value); EXPECT_EQ(0, pDevice->getUltCommandStreamReceiver().streamProperties.stateComputeMode.threadArbitrationPolicy.value); @@ -730,13 +740,14 @@ HWTEST_F(EnqueueHandlerTestBasic, givenEnqueueHandlerWhenCommandIsBlokingThenCom MockKernelWithInternals kernelInternals(*device, context.get()); Kernel *kernel = kernelInternals.mockKernel; MockMultiDispatchInfo multiDispatchInfo(device.get(), kernel); - mockCmdQ->template enqueueHandler(nullptr, - 0, - true, - multiDispatchInfo, - 0, - nullptr, - nullptr); + const auto enqueueResult = mockCmdQ->template enqueueHandler(nullptr, + 0, + true, + multiDispatchInfo, + 0, + nullptr, + nullptr); + EXPECT_EQ(CL_SUCCESS, enqueueResult); EXPECT_EQ(initialTaskCount + 1, mockInternalAllocationStorage->lastCleanAllocationsTaskCount); } @@ -755,13 +766,14 @@ HWTEST_F(EnqueueHandlerTestBasic, givenBlockedEnqueueHandlerWhenCommandIsBloking } userEvent.setStatus(CL_COMPLETE); }); - mockCmdQ->template enqueueHandler(nullptr, - 0, - true, - multiDispatchInfo, - 1, - waitlist, - nullptr); + const auto enqueueResult = mockCmdQ->template enqueueHandler(nullptr, + 0, + true, + multiDispatchInfo, + 1, + waitlist, + nullptr); + EXPECT_EQ(CL_SUCCESS, enqueueResult); EXPECT_EQ(initialTaskCount + 1, mockInternalAllocationStorage->lastCleanAllocationsTaskCount); t0.join(); diff --git a/opencl/test/unit_test/command_queue/enqueue_kernel_1_tests.cpp b/opencl/test/unit_test/command_queue/enqueue_kernel_1_tests.cpp index 7fdef7e3d6..706d5079ca 100644 --- a/opencl/test/unit_test/command_queue/enqueue_kernel_1_tests.cpp +++ b/opencl/test/unit_test/command_queue/enqueue_kernel_1_tests.cpp @@ -19,6 +19,7 @@ #include "opencl/test/unit_test/command_queue/enqueue_fixture.h" #include "opencl/test/unit_test/fixtures/hello_world_fixture.h" #include "opencl/test/unit_test/helpers/cl_hw_parse.h" +#include "opencl/test/unit_test/mocks/mock_command_queue.h" #include "opencl/test/unit_test/test_macros/test_checks_ocl.h" using namespace NEO; @@ -520,6 +521,38 @@ HWTEST_F(EnqueueKernelTest, WhenEnqueingKernelThenCommandsAreAdded) { EXPECT_NE(usedCmdBufferBefore, pCS->getUsed()); } +HWTEST_F(EnqueueKernelTest, GivenGpuHangAndBlockingCallWhenEnqueingKernelThenOutOfResourcesIsReported) { + DebugManagerStateRestore stateRestore; + DebugManager.flags.MakeEachEnqueueBlocking.set(true); + + std::unique_ptr device(new MockClDevice{MockClDevice::createWithNewExecutionEnvironment(nullptr)}); + cl_queue_properties props = {}; + + MockCommandQueueHw mockCommandQueueHw(context, device.get(), &props); + mockCommandQueueHw.waitForAllEnginesReturnValue = WaitStatus::GpuHang; + + cl_uint workDim = 1; + size_t globalWorkOffset[3] = {0, 0, 0}; + size_t globalWorkSize[3] = {1, 1, 1}; + size_t localWorkSize[3] = {1, 1, 1}; + + cl_event *eventWaitList = nullptr; + cl_int waitListSize = 0; + + const auto enqueueResult = mockCommandQueueHw.enqueueKernel( + pKernel, + workDim, + globalWorkOffset, + globalWorkSize, + localWorkSize, + waitListSize, + eventWaitList, + nullptr); + + EXPECT_EQ(CL_OUT_OF_RESOURCES, enqueueResult); + EXPECT_EQ(1, mockCommandQueueHw.waitForAllEnginesCalledCount); +} + HWTEST_F(EnqueueKernelTest, WhenEnqueingKernelThenIndirectDataIsAdded) { auto dshBefore = pDSH->getUsed(); auto iohBefore = pIOH->getUsed(); @@ -702,6 +735,24 @@ HWTEST_F(EnqueueKernelTest, givenEnqueueWithGlobalWorkSizeWhenZeroValueIsPassedI EXPECT_EQ(CL_SUCCESS, ret); } +HWTEST_F(EnqueueKernelTest, givenGpuHangAndBlockingCallAndEnqueueWithGlobalWorkSizeWhenZeroValueIsPassedInDimensionThenOutOfResourcesIsReturned) { + DebugManagerStateRestore stateRestore; + DebugManager.flags.MakeEachEnqueueBlocking.set(true); + + std::unique_ptr device(new MockClDevice{MockClDevice::createWithNewExecutionEnvironment(nullptr)}); + cl_queue_properties props = {}; + + MockCommandQueueHw mockCommandQueueHw(context, device.get(), &props); + mockCommandQueueHw.waitForAllEnginesReturnValue = WaitStatus::GpuHang; + + size_t gws[3] = {0, 0, 0}; + MockKernelWithInternals mockKernel(*pClDevice); + + const auto enqueueResult = mockCommandQueueHw.enqueueKernel(mockKernel.mockKernel, 1, nullptr, gws, nullptr, 0, nullptr, nullptr); + EXPECT_EQ(CL_OUT_OF_RESOURCES, enqueueResult); + EXPECT_EQ(1, mockCommandQueueHw.waitForAllEnginesCalledCount); +} + HWTEST_F(EnqueueKernelTest, givenCommandStreamReceiverInBatchingModeWhenEnqueueKernelIsCalledThenKernelIsRecorded) { auto mockCsr = new MockCsrHw2(*pDevice->executionEnvironment, pDevice->getRootDeviceIndex(), pDevice->getDeviceBitfield()); mockCsr->useNewResourceImplicitFlush = false; diff --git a/opencl/test/unit_test/command_queue/enqueue_marker_tests.cpp b/opencl/test/unit_test/command_queue/enqueue_marker_tests.cpp index 1afeee720c..df051c2a9f 100644 --- a/opencl/test/unit_test/command_queue/enqueue_marker_tests.cpp +++ b/opencl/test/unit_test/command_queue/enqueue_marker_tests.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018-2021 Intel Corporation + * Copyright (C) 2018-2022 Intel Corporation * * SPDX-License-Identifier: MIT * @@ -13,6 +13,7 @@ #include "opencl/source/event/user_event.h" #include "opencl/test/unit_test/command_queue/command_enqueue_fixture.h" +#include "opencl/test/unit_test/mocks/mock_command_queue.h" #include "opencl/test/unit_test/mocks/mock_kernel.h" using namespace NEO; @@ -102,6 +103,28 @@ TEST_F(MarkerTest, WhenEnqueingMarkerThenEventIsReturned) { } } +HWTEST_F(MarkerTest, GivenGpuHangAndBlockingCallWhenEnqueingMarkerThenOutOfResourcesIsReturned) { + DebugManagerStateRestore stateRestore; + DebugManager.flags.MakeEachEnqueueBlocking.set(true); + + std::unique_ptr device(new MockClDevice{MockClDevice::createWithNewExecutionEnvironment(nullptr)}); + cl_queue_properties props = {}; + + MockCommandQueueHw mockCommandQueueHw(context, device.get(), &props); + mockCommandQueueHw.waitForAllEnginesReturnValue = WaitStatus::GpuHang; + + cl_uint numEventsInWaitList = 0; + const cl_event *eventWaitList = nullptr; + + const auto enqueueResult = mockCommandQueueHw.enqueueMarkerWithWaitList( + numEventsInWaitList, + eventWaitList, + nullptr); + + EXPECT_EQ(CL_OUT_OF_RESOURCES, enqueueResult); + EXPECT_EQ(1, mockCommandQueueHw.waitForAllEnginesCalledCount); +} + HWTEST_F(MarkerTest, WhenEnqueingMarkerThenReturnedEventShouldHaveEqualDepthToLastCommandPacketInCommandQueue) { auto &commandStreamReceiver = pDevice->getUltCommandStreamReceiver(); diff --git a/opencl/test/unit_test/command_queue/enqueue_migrate_mem_objects_tests.cpp b/opencl/test/unit_test/command_queue/enqueue_migrate_mem_objects_tests.cpp index 43a2c8e651..a67d919b15 100644 --- a/opencl/test/unit_test/command_queue/enqueue_migrate_mem_objects_tests.cpp +++ b/opencl/test/unit_test/command_queue/enqueue_migrate_mem_objects_tests.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018-2021 Intel Corporation + * Copyright (C) 2018-2022 Intel Corporation * * SPDX-License-Identifier: MIT * @@ -13,6 +13,7 @@ #include "opencl/test/unit_test/command_stream/command_stream_fixture.h" #include "opencl/test/unit_test/fixtures/cl_device_fixture.h" #include "opencl/test/unit_test/mocks/mock_buffer.h" +#include "opencl/test/unit_test/mocks/mock_command_queue.h" using namespace NEO; @@ -71,6 +72,34 @@ TEST_F(MigrateMemObjectsTest, GivenValidEventListWhenMigratingEventsThenSuccessI EXPECT_EQ(CL_SUCCESS, retVal); } +HWTEST_F(MigrateMemObjectsTest, GivenGpuHangAndBlockingCallsAndValidEventListWhenMigratingEventsThenOutOfResourcesIsReturned) { + DebugManagerStateRestore stateRestore; + DebugManager.flags.MakeEachEnqueueBlocking.set(true); + + std::unique_ptr device(new MockClDevice{MockClDevice::createWithNewExecutionEnvironment(nullptr)}); + cl_queue_properties props = {}; + + MockCommandQueueHw mockCommandQueueHw(context, device.get(), &props); + mockCommandQueueHw.waitForAllEnginesReturnValue = WaitStatus::GpuHang; + + MockBuffer buffer; + auto bufferMemObj = static_cast(&buffer); + + UserEvent uEvent; + cl_event eventWaitList[] = {&uEvent}; + + const auto enqueueResult = mockCommandQueueHw.enqueueMigrateMemObjects( + 1, + &bufferMemObj, + CL_MIGRATE_MEM_OBJECT_HOST, + 1, + eventWaitList, + nullptr); + + EXPECT_EQ(CL_OUT_OF_RESOURCES, enqueueResult); + EXPECT_EQ(1, mockCommandQueueHw.waitForAllEnginesCalledCount); +} + TEST_F(MigrateMemObjectsTest, GivenEventPointerWhenMigratingEventsThenEventIsReturned) { MockBuffer buffer; diff --git a/opencl/test/unit_test/command_queue/enqueue_read_buffer_rect_tests.cpp b/opencl/test/unit_test/command_queue/enqueue_read_buffer_rect_tests.cpp index 0a3dd86665..0840fd47db 100644 --- a/opencl/test/unit_test/command_queue/enqueue_read_buffer_rect_tests.cpp +++ b/opencl/test/unit_test/command_queue/enqueue_read_buffer_rect_tests.cpp @@ -98,6 +98,37 @@ HWTEST_F(EnqueueReadBufferRectTest, GivenValidParamsWhenReadingBufferThenSuccess EXPECT_EQ(CL_SUCCESS, retVal); } +HWTEST_F(EnqueueReadBufferRectTest, GivenGpuHangAndBlockingCallAndValidParamsWhenReadingBufferThenOutOfResourcesIsReturned) { + std::unique_ptr device(new MockClDevice{MockClDevice::createWithNewExecutionEnvironment(nullptr)}); + cl_queue_properties props = {}; + + MockCommandQueueHw mockCommandQueueHw(context.get(), device.get(), &props); + mockCommandQueueHw.waitForAllEnginesReturnValue = WaitStatus::GpuHang; + + size_t bufferOrigin[] = {0, 0, 0}; + size_t hostOrigin[] = {0, 0, 0}; + size_t region[] = {1, 1, 1}; + + const auto enqueueResult = clEnqueueReadBufferRect( + &mockCommandQueueHw, + buffer.get(), + CL_TRUE, + bufferOrigin, + hostOrigin, + region, + 10, + 0, + 10, + 0, + hostPtr, + 0, + nullptr, + nullptr); + + EXPECT_EQ(CL_OUT_OF_RESOURCES, enqueueResult); + EXPECT_EQ(1, mockCommandQueueHw.waitForAllEnginesCalledCount); +} + HWTEST_F(EnqueueReadBufferRectTest, GivenBlockingEnqueueWhenReadingBufferThenTaskLevelIsNotIncremented) { //this test case assumes IOQ auto &csr = pDevice->getUltCommandStreamReceiver(); @@ -356,7 +387,6 @@ HWTEST_F(EnqueueReadBufferRectTest, givenInOrderQueueAndDstPtrEqualSrcPtrWithEve numEventsInWaitList, eventWaitList, &event); - ; EXPECT_EQ(CL_SUCCESS, retVal); ASSERT_NE(nullptr, event); @@ -657,7 +687,6 @@ struct EnqueueReadBufferRectHw : public ::testing::Test { using EnqueueReadBufferRectStatelessTest = EnqueueReadBufferRectHw; HWTEST_F(EnqueueReadBufferRectStatelessTest, WhenReadingBufferRectStatelessThenSuccessIsReturned) { - auto pCmdQ = std::make_unique>(context.get(), device.get()); void *missAlignedPtr = reinterpret_cast(0x1041); srcBuffer.size = static_cast(bigSize); diff --git a/opencl/test/unit_test/command_queue/enqueue_read_buffer_tests.cpp b/opencl/test/unit_test/command_queue/enqueue_read_buffer_tests.cpp index cd9385c072..152e8a340d 100644 --- a/opencl/test/unit_test/command_queue/enqueue_read_buffer_tests.cpp +++ b/opencl/test/unit_test/command_queue/enqueue_read_buffer_tests.cpp @@ -103,6 +103,20 @@ HWTEST_F(EnqueueReadBufferTypeTest, WhenReadingBufferThenTaskLevelIsIncremented) EXPECT_GT(pCmdQ->taskLevel, taskLevelBefore); } +HWTEST_F(EnqueueReadBufferTypeTest, GivenGpuHangAndBlockingCallWhenReadingBufferThenOutOfResourcesIsReturned) { + std::unique_ptr device(new MockClDevice{MockClDevice::createWithNewExecutionEnvironment(nullptr)}); + cl_queue_properties props{}; + + MockCommandQueueHw mockCommandQueueHw(context, device.get(), &props); + mockCommandQueueHw.waitForAllEnginesReturnValue = WaitStatus::GpuHang; + + srcBuffer->forceDisallowCPUCopy = true; + const auto enqueueResult = EnqueueReadBufferHelper<>::enqueueReadBuffer(&mockCommandQueueHw, srcBuffer.get(), CL_TRUE); + + EXPECT_EQ(CL_OUT_OF_RESOURCES, enqueueResult); + EXPECT_EQ(1, mockCommandQueueHw.waitForAllEnginesCalledCount); +} + HWTEST_F(EnqueueReadBufferTypeTest, GivenBlockingWhenReadingBufferThenAlignedToCsr) { //this test case assumes IOQ auto &csr = pDevice->getUltCommandStreamReceiver(); @@ -398,6 +412,7 @@ HWTEST_F(EnqueueReadBufferTypeTest, givenOOQWithEnabledSupportCpuCopiesAndDstPtr EXPECT_EQ(CL_SUCCESS, retVal); EXPECT_EQ(pCmdOOQ->taskLevel, 0u); } + HWTEST_F(EnqueueReadBufferTypeTest, givenOOQWithDisabledSupportCpuCopiesAndDstPtrEqualSrcPtrAndZeroCopyBufferWhenReadBufferIsExecutedThenTaskLevelNotIncreased) { DebugManagerStateRestore dbgRestore; DebugManager.flags.DoCpuCopyOnReadBuffer.set(0); @@ -418,6 +433,32 @@ HWTEST_F(EnqueueReadBufferTypeTest, givenOOQWithDisabledSupportCpuCopiesAndDstPt EXPECT_EQ(CL_SUCCESS, retVal); EXPECT_EQ(pCmdOOQ->taskLevel, 0u); } + +HWTEST_F(EnqueueReadBufferTypeTest, givenGpuHangAndBlockingCallAndOOQWithDisabledSupportCpuCopiesAndDstPtrEqualSrcPtrAndZeroCopyBufferWhenReadBufferIsExecutedThenOutOfResourcesIsReturned) { + DebugManagerStateRestore dbgRestore; + DebugManager.flags.DoCpuCopyOnReadBuffer.set(0); + + std::unique_ptr device(new MockClDevice{MockClDevice::createWithNewExecutionEnvironment(nullptr)}); + cl_queue_properties props[3] = {CL_QUEUE_PROPERTIES, CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE, 0}; + + MockCommandQueueHw mockCommandQueueHw(context, device.get(), props); + mockCommandQueueHw.waitForAllEnginesReturnValue = WaitStatus::GpuHang; + + void *ptr = srcBuffer->getCpuAddressForMemoryTransfer(); + const auto enqueueResult = mockCommandQueueHw.enqueueReadBuffer(srcBuffer.get(), + CL_TRUE, + 0, + MemoryConstants::cacheLineSize, + ptr, + nullptr, + 0, + nullptr, + nullptr); + + EXPECT_EQ(CL_OUT_OF_RESOURCES, enqueueResult); + EXPECT_EQ(1, mockCommandQueueHw.waitForAllEnginesCalledCount); +} + HWTEST_F(EnqueueReadBufferTypeTest, givenInOrderQueueAndEnabledSupportCpuCopiesAndDstPtrEqualSrcPtrAndZeroCopyBufferWhenReadBufferIsExecutedThenTaskLevelShouldNotBeIncreased) { DebugManagerStateRestore dbgRestore; DebugManager.flags.DoCpuCopyOnReadBuffer.set(1); diff --git a/opencl/test/unit_test/command_queue/enqueue_read_image_tests.cpp b/opencl/test/unit_test/command_queue/enqueue_read_image_tests.cpp index ef5f544e05..a4205d2b49 100644 --- a/opencl/test/unit_test/command_queue/enqueue_read_image_tests.cpp +++ b/opencl/test/unit_test/command_queue/enqueue_read_image_tests.cpp @@ -193,6 +193,30 @@ HWTEST_F(EnqueueReadImageTest, givenCommandQueueAndPtrCopyAllowedForHostSurfaceW cmdQ->gpgpuEngine->commandStreamReceiver = oldCommandStreamReceiver; } +HWTEST_F(EnqueueReadImageTest, givenGpuHangAndCommandQueueAndPtrCopyAllowedForHostSurfaceWhenBlockingEnqueueReadImageThenOutOfResourcesIsReturned) { + auto csr = std::make_unique>(*pDevice->getExecutionEnvironment(), pDevice->getRootDeviceIndex(), pDevice->getDeviceBitfield()); + auto cmdQ = std::make_unique>(context, pClDevice, nullptr); + cmdQ->waitForAllEnginesReturnValue = WaitStatus::GpuHang; + + csr->setupContext(*pDevice->getDefaultEngine().osContext); + CommandStreamReceiver *oldCommandStreamReceiver = cmdQ->gpgpuEngine->commandStreamReceiver; + cmdQ->gpgpuEngine->commandStreamReceiver = csr.get(); + csr->initializeTagAllocation(); + + auto retVal = cmdQ->enqueueReadImage(srcImage, CL_TRUE, + EnqueueReadImageTraits::origin, + EnqueueReadImageTraits::region, + EnqueueReadImageTraits::rowPitch, + EnqueueReadImageTraits::slicePitch, + EnqueueReadImageTraits::hostPtr, + EnqueueReadImageTraits::mapAllocation, + 0u, + nullptr, + nullptr); + EXPECT_EQ(CL_OUT_OF_RESOURCES, retVal); + cmdQ->gpgpuEngine->commandStreamReceiver = oldCommandStreamReceiver; +} + HWTEST_F(EnqueueReadImageTest, givenMultiRootDeviceImageWhenEnqueueReadImageThenKernelRequiresMigration) { MockDefaultContext context; diff --git a/opencl/test/unit_test/command_queue/enqueue_resource_barier_tests.cpp b/opencl/test/unit_test/command_queue/enqueue_resource_barier_tests.cpp index efda6edff2..1d54dd3ccd 100644 --- a/opencl/test/unit_test/command_queue/enqueue_resource_barier_tests.cpp +++ b/opencl/test/unit_test/command_queue/enqueue_resource_barier_tests.cpp @@ -1,14 +1,16 @@ /* - * Copyright (C) 2019-2021 Intel Corporation + * Copyright (C) 2019-2022 Intel Corporation * * SPDX-License-Identifier: MIT * */ +#include "shared/test/common/helpers/debug_manager_state_restore.h" #include "shared/test/common/test_macros/test.h" #include "opencl/source/command_queue/resource_barrier.h" #include "opencl/test/unit_test/command_queue/command_enqueue_fixture.h" +#include "opencl/test/unit_test/mocks/mock_command_queue.h" using namespace NEO; @@ -40,10 +42,12 @@ HWTEST_F(ResourceBarrierTest, givenNullArgsAndHWCommandQueueWhenEnqueueResourceB } HWTEST_F(ResourceBarrierTest, whenEnqueueResourceBarrierCalledThenUpdateQueueCompletionStamp) { - cl_resource_barrier_descriptor_intel descriptor{}; auto retVal = CL_INVALID_VALUE; size_t bufferSize = MemoryConstants::pageSize; std::unique_ptr buffer(Buffer::create(&pCmdQ->getContext(), CL_MEM_READ_WRITE, bufferSize, nullptr, retVal)); + ASSERT_EQ(CL_SUCCESS, retVal); + + cl_resource_barrier_descriptor_intel descriptor{}; descriptor.mem_object = buffer.get(); descriptor.svm_allocation_pointer = nullptr; @@ -51,7 +55,9 @@ HWTEST_F(ResourceBarrierTest, whenEnqueueResourceBarrierCalledThenUpdateQueueCom auto previousTaskCount = pCmdQ->taskCount; auto previousTaskLevel = pCmdQ->taskLevel; - pCmdQ->enqueueResourceBarrier(&barrierCommand, 0, nullptr, nullptr); + + const auto enqueueResult = pCmdQ->enqueueResourceBarrier(&barrierCommand, 0, nullptr, nullptr); + EXPECT_EQ(CL_SUCCESS, enqueueResult); bool resourceBarrierSupported = pCmdQ->isCacheFlushCommand(CL_COMMAND_RESOURCE_BARRIER); @@ -63,6 +69,32 @@ HWTEST_F(ResourceBarrierTest, whenEnqueueResourceBarrierCalledThenUpdateQueueCom EXPECT_EQ(pCmdQ->taskLevel, previousTaskLevel); } +HWTEST_F(ResourceBarrierTest, GivenGpuHangAndBlockingCallsWhenEnqueueResourceBarrierIsCalledThenOutOfResourcesIsReturned) { + DebugManagerStateRestore stateRestore; + DebugManager.flags.MakeEachEnqueueBlocking.set(true); + + std::unique_ptr device(new MockClDevice{MockClDevice::createWithNewExecutionEnvironment(nullptr)}); + cl_queue_properties props = {}; + + MockCommandQueueHw mockCommandQueueHw(context, device.get(), &props); + mockCommandQueueHw.waitForAllEnginesReturnValue = WaitStatus::GpuHang; + + auto retVal = CL_INVALID_VALUE; + size_t bufferSize = MemoryConstants::pageSize; + std::unique_ptr buffer(Buffer::create(&mockCommandQueueHw.getContext(), CL_MEM_READ_WRITE, bufferSize, nullptr, retVal)); + ASSERT_EQ(CL_SUCCESS, retVal); + + cl_resource_barrier_descriptor_intel descriptor{}; + descriptor.mem_object = buffer.get(); + descriptor.svm_allocation_pointer = nullptr; + + BarrierCommand barrierCommand(&mockCommandQueueHw, &descriptor, 1); + + const auto enqueueResult = mockCommandQueueHw.enqueueResourceBarrier(&barrierCommand, 0, nullptr, nullptr); + EXPECT_EQ(CL_OUT_OF_RESOURCES, enqueueResult); + EXPECT_EQ(1, mockCommandQueueHw.waitForAllEnginesCalledCount); +} + HWTEST_F(ResourceBarrierTest, whenBarierCommandCreatedWithInvalidSvmPointerThenExceptionIsThrown) { cl_resource_barrier_descriptor_intel descriptor{}; descriptor.svm_allocation_pointer = nullptr; diff --git a/opencl/test/unit_test/command_queue/enqueue_svm_tests.cpp b/opencl/test/unit_test/command_queue/enqueue_svm_tests.cpp index 3bbf38d959..02ec0d9507 100644 --- a/opencl/test/unit_test/command_queue/enqueue_svm_tests.cpp +++ b/opencl/test/unit_test/command_queue/enqueue_svm_tests.cpp @@ -100,6 +100,30 @@ TEST_F(EnqueueSvmTest, GivenValidParamsWhenMappingSvmThenSuccessIsReturned) { EXPECT_EQ(CL_SUCCESS, retVal); } +HWTEST_F(EnqueueSvmTest, GivenGpuHangAndBlockingCallAndValidParamsWhenMappingSvmThenOutOfResourcesIsReturned) { + DebugManagerStateRestore stateRestore; + DebugManager.flags.MakeEachEnqueueBlocking.set(true); + + std::unique_ptr device(new MockClDevice{MockClDevice::createWithNewExecutionEnvironment(nullptr)}); + cl_queue_properties props = {}; + + MockCommandQueueHw mockCommandQueueHw(context, device.get(), &props); + mockCommandQueueHw.waitForAllEnginesReturnValue = WaitStatus::GpuHang; + + const auto enqueueResult = mockCommandQueueHw.enqueueSVMMap( + CL_TRUE, // cl_bool blocking_map + CL_MAP_READ, // cl_map_flags map_flags + ptrSVM, // void *svm_ptr + 256, // size_t size + 0, // cl_uint num_events_in_wait_list + nullptr, // const cL_event *event_wait_list + nullptr, // cl_event *event + false); // bool externalAppCall + + EXPECT_EQ(CL_OUT_OF_RESOURCES, enqueueResult); + EXPECT_EQ(1, mockCommandQueueHw.waitForAllEnginesCalledCount); +} + TEST_F(EnqueueSvmTest, GivenValidParamsWhenMappingSvmWithBlockingThenSuccessIsReturned) { retVal = this->pCmdQ->enqueueSVMMap( CL_TRUE, // cl_bool blocking_map @@ -149,6 +173,27 @@ TEST_F(EnqueueSvmTest, GivenValidParamsWhenUnmappingSvmThenSuccessIsReturned) { EXPECT_EQ(CL_SUCCESS, retVal); } +HWTEST_F(EnqueueSvmTest, GivenGpuHangAndBlockingCallAndValidParamsWhenUnmappingSvmThenOutOfResourcesIsReturned) { + DebugManagerStateRestore stateRestore; + DebugManager.flags.MakeEachEnqueueBlocking.set(true); + + std::unique_ptr device(new MockClDevice{MockClDevice::createWithNewExecutionEnvironment(nullptr)}); + cl_queue_properties props = {}; + + MockCommandQueueHw mockCommandQueueHw(context, device.get(), &props); + mockCommandQueueHw.waitForAllEnginesReturnValue = WaitStatus::GpuHang; + + const auto enqueueResult = mockCommandQueueHw.enqueueSVMUnmap( + ptrSVM, + 0, + nullptr, + nullptr, + false); + + EXPECT_EQ(CL_OUT_OF_RESOURCES, enqueueResult); + EXPECT_EQ(1, mockCommandQueueHw.waitForAllEnginesCalledCount); +} + TEST_F(EnqueueSvmTest, GivenValidParamsWhenUnmappingSvmWithEventsThenSuccessIsReturned) { UserEvent uEvent; cl_event eventWaitList[] = {&uEvent}; @@ -261,6 +306,72 @@ TEST_F(EnqueueSvmTest, GivenValidParamsWhenFreeingSvmWithBlockingThenSuccessIsRe EXPECT_EQ(CL_SUCCESS, retVal); } +HWTEST_F(EnqueueSvmTest, GivenEventAndGpuHangAndBlockingCallAndValidParamsWhenFreeingSvmWithBlockingThenEventIsNotDeletedAndOutOfResourcesIsReturned) { + DebugManagerStateRestore dbgRestore; + DebugManager.flags.EnableAsyncEventsHandler.set(false); + DebugManager.flags.MakeEachEnqueueBlocking.set(true); + + std::unique_ptr device(new MockClDevice{MockClDevice::createWithNewExecutionEnvironment(nullptr)}); + cl_queue_properties props = {}; + + MockCommandQueueHw mockCommandQueueHw(context, device.get(), &props); + mockCommandQueueHw.waitForAllEnginesReturnValue = WaitStatus::GpuHang; + + const cl_uint numOfSvmPointers = 1; + void *svmPtrs[numOfSvmPointers] = {ptrSVM}; + + UserEvent uEvent; + const cl_uint numOfEvents = 1; + cl_event eventWaitList[numOfEvents] = {&uEvent}; + + cl_event retEvent = nullptr; + const auto enqueueResult = mockCommandQueueHw.enqueueSVMFree( + numOfSvmPointers, + svmPtrs, + nullptr, + nullptr, + numOfEvents, + eventWaitList, + &retEvent); + + EXPECT_EQ(CL_OUT_OF_RESOURCES, enqueueResult); + EXPECT_EQ(1, mockCommandQueueHw.waitForAllEnginesCalledCount); + + ASSERT_NE(nullptr, retEvent); + castToObjectOrAbort(retEvent)->release(); +} + +HWTEST_F(EnqueueSvmTest, GivenGpuHangAndBlockingCallAndValidParamsWhenFreeingSvmWithBlockingThenOutOfResourcesIsReturned) { + DebugManagerStateRestore dbgRestore; + DebugManager.flags.EnableAsyncEventsHandler.set(false); + DebugManager.flags.MakeEachEnqueueBlocking.set(true); + + std::unique_ptr device(new MockClDevice{MockClDevice::createWithNewExecutionEnvironment(nullptr)}); + cl_queue_properties props = {}; + + MockCommandQueueHw mockCommandQueueHw(context, device.get(), &props); + mockCommandQueueHw.waitForAllEnginesReturnValue = WaitStatus::GpuHang; + + const cl_uint numOfSvmPointers = 1; + void *svmPtrs[numOfSvmPointers] = {ptrSVM}; + + UserEvent uEvent; + const cl_uint numOfEvents = 1; + cl_event eventWaitList[numOfEvents] = {&uEvent}; + + const auto enqueueResult = mockCommandQueueHw.enqueueSVMFree( + numOfSvmPointers, + svmPtrs, + nullptr, + nullptr, + numOfEvents, + eventWaitList, + nullptr); + + EXPECT_EQ(CL_OUT_OF_RESOURCES, enqueueResult); + EXPECT_EQ(1, mockCommandQueueHw.waitForAllEnginesCalledCount); +} + TEST_F(EnqueueSvmTest, GivenNullDstPtrWhenCopyingMemoryThenInvalidVaueErrorIsReturned) { DebugManagerStateRestore dbgRestore; DebugManager.flags.EnableAsyncEventsHandler.set(false); @@ -692,6 +803,38 @@ TEST_F(EnqueueSvmTest, GivenValidParamsWhenFillingMemoryWithBlockingThenSuccessI uEvent->setStatus(-1); } +HWTEST_F(EnqueueSvmTest, GivenGpuHangAndBlockingCallAndValidParamsWhenFillingMemoryThenOutOfResourcesIsReturned) { + DebugManagerStateRestore stateRestore; + DebugManager.flags.MakeEachEnqueueBlocking.set(true); + + std::unique_ptr device(new MockClDevice{MockClDevice::createWithNewExecutionEnvironment(nullptr)}); + cl_queue_properties props = {}; + + MockCommandQueueHw mockCommandQueueHw(context, device.get(), &props); + mockCommandQueueHw.waitForAllEnginesReturnValue = WaitStatus::GpuHang; + + const float pattern[1] = {1.2345f}; + const size_t patternSize = sizeof(pattern); + + auto uEvent = make_releaseable(); + const cl_uint numOfEvents = 1; + cl_event eventWaitList[numOfEvents] = {uEvent.get()}; + + const auto enqueueResult = mockCommandQueueHw.enqueueSVMMemFill( + ptrSVM, + pattern, + patternSize, + 256, + numOfEvents, + eventWaitList, + nullptr); + + EXPECT_EQ(CL_OUT_OF_RESOURCES, enqueueResult); + EXPECT_EQ(1, mockCommandQueueHw.waitForAllEnginesCalledCount); + + uEvent->setStatus(-1); +} + TEST_F(EnqueueSvmTest, GivenRepeatCallsWhenFillingMemoryThenSuccessIsReturnedForEachCall) { const float pattern[1] = {1.2345f}; const size_t patternSize = sizeof(pattern); @@ -876,6 +1019,31 @@ TEST_F(EnqueueSvmTest, GivenValidParamsWhenMigratingMemoryThenSuccessIsReturned) EXPECT_EQ(CL_SUCCESS, retVal); } +HWTEST_F(EnqueueSvmTest, GivenGpuHangAndBlockingCallAndValidParamsWhenMigratingMemoryThenOutOfResourcesIsReturned) { + DebugManagerStateRestore dbgRestore; + DebugManager.flags.MakeEachEnqueueBlocking.set(true); + + std::unique_ptr device(new MockClDevice{MockClDevice::createWithNewExecutionEnvironment(nullptr)}); + cl_queue_properties props = {}; + + MockCommandQueueHw mockCommandQueueHw(context, device.get(), &props); + mockCommandQueueHw.waitForAllEnginesReturnValue = WaitStatus::GpuHang; + + const void *svmPtrs[] = {ptrSVM}; + const auto enqueueResult = mockCommandQueueHw.enqueueSVMMigrateMem( + 1, // cl_uint num_svm_pointers + svmPtrs, // const void **svm_pointers + nullptr, // const size_t *sizes + 0, // const cl_mem_migration_flags flags + 0, // cl_uint num_events_in_wait_list + nullptr, // cl_event *event_wait_list + nullptr // cL_event *event + ); + + EXPECT_EQ(CL_OUT_OF_RESOURCES, enqueueResult); + EXPECT_EQ(1, mockCommandQueueHw.waitForAllEnginesCalledCount); +} + HWTEST_F(EnqueueSvmTest, WhenMigratingMemoryThenSvmMigrateMemCommandTypeIsUsed) { MockCommandQueueHw commandQueue{context, pClDevice, nullptr}; const void *svmPtrs[] = {ptrSVM}; @@ -971,6 +1139,28 @@ HWTEST_F(EnqueueSvmTestLocalMemory, givenWriteInvalidateRegionFlagWhenMappingSvm EXPECT_FALSE(svmMap->readOnlyMap); } +HWTEST_F(EnqueueSvmTestLocalMemory, givenGpuHangAndBlockingCallAndWriteInvalidateRegionFlagWhenMappingSvmThenOutOfResourcesIsReturned) { + MockCommandQueueHw queue(context.get(), pClDevice, nullptr); + queue.waitForAllEnginesReturnValue = WaitStatus::GpuHang; + + uintptr_t offset = 64; + void *regionSvmPtr = ptrOffset(svmPtr, offset); + size_t regionSize = 64; + + const auto enqueueResult = queue.enqueueSVMMap( + CL_TRUE, + CL_MAP_WRITE_INVALIDATE_REGION, + regionSvmPtr, + regionSize, + 0, + nullptr, + nullptr, + false); + + EXPECT_EQ(CL_OUT_OF_RESOURCES, enqueueResult); + EXPECT_EQ(1, queue.waitForAllEnginesCalledCount); +} + HWTEST_F(EnqueueSvmTestLocalMemory, givenMapWriteFlagWhenMappingSvmThenMapIsSuccessfulAndReadOnlyFlagIsFalse) { MockCommandQueueHw queue(context.get(), pClDevice, nullptr); uintptr_t offset = 64; @@ -1140,6 +1330,41 @@ HWTEST_F(EnqueueSvmTestLocalMemory, givenEnabledLocalMemoryWhenEnqueueMapSvmPtrT clReleaseEvent(event); } +HWTEST_F(EnqueueSvmTestLocalMemory, givenEnabledLocalMemoryAndBlockingCallAndGpuHangOnSecondMapWhenEnqueueMapSvmPtrTwiceThenSecondCallReturnsOutOfresources) { + std::unique_ptr device(new MockClDevice{MockClDevice::createWithNewExecutionEnvironment(nullptr)}); + cl_queue_properties props = {}; + + MockCommandQueueHw mockCommandQueueHw(context.get(), device.get(), &props); + mockCommandQueueHw.waitForAllEnginesReturnValue = WaitStatus::Ready; + + uintptr_t offset = 64; + void *regionSvmPtr = ptrOffset(svmPtr, offset); + size_t regionSize = 64; + + const auto firstMapResult = mockCommandQueueHw.enqueueSVMMap( + CL_TRUE, + CL_MAP_WRITE, + regionSvmPtr, + regionSize, + 0, + nullptr, + nullptr, + false); + EXPECT_EQ(CL_SUCCESS, firstMapResult); + + mockCommandQueueHw.waitForAllEnginesReturnValue = WaitStatus::GpuHang; + const auto secondMapResult = mockCommandQueueHw.enqueueSVMMap( + CL_TRUE, + CL_MAP_WRITE, + regionSvmPtr, + regionSize, + 0, + nullptr, + nullptr, + false); + EXPECT_EQ(CL_OUT_OF_RESOURCES, secondMapResult); +} + HWTEST_F(EnqueueSvmTestLocalMemory, givenEnabledLocalMemoryWhenNoMappedSvmPtrThenExpectNoUnmapCopyKernel) { using WALKER_TYPE = typename FamilyType::WALKER_TYPE; MockCommandQueueHw queue(context.get(), pClDevice, nullptr); @@ -1166,6 +1391,27 @@ HWTEST_F(EnqueueSvmTestLocalMemory, givenEnabledLocalMemoryWhenNoMappedSvmPtrThe clReleaseEvent(event); } +HWTEST_F(EnqueueSvmTestLocalMemory, givenEnabledLocalMemoryAndGpuHangAndBlockingCallWhenUnmappingThenReturnOutOfResources) { + DebugManagerStateRestore stateRestore; + DebugManager.flags.MakeEachEnqueueBlocking.set(true); + + std::unique_ptr device(new MockClDevice{MockClDevice::createWithNewExecutionEnvironment(nullptr)}); + cl_queue_properties props = {}; + + MockCommandQueueHw mockCommandQueueHw(context.get(), device.get(), &props); + mockCommandQueueHw.waitForAllEnginesReturnValue = WaitStatus::GpuHang; + + const auto enqueueResult = mockCommandQueueHw.enqueueSVMUnmap( + svmPtr, + 0, + nullptr, + nullptr, + false); + + EXPECT_EQ(CL_OUT_OF_RESOURCES, enqueueResult); + EXPECT_EQ(1, mockCommandQueueHw.waitForAllEnginesCalledCount); +} + HWTEST_F(EnqueueSvmTestLocalMemory, givenEnabledLocalMemoryWhenMappedSvmRegionIsReadOnlyThenExpectNoUnmapCopyKernel) { using WALKER_TYPE = typename FamilyType::WALKER_TYPE; MockCommandQueueHw queue(context.get(), pClDevice, nullptr); @@ -1214,6 +1460,37 @@ HWTEST_F(EnqueueSvmTestLocalMemory, givenEnabledLocalMemoryWhenMappedSvmRegionIs clReleaseEvent(event); } +HWTEST_F(EnqueueSvmTestLocalMemory, givenEnabledLocalMemoryAndBlockingCallAndGpuHangForUnmapWhenUnmapingThenOutOfResourcesIsReturnedFromUnmap) { + DebugManagerStateRestore dbgRestore; + DebugManager.flags.MakeEachEnqueueBlocking.set(true); + + std::unique_ptr device(new MockClDevice{MockClDevice::createWithNewExecutionEnvironment(nullptr)}); + cl_queue_properties props = {}; + + MockCommandQueueHw mockCommandQueueHw(context.get(), device.get(), &props); + mockCommandQueueHw.waitForAllEnginesReturnValue = WaitStatus::Ready; + + const auto enqueueMapResult = mockCommandQueueHw.enqueueSVMMap( + CL_FALSE, + CL_MAP_READ, + svmPtr, + size, + 0, + nullptr, + nullptr, + false); + EXPECT_EQ(CL_SUCCESS, enqueueMapResult); + + mockCommandQueueHw.waitForAllEnginesReturnValue = WaitStatus::GpuHang; + const auto enqueueUnmapResult = mockCommandQueueHw.enqueueSVMUnmap( + svmPtr, + 0, + nullptr, + nullptr, + false); + EXPECT_EQ(CL_OUT_OF_RESOURCES, enqueueUnmapResult); +} + HWTEST_F(EnqueueSvmTestLocalMemory, givenNonReadOnlyMapWhenUnmappingThenSetAubTbxWritableBeforeUnmapEnqueue) { class MyQueue : public MockCommandQueueHw { public: @@ -1313,6 +1590,35 @@ HWTEST_F(EnqueueSvmTestLocalMemory, givenEnabledLocalMemoryWhenMappedSvmRegionIs clReleaseEvent(eventUnmap); } +HWTEST_F(EnqueueSvmTestLocalMemory, givenGpuHangAndBlockingCallAndEnabledLocalMemoryWhenMappedSvmRegionIsWritableThenUnmapReturnsOutOfResources) { + DebugManagerStateRestore stateRestore; + DebugManager.flags.MakeEachEnqueueBlocking.set(true); + + MockCommandQueueHw queue(context.get(), pClDevice, nullptr); + queue.waitForAllEnginesReturnValue = WaitStatus::Ready; + + const auto enqueueMapResult = queue.enqueueSVMMap( + CL_TRUE, + CL_MAP_WRITE, + svmPtr, + size, + 0, + nullptr, + nullptr, + false); + EXPECT_EQ(CL_SUCCESS, enqueueMapResult); + + queue.waitForAllEnginesReturnValue = WaitStatus::GpuHang; + const auto enqueueUnmapResult = queue.enqueueSVMUnmap( + svmPtr, + 0, + nullptr, + nullptr, + false); + EXPECT_EQ(CL_OUT_OF_RESOURCES, enqueueUnmapResult); + EXPECT_EQ(2, queue.waitForAllEnginesCalledCount); +} + HWTEST_F(EnqueueSvmTestLocalMemory, givenEnabledLocalMemoryWhenMappedSvmRegionAndNoEventIsUsedIsWritableThenExpectMapAndUnmapCopyKernelAnNo) { using WALKER_TYPE = typename FamilyType::WALKER_TYPE; MockCommandQueueHw queue(context.get(), pClDevice, nullptr); diff --git a/opencl/test/unit_test/command_queue/enqueue_write_buffer_rect_tests.cpp b/opencl/test/unit_test/command_queue/enqueue_write_buffer_rect_tests.cpp index 58670a65ab..05f8a4f2ce 100644 --- a/opencl/test/unit_test/command_queue/enqueue_write_buffer_rect_tests.cpp +++ b/opencl/test/unit_test/command_queue/enqueue_write_buffer_rect_tests.cpp @@ -74,6 +74,37 @@ HWTEST_F(EnqueueWriteBufferRectTest, GivenValidParamsWhenWritingBufferThenSucces EXPECT_EQ(CL_SUCCESS, retVal); } +HWTEST_F(EnqueueWriteBufferRectTest, GivenGpuHangAndBlockingCallAndValidParamsWhenWritingBufferThenOutOfResourcesIsReturned) { + size_t srcOrigin[] = {0, 0, 0}; + size_t dstOrigin[] = {0, 0, 0}; + size_t region[] = {1, 1, 1}; + + std::unique_ptr device(new MockClDevice{MockClDevice::createWithNewExecutionEnvironment(nullptr)}); + cl_queue_properties props = {}; + + MockCommandQueueHw mockCommandQueueHw(context.get(), device.get(), &props); + mockCommandQueueHw.waitForAllEnginesReturnValue = WaitStatus::GpuHang; + + const auto enqueueResult = clEnqueueWriteBufferRect( + &mockCommandQueueHw, + buffer.get(), + CL_TRUE, + srcOrigin, + dstOrigin, + region, + 10, + 0, + 10, + 0, + hostPtr, + 0, + nullptr, + nullptr); + + EXPECT_EQ(CL_OUT_OF_RESOURCES, enqueueResult); + EXPECT_EQ(1, mockCommandQueueHw.waitForAllEnginesCalledCount); +} + HWTEST_F(EnqueueWriteBufferRectTest, GivenBlockingEnqueueWhenWritingBufferThenTaskLevelIsNotIncremented) { //this test case assumes IOQ auto &csr = pDevice->getUltCommandStreamReceiver(); diff --git a/opencl/test/unit_test/command_queue/enqueue_write_buffer_tests.cpp b/opencl/test/unit_test/command_queue/enqueue_write_buffer_tests.cpp index 864d82c061..42a07b20a1 100644 --- a/opencl/test/unit_test/command_queue/enqueue_write_buffer_tests.cpp +++ b/opencl/test/unit_test/command_queue/enqueue_write_buffer_tests.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018-2021 Intel Corporation + * Copyright (C) 2018-2022 Intel Corporation * * SPDX-License-Identifier: MIT * @@ -72,6 +72,20 @@ HWTEST_F(EnqueueWriteBufferTypeTest, GivenBlockingEnqueueWhenWritingBufferThenTa EXPECT_EQ(oldCsrTaskLevel, pCmdQ->taskLevel); } +HWTEST_F(EnqueueWriteBufferTypeTest, GivenGpuHangAndBlockingEnqueueWhenWritingBufferThenOutOfResourcesIsReturned) { + std::unique_ptr device(new MockClDevice{MockClDevice::createWithNewExecutionEnvironment(nullptr)}); + cl_queue_properties props = {}; + + MockCommandQueueHw mockCommandQueueHw(context, device.get(), &props); + mockCommandQueueHw.waitForAllEnginesReturnValue = WaitStatus::GpuHang; + + srcBuffer->forceDisallowCPUCopy = true; + const auto enqueueResult = EnqueueWriteBufferHelper<>::enqueueWriteBuffer(&mockCommandQueueHw, srcBuffer.get(), CL_TRUE); + + EXPECT_EQ(CL_OUT_OF_RESOURCES, enqueueResult); + EXPECT_EQ(1, mockCommandQueueHw.waitForAllEnginesCalledCount); +} + HWTEST_F(EnqueueWriteBufferTypeTest, GivenNonBlockingEnqueueWhenWritingBufferThenTaskLevelIsIncremented) { //this test case assumes IOQ auto &csr = pDevice->getUltCommandStreamReceiver(); diff --git a/opencl/test/unit_test/command_queue/enqueue_write_image_tests.cpp b/opencl/test/unit_test/command_queue/enqueue_write_image_tests.cpp index b8719203ed..a327b1cb87 100644 --- a/opencl/test/unit_test/command_queue/enqueue_write_image_tests.cpp +++ b/opencl/test/unit_test/command_queue/enqueue_write_image_tests.cpp @@ -5,6 +5,7 @@ * */ +#include "shared/source/command_stream/wait_status.h" #include "shared/source/memory_manager/allocations_list.h" #include "shared/source/memory_manager/memory_manager.h" #include "shared/source/memory_manager/migration_sync_data.h" @@ -70,6 +71,19 @@ HWTEST_F(EnqueueWriteImageTest, GivenBlockingEnqueueWhenWritingImageThenTaskLeve EXPECT_EQ(oldCsrTaskLevel, pCmdQ->taskLevel); } +HWTEST_F(EnqueueWriteImageTest, GivenGpuHangAndBlockingEnqueueWhenWritingImageThenOutOfResourcesIsReturned) { + std::unique_ptr device(new MockClDevice{MockClDevice::createWithNewExecutionEnvironment(nullptr)}); + cl_queue_properties props = {}; + + MockCommandQueueHw mockCommandQueueHw(context, device.get(), &props); + mockCommandQueueHw.waitForAllEnginesReturnValue = WaitStatus::GpuHang; + + const auto enqueueResult = EnqueueWriteImageHelper<>::enqueueWriteImage(&mockCommandQueueHw, dstImage, CL_TRUE); + + EXPECT_EQ(CL_OUT_OF_RESOURCES, enqueueResult); + EXPECT_EQ(1, mockCommandQueueHw.waitForAllEnginesCalledCount); +} + HWTEST_F(EnqueueWriteImageTest, GivenNonBlockingEnqueueWhenWritingImageThenTaskLevelIsIncremented) { //this test case assumes IOQ auto &csr = pDevice->getUltCommandStreamReceiver(); diff --git a/opencl/test/unit_test/mocks/mock_command_queue.h b/opencl/test/unit_test/mocks/mock_command_queue.h index 580037bbda..f3d21ae2f4 100644 --- a/opencl/test/unit_test/mocks/mock_command_queue.h +++ b/opencl/test/unit_test/mocks/mock_command_queue.h @@ -350,14 +350,14 @@ class MockCommandQueueHw : public CommandQueueHw { return BaseClass::waitUntilComplete(gpgpuTaskCountToWait, copyEnginesToWait, flushStampToWait, useQuickKmdSleep, cleanTemporaryAllocationList, skipWait); } - WaitStatus waitForAllEngines(bool blockedQueue, PrintfHandler *printfHandler) override { + WaitStatus waitForAllEngines(bool blockedQueue, PrintfHandler *printfHandler, bool cleanTemporaryAllocationsList) override { waitForAllEnginesCalledCount++; if (waitForAllEnginesReturnValue.has_value()) { return *waitForAllEnginesReturnValue; } - return BaseClass::waitForAllEngines(blockedQueue, printfHandler); + return BaseClass::waitForAllEngines(blockedQueue, printfHandler, cleanTemporaryAllocationsList); } bool isCacheFlushForBcsRequired() const override {