From e4d56cde219bf07e7b6c4f8813da0f0060111b19 Mon Sep 17 00:00:00 2001 From: Patryk Wrobel Date: Mon, 21 Mar 2022 11:08:43 +0000 Subject: [PATCH] Detect GPU hangs in blocking enqueue handler calls This change introduces detection of GPU hangs in blocking calls to enqueueHandler() function. Moreover, usages of this function template have been revised and adjusted to check the exit code. Furthermore, enqueueBlit() and dispatchBcsOrGpgpuEnqueue() functions returns value now. ULTs have been added to cover new cases. Signed-off-by: Patryk Wrobel Related-To: NEO-6681 --- .../source/command_queue/command_queue_hw.h | 54 ++-- .../command_queue/command_queue_hw_base.inl | 7 +- opencl/source/command_queue/enqueue_barrier.h | 16 +- opencl/source/command_queue/enqueue_common.h | 85 +++-- .../command_queue/enqueue_copy_buffer.h | 6 +- .../command_queue/enqueue_copy_buffer_rect.h | 7 +- .../enqueue_copy_buffer_to_image.h | 7 +- .../source/command_queue/enqueue_copy_image.h | 7 +- .../enqueue_copy_image_to_buffer.h | 7 +- .../command_queue/enqueue_fill_buffer.h | 4 +- .../source/command_queue/enqueue_fill_image.h | 6 +- opencl/source/command_queue/enqueue_kernel.h | 5 +- opencl/source/command_queue/enqueue_marker.h | 16 +- .../enqueue_migrate_mem_objects.h | 17 +- .../command_queue/enqueue_read_buffer.h | 6 +- .../command_queue/enqueue_read_buffer_rect.h | 7 +- .../source/command_queue/enqueue_read_image.h | 7 +- .../command_queue/enqueue_resource_barrier.h | 18 +- opencl/source/command_queue/enqueue_svm.h | 135 ++++---- .../command_queue/enqueue_write_buffer.h | 7 +- .../command_queue/enqueue_write_buffer_rect.h | 7 +- .../command_queue/enqueue_write_image.h | 7 +- .../command_queue/blit_enqueue_tests.cpp | 22 ++ .../command_queue/command_queue_hw_tests.cpp | 2 + .../command_queue/enqueue_barrier_tests.cpp | 25 +- .../enqueue_command_without_kernel_tests.cpp | 11 +- .../enqueue_copy_buffer_rect_tests.cpp | 38 ++- .../enqueue_copy_buffer_tests.cpp | 27 ++ .../enqueue_copy_buffer_to_image_tests.cpp | 27 ++ .../enqueue_copy_image_tests.cpp | 16 + .../enqueue_copy_image_to_buffer_tests.cpp | 28 ++ .../enqueue_fill_buffer_negative_tests.cpp | 24 +- .../enqueue_fill_image_tests.cpp | 21 +- .../command_queue/enqueue_handler_tests.cpp | 156 ++++----- .../command_queue/enqueue_kernel_1_tests.cpp | 51 +++ .../command_queue/enqueue_marker_tests.cpp | 25 +- .../enqueue_migrate_mem_objects_tests.cpp | 31 +- .../enqueue_read_buffer_rect_tests.cpp | 33 +- .../enqueue_read_buffer_tests.cpp | 41 +++ .../enqueue_read_image_tests.cpp | 24 ++ .../enqueue_resource_barier_tests.cpp | 38 ++- .../command_queue/enqueue_svm_tests.cpp | 306 ++++++++++++++++++ .../enqueue_write_buffer_rect_tests.cpp | 31 ++ .../enqueue_write_buffer_tests.cpp | 16 +- .../enqueue_write_image_tests.cpp | 14 + .../test/unit_test/mocks/mock_command_queue.h | 4 +- 46 files changed, 1163 insertions(+), 286 deletions(-) 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 {