1# CMake find_package() module for level-zero 2# 3# Example usage: 4# 5# find_package(LevelZero) 6# 7# If successful, the following variables will be defined: 8# LevelZero_FOUND 9# LevelZero_INCLUDE_DIRS 10# LevelZero_LIBRARY 11# LevelZero_LIBRARIES_DIR 12# 13# By default, the module searches the standard paths to locate the "ze_api.h" 14# and the ze_loader shared library. When using a custom level-zero installation, 15# the environment variable "LEVEL_ZERO_DIR" should be specified telling the 16# module to get the level-zero library and headers from that location. 17 18include(FindPackageHandleStandardArgs) 19 20# Search path priority 21# 1. CMake Variable LEVEL_ZERO_DIR 22# 2. Environment Variable LEVEL_ZERO_DIR 23 24if(NOT LEVEL_ZERO_DIR) 25 if(DEFINED ENV{LEVEL_ZERO_DIR}) 26 set(LEVEL_ZERO_DIR "$ENV{LEVEL_ZERO_DIR}") 27 endif() 28endif() 29 30if(LEVEL_ZERO_DIR) 31 find_path(LevelZero_INCLUDE_DIR 32 NAMES level_zero/ze_api.h 33 PATHS ${LEVEL_ZERO_DIR}/include 34 NO_DEFAULT_PATH 35 ) 36 37 if(LINUX) 38 find_library(LevelZero_LIBRARY 39 NAMES ze_loader 40 PATHS ${LEVEL_ZERO_DIR}/lib 41 ${LEVEL_ZERO_DIR}/lib/x86_64-linux-gnu 42 NO_DEFAULT_PATH 43 ) 44 else() 45 find_library(LevelZero_LIBRARY 46 NAMES ze_loader 47 PATHS ${LEVEL_ZERO_DIR}/lib 48 NO_DEFAULT_PATH 49 ) 50 endif() 51else() 52 find_path(LevelZero_INCLUDE_DIR 53 NAMES level_zero/ze_api.h 54 ) 55 56 find_library(LevelZero_LIBRARY 57 NAMES ze_loader 58 ) 59endif() 60 61# Compares the two version string that are supposed to be in x.y.z format 62# and reports if the argument VERSION_STR1 is greater than or equal than 63# version_str2. The strings are compared lexicographically after conversion to 64# lists of equal lengths, with the shorter string getting zero-padded. 65function(compare_versions VERSION_STR1 VERSION_STR2 OUTPUT) 66 # Convert the strings to list 67 string(REPLACE "." ";" VL1 ${VERSION_STR1}) 68 string(REPLACE "." ";" VL2 ${VERSION_STR2}) 69 # get lengths of both lists 70 list(LENGTH VL1 VL1_LEN) 71 list(LENGTH VL2 VL2_LEN) 72 set(LEN ${VL1_LEN}) 73 # If they differ in size pad the shorter list with 0s 74 if(VL1_LEN GREATER VL2_LEN) 75 math(EXPR DIFF "${VL1_LEN} - ${VL2_LEN}" OUTPUT_FORMAT DECIMAL) 76 foreach(IDX RANGE 1 ${DIFF} 1) 77 list(APPEND VL2 "0") 78 endforeach() 79 elseif(VL2_LEN GREATER VL2_LEN) 80 math(EXPR DIFF "${VL1_LEN} - ${VL2_LEN}" OUTPUT_FORMAT DECIMAL) 81 foreach(IDX RANGE 1 ${DIFF} 1) 82 list(APPEND VL2 "0") 83 endforeach() 84 set(LEN ${VL2_LEN}) 85 endif() 86 math(EXPR LEN_SUB_ONE "${LEN}-1") 87 foreach(IDX RANGE 0 ${LEN_SUB_ONE} 1) 88 list(GET VL1 ${IDX} VAL1) 89 list(GET VL2 ${IDX} VAL2) 90 91 if(${VAL1} GREATER ${VAL2}) 92 set(${OUTPUT} TRUE PARENT_SCOPE) 93 break() 94 elseif(${VAL1} LESS ${VAL2}) 95 set(${OUTPUT} FALSE PARENT_SCOPE) 96 break() 97 else() 98 set(${OUTPUT} TRUE PARENT_SCOPE) 99 endif() 100 endforeach() 101 102 endfunction(compare_versions) 103 104# Creates a small function to run and extract the LevelZero loader version. 105function(get_l0_loader_version) 106 107 set(L0_VERSIONEER_SRC 108 [====[ 109 #include <iostream> 110 #include <level_zero/loader/ze_loader.h> 111 #include <string> 112 int main() { 113 ze_result_t result; 114 std::string loader("loader"); 115 zel_component_version_t *versions; 116 size_t size = 0; 117 result = zeInit(0); 118 if (result != ZE_RESULT_SUCCESS) { 119 std::cerr << "Failed to init ze driver" << std::endl; 120 return -1; 121 } 122 zelLoaderGetVersions(&size, nullptr); 123 versions = new zel_component_version_t[size]; 124 zelLoaderGetVersions(&size, versions); 125 for (size_t i = 0; i < size; i++) { 126 if (loader.compare(versions[i].component_name) == 0) { 127 std::cout << versions[i].component_lib_version.major << "." 128 << versions[i].component_lib_version.minor << "." 129 << versions[i].component_lib_version.patch; 130 break; 131 } 132 } 133 delete[] versions; 134 return 0; 135 } 136 ]====] 137 ) 138 139 set(L0_VERSIONEER_FILE ${CMAKE_BINARY_DIR}/temp/l0_versioneer.cpp) 140 141 file(WRITE ${L0_VERSIONEER_FILE} "${L0_VERSIONEER_SRC}") 142 143 # We need both the directories in the include path as ze_loader.h 144 # includes "ze_api.h" and not "level_zero/ze_api.h". 145 list(APPEND INCLUDE_DIRS ${LevelZero_INCLUDE_DIR}) 146 list(APPEND INCLUDE_DIRS ${LevelZero_INCLUDE_DIR}/level_zero) 147 list(JOIN INCLUDE_DIRS ";" INCLUDE_DIRS_STR) 148 try_run(L0_VERSIONEER_RUN L0_VERSIONEER_COMPILE 149 "${CMAKE_BINARY_DIR}" 150 "${L0_VERSIONEER_FILE}" 151 LINK_LIBRARIES ${LevelZero_LIBRARY} 152 CMAKE_FLAGS 153 "-DINCLUDE_DIRECTORIES=${INCLUDE_DIRS_STR}" 154 RUN_OUTPUT_VARIABLE L0_VERSION 155 ) 156 if(${L0_VERSIONEER_COMPILE} AND (DEFINED L0_VERSIONEER_RUN)) 157 set(LevelZero_VERSION ${L0_VERSION} PARENT_SCOPE) 158 message(STATUS "Found Level Zero of version: ${L0_VERSION}") 159 else() 160 message(FATAL_ERROR 161 "Could not compile a level-zero program to extract loader version" 162 ) 163 endif() 164endfunction(get_l0_loader_version) 165 166if(LevelZero_INCLUDE_DIR AND LevelZero_LIBRARY) 167 list(APPEND LevelZero_LIBRARIES "${LevelZero_LIBRARY}") 168 list(APPEND LevelZero_INCLUDE_DIRS ${LevelZero_INCLUDE_DIR}) 169 if(OpenCL_FOUND) 170 list(APPEND LevelZero_INCLUDE_DIRS ${OpenCL_INCLUDE_DIRS}) 171 endif() 172 173 cmake_path(GET LevelZero_LIBRARY PARENT_PATH LevelZero_LIBRARIES_PATH) 174 set(LevelZero_LIBRARIES_DIR ${LevelZero_LIBRARIES_PATH}) 175 176 if(NOT TARGET LevelZero::LevelZero) 177 add_library(LevelZero::LevelZero INTERFACE IMPORTED) 178 set_target_properties(LevelZero::LevelZero 179 PROPERTIES INTERFACE_LINK_LIBRARIES "${LevelZero_LIBRARIES}" 180 ) 181 set_target_properties(LevelZero::LevelZero 182 PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${LevelZero_INCLUDE_DIRS}" 183 ) 184 endif() 185endif() 186 187# Check if a specific version of Level Zero is required 188if(LevelZero_FIND_VERSION) 189 get_l0_loader_version() 190 set(VERSION_GT_FIND_VERSION FALSE) 191 compare_versions( 192 ${LevelZero_VERSION} 193 ${LevelZero_FIND_VERSION} 194 VERSION_GT_FIND_VERSION 195 ) 196 if(${VERSION_GT_FIND_VERSION}) 197 set(LevelZero_FOUND TRUE) 198 else() 199 set(LevelZero_FOUND FALSE) 200 endif() 201else() 202 set(LevelZero_FOUND TRUE) 203endif() 204 205find_package_handle_standard_args(LevelZero 206 REQUIRED_VARS 207 LevelZero_FOUND 208 LevelZero_INCLUDE_DIRS 209 LevelZero_LIBRARY 210 LevelZero_LIBRARIES_DIR 211 HANDLE_COMPONENTS 212) 213mark_as_advanced(LevelZero_LIBRARY LevelZero_INCLUDE_DIRS) 214 215if(LevelZero_FOUND) 216 find_package_message(LevelZero "Found LevelZero: ${LevelZero_LIBRARY}" 217 "(found version ${LevelZero_VERSION})" 218 ) 219else() 220 find_package_message(LevelZero "Could not find LevelZero" "") 221endif() 222