[ELF] Refactor merge-* tests
[llvm-project.git] / mlir / cmake / modules / FindLevelZero.cmake
blob012187f0afc0b07c37b64e744c835af964bd65ae
1 # CMake find_package() module for level-zero
3 # Example usage:
5 # find_package(LevelZero)
7 # If successful, the following variables will be defined:
8 # LevelZero_FOUND
9 # LevelZero_INCLUDE_DIRS
10 # LevelZero_LIBRARY
11 # LevelZero_LIBRARIES_DIR
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.
18 include(FindPackageHandleStandardArgs)
20 # Search path priority
21 # 1. CMake Variable LEVEL_ZERO_DIR
22 # 2. Environment Variable LEVEL_ZERO_DIR
24 if(NOT LEVEL_ZERO_DIR)
25     if(DEFINED ENV{LEVEL_ZERO_DIR})
26         set(LEVEL_ZERO_DIR "$ENV{LEVEL_ZERO_DIR}")
27     endif()
28 endif()
30 if(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     )
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()
51 else()
52     find_path(LevelZero_INCLUDE_DIR
53         NAMES level_zero/ze_api.h
54     )
56     find_library(LevelZero_LIBRARY
57         NAMES ze_loader
58     )
59 endif()
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.
65 function(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)
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()
102     endfunction(compare_versions)
104 # Creates a small function to run and extract the LevelZero loader version.
105 function(get_l0_loader_version)
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     )
139     set(L0_VERSIONEER_FILE ${CMAKE_BINARY_DIR}/temp/l0_versioneer.cpp)
141     file(WRITE ${L0_VERSIONEER_FILE} "${L0_VERSIONEER_SRC}")
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()
164 endfunction(get_l0_loader_version)
166 if(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()
173     cmake_path(GET LevelZero_LIBRARY PARENT_PATH LevelZero_LIBRARIES_PATH)
174     set(LevelZero_LIBRARIES_DIR ${LevelZero_LIBRARIES_PATH})
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()
185 endif()
187 # Check if a specific version of Level Zero is required
188 if(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()
201 else()
202     set(LevelZero_FOUND TRUE)
203 endif()
205 find_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
213 mark_as_advanced(LevelZero_LIBRARY LevelZero_INCLUDE_DIRS)
215 if(LevelZero_FOUND)
216     find_package_message(LevelZero "Found LevelZero: ${LevelZero_LIBRARY}"
217         "(found version ${LevelZero_VERSION})"
218     )
219 else()
220     find_package_message(LevelZero "Could not find LevelZero" "")
221 endif()