From d1d794c658c1e3dc0afe6db42177d9d56856e8a3 Mon Sep 17 00:00:00 2001 From: Piotr Maciejewski Date: Mon, 20 May 2019 11:19:27 +0200 Subject: [PATCH] Metrics Library Performance Counters implementation. Signed-off-by: Piotr Maciejewski Change-Id: I0f00dca1892f4857baaebc75ba2208a4f33db1bf --- CMakeLists.txt | 27 +- runtime/CMakeLists.txt | 9 - runtime/api/api.cpp | 21 +- runtime/command_queue/command_queue.cpp | 33 +- runtime/command_queue/command_queue.h | 17 - runtime/command_queue/enqueue_common.h | 9 +- runtime/command_queue/gpgpu_walker.h | 18 - runtime/command_queue/gpgpu_walker_base.inl | 132 +--- .../command_queue/gpgpu_walker_bdw_plus.inl | 27 +- .../command_stream_receiver.cpp | 4 +- .../command_stream/command_stream_receiver.h | 2 +- runtime/device/device.cpp | 3 +- runtime/dll/linux/options.cpp | 7 + runtime/dll/windows/options.cpp | 7 + runtime/event/event.cpp | 26 +- runtime/event/event.h | 5 - runtime/event/perf_counter.h | 14 +- runtime/gen11/hw_helper_gen11.cpp | 5 + runtime/gen9/hw_helper_gen9.cpp | 5 + runtime/helpers/hw_helper.h | 3 + runtime/helpers/hw_helper_base.inl | 5 + runtime/instrumentation/instrumentation.cpp | 82 -- runtime/instrumentation/instrumentation.h | 303 ++++--- runtime/os_interface/CMakeLists.txt | 2 + runtime/os_interface/linux/CMakeLists.txt | 1 + runtime/os_interface/linux/os_interface.cpp | 4 - .../os_interface/linux/os_metrics_library.cpp | 51 ++ .../linux/performance_counters_linux.cpp | 94 +-- .../linux/performance_counters_linux.h | 32 +- runtime/os_interface/metrics_library.cpp | 188 +++++ runtime/os_interface/metrics_library.h | 89 +++ runtime/os_interface/os_inc_base.h | 5 +- runtime/os_interface/os_interface.h | 1 - runtime/os_interface/performance_counters.cpp | 339 ++++---- runtime/os_interface/performance_counters.h | 134 ++-- runtime/os_interface/windows/CMakeLists.txt | 1 + runtime/os_interface/windows/os_interface.cpp | 4 - .../windows/os_metrics_library.cpp | 55 ++ .../windows/performance_counters_win.cpp | 91 ++- .../windows/performance_counters_win.h | 14 +- runtime/utilities/tag_allocator.h | 10 +- ...eate_perf_counters_command_queue_tests.inl | 30 +- .../api/cl_get_event_profiling_info_tests.inl | 2 +- ...cl_set_performance_configuration_tests.inl | 8 +- .../command_stream_receiver_tests.cpp | 5 +- unit_tests/event/event_tests.cpp | 73 +- unit_tests/instrumentation/CMakeLists.txt | 11 - .../instrumentation/instrumentation_tests.cpp | 102 --- unit_tests/mocks/CMakeLists.txt | 1 - unit_tests/mocks/mock_device.h | 6 +- unit_tests/mocks/mock_instrumentation.cpp | 82 -- .../linux/mock_performance_counters_linux.cpp | 104 +-- .../linux/mock_performance_counters_linux.h | 50 +- unit_tests/os_interface/linux/options.cpp | 1 + .../performance_counters_linux_tests.cpp | 435 +--------- .../mock_performance_counters.cpp | 466 ++++++++--- .../os_interface/mock_performance_counters.h | 335 +++++--- .../performance_counters_gen_tests.cpp | 58 +- .../performance_counters_tests.cpp | 745 ++++++++++-------- .../windows/hw_info_config_win_tests.cpp | 2 + .../windows/mock_performance_counters_win.cpp | 74 +- .../windows/mock_performance_counters_win.h | 23 +- unit_tests/os_interface/windows/options.cpp | 1 + .../windows/os_interface_win_tests.cpp | 5 - .../performance_counters_win_tests.cpp | 173 ---- .../windows/wddm_memory_manager_tests.cpp | 2 +- unit_tests/profiling/profiling_tests.cpp | 98 +-- 67 files changed, 2154 insertions(+), 2617 deletions(-) create mode 100644 runtime/os_interface/linux/os_metrics_library.cpp create mode 100644 runtime/os_interface/metrics_library.cpp create mode 100644 runtime/os_interface/metrics_library.h create mode 100644 runtime/os_interface/windows/os_metrics_library.cpp delete mode 100644 unit_tests/instrumentation/CMakeLists.txt delete mode 100644 unit_tests/instrumentation/instrumentation_tests.cpp delete mode 100644 unit_tests/mocks/mock_instrumentation.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 3a5f45a3e0..eb845744d2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -419,24 +419,17 @@ macro(copy_gmm_dll_for target) endmacro() # Instrumentation detection -if(NOT INSTRUMENTATION_LIB_NAME) - if(INSTRUMENTATION_SOURCE_DIR) - get_filename_component(INSTRUMENTATION_SOURCE_DIR "${INSTRUMENTATION_SOURCE_DIR}" ABSOLUTE) - else(INSTRUMENTATION_SOURCE_DIR) - get_filename_component(INSTRUMENTATION_SOURCE_DIR_tmp "${CMAKE_SOURCE_DIR}/../instrumentation" ABSOLUTE) - if(IS_DIRECTORY "${INSTRUMENTATION_SOURCE_DIR_tmp}") - set(INSTRUMENTATION_SOURCE_DIR "${INSTRUMENTATION_SOURCE_DIR_tmp}") - endif() +if(INSTRUMENTATION_SOURCE_DIR) + get_filename_component(INSTRUMENTATION_SOURCE_DIR "${INSTRUMENTATION_SOURCE_DIR}" ABSOLUTE) +else(INSTRUMENTATION_SOURCE_DIR) + get_filename_component(INSTRUMENTATION_SOURCE_DIR_tmp "${CMAKE_SOURCE_DIR}/../instrumentation" ABSOLUTE) + if(IS_DIRECTORY "${INSTRUMENTATION_SOURCE_DIR_tmp}") + set(INSTRUMENTATION_SOURCE_DIR "${INSTRUMENTATION_SOURCE_DIR_tmp}") endif() - if(IS_DIRECTORY "${INSTRUMENTATION_SOURCE_DIR}") - message(STATUS "Instrumentation source dir is: ${INSTRUMENTATION_SOURCE_DIR}") - add_subdirectory_unique("${INSTRUMENTATION_SOURCE_DIR}" "${IGDRCL_BUILD_DIR}/instrumentation") - set(INSTRUMENTATION_LIB_NAME "instrumentation_umd") - set(HAVE_INSTRUMENTATION TRUE) - endif() -else() +endif() +if(IS_DIRECTORY "${INSTRUMENTATION_SOURCE_DIR}") + message(STATUS "Instrumentation source dir is: ${INSTRUMENTATION_SOURCE_DIR}") set(HAVE_INSTRUMENTATION TRUE) - message(STATUS "Instrumentation library name: ${INSTRUMENTATION_LIB_NAME}") endif() # LibVA detection @@ -736,7 +729,7 @@ set(HW_SRC_INCLUDE_PATH ${IGDRCL_SOURCE_DIR}/runtime/gen_common) if(HAVE_INSTRUMENTATION) set(IGDRCL__INSTRUMENTATION_DIR_SUFFIX ${BRANCH_DIR_SUFFIX}) - include_directories($) + include_directories(${INSTRUMENTATION_SOURCE_DIR}) else() set(IGDRCL__INSTRUMENTATION_DIR_SUFFIX "/") endif() diff --git a/runtime/CMakeLists.txt b/runtime/CMakeLists.txt index 49758bd132..f168ce8e30 100644 --- a/runtime/CMakeLists.txt +++ b/runtime/CMakeLists.txt @@ -88,10 +88,6 @@ endif() target_compile_definitions(${NEO_STATIC_LIB_NAME} PUBLIC GMM_LIB_DLL DEFAULT_PLATFORM=${DEFAULT_SUPPORTED_PLATFORM}) -if(INSTRUMENTATION_LIB_NAME) - add_dependencies(${NEO_STATIC_LIB_NAME} ${INSTRUMENTATION_LIB_NAME}) -endif() - list(APPEND LIB_FLAGS_DEFINITIONS -DCIF_HEADERS_ONLY_BUILD ${SUPPORTED_GEN_FLAGS_DEFINITONS}) target_compile_definitions(${NEO_STATIC_LIB_NAME} PUBLIC ${LIB_FLAGS_DEFINITIONS}) @@ -149,15 +145,10 @@ if(${GENERATE_EXECUTABLE}) add_subdirectory(dll) - if(HAVE_INSTRUMENTATION) - target_link_libraries(${NEO_DYNAMIC_LIB_NAME} ${INSTRUMENTATION_LIB_NAME}) - endif() - target_link_libraries(${NEO_DYNAMIC_LIB_NAME} ${NEO_STATIC_LIB_NAME} ${IGDRCL_EXTRA_LIBS}) target_include_directories(${NEO_DYNAMIC_LIB_NAME} BEFORE PRIVATE ${CMAKE_CURRENT_BINARY_DIR} - ${INSTRUMENTATION_INCLUDE_PATH} ${AUB_STREAM_DIR}/.. ) diff --git a/runtime/api/api.cpp b/runtime/api/api.cpp index 127297c240..eeba12ed98 100644 --- a/runtime/api/api.cpp +++ b/runtime/api/api.cpp @@ -3374,25 +3374,8 @@ clSetPerformanceConfigurationINTEL( cl_uint count, cl_uint *offsets, cl_uint *values) { - Device *pDevice = nullptr; - - auto retVal = validateObjects(WithCastToInternal(device, &pDevice)); - - API_ENTER(&retVal); - DBG_LOG_INPUTS("device", device, - "count", count, - "offsets", offsets, - "values", values); - if (CL_SUCCESS != retVal) { - return retVal; - } - if (!pDevice->getHardwareInfo().capabilityTable.instrumentationEnabled) { - retVal = CL_PROFILING_INFO_NOT_AVAILABLE; - return retVal; - } - auto perfCounters = pDevice->getPerformanceCounters(); - retVal = perfCounters->sendPerfConfiguration(count, offsets, values); - return retVal; + // Not supported, covered by Metric Library DLL. + return CL_INVALID_OPERATION; } void *clHostMemAllocINTEL( diff --git a/runtime/command_queue/command_queue.cpp b/runtime/command_queue/command_queue.cpp index 911b7dfa2d..c28ed588cc 100644 --- a/runtime/command_queue/command_queue.cpp +++ b/runtime/command_queue/command_queue.cpp @@ -90,9 +90,6 @@ CommandQueue::~CommandQueue() { } delete commandStream; - if (perfConfigurationData) { - delete perfConfigurationData; - } if (this->perfCountersEnabled) { device->getPerformanceCounters()->shutdown(); } @@ -275,44 +272,32 @@ bool CommandQueue::setPerfCountersEnabled(bool perfCountersEnabled, cl_uint conf if (perfCountersEnabled == this->perfCountersEnabled) { return true; } + // Only dynamic configuration (set 0) is supported. + const uint32_t dynamicSet = 0; + if (configuration != dynamicSet) { + return false; + } auto perfCounters = device->getPerformanceCounters(); + if (perfCountersEnabled) { perfCounters->enable(); if (!perfCounters->isAvailable()) { perfCounters->shutdown(); return false; } - perfConfigurationData = perfCounters->getPmRegsCfg(configuration); - if (perfConfigurationData == nullptr) { - perfCounters->shutdown(); - return false; - } - InstrReadRegsCfg *pUserCounters = &perfConfigurationData->ReadRegs; - for (uint32_t i = 0; i < pUserCounters->RegsCount; ++i) { - perfCountersUserRegistersNumber++; - if (pUserCounters->Reg[i].BitSize > 32) { - perfCountersUserRegistersNumber++; - } - } } else { - if (perfCounters->isAvailable()) { - perfCounters->shutdown(); - } + perfCounters->shutdown(); } - this->perfCountersConfig = configuration; + this->perfCountersEnabled = perfCountersEnabled; return true; -} +} // namespace NEO PerformanceCounters *CommandQueue::getPerfCounters() { return device->getPerformanceCounters(); } -bool CommandQueue::sendPerfCountersConfig() { - return getPerfCounters()->sendPmRegsCfgCommands(perfConfigurationData, &perfCountersRegsCfgHandle, &perfCountersRegsCfgPending); -} - cl_int CommandQueue::enqueueWriteMemObjForUnmap(MemObj *memObj, void *mappedPtr, EventsRequest &eventsRequest) { cl_int retVal = CL_SUCCESS; diff --git a/runtime/command_queue/command_queue.h b/runtime/command_queue/command_queue.h index d94efff403..46cf60aafd 100644 --- a/runtime/command_queue/command_queue.h +++ b/runtime/command_queue/command_queue.h @@ -12,8 +12,6 @@ #include "runtime/helpers/engine_control.h" #include "runtime/helpers/task_information.h" -#include "instrumentation.h" - #include #include @@ -374,24 +372,14 @@ class CommandQueue : public BaseObject<_cl_command_queue> { return perfCountersEnabled; } - InstrPmRegsCfg *getPerfCountersConfigData() { - return perfConfigurationData; - } - PerformanceCounters *getPerfCounters(); - bool sendPerfCountersConfig(); - bool setPerfCountersEnabled(bool perfCountersEnabled, cl_uint configuration); void setIsSpecialCommandQueue(bool newValue) { this->isSpecialCommandQueue = newValue; } - uint16_t getPerfCountersUserRegistersNumber() const { - return perfCountersUserRegistersNumber; - } - QueuePriority getPriority() const { return priority; } @@ -462,11 +450,6 @@ class CommandQueue : public BaseObject<_cl_command_queue> { QueueThrottle throttle = QueueThrottle::MEDIUM; bool perfCountersEnabled = false; - cl_uint perfCountersConfig = std::numeric_limits::max(); - uint32_t perfCountersUserRegistersNumber = 0; - InstrPmRegsCfg *perfConfigurationData = nullptr; - uint32_t perfCountersRegsCfgHandle = 0; - bool perfCountersRegsCfgPending = false; LinearStream *commandStream = nullptr; diff --git a/runtime/command_queue/enqueue_common.h b/runtime/command_queue/enqueue_common.h index fcfa040ef6..f0dbe2f45f 100644 --- a/runtime/command_queue/enqueue_common.h +++ b/runtime/command_queue/enqueue_common.h @@ -403,11 +403,6 @@ void CommandQueueHw::processDispatchForKernels(const MultiDispatchInf if (event && this->isProfilingEnabled()) { // Get allocation for timestamps hwTimeStamps = event->getHwTimeStampNode(); - if (this->isPerfCountersEnabled()) { - hwPerfCounter = event->getHwPerfCounterNode(); - // PERF COUNTER: copy current configuration from queue to event - event->copyPerfCounters(this->getPerfCountersConfigData()); - } } if (parentKernel) { @@ -421,6 +416,10 @@ void CommandQueueHw::processDispatchForKernels(const MultiDispatchInf } } + if (event && this->isPerfCountersEnabled()) { + hwPerfCounter = event->getHwPerfCounterNode(); + } + HardwareInterface::dispatchWalker( *this, multiDispatchInfo, diff --git a/runtime/command_queue/gpgpu_walker.h b/runtime/command_queue/gpgpu_walker.h index 797ff552c8..8ff3b0be2d 100644 --- a/runtime/command_queue/gpgpu_walker.h +++ b/runtime/command_queue/gpgpu_walker.h @@ -175,24 +175,6 @@ class GpgpuWalkerHelper { uint32_t aluRegister, uint32_t operation, uint32_t mask); - - static void dispatchStoreRegisterCommand( - LinearStream *commandStream, - uint64_t memoryAddress, - uint32_t registerAddress); - - static void dispatchPerfCountersGeneralPurposeCounterCommands( - LinearStream *commandStream, - uint64_t baseAddress); - - static void dispatchPerfCountersUserCounterCommands( - CommandQueue &commandQueue, - LinearStream *commandStream, - uint64_t baseAddress); - - static void dispatchPerfCountersOABufferStateCommands( - TagNode &hwPerfCounter, - LinearStream *commandStream); }; template diff --git a/runtime/command_queue/gpgpu_walker_base.inl b/runtime/command_queue/gpgpu_walker_base.inl index a0777dc7a3..c241f8d4b6 100644 --- a/runtime/command_queue/gpgpu_walker_base.inl +++ b/runtime/command_queue/gpgpu_walker_base.inl @@ -24,8 +24,6 @@ #include "runtime/memory_manager/graphics_allocation.h" #include "runtime/utilities/tag_allocator.h" -#include "instrumentation.h" - #include #include @@ -149,102 +147,17 @@ void GpgpuWalkerHelper::dispatchProfilingCommandsEnd( pMICmdLow->setMemoryAddress(timeStampAddress); } -template -void GpgpuWalkerHelper::dispatchStoreRegisterCommand( - LinearStream *commandStream, - uint64_t memoryAddress, - uint32_t registerAddress) { - - using MI_STORE_REGISTER_MEM = typename GfxFamily::MI_STORE_REGISTER_MEM; - - auto pCmd = commandStream->getSpaceForCmd(); - *pCmd = GfxFamily::cmdInitStoreRegisterMem; - pCmd->setRegisterAddress(registerAddress); - pCmd->setMemoryAddress(memoryAddress); -} - -template -void GpgpuWalkerHelper::dispatchPerfCountersGeneralPurposeCounterCommands( - LinearStream *commandStream, - uint64_t baseAddress) { - - // Read General Purpose counters - for (auto i = 0u; i < NEO::INSTR_GENERAL_PURPOSE_COUNTERS_COUNT; i++) { - uint32_t regAddr = INSTR_GFX_OFFSETS::INSTR_PERF_CNT_1_DW0 + i * sizeof(cl_uint); - //Gp field is 2*uint64 wide so it can hold 4 uint32 - uint64_t address = baseAddress + i * sizeof(cl_uint); - dispatchStoreRegisterCommand(commandStream, address, regAddr); - } -} - -template -void GpgpuWalkerHelper::dispatchPerfCountersUserCounterCommands( - CommandQueue &commandQueue, - LinearStream *commandStream, - uint64_t baseAddress) { - - auto userRegs = &commandQueue.getPerfCountersConfigData()->ReadRegs; - - for (uint32_t i = 0; i < userRegs->RegsCount; i++) { - uint32_t regAddr = userRegs->Reg[i].Offset; - //offset between base (low) registers is cl_ulong wide - uint64_t address = baseAddress + i * sizeof(cl_ulong); - dispatchStoreRegisterCommand(commandStream, address, regAddr); - - if (userRegs->Reg[i].BitSize > 32) { - dispatchStoreRegisterCommand(commandStream, address + sizeof(cl_uint), regAddr + sizeof(cl_uint)); - } - } -} - -template -void GpgpuWalkerHelper::dispatchPerfCountersOABufferStateCommands( - TagNode &hwPerfCounter, - LinearStream *commandStream) { - - dispatchStoreRegisterCommand(commandStream, hwPerfCounter.getGpuAddress() + offsetof(HwPerfCounter, HWPerfCounters.OaStatus), INSTR_GFX_OFFSETS::INSTR_OA_STATUS); - dispatchStoreRegisterCommand(commandStream, hwPerfCounter.getGpuAddress() + offsetof(HwPerfCounter, HWPerfCounters.OaHead), INSTR_GFX_OFFSETS::INSTR_OA_HEAD_PTR); - dispatchStoreRegisterCommand(commandStream, hwPerfCounter.getGpuAddress() + offsetof(HwPerfCounter, HWPerfCounters.OaTail), INSTR_GFX_OFFSETS::INSTR_OA_TAIL_PTR); -} - template void GpgpuWalkerHelper::dispatchPerfCountersCommandsStart( CommandQueue &commandQueue, TagNode &hwPerfCounter, LinearStream *commandStream) { - using MI_REPORT_PERF_COUNT = typename GfxFamily::MI_REPORT_PERF_COUNT; + auto pPerformanceCounters = commandQueue.getPerfCounters(); + const uint32_t size = pPerformanceCounters->getGpuCommandsSize(true); + void *pBuffer = commandStream->getSpace(size); - auto perfCounters = commandQueue.getPerfCounters(); - - uint32_t currentReportId = perfCounters->getCurrentReportId(); - uint64_t address = 0; - //flush command streamer - auto pPipeControlCmd = commandStream->getSpaceForCmd(); - *pPipeControlCmd = GfxFamily::cmdInitPipeControl; - pPipeControlCmd->setCommandStreamerStallEnable(true); - - //Store value of NOOPID register - GpgpuWalkerHelper::dispatchStoreRegisterCommand(commandStream, hwPerfCounter.getGpuAddress() + offsetof(HwPerfCounter, HWPerfCounters.DMAFenceIdBegin), INSTR_MMIO_NOOPID); - - //Read Core Frequency - GpgpuWalkerHelper::dispatchStoreRegisterCommand(commandStream, hwPerfCounter.getGpuAddress() + offsetof(HwPerfCounter, HWPerfCounters.CoreFreqBegin), INSTR_MMIO_RPSTAT1); - - GpgpuWalkerHelper::dispatchPerfCountersGeneralPurposeCounterCommands(commandStream, hwPerfCounter.getGpuAddress() + offsetof(HwPerfCounter, HWPerfCounters.HwPerfReportBegin.Gp)); - - auto pReportPerfCount = commandStream->getSpaceForCmd(); - *pReportPerfCount = GfxFamily::cmdInitReportPerfCount; - pReportPerfCount->setReportId(currentReportId); - address = hwPerfCounter.getGpuAddress() + offsetof(HwPerfCounter, HWPerfCounters.HwPerfReportBegin.Oa); - pReportPerfCount->setMemoryAddress(address); - - address = hwPerfCounter.getGpuAddress() + offsetof(HwPerfCounter, HWTimeStamp.GlobalStartTS); - - PipeControlHelper::obtainPipeControlAndProgramPostSyncOperation(commandStream, PIPE_CONTROL::POST_SYNC_OPERATION_WRITE_TIMESTAMP, address, 0llu, false); - - GpgpuWalkerHelper::dispatchPerfCountersUserCounterCommands(commandQueue, commandStream, hwPerfCounter.getGpuAddress() + offsetof(HwPerfCounter, HWPerfCounters.HwPerfReportBegin.User)); - - commandQueue.sendPerfCountersConfig(); + pPerformanceCounters->getGpuCommands(hwPerfCounter, true, size, pBuffer); } template @@ -253,40 +166,11 @@ void GpgpuWalkerHelper::dispatchPerfCountersCommandsEnd( TagNode &hwPerfCounter, LinearStream *commandStream) { - using MI_REPORT_PERF_COUNT = typename GfxFamily::MI_REPORT_PERF_COUNT; + auto pPerformanceCounters = commandQueue.getPerfCounters(); + const uint32_t size = pPerformanceCounters->getGpuCommandsSize(false); + void *pBuffer = commandStream->getSpace(size); - auto perfCounters = commandQueue.getPerfCounters(); - - uint32_t currentReportId = perfCounters->getCurrentReportId(); - - //flush command streamer - auto pPipeControlCmd = commandStream->getSpaceForCmd(); - *pPipeControlCmd = GfxFamily::cmdInitPipeControl; - pPipeControlCmd->setCommandStreamerStallEnable(true); - - GpgpuWalkerHelper::dispatchPerfCountersOABufferStateCommands(hwPerfCounter, commandStream); - - //Timestamp: Global End - uint64_t address = hwPerfCounter.getGpuAddress() + offsetof(HwPerfCounter, HWTimeStamp.GlobalEndTS); - PipeControlHelper::obtainPipeControlAndProgramPostSyncOperation(commandStream, PIPE_CONTROL::POST_SYNC_OPERATION_WRITE_TIMESTAMP, address, 0llu, false); - - auto pReportPerfCount = commandStream->getSpaceForCmd(); - *pReportPerfCount = GfxFamily::cmdInitReportPerfCount; - pReportPerfCount->setReportId(currentReportId); - address = hwPerfCounter.getGpuAddress() + offsetof(HwPerfCounter, HWPerfCounters.HwPerfReportEnd.Oa); - pReportPerfCount->setMemoryAddress(address); - - GpgpuWalkerHelper::dispatchPerfCountersGeneralPurposeCounterCommands(commandStream, hwPerfCounter.getGpuAddress() + offsetof(HwPerfCounter, HWPerfCounters.HwPerfReportEnd.Gp)); - - //Store value of NOOPID register - GpgpuWalkerHelper::dispatchStoreRegisterCommand(commandStream, hwPerfCounter.getGpuAddress() + offsetof(HwPerfCounter, HWPerfCounters.DMAFenceIdEnd), INSTR_MMIO_NOOPID); - - //Read Core Frequency - GpgpuWalkerHelper::dispatchStoreRegisterCommand(commandStream, hwPerfCounter.getGpuAddress() + offsetof(HwPerfCounter, HWPerfCounters.CoreFreqEnd), INSTR_MMIO_RPSTAT1); - - GpgpuWalkerHelper::dispatchPerfCountersUserCounterCommands(commandQueue, commandStream, hwPerfCounter.getGpuAddress() + offsetof(HwPerfCounter, HWPerfCounters.HwPerfReportEnd.User)); - - perfCounters->setCpuTimestamp(); + pPerformanceCounters->getGpuCommands(hwPerfCounter, false, size, pBuffer); } template diff --git a/runtime/command_queue/gpgpu_walker_bdw_plus.inl b/runtime/command_queue/gpgpu_walker_bdw_plus.inl index dee5cf8173..ea49e80232 100644 --- a/runtime/command_queue/gpgpu_walker_bdw_plus.inl +++ b/runtime/command_queue/gpgpu_walker_bdw_plus.inl @@ -189,31 +189,8 @@ size_t EnqueueOperation::getSizeRequiredCSKernel(bool reserveProfilin size += 2 * sizeof(PIPE_CONTROL) + 2 * sizeof(typename GfxFamily::MI_STORE_REGISTER_MEM); } if (reservePerfCounters) { - //start cmds - //P_C: flush CS & TimeStamp BEGIN - size += 2 * sizeof(PIPE_CONTROL); - //SRM NOOPID & Frequency - size += 2 * sizeof(typename GfxFamily::MI_STORE_REGISTER_MEM); - //gp registers - size += NEO::INSTR_GENERAL_PURPOSE_COUNTERS_COUNT * sizeof(typename GfxFamily::MI_STORE_REGISTER_MEM); - //report perf count - size += sizeof(typename GfxFamily::MI_REPORT_PERF_COUNT); - //user registers - size += commandQueue.getPerfCountersUserRegistersNumber() * sizeof(typename GfxFamily::MI_STORE_REGISTER_MEM); - - //end cmds - //P_C: flush CS & TimeStamp END; - size += 2 * sizeof(PIPE_CONTROL); - //OA buffer (status head, tail) - size += 3 * sizeof(typename GfxFamily::MI_STORE_REGISTER_MEM); - //report perf count - size += sizeof(typename GfxFamily::MI_REPORT_PERF_COUNT); - //gp registers - size += NEO::INSTR_GENERAL_PURPOSE_COUNTERS_COUNT * sizeof(typename GfxFamily::MI_STORE_REGISTER_MEM); - //SRM NOOPID & Frequency - size += 2 * sizeof(typename GfxFamily::MI_STORE_REGISTER_MEM); - //user registers - size += commandQueue.getPerfCountersUserRegistersNumber() * sizeof(typename GfxFamily::MI_STORE_REGISTER_MEM); + size += commandQueue.getPerfCounters()->getGpuCommandsSize(true); + size += commandQueue.getPerfCounters()->getGpuCommandsSize(false); } size += GpgpuWalkerHelper::getSizeForWADisableLSQCROPERFforOCL(pKernel); diff --git a/runtime/command_stream/command_stream_receiver.cpp b/runtime/command_stream/command_stream_receiver.cpp index 3178b552ea..49a769b9d5 100644 --- a/runtime/command_stream/command_stream_receiver.cpp +++ b/runtime/command_stream/command_stream_receiver.cpp @@ -414,9 +414,9 @@ TagAllocator *CommandStreamReceiver::getEventTsAllocator() { return profilingTimeStampAllocator.get(); } -TagAllocator *CommandStreamReceiver::getEventPerfCountAllocator() { +TagAllocator *CommandStreamReceiver::getEventPerfCountAllocator(const uint32_t tagSize) { if (perfCounterAllocator.get() == nullptr) { - perfCounterAllocator = std::make_unique>(getMemoryManager(), getPreferredTagPoolSize(), MemoryConstants::cacheLineSize); + perfCounterAllocator = std::make_unique>(getMemoryManager(), getPreferredTagPoolSize(), MemoryConstants::cacheLineSize, tagSize); } return perfCounterAllocator.get(); } diff --git a/runtime/command_stream/command_stream_receiver.h b/runtime/command_stream/command_stream_receiver.h index a0dd90bac9..cc0a2da427 100644 --- a/runtime/command_stream/command_stream_receiver.h +++ b/runtime/command_stream/command_stream_receiver.h @@ -162,7 +162,7 @@ class CommandStreamReceiver { OsContext &getOsContext() const { return *osContext; } TagAllocator *getEventTsAllocator(); - TagAllocator *getEventPerfCountAllocator(); + TagAllocator *getEventPerfCountAllocator(const uint32_t tagSize); TagAllocator *getTimestampPacketAllocator(); virtual cl_int expectMemory(const void *gfxAddress, const void *srcAddress, size_t length, uint32_t compareOperation); diff --git a/runtime/device/device.cpp b/runtime/device/device.cpp index 9ef9df3dbe..179056a891 100644 --- a/runtime/device/device.cpp +++ b/runtime/device/device.cpp @@ -122,8 +122,7 @@ bool Device::createDeviceImpl() { auto &hwInfo = getHardwareInfo(); if (osTime->getOSInterface()) { if (hwInfo.capabilityTable.instrumentationEnabled) { - performanceCounters = createPerformanceCountersFunc(osTime.get()); - performanceCounters->initialize(&hwInfo); + performanceCounters = createPerformanceCountersFunc(this); } } diff --git a/runtime/dll/linux/options.cpp b/runtime/dll/linux/options.cpp index 4227dd25cf..d2c346888a 100644 --- a/runtime/dll/linux/options.cpp +++ b/runtime/dll/linux/options.cpp @@ -20,4 +20,11 @@ const char *gmmEntryName = GMM_ENTRY_NAME; const char *sysFsPciPath = "/sys/bus/pci/devices/"; const char *tbxLibName = "libtbxAccess.so"; + +// Os specific Metrics Library name +#if __x86_64__ || __ppc64__ +const char *metricsLibraryDllName = "libigdml64.so"; +#else +const char *metricsLibraryDllName = "libigdml32.so"; +#endif } // namespace Os diff --git a/runtime/dll/windows/options.cpp b/runtime/dll/windows/options.cpp index a85323fd36..d93bbe2d9e 100644 --- a/runtime/dll/windows/options.cpp +++ b/runtime/dll/windows/options.cpp @@ -15,4 +15,11 @@ const char *igcDllName = IGC_LIBRARY_NAME; const char *gdiDllName = "gdi32.dll"; const char *gmmDllName = GMM_UMD_DLL; const char *gmmEntryName = GMM_ENTRY_NAME; + +// Os specific Metrics Library name +#if _WIN64 +const char *metricsLibraryDllName = "igdml64.dll"; +#else +const char *metricsLibraryDllName = "igdml32.dll"; +#endif } // namespace Os diff --git a/runtime/event/event.cpp b/runtime/event/event.cpp index 25516a0236..197f72f8c7 100644 --- a/runtime/event/event.cpp +++ b/runtime/event/event.cpp @@ -26,6 +26,8 @@ #include "runtime/utilities/stackvec.h" #include "runtime/utilities/tag_allocator.h" +#define OCLRT_NUM_TIMESTAMP_BITS (32) + namespace NEO { const cl_uint Event::eventNotReady = 0xFFFFFFF0; @@ -136,9 +138,6 @@ Event::~Event() { if (ctx != nullptr) { ctx->decRefInternal(); } - if (perfConfigurationData) { - delete perfConfigurationData; - } // in case event did not unblock child events before unblockEventsBlockedByThis(executionStatus); @@ -201,12 +200,10 @@ cl_int Event::getEventProfilingInfo(cl_profiling_info paramName, if (!perfCountersEnabled) { return CL_INVALID_VALUE; } - if (!cmdQueue->getPerfCounters()->processEventReport(paramValueSize, - paramValue, - paramValueSizeRet, - getHwPerfCounterNode()->tagForCpuAccess, - perfConfigurationData, - updateStatusAndCheckCompletion())) { + if (!cmdQueue->getPerfCounters()->getApiReport(paramValueSize, + paramValue, + paramValueSizeRet, + updateStatusAndCheckCompletion())) { return CL_PROFILING_INFO_NOT_AVAILABLE; } return CL_SUCCESS; @@ -701,17 +698,14 @@ TagNode *Event::getHwTimeStampNode() { } TagNode *Event::getHwPerfCounterNode() { - if (!perfCounterNode) { - perfCounterNode = cmdQueue->getCommandStreamReceiver().getEventPerfCountAllocator()->getTag(); + + if (!perfCounterNode && cmdQueue->getPerfCounters()) { + const uint32_t gpuReportSize = cmdQueue->getPerfCounters()->getGpuReportSize(); + perfCounterNode = cmdQueue->getCommandStreamReceiver().getEventPerfCountAllocator(gpuReportSize)->getTag(); } return perfCounterNode; } -void Event::copyPerfCounters(InstrPmRegsCfg *config) { - perfConfigurationData = new InstrPmRegsCfg; - memcpy_s(perfConfigurationData, sizeof(InstrPmRegsCfg), config, sizeof(InstrPmRegsCfg)); -} - void Event::addTimestampPacketNodes(const TimestampPacketContainer &inputTimestampPacketContainer) { timestampPacketContainer->assignAndIncrementNodesRefCounts(inputTimestampPacketContainer); } diff --git a/runtime/event/event.h b/runtime/event/event.h index 0cfb7ab6ae..1dc592d5d9 100644 --- a/runtime/event/event.h +++ b/runtime/event/event.h @@ -21,8 +21,6 @@ #include #include -#define OCLRT_NUM_TIMESTAMP_BITS (32) - namespace NEO { template struct TagNode; @@ -121,8 +119,6 @@ class Event : public BaseObject<_cl_event>, public IDNode { this->perfCountersEnabled = perfCountersEnabled; } - void copyPerfCounters(InstrPmRegsCfg *config); - TagNode *getHwPerfCounterNode(); std::unique_ptr flushStamp; @@ -375,7 +371,6 @@ class Event : public BaseObject<_cl_event>, public IDNode { TagNode *timeStampNode = nullptr; TagNode *perfCounterNode = nullptr; std::unique_ptr timestampPacketContainer; - InstrPmRegsCfg *perfConfigurationData = nullptr; //number of events this event depends on std::atomic parentCount; //event parents diff --git a/runtime/event/perf_counter.h b/runtime/event/perf_counter.h index 83279841f0..3e42ef5d78 100644 --- a/runtime/event/perf_counter.h +++ b/runtime/event/perf_counter.h @@ -10,20 +10,22 @@ #include "runtime/event/hw_timestamps.h" #include "runtime/memory_manager/graphics_allocation.h" -#include "instrumentation.h" - namespace NEO { struct HwPerfCounter { void initialize() { - HWPerfCounters = {}; - HWTimeStamp.initialize(); + report[0] = 0; } + static GraphicsAllocation::AllocationType getAllocationType() { return GraphicsAllocation::AllocationType::PROFILING_TAG_BUFFER; } bool canBeReleased() const { return true; } - HwPerfCounters HWPerfCounters; - HwTimeStamps HWTimeStamp; + + // Gpu report size is not known during compile time. + // Such information will be provided by metrics library dll. + // Bellow variable will be allocated dynamically based on information + // from metrics library. Take look at CommandStreamReceiver::getEventPerfCountAllocator. + uint8_t report[1] = {}; }; } // namespace NEO diff --git a/runtime/gen11/hw_helper_gen11.cpp b/runtime/gen11/hw_helper_gen11.cpp index 5e022a7f82..6dc50f6fb7 100644 --- a/runtime/gen11/hw_helper_gen11.cpp +++ b/runtime/gen11/hw_helper_gen11.cpp @@ -17,6 +17,11 @@ uint32_t HwHelperHw::getComputeUnitsUsedForScratch(const HardwareInfo *p return pHwInfo->gtSystemInfo.MaxSubSlicesSupported * pHwInfo->gtSystemInfo.MaxEuPerSubSlice * 8; } +template <> +uint32_t HwHelperHw::getMetricsLibraryGenId() const { + return static_cast(MetricsLibraryApi::ClientGen::Gen11); +} + template class AubHelperHw; template class HwHelperHw; template class FlatBatchBufferHelperHw; diff --git a/runtime/gen9/hw_helper_gen9.cpp b/runtime/gen9/hw_helper_gen9.cpp index 27a4edbdba..236871fe38 100644 --- a/runtime/gen9/hw_helper_gen9.cpp +++ b/runtime/gen9/hw_helper_gen9.cpp @@ -33,6 +33,11 @@ void PipeControlHelper::addPipeControlWA(LinearStream &commandStream) { pCmd->setCommandStreamerStallEnable(true); } +template <> +uint32_t HwHelperHw::getMetricsLibraryGenId() const { + return static_cast(MetricsLibraryApi::ClientGen::Gen9); +} + template class AubHelperHw; template class HwHelperHw; template class FlatBatchBufferHelperHw; diff --git a/runtime/helpers/hw_helper.h b/runtime/helpers/hw_helper.h index d4123cd715..02722295ca 100644 --- a/runtime/helpers/hw_helper.h +++ b/runtime/helpers/hw_helper.h @@ -64,6 +64,7 @@ class HwHelper { virtual bool getEnableLocalMemory(const HardwareInfo &hwInfo) const = 0; virtual std::string getExtensions() const = 0; static uint32_t getMaxThreadsForVfe(const HardwareInfo &hwInfo); + virtual uint32_t getMetricsLibraryGenId() const = 0; static constexpr uint32_t lowPriorityGpgpuEngineIndex = 1; @@ -155,6 +156,8 @@ class HwHelperHw : public HwHelper { std::string getExtensions() const override; + uint32_t getMetricsLibraryGenId() const override; + protected: HwHelperHw() = default; }; diff --git a/runtime/helpers/hw_helper_base.inl b/runtime/helpers/hw_helper_base.inl index dae1f4162a..8bda51b79c 100644 --- a/runtime/helpers/hw_helper_base.inl +++ b/runtime/helpers/hw_helper_base.inl @@ -204,4 +204,9 @@ int PipeControlHelper::getRequiredPipeControlSize() { return pipeControlCount * sizeof(typename GfxFamily::PIPE_CONTROL); } +template +uint32_t HwHelperHw::getMetricsLibraryGenId() const { + return static_cast(MetricsLibraryApi::ClientGen::Gen9); +} + } // namespace NEO diff --git a/runtime/instrumentation/instrumentation.cpp b/runtime/instrumentation/instrumentation.cpp index 7b16ab1e18..22b2394ddf 100644 --- a/runtime/instrumentation/instrumentation.cpp +++ b/runtime/instrumentation/instrumentation.cpp @@ -9,86 +9,4 @@ namespace NEO { const bool haveInstrumentation = false; - -bool instrAutoSamplingStart( - InstrEscCbData cbData, - void **ppOAInterface) { - return false; -} - -bool instrAutoSamplingStop( - void **ppOAInterface) { - return false; -} - -bool instrCheckPmRegsCfg( - InstrPmRegsCfg *pQueryPmRegsCfg, - uint32_t *pLastPmRegsCfgHandle, - const void *pASInterface) { - return false; -} - -void instrGetPerfCountersQueryData( - InstrEscCbData cbData, - GTDI_QUERY *pData, - HwPerfCounters *pLayout, - uint64_t cpuRawTimestamp, - void *pASInterface, - InstrPmRegsCfg *pPmRegsCfg, - bool useMiRPC, - bool resetASData, - const InstrAllowedContexts *pAllowedContexts) { -} - -bool instrEscGetPmRegsCfg( - InstrEscCbData cbData, - uint32_t cfgId, - InstrPmRegsCfg *pCfg, - InstrAutoSamplingMode *pAutoSampling) { - return false; -} - -bool instrEscHwMetricsEnable( - InstrEscCbData cbData, - bool enable) { - return false; -} - -bool instrEscLoadPmRegsCfg( - InstrEscCbData cbData, - InstrPmRegsCfg *pCfg, - bool hardwareAccess) { - return false; -} - -bool instrEscSetPmRegsCfg( - InstrEscCbData cbData, - uint32_t count, - uint32_t *pOffsets, - uint32_t *pValues) { - return false; -} - -bool instrEscSendReadRegsCfg( - InstrEscCbData cbData, - uint32_t count, - uint32_t *pOffsets, - uint32_t *pBitSizes) { - return false; -} - -bool instrSetAvailable(bool enabled) { - return false; -} - -void instrEscVerifyEnable( - InstrEscCbData cbData) { -} - -uint32_t instrSetPlatformInfo( - uint32_t productId, - void *featureTable) { - return 0; -} - } // namespace NEO diff --git a/runtime/instrumentation/instrumentation.h b/runtime/instrumentation/instrumentation.h index c666cac7e8..d8b112e601 100644 --- a/runtime/instrumentation/instrumentation.h +++ b/runtime/instrumentation/instrumentation.h @@ -10,201 +10,162 @@ #include namespace NEO { - -constexpr unsigned int INSTR_GENERAL_PURPOSE_COUNTERS_COUNT = 4; -constexpr unsigned int INSTR_MAX_USER_COUNTERS_COUNT = 32; -constexpr unsigned int INSTR_MMIO_NOOPID = 0x2094; -constexpr unsigned int INSTR_MMIO_RPSTAT1 = 0xA01C; - -constexpr unsigned int INSTR_GTDI_MAX_READ_REGS = 16; -constexpr unsigned int INSTR_GTDI_PERF_METRICS_OA_COUNT = 36; -constexpr unsigned int INSTR_GTDI_PERF_METRICS_OA_40b_COUNT = 32; -constexpr unsigned int INSTR_GTDI_PERF_METRICS_NOA_COUNT = 16; -constexpr unsigned int INSTR_MAX_CONTEXT_TAGS = 128; - -constexpr unsigned int INSTR_MAX_OA_PROLOG = 2; -constexpr unsigned int INSTR_MAX_OA_EPILOG = 2; -constexpr unsigned int INSTR_MAX_PM_REGS_BASE = 256; -constexpr unsigned int INSTR_MAX_PM_REGS = (INSTR_MAX_PM_REGS_BASE + INSTR_MAX_OA_PROLOG + INSTR_MAX_OA_EPILOG); - -constexpr unsigned int INSTR_PM_REGS_CFG_INVALID = 0; -constexpr unsigned int INSTR_READ_REGS_CFG_TAG = 0xFFFFFFFE; -constexpr unsigned int INSTR_MAX_READ_REGS = 16; - extern const bool haveInstrumentation; +} // namespace NEO -typedef enum { - INSTR_AS_MODE_OFF, - INSTR_AS_MODE_EVENT, - INSTR_AS_MODE_TIMER, - INSTR_AS_MODE_DMA -} InstrAutoSamplingMode; +namespace MetricsLibraryApi { +// Dummy macros. +#define ML_STDCALL +#define METRICS_LIBRARY_CONTEXT_CREATE_1_0 "create" +#define METRICS_LIBRARY_CONTEXT_DELETE_1_0 "delete" -typedef enum GTDI_CONFIGURATION_SET { - GTDI_CONFIGURATION_SET_DYNAMIC = 0, - GTDI_CONFIGURATION_SET_1, - GTDI_CONFIGURATION_SET_2, - GTDI_CONFIGURATION_SET_3, - GTDI_CONFIGURATION_SET_4, - GTDI_CONFIGURATION_SET_COUNT, - GTDI_CONFIGURATION_SET_MAX = 0xFFFFFFFF -} GTDI_CONFIGURATION_SET; +// Dummy enumerators. +enum class ClientApi : uint32_t { OpenCL }; +enum class ClientGen : uint32_t { Unknown, + Gen9, + Gen11 }; +enum class ValueType : uint32_t { Uint32 }; +enum class GpuConfigurationActivationType : uint32_t { Tbs, + EscapeCode }; +enum class ObjectType : uint32_t { QueryHwCounters, + ConfigurationHwCountersUser, + ConfigurationHwCountersOa }; +enum class ParameterType : uint32_t { QueryHwCountersReportApiSize, + QueryHwCountersReportGpuSize }; +enum class StatusCode : uint32_t { Failed, + IncorrectObject, + Success }; +enum class GpuCommandBufferType : uint32_t { Render }; -enum INSTR_GFX_OFFSETS { - INSTR_PERF_CNT_1_DW0 = 0x91B8, - INSTR_PERF_CNT_1_DW1 = 0x91BC, - INSTR_PERF_CNT_2_DW0 = 0x91C0, - INSTR_PERF_CNT_2_DW1 = 0x91C4, - INSTR_OA_STATUS = 0x2B08, - INSTR_OA_HEAD_PTR = 0x2B0C, - INSTR_OA_TAIL_PTR = 0x2B10 +// Dummy handles. +struct Handle { + void *data; + bool IsValid() const { return data != nullptr; } // NOLINT +}; +struct QueryHandle_1_0 : Handle {}; +struct ConfigurationHandle_1_0 : Handle {}; +struct ContextHandle_1_0 : Handle {}; + +// Dummy structures. +struct ClientCallbacks_1_0 {}; + +struct ClientDataWindows_1_0 { + void *Device; + void *Adapter; + void *Escape; + bool KmdInstrumentationEnabled; }; -typedef struct { +struct ClientDataLinux_1_0 { + void *Reserved; +}; -} GTDI_QUERY; +struct ClientData_1_0 { + union { + ClientDataWindows_1_0 Windows; + ClientDataLinux_1_0 Linux; + }; +}; -typedef struct { - uint32_t contextId[INSTR_MAX_CONTEXT_TAGS]; - uint32_t count; -} InstrAllowedContexts; +struct ConfigurationActivateData_1_0 { + GpuConfigurationActivationType Type; +}; -typedef struct { - uint64_t counter[INSTR_GTDI_MAX_READ_REGS]; - uint32_t userCntrCfgId; -} InstrReportDataUser; +struct ClientType_1_0 { + ClientApi Api; + ClientGen Gen; +}; -typedef struct { - uint32_t reportId; - uint32_t timestamp; - uint32_t contextId; - uint32_t gpuTicksCounter; -} InstrReportDataOaHeader; +struct TypedValue_1_0 { + uint32_t ValueUInt32; +}; -typedef struct { - uint32_t oaCounter[INSTR_GTDI_PERF_METRICS_OA_COUNT]; - uint8_t oaCounterHB[INSTR_GTDI_PERF_METRICS_OA_40b_COUNT]; - uint32_t noaCounter[INSTR_GTDI_PERF_METRICS_NOA_COUNT]; -} InstrReportDataOaData; +struct GpuMemory_1_0 { + uint64_t GpuAddress; + void *CpuAddress; +}; -typedef struct { - InstrReportDataOaHeader header; - InstrReportDataOaData data; -} InstrReportDataOa; +struct CommandBufferQueryHwCounters_1_0 { + QueryHandle_1_0 Handle; + ConfigurationHandle_1_0 HandleUserConfiguration; + bool Begin; +}; -typedef struct { - uint64_t counter1; - uint64_t counter2; -} InstrReportDataMonitor; +struct CommandBufferSize_1_0 { + uint32_t GpuMemorySize; +}; -typedef struct { - InstrReportDataMonitor Gp; - InstrReportDataUser User; - InstrReportDataOa Oa; -} InstrReportData; +struct ConfigurationCreateData_1_0 { + ContextHandle_1_0 HandleContext; + ObjectType Type; +}; -typedef struct { - uint32_t DMAFenceIdBegin; - uint32_t DMAFenceIdEnd; - uint32_t CoreFreqBegin; - uint32_t CoreFreqEnd; - InstrReportData HwPerfReportBegin; - InstrReportData HwPerfReportEnd; - uint32_t OaStatus; - uint32_t OaHead; - uint32_t OaTail; -} HwPerfCounters; +struct CommandBufferData_1_0 { + ContextHandle_1_0 HandleContext; + ObjectType CommandsType; + GpuCommandBufferType Type; + GpuMemory_1_0 Allocation; + void *Data; + uint32_t Size; + CommandBufferQueryHwCounters_1_0 QueryHwCounters; +}; -typedef struct { - uint32_t Offset; - uint32_t BitSize; -} InstrPmReg; +struct QueryCreateData_1_0 { + ContextHandle_1_0 HandleContext; + ObjectType Type; + uint32_t Slots; +}; -typedef struct { - uint32_t Handle; - uint32_t RegsCount; -} InstrPmRegsOaCountersCfg; +struct GetReportQuery_1_0 { + QueryHandle_1_0 Handle; -typedef struct { - uint32_t Handle; - uint32_t RegsCount; -} InstrPmRegsGpCountersCfg; + uint32_t Slot; + uint32_t SlotsCount; -typedef struct { - InstrPmReg Reg[INSTR_MAX_READ_REGS]; - uint32_t RegsCount; -} InstrReadRegsCfg; + uint32_t DataSize; + void *Data; +}; -typedef struct { - InstrPmRegsOaCountersCfg OaCounters; - InstrPmRegsGpCountersCfg GpCounters; - InstrReadRegsCfg ReadRegs; -} InstrPmRegsCfg; +struct GetReportData_1_0 { + ObjectType Type; + GetReportQuery_1_0 Query; +}; -typedef struct { - void *hAdapter; - void *hDevice; - void *pfnEscapeCb; - bool DDI; -} InstrEscCbData; +struct ContextCreateData_1_0 { + ClientData_1_0 *ClientData; + ClientCallbacks_1_0 *ClientCallbacks; + struct Interface_1_0 *Api; +}; -bool instrAutoSamplingStart( - InstrEscCbData cbData, - void **ppOAInterface); +// Dummy functions. +using ContextCreateFunction_1_0 = StatusCode(ML_STDCALL *)(ClientType_1_0 clientType, struct ContextCreateData_1_0 *createData, ContextHandle_1_0 *handle); +using ContextDeleteFunction_1_0 = StatusCode(ML_STDCALL *)(const ContextHandle_1_0 handle); +using GetParameterFunction_1_0 = StatusCode(ML_STDCALL *)(const ParameterType parameter, ValueType *type, TypedValue_1_0 *value); +using CommandBufferGetFunction_1_0 = StatusCode(ML_STDCALL *)(const CommandBufferData_1_0 *data); +using CommandBufferGetSizeFunction_1_0 = StatusCode(ML_STDCALL *)(const CommandBufferData_1_0 *data, CommandBufferSize_1_0 *size); +using QueryCreateFunction_1_0 = StatusCode(ML_STDCALL *)(const QueryCreateData_1_0 *createData, QueryHandle_1_0 *handle); +using QueryDeleteFunction_1_0 = StatusCode(ML_STDCALL *)(const QueryHandle_1_0 handle); +using ConfigurationCreateFunction_1_0 = StatusCode(ML_STDCALL *)(const ConfigurationCreateData_1_0 *createData, ConfigurationHandle_1_0 *handle); +using ConfigurationActivateFunction_1_0 = StatusCode(ML_STDCALL *)(const ConfigurationHandle_1_0 handle, const ConfigurationActivateData_1_0 *activateData); +using ConfigurationDeactivateFunction_1_0 = StatusCode(ML_STDCALL *)(const ConfigurationHandle_1_0 handle); +using ConfigurationDeleteFunction_1_0 = StatusCode(ML_STDCALL *)(const ConfigurationHandle_1_0 handle); +using GetDataFunction_1_0 = StatusCode(ML_STDCALL *)(GetReportData_1_0 *data); -bool instrAutoSamplingStop( - void **ppOAInterface); +// Dummy interface. +struct Interface_1_0 { + GetParameterFunction_1_0 GetParameter; -bool instrCheckPmRegsCfg( - InstrPmRegsCfg *pQueryPmRegsCfg, - uint32_t *pLastPmRegsCfgHandle, - const void *pASInterface); + CommandBufferGetFunction_1_0 CommandBufferGet; + CommandBufferGetSizeFunction_1_0 CommandBufferGetSize; -void instrGetPerfCountersQueryData( - InstrEscCbData cbData, - GTDI_QUERY *pData, - HwPerfCounters *pLayout, - uint64_t cpuRawTimestamp, - void *pASInterface, - InstrPmRegsCfg *pPmRegsCfg, - bool useMiRPC, - bool resetASData = false, - const InstrAllowedContexts *pAllowedContexts = nullptr); + QueryCreateFunction_1_0 QueryCreate; + QueryDeleteFunction_1_0 QueryDelete; -bool instrEscGetPmRegsCfg( - InstrEscCbData cbData, - uint32_t cfgId, - InstrPmRegsCfg *pCfg, - InstrAutoSamplingMode *pAutoSampling); + ConfigurationCreateFunction_1_0 ConfigurationCreate; + ConfigurationActivateFunction_1_0 ConfigurationActivate; + ConfigurationDeactivateFunction_1_0 ConfigurationDeactivate; + ConfigurationDeleteFunction_1_0 ConfigurationDelete; -bool instrEscHwMetricsEnable( - InstrEscCbData cbData, - bool enable); - -bool instrEscLoadPmRegsCfg( - InstrEscCbData cbData, - InstrPmRegsCfg *pCfg, - bool hardwareAccess = 1); - -bool instrEscSetPmRegsCfg( - InstrEscCbData cbData, - uint32_t count, - uint32_t *pOffsets, - uint32_t *pValues); - -bool instrEscSendReadRegsCfg( - InstrEscCbData cbData, - uint32_t count, - uint32_t *pOffsets, - uint32_t *pBitSizes); - -bool instrSetAvailable(bool enabled); - -void instrEscVerifyEnable( - InstrEscCbData cbData); - -uint32_t instrSetPlatformInfo( - uint32_t productId, - void *featureTable); - -} // namespace NEO + GetDataFunction_1_0 GetData; +}; +}; // namespace MetricsLibraryApi \ No newline at end of file diff --git a/runtime/os_interface/CMakeLists.txt b/runtime/os_interface/CMakeLists.txt index 253c6b7e64..975569e1d0 100644 --- a/runtime/os_interface/CMakeLists.txt +++ b/runtime/os_interface/CMakeLists.txt @@ -14,6 +14,8 @@ set(RUNTIME_SRCS_OS_INTERFACE_BASE ${CMAKE_CURRENT_SOURCE_DIR}/debug_settings_manager.h ${CMAKE_CURRENT_SOURCE_DIR}/device_factory.cpp ${CMAKE_CURRENT_SOURCE_DIR}/device_factory.h + ${CMAKE_CURRENT_SOURCE_DIR}/metrics_library.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/metrics_library.h ${CMAKE_CURRENT_SOURCE_DIR}/os_context.h ${CMAKE_CURRENT_SOURCE_DIR}/os_inc_base.h ${CMAKE_CURRENT_SOURCE_DIR}/os_interface.h diff --git a/runtime/os_interface/linux/CMakeLists.txt b/runtime/os_interface/linux/CMakeLists.txt index 39f21d5e9b..473ebaccf6 100644 --- a/runtime/os_interface/linux/CMakeLists.txt +++ b/runtime/os_interface/linux/CMakeLists.txt @@ -44,6 +44,7 @@ set(RUNTIME_SRCS_OS_INTERFACE_LINUX ${CMAKE_CURRENT_SOURCE_DIR}/os_library.cpp ${CMAKE_CURRENT_SOURCE_DIR}/os_library.h ${CMAKE_CURRENT_SOURCE_DIR}/os_memory_linux.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/os_metrics_library.cpp ${CMAKE_CURRENT_SOURCE_DIR}/os_thread_linux.cpp ${CMAKE_CURRENT_SOURCE_DIR}/os_thread_linux.h ${CMAKE_CURRENT_SOURCE_DIR}/os_time_linux.cpp diff --git a/runtime/os_interface/linux/os_interface.cpp b/runtime/os_interface/linux/os_interface.cpp index c7a5054778..c26a147f89 100644 --- a/runtime/os_interface/linux/os_interface.cpp +++ b/runtime/os_interface/linux/os_interface.cpp @@ -19,10 +19,6 @@ OSInterface::~OSInterface() { delete osInterfaceImpl; } -uint32_t OSInterface::getHwContextId() const { - return 0; -} - bool OSInterface::are64kbPagesEnabled() { return osEnabled64kbPages; } diff --git a/runtime/os_interface/linux/os_metrics_library.cpp b/runtime/os_interface/linux/os_metrics_library.cpp new file mode 100644 index 0000000000..42a0e4e7f2 --- /dev/null +++ b/runtime/os_interface/linux/os_metrics_library.cpp @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2017-2019 Intel Corporation + * + * SPDX-License-Identifier: MIT + * + */ + +#include "runtime/os_interface/metrics_library.h" + +namespace NEO { +////////////////////////////////////////////////////// +// FUNCTION: MetricsLibrary::oaConfigurationActivate +////////////////////////////////////////////////////// +bool MetricsLibrary::oaConfigurationActivate( + const ConfigurationHandle_1_0 &handle) { + ConfigurationActivateData_1_0 data = {}; + data.Type = GpuConfigurationActivationType::Tbs; + + return api->functions.ConfigurationActivate( + handle, + &data) == StatusCode::Success; +} + +////////////////////////////////////////////////////// +// FUNCTION: MetricsLibrary::oaConfigurationDeactivate +////////////////////////////////////////////////////// +bool MetricsLibrary::oaConfigurationDeactivate( + const ConfigurationHandle_1_0 &handle) { + return api->functions.ConfigurationDeactivate( + handle) == StatusCode::Success; +} + +////////////////////////////////////////////////////// +// FUNCTION: MetricsLibrary::userConfigurationCreate +////////////////////////////////////////////////////// +bool MetricsLibrary::userConfigurationCreate( + const ContextHandle_1_0 &context, + ConfigurationHandle_1_0 &handle) { + // Not supported on Linux. + return true; +} + +////////////////////////////////////////////////////// +// FUNCTION: MetricsLibrary::userConfigurationDelete +////////////////////////////////////////////////////// +bool MetricsLibrary::userConfigurationDelete( + const ConfigurationHandle_1_0 &handle) { + // Not supported on Linux. + return true; +} +} // namespace NEO \ No newline at end of file diff --git a/runtime/os_interface/linux/performance_counters_linux.cpp b/runtime/os_interface/linux/performance_counters_linux.cpp index 1b18b7ae12..0367b97a3c 100644 --- a/runtime/os_interface/linux/performance_counters_linux.cpp +++ b/runtime/os_interface/linux/performance_counters_linux.cpp @@ -7,66 +7,58 @@ #include "performance_counters_linux.h" +#include "runtime/device/device.h" +#include "runtime/helpers/hw_helper.h" + namespace NEO { +//////////////////////////////////////////////////// +// PerformanceCounters::create +//////////////////////////////////////////////////// +std::unique_ptr PerformanceCounters::create(Device *device) { + auto counter = std::make_unique(); + auto gen = device->getHardwareInfo().platform.eRenderCoreFamily; + auto &hwHelper = HwHelper::get(gen); + UNRECOVERABLE_IF(counter == nullptr); -std::unique_ptr PerformanceCounters::create(OSTime *osTime) { - return std::unique_ptr(new PerformanceCountersLinux(osTime)); -} -PerformanceCountersLinux::PerformanceCountersLinux(OSTime *osTime) : PerformanceCounters(osTime) { - mdLibHandle = nullptr; - perfmonLoadConfigFunc = nullptr; + counter->clientType.Gen = static_cast(hwHelper.getMetricsLibraryGenId()); + return counter; } -PerformanceCountersLinux::~PerformanceCountersLinux() { - if (pAutoSamplingInterface) { - autoSamplingStopFunc(&pAutoSamplingInterface); - pAutoSamplingInterface = nullptr; - available = false; - } +////////////////////////////////////////////////////// +// PerformanceCountersLinux::enableCountersConfiguration +////////////////////////////////////////////////////// +bool PerformanceCountersLinux::enableCountersConfiguration() { + // Release previous counters configuration so the user + // can change configuration between kernels. + releaseCountersConfiguration(); - if (mdLibHandle) { - dlcloseFunc(mdLibHandle); - mdLibHandle = nullptr; - } -} - -void PerformanceCountersLinux::initialize(const HardwareInfo *hwInfo) { - PerformanceCounters::initialize(hwInfo); - mdLibHandle = dlopenFunc("libmd.so", RTLD_LAZY | RTLD_LOCAL); - if (mdLibHandle) { - perfmonLoadConfigFunc = reinterpret_cast(dlsymFunc(mdLibHandle, "drm_intel_perfmon_load_config")); - } - setPlatformInfoFunc(hwInfo->platform.eProductFamily, (void *)(&hwInfo->featureTable)); -} - -void PerformanceCountersLinux::enableImpl() { - if (mdLibHandle && perfmonLoadConfigFunc) { - PerformanceCounters::enableImpl(); - } -} - -bool PerformanceCountersLinux::verifyPmRegsCfg(InstrPmRegsCfg *pCfg, uint32_t *pLastPmRegsCfgHandle, bool *pLastPmRegsCfgPending) { - if (perfmonLoadConfigFunc == nullptr) { + // Create oa configuration. + if (!metricsLibrary->oaConfigurationCreate( + context, + oaConfiguration)) { + DEBUG_BREAK_IF(true); return false; } - if (PerformanceCounters::verifyPmRegsCfg(pCfg, pLastPmRegsCfgHandle, pLastPmRegsCfgPending)) { - return getPerfmonConfig(pCfg); - } - return false; -} -bool PerformanceCountersLinux::getPerfmonConfig(InstrPmRegsCfg *pCfg) { - unsigned int oaCfgHandle = pCfg->OaCounters.Handle; - unsigned int gpCfgHandle = pCfg->GpCounters.Handle; - int fd = osInterface->get()->getDrm()->getFileDescriptor(); - if (perfmonLoadConfigFunc(fd, nullptr, &oaCfgHandle, &gpCfgHandle) != 0) { - return false; - } - if (pCfg->OaCounters.Handle != 0 && oaCfgHandle != pCfg->OaCounters.Handle) { - return false; - } - if (pCfg->GpCounters.Handle != 0 && gpCfgHandle != pCfg->GpCounters.Handle) { + + // Enable oa configuration. + if (!metricsLibrary->oaConfigurationActivate( + oaConfiguration)) { + DEBUG_BREAK_IF(true); return false; } + return true; } + +////////////////////////////////////////////////////// +// PerformanceCountersLinux::releaseCountersConfiguration +////////////////////////////////////////////////////// +void PerformanceCountersLinux::releaseCountersConfiguration() { + // Oa configuration. + if (oaConfiguration.IsValid()) { + metricsLibrary->oaConfigurationDeactivate(oaConfiguration); + metricsLibrary->oaConfigurationDelete(oaConfiguration); + oaConfiguration.data = nullptr; + } +} } // namespace NEO diff --git a/runtime/os_interface/linux/performance_counters_linux.h b/runtime/os_interface/linux/performance_counters_linux.h index 42b50da882..b99e650c1d 100644 --- a/runtime/os_interface/linux/performance_counters_linux.h +++ b/runtime/os_interface/linux/performance_counters_linux.h @@ -8,35 +8,17 @@ #pragma once #include "runtime/os_interface/performance_counters.h" -#include "os_interface.h" - -#include - -typedef struct _drm_intel_context drm_intel_context; - namespace NEO { class PerformanceCountersLinux : virtual public PerformanceCounters { public: - PerformanceCountersLinux(OSTime *osTime); - ~PerformanceCountersLinux() override; - void initialize(const HardwareInfo *hwInfo) override; - void enableImpl() override; + PerformanceCountersLinux() = default; + ~PerformanceCountersLinux() override = default; - protected: - virtual bool getPerfmonConfig(InstrPmRegsCfg *pCfg); - bool verifyPmRegsCfg(InstrPmRegsCfg *pCfg, uint32_t *pLastPmRegsCfgHandle, bool *pLastPmRegsCfgPending) override; - - typedef int (*perfmonLoadConfig_t)(int fd, drm_intel_context *ctx, uint32_t *oaCfgId, uint32_t *gpCfgId); - typedef void *(*dlopenFunc_t)(const char *, int); - typedef void *(*dlsymFunc_t)(void *, const char *); - - void *mdLibHandle; - - perfmonLoadConfig_t perfmonLoadConfigFunc; - dlopenFunc_t dlopenFunc = dlopen; - dlsymFunc_t dlsymFunc = dlsym; - decltype(&dlclose) dlcloseFunc = dlclose; - decltype(&instrSetPlatformInfo) setPlatformInfoFunc = instrSetPlatformInfo; + ///////////////////////////////////////////////////// + // Gpu oa/mmio configuration. + ///////////////////////////////////////////////////// + bool enableCountersConfiguration() override; + void releaseCountersConfiguration() override; }; } // namespace NEO diff --git a/runtime/os_interface/metrics_library.cpp b/runtime/os_interface/metrics_library.cpp new file mode 100644 index 0000000000..480c1bca82 --- /dev/null +++ b/runtime/os_interface/metrics_library.cpp @@ -0,0 +1,188 @@ +/* + * Copyright (C) 2017-2019 Intel Corporation + * + * SPDX-License-Identifier: MIT + * + */ + +#include "runtime/os_interface/metrics_library.h" + +#include "runtime/helpers/hw_helper.h" +#include "runtime/os_interface/os_inc_base.h" + +namespace NEO { +/////////////////////////////////////////////////////// +// FUNCTION: MetricsLibrary::MetricsLibrary +/////////////////////////////////////////////////////// +MetricsLibrary::MetricsLibrary() { + api = std::make_unique(); + osLibrary.reset(OsLibrary::load(Os::metricsLibraryDllName)); +} + +////////////////////////////////////////////////////// +// FUNCTION: MetricsLibrary::open +////////////////////////////////////////////////////// +bool MetricsLibrary::open() { + + UNRECOVERABLE_IF(osLibrary.get() == nullptr); + + if (osLibrary->isLoaded()) { + api->contextCreate = reinterpret_cast(osLibrary->getProcAddress(METRICS_LIBRARY_CONTEXT_CREATE_1_0)); + api->contextDelete = reinterpret_cast(osLibrary->getProcAddress(METRICS_LIBRARY_CONTEXT_DELETE_1_0)); + } else { + api->contextCreate = nullptr; + api->contextDelete = nullptr; + } + + if (!api->contextCreate) { + return false; + } + + if (!api->contextDelete) { + return false; + } + + return true; +} + +////////////////////////////////////////////////////// +// MetricsLibrary::createContext +////////////////////////////////////////////////////// +bool MetricsLibrary::contextCreate( + const ClientType_1_0 &clientType, + ClientData_1_0 &clientData, + ContextCreateData_1_0 &createData, + ContextHandle_1_0 &handle) { + + createData.Api = &api->functions; + createData.ClientCallbacks = &api->callbacks; + createData.ClientData = &clientData; + + return api->contextCreate( + clientType, + &createData, + &handle) == StatusCode::Success; +} + +////////////////////////////////////////////////////// +// MetricsLibrary::contextDelete +////////////////////////////////////////////////////// +bool MetricsLibrary::contextDelete( + const ContextHandle_1_0 &handle) { + return api->contextDelete(handle) == StatusCode::Success; +} + +////////////////////////////////////////////////////// +// MetricsLibrary::hwCountersCreate +////////////////////////////////////////////////////// +bool MetricsLibrary::hwCountersCreate( + const ContextHandle_1_0 &context, + const uint32_t slots, + const ConfigurationHandle_1_0 user, + QueryHandle_1_0 &query) { + QueryCreateData_1_0 data = {}; + data.HandleContext = context; + data.Type = ObjectType::QueryHwCounters; + data.Slots = slots; + + return api->functions.QueryCreate( + &data, + &query) == StatusCode::Success; +} + +////////////////////////////////////////////////////// +// MetricsLibrary::hwCountersDelete +////////////////////////////////////////////////////// +bool MetricsLibrary::hwCountersDelete( + const QueryHandle_1_0 &query) { + return api->functions.QueryDelete(query) == StatusCode::Success; +} + +////////////////////////////////////////////////////// +// MetricsLibrary::hwCountersGetReport +////////////////////////////////////////////////////// +bool MetricsLibrary::hwCountersGetReport( + const QueryHandle_1_0 &handle, + const uint32_t slot, + const uint32_t slotsCount, + const uint32_t dataSize, + void *data) { + GetReportData_1_0 report = {}; + report.Type = ObjectType::QueryHwCounters; + report.Query.Handle = handle; + report.Query.Slot = slot; + report.Query.SlotsCount = slotsCount; + report.Query.Data = data; + report.Query.DataSize = dataSize; + + return api->functions.GetData(&report) == StatusCode::Success; +} + +////////////////////////////////////////////////////// +// MetricsLibrary::hwCountersGetApiReportSize +////////////////////////////////////////////////////// +uint32_t MetricsLibrary::hwCountersGetApiReportSize() { + ValueType type = ValueType::Uint32; + TypedValue_1_0 value = {}; + + return api->functions.GetParameter(ParameterType::QueryHwCountersReportApiSize, &type, &value) == StatusCode::Success + ? value.ValueUInt32 + : 0; +} + +////////////////////////////////////////////////////// +// MetricsLibrary::hwCountersGetGpuReportSize +////////////////////////////////////////////////////// +uint32_t MetricsLibrary::hwCountersGetGpuReportSize() { + ValueType type = ValueType::Uint32; + TypedValue_1_0 value = {}; + + return api->functions.GetParameter(ParameterType::QueryHwCountersReportGpuSize, &type, &value) == StatusCode::Success + ? value.ValueUInt32 + : 0; +} + +////////////////////////////////////////////////////// +// MetricsLibrary::commandBufferGet +////////////////////////////////////////////////////// +bool MetricsLibrary::commandBufferGet( + CommandBufferData_1_0 &data) { + return api->functions.CommandBufferGet( + &data) == StatusCode::Success; +} + +////////////////////////////////////////////////////// +// MetricsLibrary::commandBufferGetSize +////////////////////////////////////////////////////// +bool MetricsLibrary::commandBufferGetSize( + const CommandBufferData_1_0 &commandBufferData, + CommandBufferSize_1_0 &commandBufferSize) { + return api->functions.CommandBufferGetSize( + &commandBufferData, + &commandBufferSize) == StatusCode::Success; +} + +////////////////////////////////////////////////////// +// MetricsLibrary::oaConfigurationCreate +////////////////////////////////////////////////////// +bool MetricsLibrary::oaConfigurationCreate( + const ContextHandle_1_0 &context, + ConfigurationHandle_1_0 &handle) { + ConfigurationCreateData_1_0 data = {}; + data.HandleContext = context; + data.Type = ObjectType::ConfigurationHwCountersOa; + + return api->functions.ConfigurationCreate( + &data, + &handle) == StatusCode::Success; +} + +////////////////////////////////////////////////////// +// MetricsLibrary::oaConfigurationDelete +////////////////////////////////////////////////////// +bool MetricsLibrary::oaConfigurationDelete( + const ConfigurationHandle_1_0 &handle) { + + return api->functions.ConfigurationDelete(handle) == StatusCode::Success; +} +} // namespace NEO \ No newline at end of file diff --git a/runtime/os_interface/metrics_library.h b/runtime/os_interface/metrics_library.h new file mode 100644 index 0000000000..8cf5766631 --- /dev/null +++ b/runtime/os_interface/metrics_library.h @@ -0,0 +1,89 @@ +/* + * Copyright (C) 2017-2019 Intel Corporation + * + * SPDX-License-Identifier: MIT + * + */ + +#pragma once + +#include "runtime/os_interface/os_library.h" + +#include "instrumentation.h" + +#include + +namespace NEO { + +using MetricsLibraryApi::ClientApi; +using MetricsLibraryApi::ClientCallbacks_1_0; +using MetricsLibraryApi::ClientData_1_0; +using MetricsLibraryApi::ClientGen; +using MetricsLibraryApi::ClientType_1_0; +using MetricsLibraryApi::CommandBufferData_1_0; +using MetricsLibraryApi::CommandBufferSize_1_0; +using MetricsLibraryApi::ConfigurationActivateData_1_0; +using MetricsLibraryApi::ConfigurationCreateData_1_0; +using MetricsLibraryApi::ConfigurationHandle_1_0; +using MetricsLibraryApi::ContextCreateData_1_0; +using MetricsLibraryApi::ContextCreateFunction_1_0; +using MetricsLibraryApi::ContextDeleteFunction_1_0; +using MetricsLibraryApi::ContextHandle_1_0; +using MetricsLibraryApi::GetReportData_1_0; +using MetricsLibraryApi::GpuConfigurationActivationType; +using MetricsLibraryApi::GpuMemory_1_0; +using MetricsLibraryApi::Interface_1_0; +using MetricsLibraryApi::ObjectType; +using MetricsLibraryApi::ParameterType; +using MetricsLibraryApi::QueryCreateData_1_0; +using MetricsLibraryApi::QueryHandle_1_0; +using MetricsLibraryApi::StatusCode; +using MetricsLibraryApi::TypedValue_1_0; +using MetricsLibraryApi::ValueType; + +class MetricsLibraryInterface { + public: + ContextCreateFunction_1_0 contextCreate = nullptr; + ContextDeleteFunction_1_0 contextDelete = nullptr; + Interface_1_0 functions = {}; + ClientCallbacks_1_0 callbacks = {}; +}; + +class MetricsLibrary { + public: + MetricsLibrary(); + MOCKABLE_VIRTUAL ~MetricsLibrary(){}; + + // Library open function. + MOCKABLE_VIRTUAL bool open(); + + // Context create / destroy functions. + MOCKABLE_VIRTUAL bool contextCreate(const ClientType_1_0 &client, ClientData_1_0 &clientData, ContextCreateData_1_0 &createData, ContextHandle_1_0 &handle); + MOCKABLE_VIRTUAL bool contextDelete(const ContextHandle_1_0 &handle); + + // HwCounters functions. + MOCKABLE_VIRTUAL bool hwCountersCreate(const ContextHandle_1_0 &context, const uint32_t slots, const ConfigurationHandle_1_0 mmio, QueryHandle_1_0 &handle); + MOCKABLE_VIRTUAL bool hwCountersDelete(const QueryHandle_1_0 &handle); + MOCKABLE_VIRTUAL bool hwCountersGetReport(const QueryHandle_1_0 &handle, const uint32_t slot, const uint32_t slotsCount, const uint32_t dataSize, void *data); + MOCKABLE_VIRTUAL uint32_t hwCountersGetApiReportSize(); + MOCKABLE_VIRTUAL uint32_t hwCountersGetGpuReportSize(); + + // Oa configuration functions. + MOCKABLE_VIRTUAL bool oaConfigurationCreate(const ContextHandle_1_0 &context, ConfigurationHandle_1_0 &handle); + MOCKABLE_VIRTUAL bool oaConfigurationDelete(const ConfigurationHandle_1_0 &handle); + MOCKABLE_VIRTUAL bool oaConfigurationActivate(const ConfigurationHandle_1_0 &handle); + MOCKABLE_VIRTUAL bool oaConfigurationDeactivate(const ConfigurationHandle_1_0 &handle); + + // User mmio configuration functions. + MOCKABLE_VIRTUAL bool userConfigurationCreate(const ContextHandle_1_0 &context, ConfigurationHandle_1_0 &handle); + MOCKABLE_VIRTUAL bool userConfigurationDelete(const ConfigurationHandle_1_0 &handle); + + // Command buffer functions. + MOCKABLE_VIRTUAL bool commandBufferGet(CommandBufferData_1_0 &data); + MOCKABLE_VIRTUAL bool commandBufferGetSize(const CommandBufferData_1_0 &commandBufferData, CommandBufferSize_1_0 &commandBufferSize); + + public: + std::unique_ptr osLibrary; + std::unique_ptr api; +}; +} // namespace NEO \ No newline at end of file diff --git a/runtime/os_interface/os_inc_base.h b/runtime/os_interface/os_inc_base.h index 2c58d8e8be..1cdd0a8d8e 100644 --- a/runtime/os_interface/os_inc_base.h +++ b/runtime/os_interface/os_inc_base.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017-2018 Intel Corporation + * Copyright (C) 2017-2019 Intel Corporation * * SPDX-License-Identifier: MIT * @@ -18,4 +18,7 @@ extern const char *testDllName; extern const char *fileSeparator; // Pci Path extern const char *sysFsPciPath; + +// Os specific Metrics Library name +extern const char *metricsLibraryDllName; }; // namespace Os diff --git a/runtime/os_interface/os_interface.h b/runtime/os_interface/os_interface.h index 701f239297..2f0bb08a13 100644 --- a/runtime/os_interface/os_interface.h +++ b/runtime/os_interface/os_interface.h @@ -21,7 +21,6 @@ class OSInterface { OSInterfaceImpl *get() const { return osInterfaceImpl; }; - unsigned int getHwContextId() const; static bool osEnabled64kbPages; static bool osEnableLocalMemory; static bool are64kbPagesEnabled(); diff --git a/runtime/os_interface/performance_counters.cpp b/runtime/os_interface/performance_counters.cpp index 9809fef258..2ad972432c 100644 --- a/runtime/os_interface/performance_counters.cpp +++ b/runtime/os_interface/performance_counters.cpp @@ -7,175 +7,240 @@ #include "runtime/os_interface/performance_counters.h" -#include "runtime/helpers/debug_helpers.h" -#include "runtime/os_interface/os_interface.h" -#include "runtime/os_interface/os_time.h" +#include "runtime/utilities/tag_allocator.h" -#include "CL/cl.h" +using namespace MetricsLibraryApi; namespace NEO { -decltype(&instrGetPerfCountersQueryData) getPerfCountersQueryDataFactory[IGFX_MAX_CORE] = { - nullptr, -}; -size_t perfCountersQuerySize[IGFX_MAX_CORE] = { - 0, -}; -PerformanceCounters::PerformanceCounters(OSTime *osTime) { - this->osTime = osTime; - DEBUG_BREAK_IF(osTime == nullptr); - gfxFamily = IGFX_UNKNOWN_CORE; - cbData = { - 0, - }; - this->osInterface = osTime->getOSInterface(); - hwMetricsEnabled = false; - useMIRPC = false; - pAutoSamplingInterface = nullptr; - cpuRawTimestamp = 0; - refCounter = 0; - available = false; - reportId = 0; +////////////////////////////////////////////////////// +// PerformanceCounters constructor. +////////////////////////////////////////////////////// +PerformanceCounters::PerformanceCounters() { + metricsLibrary = std::make_unique(); + UNRECOVERABLE_IF(metricsLibrary == nullptr); } +////////////////////////////////////////////////////// +// PerformanceCounters::getReferenceNumber +////////////////////////////////////////////////////// +uint32_t PerformanceCounters::getReferenceNumber() { + std::lock_guard lockMutex(mutex); + return referenceCounter; +} + +////////////////////////////////////////////////////// +// PerformanceCounters::isAvailable +////////////////////////////////////////////////////// +bool PerformanceCounters::isAvailable() { + return available; +} + +////////////////////////////////////////////////////// +// PerformanceCounters::enable +////////////////////////////////////////////////////// void PerformanceCounters::enable() { - mutex.lock(); - std::lock_guard lg(mutex, std::adopt_lock); - if (refCounter == 0) { - enableImpl(); + std::lock_guard lockMutex(mutex); + + if (referenceCounter == 0) { + available = openMetricsLibrary(); } - refCounter++; + + referenceCounter++; } + +////////////////////////////////////////////////////// +// PerformanceCounters::shutdown +////////////////////////////////////////////////////// void PerformanceCounters::shutdown() { - mutex.lock(); - std::lock_guard lg(mutex, std::adopt_lock); - if (refCounter >= 1) { - if (refCounter == 1) { - shutdownImpl(); + std::lock_guard lockMutex(mutex); + + if (referenceCounter >= 1) { + if (referenceCounter == 1) { + available = false; + closeMetricsLibrary(); } - refCounter--; + referenceCounter--; } } -void PerformanceCounters::initialize(const HardwareInfo *hwInfo) { - useMIRPC = !(hwInfo->workaroundTable.waDoNotUseMIReportPerfCount); - gfxFamily = hwInfo->platform.eRenderCoreFamily; +////////////////////////////////////////////////////// +// PerformanceCounters::getMetricsLibraryInterface +////////////////////////////////////////////////////// +MetricsLibrary *PerformanceCounters::getMetricsLibraryInterface() { + return metricsLibrary.get(); +} - if (getPerfCountersQueryDataFactory[gfxFamily] != nullptr) { - getPerfCountersQueryDataFunc = getPerfCountersQueryDataFactory[gfxFamily]; - } else { - perfCountersQuerySize[gfxFamily] = sizeof(GTDI_QUERY); +////////////////////////////////////////////////////// +// PerformanceCounters::setMetricsLibraryInterface +////////////////////////////////////////////////////// +void PerformanceCounters::setMetricsLibraryInterface(std::unique_ptr newMetricsLibrary) { + metricsLibrary = std::move(newMetricsLibrary); +} + +////////////////////////////////////////////////////// +// PerformanceCounters::getMetricsLibraryContext +////////////////////////////////////////////////////// +ContextHandle_1_0 PerformanceCounters::getMetricsLibraryContext() { + return context; +} + +////////////////////////////////////////////////////// +// PerformanceCounters::openMetricsLibrary +////////////////////////////////////////////////////// +bool PerformanceCounters::openMetricsLibrary() { + + // Open metrics library. + bool result = metricsLibrary->open(); + DEBUG_BREAK_IF(!result); + + // Create metrics library context. + if (result) { + result = metricsLibrary->contextCreate( + clientType, + clientData, + contextData, + context); + + // Validate gpu report size. + DEBUG_BREAK_IF(!metricsLibrary->hwCountersGetGpuReportSize()); + } + + // Error handling. + if (!result) { + closeMetricsLibrary(); + } + + return result; +} + +////////////////////////////////////////////////////// +// PerformanceCounters::closeMetricsLibrary +////////////////////////////////////////////////////// +void PerformanceCounters::closeMetricsLibrary() { + // Destroy oa/user mmio configuration. + releaseCountersConfiguration(); + + // Destroy hw counters query. + if (query.IsValid()) { + metricsLibrary->hwCountersDelete(query); + } + + // Destroy metrics library context. + if (context.IsValid()) { + metricsLibrary->contextDelete(context); } } -void PerformanceCounters::enableImpl() { - hwMetricsEnabled = hwMetricsEnableFunc(cbData, true); - if (!pAutoSamplingInterface && hwMetricsEnabled) { - autoSamplingStartFunc(cbData, &pAutoSamplingInterface); - if (pAutoSamplingInterface) { - available = true; +////////////////////////////////////////////////////// +// PerformanceCounters::getQueryHandle +////////////////////////////////////////////////////// +QueryHandle_1_0 PerformanceCounters::getQueryHandle() { + if (!query.IsValid()) { + metricsLibrary->hwCountersCreate( + context, + 1, + userConfiguration, + query); + } + + DEBUG_BREAK_IF(!query.IsValid()); + return query; +} + +////////////////////////////////////////////////////// +// PerformanceCounters::getGpuCommandsSize +////////////////////////////////////////////////////// +uint32_t PerformanceCounters::getGpuCommandsSize( + const bool begin) { + CommandBufferData_1_0 bufferData = {}; + CommandBufferSize_1_0 bufferSize = {}; + + if (begin) { + // Load currently activated (through metrics discovery) oa/user mmio configuration and use it. + // It will allow to change counters configuration between subsequent clEnqueueNDCommandRange calls. + if (!enableCountersConfiguration()) { + return 0; } } + + bufferData.HandleContext = context; + bufferData.Type = GpuCommandBufferType::Render; + bufferData.CommandsType = ObjectType::QueryHwCounters; + + bufferData.QueryHwCounters.Begin = begin; + bufferData.QueryHwCounters.Handle = getQueryHandle(); + bufferData.QueryHwCounters.HandleUserConfiguration = userConfiguration; + + return metricsLibrary->commandBufferGetSize(bufferData, bufferSize) + ? bufferSize.GpuMemorySize + : 0; } -void PerformanceCounters::shutdownImpl() { - if (hwMetricsEnabled) { - hwMetricsEnableFunc(cbData, false); - hwMetricsEnabled = false; - } - if (pAutoSamplingInterface) { - autoSamplingStopFunc(&pAutoSamplingInterface); - pAutoSamplingInterface = nullptr; - available = false; - } + +////////////////////////////////////////////////////// +// PerformanceCounters::getGpuCommands +////////////////////////////////////////////////////// +bool PerformanceCounters::getGpuCommands( + TagNode &performanceCounters, + const bool begin, + const uint32_t bufferSize, + void *pBuffer) { + // Command Buffer data. + CommandBufferData_1_0 bufferData = {}; + bufferData.HandleContext = context; + bufferData.Type = GpuCommandBufferType::Render; + bufferData.CommandsType = ObjectType::QueryHwCounters; + bufferData.Data = pBuffer; + bufferData.Size = bufferSize; + + // Gpu memory allocation for query hw counters. + bufferData.Allocation.CpuAddress = reinterpret_cast(performanceCounters.tagForCpuAccess); + bufferData.Allocation.GpuAddress = performanceCounters.getGpuAddress(); + + // Query hw counters specific data. + bufferData.QueryHwCounters.Begin = begin; + bufferData.QueryHwCounters.Handle = getQueryHandle(); + bufferData.QueryHwCounters.HandleUserConfiguration = userConfiguration; + + return metricsLibrary->commandBufferGet(bufferData); } -void PerformanceCounters::setCpuTimestamp() { - cpuRawTimestamp = osTime->getCpuRawTimestamp(); + +////////////////////////////////////////////////////// +// PerformanceCounters::getApiReportSize +////////////////////////////////////////////////////// +uint32_t PerformanceCounters::getApiReportSize() { + return metricsLibrary->hwCountersGetApiReportSize(); } -InstrPmRegsCfg *PerformanceCounters::getPmRegsCfg(uint32_t configuration) { - if (!hwMetricsEnabled) { - return nullptr; + +////////////////////////////////////////////////////// +// PerformanceCounters::getGpuReportSize +////////////////////////////////////////////////////// +uint32_t PerformanceCounters::getGpuReportSize() { + return metricsLibrary->hwCountersGetGpuReportSize(); +} + +////////////////////////////////////////////////////// +// PerformanceCounters::getApiReport +////////////////////////////////////////////////////// +bool PerformanceCounters::getApiReport(const size_t inputParamSize, void *pInputParam, size_t *pOutputParamSize, bool isEventComplete) { + const uint32_t outputSize = metricsLibrary->hwCountersGetApiReportSize(); + + if (pOutputParamSize) { + *pOutputParamSize = outputSize; } - switch (configuration) { - case GTDI_CONFIGURATION_SET_DYNAMIC: - case GTDI_CONFIGURATION_SET_1: - case GTDI_CONFIGURATION_SET_2: - case GTDI_CONFIGURATION_SET_3: - break; - - default: - return nullptr; - } - - InstrPmRegsCfg *pPmRegsCfg = new InstrPmRegsCfg(); - pPmRegsCfg->OaCounters.Handle = INSTR_PM_REGS_CFG_INVALID; - - mutex.lock(); - std::lock_guard lg(mutex, std::adopt_lock); - - if (getPmRegsCfgFunc(cbData, configuration, pPmRegsCfg, nullptr)) { - return pPmRegsCfg; - } - delete pPmRegsCfg; - return nullptr; -} -bool PerformanceCounters::verifyPmRegsCfg(InstrPmRegsCfg *pCfg, uint32_t *pLastPmRegsCfgHandle, bool *pLastPmRegsCfgPending) { - if (pCfg == nullptr || pLastPmRegsCfgHandle == nullptr || pLastPmRegsCfgPending == nullptr) { - return false; - } - if (checkPmRegsCfgFunc(pCfg, pLastPmRegsCfgHandle, pAutoSamplingInterface)) { - if (loadPmRegsCfgFunc(cbData, pCfg, 1)) { - return true; - } - } - return false; -} -bool PerformanceCounters::sendPmRegsCfgCommands(InstrPmRegsCfg *pCfg, uint32_t *pLastPmRegsCfgHandle, bool *pLastPmRegsCfgPending) { - if (verifyPmRegsCfg(pCfg, pLastPmRegsCfgHandle, pLastPmRegsCfgPending)) { - *pLastPmRegsCfgPending = true; + if (pInputParam == nullptr && inputParamSize == 0 && pOutputParamSize) { return true; } - return false; -} -bool PerformanceCounters::processEventReport(size_t inputParamSize, void *inputParam, size_t *outputParamSize, HwPerfCounter *pPrivateData, InstrPmRegsCfg *countersConfiguration, bool isEventComplete) { - size_t outputSize = perfCountersQuerySize[gfxFamily]; - if (outputParamSize) { - *outputParamSize = outputSize; - } - if (inputParam == nullptr && inputParamSize == 0 && outputParamSize) { - return true; - } - if (inputParam == nullptr || isEventComplete == false) { + + if (pInputParam == nullptr || isEventComplete == false) { return false; } + if (inputParamSize < outputSize) { return false; } - GTDI_QUERY *pClientData = static_cast(inputParam); - getPerfCountersQueryDataFunc(cbData, pClientData, &pPrivateData->HWPerfCounters, - cpuRawTimestamp, pAutoSamplingInterface, countersConfiguration, useMIRPC, true, nullptr); - return true; -} -int PerformanceCounters::sendPerfConfiguration(uint32_t count, uint32_t *pOffsets, uint32_t *pValues) { - bool ret = false; - - if (count == 0 || pOffsets == NULL || pValues == NULL) { - return CL_INVALID_VALUE; - } - - mutex.lock(); - std::lock_guard lg(mutex, std::adopt_lock); - if (pOffsets[0] != INSTR_READ_REGS_CFG_TAG) { - ret = setPmRegsCfgFunc(cbData, count, pOffsets, pValues); - } else if (count > 1) { - ret = sendReadRegsCfgFunc(cbData, count - 1, pOffsets + 1, pValues + 1); - } - - return ret ? CL_SUCCESS : CL_PROFILING_INFO_NOT_AVAILABLE; -} - -uint32_t PerformanceCounters::getCurrentReportId() { - return (osInterface->getHwContextId() << 12) | getReportId(); + return metricsLibrary->hwCountersGetReport(query, 0, 1, outputSize, pInputParam); } } // namespace NEO diff --git a/runtime/os_interface/performance_counters.h b/runtime/os_interface/performance_counters.h index 35e1620a0b..541ad5ae58 100644 --- a/runtime/os_interface/performance_counters.h +++ b/runtime/os_interface/performance_counters.h @@ -7,71 +7,105 @@ #pragma once #include "runtime/event/perf_counter.h" -#include "runtime/helpers/hw_info.h" +#include "runtime/os_interface/metrics_library.h" -#include "CL/cl.h" - -#include #include namespace NEO { -struct HardwareInfo; -class OSInterface; -class OSTime; +////////////////////////////////////////////////////// +// Forward declaration. +////////////////////////////////////////////////////// +template +struct TagNode; + +////////////////////////////////////////////////////// +// Performance counters implementation. +////////////////////////////////////////////////////// class PerformanceCounters { public: - static std::unique_ptr create(OSTime *osTime); + ////////////////////////////////////////////////////// + // Constructor/destructor. + ////////////////////////////////////////////////////// + PerformanceCounters(); virtual ~PerformanceCounters() = default; + + ////////////////////////////////////////////////////// + // Performance counters creation. + ////////////////////////////////////////////////////// + static std::unique_ptr create(class Device *device); void enable(); void shutdown(); - virtual void initialize(const HardwareInfo *hwInfo); - InstrPmRegsCfg *getPmRegsCfg(uint32_t configuration); - bool sendPmRegsCfgCommands(InstrPmRegsCfg *pCfg, uint32_t *pLastPmRegsCfgHandle, bool *pLastPmRegsCfgPending); - void setCpuTimestamp(); - bool processEventReport(size_t pClientDataSize, void *pClientData, size_t *outputSize, HwPerfCounter *pPrivateData, InstrPmRegsCfg *countersConfiguration, bool isEventComplete); - int sendPerfConfiguration(uint32_t count, uint32_t *pOffsets, uint32_t *pValues); - uint32_t getCurrentReportId(); + bool isAvailable(); + uint32_t getReferenceNumber(); - uint32_t getPerfCountersReferenceNumber() { - mutex.lock(); - std::lock_guard lg(mutex, std::adopt_lock); + ///////////////////////////////////////////////////// + // Gpu oa/mmio configuration. + ///////////////////////////////////////////////////// + virtual bool enableCountersConfiguration() = 0; + virtual void releaseCountersConfiguration() = 0; - return refCounter; - } + ////////////////////////////////////////////////////// + // Gpu commands. + ////////////////////////////////////////////////////// + uint32_t getGpuCommandsSize(const bool begin); + bool getGpuCommands(TagNode &performanceCounters, const bool begin, const uint32_t bufferSize, void *pBuffer); - bool isAvailable() { - return available; - } + ///////////////////////////////////////////////////// + // Gpu/Api reports. + ///////////////////////////////////////////////////// + uint32_t getApiReportSize(); + uint32_t getGpuReportSize(); + bool getApiReport(const size_t inputParamSize, void *pClientData, size_t *pOutputSize, bool isEventComplete); + + ///////////////////////////////////////////////////// + // Metrics Library interface. + ///////////////////////////////////////////////////// + MetricsLibrary *getMetricsLibraryInterface(); + void setMetricsLibraryInterface(std::unique_ptr newMetricsLibrary); + bool openMetricsLibrary(); + void closeMetricsLibrary(); + + ///////////////////////////////////////////////////// + // Metrics Library context/query handles. + ///////////////////////////////////////////////////// + ContextHandle_1_0 getMetricsLibraryContext(); + QueryHandle_1_0 getQueryHandle(); protected: - PerformanceCounters(OSTime *osTime); - virtual bool verifyPmRegsCfg(InstrPmRegsCfg *pCfg, uint32_t *pLastPmRegsCfgHandle, bool *pLastPmRegsCfgPending); - virtual void enableImpl(); - void shutdownImpl(); - MOCKABLE_VIRTUAL uint32_t getReportId() { - return ++reportId & 0xFFF; - } - GFXCORE_FAMILY gfxFamily; - InstrEscCbData cbData; - OSInterface *osInterface; - OSTime *osTime; - bool hwMetricsEnabled; - bool useMIRPC; - void *pAutoSamplingInterface; - uint64_t cpuRawTimestamp; + ///////////////////////////////////////////////////// + // Common members. + ///////////////////////////////////////////////////// std::mutex mutex; - uint32_t refCounter; - bool available; - uint32_t reportId; - decltype(&instrAutoSamplingStart) autoSamplingStartFunc = instrAutoSamplingStart; - decltype(&instrAutoSamplingStop) autoSamplingStopFunc = instrAutoSamplingStop; - decltype(&instrCheckPmRegsCfg) checkPmRegsCfgFunc = instrCheckPmRegsCfg; - decltype(&instrGetPerfCountersQueryData) getPerfCountersQueryDataFunc = instrGetPerfCountersQueryData; - decltype(&instrEscGetPmRegsCfg) getPmRegsCfgFunc = instrEscGetPmRegsCfg; - decltype(&instrEscHwMetricsEnable) hwMetricsEnableFunc = instrEscHwMetricsEnable; - decltype(&instrEscLoadPmRegsCfg) loadPmRegsCfgFunc = instrEscLoadPmRegsCfg; - decltype(&instrEscSetPmRegsCfg) setPmRegsCfgFunc = instrEscSetPmRegsCfg; - decltype(&instrEscSendReadRegsCfg) sendReadRegsCfgFunc = instrEscSendReadRegsCfg; + uint32_t referenceCounter = 0; + bool available = false; + + ///////////////////////////////////////////////////// + // Metrics Library interface. + ///////////////////////////////////////////////////// + std::unique_ptr metricsLibrary = {}; + + ///////////////////////////////////////////////////// + // Metrics Library client data. + ///////////////////////////////////////////////////// + ClientData_1_0 clientData = {}; + ClientType_1_0 clientType = {ClientApi::OpenCL, ClientGen::Unknown}; + + ///////////////////////////////////////////////////// + // Metrics Library context. + ///////////////////////////////////////////////////// + ContextCreateData_1_0 contextData = {}; + ContextHandle_1_0 context = {}; + + ///////////////////////////////////////////////////// + // Metrics Library oa/mmio counters configuration. + ///////////////////////////////////////////////////// + ConfigurationHandle_1_0 oaConfiguration = {}; + ConfigurationHandle_1_0 userConfiguration = {}; + + ///////////////////////////////////////////////////// + // Metrics Library query object. + ///////////////////////////////////////////////////// + QueryHandle_1_0 query = {}; }; } // namespace NEO diff --git a/runtime/os_interface/windows/CMakeLists.txt b/runtime/os_interface/windows/CMakeLists.txt index 0b46a934c0..98ba0ff7d4 100644 --- a/runtime/os_interface/windows/CMakeLists.txt +++ b/runtime/os_interface/windows/CMakeLists.txt @@ -36,6 +36,7 @@ set(RUNTIME_SRCS_OS_INTERFACE_WINDOWS ${CMAKE_CURRENT_SOURCE_DIR}/os_library.cpp ${CMAKE_CURRENT_SOURCE_DIR}/os_library.h ${CMAKE_CURRENT_SOURCE_DIR}/os_memory_win.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/os_metrics_library.cpp ${CMAKE_CURRENT_SOURCE_DIR}/os_socket.h ${CMAKE_CURRENT_SOURCE_DIR}/os_thread_win.cpp ${CMAKE_CURRENT_SOURCE_DIR}/os_thread_win.h diff --git a/runtime/os_interface/windows/os_interface.cpp b/runtime/os_interface/windows/os_interface.cpp index b529c4f1b6..111bdd9c96 100644 --- a/runtime/os_interface/windows/os_interface.cpp +++ b/runtime/os_interface/windows/os_interface.cpp @@ -22,10 +22,6 @@ OSInterface::~OSInterface() { delete osInterfaceImpl; } -uint32_t OSInterface::getHwContextId() const { - return osInterfaceImpl->getHwContextId(); -} - uint32_t OSInterface::getDeviceHandle() const { return static_cast(osInterfaceImpl->getDeviceHandle()); } diff --git a/runtime/os_interface/windows/os_metrics_library.cpp b/runtime/os_interface/windows/os_metrics_library.cpp new file mode 100644 index 0000000000..c2b831cbe9 --- /dev/null +++ b/runtime/os_interface/windows/os_metrics_library.cpp @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2017-2019 Intel Corporation + * + * SPDX-License-Identifier: MIT + * + */ + +#include "runtime/os_interface/metrics_library.h" + +namespace NEO { +////////////////////////////////////////////////////// +// FUNCTION: MetricsLibrary::oaConfigurationActivate +////////////////////////////////////////////////////// +bool MetricsLibrary::oaConfigurationActivate( + const ConfigurationHandle_1_0 &handle) { + ConfigurationActivateData_1_0 data = {}; + data.Type = GpuConfigurationActivationType::EscapeCode; + + return api->functions.ConfigurationActivate( + handle, + &data) == StatusCode::Success; +} + +////////////////////////////////////////////////////// +// FUNCTION: MetricsLibrary::oaConfigurationDeactivate +////////////////////////////////////////////////////// +bool MetricsLibrary::oaConfigurationDeactivate( + const ConfigurationHandle_1_0 &handle) { + return api->functions.ConfigurationDeactivate( + handle) == StatusCode::Success; +} + +////////////////////////////////////////////////////// +// FUNCTION: MetricsLibrary::userConfigurationCreate +////////////////////////////////////////////////////// +bool MetricsLibrary::userConfigurationCreate( + const ContextHandle_1_0 &context, + ConfigurationHandle_1_0 &handle) { + ConfigurationCreateData_1_0 data = {}; + data.HandleContext = context; + data.Type = ObjectType::ConfigurationHwCountersUser; + + return api->functions.ConfigurationCreate( + &data, + &handle) == StatusCode::Success; +} + +////////////////////////////////////////////////////// +// FUNCTION: MetricsLibrary::userConfigurationDelete +////////////////////////////////////////////////////// +bool MetricsLibrary::userConfigurationDelete( + const ConfigurationHandle_1_0 &handle) { + return api->functions.ConfigurationDelete(handle) == StatusCode::Success; +} +} // namespace NEO \ No newline at end of file diff --git a/runtime/os_interface/windows/performance_counters_win.cpp b/runtime/os_interface/windows/performance_counters_win.cpp index f8382f3327..6092b99bb5 100644 --- a/runtime/os_interface/windows/performance_counters_win.cpp +++ b/runtime/os_interface/windows/performance_counters_win.cpp @@ -7,31 +7,82 @@ #include "performance_counters_win.h" +#include "runtime/device/device.h" +#include "runtime/helpers/hw_helper.h" #include "runtime/os_interface/windows/os_interface.h" -#include "runtime/os_interface/windows/windows_wrapper.h" +#include "runtime/os_interface/windows/os_time_win.h" namespace NEO { -std::unique_ptr PerformanceCounters::create(OSTime *osTime) { - return std::unique_ptr(new PerformanceCountersWin(osTime)); -} -PerformanceCountersWin::PerformanceCountersWin(OSTime *osTime) : PerformanceCounters(osTime) { - cbData.hAdapter = (void *)(UINT_PTR)osInterface->get()->getAdapterHandle(); - cbData.hDevice = (void *)(UINT_PTR)osInterface->get()->getDeviceHandle(); - cbData.pfnEscapeCb = osInterface->get()->getEscapeHandle(); +///////////////////////////////////////////////////// +// PerformanceCounters::create +///////////////////////////////////////////////////// +std::unique_ptr PerformanceCounters::create(Device *device) { + auto counter = std::make_unique(); + auto osInterface = device->getOSTime()->getOSInterface()->get(); + auto gen = device->getHardwareInfo().platform.eRenderCoreFamily; + auto &hwHelper = HwHelper::get(gen); + UNRECOVERABLE_IF(counter == nullptr); + + counter->clientData.Windows.Adapter = reinterpret_cast(static_cast(osInterface->getAdapterHandle())); + counter->clientData.Windows.Device = reinterpret_cast(static_cast(osInterface->getDeviceHandle())); + counter->clientData.Windows.Device = reinterpret_cast(static_cast(osInterface->getDeviceHandle())); + counter->clientData.Windows.Escape = osInterface->getEscapeHandle(); + counter->clientData.Windows.KmdInstrumentationEnabled = device->getHardwareInfo().capabilityTable.instrumentationEnabled; + counter->contextData.ClientData = &counter->clientData; + counter->clientType.Gen = static_cast(hwHelper.getMetricsLibraryGenId()); + + return counter; } -PerformanceCountersWin::~PerformanceCountersWin() { - if (pAutoSamplingInterface) { - autoSamplingStopFunc(&pAutoSamplingInterface); - pAutoSamplingInterface = nullptr; - available = false; +////////////////////////////////////////////////////// +// PerformanceCountersWin::enableCountersConfiguration +////////////////////////////////////////////////////// +bool PerformanceCountersWin::enableCountersConfiguration() { + // Release previous counters configuration so the user + // can change configuration between kernels. + releaseCountersConfiguration(); + + // Create mmio user configuration. + if (!metricsLibrary->userConfigurationCreate( + context, + userConfiguration)) { + DEBUG_BREAK_IF(true); + return false; + } + + // Create oa configuration. + if (!metricsLibrary->oaConfigurationCreate( + context, + oaConfiguration)) { + DEBUG_BREAK_IF(true); + return false; + } + + // Enable oa configuration. + if (!metricsLibrary->oaConfigurationActivate( + oaConfiguration)) { + DEBUG_BREAK_IF(true); + return false; + } + + return true; +} + +////////////////////////////////////////////////////// +// PerformanceCountersWin::releaseCountersConfiguration +////////////////////////////////////////////////////// +void PerformanceCountersWin::releaseCountersConfiguration() { + // Mmio user configuration. + if (userConfiguration.IsValid()) { + metricsLibrary->userConfigurationDelete(userConfiguration); + userConfiguration.data = nullptr; + } + + // Oa configuration. + if (oaConfiguration.IsValid()) { + metricsLibrary->oaConfigurationDeactivate(oaConfiguration); + metricsLibrary->oaConfigurationDelete(oaConfiguration); + oaConfiguration.data = nullptr; } } - -void PerformanceCountersWin::initialize(const HardwareInfo *hwInfo) { - PerformanceCounters::initialize(hwInfo); - setAvailableFunc(true); - verifyEnableFunc(cbData); -} - } // namespace NEO diff --git a/runtime/os_interface/windows/performance_counters_win.h b/runtime/os_interface/windows/performance_counters_win.h index e6ee2d92c3..5ef12ccbda 100644 --- a/runtime/os_interface/windows/performance_counters_win.h +++ b/runtime/os_interface/windows/performance_counters_win.h @@ -7,18 +7,18 @@ #pragma once #include "runtime/os_interface/performance_counters.h" -#include "runtime/os_interface/windows/os_interface.h" namespace NEO { class PerformanceCountersWin : virtual public PerformanceCounters { public: - PerformanceCountersWin(OSTime *osTime); - ~PerformanceCountersWin() override; - void initialize(const HardwareInfo *hwInfo) override; + PerformanceCountersWin() = default; + ~PerformanceCountersWin() override = default; - protected: - decltype(&instrSetAvailable) setAvailableFunc = instrSetAvailable; - decltype(&instrEscVerifyEnable) verifyEnableFunc = instrEscVerifyEnable; + ///////////////////////////////////////////////////// + // Gpu oa/mmio configuration. + ///////////////////////////////////////////////////// + bool enableCountersConfiguration() override; + void releaseCountersConfiguration() override; }; } // namespace NEO diff --git a/runtime/utilities/tag_allocator.h b/runtime/utilities/tag_allocator.h index 8d45b08f1e..53f13cb92a 100644 --- a/runtime/utilities/tag_allocator.h +++ b/runtime/utilities/tag_allocator.h @@ -51,9 +51,11 @@ class TagAllocator { public: using NodeType = TagNode; - TagAllocator(MemoryManager *memMngr, size_t tagCount, size_t tagAlignment) : memoryManager(memMngr), - tagCount(tagCount), - tagAlignment(tagAlignment) { + TagAllocator(MemoryManager *memMngr, size_t tagCount, size_t tagAlignment, size_t tagSize = sizeof(TagType)) : memoryManager(memMngr), + tagCount(tagCount), + tagAlignment(tagAlignment) { + + this->tagSize = alignUp(tagSize, tagAlignment); populateFreeTags(); } @@ -109,6 +111,7 @@ class TagAllocator { MemoryManager *memoryManager; size_t tagCount; size_t tagAlignment; + size_t tagSize; std::mutex allocatorMutex; @@ -126,7 +129,6 @@ class TagAllocator { } void populateFreeTags() { - size_t tagSize = alignUp(sizeof(TagType), tagAlignment); size_t allocationSizeRequired = tagCount * tagSize; auto allocationType = TagType::getAllocationType(); diff --git a/unit_tests/api/cl_create_perf_counters_command_queue_tests.inl b/unit_tests/api/cl_create_perf_counters_command_queue_tests.inl index d843cc786f..08e8cedf33 100644 --- a/unit_tests/api/cl_create_perf_counters_command_queue_tests.inl +++ b/unit_tests/api/cl_create_perf_counters_command_queue_tests.inl @@ -42,7 +42,7 @@ namespace ULT { TEST_F(clCreatePerfCountersCommandQueueINTELTests, GivenCorrectParamatersWhenCreatingPerfCountersCmdQThenCmdQIsCreatedAndPerfCountersAreEnabled) { cl_command_queue cmdQ = nullptr; cl_queue_properties properties = CL_QUEUE_PROFILING_ENABLE; - cl_uint configuration = 1; + cl_uint configuration = 0; cmdQ = clCreatePerfCountersCommandQueueINTEL(context.get(), clDevice, properties, configuration, &retVal); ASSERT_NE(nullptr, cmdQ); @@ -99,7 +99,7 @@ TEST_F(clCreatePerfCountersCommandQueueINTELTests, GivenNullContextWhenCreatingP TEST_F(clCreatePerfCountersCommandQueueINTELTests, GivenMaximumGtdiConfigurationWhenCreatingPerfCountersCmdQThenOutOfResourcesErrorIsReturned) { cl_command_queue cmdQ = nullptr; cl_queue_properties properties = CL_QUEUE_PROFILING_ENABLE; - cl_uint configuration = GTDI_CONFIGURATION_SET_MAX; + cl_uint configuration = 4; cmdQ = clCreatePerfCountersCommandQueueINTEL(context.get(), clDevice, properties, configuration, &retVal); @@ -110,7 +110,7 @@ TEST_F(clCreatePerfCountersCommandQueueINTELTests, GivenMaximumGtdiConfiguration TEST_F(clCreatePerfCountersCommandQueueINTELTests, GivenCorrectCmdQWhenEventIsCreatedThenPerfCountersAreEnabled) { cl_command_queue cmdQ = nullptr; cl_queue_properties properties = CL_QUEUE_PROFILING_ENABLE; - cl_uint configuration = 1; + cl_uint configuration = 0; cmdQ = clCreatePerfCountersCommandQueueINTEL(context.get(), clDevice, properties, configuration, &retVal); ASSERT_NE(nullptr, cmdQ); @@ -130,7 +130,7 @@ TEST_F(clCreatePerfCountersCommandQueueINTELTests, GivenInstrumentationEnabledIs hwInfo->capabilityTable.instrumentationEnabled = false; cl_command_queue cmdQ = nullptr; cl_queue_properties properties = CL_QUEUE_PROFILING_ENABLE; - cl_uint configuration = 1; + cl_uint configuration = 0; cmdQ = clCreatePerfCountersCommandQueueINTEL(context.get(), clDevice, properties, configuration, &retVal); ASSERT_EQ(nullptr, cmdQ); @@ -148,4 +148,26 @@ TEST_F(clCreatePerfCountersCommandQueueINTELTests, GivenInvalidDeviceWhenCreatin ASSERT_EQ(CL_INVALID_DEVICE, retVal); } +TEST_F(clCreatePerfCountersCommandQueueINTELTests, GivenInvalidMetricsLibraryWhenCreatingPerfCountersThenPerfCountersReturnError) { + cl_command_queue cmdQ = nullptr; + cl_queue_properties properties = CL_QUEUE_PROFILING_ENABLE; + cl_uint configuration = 0; + + cmdQ = clCreatePerfCountersCommandQueueINTEL(context.get(), clDevice, properties, configuration, &retVal); + auto commandQueueObject = castToObject(cmdQ); + ASSERT_NE(nullptr, cmdQ); + ASSERT_EQ(CL_SUCCESS, retVal); + auto performanceCounters = commandQueueObject->getPerfCounters(); + auto metricsLibary = static_cast(performanceCounters->getMetricsLibraryInterface()); + metricsLibary->validOpen = false; + ASSERT_NE(nullptr, metricsLibary); + EXPECT_TRUE(commandQueueObject->isPerfCountersEnabled()); + EXPECT_TRUE(commandQueueObject->setPerfCountersEnabled(false, 0)); + EXPECT_FALSE(commandQueueObject->setPerfCountersEnabled(true, 0)); + EXPECT_FALSE(commandQueueObject->isPerfCountersEnabled()); + + retVal = clReleaseCommandQueue(cmdQ); + EXPECT_EQ(CL_SUCCESS, retVal); +} + } // namespace ULT diff --git a/unit_tests/api/cl_get_event_profiling_info_tests.inl b/unit_tests/api/cl_get_event_profiling_info_tests.inl index e3ed28dd2f..75abe217b1 100644 --- a/unit_tests/api/cl_get_event_profiling_info_tests.inl +++ b/unit_tests/api/cl_get_event_profiling_info_tests.inl @@ -265,7 +265,7 @@ class clEventProfilingWithPerfCountersTests : public DeviceInstrumentationFixtur commandQueue = std::make_unique(context.get(), device.get(), nullptr); event = std::make_unique(commandQueue.get(), 0, 0, 0); event->setStatus(CL_COMPLETE); - commandQueue->getPerfCounters()->processEventReport(0, nullptr, ¶m_value_size, nullptr, nullptr, true); + commandQueue->getPerfCounters()->getApiReport(0, nullptr, ¶m_value_size, true); event->setProfilingEnabled(true); eventCl = static_cast(event.get()); diff --git a/unit_tests/api/cl_set_performance_configuration_tests.inl b/unit_tests/api/cl_set_performance_configuration_tests.inl index e773ba346e..50a84fa7fe 100644 --- a/unit_tests/api/cl_set_performance_configuration_tests.inl +++ b/unit_tests/api/cl_set_performance_configuration_tests.inl @@ -25,13 +25,13 @@ struct clSetPerformanceConfigurationINTELTests : public DeviceInstrumentationFix }; namespace ULT { -TEST_F(clSetPerformanceConfigurationINTELTests, positiveSetPerfConfig) { +TEST_F(clSetPerformanceConfigurationINTELTests, negativeSetPerfConfig) { cl_int ret = CL_OUT_OF_RESOURCES; cl_uint offsets[2]; cl_uint values[2]; ret = clSetPerformanceConfigurationINTEL(device.get(), 2, offsets, values); - EXPECT_EQ(CL_SUCCESS, ret); + EXPECT_EQ(CL_INVALID_OPERATION, ret); } TEST_F(clSetPerformanceConfigurationINTELTests, negativeInvalidDevice) { @@ -41,7 +41,7 @@ TEST_F(clSetPerformanceConfigurationINTELTests, negativeInvalidDevice) { cl_device_id clDevice = {0}; ret = clSetPerformanceConfigurationINTEL(clDevice, 2, offsets, values); - EXPECT_EQ(CL_INVALID_DEVICE, ret); + EXPECT_EQ(CL_INVALID_OPERATION, ret); } TEST_F(clSetPerformanceConfigurationINTELTests, negativeInstrumentationDisabled) { @@ -53,7 +53,7 @@ TEST_F(clSetPerformanceConfigurationINTELTests, negativeInstrumentationDisabled) hwInfo->capabilityTable.instrumentationEnabled = false; ret = clSetPerformanceConfigurationINTEL(device.get(), 2, offsets, values); - EXPECT_EQ(CL_PROFILING_INFO_NOT_AVAILABLE, ret); + EXPECT_EQ(CL_INVALID_OPERATION, ret); hwInfo->capabilityTable.instrumentationEnabled = instrumentationEnabled; } diff --git a/unit_tests/command_stream/command_stream_receiver_tests.cpp b/unit_tests/command_stream/command_stream_receiver_tests.cpp index d29d62a580..6233f7dd7d 100644 --- a/unit_tests/command_stream/command_stream_receiver_tests.cpp +++ b/unit_tests/command_stream/command_stream_receiver_tests.cpp @@ -301,9 +301,10 @@ TEST_F(CommandStreamReceiverTest, whenGetEventTsAllocatorIsCalledItReturnsSameTa } TEST_F(CommandStreamReceiverTest, whenGetEventPerfCountAllocatorIsCalledItReturnsSameTagAllocator) { - TagAllocator *allocator = commandStreamReceiver->getEventPerfCountAllocator(); + const uint32_t gpuReportSize = 100; + TagAllocator *allocator = commandStreamReceiver->getEventPerfCountAllocator(gpuReportSize); EXPECT_NE(nullptr, allocator); - TagAllocator *allocator2 = commandStreamReceiver->getEventPerfCountAllocator(); + TagAllocator *allocator2 = commandStreamReceiver->getEventPerfCountAllocator(gpuReportSize); EXPECT_EQ(allocator2, allocator); } diff --git a/unit_tests/event/event_tests.cpp b/unit_tests/event/event_tests.cpp index 7264f05159..e04ffa8a07 100644 --- a/unit_tests/event/event_tests.cpp +++ b/unit_tests/event/event_tests.cpp @@ -792,7 +792,6 @@ struct InternalsEventWithPerfCountersTest PerformanceCountersFixture::SetUp(); InternalsEventTest::SetUp(); createPerfCounters(); - performanceCountersBase->initialize(platformDevices[0]); pDevice->setPerfCounters(performanceCountersBase.get()); } @@ -806,9 +805,9 @@ HWTEST_F(InternalsEventWithPerfCountersTest, givenCpuProfilingPerfCountersPathWh const cl_queue_properties props[3] = {CL_QUEUE_PROPERTIES, CL_QUEUE_PROFILING_ENABLE, 0}; CommandQueue *pCmdQ = new CommandQueue(mockContext, pDevice, props); bool ret = false; - ret = pCmdQ->setPerfCountersEnabled(true, 1); + ret = pCmdQ->setPerfCountersEnabled(true, 0); EXPECT_TRUE(ret); - ret = pCmdQ->setPerfCountersEnabled(true, 1); + ret = pCmdQ->setPerfCountersEnabled(true, 0); EXPECT_TRUE(ret); MockEvent *event = new MockEvent(pCmdQ, CL_COMMAND_MARKER, 0, 0); event->setCPUProfilingPath(true); @@ -834,7 +833,7 @@ HWTEST_F(InternalsEventWithPerfCountersTest, givenCpuProfilingPerfCountersPathWh HWTEST_F(InternalsEventWithPerfCountersTest, givenCpuProfilingPerfCountersPathWhenEnqueuedMarkerThenUseTimeStampNodePerfCounterNode) { const cl_queue_properties props[3] = {CL_QUEUE_PROPERTIES, CL_QUEUE_PROFILING_ENABLE, 0}; CommandQueue *pCmdQ = new CommandQueue(mockContext, pDevice, props); - pCmdQ->setPerfCountersEnabled(true, 1); + pCmdQ->setPerfCountersEnabled(true, 0); MockEvent *event = new MockEvent(pCmdQ, CL_COMMAND_MARKER, 0, 0); event->setCPUProfilingPath(true); HwPerfCounter *perfCounter = event->getHwPerfCounterNode()->tagForCpuAccess; @@ -862,7 +861,7 @@ HWTEST_F(InternalsEventWithPerfCountersTest, givenCpuProfilingPerfCountersPathWh TEST_F(InternalsEventWithPerfCountersTest, IsPerfCounter_Enabled) { const cl_queue_properties props[3] = {CL_QUEUE_PROPERTIES, CL_QUEUE_PROFILING_ENABLE, 0}; CommandQueue *pCmdQ = new CommandQueue(mockContext, pDevice, props); - pCmdQ->setPerfCountersEnabled(true, 2); + pCmdQ->setPerfCountersEnabled(true, 0); Event *ev = new Event(pCmdQ, CL_COMMAND_COPY_BUFFER, 3, 0); EXPECT_TRUE(ev->isProfilingEnabled()); EXPECT_TRUE(ev->isPerfCountersEnabled()); @@ -1137,57 +1136,6 @@ TEST_F(EventTest, hwTimeStampsMemoryIsPlacedInGraphicsAllocation) { EXPECT_LE(timeStamps + 1, ptrOffset(memoryStorage, graphicsAllocationSize)); } -TEST_F(EventTest, getHwPerfCounterReturnsValidPointer) { - std::unique_ptr event(new Event(this->pCmdQ, CL_COMMAND_COPY_BUFFER, 0, 0)); - ASSERT_NE(nullptr, event); - - HwPerfCounter *perfCounter = event->getHwPerfCounterNode()->tagForCpuAccess; - ASSERT_NE(nullptr, perfCounter); - - ASSERT_EQ(0ULL, perfCounter->HWTimeStamp.GlobalStartTS); - ASSERT_EQ(0ULL, perfCounter->HWTimeStamp.ContextStartTS); - ASSERT_EQ(0ULL, perfCounter->HWTimeStamp.GlobalEndTS); - ASSERT_EQ(0ULL, perfCounter->HWTimeStamp.ContextEndTS); - ASSERT_EQ(0ULL, perfCounter->HWTimeStamp.GlobalCompleteTS); - ASSERT_EQ(0ULL, perfCounter->HWTimeStamp.ContextCompleteTS); - - EXPECT_TRUE(perfCounter->canBeReleased()); - - HwPerfCounter *perfCounter2 = event->getHwPerfCounterNode()->tagForCpuAccess; - ASSERT_EQ(perfCounter, perfCounter2); -} - -TEST_F(EventTest, getHwPerfCounterAllocationReturnsValidPointer) { - std::unique_ptr event(new Event(this->pCmdQ, CL_COMMAND_COPY_BUFFER, 0, 0)); - ASSERT_NE(nullptr, event); - - GraphicsAllocation *allocation = event->getHwPerfCounterNode()->getBaseGraphicsAllocation(); - ASSERT_NE(nullptr, allocation); - - void *memoryStorage = allocation->getUnderlyingBuffer(); - size_t memoryStorageSize = allocation->getUnderlyingBufferSize(); - - EXPECT_NE(nullptr, memoryStorage); - EXPECT_GT(memoryStorageSize, 0u); -} - -TEST_F(EventTest, hwPerfCounterMemoryIsPlacedInGraphicsAllocation) { - std::unique_ptr event(new Event(this->pCmdQ, CL_COMMAND_COPY_BUFFER, 0, 0)); - ASSERT_NE(nullptr, event); - - HwPerfCounter *perfCounter = event->getHwPerfCounterNode()->tagForCpuAccess; - ASSERT_NE(nullptr, perfCounter); - - GraphicsAllocation *allocation = event->getHwPerfCounterNode()->getBaseGraphicsAllocation(); - ASSERT_NE(nullptr, allocation); - - void *memoryStorage = allocation->getUnderlyingBuffer(); - size_t graphicsAllocationSize = allocation->getUnderlyingBufferSize(); - - EXPECT_GE(perfCounter, memoryStorage); - EXPECT_LE(perfCounter + 1, ptrOffset(memoryStorage, graphicsAllocationSize)); -} - TEST_F(EventTest, IsPerfCounter_DisabledByNullQueue) { Event ev(nullptr, CL_COMMAND_COPY_BUFFER, 3, 0); EXPECT_FALSE(ev.isProfilingEnabled()); @@ -1212,24 +1160,13 @@ TEST_F(InternalsEventTest, IsPerfCounter_DisabledByNoPerfCounter) { delete pCmdQ; } -TEST_F(InternalsEventWithPerfCountersTest, SetPerfCounter_negativeInvalidASInterface) { - const cl_queue_properties props[3] = {CL_QUEUE_PROPERTIES, CL_QUEUE_PROFILING_ENABLE, 0}; - CommandQueue *pCmdQ = new CommandQueue(mockContext, pDevice, props); - performanceCountersBase->setAutoSamplingStartFunc(autoSamplingStartFailing); - bool ret = false; - ret = pCmdQ->setPerfCountersEnabled(true, 1); - EXPECT_FALSE(ret); - delete pCmdQ; -} - TEST_F(InternalsEventWithPerfCountersTest, SetPerfCounter_AvailFalse) { const cl_queue_properties props[3] = {CL_QUEUE_PROPERTIES, CL_QUEUE_PROFILING_ENABLE, 0}; CommandQueue *pCmdQ = new CommandQueue(mockContext, pDevice, props); bool ret = false; - ret = pCmdQ->setPerfCountersEnabled(true, 1); + ret = pCmdQ->setPerfCountersEnabled(true, 0); EXPECT_TRUE(ret); - performanceCountersBase->setAvailableFlag(false); ret = pCmdQ->setPerfCountersEnabled(false, 0); EXPECT_TRUE(ret); performanceCountersBase->shutdown(); diff --git a/unit_tests/instrumentation/CMakeLists.txt b/unit_tests/instrumentation/CMakeLists.txt deleted file mode 100644 index 640c89f2f5..0000000000 --- a/unit_tests/instrumentation/CMakeLists.txt +++ /dev/null @@ -1,11 +0,0 @@ -# -# Copyright (C) 2017-2018 Intel Corporation -# -# SPDX-License-Identifier: MIT -# - -set(IGDRCL_SRCS_tests_instrumentation - ${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt - ${CMAKE_CURRENT_SOURCE_DIR}/instrumentation_tests.cpp -) -target_sources(igdrcl_tests PRIVATE ${IGDRCL_SRCS_tests_instrumentation}) diff --git a/unit_tests/instrumentation/instrumentation_tests.cpp b/unit_tests/instrumentation/instrumentation_tests.cpp deleted file mode 100644 index b393e19aa0..0000000000 --- a/unit_tests/instrumentation/instrumentation_tests.cpp +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright (C) 2017-2019 Intel Corporation - * - * SPDX-License-Identifier: MIT - * - */ - -#include "gmock/gmock.h" -#include "gtest/gtest.h" -#include "instrumentation.h" - -using namespace NEO; - -struct InstrumentationTest : public ::testing::Test { - InstrumentationTest() {} -}; - -TEST(InstrumentationTest, instrAutoSamplingStart) { - InstrEscCbData cbData = {0}; - void **ppOAInterface = nullptr; - instrAutoSamplingStart(cbData, ppOAInterface); -} - -TEST(InstrumentationTest, instrAutoSamplingStop) { - void **ppOAInterface = nullptr; - instrAutoSamplingStop(ppOAInterface); -} - -TEST(InstrumentationTest, instrCheckPmRegsCfg) { - InstrPmRegsCfg *pQueryPmRegsCfg = nullptr; - uint32_t *pLastPmRegsCfgHandle = nullptr; - const void *pASInterface = nullptr; - instrCheckPmRegsCfg(pQueryPmRegsCfg, pLastPmRegsCfgHandle, pASInterface); - InstrPmRegsCfg cfg; - instrCheckPmRegsCfg(&cfg, pLastPmRegsCfgHandle, pASInterface); -} - -TEST(InstrumentationTest, instrGetPerfCountersQueryData) { - InstrEscCbData cbData = {0}; - GTDI_QUERY *pData = nullptr; - HwPerfCounters *pLayout = nullptr; - uint64_t cpuRawTimestamp = 0; - void *pASInterface = nullptr; - InstrPmRegsCfg *pPmRegsCfg = nullptr; - bool useMiRPC = false; - bool resetASData = false; - const InstrAllowedContexts *pAllowedContexts = nullptr; - instrGetPerfCountersQueryData(cbData, pData, pLayout, cpuRawTimestamp, pASInterface, pPmRegsCfg, useMiRPC, resetASData, pAllowedContexts); -} - -TEST(InstrumentationTest, instrEscGetPmRegsCfg) { - InstrEscCbData cbData = {0}; - uint32_t cfgId = 0; - InstrPmRegsCfg *pCfg = nullptr; - InstrAutoSamplingMode *pAutoSampling = nullptr; - instrEscGetPmRegsCfg(cbData, cfgId, pCfg, pAutoSampling); -} - -TEST(InstrumentationTest, instrEscHwMetricsEnable) { - InstrEscCbData cbData = {0}; - bool enable = false; - instrEscHwMetricsEnable(cbData, enable); -} - -TEST(InstrumentationTest, instrEscLoadPmRegsCfg) { - InstrEscCbData cbData = {0}; - InstrPmRegsCfg *pCfg = nullptr; - bool hardwareAccess = false; - instrEscLoadPmRegsCfg(cbData, pCfg, hardwareAccess); -} - -TEST(InstrumentationTest, instrEscSetPmRegsCfg) { - InstrEscCbData cbData = {0}; - uint32_t count = 0; - uint32_t *pOffsets = nullptr; - uint32_t *pValues = nullptr; - instrEscSetPmRegsCfg(cbData, count, pOffsets, pValues); -} - -TEST(InstrumentationTest, instrEscSendReadRegsCfg) { - InstrEscCbData cbData = {0}; - uint32_t count = 0; - uint32_t *pOffsets = nullptr; - uint32_t *pBitSizes = nullptr; - instrEscSendReadRegsCfg(cbData, count, pOffsets, pBitSizes); -} - -TEST(InstrumentationTest, instrSetAvailable) { - bool enabled = false; - instrSetAvailable(enabled); -} - -TEST(InstrumentationTest, instrEscVerifyEnable) { - InstrEscCbData cbData = {0}; - instrEscVerifyEnable(cbData); -} - -TEST(InstrumentationTest, instrSetPlatformInfo) { - uint32_t productId = 0; - void *featureTable = nullptr; - instrSetPlatformInfo(productId, featureTable); -} diff --git a/unit_tests/mocks/CMakeLists.txt b/unit_tests/mocks/CMakeLists.txt index b2ba9abfae..ce2aef8e23 100644 --- a/unit_tests/mocks/CMakeLists.txt +++ b/unit_tests/mocks/CMakeLists.txt @@ -46,7 +46,6 @@ set(IGDRCL_SRCS_tests_mocks ${CMAKE_CURRENT_SOURCE_DIR}/mock_gmm_resource_info.h ${CMAKE_CURRENT_SOURCE_DIR}/mock_gmm_resource_info.cpp ${CMAKE_CURRENT_SOURCE_DIR}/mock_graphics_allocation.h - ${CMAKE_CURRENT_SOURCE_DIR}${IGDRCL__INSTRUMENTATION_DIR_SUFFIX}/mock_instrumentation.cpp ${CMAKE_CURRENT_SOURCE_DIR}${BRANCH_DIR_SUFFIX}/mock_gmm_client_context.cpp ${CMAKE_CURRENT_SOURCE_DIR}${BRANCH_DIR_SUFFIX}/mock_gmm_client_context.h ${CMAKE_CURRENT_SOURCE_DIR}/mock_host_ptr_manager.h diff --git a/unit_tests/mocks/mock_device.h b/unit_tests/mocks/mock_device.h index ad6c7a17f3..8bbbd4f1a5 100644 --- a/unit_tests/mocks/mock_device.h +++ b/unit_tests/mocks/mock_device.h @@ -67,7 +67,11 @@ class MockDevice : public Device { void injectMemoryManager(MemoryManager *); void setPerfCounters(PerformanceCounters *perfCounters) { - performanceCounters = std::unique_ptr(perfCounters); + if (perfCounters) { + performanceCounters = std::unique_ptr(perfCounters); + } else { + performanceCounters.release(); + } } template diff --git a/unit_tests/mocks/mock_instrumentation.cpp b/unit_tests/mocks/mock_instrumentation.cpp deleted file mode 100644 index 4b9f221e19..0000000000 --- a/unit_tests/mocks/mock_instrumentation.cpp +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright (C) 2018-2019 Intel Corporation - * - * SPDX-License-Identifier: MIT - * - */ - -#include "instrumentation.h" - -#include - -using namespace NEO; - -bool InstrAutoSamplingStart( - InstrEscCbData cbData, - void **ppOAInterface) { - - return false; -} - -bool InstrAutoSamplingStop( - void **ppOAInterface) { - - return false; -} - -bool InstrCheckPmRegsCfg( - InstrPmRegsCfg *pQueryPmRegsCfg, - uint32_t *pLastPmRegsCfgHandle, - const void *pASInterface) { - - return false; -} - -bool InstrEscGetPmRegsCfg( - InstrEscCbData cbData, - uint32_t cfgId, - InstrPmRegsCfg *pCfg, - InstrAutoSamplingMode *pAutoSampling) { - return false; -} -bool InstrEscHwMetricsEnable( - InstrEscCbData cbData, - bool enable) { - return false; -} - -bool InstrEscLoadPmRegsCfg( - InstrEscCbData cbData, - InstrPmRegsCfg *pCfg, - bool hardwareAccess) { - return false; -} - -bool InstrEscSetPmRegsCfg( - InstrEscCbData cbData, - uint32_t count, - uint32_t *pOffsets, - uint32_t *pValues) { - return false; -} - -bool InstrEscSendReadRegsCfg( - InstrEscCbData cbData, - uint32_t count, - uint32_t *pOffsets, - uint32_t *pBitSizes) { - return false; -} - -uint32_t InstrSetPlatformInfo( - uint32_t productId, - void *featureTable) { - return -1; -} - -bool InstrSetAvailable(bool enabled) { - return false; -} - -void InstrEscVerifyEnable(InstrEscCbData cbData) { -} diff --git a/unit_tests/os_interface/linux/mock_performance_counters_linux.cpp b/unit_tests/os_interface/linux/mock_performance_counters_linux.cpp index 22a69f5254..7d858450dc 100644 --- a/unit_tests/os_interface/linux/mock_performance_counters_linux.cpp +++ b/unit_tests/os_interface/linux/mock_performance_counters_linux.cpp @@ -7,83 +7,53 @@ #include "mock_performance_counters_linux.h" -#include "unit_tests/os_interface/linux/drm_mock.h" #include "unit_tests/os_interface/linux/mock_os_time_linux.h" +#include "unit_tests/os_interface/mock_performance_counters.h" namespace NEO { -MockPerformanceCountersLinux::MockPerformanceCountersLinux(OSTime *osTime) - : PerformanceCounters(osTime), PerformanceCountersLinux(osTime), MockPerformanceCounters(osTime) { - dlopenFunc = dlopenMockPassing; - dlsymFunc = dlsymMockPassing; - dlcloseFunc = dlcloseMock; - setPlatformInfoFunc = setPlatformInfo; - PerfCounterFlagsLinux::resetPerfCountersFlags(); -} -std::unique_ptr MockPerformanceCounters::create(OSTime *osTime) { - return std::unique_ptr(new MockPerformanceCountersLinux(osTime)); +////////////////////////////////////////////////////// +// MockPerformanceCountersLinux::MockPerformanceCountersLinux +////////////////////////////////////////////////////// +MockPerformanceCountersLinux::MockPerformanceCountersLinux(Device *device) + : PerformanceCountersLinux() { } -int PerfCounterFlagsLinux::dlopenFuncCalled; -int PerfCounterFlagsLinux::dlsymFuncCalled; -int PerfCounterFlagsLinux::dlcloseFuncCalled; -int PerfCounterFlagsLinux::perfmonLoadConfigCalled; -int PerfCounterFlagsLinux::setPlatformInfoFuncCalled; +////////////////////////////////////////////////////// +// MockPerformanceCounters::create +////////////////////////////////////////////////////// +std::unique_ptr MockPerformanceCounters::create(Device *device) { + auto performanceCounters = std::unique_ptr(new MockPerformanceCountersLinux(device)); + auto metricsLibrary = std::make_unique(); + auto metricsLibraryDll = std::make_unique(); -void *dlopenMockPassing(const char *filename, int flag) throw() { - PerfCounterFlagsLinux::dlopenFuncCalled++; - return new char[1]; -} -void *dlopenMockFailing(const char *filename, int flag) throw() { - PerfCounterFlagsLinux::dlopenFuncCalled++; - return nullptr; -} -void *dlsymMockPassing(void *handle, const char *symbol) throw() { - PerfCounterFlagsLinux::dlsymFuncCalled++; - return (void *)perfmonLoadConfigMock; -} -void *dlsymMockFailing(void *handle, const char *symbol) throw() { - PerfCounterFlagsLinux::dlsymFuncCalled++; - return nullptr; -} -int dlcloseMock(void *handle) throw() { - PerfCounterFlagsLinux::dlcloseFuncCalled++; - if (handle) { - delete[] static_cast(handle); - } - return 0; -} -uint32_t setPlatformInfo(uint32_t productId, void *featureTable) { - PerfCounterFlagsLinux::setPlatformInfoFuncCalled++; - return 0; -} -int getTimeFuncPassing(clockid_t clkId, struct timespec *tp) throw() { - tp->tv_sec = 0; - tp->tv_nsec = 1; - return 0; -} -int perfmonLoadConfigMock(int fd, drm_intel_context *ctx, uint32_t *oaCfgId, uint32_t *gpCfgId) { - PerfCounterFlagsLinux::perfmonLoadConfigCalled++; - return 0; + metricsLibrary->api = std::make_unique(); + metricsLibrary->osLibrary = std::move(metricsLibraryDll); + performanceCounters->setMetricsLibraryInterface(std::move(metricsLibrary)); + + return performanceCounters; } -void PerfCounterFlagsLinux::resetPerfCountersFlags() { - PerfCounterFlags::resetPerfCountersFlags(); - PerfCounterFlagsLinux::dlopenFuncCalled = 0; - PerfCounterFlagsLinux::dlsymFuncCalled = 0; - PerfCounterFlagsLinux::dlcloseFuncCalled = 0; - PerfCounterFlagsLinux::perfmonLoadConfigCalled = 0; - PerfCounterFlagsLinux::setPlatformInfoFuncCalled = 0; -} +////////////////////////////////////////////////////// +// PerformanceCountersFixture::createPerfCounters +////////////////////////////////////////////////////// void PerformanceCountersFixture::createPerfCounters() { - performanceCountersBase = std::unique_ptr(new MockPerformanceCountersLinux(osTimeBase.get())); + performanceCountersBase = MockPerformanceCounters::create(device.get()); } -void PerformanceCountersFixture::createOsTime() { - osTimeBase = std::unique_ptr(new MockOSTimeLinux(osInterfaceBase.get())); + +////////////////////////////////////////////////////// +// PerformanceCountersFixture::SetUp +////////////////////////////////////////////////////// +void PerformanceCountersFixture::SetUp() { + device = std::unique_ptr(new MockDevice()); + context = std::make_unique(device.get()); + queue = std::make_unique(context.get(), device.get(), &queueProperties); + osInterface = std::unique_ptr(new OSInterface()); + device->setOSTime(new MockOSTimeLinux(osInterface.get())); } -void PerformanceCountersFixture::fillOsInterface() { - osInterfaceBase->get()->setDrm(new DrmMock()); -} -void PerformanceCountersFixture::releaseOsInterface() { - delete static_cast(osInterfaceBase->get()->getDrm()); + +////////////////////////////////////////////////////// +// PerformanceCountersFixture::TearDown +////////////////////////////////////////////////////// +void PerformanceCountersFixture::TearDown() { } } // namespace NEO diff --git a/unit_tests/os_interface/linux/mock_performance_counters_linux.h b/unit_tests/os_interface/linux/mock_performance_counters_linux.h index f8920446ce..9236f876fd 100644 --- a/unit_tests/os_interface/linux/mock_performance_counters_linux.h +++ b/unit_tests/os_interface/linux/mock_performance_counters_linux.h @@ -7,57 +7,11 @@ #pragma once #include "runtime/os_interface/linux/performance_counters_linux.h" -#include "unit_tests/os_interface/mock_performance_counters.h" namespace NEO { -void *dlopenMockPassing(const char *filename, int flag) throw(); -void *dlopenMockFailing(const char *filename, int flag) throw(); -void *dlsymMockPassing(void *handle, const char *symbol) throw(); -void *dlsymMockFailing(void *handle, const char *symbol) throw(); -int getTimeFuncPassing(clockid_t clk_id, struct timespec *tp) throw(); -int dlcloseMock(void *handle) throw(); -uint32_t setPlatformInfo(uint32_t productId, void *featureTable); -int perfmonLoadConfigMock(int fd, drm_intel_context *ctx, uint32_t *oa_cfg_id, uint32_t *gp_cfg_id); - -class PerfCounterFlagsLinux : public PerfCounterFlags { +class MockPerformanceCountersLinux : public PerformanceCountersLinux { public: - static int dlopenFuncCalled; - static int dlsymFuncCalled; - static int dlcloseFuncCalled; - static int perfmonLoadConfigCalled; - static int setPlatformInfoFuncCalled; - static void resetPerfCountersFlags(); -}; - -class MockPerformanceCountersLinux : public PerformanceCountersLinux, - public MockPerformanceCounters { - public: - MockPerformanceCountersLinux(OSTime *osTime); - uint32_t getReportId() override { - return MockPerformanceCounters::getReportId(); - } - void initialize(const HardwareInfo *hwInfo) override { - MockPerformanceCounters::initialize(hwInfo); - return PerformanceCountersLinux::initialize(hwInfo); - } - void enableImpl() override { - return PerformanceCountersLinux::enableImpl(); - } - bool verifyPmRegsCfg(InstrPmRegsCfg *pCfg, uint32_t *pLastPmRegsCfgHandle, bool *pLastPmRegsCfgPending) override { - return PerformanceCountersLinux::verifyPmRegsCfg(pCfg, pLastPmRegsCfgHandle, pLastPmRegsCfgPending); - } - bool getPerfmonConfig(InstrPmRegsCfg *pCfg) override { - return PerformanceCountersLinux::getPerfmonConfig(pCfg); - } - void setDlopenFunc(dlopenFunc_t func) { - dlopenFunc = func; - } - void setDlsymFunc(dlsymFunc_t func) { - dlsymFunc = func; - } - void setPerfmonLoadConfigFunc(perfmonLoadConfig_t func) { - perfmonLoadConfigFunc = func; - } + MockPerformanceCountersLinux(Device *device); }; } // namespace NEO diff --git a/unit_tests/os_interface/linux/options.cpp b/unit_tests/os_interface/linux/options.cpp index 17ae678037..dfd800c731 100644 --- a/unit_tests/os_interface/linux/options.cpp +++ b/unit_tests/os_interface/linux/options.cpp @@ -22,6 +22,7 @@ const char *libvaDllName = nullptr; const char *testDllName = "libtest_dynamic_lib.so"; const char *gmmDllName = "libmock_gmm.so"; const char *gmmEntryName = "openMockGmm"; +const char *metricsLibraryDllName = ""; #endif const char *sysFsPciPath = "./test_files"; } // namespace Os diff --git a/unit_tests/os_interface/linux/performance_counters_linux_tests.cpp b/unit_tests/os_interface/linux/performance_counters_linux_tests.cpp index 2b48629c69..e3af1fc599 100644 --- a/unit_tests/os_interface/linux/performance_counters_linux_tests.cpp +++ b/unit_tests/os_interface/linux/performance_counters_linux_tests.cpp @@ -6,11 +6,10 @@ */ #include "runtime/helpers/options.h" -#include "unit_tests/os_interface/linux/drm_mock.h" -#include "unit_tests/os_interface/linux/mock_os_time_linux.h" +#include "unit_tests/os_interface/linux/mock_performance_counters_linux.h" +#include "unit_tests/os_interface/mock_performance_counters.h" #include "gtest/gtest.h" -#include "mock_performance_counters_linux.h" using namespace NEO; @@ -19,438 +18,8 @@ struct PerformanceCountersLinuxTest : public PerformanceCountersFixture, void SetUp() override { PerformanceCountersFixture::SetUp(); - PerfCounterFlagsLinux::resetPerfCountersFlags(); - - drm = static_cast(osInterfaceBase->get()->getDrm()); - osTimeLinux = static_cast(osTimeBase.get()); } void TearDown() override { PerformanceCountersFixture::TearDown(); } - void createPerfCounters() override { - PerformanceCountersFixture::createPerfCounters(); - performanceCountersLinux = static_cast(performanceCountersBase.get()); - } - - DrmMock *drm; - MockOSTimeLinux *osTimeLinux; - MockPerformanceCountersLinux *performanceCountersLinux; }; - -struct PerformanceCountersLinuxSendConfigCommandPointersTest : public PerformanceCountersLinuxTest, - public ::testing::WithParamInterface { - void SetUp() override { - PerformanceCountersLinuxTest::SetUp(); - createPerfCounters(); - perfmonFuncIsNullptr = GetParam(); - } - - void TearDown() override { - performanceCountersBase->shutdown(); - PerformanceCountersLinuxTest::TearDown(); - } - bool perfmonFuncIsNullptr; - InstrPmRegsCfg config; - uint32_t lastConfigHandle; - bool lastConfigPending; -}; - -struct PerformanceCountersLinuxGetPerfmonConfigTest : public PerformanceCountersLinuxTest, - public ::testing::WithParamInterface> { - void SetUp() override { - PerformanceCountersLinuxTest::SetUp(); - createPerfCounters(); - performanceCountersLinux->setPerfmonLoadConfigFunc(perfmonLoadConfigMock); - } - void TearDown() override { - PerformanceCountersLinuxTest::TearDown(); - } -}; - -TEST_F(PerformanceCountersLinuxTest, enableWithCreatedAsInterface) { - createPerfCounters(); - performanceCountersLinux->setDlopenFunc(dlopenMockPassing); - performanceCountersLinux->setDlsymFunc(dlsymMockPassing); - performanceCountersBase->initialize(platformDevices[0]); - performanceCountersBase->setAsIface(new char[1]); - performanceCountersBase->enable(); -} - -TEST_F(PerformanceCountersLinuxTest, initializePerformanceCountersWithPassingFuncs) { - createPerfCounters(); - performanceCountersLinux->setDlopenFunc(dlopenMockPassing); - performanceCountersLinux->setDlsymFunc(dlsymMockPassing); - performanceCountersBase->initialize(platformDevices[0]); - EXPECT_EQ(1, PerfCounterFlagsLinux::dlopenFuncCalled); - EXPECT_EQ(1, PerfCounterFlagsLinux::dlsymFuncCalled); - EXPECT_FALSE(performanceCountersBase->isAvailable()); - performanceCountersBase->shutdown(); - EXPECT_EQ(0, PerfCounterFlagsLinux::dlcloseFuncCalled); - EXPECT_EQ(0, PerfCounterFlagsLinux::escHwMetricsCalled); - EXPECT_EQ(0, PerfCounterFlagsLinux::autoSamplingFuncCalled); - EXPECT_EQ(0, PerfCounterFlagsLinux::autoSamplingStopped); - EXPECT_EQ(0, PerfCounterFlagsLinux::autoSamplingStarted); - EXPECT_FALSE(performanceCountersBase->isAvailable()); -} - -TEST_F(PerformanceCountersLinuxTest, initializePerformanceCountersWithFailingDlopenFunc) { - createPerfCounters(); - performanceCountersLinux->setDlopenFunc(dlopenMockFailing); - performanceCountersBase->initialize(platformDevices[0]); - EXPECT_EQ(1, PerfCounterFlagsLinux::dlopenFuncCalled); - EXPECT_EQ(0, PerfCounterFlagsLinux::dlsymFuncCalled); - performanceCountersBase->shutdown(); - EXPECT_EQ(0, PerfCounterFlagsLinux::dlcloseFuncCalled); -} - -TEST_F(PerformanceCountersLinuxTest, initializePerformanceCountersWithPassingDlopenFuncAndFailingDlsymFunc) { - createPerfCounters(); - performanceCountersLinux->setDlopenFunc(dlopenMockPassing); - performanceCountersLinux->setDlsymFunc(dlsymMockFailing); - performanceCountersBase->initialize(platformDevices[0]); - EXPECT_EQ(1, PerfCounterFlagsLinux::dlopenFuncCalled); - EXPECT_EQ(1, PerfCounterFlagsLinux::dlsymFuncCalled); - performanceCountersBase->shutdown(); - EXPECT_EQ(0, PerfCounterFlagsLinux::dlcloseFuncCalled); -} - -TEST_F(PerformanceCountersLinuxTest, enablePerformanceCountersWithoutInitializing) { - uint32_t refNum = 0; - createPerfCounters(); - refNum = performanceCountersBase->getPerfCountersReferenceNumber(); - EXPECT_EQ(0u, refNum); - performanceCountersBase->enable(); - EXPECT_EQ(0, PerfCounterFlagsLinux::escHwMetricsCalled); - EXPECT_EQ(0, PerfCounterFlagsLinux::autoSamplingFuncCalled); - EXPECT_EQ(0, PerfCounterFlagsLinux::hwMetricsEnableStatus); - refNum = performanceCountersBase->getPerfCountersReferenceNumber(); - EXPECT_EQ(1u, refNum); - performanceCountersBase->shutdown(); - EXPECT_EQ(0, PerfCounterFlagsLinux::dlcloseFuncCalled); - EXPECT_EQ(0, PerfCounterFlagsLinux::escHwMetricsCalled); - EXPECT_EQ(0, PerfCounterFlagsLinux::autoSamplingFuncCalled); - EXPECT_EQ(0, PerfCounterFlagsLinux::autoSamplingStopped); - refNum = performanceCountersBase->getPerfCountersReferenceNumber(); - EXPECT_EQ(0u, refNum); -} - -TEST_F(PerformanceCountersLinuxTest, enablePerformanceCountersWithPassingEscHwMetricsFuncTwice) { - uint32_t refNum = 0; - createPerfCounters(); - EXPECT_FALSE(performanceCountersBase->isAvailable()); - refNum = performanceCountersBase->getPerfCountersReferenceNumber(); - EXPECT_EQ(0u, refNum); - performanceCountersBase->enable(); - refNum = performanceCountersBase->getPerfCountersReferenceNumber(); - EXPECT_EQ(0, PerfCounterFlagsLinux::escHwMetricsCalled); - EXPECT_EQ(0, PerfCounterFlagsLinux::autoSamplingFuncCalled); - EXPECT_EQ(0, PerfCounterFlagsLinux::autoSamplingStarted); - EXPECT_EQ(1u, refNum); - EXPECT_FALSE(performanceCountersBase->isAvailable()); - performanceCountersBase->enable(); - refNum = performanceCountersBase->getPerfCountersReferenceNumber(); - EXPECT_EQ(0, PerfCounterFlagsLinux::escHwMetricsCalled); - EXPECT_EQ(0, PerfCounterFlagsLinux::autoSamplingFuncCalled); - EXPECT_EQ(0, PerfCounterFlagsLinux::autoSamplingStarted); - EXPECT_EQ(2u, refNum); - EXPECT_FALSE(performanceCountersBase->isAvailable()); - performanceCountersBase->shutdown(); - refNum = performanceCountersBase->getPerfCountersReferenceNumber(); - EXPECT_EQ(0, PerfCounterFlagsLinux::escHwMetricsCalled); - EXPECT_EQ(0, PerfCounterFlagsLinux::autoSamplingFuncCalled); - EXPECT_EQ(0, PerfCounterFlagsLinux::autoSamplingStopped); - EXPECT_EQ(1u, refNum); - EXPECT_FALSE(performanceCountersBase->isAvailable()); - performanceCountersBase->shutdown(); - refNum = performanceCountersBase->getPerfCountersReferenceNumber(); - EXPECT_EQ(0, PerfCounterFlagsLinux::escHwMetricsCalled); - EXPECT_EQ(0, PerfCounterFlagsLinux::autoSamplingFuncCalled); - EXPECT_EQ(0, PerfCounterFlagsLinux::autoSamplingStopped); - EXPECT_EQ(0u, refNum); - EXPECT_FALSE(performanceCountersBase->isAvailable()); -} - -TEST_F(PerformanceCountersLinuxTest, enablePerformanceCountersWithPassingHwMetricsFuncAfterProperInitializing) { - uint32_t refNum = 0; - createPerfCounters(); - performanceCountersLinux->setDlopenFunc(dlopenMockPassing); - performanceCountersLinux->setDlsymFunc(dlsymMockPassing); - performanceCountersBase->setEscHwMetricsFunc(hwMetricsEnableFuncPassing); - performanceCountersBase->initialize(platformDevices[0]); - refNum = performanceCountersBase->getPerfCountersReferenceNumber(); - EXPECT_EQ(0u, refNum); - EXPECT_FALSE(performanceCountersBase->isAvailable()); - performanceCountersBase->enable(); - EXPECT_EQ(1, PerfCounterFlagsLinux::hwMetricsEnableStatus); - EXPECT_EQ(1, PerfCounterFlagsLinux::escHwMetricsCalled); - EXPECT_EQ(1, PerfCounterFlagsLinux::autoSamplingFuncCalled); - EXPECT_EQ(1, PerfCounterFlagsLinux::autoSamplingStarted); - refNum = performanceCountersBase->getPerfCountersReferenceNumber(); - EXPECT_EQ(1u, refNum); - EXPECT_TRUE(performanceCountersBase->isAvailable()); - performanceCountersBase->shutdown(); - EXPECT_EQ(0, PerfCounterFlagsLinux::hwMetricsEnableStatus); - EXPECT_EQ(0, PerfCounterFlagsLinux::dlcloseFuncCalled); - EXPECT_EQ(2, PerfCounterFlagsLinux::escHwMetricsCalled); - EXPECT_EQ(2, PerfCounterFlagsLinux::autoSamplingFuncCalled); - EXPECT_EQ(1, PerfCounterFlagsLinux::autoSamplingStopped); - refNum = performanceCountersBase->getPerfCountersReferenceNumber(); - EXPECT_EQ(0u, refNum); - EXPECT_FALSE(performanceCountersBase->isAvailable()); -} - -TEST_F(PerformanceCountersLinuxTest, enablePerformanceCountersWithFailingAutoStartFuncAfterProperInitializing) { - uint32_t refNum = 0; - createPerfCounters(); - performanceCountersLinux->setDlopenFunc(dlopenMockPassing); - performanceCountersLinux->setDlsymFunc(dlsymMockPassing); - performanceCountersBase->setEscHwMetricsFunc(hwMetricsEnableFuncPassing); - performanceCountersBase->setAutoSamplingStartFunc(autoSamplingStartFailing); - performanceCountersBase->initialize(platformDevices[0]); - refNum = performanceCountersBase->getPerfCountersReferenceNumber(); - EXPECT_EQ(0u, refNum); - EXPECT_FALSE(performanceCountersBase->isAvailable()); - performanceCountersBase->enable(); - EXPECT_EQ(1, PerfCounterFlagsLinux::hwMetricsEnableStatus); - EXPECT_EQ(1, PerfCounterFlagsLinux::escHwMetricsCalled); - EXPECT_EQ(1, PerfCounterFlagsLinux::autoSamplingFuncCalled); - EXPECT_EQ(1, PerfCounterFlagsLinux::autoSamplingStarted); - refNum = performanceCountersBase->getPerfCountersReferenceNumber(); - EXPECT_EQ(1u, refNum); - EXPECT_FALSE(performanceCountersBase->isAvailable()); - performanceCountersBase->shutdown(); - EXPECT_EQ(0, PerfCounterFlagsLinux::hwMetricsEnableStatus); - EXPECT_EQ(0, PerfCounterFlagsLinux::dlcloseFuncCalled); - EXPECT_EQ(2, PerfCounterFlagsLinux::escHwMetricsCalled); - EXPECT_EQ(1, PerfCounterFlagsLinux::autoSamplingFuncCalled); - EXPECT_EQ(0, PerfCounterFlagsLinux::autoSamplingStopped); - refNum = performanceCountersBase->getPerfCountersReferenceNumber(); - EXPECT_EQ(0u, refNum); - EXPECT_FALSE(performanceCountersBase->isAvailable()); -} - -TEST_F(PerformanceCountersLinuxTest, enablePerformanceCountersWithFailingHwMetricsFuncAfterProperInitializing) { - createPerfCounters(); - performanceCountersLinux->setDlopenFunc(dlopenMockPassing); - performanceCountersLinux->setDlsymFunc(dlsymMockPassing); - performanceCountersBase->setEscHwMetricsFunc(hwMetricsEnableFuncFailing); - performanceCountersBase->initialize(platformDevices[0]); - performanceCountersBase->enable(); - EXPECT_EQ(1, PerfCounterFlagsLinux::hwMetricsEnableStatus); - EXPECT_EQ(1, PerfCounterFlagsLinux::escHwMetricsCalled); - EXPECT_EQ(0, PerfCounterFlagsLinux::autoSamplingFuncCalled); - EXPECT_EQ(0, PerfCounterFlagsLinux::autoSamplingStarted); - performanceCountersBase->shutdown(); - EXPECT_EQ(1, PerfCounterFlagsLinux::hwMetricsEnableStatus); - EXPECT_EQ(0, PerfCounterFlagsLinux::dlcloseFuncCalled); - EXPECT_EQ(1, PerfCounterFlagsLinux::escHwMetricsCalled); - EXPECT_EQ(0, PerfCounterFlagsLinux::autoSamplingFuncCalled); - EXPECT_EQ(0, PerfCounterFlagsLinux::autoSamplingStopped); -} - -TEST_F(PerformanceCountersLinuxTest, enablePerformanceCountersWithPassingHwMetricsFuncAfterProperInitializingTwice) { - createPerfCounters(); - performanceCountersLinux->setDlopenFunc(dlopenMockPassing); - performanceCountersLinux->setDlsymFunc(dlsymMockPassing); - performanceCountersBase->setEscHwMetricsFunc(hwMetricsEnableFuncPassing); - performanceCountersBase->initialize(platformDevices[0]); - performanceCountersBase->enable(); - EXPECT_EQ(1, PerfCounterFlagsLinux::hwMetricsEnableStatus); - EXPECT_EQ(1, PerfCounterFlagsLinux::escHwMetricsCalled); - EXPECT_EQ(1, PerfCounterFlagsLinux::autoSamplingFuncCalled); - EXPECT_EQ(1, PerfCounterFlagsLinux::autoSamplingStarted); - performanceCountersBase->enable(); - EXPECT_EQ(1, PerfCounterFlagsLinux::hwMetricsEnableStatus); - EXPECT_EQ(1, PerfCounterFlagsLinux::escHwMetricsCalled); - EXPECT_EQ(1, PerfCounterFlagsLinux::autoSamplingFuncCalled); - EXPECT_EQ(1, PerfCounterFlagsLinux::autoSamplingStarted); - performanceCountersBase->shutdown(); - EXPECT_EQ(1, PerfCounterFlagsLinux::hwMetricsEnableStatus); - EXPECT_EQ(0, PerfCounterFlagsLinux::dlcloseFuncCalled); - EXPECT_EQ(1, PerfCounterFlagsLinux::escHwMetricsCalled); - EXPECT_EQ(1, PerfCounterFlagsLinux::autoSamplingFuncCalled); - EXPECT_EQ(0, PerfCounterFlagsLinux::autoSamplingStopped); - performanceCountersBase->shutdown(); - EXPECT_EQ(0, PerfCounterFlagsLinux::hwMetricsEnableStatus); - EXPECT_EQ(0, PerfCounterFlagsLinux::dlcloseFuncCalled); - EXPECT_EQ(2, PerfCounterFlagsLinux::escHwMetricsCalled); - EXPECT_EQ(2, PerfCounterFlagsLinux::autoSamplingFuncCalled); - EXPECT_EQ(1, PerfCounterFlagsLinux::autoSamplingStopped); -} - -TEST_F(PerformanceCountersLinuxTest, enablePerformanceCountersWithFailingHwMetricsFuncAfterStartingAutoSampling) { - createPerfCounters(); - performanceCountersLinux->setDlopenFunc(dlopenMockPassing); - performanceCountersLinux->setDlsymFunc(dlsymMockPassing); - performanceCountersBase->setEscHwMetricsFunc(hwMetricsEnableFuncPassing); - performanceCountersBase->initialize(platformDevices[0]); - performanceCountersBase->enable(); - EXPECT_EQ(1, PerfCounterFlagsLinux::hwMetricsEnableStatus); - EXPECT_EQ(1, PerfCounterFlagsLinux::escHwMetricsCalled); - EXPECT_EQ(1, PerfCounterFlagsLinux::autoSamplingFuncCalled); - EXPECT_EQ(1, PerfCounterFlagsLinux::autoSamplingStarted); - performanceCountersBase->setEscHwMetricsFunc(hwMetricsEnableFuncFailing); - performanceCountersBase->enable(); - EXPECT_EQ(1, PerfCounterFlagsLinux::hwMetricsEnableStatus); - EXPECT_EQ(1, PerfCounterFlagsLinux::escHwMetricsCalled); - EXPECT_EQ(1, PerfCounterFlagsLinux::autoSamplingFuncCalled); - EXPECT_EQ(1, PerfCounterFlagsLinux::autoSamplingStarted); - performanceCountersBase->shutdown(); - EXPECT_EQ(1, PerfCounterFlagsLinux::hwMetricsEnableStatus); - EXPECT_EQ(0, PerfCounterFlagsLinux::dlcloseFuncCalled); - EXPECT_EQ(1, PerfCounterFlagsLinux::escHwMetricsCalled); - EXPECT_EQ(1, PerfCounterFlagsLinux::autoSamplingFuncCalled); - EXPECT_EQ(0, PerfCounterFlagsLinux::autoSamplingStopped); - performanceCountersBase->shutdown(); - EXPECT_EQ(0, PerfCounterFlagsLinux::dlcloseFuncCalled); - EXPECT_EQ(2, PerfCounterFlagsLinux::escHwMetricsCalled); - EXPECT_EQ(2, PerfCounterFlagsLinux::autoSamplingFuncCalled); - EXPECT_EQ(1, PerfCounterFlagsLinux::autoSamplingStopped); -} - -TEST_F(PerformanceCountersLinuxTest, enablePerformanceCountersWithMdLibHandleAndNotLoadedFunc) { - createPerfCounters(); - performanceCountersLinux->setDlopenFunc(dlopenMockPassing); - performanceCountersLinux->setDlsymFunc(dlsymMockFailing); - performanceCountersBase->setEscHwMetricsFunc(hwMetricsEnableFuncPassing); - performanceCountersBase->initialize(platformDevices[0]); - EXPECT_EQ(1, PerfCounterFlagsLinux::dlopenFuncCalled); - EXPECT_EQ(1, PerfCounterFlagsLinux::dlsymFuncCalled); - performanceCountersBase->enable(); - EXPECT_EQ(0, PerfCounterFlagsLinux::hwMetricsEnableStatus); - EXPECT_EQ(0, PerfCounterFlagsLinux::escHwMetricsCalled); - EXPECT_EQ(0, PerfCounterFlagsLinux::autoSamplingFuncCalled); - EXPECT_EQ(0, PerfCounterFlagsLinux::autoSamplingStarted); - performanceCountersBase->shutdown(); - EXPECT_EQ(0, PerfCounterFlagsLinux::hwMetricsEnableStatus); - EXPECT_EQ(0, PerfCounterFlagsLinux::dlcloseFuncCalled); - EXPECT_EQ(0, PerfCounterFlagsLinux::escHwMetricsCalled); - EXPECT_EQ(0, PerfCounterFlagsLinux::autoSamplingFuncCalled); - EXPECT_EQ(0, PerfCounterFlagsLinux::autoSamplingStopped); -} - -TEST_F(PerformanceCountersLinuxTest, setCpuTimestamp) { - createPerfCounters(); - EXPECT_EQ(0ull, performanceCountersBase->getCpuRawTimestamp()); - osTimeLinux->setGetTimeFunc(getTimeFuncPassing); - performanceCountersBase->setCpuTimestamp(); - EXPECT_NE(0ull, performanceCountersBase->getCpuRawTimestamp()); - EXPECT_EQ(performanceCountersBase->getCpuRawTimestamp(), - osTimeBase->getCpuRawTimestamp()); -} - -TEST_P(PerformanceCountersLinuxSendConfigCommandPointersTest, givenPerformanceCountersWithPassingFuncsWhenSendPmRegsCfgCommandsIsCalledWithPerfmonFuncNullptrThenReturnsFalseOtherwiseTrue) { - if (!perfmonFuncIsNullptr) { - performanceCountersBase->initialize(platformDevices[0]); - } - lastConfigPending = false; - - auto retVal = performanceCountersBase->sendPmRegsCfgCommands(&config, &lastConfigHandle, &lastConfigPending); - if (perfmonFuncIsNullptr) { - EXPECT_FALSE(retVal); - EXPECT_EQ(0, PerfCounterFlagsLinux::checkPmRegsCfgCalled); - EXPECT_EQ(0, PerfCounterFlagsLinux::loadPmRegsCfgCalled); - } else { - EXPECT_TRUE(retVal); - EXPECT_TRUE(lastConfigPending); - EXPECT_EQ(1, PerfCounterFlagsLinux::checkPmRegsCfgCalled); - EXPECT_EQ(1, PerfCounterFlagsLinux::loadPmRegsCfgCalled); - } -} - -INSTANTIATE_TEST_CASE_P( - PerfCountersTests, - PerformanceCountersLinuxSendConfigCommandPointersTest, - testing::Bool()); - -int perfmonLoadConfigFailing(int fd, drm_intel_context *ctx, uint32_t *oaCfgId, uint32_t *gpCfgId) { - PerfCounterFlagsLinux::perfmonLoadConfigCalled++; - return -1; -} - -TEST_F(PerformanceCountersLinuxTest, givenPerformanceCountersWithFailingPerfmonLoadConfigFuncWhenGetPerfmonConfigIsCalledThenReturnsFalse) { - InstrPmRegsCfg config; - uint32_t lastConfigHandle; - bool lastConfigPending; - createPerfCounters(); - performanceCountersLinux->setPerfmonLoadConfigFunc(perfmonLoadConfigFailing); - performanceCountersBase->setCheckPmRegsCfgFunc(checkPmRegsCfgPassing); - performanceCountersBase->setLoadPmRegsCfgFunc(loadPmRegsCfgPassing); - auto retVal = performanceCountersBase->sendPmRegsCfgCommands(&config, &lastConfigHandle, &lastConfigPending); - EXPECT_EQ(1, PerfCounterFlagsLinux::perfmonLoadConfigCalled); - EXPECT_FALSE(retVal); -} - -int perfmonLoadConfigChangingOa(int fd, drm_intel_context *ctx, uint32_t *oaCfgId, uint32_t *gpCfgId) { - PerfCounterFlagsLinux::perfmonLoadConfigCalled++; - (*oaCfgId)++; - return 0; -} - -int perfmonLoadConfigChangingGp(int fd, drm_intel_context *ctx, uint32_t *oaCfgId, uint32_t *gpCfgId) { - PerfCounterFlagsLinux::perfmonLoadConfigCalled++; - (*gpCfgId)++; - return 0; -} - -TEST_P(PerformanceCountersLinuxGetPerfmonConfigTest, givenPassingPerfmonLoadConfigFuncWhenGetPerfmonConfigIsCalledThenReturnsTrueIfDoesntChangeOaHandle) { - bool changingOaHandle; - bool isZeroValue; - InstrPmRegsCfg config; - std::tie(changingOaHandle, isZeroValue) = GetParam(); - - if (changingOaHandle) { - performanceCountersLinux->setPerfmonLoadConfigFunc(perfmonLoadConfigChangingOa); - } - if (isZeroValue) { - config.OaCounters.Handle = 0; - } else { - config.OaCounters.Handle = 1; - } - auto retVal = performanceCountersLinux->getPerfmonConfig(&config); - EXPECT_EQ(1, PerfCounterFlagsLinux::perfmonLoadConfigCalled); - if (!isZeroValue && changingOaHandle) { - EXPECT_FALSE(retVal); - } else { - EXPECT_TRUE(retVal); - } -} - -TEST_P(PerformanceCountersLinuxGetPerfmonConfigTest, givenPassingPerfmonLoadConfigFuncWhenGetPerfmonConfigIsCalledThenReturnsTrueIfDoesntChangeGpHandle) { - bool changingGpHandle; - bool isZeroValue; - InstrPmRegsCfg config; - std::tie(changingGpHandle, isZeroValue) = GetParam(); - - if (changingGpHandle) { - performanceCountersLinux->setPerfmonLoadConfigFunc(perfmonLoadConfigChangingGp); - } - if (isZeroValue) { - config.GpCounters.Handle = 0; - } else { - config.GpCounters.Handle = 1; - } - auto retVal = performanceCountersLinux->getPerfmonConfig(&config); - EXPECT_EQ(1, PerfCounterFlagsLinux::perfmonLoadConfigCalled); - if (!isZeroValue && changingGpHandle) { - EXPECT_FALSE(retVal); - } else { - EXPECT_TRUE(retVal); - } -} - -INSTANTIATE_TEST_CASE_P( - PerfCountersTests, - PerformanceCountersLinuxGetPerfmonConfigTest, - testing::Combine( - testing::Bool(), - testing::Bool())); - -TEST_F(PerformanceCountersLinuxTest, givenPerfCountersWithHwContextEqualsZeroWhenGetCurrentReportIdsIsCalledManyTimesThenReturnProperNumber) { - unsigned int retVal; - createPerfCounters(); - retVal = performanceCountersBase->getCurrentReportId(); - EXPECT_EQ(0x00000u, osInterfaceBase->getHwContextId()); - EXPECT_EQ(0x00000001u, retVal); -} diff --git a/unit_tests/os_interface/mock_performance_counters.cpp b/unit_tests/os_interface/mock_performance_counters.cpp index 2e69e29da5..f9798db49f 100644 --- a/unit_tests/os_interface/mock_performance_counters.cpp +++ b/unit_tests/os_interface/mock_performance_counters.cpp @@ -7,141 +7,371 @@ #include "mock_performance_counters.h" -#include "runtime/os_interface/os_interface.h" +using namespace MetricsLibraryApi; namespace NEO { -MockPerformanceCounters::MockPerformanceCounters(OSTime *osTime) - : PerformanceCounters(osTime) { - autoSamplingStartFunc = autoSamplingStart; - autoSamplingStopFunc = autoSamplingStop; - hwMetricsEnableFunc = hwMetricsEnableFuncPassing; - getPmRegsCfgFunc = getPmRegsCfgPassing; - loadPmRegsCfgFunc = loadPmRegsCfgPassing; - checkPmRegsCfgFunc = checkPmRegsCfgPassing; - setPmRegsCfgFunc = setPmRegsCfgFuncPassing; - sendReadRegsCfgFunc = sendReadRegsCfgFuncPassing; - getPerfCountersQueryDataFunc = getPerfCountersQueryData; - PerfCounterFlags::resetPerfCountersFlags(); -} -void MockPerformanceCounters::initialize(const HardwareInfo *hwInfo) { - PerfCounterFlags::initalizeCalled++; -} - -int PerfCounterFlags::autoSamplingFuncCalled; -int PerfCounterFlags::autoSamplingStarted; -int PerfCounterFlags::autoSamplingStopped; -int PerfCounterFlags::checkPmRegsCfgCalled; -int PerfCounterFlags::escHwMetricsCalled; -int PerfCounterFlags::getPerfCountersQueryDataCalled; -int PerfCounterFlags::getPmRegsCfgCalled; -int PerfCounterFlags::hwMetricsEnableStatus; -int PerfCounterFlags::initalizeCalled; -int PerfCounterFlags::loadPmRegsCfgCalled; -int PerfCounterFlags::setPmRegsCfgCalled; -int PerfCounterFlags::sendReadRegsCfgCalled; - -bool hwMetricsEnableFuncFailing(InstrEscCbData cbData, bool enable) { - PerfCounterFlags::escHwMetricsCalled++; - PerfCounterFlags::hwMetricsEnableStatus = enable; - return false; -} -bool hwMetricsEnableFuncPassing(InstrEscCbData cbData, bool enable) { - PerfCounterFlags::escHwMetricsCalled++; - PerfCounterFlags::hwMetricsEnableStatus = enable; - return true; -} -bool autoSamplingStart(InstrEscCbData cbData, void **ppOAInterface) { - PerfCounterFlags::autoSamplingFuncCalled++; - PerfCounterFlags::autoSamplingStarted++; - ppOAInterface[0] = new char[1]; - return true; -} -bool autoSamplingStartFailing(InstrEscCbData cbData, void **ppOAInterface) { - PerfCounterFlags::autoSamplingFuncCalled++; - PerfCounterFlags::autoSamplingStarted++; - ppOAInterface[0] = nullptr; - return false; -} -bool autoSamplingStop(void **ppOAInterface) { - PerfCounterFlags::autoSamplingFuncCalled++; - PerfCounterFlags::autoSamplingStopped++; - if (ppOAInterface[0]) { - delete[] static_cast(ppOAInterface[0]); - ppOAInterface[0] = nullptr; +////////////////////////////////////////////////////// +// MockMetricsLibrary::open +////////////////////////////////////////////////////// +bool MockMetricsLibrary::open() { + if (validOpen) { + ++openCount; return true; + } else { + return false; } - return false; } -bool getPmRegsCfgPassing(InstrEscCbData cbData, uint32_t cfgId, InstrPmRegsCfg *pCfg, InstrAutoSamplingMode *pAutoSampling) { - PerfCounterFlags::getPmRegsCfgCalled++; - if (cfgId == 1) { - pCfg->ReadRegs.RegsCount = 2; - pCfg->ReadRegs.Reg[0].BitSize = 32; - pCfg->ReadRegs.Reg[1].BitSize = 64; + +////////////////////////////////////////////////////// +// MockMetricsLibrary::contextCreate +////////////////////////////////////////////////////// +bool MockMetricsLibrary::contextCreate(const ClientType_1_0 &client, ClientData_1_0 &clientData, ContextCreateData_1_0 &createData, ContextHandle_1_0 &handle) { + if (client.Api != MetricsLibraryApi::ClientApi::OpenCL) { + return false; } + + handle.data = reinterpret_cast(this); + ++contextCount; return true; } -bool getPmRegsCfgFailing(InstrEscCbData cbData, uint32_t cfgId, InstrPmRegsCfg *pCfg, InstrAutoSamplingMode *pAutoSampling) { - PerfCounterFlags::getPmRegsCfgCalled++; - return false; -} -bool checkPmRegsCfgPassing(InstrPmRegsCfg *pQueryPmRegsCfg, uint32_t *pLastPmRegsCfgHandle, const void *pASInterface) { - PerfCounterFlags::checkPmRegsCfgCalled++; - return true; -} -bool checkPmRegsCfgFailing(InstrPmRegsCfg *pQueryPmRegsCfg, uint32_t *pLastPmRegsCfgHandle, const void *pASInterface) { - PerfCounterFlags::checkPmRegsCfgCalled++; - return false; -} -bool loadPmRegsCfgPassing(InstrEscCbData cbData, InstrPmRegsCfg *pCfg, bool hardwareAccess) { - PerfCounterFlags::loadPmRegsCfgCalled++; - return true; -} -bool loadPmRegsCfgFailing(InstrEscCbData cbData, InstrPmRegsCfg *pCfg, bool hardwareAccess) { - PerfCounterFlags::loadPmRegsCfgCalled++; - return false; -} -bool setPmRegsCfgFuncPassing(InstrEscCbData cbData, uint32_t count, uint32_t *pOffsets, uint32_t *pValues) { - PerfCounterFlags::setPmRegsCfgCalled++; +////////////////////////////////////////////////////// +// MockMetricsLibrary::contextDelete +////////////////////////////////////////////////////// +bool MockMetricsLibrary::contextDelete(const ContextHandle_1_0 &handle) { + if (!handle.IsValid()) { + return false; + } + + --contextCount; return true; } -bool setPmRegsCfgFuncFailing(InstrEscCbData cbData, uint32_t count, uint32_t *pOffsets, uint32_t *pValues) { - PerfCounterFlags::setPmRegsCfgCalled++; - return false; -} -bool sendReadRegsCfgFuncPassing(InstrEscCbData cbData, uint32_t count, uint32_t *pOffsets, uint32_t *pBitSizes) { - PerfCounterFlags::sendReadRegsCfgCalled++; + +////////////////////////////////////////////////////// +// MockMetricsLibrary::hwCountersCreate +////////////////////////////////////////////////////// +bool MockMetricsLibrary::hwCountersCreate(const ContextHandle_1_0 &context, const uint32_t slots, const ConfigurationHandle_1_0 mmio, QueryHandle_1_0 &handle) { + ++queryCount; + return true; +}; + +////////////////////////////////////////////////////// +// MockMetricsLibrary::hwCountersDelete +////////////////////////////////////////////////////// +bool MockMetricsLibrary::hwCountersDelete(const QueryHandle_1_0 &handle) { + --queryCount; return true; } -bool sendReadRegsCfgFuncFailing(InstrEscCbData cbData, uint32_t count, uint32_t *pOffsets, uint32_t *pBitSizes) { - PerfCounterFlags::sendReadRegsCfgCalled++; - return false; + +////////////////////////////////////////////////////// +// MockMetricsLibrary::hwCountersGetReport +////////////////////////////////////////////////////// +bool MockMetricsLibrary::hwCountersGetReport(const QueryHandle_1_0 &handle, const uint32_t slot, const uint32_t slotsCount, const uint32_t dataSize, void *data) { + return validGetData; } -template -void getPerfCountersQueryData(InstrEscCbData cbData, GTDI_QUERY *pData, HwPerfCountersLayout *pLayout, uint64_t cpuRawTimestamp, void *pASInterface, InstrPmRegsCfg *pPmRegsCfg, bool useMiRPC, bool resetASData, const InstrAllowedContexts *pAllowedContexts) { - PerfCounterFlags::getPerfCountersQueryDataCalled++; +////////////////////////////////////////////////////// +// MockMetricsLibrary::hwCountersGetApiReportSize +////////////////////////////////////////////////////// +uint32_t MockMetricsLibrary::hwCountersGetApiReportSize() { + return 1; } -void PerfCounterFlags::resetPerfCountersFlags() { - PerfCounterFlags::autoSamplingFuncCalled = 0; - PerfCounterFlags::autoSamplingStarted = 0; - PerfCounterFlags::autoSamplingStopped = 0; - PerfCounterFlags::checkPmRegsCfgCalled = 0; - PerfCounterFlags::escHwMetricsCalled = 0; - PerfCounterFlags::getPerfCountersQueryDataCalled = 0; - PerfCounterFlags::getPmRegsCfgCalled = 0; - PerfCounterFlags::hwMetricsEnableStatus = 0; - PerfCounterFlags::initalizeCalled = 0; - PerfCounterFlags::loadPmRegsCfgCalled = 0; - PerfCounterFlags::setPmRegsCfgCalled = 0; - PerfCounterFlags::sendReadRegsCfgCalled = 0; +////////////////////////////////////////////////////// +// MockMetricsLibrary::hwCountersGetGpuReportSize +////////////////////////////////////////////////////// +uint32_t MockMetricsLibrary::hwCountersGetGpuReportSize() { + return sizeof(HwPerfCounter); } -void PerformanceCountersFixture::SetUp() { - osInterfaceBase = std::unique_ptr(new OSInterface()); - createOsTime(); - fillOsInterface(); - PerfCounterFlags::resetPerfCountersFlags(); + +////////////////////////////////////////////////////// +// MockMetricsLibrary::commandBufferGet +////////////////////////////////////////////////////// +bool MockMetricsLibrary::commandBufferGet(CommandBufferData_1_0 &data) { + MI_REPORT_PERF_COUNT mirpc = {}; + mirpc.init(); + DEBUG_BREAK_IF(data.Data == nullptr); + memcpy(data.Data, &mirpc, sizeof(mirpc)); + return true; +} + +////////////////////////////////////////////////////// +// MockMetricsLibrary::commandBufferGetSize +////////////////////////////////////////////////////// +bool MockMetricsLibrary::commandBufferGetSize(const CommandBufferData_1_0 &commandBufferData, CommandBufferSize_1_0 &commandBufferSize) { + commandBufferSize.GpuMemorySize = sizeof(MI_REPORT_PERF_COUNT); + return true; +} + +////////////////////////////////////////////////////// +// MockMetricsLibrary::getProcAddress +////////////////////////////////////////////////////// +void *MockMetricsLibraryDll::getProcAddress(const std::string &procName) { + if (procName == METRICS_LIBRARY_CONTEXT_CREATE_1_0) { + return validContextCreate + ? reinterpret_cast(&MockMetricsLibraryValidInterface::ContextCreate) + : nullptr; + } else if (procName == METRICS_LIBRARY_CONTEXT_DELETE_1_0) { + return validContextDelete + ? reinterpret_cast(&MockMetricsLibraryValidInterface::ContextDelete) + : nullptr; + } else { + return nullptr; + } +} + +////////////////////////////////////////////////////// +// MockMetricsLibrary::isLoaded +////////////////////////////////////////////////////// +bool MockMetricsLibraryDll::isLoaded() { + return validIsLoaded; +} + +////////////////////////////////////////////////////// +// MockMetricsLibraryValidInterface::ContextCreate +////////////////////////////////////////////////////// +StatusCode MockMetricsLibraryValidInterface::ContextCreate(ClientType_1_0 clientType, ContextCreateData_1_0 *createData, ContextHandle_1_0 *handle) { + + // Validate input. + EXPECT_EQ(clientType.Api, ClientApi::OpenCL); + + // Library handle. + auto library = new MockMetricsLibraryValidInterface(); + handle->data = library; + EXPECT_TRUE(handle->IsValid()); + + // Context count. + library->contextCount++; + EXPECT_EQ(library->contextCount, 1u); + + return handle->IsValid() + ? StatusCode::Success + : StatusCode::Failed; +} + +////////////////////////////////////////////////////// +// MockMetricsLibraryValidInterface::ContextDelete +////////////////////////////////////////////////////// +StatusCode MockMetricsLibraryValidInterface::ContextDelete(const ContextHandle_1_0 handle) { + + auto validHandle = handle.IsValid(); + auto library = static_cast(handle.data); + + // Validate input. + EXPECT_TRUE(validHandle); + EXPECT_TRUE(validHandle); + EXPECT_EQ(--library->contextCount, 0u); + + // Delete handle. + delete library; + + return validHandle + ? StatusCode::Success + : StatusCode::IncorrectObject; +} + +////////////////////////////////////////////////////// +// MockMetricsLibraryInterface::QueryCreate +////////////////////////////////////////////////////// +StatusCode MockMetricsLibraryValidInterface::QueryCreate(const QueryCreateData_1_0 *createData, QueryHandle_1_0 *handle) { + + EXPECT_NE(handle, nullptr); + EXPECT_NE(createData, nullptr); + EXPECT_GE(createData->Slots, 1u); + EXPECT_TRUE(createData->HandleContext.IsValid()); + EXPECT_EQ(createData->Type, ObjectType::QueryHwCounters); + + handle->data = new uint32_t(0); + return StatusCode::Success; +} + +////////////////////////////////////////////////////// +// MockMetricsLibraryValidInterface::QueryDelete +////////////////////////////////////////////////////// +StatusCode MockMetricsLibraryValidInterface::QueryDelete(const QueryHandle_1_0 handle) { + EXPECT_TRUE(handle.IsValid()); + delete (uint32_t *)handle.data; + return StatusCode::Success; +} + +////////////////////////////////////////////////////// +// MockMetricsLibraryValidInterface::CommandBufferGetSize +////////////////////////////////////////////////////// +StatusCode MockMetricsLibraryValidInterface::CommandBufferGetSize(const CommandBufferData_1_0 *data, CommandBufferSize_1_0 *size) { + auto library = static_cast(data->HandleContext.data); + EXPECT_NE(data, nullptr); + EXPECT_TRUE(data->HandleContext.IsValid()); + EXPECT_TRUE(data->QueryHwCounters.Handle.IsValid()); + EXPECT_EQ(data->Type, GpuCommandBufferType::Render); + EXPECT_EQ(data->CommandsType, ObjectType::QueryHwCounters); + EXPECT_NE(size, nullptr); + + size->GpuMemorySize = library->validGpuReportSize + ? 123 + : 0; + return library->validGpuReportSize + ? StatusCode::Success + : StatusCode::Failed; +} + +////////////////////////////////////////////////////// +// MockMetricsLibraryValidInterface::CommandBufferGet +////////////////////////////////////////////////////// +StatusCode MockMetricsLibraryValidInterface::CommandBufferGet(const CommandBufferData_1_0 *data) { + EXPECT_NE(data, nullptr); + EXPECT_TRUE(data->HandleContext.IsValid()); + EXPECT_TRUE(data->QueryHwCounters.Handle.IsValid()); + EXPECT_EQ(data->Type, GpuCommandBufferType::Render); + EXPECT_EQ(data->CommandsType, ObjectType::QueryHwCounters); + EXPECT_NE(data->Data, nullptr); + EXPECT_GT(data->Size, 0u); + return StatusCode::Success; +} + +////////////////////////////////////////////////////// +// MockMetricsLibraryValidInterface::CommandBufferGet +////////////////////////////////////////////////////// +StatusCode MockMetricsLibraryValidInterface::GetParameter(const ParameterType parameter, ValueType *type, TypedValue_1_0 *value) { + EXPECT_NE(type, nullptr); + EXPECT_NE(value, nullptr); + switch (parameter) { + case ParameterType::QueryHwCountersReportApiSize: + *type = ValueType::Uint32; + value->ValueUInt32 = 123; + break; + case ParameterType::QueryHwCountersReportGpuSize: + *type = ValueType::Uint32; + value->ValueUInt32 = 123; + break; + default: + EXPECT_TRUE(false); + break; + } + return StatusCode::Success; +} + +////////////////////////////////////////////////////// +// MockMetricsLibraryValidInterface::ConfigurationCreate +////////////////////////////////////////////////////// +StatusCode ML_STDCALL MockMetricsLibraryValidInterface::ConfigurationCreate(const ConfigurationCreateData_1_0 *createData, ConfigurationHandle_1_0 *handle) { + EXPECT_NE(createData, nullptr); + EXPECT_NE(handle, nullptr); + EXPECT_TRUE(createData->HandleContext.IsValid()); + + const bool validType = (createData->Type == ObjectType::ConfigurationHwCountersOa) || + (createData->Type == ObjectType::ConfigurationHwCountersUser); + + // Mock overrides + auto api = static_cast(createData->HandleContext.data); + if (!api->validCreateConfigurationOa && (createData->Type == ObjectType::ConfigurationHwCountersOa)) { + return StatusCode::Failed; + } + + if (!api->validCreateConfigurationUser && (createData->Type == ObjectType::ConfigurationHwCountersUser)) { + return StatusCode::Failed; + } + + EXPECT_TRUE(validType); + + handle->data = api; + return StatusCode::Success; +} + +////////////////////////////////////////////////////// +// MockMetricsLibraryValidInterface::ConfigurationActivate +////////////////////////////////////////////////////// +StatusCode ML_STDCALL MockMetricsLibraryValidInterface::ConfigurationActivate(const ConfigurationHandle_1_0 handle, const ConfigurationActivateData_1_0 *activateData) { + auto api = static_cast(handle.data); + return api->validActivateConfigurationOa + ? StatusCode::Success + : StatusCode::Failed; +} + +////////////////////////////////////////////////////// +// MockMetricsLibraryValidInterface::ConfigurationDelete +////////////////////////////////////////////////////// +StatusCode ML_STDCALL MockMetricsLibraryValidInterface::ConfigurationDelete(const ConfigurationHandle_1_0 handle) { + EXPECT_TRUE(handle.IsValid()); + + return StatusCode::Success; +} + +////////////////////////////////////////////////////// +// MockMetricsLibraryValidInterface::GetData +////////////////////////////////////////////////////// +StatusCode MockMetricsLibraryValidInterface::GetData(GetReportData_1_0 *data) { + EXPECT_NE(data, nullptr); + EXPECT_EQ(data->Type, ObjectType::QueryHwCounters); + EXPECT_TRUE(data->Query.Handle.IsValid()); + EXPECT_GE(data->Query.Slot, 0u); + EXPECT_GT(data->Query.SlotsCount, 0u); + EXPECT_NE(data->Query.Data, nullptr); + EXPECT_GT(data->Query.DataSize, 0u); + return StatusCode::Success; +} + +////////////////////////////////////////////////////// +// PerformanceCountersDeviceFixture::SetUp +////////////////////////////////////////////////////// +void PerformanceCountersDeviceFixture::SetUp() { + createFunc = Device::createPerformanceCountersFunc; + Device::createPerformanceCountersFunc = MockPerformanceCounters::create; +} + +////////////////////////////////////////////////////// +// PerformanceCountersDeviceFixture::TearDown +////////////////////////////////////////////////////// +void PerformanceCountersDeviceFixture::TearDown() { + Device::createPerformanceCountersFunc = createFunc; +} + +////////////////////////////////////////////////////// +// PerformanceCountersMetricsLibraryFixture::SetUp +////////////////////////////////////////////////////// +void PerformanceCountersMetricsLibraryFixture::SetUp() { + PerformanceCountersFixture::SetUp(); +} + +////////////////////////////////////////////////////// +// PerformanceCountersMetricsLibraryFixture::TearDown +////////////////////////////////////////////////////// +void PerformanceCountersMetricsLibraryFixture::TearDown() { + device->setPerfCounters(nullptr); + PerformanceCountersFixture::TearDown(); +} + +////////////////////////////////////////////////////// +// PerformanceCountersMetricsLibraryFixture::createPerformanceCounters +////////////////////////////////////////////////////// +void PerformanceCountersMetricsLibraryFixture::createPerformanceCounters(const bool validMetricsLibraryApi, const bool mockMetricsLibrary) { + performanceCountersBase = MockPerformanceCounters::create(device.get()); + auto metricsLibraryInterface = performanceCountersBase->getMetricsLibraryInterface(); + auto metricsLibraryDll = std::make_unique(); + EXPECT_NE(performanceCountersBase, nullptr); + EXPECT_NE(metricsLibraryInterface, nullptr); + + device->setPerfCounters(performanceCountersBase.get()); + + // Attached mock version of metrics library interface. + if (mockMetricsLibrary) { + performanceCountersBase->setMetricsLibraryInterface(std::make_unique()); + metricsLibraryInterface = performanceCountersBase->getMetricsLibraryInterface(); + } else { + performanceCountersBase->setMetricsLibraryInterface(std::make_unique()); + metricsLibraryInterface = performanceCountersBase->getMetricsLibraryInterface(); + } + + if (validMetricsLibraryApi) { + metricsLibraryInterface->api = std::make_unique(); + metricsLibraryInterface->osLibrary = std::move(metricsLibraryDll); + } else { + metricsLibraryDll->validContextCreate = false; + metricsLibraryDll->validContextDelete = false; + metricsLibraryDll->validIsLoaded = false; + metricsLibraryInterface->api = std::make_unique(); + metricsLibraryInterface->osLibrary = std::move(metricsLibraryDll); + } + + EXPECT_NE(metricsLibraryInterface->api, nullptr); } } // namespace NEO diff --git a/unit_tests/os_interface/mock_performance_counters.h b/unit_tests/os_interface/mock_performance_counters.h index 7420705b92..fc207f7d80 100644 --- a/unit_tests/os_interface/mock_performance_counters.h +++ b/unit_tests/os_interface/mock_performance_counters.h @@ -9,141 +9,238 @@ #include "runtime/device/device.h" #include "runtime/memory_manager/os_agnostic_memory_manager.h" #include "unit_tests/libult/create_command_stream.h" +#include "unit_tests/mocks/mock_command_queue.h" +#include "unit_tests/mocks/mock_context.h" +#include "unit_tests/mocks/mock_device.h" + +#include "instrumentation.h" namespace NEO { -class OSInterface; -bool hwMetricsEnableFuncPassing(InstrEscCbData cbData, bool enable); -bool hwMetricsEnableFuncFailing(InstrEscCbData cbData, bool enable); -bool autoSamplingStart(InstrEscCbData cbData, void **ppOAInterface); -bool autoSamplingStartFailing(InstrEscCbData cbData, void **ppOAInterface); -bool autoSamplingStop(void **ppOAInterface); -bool getPmRegsCfgPassing(InstrEscCbData cbData, uint32_t cfgId, InstrPmRegsCfg *pCfg, InstrAutoSamplingMode *pAutoSampling); -bool getPmRegsCfgFailing(InstrEscCbData cbData, uint32_t cfgId, InstrPmRegsCfg *pCfg, InstrAutoSamplingMode *pAutoSampling); -bool checkPmRegsCfgPassing(InstrPmRegsCfg *pQueryPmRegsCfg, uint32_t *pLastPmRegsCfgHandle, const void *pASInterface); -bool checkPmRegsCfgFailing(InstrPmRegsCfg *pQueryPmRegsCfg, uint32_t *pLastPmRegsCfgHandle, const void *pASInterface); -bool loadPmRegsCfgPassing(InstrEscCbData cbData, InstrPmRegsCfg *pCfg, bool hardwareAccess); -bool loadPmRegsCfgFailing(InstrEscCbData cbData, InstrPmRegsCfg *pCfg, bool hardwareAccess); -template -void getPerfCountersQueryData(InstrEscCbData cbData, GTDI_QUERY *pData, HwPerfCountersLayout *pLayout, uint64_t cpuRawTimestamp, void *pASInterface, InstrPmRegsCfg *pPmRegsCfg, bool useMiRPC, bool resetASData = false, const InstrAllowedContexts *pAllowedContexts = NULL); -bool setPmRegsCfgFuncPassing(InstrEscCbData cbData, uint32_t count, uint32_t *pOffsets, uint32_t *pValues); -bool setPmRegsCfgFuncFailing(InstrEscCbData cbData, uint32_t count, uint32_t *pOffsets, uint32_t *pValues); -bool sendReadRegsCfgFuncPassing(InstrEscCbData cbData, uint32_t count, uint32_t *pOffsets, uint32_t *pBitSizes); -bool sendReadRegsCfgFuncFailing(InstrEscCbData cbData, uint32_t count, uint32_t *pOffsets, uint32_t *pBitSizes); +////////////////////////////////////////////////////// +// Metrics Library types +////////////////////////////////////////////////////// +using MetricsLibraryApi::ClientApi; +using MetricsLibraryApi::ClientData_1_0; +using MetricsLibraryApi::ClientGen; +using MetricsLibraryApi::ClientType_1_0; +using MetricsLibraryApi::CommandBufferData_1_0; +using MetricsLibraryApi::CommandBufferSize_1_0; +using MetricsLibraryApi::ConfigurationHandle_1_0; +using MetricsLibraryApi::ContextCreateData_1_0; +using MetricsLibraryApi::ContextHandle_1_0; +using MetricsLibraryApi::GpuMemory_1_0; +using MetricsLibraryApi::QueryHandle_1_0; -class PerfCounterFlags { - public: - static int autoSamplingStarted; - static int autoSamplingStopped; - static int autoSamplingFuncCalled; - static int checkPmRegsCfgCalled; - static int escHwMetricsCalled; - static int getPerfCountersQueryDataCalled; - static int getPmRegsCfgCalled; - static int hwMetricsEnableStatus; - static int initalizeCalled; - static int loadPmRegsCfgCalled; - static int setPmRegsCfgCalled; - static int sendReadRegsCfgCalled; - static void resetPerfCountersFlags(); -}; +////////////////////////////////////////////////////// +// MI_REPORT_PERF_COUNT definition for all GENs +////////////////////////////////////////////////////// +struct MI_REPORT_PERF_COUNT { + uint32_t DwordLength : BITFIELD_RANGE(0, 5); + uint32_t Reserved_6 : BITFIELD_RANGE(6, 22); + uint32_t MiCommandOpcode : BITFIELD_RANGE(23, 28); + uint32_t CommandType : BITFIELD_RANGE(29, 31); + uint64_t UseGlobalGtt : BITFIELD_RANGE(0, 0); + uint64_t Reserved_33 : BITFIELD_RANGE(1, 3); + uint64_t CoreModeEnable : BITFIELD_RANGE(4, 4); + uint64_t Reserved_37 : BITFIELD_RANGE(5, 5); + uint64_t MemoryAddress : BITFIELD_RANGE(6, 63); + uint32_t ReportId; -class MockPerformanceCounters : virtual public PerformanceCounters { - public: - MockPerformanceCounters(OSTime *osTime); - static std::unique_ptr create(OSTime *osTime); + typedef enum tagDWORD_LENGTH { + DWORD_LENGTH_EXCLUDES_DWORD_0_1 = 0x2, + } DWORD_LENGTH; - void initialize(const HardwareInfo *hwInfo) override; + typedef enum tagMI_COMMAND_OPCODE { + MI_COMMAND_OPCODE_MI_REPORT_PERF_COUNT = 0x28, + } MI_COMMAND_OPCODE; - void setEscHwMetricsFunc(decltype(hwMetricsEnableFunc) func) { - hwMetricsEnableFunc = func; - } - void setAutoSamplingStartFunc(decltype(autoSamplingStartFunc) func) { - autoSamplingStartFunc = func; - } - void setGetPmRegsCfgFunc(decltype(getPmRegsCfgFunc) func) { - getPmRegsCfgFunc = func; - } - void setCheckPmRegsCfgFunc(decltype(checkPmRegsCfgFunc) func) { - checkPmRegsCfgFunc = func; - } - void setLoadPmRegsCfgFunc(decltype(loadPmRegsCfgFunc) func) { - loadPmRegsCfgFunc = func; - } - void setSetPmRegsCfgFunc(decltype(setPmRegsCfgFunc) func) { - setPmRegsCfgFunc = func; - } - void setSendReadRegsCfgFunc(decltype(sendReadRegsCfgFunc) func) { - sendReadRegsCfgFunc = func; - } - uint64_t getCpuRawTimestamp() const { - return cpuRawTimestamp; - } - void setAsIface(void *asIface) { - pAutoSamplingInterface = asIface; - } - void setGfxFamily(GFXCORE_FAMILY family) { - gfxFamily = family; - } - uint32_t getReportId() override { - return PerformanceCounters::getReportId(); - } - void setAvailableFlag(bool value) { - available = value; - } - GFXCORE_FAMILY getGfxFamily() { - return gfxFamily; - } - InstrEscCbData getCbData() { - return cbData; - } - bool getHwMetricsEnabled() { - return hwMetricsEnabled; - } - bool getUseMIRPC() { - return useMIRPC; - } - void *getPAutoSamplingInterface() { - return pAutoSamplingInterface; - } - uint64_t getCpuRawTimestamp() { - return cpuRawTimestamp; - } - bool getAvailable() { - return available; + typedef enum tagCOMMAND_TYPE { + COMMAND_TYPE_MI_COMMAND = 0x0, + } COMMAND_TYPE; + + inline void init(void) { + memset(this, 0, sizeof(MI_REPORT_PERF_COUNT)); + DwordLength = DWORD_LENGTH_EXCLUDES_DWORD_0_1; + MiCommandOpcode = MI_COMMAND_OPCODE_MI_REPORT_PERF_COUNT; + CommandType = COMMAND_TYPE_MI_COMMAND; } }; +// clang-format off +////////////////////////////////////////////////////// +// MockMetricsLibrary +////////////////////////////////////////////////////// +class MockMetricsLibrary : public MetricsLibrary { + public: + uint32_t openCount = 0; + uint32_t contextCount = 0; + uint32_t queryCount = 0; + bool validOpen = true; + bool validGetData = true; + + // Library open / close functions. + bool open() override; + + // Context create / destroy functions. + bool contextCreate (const ClientType_1_0 &client, ClientData_1_0& clientData, ContextCreateData_1_0 &createData, ContextHandle_1_0 &handle) override; + bool contextDelete (const ContextHandle_1_0 &handle) override; + + // HwCounters functions. + bool hwCountersCreate (const ContextHandle_1_0 &context, const uint32_t slots, const ConfigurationHandle_1_0 mmio, QueryHandle_1_0 &handle) override; + bool hwCountersDelete (const QueryHandle_1_0 &handle) override; + bool hwCountersGetReport (const QueryHandle_1_0 &handle, const uint32_t slot, const uint32_t slotsCount, const uint32_t dataSize, void *data) override; + uint32_t hwCountersGetApiReportSize() override; + uint32_t hwCountersGetGpuReportSize() override; + + // Command buffer functions. + bool commandBufferGet (CommandBufferData_1_0 &data) override; + bool commandBufferGetSize (const CommandBufferData_1_0 &commandBufferData, CommandBufferSize_1_0 &commandBufferSize) override; + + // Oa configuration functions. + bool oaConfigurationCreate (const ContextHandle_1_0 &context, ConfigurationHandle_1_0 &handle) override { return true; } + bool oaConfigurationDelete (const ConfigurationHandle_1_0 &handle) override { return true; } + bool oaConfigurationActivate (const ConfigurationHandle_1_0 &handle) override { return true; } + bool oaConfigurationDeactivate (const ConfigurationHandle_1_0 &handle) override { return true; } + + // User mmio configuration functions. + bool userConfigurationCreate (const ContextHandle_1_0 &context, ConfigurationHandle_1_0 &handle) override { return true; } + bool userConfigurationDelete (const ConfigurationHandle_1_0 &handle) override { return true; } +}; + +////////////////////////////////////////////////////// +// MockMetricsLibraryValidInterface +////////////////////////////////////////////////////// +class MockMetricsLibraryValidInterface: public MetricsLibraryInterface { + public: + uint32_t contextCount = 0; + bool validCreateConfigurationOa = true; + bool validCreateConfigurationUser = true; + bool validActivateConfigurationOa = true; + bool validGpuReportSize = true; + + static StatusCode ML_STDCALL ContextCreate ( ClientType_1_0 clientType, ContextCreateData_1_0* createData, ContextHandle_1_0* handle ); + static StatusCode ML_STDCALL ContextDelete (const ContextHandle_1_0 handle); + static StatusCode ML_STDCALL GetParameter (const ParameterType parameter, ValueType *type, TypedValue_1_0 *value); + static StatusCode ML_STDCALL CommandBufferGet (const CommandBufferData_1_0 *data); + static StatusCode ML_STDCALL CommandBufferGetSize (const CommandBufferData_1_0 *data, CommandBufferSize_1_0 *size); + static StatusCode ML_STDCALL QueryCreate (const QueryCreateData_1_0 *createData, QueryHandle_1_0 *handle); + static StatusCode ML_STDCALL QueryDelete (const QueryHandle_1_0 handle); + static StatusCode ML_STDCALL ConfigurationCreate (const ConfigurationCreateData_1_0 *createData, ConfigurationHandle_1_0 *handle); + static StatusCode ML_STDCALL ConfigurationActivate (const ConfigurationHandle_1_0 handle, const ConfigurationActivateData_1_0 *activateData); + static StatusCode ML_STDCALL ConfigurationDeactivate (const ConfigurationHandle_1_0 handle) { return StatusCode::Success; } + static StatusCode ML_STDCALL ConfigurationDelete (const ConfigurationHandle_1_0 handle); + static StatusCode ML_STDCALL GetData (GetReportData_1_0 *data); + + MockMetricsLibraryValidInterface() + { + contextCreate = &ContextCreate; + contextDelete = &ContextDelete; + functions.GetParameter = &GetParameter; + functions.CommandBufferGet = &CommandBufferGet; + functions.CommandBufferGetSize = &CommandBufferGetSize; + functions.QueryCreate = &QueryCreate; + functions.QueryDelete = &QueryDelete; + functions.ConfigurationCreate = &ConfigurationCreate; + functions.ConfigurationActivate = &ConfigurationActivate; + functions.ConfigurationDeactivate = &ConfigurationDeactivate; + functions.ConfigurationDelete = &ConfigurationDelete; + functions.GetData = &GetData; + } +}; + +////////////////////////////////////////////////////// +// MockMetricsLibraryInvalidInterface +////////////////////////////////////////////////////// +class MockMetricsLibraryInvalidInterface: public MetricsLibraryInterface { + public: + static StatusCode ML_STDCALL ContextCreate ( ClientType_1_0 clientType, ContextCreateData_1_0* createData, ContextHandle_1_0* handle ){ return StatusCode::Failed;} + static StatusCode ML_STDCALL ContextDelete (const ContextHandle_1_0 handle){ return StatusCode::Failed;} + static StatusCode ML_STDCALL GetParameter (const ParameterType parameter, ValueType *type, TypedValue_1_0 *value){ return StatusCode::Failed;} + static StatusCode ML_STDCALL CommandBufferGet (const CommandBufferData_1_0 *data){ return StatusCode::Failed;} + static StatusCode ML_STDCALL CommandBufferGetSize (const CommandBufferData_1_0 *data, CommandBufferSize_1_0 *size){ return StatusCode::Failed;} + static StatusCode ML_STDCALL QueryCreate (const QueryCreateData_1_0 *createData, QueryHandle_1_0 *handle){ return StatusCode::Failed;} + static StatusCode ML_STDCALL QueryDelete (const QueryHandle_1_0 handle){ return StatusCode::Failed;} + static StatusCode ML_STDCALL ConfigurationCreate (const ConfigurationCreateData_1_0 *createData, ConfigurationHandle_1_0 *handle){ return StatusCode::Failed;} + static StatusCode ML_STDCALL ConfigurationActivate (const ConfigurationHandle_1_0 handle, const ConfigurationActivateData_1_0 *activateData){ return StatusCode::Failed;} + static StatusCode ML_STDCALL ConfigurationDeactivate (const ConfigurationHandle_1_0 handle){ return StatusCode::Failed;} + static StatusCode ML_STDCALL ConfigurationDelete (const ConfigurationHandle_1_0 handle){ return StatusCode::Failed;} + static StatusCode ML_STDCALL GetData (GetReportData_1_0 *data){ return StatusCode::Failed;} + + MockMetricsLibraryInvalidInterface() + { + contextCreate = &ContextCreate; + contextDelete = &ContextDelete; + functions.GetParameter = &GetParameter; + functions.CommandBufferGet = &CommandBufferGet; + functions.CommandBufferGetSize = &CommandBufferGetSize; + functions.QueryCreate = &QueryCreate; + functions.QueryDelete = &QueryDelete; + functions.ConfigurationCreate = &ConfigurationCreate; + functions.ConfigurationActivate = &ConfigurationActivate; + functions.ConfigurationDeactivate = &ConfigurationDeactivate; + functions.ConfigurationDelete = &ConfigurationDelete; + functions.GetData = &GetData; + } +}; +// clang-format on + +////////////////////////////////////////////////////// +// MockMetricsLibraryDll +////////////////////////////////////////////////////// +class MockMetricsLibraryDll : public OsLibrary { + public: + bool validContextCreate = true; + bool validContextDelete = true; + bool validIsLoaded = true; + + void *getProcAddress(const std::string &procName) override; + bool isLoaded() override; +}; + +////////////////////////////////////////////////////// +// MockPerformanceCounters +////////////////////////////////////////////////////// +class MockPerformanceCounters { + public: + static std::unique_ptr create(Device *device); +}; + +////////////////////////////////////////////////////// +// PerformanceCountersDeviceFixture +////////////////////////////////////////////////////// struct PerformanceCountersDeviceFixture { - virtual void SetUp() { - overrideCSR = overrideCommandStreamReceiverCreation; - createFunc = Device::createPerformanceCountersFunc; - overrideCommandStreamReceiverCreation = true; - Device::createPerformanceCountersFunc = MockPerformanceCounters::create; - } - virtual void TearDown() { - overrideCommandStreamReceiverCreation = overrideCSR; - Device::createPerformanceCountersFunc = createFunc; - } - bool overrideCSR; + virtual void SetUp(); + virtual void TearDown(); decltype(&PerformanceCounters::create) createFunc; }; +///////////////////////////////////////////////////// +// PerformanceCountersFixture +////////////////////////////////////////////////////// struct PerformanceCountersFixture { - virtual void SetUp(); - - virtual void TearDown() { - releaseOsInterface(); - } - + virtual void TearDown(); virtual void createPerfCounters(); - void createOsTime(); - void fillOsInterface(); - void releaseOsInterface(); - - std::unique_ptr osInterfaceBase; - std::unique_ptr osTimeBase; - std::unique_ptr performanceCountersBase; + cl_queue_properties queueProperties = {}; + std::unique_ptr device; + std::unique_ptr context; + std::unique_ptr queue; + std::unique_ptr osInterface; + std::unique_ptr performanceCountersBase; }; + +////////////////////////////////////////////////////// +// PerformanceCountersMetricsLibraryFixture +////////////////////////////////////////////////////// +struct PerformanceCountersMetricsLibraryFixture : PerformanceCountersFixture { + + void SetUp() override; + void TearDown() override; + + void createPerformanceCounters(const bool validMetricsLibraryApi, const bool mockMatricsLibrary); + + std::unique_ptr performanceCountersBase; +}; + } // namespace NEO diff --git a/unit_tests/os_interface/performance_counters_gen_tests.cpp b/unit_tests/os_interface/performance_counters_gen_tests.cpp index a0208de62a..1b32e0406e 100644 --- a/unit_tests/os_interface/performance_counters_gen_tests.cpp +++ b/unit_tests/os_interface/performance_counters_gen_tests.cpp @@ -5,70 +5,16 @@ * */ -#include "runtime/helpers/options.h" #include "runtime/os_interface/performance_counters.h" #include "test.h" -#include "unit_tests/helpers/variable_backup.h" -#include "unit_tests/mocks/mock_ostime.h" -#include "unit_tests/os_interface/mock_performance_counters.h" using namespace NEO; struct PerformanceCountersGenTest : public ::testing::Test { }; -namespace NEO { -extern decltype(&instrGetPerfCountersQueryData) getPerfCountersQueryDataFactory[IGFX_MAX_CORE]; -extern size_t perfCountersQuerySize[IGFX_MAX_CORE]; -} // namespace NEO - class MockPerformanceCountersGen : public PerformanceCounters { public: - MockPerformanceCountersGen(OSTime *osTime) : PerformanceCounters(osTime) { + MockPerformanceCountersGen() : PerformanceCounters() { } - - decltype(&instrGetPerfCountersQueryData) getFn() const { - return getPerfCountersQueryDataFunc; - } -}; - -HWTEST_F(PerformanceCountersGenTest, givenPerfCountersWhenInitializedWithoutGenSpecificThenDefaultFunctionIsUsed) { - auto gfxCore = platformDevices[0]->platform.eRenderCoreFamily; - - VariableBackup bkp(&getPerfCountersQueryDataFactory[gfxCore], nullptr); - - MockOSTime osTime; - std::unique_ptr counters(new MockPerformanceCountersGen(&osTime)); - ASSERT_NE(nullptr, counters.get()); - - counters->initialize(platformDevices[0]); - EXPECT_EQ(counters->getFn(), &instrGetPerfCountersQueryData); - - size_t expected = sizeof(GTDI_QUERY); - EXPECT_EQ(expected, perfCountersQuerySize[gfxCore]); -} - -HWTEST_F(PerformanceCountersGenTest, givenPerfCountersWhenInitializedWithGenSpecificThenGenFunctionIsUsed) { - VariableBackup bkp(&getPerfCountersQueryDataFactory[platformDevices[0]->platform.eRenderCoreFamily]); - - auto mockFn = []( - InstrEscCbData cbData, - GTDI_QUERY *pData, - HwPerfCounters *pLayout, - uint64_t cpuRawTimestamp, - void *pASInterface, - InstrPmRegsCfg *pPmRegsCfg, - bool useMiRPC, - bool resetASData = false, - const InstrAllowedContexts *pAllowedContexts = nullptr) -> void { - }; - - bkp = mockFn; - - MockOSTime osTime; - std::unique_ptr counters(new MockPerformanceCountersGen(&osTime)); - ASSERT_NE(nullptr, counters.get()); - - counters->initialize(platformDevices[0]); - EXPECT_EQ(counters->getFn(), mockFn); -} +}; \ No newline at end of file diff --git a/unit_tests/os_interface/performance_counters_tests.cpp b/unit_tests/os_interface/performance_counters_tests.cpp index a9bc7fe3c3..fbb4ecdcfa 100644 --- a/unit_tests/os_interface/performance_counters_tests.cpp +++ b/unit_tests/os_interface/performance_counters_tests.cpp @@ -8,6 +8,7 @@ #include "runtime/helpers/options.h" #include "runtime/os_interface/os_interface.h" #include "runtime/os_interface/os_time.h" +#include "runtime/utilities/tag_allocator.h" #include "unit_tests/fixtures/device_instrumentation_fixture.h" #include "unit_tests/mocks/mock_device.h" #include "unit_tests/os_interface/mock_performance_counters.h" @@ -21,7 +22,6 @@ struct PerformanceCountersDeviceTest : public PerformanceCountersDeviceFixture, public ::testing::Test { void SetUp() override { PerformanceCountersDeviceFixture::SetUp(); - PerfCounterFlags::resetPerfCountersFlags(); } void TearDown() override { PerformanceCountersDeviceFixture::TearDown(); @@ -31,13 +31,11 @@ struct PerformanceCountersDeviceTest : public PerformanceCountersDeviceFixture, TEST_F(PerformanceCountersDeviceTest, createDeviceWithPerformanceCounters) { DeviceInstrumentationFixture::SetUp(true); EXPECT_NE(nullptr, device->getPerformanceCounters()); - EXPECT_EQ(1, PerfCounterFlags::initalizeCalled); } TEST_F(PerformanceCountersDeviceTest, createDeviceWithoutPerformanceCounters) { DeviceInstrumentationFixture::SetUp(false); EXPECT_EQ(nullptr, device->getPerformanceCounters()); - EXPECT_EQ(0, PerfCounterFlags::initalizeCalled); } struct PerformanceCountersTest : public PerformanceCountersFixture, @@ -53,305 +51,92 @@ struct PerformanceCountersTest : public PerformanceCountersFixture, }; TEST_F(PerformanceCountersTest, createPerformanceCounters) { - auto performanceCounters = PerformanceCounters::create(osTimeBase.get()); + auto performanceCounters = PerformanceCounters::create(device.get()); EXPECT_NE(nullptr, performanceCounters); EXPECT_NE(nullptr, performanceCounters.get()); EXPECT_FALSE(performanceCounters->isAvailable()); } -TEST_F(PerformanceCountersTest, shutdownPerformanceCountersWithoutEnabling) { - createPerfCounters(); - performanceCountersBase->shutdown(); - EXPECT_EQ(0, PerfCounterFlags::escHwMetricsCalled); - EXPECT_EQ(0, PerfCounterFlags::autoSamplingFuncCalled); - EXPECT_EQ(0, PerfCounterFlags::autoSamplingStopped); -} - TEST_F(PerformanceCountersTest, givenPerformanceCountersWhenCreatedThenAllValuesProperlyInitialized) { createPerfCounters(); - EXPECT_EQ(IGFX_UNKNOWN_CORE, performanceCountersBase->getGfxFamily()); - - EXPECT_EQ(nullptr, performanceCountersBase->getCbData().hDevice); - - EXPECT_FALSE(performanceCountersBase->getHwMetricsEnabled()); - EXPECT_FALSE(performanceCountersBase->getUseMIRPC()); - EXPECT_EQ(nullptr, performanceCountersBase->getPAutoSamplingInterface()); - EXPECT_EQ(0u, performanceCountersBase->getCpuRawTimestamp()); - EXPECT_EQ(1u, performanceCountersBase->getReportId()); - EXPECT_FALSE(performanceCountersBase->getAvailable()); - EXPECT_EQ(0u, performanceCountersBase->getPerfCountersReferenceNumber()); + EXPECT_NE(nullptr, performanceCountersBase->getMetricsLibraryInterface()); + EXPECT_EQ(0u, performanceCountersBase->getReferenceNumber()); } -TEST_F(PerformanceCountersTest, givenPerformanceCountersNotEnabledWhenGetPmRegsCfgIsCalledThenReturnsNullptr) { - createPerfCounters(); - auto pConfig = performanceCountersBase->getPmRegsCfg(0); - EXPECT_EQ(nullptr, pConfig); -} - -TEST_F(PerformanceCountersTest, givenPerformanceCountersEnabledWithPassingGetPmRegsCfgFuncWhenGetPmRegsCfgIsCalledThenReturnsPtr) { - createPerfCounters(); - performanceCountersBase->setGetPmRegsCfgFunc(getPmRegsCfgPassing); - performanceCountersBase->initialize(platformDevices[0]); - performanceCountersBase->enable(); - auto pConfig = performanceCountersBase->getPmRegsCfg(0); - EXPECT_EQ(1, PerfCounterFlags::getPmRegsCfgCalled); - EXPECT_NE(nullptr, pConfig); - delete pConfig; - performanceCountersBase->shutdown(); -} - -TEST_F(PerformanceCountersTest, givenPerformanceCountersEnabledWithFailingGetPmRegsCfgFuncWhenGetPmRegsCfgIsCalledThenReturnsNullptr) { - createPerfCounters(); - performanceCountersBase->setGetPmRegsCfgFunc(getPmRegsCfgFailing); - performanceCountersBase->initialize(platformDevices[0]); - performanceCountersBase->enable(); - auto pConfig = performanceCountersBase->getPmRegsCfg(0); - EXPECT_EQ(1, PerfCounterFlags::getPmRegsCfgCalled); - EXPECT_EQ(nullptr, pConfig); - performanceCountersBase->shutdown(); -} - -TEST_F(PerformanceCountersTest, givenPerfCountersWhenGetReportIdsIsCalledManyTimesThenReturnNextNumbers) { - int retVal; - createPerfCounters(); - for (int i = 0; i < 4095; i++) { - retVal = performanceCountersBase->getReportId(); - EXPECT_EQ((i + 1), retVal); - } - retVal = performanceCountersBase->getReportId(); - EXPECT_EQ(0, retVal); -} - -TEST_F(PerformanceCountersTest, sendPerfConfigPositiveReadRegsTag) { - cl_int ret; - cl_uint count = 2; - cl_uint offsets[2]; - cl_uint values[2]; - offsets[0] = INSTR_READ_REGS_CFG_TAG - 1; - createPerfCounters(); - performanceCountersBase->initialize(platformDevices[0]); - ret = performanceCountersBase->sendPerfConfiguration(count, offsets, values); - EXPECT_EQ(CL_SUCCESS, ret); - EXPECT_EQ(1, PerfCounterFlags::setPmRegsCfgCalled); - EXPECT_EQ(0, PerfCounterFlags::sendReadRegsCfgCalled); -} - -TEST_F(PerformanceCountersTest, sendPerfConfigPositiveReadRegs) { - cl_int ret; - cl_uint count = 2; - cl_uint offsets[2]; - cl_uint values[2]; - offsets[0] = INSTR_READ_REGS_CFG_TAG; - createPerfCounters(); - performanceCountersBase->initialize(platformDevices[0]); - ret = performanceCountersBase->sendPerfConfiguration(count, offsets, values); - EXPECT_EQ(CL_SUCCESS, ret); - EXPECT_EQ(0, PerfCounterFlags::setPmRegsCfgCalled); - EXPECT_EQ(1, PerfCounterFlags::sendReadRegsCfgCalled); -} - -TEST_F(PerformanceCountersTest, negativeInvalidVal) { - cl_int ret; - cl_uint count = 2; - cl_uint offsets[2]; - cl_uint values[2]; - createPerfCounters(); - performanceCountersBase->initialize(platformDevices[0]); - ret = performanceCountersBase->sendPerfConfiguration(0, offsets, values); - EXPECT_EQ(CL_INVALID_VALUE, ret); - ret = performanceCountersBase->sendPerfConfiguration(count, nullptr, values); - EXPECT_EQ(CL_INVALID_VALUE, ret); - ret = performanceCountersBase->sendPerfConfiguration(count, offsets, nullptr); - EXPECT_EQ(CL_INVALID_VALUE, ret); - - EXPECT_EQ(0, PerfCounterFlags::setPmRegsCfgCalled); - EXPECT_EQ(0, PerfCounterFlags::sendReadRegsCfgCalled); -} - -TEST_F(PerformanceCountersTest, negativeNoMatchingData) { - cl_int ret; - cl_uint count = 1; - cl_uint offsets[2]; - cl_uint values[2]; - offsets[0] = INSTR_READ_REGS_CFG_TAG; - createPerfCounters(); - performanceCountersBase->initialize(platformDevices[0]); - ret = performanceCountersBase->sendPerfConfiguration(count, offsets, values); - EXPECT_EQ(CL_PROFILING_INFO_NOT_AVAILABLE, ret); - - EXPECT_EQ(0, PerfCounterFlags::setPmRegsCfgCalled); - EXPECT_EQ(0, PerfCounterFlags::sendReadRegsCfgCalled); -} - -TEST_F(PerformanceCountersTest, sendPerfConfigNegativeFailingReadRegsTag) { - cl_int ret; - cl_uint count = 1; - cl_uint offsets[1]; - cl_uint values[1]; - offsets[0] = INSTR_READ_REGS_CFG_TAG - 1; - createPerfCounters(); - performanceCountersBase->setSetPmRegsCfgFunc(setPmRegsCfgFuncFailing); - performanceCountersBase->initialize(platformDevices[0]); - ret = performanceCountersBase->sendPerfConfiguration(count, offsets, values); - EXPECT_EQ(CL_PROFILING_INFO_NOT_AVAILABLE, ret); - - EXPECT_EQ(1, PerfCounterFlags::setPmRegsCfgCalled); - EXPECT_EQ(0, PerfCounterFlags::sendReadRegsCfgCalled); -} - -TEST_F(PerformanceCountersTest, sendPerfConfigNegativeFailingReadRegs) { - cl_int ret; - cl_uint count = 2; - cl_uint offsets[2]; - cl_uint values[2]; - offsets[0] = INSTR_READ_REGS_CFG_TAG; - createPerfCounters(); - performanceCountersBase->setSendReadRegsCfgFunc(sendReadRegsCfgFuncFailing); - performanceCountersBase->initialize(platformDevices[0]); - ret = performanceCountersBase->sendPerfConfiguration(count, offsets, values); - EXPECT_EQ(CL_PROFILING_INFO_NOT_AVAILABLE, ret); - - EXPECT_EQ(0, PerfCounterFlags::setPmRegsCfgCalled); - EXPECT_EQ(1, PerfCounterFlags::sendReadRegsCfgCalled); -} - -struct PerformanceCountersGetConfigTest : public PerformanceCountersTest, - public ::testing::WithParamInterface> { - void SetUp() override { - PerformanceCountersTest::SetUp(); - } - - void TearDown() override { - PerformanceCountersTest::TearDown(); - } - - unsigned int givenConfigType; - bool expectedValue; -}; - -TEST_P(PerformanceCountersGetConfigTest, givenPerformanceCountersEnabledWithPassingGetPmRegsCfgFuncWhenGetPmRegsCfgIsCalledWithProperConfigurationTypeThenReturnsPtrOtherwiseNullptr) { - std::tie(givenConfigType, expectedValue) = GetParam(); - createPerfCounters(); - performanceCountersBase->setGetPmRegsCfgFunc(getPmRegsCfgPassing); - performanceCountersBase->initialize(platformDevices[0]); - performanceCountersBase->enable(); - auto pConfig = performanceCountersBase->getPmRegsCfg(givenConfigType); - if (expectedValue) { - EXPECT_EQ(1, PerfCounterFlags::getPmRegsCfgCalled); - EXPECT_NE(nullptr, pConfig); - delete pConfig; - } else { - EXPECT_EQ(0, PerfCounterFlags::getPmRegsCfgCalled); - EXPECT_EQ(nullptr, pConfig); - } - performanceCountersBase->shutdown(); -} - -std::tuple configsForGetPmRegsCfgTests[] = { - std::make_tuple(GTDI_CONFIGURATION_SET_DYNAMIC, true), - std::make_tuple(GTDI_CONFIGURATION_SET_1, true), - std::make_tuple(GTDI_CONFIGURATION_SET_2, true), - std::make_tuple(GTDI_CONFIGURATION_SET_3, true), - std::make_tuple(GTDI_CONFIGURATION_SET_4, false), - std::make_tuple(GTDI_CONFIGURATION_SET_COUNT, false), - std::make_tuple(GTDI_CONFIGURATION_SET_MAX, false)}; - -INSTANTIATE_TEST_CASE_P( - PerfCountersTests, - PerformanceCountersGetConfigTest, - testing::ValuesIn(configsForGetPmRegsCfgTests)); - struct PerformanceCountersProcessEventTest : public PerformanceCountersTest, public ::testing::WithParamInterface { void SetUp() override { PerformanceCountersTest::SetUp(); createPerfCounters(); - performanceCountersBase->initialize(platformDevices[0]); - privateData.reset(new HwPerfCounter()); eventComplete = true; outputParamSize = 0; - inputParam.reset(new GTDI_QUERY()); - inputParamSize = sizeof(GTDI_QUERY); + inputParamSize = performanceCountersBase->getApiReportSize(); + inputParam.reset(new uint8_t); } void TearDown() override { performanceCountersBase->shutdown(); PerformanceCountersTest::TearDown(); } - std::unique_ptr inputParam; + + std::unique_ptr inputParam; size_t inputParamSize; size_t outputParamSize; - std::unique_ptr privateData; bool eventComplete; }; TEST_P(PerformanceCountersProcessEventTest, givenNullptrInputParamWhenProcessEventPerfCountersIsCalledThenReturnsFalse) { eventComplete = GetParam(); - auto retVal = performanceCountersBase->processEventReport(inputParamSize, nullptr, &outputParamSize, privateData.get(), - nullptr, eventComplete); + auto retVal = performanceCountersBase->getApiReport(inputParamSize, nullptr, &outputParamSize, eventComplete); EXPECT_FALSE(retVal); - EXPECT_EQ(0, PerfCounterFlags::getPerfCountersQueryDataCalled); } TEST_P(PerformanceCountersProcessEventTest, givenCorrectInputParamWhenProcessEventPerfCountersIsCalledAndEventIsCompletedThenReturnsTrue) { eventComplete = GetParam(); EXPECT_EQ(0ull, outputParamSize); - auto retVal = performanceCountersBase->processEventReport(inputParamSize, inputParam.get(), &outputParamSize, privateData.get(), - nullptr, eventComplete); + auto retVal = performanceCountersBase->getApiReport(inputParamSize, inputParam.get(), &outputParamSize, eventComplete); if (eventComplete) { EXPECT_TRUE(retVal); - EXPECT_EQ(1, PerfCounterFlags::getPerfCountersQueryDataCalled); EXPECT_EQ(outputParamSize, inputParamSize); } else { EXPECT_FALSE(retVal); - EXPECT_EQ(0, PerfCounterFlags::getPerfCountersQueryDataCalled); EXPECT_EQ(inputParamSize, outputParamSize); } } TEST_F(PerformanceCountersProcessEventTest, givenInvalidInputParamSizeWhenProcessEventPerfCountersIsCalledThenReturnsFalse) { EXPECT_EQ(0ull, outputParamSize); - auto retVal = performanceCountersBase->processEventReport(inputParamSize - 1, inputParam.get(), &outputParamSize, privateData.get(), - nullptr, eventComplete); + auto retVal = performanceCountersBase->getApiReport(inputParamSize - 1, inputParam.get(), &outputParamSize, eventComplete); EXPECT_FALSE(retVal); - EXPECT_EQ(0, PerfCounterFlags::getPerfCountersQueryDataCalled); EXPECT_EQ(outputParamSize, inputParamSize); } TEST_F(PerformanceCountersProcessEventTest, givenNullptrOutputParamSizeWhenProcessEventPerfCountersIsCalledThenDoesNotReturnsOutputSize) { EXPECT_EQ(0ull, outputParamSize); - auto retVal = performanceCountersBase->processEventReport(inputParamSize, inputParam.get(), nullptr, privateData.get(), - nullptr, eventComplete); + auto retVal = performanceCountersBase->getApiReport(inputParamSize, inputParam.get(), nullptr, eventComplete); EXPECT_TRUE(retVal); - EXPECT_EQ(1, PerfCounterFlags::getPerfCountersQueryDataCalled); EXPECT_EQ(0ull, outputParamSize); } TEST_F(PerformanceCountersProcessEventTest, givenNullptrInputZeroSizeWhenProcessEventPerfCountersIsCalledThenQueryProperSize) { EXPECT_EQ(0ull, outputParamSize); - auto retVal = performanceCountersBase->processEventReport(0, nullptr, &outputParamSize, privateData.get(), - nullptr, eventComplete); + auto retVal = performanceCountersBase->getApiReport(0, nullptr, &outputParamSize, eventComplete); EXPECT_TRUE(retVal); - EXPECT_EQ(0, PerfCounterFlags::getPerfCountersQueryDataCalled); EXPECT_EQ(inputParamSize, outputParamSize); } TEST_F(PerformanceCountersProcessEventTest, givenNullptrInputZeroSizeAndNullptrOutputSizeWhenProcessEventPerfCountersIsCalledThenReturnFalse) { EXPECT_EQ(0ull, outputParamSize); - auto retVal = performanceCountersBase->processEventReport(0, nullptr, nullptr, privateData.get(), - nullptr, eventComplete); + auto retVal = performanceCountersBase->getApiReport(0, nullptr, nullptr, eventComplete); EXPECT_FALSE(retVal); - EXPECT_EQ(0, PerfCounterFlags::getPerfCountersQueryDataCalled); EXPECT_EQ(0ull, outputParamSize); } @@ -360,120 +145,420 @@ INSTANTIATE_TEST_CASE_P( PerformanceCountersProcessEventTest, testing::Bool()); -struct PerformanceCountersSendConfigCommandPointersTest : public PerformanceCountersTest, - public ::testing::WithParamInterface> { +struct PerformanceCountersMetricsLibraryTest : public PerformanceCountersMetricsLibraryFixture, + public ::testing::Test { + + public: void SetUp() override { - PerformanceCountersTest::SetUp(); - createPerfCounters(); - performanceCountersBase->initialize(platformDevices[0]); - std::tie(pConfigIsNullptr, pLastConfigHandleIsNullptr, pLastConfigPendingIsNullptr) = GetParam(); + PerformanceCountersMetricsLibraryFixture::SetUp(); } void TearDown() override { - performanceCountersBase->shutdown(); - PerformanceCountersTest::TearDown(); + PerformanceCountersMetricsLibraryFixture::TearDown(); } - bool pConfigIsNullptr; - bool pLastConfigHandleIsNullptr; - bool pLastConfigPendingIsNullptr; - InstrPmRegsCfg config; - uint32_t lastConfigHandle; - bool lastConfigPending; }; -TEST_P(PerformanceCountersSendConfigCommandPointersTest, givenPerformanceCountersWithPassingFuncsWhenSendPmRegsCfgCommandsIsCalledWithAnyNullptrThenReturnsFalseOtherwiseTrue) { - InstrPmRegsCfg *pConfig = nullptr; - uint32_t *pLastConfigHandle = nullptr; - bool *pLastConfigPending = nullptr; +TEST_F(PerformanceCountersMetricsLibraryTest, givenPerformanceCountersWhenMetricLibraryIsValidThenQueryIsCreated) { + // Create performance counters. + createPerformanceCounters(true, true); + EXPECT_NE(nullptr, performanceCountersBase); + performanceCountersBase->enable(); + EXPECT_EQ(1u, performanceCountersBase->getReferenceNumber()); + EXPECT_TRUE(performanceCountersBase->isAvailable()); - if (!pConfigIsNullptr) { - pConfig = &config; - } - if (!pLastConfigHandleIsNullptr) { - pLastConfigHandle = &lastConfigHandle; - } - if (!pLastConfigPendingIsNullptr) { - lastConfigPending = false; - pLastConfigPending = &lastConfigPending; - } + // Check metric library context. + auto context = static_cast(performanceCountersBase->getMetricsLibraryContext().data); + EXPECT_NE(nullptr, context); + EXPECT_EQ(1u, context->contextCount); - auto retVal = performanceCountersBase->sendPmRegsCfgCommands(pConfig, pLastConfigHandle, pLastConfigPending); - if (pConfigIsNullptr || pLastConfigHandleIsNullptr || pLastConfigPendingIsNullptr) { - EXPECT_FALSE(retVal); - EXPECT_EQ(0, PerfCounterFlags::checkPmRegsCfgCalled); - EXPECT_EQ(0, PerfCounterFlags::loadPmRegsCfgCalled); - } else { - EXPECT_TRUE(retVal); - EXPECT_TRUE(lastConfigPending); - EXPECT_EQ(1, PerfCounterFlags::checkPmRegsCfgCalled); - EXPECT_EQ(1, PerfCounterFlags::loadPmRegsCfgCalled); - } + // Close library. + performanceCountersBase->shutdown(); + EXPECT_EQ(0u, performanceCountersBase->getReferenceNumber()); } -INSTANTIATE_TEST_CASE_P( - PerfCountersTests, - PerformanceCountersSendConfigCommandPointersTest, - testing::Combine( - testing::Bool(), - testing::Bool(), - testing::Bool())); +TEST_F(PerformanceCountersMetricsLibraryTest, givenPerformanceCountersWhenMetricLibraryIsValidThenQueryReturnsValidGpuCommands) { + // Create performance counters. + createPerformanceCounters(true, false); + EXPECT_NE(nullptr, performanceCountersBase); + performanceCountersBase->enable(); + EXPECT_EQ(1u, performanceCountersBase->getReferenceNumber()); + EXPECT_TRUE(performanceCountersBase->isAvailable()); -struct PerformanceCountersSendConfigCommandFuncPointersTest : public PerformanceCountersTest, - public ::testing::WithParamInterface> { - void SetUp() override { + // Obtain required command buffer size. + uint32_t commandsSize = performanceCountersBase->getGpuCommandsSize(true); + EXPECT_NE(0u, commandsSize); - PerformanceCountersTest::SetUp(); - createPerfCounters(); - std::tie(checkConfigFuncPassing, loadConfigFuncPassing) = GetParam(); - if (checkConfigFuncPassing) { - performanceCountersBase->setCheckPmRegsCfgFunc(checkPmRegsCfgPassing); - } else { - performanceCountersBase->setCheckPmRegsCfgFunc(checkPmRegsCfgFailing); - } - if (loadConfigFuncPassing) { - performanceCountersBase->setLoadPmRegsCfgFunc(loadPmRegsCfgPassing); - } else { - performanceCountersBase->setLoadPmRegsCfgFunc(loadPmRegsCfgFailing); - } - lastConfigPending = false; - performanceCountersBase->initialize(platformDevices[0]); - } + // Fill command buffer. + uint8_t buffer[1000] = {}; + HwPerfCounter perfCounter = {}; + TagNode query = {}; + query.tagForCpuAccess = &perfCounter; + EXPECT_TRUE(performanceCountersBase->getGpuCommands(query, true, sizeof(buffer), buffer)); - void TearDown() override { - performanceCountersBase->shutdown(); - PerformanceCountersTest::TearDown(); - } - bool checkConfigFuncPassing; - bool loadConfigFuncPassing; - InstrPmRegsCfg config; - uint32_t lastConfigHandle; - bool lastConfigPending; -}; - -TEST_P(PerformanceCountersSendConfigCommandFuncPointersTest, givenPerformanceCountersSendPmRegsCfgCommandsFuncWhenAllLoadConfigFuncAndCheckConfigFuncAndGetPerfmonConfigReturnTrueThenReturnsTrueOtherwiseFalse) { - auto retVal = performanceCountersBase->sendPmRegsCfgCommands(&config, &lastConfigHandle, &lastConfigPending); - EXPECT_EQ(1, PerfCounterFlags::checkPmRegsCfgCalled); - if (checkConfigFuncPassing) { - EXPECT_EQ(1, PerfCounterFlags::loadPmRegsCfgCalled); - if (loadConfigFuncPassing) { - EXPECT_TRUE(retVal); - EXPECT_TRUE(lastConfigPending); - } else { - EXPECT_FALSE(retVal); - EXPECT_EQ(1, PerfCounterFlags::loadPmRegsCfgCalled); - } - } else { - EXPECT_FALSE(retVal); - EXPECT_EQ(0, PerfCounterFlags::loadPmRegsCfgCalled); - } + // Close library. + performanceCountersBase->shutdown(); + EXPECT_EQ(0u, performanceCountersBase->getReferenceNumber()); } -INSTANTIATE_TEST_CASE_P( - PerfCountersTests, - PerformanceCountersSendConfigCommandFuncPointersTest, - testing::Combine( - testing::Bool(), - testing::Bool())); +TEST_F(PerformanceCountersMetricsLibraryTest, givenPerformanceCountersWhenMetricLibraryIsInvalidThenQueryReturnsInvalidGpuCommands) { + // Create performance counters. + createPerformanceCounters(false, false); + EXPECT_NE(nullptr, performanceCountersBase); + performanceCountersBase->enable(); + + // Obtain required command buffer size. + uint32_t commandsSize = performanceCountersBase->getGpuCommandsSize(true); + EXPECT_EQ(0u, commandsSize); + + // Close library. + performanceCountersBase->shutdown(); + EXPECT_EQ(0u, performanceCountersBase->getReferenceNumber()); +} + +TEST_F(PerformanceCountersMetricsLibraryTest, givenPerformanceCountersWhenMetricLibraryIsValidThenApiReportSizeIsValid) { + // Create performance counters. + createPerformanceCounters(true, true); + EXPECT_NE(nullptr, performanceCountersBase); + performanceCountersBase->enable(); + EXPECT_EQ(1u, performanceCountersBase->getReferenceNumber()); + EXPECT_TRUE(performanceCountersBase->isAvailable()); + + // Obtain api report size. + uint32_t apiReportSize = performanceCountersBase->getApiReportSize(); + EXPECT_GT(apiReportSize, 0u); + + // Close library. + performanceCountersBase->shutdown(); + EXPECT_EQ(0u, performanceCountersBase->getReferenceNumber()); +} + +TEST_F(PerformanceCountersMetricsLibraryTest, givenPerformanceCountersWhenMetricLibraryIsInvalidThenApiReportSizeIsInvalid) { + // Create performance counters. + createPerformanceCounters(false, false); + EXPECT_NE(nullptr, performanceCountersBase); + performanceCountersBase->enable(); + EXPECT_EQ(1u, performanceCountersBase->getReferenceNumber()); + + // Obtain api report size. + uint32_t apiReportSize = performanceCountersBase->getApiReportSize(); + EXPECT_EQ(0u, apiReportSize); + + // Close library. + performanceCountersBase->shutdown(); + EXPECT_EQ(0u, performanceCountersBase->getReferenceNumber()); +} + +TEST_F(PerformanceCountersMetricsLibraryTest, givenPerformanceCountersWhenMetricLibraryIsInvalidThenGpuReportSizeIsInvalid) { + // Create performance counters. + createPerformanceCounters(false, false); + EXPECT_NE(nullptr, performanceCountersBase); + performanceCountersBase->enable(); + EXPECT_EQ(1u, performanceCountersBase->getReferenceNumber()); + + // Obtain gpu report size. + uint32_t gpuReportSize = performanceCountersBase->getGpuReportSize(); + EXPECT_EQ(0u, gpuReportSize); + + // Close library. + performanceCountersBase->shutdown(); + EXPECT_EQ(0u, performanceCountersBase->getReferenceNumber()); +} + +TEST_F(PerformanceCountersMetricsLibraryTest, givenPerformanceCountersWhenMetricLibraryIsValidThenQueryIsAvailable) { + // Create performance counters. + createPerformanceCounters(true, true); + EXPECT_NE(nullptr, performanceCountersBase); + performanceCountersBase->enable(); + EXPECT_EQ(1u, performanceCountersBase->getReferenceNumber()); + EXPECT_TRUE(performanceCountersBase->isAvailable()); + + // Close library. + performanceCountersBase->shutdown(); + EXPECT_EQ(0u, performanceCountersBase->getReferenceNumber()); +} + +TEST_F(PerformanceCountersMetricsLibraryTest, givenPerformanceCountersWhenMetricLibraryIsInvalidThenQueryIsNotAvailable) { + // Create performance counters. + createPerformanceCounters(false, false); + EXPECT_NE(nullptr, performanceCountersBase); + performanceCountersBase->enable(); + EXPECT_EQ(1u, performanceCountersBase->getReferenceNumber()); + EXPECT_FALSE(performanceCountersBase->isAvailable()); + + // Close library. + performanceCountersBase->shutdown(); + EXPECT_EQ(0u, performanceCountersBase->getReferenceNumber()); +} + +TEST_F(PerformanceCountersMetricsLibraryTest, givenPerformanceCountersWhenMetricLibraryHasInvalidExportFunctionsDestroyThenQueryIsNotAvailable) { + createPerformanceCounters(true, false); + auto metricsLibraryInterface = performanceCountersBase->getMetricsLibraryInterface(); + auto metricsLibraryDll = reinterpret_cast(metricsLibraryInterface->osLibrary.get()); + metricsLibraryDll->validContextCreate = true; + metricsLibraryDll->validContextDelete = false; + EXPECT_NE(nullptr, performanceCountersBase); + EXPECT_EQ(0u, performanceCountersBase->getReferenceNumber()); + performanceCountersBase->enable(); + EXPECT_EQ(1u, performanceCountersBase->getReferenceNumber()); + EXPECT_FALSE(performanceCountersBase->isAvailable()); + + // Close library. + performanceCountersBase->shutdown(); + EXPECT_EQ(0u, performanceCountersBase->getReferenceNumber()); +} + +TEST_F(PerformanceCountersMetricsLibraryTest, givenPerformanceCountersWhenMetricLibraryHasInvalidExportFunctionsCreateAndDestroyThenQueryIsNotAvailable) { + createPerformanceCounters(true, false); + auto metricsLibraryInterface = performanceCountersBase->getMetricsLibraryInterface(); + auto metricsLibraryDll = reinterpret_cast(metricsLibraryInterface->osLibrary.get()); + metricsLibraryDll->validContextCreate = false; + metricsLibraryDll->validContextDelete = false; + EXPECT_NE(nullptr, performanceCountersBase); + EXPECT_EQ(0u, performanceCountersBase->getReferenceNumber()); + performanceCountersBase->enable(); + EXPECT_EQ(1u, performanceCountersBase->getReferenceNumber()); + EXPECT_FALSE(performanceCountersBase->isAvailable()); + + // Close library. + performanceCountersBase->shutdown(); + EXPECT_EQ(0u, performanceCountersBase->getReferenceNumber()); +} + +TEST_F(PerformanceCountersMetricsLibraryTest, givenPerformanceCountersWhenMetricLibraryIsValidThenQueryReturnsCorrectApiReport) { + // Create performance counters. + createPerformanceCounters(true, false); + EXPECT_NE(nullptr, performanceCountersBase); + performanceCountersBase->enable(); + EXPECT_EQ(1u, performanceCountersBase->getReferenceNumber()); + EXPECT_TRUE(performanceCountersBase->isAvailable()); + + // Obtain required command buffer size. + uint32_t commandsSize = performanceCountersBase->getGpuCommandsSize(true); + EXPECT_NE(0u, commandsSize); + + // Fill command buffer. + uint8_t buffer[1000] = {}; + TagNode query = {}; + HwPerfCounter perfCounter = {}; + query.tagForCpuAccess = &perfCounter; + EXPECT_TRUE(performanceCountersBase->getGpuCommands(query, true, sizeof(buffer), buffer)); + + // Obtain api report size. + uint32_t apiReportSize = performanceCountersBase->getApiReportSize(); + EXPECT_GT(apiReportSize, 0u); + + // Obtain gpu report size. + uint32_t gpuReportSize = performanceCountersBase->getGpuReportSize(); + EXPECT_GT(gpuReportSize, 0u); + + // Allocate memory for api report. + uint8_t *apiReport = new uint8_t[apiReportSize]; + EXPECT_NE(apiReport, nullptr); + + // Obtain api report. + EXPECT_TRUE(performanceCountersBase->getApiReport(apiReportSize, apiReport, nullptr, true)); + + delete[] apiReport; + apiReport = nullptr; + + // Close library. + performanceCountersBase->shutdown(); + EXPECT_EQ(0u, performanceCountersBase->getReferenceNumber()); +} + +TEST_F(PerformanceCountersMetricsLibraryTest, givenPerformanceCountersWhenMetricLibraryIsValidThenReferenceCounterIsValid) { + createPerformanceCounters(true, true); + EXPECT_NE(nullptr, performanceCountersBase); + EXPECT_EQ(0u, performanceCountersBase->getReferenceNumber()); + performanceCountersBase->enable(); + EXPECT_EQ(1u, performanceCountersBase->getReferenceNumber()); + performanceCountersBase->enable(); + EXPECT_EQ(2u, performanceCountersBase->getReferenceNumber()); + performanceCountersBase->shutdown(); + EXPECT_EQ(1u, performanceCountersBase->getReferenceNumber()); + performanceCountersBase->shutdown(); + EXPECT_EQ(0u, performanceCountersBase->getReferenceNumber()); + performanceCountersBase->shutdown(); + EXPECT_EQ(0u, performanceCountersBase->getReferenceNumber()); +} + +TEST_F(PerformanceCountersMetricsLibraryTest, givenPerformanceCountersWhenMetricLibraryIsValidThenQueryHandleIsValid) { + createPerformanceCounters(true, false); + EXPECT_NE(nullptr, performanceCountersBase); + + EXPECT_EQ(0u, performanceCountersBase->getReferenceNumber()); + performanceCountersBase->enable(); + EXPECT_TRUE(performanceCountersBase->getQueryHandle().IsValid()); + EXPECT_TRUE(performanceCountersBase->getQueryHandle().IsValid()); + + performanceCountersBase->shutdown(); + EXPECT_EQ(0u, performanceCountersBase->getReferenceNumber()); +} + +TEST_F(PerformanceCountersMetricsLibraryTest, givenPerformanceCountersWhenOaConfigurationIsInvalidThenGpuReportSizeIsInvalid) { + createPerformanceCounters(true, false); + EXPECT_NE(nullptr, performanceCountersBase); + performanceCountersBase->enable(); + EXPECT_EQ(1u, performanceCountersBase->getReferenceNumber()); + + auto metricLibraryApi = static_cast(performanceCountersBase->getMetricsLibraryContext().data); + metricLibraryApi->validCreateConfigurationOa = false; + + EXPECT_EQ(0u, performanceCountersBase->getGpuCommandsSize(true)); + EXPECT_GT(performanceCountersBase->getGpuCommandsSize(false), 0u); + + performanceCountersBase->shutdown(); + EXPECT_EQ(0u, performanceCountersBase->getReferenceNumber()); +} + +TEST_F(PerformanceCountersMetricsLibraryTest, givenPerformanceCountersWhenMetricsLibraryIsInvalidGpuReportSizeIsInvalid) { + createPerformanceCounters(true, false); + EXPECT_NE(nullptr, performanceCountersBase); + performanceCountersBase->enable(); + EXPECT_EQ(1u, performanceCountersBase->getReferenceNumber()); + + auto metricLibraryApi = static_cast(performanceCountersBase->getMetricsLibraryContext().data); + metricLibraryApi->validGpuReportSize = false; + + EXPECT_EQ(0u, performanceCountersBase->getGpuCommandsSize(true)); + EXPECT_EQ(0u, performanceCountersBase->getGpuCommandsSize(false)); + + performanceCountersBase->shutdown(); + EXPECT_EQ(0u, performanceCountersBase->getReferenceNumber()); +} + +TEST_F(PerformanceCountersMetricsLibraryTest, givenPerformanceCountersWhenAllConfigurationsAreValidThenGpuReportSizeIsValid) { + createPerformanceCounters(true, false); + EXPECT_NE(nullptr, performanceCountersBase); + performanceCountersBase->enable(); + EXPECT_EQ(1u, performanceCountersBase->getReferenceNumber()); + + auto metricLibraryApi = static_cast(performanceCountersBase->getMetricsLibraryContext().data); + metricLibraryApi->validCreateConfigurationOa = true; + metricLibraryApi->validCreateConfigurationUser = true; + + EXPECT_GT(performanceCountersBase->getGpuCommandsSize(true), 0u); + EXPECT_GT(performanceCountersBase->getGpuCommandsSize(false), 0u); + + performanceCountersBase->shutdown(); + EXPECT_EQ(0u, performanceCountersBase->getReferenceNumber()); +} + +TEST_F(PerformanceCountersMetricsLibraryTest, givenPerformanceCountersWhenOaConfigurationsActivationIsInvalidThenGpuReportSizeIsInvalid) { + createPerformanceCounters(true, false); + EXPECT_NE(nullptr, performanceCountersBase); + performanceCountersBase->enable(); + EXPECT_EQ(1u, performanceCountersBase->getReferenceNumber()); + + auto metricLibraryApi = static_cast(performanceCountersBase->getMetricsLibraryContext().data); + metricLibraryApi->validActivateConfigurationOa = false; + + EXPECT_EQ(0u, performanceCountersBase->getGpuCommandsSize(true)); + EXPECT_GT(performanceCountersBase->getGpuCommandsSize(false), 0u); + + performanceCountersBase->shutdown(); + EXPECT_EQ(0u, performanceCountersBase->getReferenceNumber()); +} + +TEST_F(PerformanceCountersMetricsLibraryTest, givenPerformanceCountersWhenCreatingUserConfigurationThenReturnSuccess) { + createPerformanceCounters(true, false); + EXPECT_NE(nullptr, performanceCountersBase); + performanceCountersBase->enable(); + EXPECT_EQ(1u, performanceCountersBase->getReferenceNumber()); + + ConfigurationHandle_1_0 configurationHandle = {}; + auto metricsLibrary = performanceCountersBase->getMetricsLibraryInterface(); + auto contextHandle = performanceCountersBase->getMetricsLibraryContext(); + EXPECT_TRUE(metricsLibrary->userConfigurationCreate(contextHandle, configurationHandle)); + EXPECT_TRUE(metricsLibrary->userConfigurationDelete(configurationHandle)); + + performanceCountersBase->shutdown(); + EXPECT_EQ(0u, performanceCountersBase->getReferenceNumber()); +} + +TEST_F(PerformanceCountersMetricsLibraryTest, getHwPerfCounterReturnsValidPointer) { + createPerformanceCounters(true, false); + EXPECT_NE(nullptr, performanceCountersBase); + performanceCountersBase->enable(); + EXPECT_EQ(1u, performanceCountersBase->getReferenceNumber()); + + ASSERT_NE(nullptr, queue->getPerfCounters()); + + std::unique_ptr event(new Event(queue.get(), CL_COMMAND_COPY_BUFFER, 0, 0)); + ASSERT_NE(nullptr, event); + + HwPerfCounter *perfCounter = event->getHwPerfCounterNode()->tagForCpuAccess; + ASSERT_NE(nullptr, perfCounter); + + ASSERT_EQ(0ULL, perfCounter->report[0]); + EXPECT_TRUE(perfCounter->canBeReleased()); + + HwPerfCounter *perfCounter2 = event->getHwPerfCounterNode()->tagForCpuAccess; + ASSERT_EQ(perfCounter, perfCounter2); + + performanceCountersBase->shutdown(); + EXPECT_EQ(0u, performanceCountersBase->getReferenceNumber()); +} + +TEST_F(PerformanceCountersMetricsLibraryTest, getHwPerfCounterAllocationReturnsValidPointer) { + createPerformanceCounters(true, false); + EXPECT_NE(nullptr, performanceCountersBase); + performanceCountersBase->enable(); + EXPECT_EQ(1u, performanceCountersBase->getReferenceNumber()); + ASSERT_NE(nullptr, queue->getPerfCounters()); + + std::unique_ptr event(new Event(queue.get(), CL_COMMAND_COPY_BUFFER, 0, 0)); + ASSERT_NE(nullptr, event); + + GraphicsAllocation *allocation = event->getHwPerfCounterNode()->getBaseGraphicsAllocation(); + ASSERT_NE(nullptr, allocation); + + void *memoryStorage = allocation->getUnderlyingBuffer(); + size_t memoryStorageSize = allocation->getUnderlyingBufferSize(); + + EXPECT_NE(nullptr, memoryStorage); + EXPECT_GT(memoryStorageSize, 0u); + + performanceCountersBase->shutdown(); + EXPECT_EQ(0u, performanceCountersBase->getReferenceNumber()); +} + +TEST_F(PerformanceCountersMetricsLibraryTest, hwPerfCounterMemoryIsPlacedInGraphicsAllocation) { + createPerformanceCounters(true, false); + EXPECT_NE(nullptr, performanceCountersBase); + performanceCountersBase->enable(); + EXPECT_EQ(1u, performanceCountersBase->getReferenceNumber()); + ASSERT_NE(nullptr, queue->getPerfCounters()); + + std::unique_ptr event(new Event(queue.get(), CL_COMMAND_COPY_BUFFER, 0, 0)); + ASSERT_NE(nullptr, event); + + HwPerfCounter *perfCounter = event->getHwPerfCounterNode()->tagForCpuAccess; + ASSERT_NE(nullptr, perfCounter); + + GraphicsAllocation *allocation = event->getHwPerfCounterNode()->getBaseGraphicsAllocation(); + ASSERT_NE(nullptr, allocation); + + void *memoryStorage = allocation->getUnderlyingBuffer(); + size_t graphicsAllocationSize = allocation->getUnderlyingBufferSize(); + + EXPECT_GE(perfCounter, memoryStorage); + EXPECT_LE(perfCounter + 1, ptrOffset(memoryStorage, graphicsAllocationSize)); + + performanceCountersBase->shutdown(); + EXPECT_EQ(0u, performanceCountersBase->getReferenceNumber()); +} + +TEST_F(PerformanceCountersMetricsLibraryTest, hwPerfCounterNodeWhenPerformanceCountersObjectIsNotPresentThenNodeisNull) { + std::unique_ptr event(new Event(queue.get(), CL_COMMAND_COPY_BUFFER, 0, 0)); + ASSERT_NE(nullptr, event); + + auto node = event->getHwPerfCounterNode(); + ASSERT_EQ(nullptr, node); +} + +TEST_F(PerformanceCountersTest, givenRenderCoreFamilyThenMetricsLibraryGenIdentifierAreValid) { + const auto &hwInfo = device->getHardwareInfo(); + const auto gen = hwInfo.platform.eRenderCoreFamily; + EXPECT_NE(ClientGen::Unknown, static_cast(HwHelper::get(gen).getMetricsLibraryGenId())); +} \ No newline at end of file diff --git a/unit_tests/os_interface/windows/hw_info_config_win_tests.cpp b/unit_tests/os_interface/windows/hw_info_config_win_tests.cpp index 55ba4cfa7e..bcf3442706 100644 --- a/unit_tests/os_interface/windows/hw_info_config_win_tests.cpp +++ b/unit_tests/os_interface/windows/hw_info_config_win_tests.cpp @@ -11,6 +11,8 @@ #include "runtime/os_interface/windows/wddm/wddm.h" #include "unit_tests/helpers/debug_manager_state_restore.h" +#include "instrumentation.h" + namespace NEO { template <> diff --git a/unit_tests/os_interface/windows/mock_performance_counters_win.cpp b/unit_tests/os_interface/windows/mock_performance_counters_win.cpp index 5c0822cd0d..af049b1bbe 100644 --- a/unit_tests/os_interface/windows/mock_performance_counters_win.cpp +++ b/unit_tests/os_interface/windows/mock_performance_counters_win.cpp @@ -7,47 +7,59 @@ #include "mock_performance_counters_win.h" +#include "runtime/os_interface/os_interface.h" +#include "runtime/os_interface/windows/os_interface.h" #include "runtime/os_interface/windows/windows_wrapper.h" #include "unit_tests/mocks/mock_wddm.h" +#include "unit_tests/os_interface/windows/mock_os_time_win.h" namespace NEO { -MockPerformanceCountersWin::MockPerformanceCountersWin(OSTime *osTime) - : PerformanceCounters(osTime), PerformanceCountersWin(osTime), MockPerformanceCounters(osTime) { - setAvailableFunc = setAvailable; - verifyEnableFunc = verifyEnable; - PerfCounterFlagsWin::resetPerfCountersFlags(); -} -std::unique_ptr MockPerformanceCounters::create(OSTime *osTime) { - return std::unique_ptr(new MockPerformanceCountersWin(osTime)); + +/////////////////////////////////////////////////////// +// MockPerformanceCounters::create +/////////////////////////////////////////////////////// +std::unique_ptr MockPerformanceCounters::create(Device *device) { + auto performanceCounters = std::unique_ptr(new MockPerformanceCountersWin(device)); + auto metricsLibrary = std::make_unique(); + auto metricsLibraryDll = std::make_unique(); + + metricsLibrary->api = std::make_unique(); + metricsLibrary->osLibrary = std::move(metricsLibraryDll); + performanceCounters->setMetricsLibraryInterface(std::move(metricsLibrary)); + + return performanceCounters; } -int PerfCounterFlagsWin::setAvailableFuncCalled; -int PerfCounterFlagsWin::verifyEnableFuncCalled; - -bool setAvailable(bool value) { - PerfCounterFlagsWin::setAvailableFuncCalled++; - return value; -} - -void verifyEnable(InstrEscCbData cbData) { - PerfCounterFlagsWin::verifyEnableFuncCalled++; -} - -void PerfCounterFlagsWin::resetPerfCountersFlags() { - PerfCounterFlags::resetPerfCountersFlags(); - PerfCounterFlagsWin::setAvailableFuncCalled = 0; - PerfCounterFlagsWin::verifyEnableFuncCalled = 0; +/////////////////////////////////////////////////////// +// MockPerformanceCountersWin::MockPerformanceCountersWin +/////////////////////////////////////////////////////// +MockPerformanceCountersWin::MockPerformanceCountersWin(Device *device) + : PerformanceCountersWin() { } +////////////////////////////////////////////////////// +// PerformanceCountersFixture::createPerfCounters +////////////////////////////////////////////////////// void PerformanceCountersFixture::createPerfCounters() { - performanceCountersBase = std::unique_ptr(new MockPerformanceCountersWin(osTimeBase.get())); + performanceCountersBase = MockPerformanceCounters::create(device.get()); } -void PerformanceCountersFixture::createOsTime() { - osTimeBase = std::unique_ptr(new MockOSTimeWin(osInterfaceBase.get())); + +////////////////////////////////////////////////////// +// PerformanceCountersFixture::SetUp +////////////////////////////////////////////////////// +void PerformanceCountersFixture::SetUp() { + device = std::unique_ptr(new MockDevice()); + context = std::make_unique(device.get()); + queue = std::make_unique(context.get(), device.get(), &queueProperties); + osInterface = std::unique_ptr(new OSInterface()); + osInterface->get()->setWddm(new WddmMock()); + device->setOSTime(new MockOSTimeWin(osInterface.get())); } -void PerformanceCountersFixture::fillOsInterface() { - osInterfaceBase->get()->setWddm(new WddmMock()); -} -void PerformanceCountersFixture::releaseOsInterface() { + +////////////////////////////////////////////////////// +// PerformanceCountersFixture::TearDown +////////////////////////////////////////////////////// +void PerformanceCountersFixture::TearDown() { } + } // namespace NEO diff --git a/unit_tests/os_interface/windows/mock_performance_counters_win.h b/unit_tests/os_interface/windows/mock_performance_counters_win.h index 208aefb20d..9a4c8b8aab 100644 --- a/unit_tests/os_interface/windows/mock_performance_counters_win.h +++ b/unit_tests/os_interface/windows/mock_performance_counters_win.h @@ -8,30 +8,11 @@ #pragma once #include "runtime/os_interface/windows/performance_counters_win.h" #include "unit_tests/os_interface/mock_performance_counters.h" -#include "unit_tests/os_interface/windows/mock_os_time_win.h" namespace NEO { -bool setAvailable(bool value); -void verifyEnable(InstrEscCbData cbData); - -class PerfCounterFlagsWin : public PerfCounterFlags { +class MockPerformanceCountersWin : public PerformanceCountersWin { public: - static int setAvailableFuncCalled; - static int verifyEnableFuncCalled; - static void resetPerfCountersFlags(); -}; - -class MockPerformanceCountersWin : public PerformanceCountersWin, - public MockPerformanceCounters { - public: - MockPerformanceCountersWin(OSTime *osTime); - uint32_t getReportId() override { - return MockPerformanceCounters::getReportId(); - } - void initialize(const HardwareInfo *hwInfo) override { - MockPerformanceCounters::initialize(hwInfo); - return PerformanceCountersWin::initialize(hwInfo); - } + MockPerformanceCountersWin(Device *device); }; } // namespace NEO diff --git a/unit_tests/os_interface/windows/options.cpp b/unit_tests/os_interface/windows/options.cpp index 0c8f15a4c5..a461610be1 100644 --- a/unit_tests/os_interface/windows/options.cpp +++ b/unit_tests/os_interface/windows/options.cpp @@ -21,6 +21,7 @@ const char *gdiDllName = "gdi32_mock.dll"; const char *gmmDllName = "mock_gmm.dll"; const char *gmmEntryName = "openMockGmm"; const char *testDllName = "test_dynamic_lib.dll"; +const char *metricsLibraryDllName = ""; } // namespace Os NEO::OsLibrary *setAdapterInfo(const PLATFORM *platform, const GT_SYSTEM_INFO *gtSystemInfo, uint64_t gpuAddressSpace) { diff --git a/unit_tests/os_interface/windows/os_interface_win_tests.cpp b/unit_tests/os_interface/windows/os_interface_win_tests.cpp index 4c6fac2bce..9ffbce3374 100644 --- a/unit_tests/os_interface/windows/os_interface_win_tests.cpp +++ b/unit_tests/os_interface/windows/os_interface_win_tests.cpp @@ -10,11 +10,6 @@ #include "runtime/os_interface/windows/os_context_win.h" #include "unit_tests/os_interface/windows/wddm_fixture.h" -TEST_F(OsInterfaceTest, givenOsInterfaceWithoutWddmWhenGetHwContextIdIsCalledThenReturnsZero) { - auto retVal = osInterface->getHwContextId(); - EXPECT_EQ(0u, retVal); -} - TEST_F(OsInterfaceTest, GivenWindowsWhenOsSupportFor64KBpagesIsBeingQueriedThenTrueIsReturned) { EXPECT_TRUE(OSInterface::are64kbPagesEnabled()); } diff --git a/unit_tests/os_interface/windows/performance_counters_win_tests.cpp b/unit_tests/os_interface/windows/performance_counters_win_tests.cpp index 5ccc94bba4..9f66e49dfb 100644 --- a/unit_tests/os_interface/windows/performance_counters_win_tests.cpp +++ b/unit_tests/os_interface/windows/performance_counters_win_tests.cpp @@ -6,8 +6,6 @@ */ #include "runtime/helpers/options.h" -#include "runtime/os_interface/windows/windows_wrapper.h" -#include "unit_tests/mocks/mock_wddm.h" #include "unit_tests/os_interface/windows/mock_performance_counters_win.h" #include "gtest/gtest.h" @@ -19,180 +17,9 @@ struct PerformanceCountersWinTest : public PerformanceCountersFixture, public: void SetUp() override { PerformanceCountersFixture::SetUp(); - PerfCounterFlagsWin::resetPerfCountersFlags(); - - wddm = static_cast(osInterfaceBase->get()->getWddm()); } void TearDown() override { PerformanceCountersFixture::TearDown(); } - - WddmMock *wddm; }; - -TEST_F(PerformanceCountersWinTest, initializePerformanceCounters) { - createPerfCounters(); - performanceCountersBase->initialize(platformDevices[0]); - EXPECT_EQ(1, PerfCounterFlagsWin::setAvailableFuncCalled); - EXPECT_EQ(1, PerfCounterFlagsWin::verifyEnableFuncCalled); - - EXPECT_FALSE(performanceCountersBase->isAvailable()); -} - -TEST_F(PerformanceCountersWinTest, enableWithCreatedAsInterface) { - createPerfCounters(); - performanceCountersBase->initialize(platformDevices[0]); - performanceCountersBase->setAsIface(new char[1]); - performanceCountersBase->enable(); -} - -TEST_F(PerformanceCountersWinTest, enablePerformanceCountersWithPassingEscHwMetricsFunc) { - createPerfCounters(); - performanceCountersBase->enable(); - EXPECT_EQ(1, PerfCounterFlagsWin::escHwMetricsCalled); - EXPECT_EQ(1, PerfCounterFlagsWin::autoSamplingFuncCalled); - EXPECT_EQ(1, PerfCounterFlagsWin::autoSamplingStarted); - EXPECT_EQ(1, PerfCounterFlagsWin::hwMetricsEnableStatus); - EXPECT_TRUE(performanceCountersBase->isAvailable()); - - performanceCountersBase->shutdown(); - EXPECT_EQ(2, PerfCounterFlagsWin::escHwMetricsCalled); - EXPECT_EQ(2, PerfCounterFlagsWin::autoSamplingFuncCalled); - EXPECT_EQ(1, PerfCounterFlagsWin::autoSamplingStopped); - EXPECT_EQ(0, PerfCounterFlagsWin::hwMetricsEnableStatus); - EXPECT_FALSE(performanceCountersBase->isAvailable()); -} - -TEST_F(PerformanceCountersWinTest, enablePerformanceCountersWithFailingEscHwMetricsFunc) { - createPerfCounters(); - performanceCountersBase->setEscHwMetricsFunc(hwMetricsEnableFuncFailing); - performanceCountersBase->enable(); - EXPECT_EQ(1, PerfCounterFlagsWin::escHwMetricsCalled); - EXPECT_EQ(0, PerfCounterFlagsWin::autoSamplingFuncCalled); - EXPECT_EQ(0, PerfCounterFlagsWin::autoSamplingStarted); - EXPECT_EQ(1, PerfCounterFlagsWin::hwMetricsEnableStatus); - performanceCountersBase->shutdown(); - EXPECT_EQ(1, PerfCounterFlagsWin::escHwMetricsCalled); - EXPECT_EQ(0, PerfCounterFlagsWin::autoSamplingFuncCalled); - EXPECT_EQ(0, PerfCounterFlagsWin::autoSamplingStopped); -} - -TEST_F(PerformanceCountersWinTest, enablePerformanceCountersWithPassingEscHwMetricsFuncTwice) { - uint32_t refNum = 0; - createPerfCounters(); - EXPECT_FALSE(performanceCountersBase->isAvailable()); - refNum = performanceCountersBase->getPerfCountersReferenceNumber(); - EXPECT_EQ(0u, refNum); - performanceCountersBase->enable(); - refNum = performanceCountersBase->getPerfCountersReferenceNumber(); - EXPECT_EQ(1, PerfCounterFlagsWin::escHwMetricsCalled); - EXPECT_EQ(1, PerfCounterFlagsWin::autoSamplingFuncCalled); - EXPECT_EQ(1, PerfCounterFlagsWin::autoSamplingStarted); - EXPECT_EQ(1u, refNum); - EXPECT_TRUE(performanceCountersBase->isAvailable()); - performanceCountersBase->enable(); - refNum = performanceCountersBase->getPerfCountersReferenceNumber(); - EXPECT_EQ(1, PerfCounterFlagsWin::escHwMetricsCalled); - EXPECT_EQ(1, PerfCounterFlagsWin::autoSamplingFuncCalled); - EXPECT_EQ(1, PerfCounterFlagsWin::autoSamplingStarted); - EXPECT_EQ(2u, refNum); - EXPECT_TRUE(performanceCountersBase->isAvailable()); - performanceCountersBase->shutdown(); - refNum = performanceCountersBase->getPerfCountersReferenceNumber(); - EXPECT_EQ(1, PerfCounterFlagsWin::escHwMetricsCalled); - EXPECT_EQ(1, PerfCounterFlagsWin::autoSamplingFuncCalled); - EXPECT_EQ(0, PerfCounterFlagsWin::autoSamplingStopped); - EXPECT_EQ(1u, refNum); - EXPECT_TRUE(performanceCountersBase->isAvailable()); - performanceCountersBase->shutdown(); - refNum = performanceCountersBase->getPerfCountersReferenceNumber(); - EXPECT_EQ(2, PerfCounterFlagsWin::escHwMetricsCalled); - EXPECT_EQ(2, PerfCounterFlagsWin::autoSamplingFuncCalled); - EXPECT_EQ(1, PerfCounterFlagsWin::autoSamplingStopped); - EXPECT_EQ(0u, refNum); - EXPECT_FALSE(performanceCountersBase->isAvailable()); -} - -TEST_F(PerformanceCountersWinTest, enablePerformanceCountersWithFailingEscHwMetricsFuncTwice) { - createPerfCounters(); - performanceCountersBase->setEscHwMetricsFunc(hwMetricsEnableFuncFailing); - performanceCountersBase->enable(); - EXPECT_EQ(1, PerfCounterFlagsWin::escHwMetricsCalled); - EXPECT_EQ(0, PerfCounterFlagsWin::autoSamplingFuncCalled); - EXPECT_EQ(0, PerfCounterFlagsWin::autoSamplingStarted); - EXPECT_FALSE(performanceCountersBase->isAvailable()); - performanceCountersBase->enable(); - EXPECT_EQ(1, PerfCounterFlagsWin::escHwMetricsCalled); - EXPECT_EQ(0, PerfCounterFlagsWin::autoSamplingFuncCalled); - EXPECT_EQ(0, PerfCounterFlagsWin::autoSamplingStarted); - performanceCountersBase->shutdown(); - EXPECT_EQ(1, PerfCounterFlagsWin::escHwMetricsCalled); - EXPECT_EQ(0, PerfCounterFlagsWin::autoSamplingFuncCalled); - EXPECT_EQ(0, PerfCounterFlagsWin::autoSamplingStopped); -} - -TEST_F(PerformanceCountersWinTest, enablePerformanceCountersWithFailingAutoStartFuncAfterProperInitializing) { - uint32_t refNum = 0; - createPerfCounters(); - performanceCountersBase->setEscHwMetricsFunc(hwMetricsEnableFuncPassing); - performanceCountersBase->setAutoSamplingStartFunc(autoSamplingStartFailing); - performanceCountersBase->initialize(platformDevices[0]); - refNum = performanceCountersBase->getPerfCountersReferenceNumber(); - EXPECT_EQ(0u, refNum); - EXPECT_FALSE(performanceCountersBase->isAvailable()); - performanceCountersBase->enable(); - EXPECT_EQ(1, PerfCounterFlagsWin::hwMetricsEnableStatus); - EXPECT_EQ(1, PerfCounterFlagsWin::escHwMetricsCalled); - EXPECT_EQ(1, PerfCounterFlagsWin::autoSamplingFuncCalled); - EXPECT_EQ(1, PerfCounterFlagsWin::autoSamplingStarted); - refNum = performanceCountersBase->getPerfCountersReferenceNumber(); - EXPECT_FALSE(performanceCountersBase->isAvailable()); - EXPECT_EQ(1u, refNum); - performanceCountersBase->shutdown(); - EXPECT_EQ(0, PerfCounterFlagsWin::hwMetricsEnableStatus); - EXPECT_EQ(2, PerfCounterFlagsWin::escHwMetricsCalled); - EXPECT_EQ(1, PerfCounterFlagsWin::autoSamplingFuncCalled); - EXPECT_EQ(0, PerfCounterFlagsWin::autoSamplingStopped); - refNum = performanceCountersBase->getPerfCountersReferenceNumber(); - EXPECT_EQ(0u, refNum); - EXPECT_FALSE(performanceCountersBase->isAvailable()); -} - -TEST_F(PerformanceCountersWinTest, enablePerformanceCountersWithFailingEscHwMetricsFuncAfterStartingAutoSampling) { - createPerfCounters(); - performanceCountersBase->setEscHwMetricsFunc(hwMetricsEnableFuncPassing); - performanceCountersBase->enable(); - EXPECT_EQ(1, PerfCounterFlagsWin::escHwMetricsCalled); - EXPECT_EQ(1, PerfCounterFlagsWin::autoSamplingFuncCalled); - EXPECT_EQ(1, PerfCounterFlagsWin::autoSamplingStarted); - performanceCountersBase->setEscHwMetricsFunc(hwMetricsEnableFuncFailing); - performanceCountersBase->enable(); - EXPECT_EQ(1, PerfCounterFlagsWin::escHwMetricsCalled); - EXPECT_EQ(1, PerfCounterFlagsWin::autoSamplingFuncCalled); - EXPECT_EQ(1, PerfCounterFlagsWin::autoSamplingStarted); - performanceCountersBase->shutdown(); - EXPECT_EQ(1, PerfCounterFlagsWin::escHwMetricsCalled); - EXPECT_EQ(1, PerfCounterFlagsWin::autoSamplingFuncCalled); - EXPECT_EQ(0, PerfCounterFlagsWin::autoSamplingStopped); - performanceCountersBase->shutdown(); - EXPECT_EQ(2, PerfCounterFlagsWin::escHwMetricsCalled); - EXPECT_EQ(2, PerfCounterFlagsWin::autoSamplingFuncCalled); - EXPECT_EQ(1, PerfCounterFlagsWin::autoSamplingStopped); -} - -TEST_F(PerformanceCountersWinTest, setCpuTimestamp) { - createPerfCounters(); - EXPECT_EQ(0ull, performanceCountersBase->getCpuRawTimestamp()); - performanceCountersBase->setCpuTimestamp(); - EXPECT_NE(0ull, performanceCountersBase->getCpuRawTimestamp()); -} - -TEST_F(PerformanceCountersWinTest, givenPerfCountersWithWddmWithSetHwContextIdWhenGetCurrentReportIdsIsCalledManyTimesThenReturnProperNumber) { - unsigned int retVal; - wddm->setHwContextId(0x12345); - createPerfCounters(); - retVal = performanceCountersBase->getCurrentReportId(); - EXPECT_EQ(0x12345u, osInterfaceBase->getHwContextId()); - EXPECT_EQ(0x12345001u, retVal); -} diff --git a/unit_tests/os_interface/windows/wddm_memory_manager_tests.cpp b/unit_tests/os_interface/windows/wddm_memory_manager_tests.cpp index b90c83d557..e060c5b2e5 100644 --- a/unit_tests/os_interface/windows/wddm_memory_manager_tests.cpp +++ b/unit_tests/os_interface/windows/wddm_memory_manager_tests.cpp @@ -1610,7 +1610,7 @@ TEST(WddmMemoryManagerCleanupTest, givenUsedTagAllocationInWddmMemoryManagerWhen csr->setupContext(*osContext); EXPECT_EQ(csr, executionEnvironment.memoryManager->getDefaultCommandStreamReceiver(0)); - auto tagAllocator = csr->getEventPerfCountAllocator(); + auto tagAllocator = csr->getEventPerfCountAllocator(100); auto allocation = tagAllocator->getTag()->getBaseGraphicsAllocation(); allocation->updateTaskCount(1, csr->getOsContext().getContextId()); executionEnvironment.commandStreamReceivers.clear(); diff --git a/unit_tests/profiling/profiling_tests.cpp b/unit_tests/profiling/profiling_tests.cpp index a46df380e8..3f57801197 100644 --- a/unit_tests/profiling/profiling_tests.cpp +++ b/unit_tests/profiling/profiling_tests.cpp @@ -517,7 +517,6 @@ struct ProfilingWithPerfCountersTests : public ProfilingTests, PerformanceCountersFixture::SetUp(); ProfilingTests::SetUp(); createPerfCounters(); - performanceCountersBase->initialize(platformDevices[0]); pDevice->setPerfCounters(performanceCountersBase.release()); } @@ -540,45 +539,13 @@ struct ProfilingWithPerfCountersTests : public ProfilingTests, } }; -HWCMDTEST_F(IGFX_GEN8_CORE, ProfilingWithPerfCountersTests, GIVENCommandQueueWithProfilingPerfCounterAndForWorkloadWithKernelWHENGetCSFromCmdQueueTHENEnoughSpaceInCS) { - typedef typename FamilyType::MI_STORE_REGISTER_MEM MI_STORE_REGISTER_MEM; - typedef typename FamilyType::PIPE_CONTROL PIPE_CONTROL; - typedef typename FamilyType::GPGPU_WALKER GPGPU_WALKER; - typedef typename FamilyType::MI_REPORT_PERF_COUNT MI_REPORT_PERF_COUNT; - - pCmdQ->setPerfCountersEnabled(true, 1); - - MockKernel kernel(program.get(), kernelInfo, *pDevice); - - uint64_t requiredSize = 2 * sizeof(PIPE_CONTROL) + 4 * sizeof(MI_STORE_REGISTER_MEM) + sizeof(GPGPU_WALKER) + HardwareCommandsHelper::getSizeRequiredCS(&kernel); - //begin perf cmds - requiredSize += 2 * sizeof(PIPE_CONTROL) + 2 * sizeof(MI_STORE_REGISTER_MEM) + NEO::INSTR_GENERAL_PURPOSE_COUNTERS_COUNT * sizeof(MI_STORE_REGISTER_MEM) + sizeof(MI_REPORT_PERF_COUNT) + pCmdQ->getPerfCountersUserRegistersNumber() * sizeof(MI_STORE_REGISTER_MEM); - //end perf cmds - requiredSize += 2 * sizeof(PIPE_CONTROL) + 3 * sizeof(MI_STORE_REGISTER_MEM) + NEO::INSTR_GENERAL_PURPOSE_COUNTERS_COUNT * sizeof(MI_STORE_REGISTER_MEM) + sizeof(MI_REPORT_PERF_COUNT) + pCmdQ->getPerfCountersUserRegistersNumber() * sizeof(MI_STORE_REGISTER_MEM); - - auto &commandStreamNDRangeKernel = getCommandStream(*pCmdQ, true, true, &kernel); - auto expectedSizeCS = EnqueueOperation::getSizeRequiredCS(CL_COMMAND_NDRANGE_KERNEL, true, true, *pCmdQ, &kernel); - EXPECT_GE(expectedSizeCS, requiredSize); - EXPECT_GE(commandStreamNDRangeKernel.getAvailableSpace(), requiredSize); - - auto &commandStreamTask = getCommandStream(*pCmdQ, true, true, &kernel); - expectedSizeCS = EnqueueOperation::getSizeRequiredCS(CL_COMMAND_TASK, true, true, *pCmdQ, &kernel); - EXPECT_GE(expectedSizeCS, requiredSize); - EXPECT_GE(commandStreamTask.getAvailableSpace(), requiredSize); - bool retVal = false; - retVal = pCmdQ->setPerfCountersEnabled(false, UINT32_MAX); - EXPECT_TRUE(retVal); - retVal = pCmdQ->setPerfCountersEnabled(false, UINT32_MAX); - EXPECT_TRUE(retVal); -} - HWTEST_F(ProfilingWithPerfCountersTests, GIVENCommandQueueWithProfilingPerfCounterAndForWorkloadWithNoKernelWHENGetCSFromCmdQueueTHENEnoughSpaceInCS) { typedef typename FamilyType::MI_STORE_REGISTER_MEM MI_STORE_REGISTER_MEM; typedef typename FamilyType::PIPE_CONTROL PIPE_CONTROL; typedef typename FamilyType::WALKER_TYPE GPGPU_WALKER; - pCmdQ->setPerfCountersEnabled(true, 1); + pCmdQ->setPerfCountersEnabled(true, 0); uint64_t requiredSize = 2 * sizeof(PIPE_CONTROL) + 4 * sizeof(MI_STORE_REGISTER_MEM); @@ -595,43 +562,12 @@ HWTEST_F(ProfilingWithPerfCountersTests, pCmdQ->setPerfCountersEnabled(false, UINT32_MAX); } -HWCMDTEST_F(IGFX_GEN8_CORE, ProfilingWithPerfCountersTests, GIVENCommandQueueWithProfilingPerfCountersAndForWorkloadWithTwoKernelsInMdiWHENGetCSFromCmdQueueTHENEnoughSpaceInCS) { - typedef typename FamilyType::MI_STORE_REGISTER_MEM MI_STORE_REGISTER_MEM; - typedef typename FamilyType::PIPE_CONTROL PIPE_CONTROL; - typedef typename FamilyType::GPGPU_WALKER GPGPU_WALKER; - typedef typename FamilyType::MI_REPORT_PERF_COUNT MI_REPORT_PERF_COUNT; - - MockKernel kernel(program.get(), kernelInfo, *pDevice); - - pCmdQ->setPerfCountersEnabled(true, 1); - - uint64_t requiredSize = 2 * sizeof(PIPE_CONTROL) + 4 * sizeof(MI_STORE_REGISTER_MEM) + HardwareCommandsHelper::getSizeRequiredCS(&kernel); - requiredSize += 2 * sizeof(GPGPU_WALKER); - - //begin perf cmds - requiredSize += 2 * sizeof(PIPE_CONTROL) + 2 * sizeof(MI_STORE_REGISTER_MEM) + NEO::INSTR_GENERAL_PURPOSE_COUNTERS_COUNT * sizeof(MI_STORE_REGISTER_MEM) + sizeof(MI_REPORT_PERF_COUNT) + pCmdQ->getPerfCountersUserRegistersNumber() * sizeof(MI_STORE_REGISTER_MEM); - //end perf cmds - requiredSize += 2 * sizeof(PIPE_CONTROL) + 3 * sizeof(MI_STORE_REGISTER_MEM) + NEO::INSTR_GENERAL_PURPOSE_COUNTERS_COUNT * sizeof(MI_STORE_REGISTER_MEM) + sizeof(MI_REPORT_PERF_COUNT) + pCmdQ->getPerfCountersUserRegistersNumber() * sizeof(MI_STORE_REGISTER_MEM); - - DispatchInfo dispatchInfo; - dispatchInfo.setKernel(&kernel); - MultiDispatchInfo multiDispatchInfo; - multiDispatchInfo.push(dispatchInfo); - multiDispatchInfo.push(dispatchInfo); - auto &commandStreamTask = getCommandStream(*pCmdQ, true, true, &kernel); - auto expectedSizeCS = EnqueueOperation::getTotalSizeRequiredCS(CL_COMMAND_TASK, CsrDependencies(), true, true, *pCmdQ, multiDispatchInfo); - EXPECT_GE(expectedSizeCS, requiredSize); - EXPECT_GE(commandStreamTask.getAvailableSpace(), requiredSize); - - pCmdQ->setPerfCountersEnabled(false, UINT32_MAX); -} - HWCMDTEST_F(IGFX_GEN8_CORE, ProfilingWithPerfCountersTests, GIVENCommandQueueWithProfilingPerfCountersWHENWalkerIsDispatchedTHENPipeControlWithTimeStampIsPresentInCS) { typedef typename FamilyType::PIPE_CONTROL PIPE_CONTROL; typedef typename FamilyType::GPGPU_WALKER GPGPU_WALKER; typedef typename FamilyType::MI_REPORT_PERF_COUNT MI_REPORT_PERF_COUNT; - pCmdQ->setPerfCountersEnabled(true, 1); + pCmdQ->setPerfCountersEnabled(true, 0); MockKernel kernel(program.get(), kernelInfo, *pDevice); ASSERT_EQ(CL_SUCCESS, kernel.initialize()); @@ -694,7 +630,7 @@ HWCMDTEST_F(IGFX_GEN8_CORE, ProfilingWithPerfCountersTests, GIVENCommandQueueWit typedef typename FamilyType::GPGPU_WALKER GPGPU_WALKER; typedef typename FamilyType::MI_REPORT_PERF_COUNT MI_REPORT_PERF_COUNT; - pCmdQ->setPerfCountersEnabled(true, 2); + pCmdQ->setPerfCountersEnabled(true, 0); MockKernel kernel(program.get(), kernelInfo, *pDevice); ASSERT_EQ(CL_SUCCESS, kernel.initialize()); @@ -757,7 +693,7 @@ HWCMDTEST_F(IGFX_GEN8_CORE, ProfilingWithPerfCountersTests, GIVENCommandQueueBlo typedef typename FamilyType::GPGPU_WALKER GPGPU_WALKER; typedef typename FamilyType::MI_REPORT_PERF_COUNT MI_REPORT_PERF_COUNT; - pCmdQ->setPerfCountersEnabled(true, 1); + pCmdQ->setPerfCountersEnabled(true, 0); MockKernel kernel(program.get(), kernelInfo, *pDevice); ASSERT_EQ(CL_SUCCESS, kernel.initialize()); @@ -822,7 +758,7 @@ HWTEST_F(ProfilingWithPerfCountersTests, typedef typename FamilyType::WALKER_TYPE GPGPU_WALKER; typedef typename FamilyType::MI_REPORT_PERF_COUNT MI_REPORT_PERF_COUNT; - pCmdQ->setPerfCountersEnabled(true, 1); + pCmdQ->setPerfCountersEnabled(true, 0); MockKernel kernel(program.get(), kernelInfo, *pDevice); ASSERT_EQ(CL_SUCCESS, kernel.initialize()); @@ -897,7 +833,7 @@ HWTEST_F(ProfilingWithPerfCountersTests, GIVENCommandQueueWithProfilingPerfCount csr.profilingTimeStampAllocator.reset(new FixedGpuAddressTagAllocator(csr, timeStampGpuAddress)); csr.perfCounterAllocator.reset(new FixedGpuAddressTagAllocator(csr, perfCountersGpuAddress)); - pCmdQ->setPerfCountersEnabled(true, 1); + pCmdQ->setPerfCountersEnabled(true, 0); MockKernel kernel(program.get(), kernelInfo, *pDevice); ASSERT_EQ(CL_SUCCESS, kernel.initialize()); @@ -924,31 +860,9 @@ HWTEST_F(ProfilingWithPerfCountersTests, GIVENCommandQueueWithProfilingPerfCount parseCommands(*pCmdQ); auto itor = expectStoreRegister(cmdList.begin(), timeStampGpuAddress + offsetof(HwTimeStamps, ContextStartTS), GP_THREAD_TIME_REG_ADDRESS_OFFSET_LOW); - itor = expectStoreRegister(itor, perfCountersGpuAddress + offsetof(HwPerfCounter, HWPerfCounters.DMAFenceIdBegin), INSTR_MMIO_NOOPID); - itor = expectStoreRegister(itor, perfCountersGpuAddress + offsetof(HwPerfCounter, HWPerfCounters.CoreFreqBegin), INSTR_MMIO_RPSTAT1); - for (auto i = 0u; i < NEO::INSTR_GENERAL_PURPOSE_COUNTERS_COUNT; i++) { - itor = expectStoreRegister(itor, perfCountersGpuAddress + offsetof(HwPerfCounter, HWPerfCounters.HwPerfReportBegin.Gp) + i * sizeof(cl_uint), - INSTR_GFX_OFFSETS::INSTR_PERF_CNT_1_DW0 + i * sizeof(cl_uint)); - } - itor = expectStoreRegister(itor, perfCountersGpuAddress + offsetof(HwPerfCounter, HWPerfCounters.HwPerfReportBegin.User), 0); - itor = expectStoreRegister(itor, perfCountersGpuAddress + offsetof(HwPerfCounter, HWPerfCounters.HwPerfReportBegin.User) + 8, 0); - itor = expectStoreRegister(itor, perfCountersGpuAddress + offsetof(HwPerfCounter, HWPerfCounters.HwPerfReportBegin.User) + 12, 4); - // after WALKER: itor = expectStoreRegister(itor, timeStampGpuAddress + offsetof(HwTimeStamps, ContextEndTS), GP_THREAD_TIME_REG_ADDRESS_OFFSET_LOW); - itor = expectStoreRegister(itor, perfCountersGpuAddress + offsetof(HwPerfCounter, HWPerfCounters.OaStatus), INSTR_GFX_OFFSETS::INSTR_OA_STATUS); - itor = expectStoreRegister(itor, perfCountersGpuAddress + offsetof(HwPerfCounter, HWPerfCounters.OaHead), INSTR_GFX_OFFSETS::INSTR_OA_HEAD_PTR); - itor = expectStoreRegister(itor, perfCountersGpuAddress + offsetof(HwPerfCounter, HWPerfCounters.OaTail), INSTR_GFX_OFFSETS::INSTR_OA_TAIL_PTR); - for (auto i = 0u; i < NEO::INSTR_GENERAL_PURPOSE_COUNTERS_COUNT; i++) { - itor = expectStoreRegister(itor, perfCountersGpuAddress + offsetof(HwPerfCounter, HWPerfCounters.HwPerfReportEnd.Gp) + i * sizeof(cl_uint), - INSTR_GFX_OFFSETS::INSTR_PERF_CNT_1_DW0 + i * sizeof(cl_uint)); - } - itor = expectStoreRegister(itor, perfCountersGpuAddress + offsetof(HwPerfCounter, HWPerfCounters.DMAFenceIdEnd), INSTR_MMIO_NOOPID); - itor = expectStoreRegister(itor, perfCountersGpuAddress + offsetof(HwPerfCounter, HWPerfCounters.CoreFreqEnd), INSTR_MMIO_RPSTAT1); - itor = expectStoreRegister(itor, perfCountersGpuAddress + offsetof(HwPerfCounter, HWPerfCounters.HwPerfReportEnd.User), 0); - itor = expectStoreRegister(itor, perfCountersGpuAddress + offsetof(HwPerfCounter, HWPerfCounters.HwPerfReportEnd.User) + 8, 0); - itor = expectStoreRegister(itor, perfCountersGpuAddress + offsetof(HwPerfCounter, HWPerfCounters.HwPerfReportEnd.User) + 12, 4); EXPECT_TRUE(pEvent->calcProfilingData());