From 8978fcce3d8bf1f8cdf6c44030631d542883fff5 Mon Sep 17 00:00:00 2001 From: Mateusz Hoppe Date: Mon, 23 Mar 2020 21:02:43 +0100 Subject: [PATCH] Enhanced unit tests for level zero - add mocks - link test with driver library - add debugger test Related-To: NEO-4500 Change-Id: I33313553c3f10ab899fd13447d1091f223e79a87 Signed-off-by: Mateusz Hoppe --- level_zero/CMakeLists.txt | 3 - level_zero/cmake/l0_tests.cmake | 4 +- .../core/test/unit_tests/CMakeLists.txt | 53 ++++---- level_zero/core/test/unit_tests/main.cpp | 37 ++++-- level_zero/core/test/unit_tests/mock.h | 18 +++ .../core/test/unit_tests/mocks/CMakeLists.txt | 35 +++++ .../test/unit_tests/mocks/mock_built_ins.cpp | 20 +++ .../test/unit_tests/mocks/mock_built_ins.h | 19 +++ .../test/unit_tests/mocks/mock_cmdqueue.cpp | 29 ++++ .../test/unit_tests/mocks/mock_cmdqueue.h | 73 ++++++++++ .../test/unit_tests/mocks/mock_device.cpp | 33 +++++ .../core/test/unit_tests/mocks/mock_device.h | 118 +++++++++++++++++ .../test/unit_tests/mocks/mock_driver.cpp | 30 +++++ .../core/test/unit_tests/mocks/mock_driver.h | 48 +++++++ .../unit_tests/mocks/mock_memory_manager.cpp | 55 ++++++++ .../unit_tests/mocks/mock_memory_manager.h | 50 +++++++ .../test/unit_tests/sources/CMakeLists.txt | 2 + .../sources/debugger/CMakeLists.txt | 10 ++ .../sources/debugger/test_debugger.cpp | 125 ++++++++++++++++++ level_zero/core/test/unit_tests/white_box.h | 32 +++++ shared/source/helpers/hw_helper.h | 1 + 21 files changed, 753 insertions(+), 42 deletions(-) create mode 100644 level_zero/core/test/unit_tests/mock.h create mode 100644 level_zero/core/test/unit_tests/mocks/CMakeLists.txt create mode 100644 level_zero/core/test/unit_tests/mocks/mock_built_ins.cpp create mode 100644 level_zero/core/test/unit_tests/mocks/mock_built_ins.h create mode 100644 level_zero/core/test/unit_tests/mocks/mock_cmdqueue.cpp create mode 100644 level_zero/core/test/unit_tests/mocks/mock_cmdqueue.h create mode 100644 level_zero/core/test/unit_tests/mocks/mock_device.cpp create mode 100644 level_zero/core/test/unit_tests/mocks/mock_device.h create mode 100644 level_zero/core/test/unit_tests/mocks/mock_driver.cpp create mode 100644 level_zero/core/test/unit_tests/mocks/mock_driver.h create mode 100644 level_zero/core/test/unit_tests/mocks/mock_memory_manager.cpp create mode 100644 level_zero/core/test/unit_tests/mocks/mock_memory_manager.h create mode 100644 level_zero/core/test/unit_tests/sources/debugger/CMakeLists.txt create mode 100644 level_zero/core/test/unit_tests/sources/debugger/test_debugger.cpp create mode 100644 level_zero/core/test/unit_tests/white_box.h diff --git a/level_zero/CMakeLists.txt b/level_zero/CMakeLists.txt index af61a6268e..3088ea1fdc 100644 --- a/level_zero/CMakeLists.txt +++ b/level_zero/CMakeLists.txt @@ -33,9 +33,6 @@ if(BUILD_WITH_L0 AND "${NEO_BITS}" STREQUAL "64") message(STATUS "Level Zero driver version: ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}") include(cmake/source_tree.cmake) - if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/cmake/${BRANCH_TYPE}/platforms.cmake AND NOT SKIP_L0_UNIT_TESTS) - include(cmake/${BRANCH_TYPE}/platforms.cmake) - endif() list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake") find_package(LevelZero) if(NOT LevelZero_FOUND) diff --git a/level_zero/cmake/l0_tests.cmake b/level_zero/cmake/l0_tests.cmake index 7bb8e73c56..8ab72e3b34 100644 --- a/level_zero/cmake/l0_tests.cmake +++ b/level_zero/cmake/l0_tests.cmake @@ -89,11 +89,13 @@ add_library(compute_runtime_mockable_extra ${COMPUTE_RUNTIME_DIR}/opencl/test/unit_test/libult/source_level_debugger_library.cpp ${COMPUTE_RUNTIME_DIR}/opencl/test/unit_test/mocks/mock_cif.cpp ${COMPUTE_RUNTIME_DIR}/opencl/test/unit_test/mocks/mock_csr.cpp - ${COMPUTE_RUNTIME_DIR}/opencl/test/unit_test/mocks/mock_gmm_page_table_mngr.cpp ${COMPUTE_RUNTIME_DIR}/opencl/test/unit_test/mocks/mock_compilers.cpp + ${COMPUTE_RUNTIME_DIR}/opencl/test/unit_test/mocks/mock_device.cpp + ${COMPUTE_RUNTIME_DIR}/opencl/test/unit_test/mocks/mock_gmm_page_table_mngr.cpp ${COMPUTE_RUNTIME_DIR}/opencl/test/unit_test/mocks${BRANCH_SUFIX_DIR}/mock_gmm_client_context.cpp ${COMPUTE_RUNTIME_DIR}/opencl/test/unit_test/mocks/mock_gmm_resource_info.cpp ${COMPUTE_RUNTIME_DIR}/opencl/test/unit_test/mocks/mock_gmm_client_context_base.cpp + ${COMPUTE_RUNTIME_DIR}/opencl/test/unit_test/mocks/mock_memory_manager.cpp ${COMPUTE_RUNTIME_DIR}/opencl/test/unit_test/mocks/mock_program.cpp ${COMPUTE_RUNTIME_DIR}/opencl/test/unit_test/mocks/mock_sip.cpp ${COMPUTE_RUNTIME_DIR}/opencl/test/unit_test/utilities/debug_settings_reader_creator.cpp diff --git a/level_zero/core/test/unit_tests/CMakeLists.txt b/level_zero/core/test/unit_tests/CMakeLists.txt index e13001da2c..0d61148d1a 100644 --- a/level_zero/core/test/unit_tests/CMakeLists.txt +++ b/level_zero/core/test/unit_tests/CMakeLists.txt @@ -10,13 +10,16 @@ set(TARGET_NAME ${TARGET_NAME_L0}_core_tests) append_sources_from_properties(L0_CORE_ENABLERS NEO_CORE_SRCS_LINK) +function(ADD_SUPPORTED_TEST_PRODUCT_FAMILIES_DEFINITION) + set(L0_TESTED_PRODUCT_FAMILIES ${ALL_TESTED_PRODUCT_FAMILY}) + string(REPLACE ";" "," L0_TESTED_PRODUCT_FAMILIES "${L0_TESTED_PRODUCT_FAMILIES}") + add_definitions(-DSUPPORTED_TEST_PRODUCT_FAMILIES=${L0_TESTED_PRODUCT_FAMILIES}) +endfunction() + +ADD_SUPPORTED_TEST_PRODUCT_FAMILIES_DEFINITION() + add_executable(${TARGET_NAME} ${NEO_SOURCE_DIR}/level_zero/core/source/dll/disallow_deferred_deleter.cpp - ${NEO_SOURCE_DIR}/level_zero/core/source/debug_manager.cpp - ${NEO_SOURCE_DIR}/level_zero/core/source/debugger.cpp - ${NEO_SOURCE_DIR}/level_zero/core/source/debugger/debugger_l0.cpp - ${NEO_SOURCE_DIR}/level_zero/core/source/compiler_interface/default_l0_cache_config.cpp - ${NEO_SOURCE_DIR}/level_zero/core/source/compiler_interface/default_cache_config.cpp ${NEO_SOURCE_DIR}/shared/test/unit_test/helpers/memory_management.h ${NEO_SOURCE_DIR}/shared/test/unit_test/helpers/memory_management.cpp ${NEO_SOURCE_DIR}/shared/test/unit_test/helpers/memory_leak_listener.h @@ -27,10 +30,13 @@ add_executable(${TARGET_NAME} target_sources(${TARGET_NAME} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt ${CMAKE_CURRENT_SOURCE_DIR}/main.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/mock.h + ${CMAKE_CURRENT_SOURCE_DIR}/white_box.h ) target_sources(${TARGET_NAME} PRIVATE ${COMPUTE_RUNTIME_DIR}/opencl/test/unit_test/libult/create_command_stream.cpp + $ ) if (UNIX) @@ -39,8 +45,7 @@ if (UNIX) ${COMPUTE_RUNTIME_DIR}/opencl/test/unit_test/os_interface/linux/drm_neo_create.cpp ${COMPUTE_RUNTIME_DIR}/opencl/test/unit_test/os_interface/linux/options.cpp ${COMPUTE_RUNTIME_DIR}/opencl/test/unit_test/os_interface/linux/sys_calls_linux_ult.cpp - ${COMPUTE_RUNTIME_DIR}/level_zero/core/source/linux/registry_path.cpp -) + ) else() target_sources(${TARGET_NAME} PRIVATE ${COMPUTE_RUNTIME_DIR}/opencl/test/unit_test/os_interface/windows/create_wddm_memory_manager.cpp @@ -49,18 +54,15 @@ else() ${COMPUTE_RUNTIME_DIR}/opencl/test/unit_test/os_interface/windows/ult_dxgi_factory.cpp ${COMPUTE_RUNTIME_DIR}/opencl/test/unit_test/os_interface/windows/wddm_calls.cpp ${COMPUTE_RUNTIME_DIR}/opencl/test/unit_test/os_interface/windows/wddm_create.cpp - ${COMPUTE_RUNTIME_DIR}/level_zero/core/source/windows/registry_path.cpp -) + ) endif() set_property(TARGET ${TARGET_NAME} APPEND_STRING PROPERTY COMPILE_FLAGS ${ASAN_FLAGS}) set_target_properties(${TARGET_NAME} PROPERTIES FOLDER ${TARGET_NAME_L0}) -target_compile_definitions(${TARGET_NAME} - PUBLIC - DEFAULT_PRODUCT_FAMILY=${DEFAULT_PRODUCT_FAMILY} - ZE_MAKEDLL -) +add_subdirectoriesL0(${CMAKE_CURRENT_SOURCE_DIR} "*") + +target_compile_definitions(${TARGET_NAME} PRIVATE $) target_include_directories(${TARGET_NAME} BEFORE @@ -80,9 +82,6 @@ if (UNIX) $/tools/linux ${COMPUTE_RUNTIME_DIR}/opencl/test/unit_test/linux ) - target_link_libraries(${TARGET_NAME} - pthread - ) else() target_include_directories(${TARGET_NAME} BEFORE @@ -94,20 +93,13 @@ else() endif() if (UNIX) - target_link_libraries(${TARGET_NAME} - rt - ) + target_link_libraries(${TARGET_NAME} pthread rt) else() - target_link_libraries(${TARGET_NAME} - dbghelp - ) + target_link_libraries(${TARGET_NAME} dbghelp) endif() target_link_libraries(${TARGET_NAME} - ${NEO_MOCKABLE_LIB_NAME} - ${NEO_SHARED_MOCKABLE_LIB_NAME} - ${NEO_MOCKABLE_LIB_NAME} - ${NEO_SHARED_MOCKABLE_LIB_NAME} + ${NEO_STATICALLY_LINKED_LIBRARIES_MOCKABLE} compute_runtime_mockable_extra ${HW_LIBS_ULT} gmock-gtest @@ -117,7 +109,10 @@ if(SKIP_NEO_UNIT_TESTS) add_subdirectory(${COMPUTE_RUNTIME_DIR}/opencl/test/unit_test/mock_gmm ${CMAKE_BINARY_DIR}/mock_gmm) endif() -target_sources(${TARGET_NAME} PRIVATE $) +target_sources(${TARGET_NAME} PRIVATE + $ + $ +) option(L0_ULT_VERBOSE "Use the default/verbose test output" OFF) if(NOT L0_ULT_VERBOSE) @@ -153,6 +148,4 @@ if(NOT GTEST_SHUFFLE) endif() message(STATUS "GTest shuffle set to ${GTEST_SHUFFLE}") -add_subdirectoriesL0(${CMAKE_CURRENT_SOURCE_DIR} "*") - create_source_tree(${TARGET_NAME} ${L0_ROOT_DIR}/..) diff --git a/level_zero/core/test/unit_tests/main.cpp b/level_zero/core/test/unit_tests/main.cpp index 7478e7aaa4..33d6de3620 100644 --- a/level_zero/core/test/unit_tests/main.cpp +++ b/level_zero/core/test/unit_tests/main.cpp @@ -18,6 +18,8 @@ #include "opencl/test/unit_test/mocks/mock_gmm_client_context.h" #include "opencl/test/unit_test/mocks/mock_sip.h" +#include "level_zero/core/source/cmdlist.h" + #include "gmock/gmock.h" #include "igfxfmid.h" @@ -118,6 +120,11 @@ void applyWorkarounds() { }); tempThreadID = t.get_id(); t.join(); + + //Create FileLogger to prevent false memory leaks + { + NEO::FileLoggerInstance(); + } } int main(int argc, char **argv) { @@ -168,9 +175,12 @@ int main(int argc, char **argv) { useDefaultListener = true; } } - - productFamily = hwInfoForTests.platform.eProductFamily; - renderCoreFamily = hwInfoForTests.platform.eRenderCoreFamily; + // Platforms with uninitialized factory are not supported + if (L0::commandListFactory[productFamily] == nullptr) { + std::cout << "unsupported product family has been set: " << NEO::hardwarePrefix[::productFamily] << std::endl; + std::cout << "skipping tests" << std::endl; + return 0; + } auto &listeners = ::testing::UnitTest::GetInstance()->listeners(); if (useDefaultListener == false) { @@ -191,17 +201,28 @@ int main(int argc, char **argv) { ::testing::AddGlobalTestEnvironment(environment); } - auto hwInfoConfig = NEO::defaultHardwareInfoConfigTable[productFamily]; - NEO::setHwInfoValuesFromConfig(hwInfoConfig, hwInfoForTests); - NEO::hardwareInfoSetup[productFamily](&hwInfoForTests, true, hwInfoConfig); + NEO::HardwareInfo hwInfo = hwInfoForTests; + uint64_t hwInfoConfig = NEO::defaultHardwareInfoConfigTable[productFamily]; + NEO::setHwInfoValuesFromConfig(hwInfoConfig, hwInfo); + // set Gt and FeatureTable to initial state + NEO::hardwareInfoSetup[productFamily](&hwInfo, false, hwInfoConfig); + + ::productFamily = hwInfo.platform.eProductFamily; + ::renderCoreFamily = hwInfo.platform.eRenderCoreFamily; + + NEO::platformDevices = new NEO::HardwareInfo *[1]; + NEO::platformDevices[0] = &hwInfo; NEO::defaultHwInfo = std::make_unique(); - *NEO::defaultHwInfo = hwInfoForTests; + *NEO::defaultHwInfo = hwInfo; NEO::useKernelDescriptor = true; NEO::MockSipData::mockSipKernel.reset(new NEO::MockSipKernel()); - return RUN_ALL_TESTS(); + auto retVal = RUN_ALL_TESTS(); + delete[] NEO::platformDevices; + + return retVal; } #if defined(__clang__) diff --git a/level_zero/core/test/unit_tests/mock.h b/level_zero/core/test/unit_tests/mock.h new file mode 100644 index 0000000000..938eed0be5 --- /dev/null +++ b/level_zero/core/test/unit_tests/mock.h @@ -0,0 +1,18 @@ +/* + * Copyright (C) 2019-2020 Intel Corporation + * + * SPDX-License-Identifier: MIT + * + */ + +#pragma once +#include "gmock/gmock.h" + +namespace L0 { +namespace ult { + +template +struct Mock : public Type {}; + +} // namespace ult +} // namespace L0 diff --git a/level_zero/core/test/unit_tests/mocks/CMakeLists.txt b/level_zero/core/test/unit_tests/mocks/CMakeLists.txt new file mode 100644 index 0000000000..1144446912 --- /dev/null +++ b/level_zero/core/test/unit_tests/mocks/CMakeLists.txt @@ -0,0 +1,35 @@ +# +# Copyright (C) 2020 Intel Corporation +# +# SPDX-License-Identifier: MIT +# + +set(TARGET_NAME ${TARGET_NAME_L0}_mocks) + +set(L0_MOCKS_SOURCES + ${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt + ${CMAKE_CURRENT_SOURCE_DIR}/mock_built_ins.h + ${CMAKE_CURRENT_SOURCE_DIR}/mock_built_ins.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/mock_cmdqueue.h + ${CMAKE_CURRENT_SOURCE_DIR}/mock_cmdqueue.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/mock_device.h + ${CMAKE_CURRENT_SOURCE_DIR}/mock_device.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/mock_driver.h + ${CMAKE_CURRENT_SOURCE_DIR}/mock_driver.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/mock_memory_manager.h + ${CMAKE_CURRENT_SOURCE_DIR}/mock_memory_manager.cpp +) + +add_library(${TARGET_NAME} OBJECT ${L0_MOCKS_SOURCES}) + +target_include_directories(${TARGET_NAME} PRIVATE + $ + $ + $ + ${NEO_SOURCE_DIR}/level_zero/core/test/unit_test +) + +target_compile_definitions(${TARGET_NAME} PRIVATE $) +set_target_properties(${TARGET_NAME} PROPERTIES FOLDER ${TARGET_NAME_L0}) + +create_source_tree(${TARGET_NAME} ${L0_ROOT_DIR}) diff --git a/level_zero/core/test/unit_tests/mocks/mock_built_ins.cpp b/level_zero/core/test/unit_tests/mocks/mock_built_ins.cpp new file mode 100644 index 0000000000..05836631e8 --- /dev/null +++ b/level_zero/core/test/unit_tests/mocks/mock_built_ins.cpp @@ -0,0 +1,20 @@ +/* + * Copyright (C) 2019-2020 Intel Corporation + * + * SPDX-License-Identifier: MIT + * + */ + +#include "level_zero/core/test/unit_tests/mocks/mock_built_ins.h" + +#include "opencl/source/helpers/built_ins_helper.h" + +namespace L0 { +namespace ult { + +const NEO::SipKernel &MockBuiltins::getSipKernel(NEO::SipKernelType type, NEO::Device &device) { + return NEO::initSipKernel(type, device); +} + +} // namespace ult +} // namespace L0 diff --git a/level_zero/core/test/unit_tests/mocks/mock_built_ins.h b/level_zero/core/test/unit_tests/mocks/mock_built_ins.h new file mode 100644 index 0000000000..2e553329af --- /dev/null +++ b/level_zero/core/test/unit_tests/mocks/mock_built_ins.h @@ -0,0 +1,19 @@ +/* + * Copyright (C) 2019-2020 Intel Corporation + * + * SPDX-License-Identifier: MIT + * + */ + +#pragma once +#include "shared/source/built_ins/built_ins.h" + +namespace L0 { +namespace ult { + +class MockBuiltins : public NEO::BuiltIns { + public: + const NEO::SipKernel &getSipKernel(NEO::SipKernelType type, NEO::Device &device) override; +}; +} // namespace ult +} // namespace L0 diff --git a/level_zero/core/test/unit_tests/mocks/mock_cmdqueue.cpp b/level_zero/core/test/unit_tests/mocks/mock_cmdqueue.cpp new file mode 100644 index 0000000000..e3c964f188 --- /dev/null +++ b/level_zero/core/test/unit_tests/mocks/mock_cmdqueue.cpp @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2019-2020 Intel Corporation + * + * SPDX-License-Identifier: MIT + * + */ + +#include "mock_cmdqueue.h" + +#include "shared/source/device/device.h" + +namespace L0 { +namespace ult { + +WhiteBox<::L0::CommandQueue>::WhiteBox(L0::Device *device, NEO::CommandStreamReceiver *csr, const ze_command_queue_desc_t *desc) + : ::L0::CommandQueueImp(device, csr, desc) {} + +WhiteBox<::L0::CommandQueue>::~WhiteBox() {} + +Mock::Mock(L0::Device *device, NEO::CommandStreamReceiver *csr, const ze_command_queue_desc_t *desc) + : WhiteBox<::L0::CommandQueue>(device, csr, desc) { + this->device = device; +} + +Mock::~Mock() { +} + +} // namespace ult +} // namespace L0 diff --git a/level_zero/core/test/unit_tests/mocks/mock_cmdqueue.h b/level_zero/core/test/unit_tests/mocks/mock_cmdqueue.h new file mode 100644 index 0000000000..61663c8615 --- /dev/null +++ b/level_zero/core/test/unit_tests/mocks/mock_cmdqueue.h @@ -0,0 +1,73 @@ +/* + * Copyright (C) 2019-2020 Intel Corporation + * + * SPDX-License-Identifier: MIT + * + */ + +#pragma once +#include "level_zero/core/source/cmdqueue_hw.h" +#include "level_zero/core/source/cmdqueue_imp.h" +#include "level_zero/core/test/unit_tests/mock.h" +#include "level_zero/core/test/unit_tests/white_box.h" + +#if defined(__clang__) +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Winconsistent-missing-override" +#endif + +namespace L0 { +namespace ult { + +template <> +struct WhiteBox<::L0::CommandQueue> : public ::L0::CommandQueueImp { + using BaseClass = ::L0::CommandQueueImp; + using BaseClass::buffers; + using BaseClass::commandStream; + using BaseClass::csr; + using BaseClass::device; + using BaseClass::printfFunctionContainer; + using BaseClass::synchronizeByPollingForTaskCount; + + WhiteBox(Device *device, NEO::CommandStreamReceiver *csr, + const ze_command_queue_desc_t *desc); + ~WhiteBox() override; +}; + +using CommandQueue = WhiteBox<::L0::CommandQueue>; +static ze_command_queue_desc_t default_cmd_queue_desc = {}; +template <> +struct Mock : public CommandQueue { + Mock(L0::Device *device = nullptr, NEO::CommandStreamReceiver *csr = nullptr, const ze_command_queue_desc_t *desc = &default_cmd_queue_desc); + ~Mock() override; + + MOCK_METHOD2(createFence, ze_result_t(const ze_fence_desc_t *desc, ze_fence_handle_t *phFence)); + MOCK_METHOD0(destroy, ze_result_t()); + MOCK_METHOD4(executeCommandLists, + ze_result_t(uint32_t numCommandLists, ze_command_list_handle_t *phCommandLists, + ze_fence_handle_t hFence, bool performMigration)); + MOCK_METHOD3(executeCommands, ze_result_t(uint32_t numCommands, + void *phCommands, + ze_fence_handle_t hFence)); + MOCK_METHOD1(synchronize, ze_result_t(uint32_t timeout)); + + MOCK_METHOD2(dispatchTaskCountWrite, void(NEO::LinearStream &commandStream, bool flushDataCache)); +}; + +template +struct MockCommandQueueHw : public L0::CommandQueueHw { + MockCommandQueueHw(L0::Device *device, NEO::CommandStreamReceiver *csr, const ze_command_queue_desc_t *desc) : L0::CommandQueueHw(device, csr, desc) { + } + ze_result_t synchronize(uint32_t timeout) override { + synchronizedCalled++; + return ZE_RESULT_SUCCESS; + } + uint32_t synchronizedCalled = 0; +}; + +} // namespace ult +} // namespace L0 + +#if defined(__clang__) +#pragma clang diagnostic pop +#endif diff --git a/level_zero/core/test/unit_tests/mocks/mock_device.cpp b/level_zero/core/test/unit_tests/mocks/mock_device.cpp new file mode 100644 index 0000000000..af4791ae15 --- /dev/null +++ b/level_zero/core/test/unit_tests/mocks/mock_device.cpp @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2019-2020 Intel Corporation + * + * SPDX-License-Identifier: MIT + * + */ + +#include "mock_device.h" + +#include "shared/source/device/device.h" + +#include "gmock/gmock.h" + +namespace L0 { +namespace ult { + +using ::testing::AnyNumber; +using ::testing::Return; + +Mock::Mock() { + ON_CALL(*this, getMOCS(false, false)).WillByDefault(Return(0)); + EXPECT_CALL(*this, getMOCS(false, false)).Times(AnyNumber()); + ON_CALL(*this, getMOCS(true, false)).WillByDefault(Return(2)); + EXPECT_CALL(*this, getMOCS(true, false)).Times(AnyNumber()); + + EXPECT_CALL(*this, getMaxNumHwThreads).WillRepeatedly(Return(16)); +} + +Mock::~Mock() { +} + +} // namespace ult +} // namespace L0 diff --git a/level_zero/core/test/unit_tests/mocks/mock_device.h b/level_zero/core/test/unit_tests/mocks/mock_device.h new file mode 100644 index 0000000000..48d8f3bc4e --- /dev/null +++ b/level_zero/core/test/unit_tests/mocks/mock_device.h @@ -0,0 +1,118 @@ +/* + * Copyright (C) 2019-2020 Intel Corporation + * + * SPDX-License-Identifier: MIT + * + */ + +#pragma once + +#include "shared/source/command_stream/preemption_mode.h" +#include "shared/source/device/device.h" +#include "shared/source/device/device_info.h" + +#include "level_zero/core/source/device.h" +#include "level_zero/core/source/driver_handle.h" +#include "level_zero/core/test/unit_tests/mock.h" +#include "level_zero/core/test/unit_tests/white_box.h" +#include "level_zero/tools/source/metrics/metric.h" + +#if defined(__clang__) +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Winconsistent-missing-override" +#endif + +namespace L0 { +namespace ult { + +template <> +struct WhiteBox<::L0::Device> : public ::L0::Device {}; + +using Device = WhiteBox<::L0::Device>; + +template <> +struct Mock : public Device { + Mock(); + ~Mock() override; + + MOCK_METHOD0(getRootDeviceIndex, uint32_t()); + MOCK_METHOD2(canAccessPeer, ze_result_t(ze_device_handle_t hPeerDevice, ze_bool_t *value)); + MOCK_METHOD2(copyCommandList, ze_result_t(ze_command_list_handle_t hCommandList, + ze_command_list_handle_t *phCommandList)); + MOCK_METHOD2(createCommandList, ze_result_t(const ze_command_list_desc_t *desc, + ze_command_list_handle_t *commandList)); + + MOCK_METHOD2(createCommandListImmediate, ze_result_t(const ze_command_queue_desc_t *desc, + ze_command_list_handle_t *commandList)); + + MOCK_METHOD2(createCommandQueue, ze_result_t(const ze_command_queue_desc_t *desc, + ze_command_queue_handle_t *commandQueue)); + + MOCK_METHOD2(createEventPool, + ze_result_t(const ze_event_pool_desc_t *desc, ze_event_pool_handle_t *eventPool)); + MOCK_METHOD2(createImage, ze_result_t(const ze_image_desc_t *desc, ze_image_handle_t *phImage)); + + MOCK_METHOD3(createModule, ze_result_t(const ze_module_desc_t *desc, ze_module_handle_t *module, + ze_module_build_log_handle_t *buildLog)); + MOCK_METHOD2(createSampler, + ze_result_t(const ze_sampler_desc_t *pDesc, ze_sampler_handle_t *phSampler)); + MOCK_METHOD1(evictImage, ze_result_t(ze_image_handle_t hImage)); + MOCK_METHOD2(evictMemory, ze_result_t(void *ptr, size_t size)); + MOCK_METHOD1(getComputeProperties, + ze_result_t(ze_device_compute_properties_t *pComputeProperties)); + MOCK_METHOD2(getP2PProperties, ze_result_t(ze_device_handle_t hPeerDevice, + ze_device_p2p_properties_t *pP2PProperties)); + MOCK_METHOD1(getKernelProperties, ze_result_t(ze_device_kernel_properties_t *pKernelProperties)); + MOCK_METHOD2(getMemoryProperties, ze_result_t(uint32_t *pCount, ze_device_memory_properties_t *pMemProperties)); + MOCK_METHOD1(getMemoryAccessProperties, ze_result_t(ze_device_memory_access_properties_t *pMemAccessProperties)); + MOCK_METHOD1(getProperties, ze_result_t(ze_device_properties_t *pDeviceProperties)); + MOCK_METHOD2(getSubDevice, ze_result_t(uint32_t ordinal, ze_device_handle_t *phSubDevice)); + MOCK_METHOD2(getSubDevices, ze_result_t(uint32_t *pCount, ze_device_handle_t *phSubdevices)); + MOCK_METHOD1(makeImageResident, ze_result_t(ze_image_handle_t hImage)); + MOCK_METHOD2(makeMemoryResident, ze_result_t(void *ptr, size_t size)); + MOCK_METHOD1(setIntermediateCacheConfig, ze_result_t(ze_cache_config_t CacheConfig)); + MOCK_METHOD1(setLastLevelCacheConfig, ze_result_t(ze_cache_config_t CacheConfig)); + MOCK_METHOD1(getCacheProperties, ze_result_t(ze_device_cache_properties_t *pCacheProperties)); + + MOCK_METHOD2(imageGetProperties, + ze_result_t(const ze_image_desc_t *desc, ze_image_properties_t *pImageProperties)); + MOCK_METHOD1(getDeviceImageProperties, + ze_result_t(ze_device_image_properties_t *pDeviceImageProperties)); + MOCK_METHOD0(systemBarrier, ze_result_t()); + MOCK_METHOD3(registerCLMemory, ze_result_t(cl_context context, cl_mem mem, void **ptr)); + MOCK_METHOD3(registerCLProgram, + ze_result_t(cl_context context, cl_program program, ze_module_handle_t *phModule)); + MOCK_METHOD3(registerCLCommandQueue, + ze_result_t(cl_context context, cl_command_queue command_queue, + ze_command_queue_handle_t *phCommandQueue)); + // Runtime internal methods + MOCK_METHOD0(getMemoryManager, NEO::MemoryManager *()); + MOCK_METHOD0(getExecEnvironment, void *()); + MOCK_METHOD0(getHwHelper, NEO::HwHelper &()); + MOCK_CONST_METHOD0(isMultiDeviceCapable, bool()); + MOCK_METHOD0(getBuiltinFunctionsLib, BuiltinFunctionsLib *()); + MOCK_METHOD2(getMOCS, uint32_t(bool l3enabled, bool l1enabled)); + MOCK_CONST_METHOD0(getMaxNumHwThreads, uint32_t()); + + MOCK_METHOD2(activateMetricGroups, + ze_result_t(uint32_t count, zet_metric_group_handle_t *phMetricGroups)); + MOCK_METHOD0(getOsInterface, NEO::OSInterface &()); + MOCK_CONST_METHOD0(getPlatformInfo, uint32_t()); + MOCK_METHOD0(getMetricContext, MetricContext &()); + MOCK_CONST_METHOD0(getHwInfo, const NEO::HardwareInfo &()); + MOCK_METHOD0(getDriverHandle, L0::DriverHandle *()); + MOCK_METHOD1(setDriverHandle, void(L0::DriverHandle *)); + + MOCK_CONST_METHOD0(getDevicePreemptionMode, NEO::PreemptionMode()); + MOCK_CONST_METHOD0(getDeviceInfo, const NEO::DeviceInfo &()); + MOCK_METHOD0(getNEODevice, NEO::Device *()); + MOCK_METHOD0(activateMetricGroups, void()); + MOCK_CONST_METHOD0(getDebugSurface, NEO::GraphicsAllocation *()); +}; + +} // namespace ult +} // namespace L0 + +#if defined(__clang__) +#pragma clang diagnostic pop +#endif diff --git a/level_zero/core/test/unit_tests/mocks/mock_driver.cpp b/level_zero/core/test/unit_tests/mocks/mock_driver.cpp new file mode 100644 index 0000000000..27d8080233 --- /dev/null +++ b/level_zero/core/test/unit_tests/mocks/mock_driver.cpp @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2019-2020 Intel Corporation + * + * SPDX-License-Identifier: MIT + * + */ + +#include "mock_driver.h" + +namespace L0 { +namespace ult { + +using MockDriver = Mock; +using ::testing::Invoke; + +Mock::Mock() { + previousDriver = driver; + driver = this; + EXPECT_CALL(*this, initialize) + .WillRepeatedly(Invoke(this, &MockDriver::mockInitialize)); +} + +Mock::~Mock() { + if (driver == this) { + driver = previousDriver; + } +} + +} // namespace ult +} // namespace L0 diff --git a/level_zero/core/test/unit_tests/mocks/mock_driver.h b/level_zero/core/test/unit_tests/mocks/mock_driver.h new file mode 100644 index 0000000000..4589633c87 --- /dev/null +++ b/level_zero/core/test/unit_tests/mocks/mock_driver.h @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2019-2020 Intel Corporation + * + * SPDX-License-Identifier: MIT + * + */ + +#pragma once +#include "level_zero/core/source/driver_imp.h" +#include "level_zero/core/test/unit_tests/mock.h" +#include "level_zero/core/test/unit_tests/white_box.h" + +#include + +#if defined(__clang__) +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Winconsistent-missing-override" +#endif + +namespace L0 { +namespace ult { + +template <> +struct WhiteBox<::L0::DriverImp> : public ::L0::DriverImp { +}; + +using Driver = WhiteBox<::L0::DriverImp>; + +template <> +struct Mock : public DriverImp { + Mock(); + virtual ~Mock(); + + MOCK_METHOD1(driverInit, ze_result_t(ze_init_flag_t)); + MOCK_METHOD1(initialize, void(bool *result)); + + ze_result_t mockInit(ze_init_flag_t) { return this->DriverImp::driverInit(ZE_INIT_FLAG_NONE); } + void mockInitialize(bool *result) { *result = true; } + + Driver *previousDriver = nullptr; +}; + +} // namespace ult +} // namespace L0 + +#if defined(__clang__) +#pragma clang diagnostic pop +#endif diff --git a/level_zero/core/test/unit_tests/mocks/mock_memory_manager.cpp b/level_zero/core/test/unit_tests/mocks/mock_memory_manager.cpp new file mode 100644 index 0000000000..215e9312fe --- /dev/null +++ b/level_zero/core/test/unit_tests/mocks/mock_memory_manager.cpp @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2019-2020 Intel Corporation + * + * SPDX-License-Identifier: MIT + * + */ + +#include "mock_memory_manager.h" + +#include "shared/source/helpers/aligned_memory.h" +#include "shared/source/helpers/string.h" + +#include + +namespace L0 { +namespace ult { + +using namespace testing; +using ::testing::Return; + +Mock::Mock(NEO::ExecutionEnvironment &executionEnvironment) : MemoryManagerMock(executionEnvironment) { + EXPECT_CALL(*this, allocateGraphicsMemoryInPreferredPool) + .WillRepeatedly(Invoke(this, &Mock::doAllocateGraphicsMemoryInPreferredPool)); + EXPECT_CALL(*this, freeGraphicsMemory) + .WillRepeatedly(Invoke(this, &Mock::doFreeGraphicsMemory)); +} + +inline NEO::GraphicsAllocation *Mock::doAllocateGraphicsMemoryInPreferredPool(const NEO::AllocationProperties &properties, const void *hostPtr) { + void *buffer; + if (hostPtr != nullptr) { + buffer = const_cast(hostPtr); + } else { + buffer = alignedMalloc(properties.size, MemoryConstants::pageSize); + } + uint64_t baseAddress = 0; + if (properties.allocationType == NEO::GraphicsAllocation::AllocationType::INTERNAL_HEAP) { + baseAddress = castToUint64(alignDown(buffer, MemoryConstants::pageSize64k)); + } + auto allocation = new NEO::GraphicsAllocation(properties.rootDeviceIndex, properties.allocationType, + buffer, reinterpret_cast(buffer), baseAddress, properties.size, + MemoryPool::System4KBPages); + + return allocation; +} + +inline void Mock::doFreeGraphicsMemory(NEO::GraphicsAllocation *allocation) { + if (allocation == nullptr) { + return; + } + alignedFree(allocation->getUnderlyingBuffer()); + delete allocation; +} + +} // namespace ult +} // namespace L0 diff --git a/level_zero/core/test/unit_tests/mocks/mock_memory_manager.h b/level_zero/core/test/unit_tests/mocks/mock_memory_manager.h new file mode 100644 index 0000000000..7fa731f261 --- /dev/null +++ b/level_zero/core/test/unit_tests/mocks/mock_memory_manager.h @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2019-2020 Intel Corporation + * + * SPDX-License-Identifier: MIT + * + */ + +#pragma once +#include "shared/source/memory_manager/unified_memory_manager.h" + +#include "opencl/source/memory_manager/os_agnostic_memory_manager.h" + +#include "level_zero/core/test/unit_tests/mock.h" +#include "level_zero/core/test/unit_tests/white_box.h" + +#include + +#if defined(__clang__) +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Winconsistent-missing-override" +#endif + +namespace L0 { +namespace ult { + +template <> +struct WhiteBox<::NEO::OsAgnosticMemoryManager> : public ::NEO::OsAgnosticMemoryManager { + using BaseClass = ::NEO::OsAgnosticMemoryManager; + WhiteBox(NEO::ExecutionEnvironment &executionEnvironment) : NEO::OsAgnosticMemoryManager(executionEnvironment) {} +}; + +using MemoryManagerMock = WhiteBox<::NEO::OsAgnosticMemoryManager>; + +template <> +struct Mock : public MemoryManagerMock { + Mock(NEO::ExecutionEnvironment &executionEnvironment); + MOCK_METHOD2(allocateGraphicsMemoryInPreferredPool, + NEO::GraphicsAllocation *(const NEO::AllocationProperties &properties, const void *hostPtr)); + MOCK_METHOD1(freeGraphicsMemory, void(NEO::GraphicsAllocation *)); + + NEO::GraphicsAllocation *doAllocateGraphicsMemoryInPreferredPool(const NEO::AllocationProperties &properties, const void *hostPtr); + void doFreeGraphicsMemory(NEO::GraphicsAllocation *allocation); +}; + +} // namespace ult +} // namespace L0 + +#if defined(__clang__) +#pragma clang diagnostic pop +#endif diff --git a/level_zero/core/test/unit_tests/sources/CMakeLists.txt b/level_zero/core/test/unit_tests/sources/CMakeLists.txt index 20f9b2de42..a5326dcaaa 100644 --- a/level_zero/core/test/unit_tests/sources/CMakeLists.txt +++ b/level_zero/core/test/unit_tests/sources/CMakeLists.txt @@ -8,3 +8,5 @@ target_sources(${TARGET_NAME} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt ${CMAKE_CURRENT_SOURCE_DIR}/deferred_deleter_test.cpp ) + +add_subdirectories() \ No newline at end of file diff --git a/level_zero/core/test/unit_tests/sources/debugger/CMakeLists.txt b/level_zero/core/test/unit_tests/sources/debugger/CMakeLists.txt new file mode 100644 index 0000000000..bfe3022738 --- /dev/null +++ b/level_zero/core/test/unit_tests/sources/debugger/CMakeLists.txt @@ -0,0 +1,10 @@ +# +# Copyright (C) 2020 Intel Corporation +# +# SPDX-License-Identifier: MIT +# + +target_sources(${TARGET_NAME} PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt + ${CMAKE_CURRENT_SOURCE_DIR}/test_debugger.cpp +) \ No newline at end of file diff --git a/level_zero/core/test/unit_tests/sources/debugger/test_debugger.cpp b/level_zero/core/test/unit_tests/sources/debugger/test_debugger.cpp new file mode 100644 index 0000000000..2da04e4850 --- /dev/null +++ b/level_zero/core/test/unit_tests/sources/debugger/test_debugger.cpp @@ -0,0 +1,125 @@ +/* + * Copyright (C) 2019-2020 Intel Corporation + * + * SPDX-License-Identifier: MIT + * + */ + +#include "shared/source/command_stream/linear_stream.h" +#include "shared/source/gen_common/reg_configs/reg_configs_common.h" +#include "shared/source/helpers/preamble.h" +#include "shared/test/unit_test/mocks/mock_os_library.h" + +#include "opencl/test/unit_test/gen_common/gen_cmd_parse.h" +#include "opencl/test/unit_test/mocks/mock_device.h" +#include "opencl/test/unit_test/mocks/mock_source_level_debugger.h" +#include "test.h" + +#include "level_zero/core/source/cmdqueue_hw.h" +#include "level_zero/core/source/fence.h" +#include "level_zero/core/test/unit_tests/mocks/mock_built_ins.h" +#include "level_zero/core/test/unit_tests/mocks/mock_cmdqueue.h" +#include "level_zero/core/test/unit_tests/mocks/mock_device.h" +#include "level_zero/core/test/unit_tests/mocks/mock_driver.h" +#include "level_zero/core/test/unit_tests/mocks/mock_memory_manager.h" +#include + +#include "gtest/gtest.h" + +namespace L0 { +namespace ult { + +struct ActiveDebuggerFixture { + void SetUp() { + auto executionEnvironment = new NEO::ExecutionEnvironment(); + auto mockBuiltIns = new MockBuiltins(); + executionEnvironment->prepareRootDeviceEnvironments(1); + executionEnvironment->rootDeviceEnvironments[0]->builtins.reset(mockBuiltIns); + executionEnvironment->rootDeviceEnvironments[0]->setHwInfo(*platformDevices); + + debugger = new MockActiveSourceLevelDebugger(new MockOsLibrary); + executionEnvironment->rootDeviceEnvironments[0]->debugger.reset(debugger); + executionEnvironment->initializeMemoryManager(); + + device = NEO::MockDevice::create(executionEnvironment, 0u); + device->setDebuggerActive(true); + + std::vector> devices; + devices.push_back(std::unique_ptr(device)); + + auto driverHandleUlt = whitebox_cast(DriverHandle::create(std::move(devices))); + driverHandle.reset(driverHandleUlt); + + ASSERT_NE(nullptr, driverHandle); + + ze_device_handle_t hDevice; + uint32_t count = 1; + ze_result_t result = driverHandle->getDevice(&count, &hDevice); + EXPECT_EQ(ZE_RESULT_SUCCESS, result); + deviceL0 = L0::Device::fromHandle(hDevice); + ASSERT_NE(nullptr, deviceL0); + } + void TearDown() { + } + + std::unique_ptr> driverHandle; + NEO::MockDevice *device = nullptr; + L0::Device *deviceL0; + MockActiveSourceLevelDebugger *debugger = nullptr; +}; + +using CommandQueueDebugCommandsTest = Test; + +HWTEST_F(CommandQueueDebugCommandsTest, givenDebuggingEnabledWhenCommandListIsExecutedThenKernelDebugCommandsAreAdded) { + ze_command_queue_desc_t queueDesc = {}; + auto commandQueue = whitebox_cast(CommandQueue::create(productFamily, deviceL0, device->getDefaultEngine().commandStreamReceiver, &queueDesc)); + ASSERT_NE(nullptr, commandQueue->commandStream); + + auto usedSpaceBefore = commandQueue->commandStream->getUsed(); + + ze_command_list_handle_t commandLists[] = { + CommandList::create(productFamily, deviceL0)->toHandle()}; + uint32_t numCommandLists = sizeof(commandLists) / sizeof(commandLists[0]); + + auto result = commandQueue->executeCommandLists(numCommandLists, commandLists, nullptr, true); + ASSERT_EQ(ZE_RESULT_SUCCESS, result); + + auto usedSpaceAfter = commandQueue->commandStream->getUsed(); + ASSERT_GT(usedSpaceAfter, usedSpaceBefore); + + GenCmdList cmdList; + ASSERT_TRUE(FamilyType::PARSE::parseCommandBuffer( + cmdList, ptrOffset(commandQueue->commandStream->getCpuBase(), 0), usedSpaceAfter)); + using MI_LOAD_REGISTER_IMM = typename FamilyType::MI_LOAD_REGISTER_IMM; + + auto miLoadImm = findAll(cmdList.begin(), cmdList.end()); + ASSERT_LE(2u, miLoadImm.size()); + + MI_LOAD_REGISTER_IMM *miLoad = genCmdCast(*miLoadImm[0]); + ASSERT_NE(nullptr, miLoad); + + EXPECT_EQ(DebugModeRegisterOffset::registerOffset, miLoad->getRegisterOffset()); + EXPECT_EQ(DebugModeRegisterOffset::debugEnabledValue, miLoad->getDataDword()); + + miLoad = genCmdCast(*miLoadImm[1]); + ASSERT_NE(nullptr, miLoad); + + EXPECT_EQ(TdDebugControlRegisterOffset::registerOffset, miLoad->getRegisterOffset()); + EXPECT_EQ(TdDebugControlRegisterOffset::debugEnabledValue, miLoad->getDataDword()); + + for (auto i = 0u; i < numCommandLists; i++) { + auto commandList = CommandList::fromHandle(commandLists[i]); + commandList->destroy(); + } + + commandQueue->destroy(); +} + +using DeviceWithDebuggerEnabledTest = Test; + +TEST_F(DeviceWithDebuggerEnabledTest, givenDebuggingEnabledWhenDeviceIsCreatedThenItHasDebugSurfaceCreated) { + EXPECT_NE(nullptr, deviceL0->getDebugSurface()); +} + +} // namespace ult +} // namespace L0 diff --git a/level_zero/core/test/unit_tests/white_box.h b/level_zero/core/test/unit_tests/white_box.h new file mode 100644 index 0000000000..2785041681 --- /dev/null +++ b/level_zero/core/test/unit_tests/white_box.h @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2019-2020 Intel Corporation + * + * SPDX-License-Identifier: MIT + * + */ + +#pragma once + +namespace L0 { +namespace ult { + +template +struct WhiteBox : public Type {}; + +template +WhiteBox *whitebox_cast(Type *obj) { + return static_cast *>(obj); +} + +template +WhiteBox &whitebox_cast(Type &obj) { + return static_cast &>(obj); +} + +template +Type *blackbox_cast(WhiteBox *obj) { + return static_cast(obj); +} + +} // namespace ult +} // namespace L0 diff --git a/shared/source/helpers/hw_helper.h b/shared/source/helpers/hw_helper.h index 370d8a7cf2..2040671403 100644 --- a/shared/source/helpers/hw_helper.h +++ b/shared/source/helpers/hw_helper.h @@ -8,6 +8,7 @@ #pragma once #include "shared/source/built_ins/sip.h" #include "shared/source/command_stream/linear_stream.h" +#include "shared/source/commands/bxml_generator_glue.h" #include "shared/source/helpers/aux_translation.h" #include "shared/source/helpers/hw_cmds.h"