diff --git a/config/hwloc.m4 b/config/hwloc.m4 index 7b2fdb8a38..3fddacf49e 100644 --- a/config/hwloc.m4 +++ b/config/hwloc.m4 @@ -1409,6 +1409,7 @@ return clGetDeviceIDs(0, 0, 0, NULL, NULL); HWLOC_PKG_CHECK_MODULES([LEVELZERO], [libze_loader], [zesDevicePciGetProperties], [level_zero/zes_api.h], [hwloc_levelzero_happy=yes HWLOC_LEVELZERO_REQUIRES=libze_loader + AC_CHECK_LIB([ze_loader], [zesInit], [AC_DEFINE(HWLOC_HAVE_ZESINIT, 1, [Define to 1 if zesInit is available])]) AC_CHECK_LIB([ze_loader], [zeDevicePciGetPropertiesExt], [AC_DEFINE(HWLOC_HAVE_ZEDEVICEPCIGETPROPERTIESEXT, 1, [Define to 1 if zeDevicePciGetPropertiesExt is available])]) ], [hwloc_levelzero_happy=no]) if test x$hwloc_levelzero_happy = xno; then @@ -1419,6 +1420,7 @@ return clGetDeviceIDs(0, 0, 0, NULL, NULL); AC_CHECK_LIB([ze_loader], [zesDevicePciGetProperties], [HWLOC_LEVELZERO_LIBS="-lze_loader" + AC_CHECK_LIB([ze_loader], [zesInit], [AC_DEFINE(HWLOC_HAVE_ZESINIT, 1, [Define to 1 if zesInit is available])]) AC_CHECK_LIB([ze_loader], [zeDevicePciGetPropertiesExt], [AC_DEFINE(HWLOC_HAVE_ZEDEVICEPCIGETPROPERTIESEXT, 1, [Define to 1 if zeDevicePciGetPropertiesExt is available])]) ], [hwloc_levelzero_happy=no]) ], [hwloc_levelzero_happy=no]) diff --git a/hwloc/topology-levelzero.c b/hwloc/topology-levelzero.c index 3f111c845a..cac24d64b4 100644 --- a/hwloc/topology-levelzero.c +++ b/hwloc/topology-levelzero.c @@ -1,5 +1,5 @@ /* - * Copyright © 2020-2022 Inria. All rights reserved. + * Copyright © 2020-2023 Inria. All rights reserved. * See COPYING in top-level directory. */ @@ -604,8 +604,7 @@ hwloc_levelzero_discover(struct hwloc_backend *backend, struct hwloc_disc_status uint32_t nbdrivers, i, k, zeidx; struct hwloc_osdev_array oarray; struct hwloc_levelzero_ports hports; - int sysman_maybe_missing = 0; /* 1 if ZES_ENABLE_SYSMAN=1 was NOT set early, 2 if ZES_ENABLE_SYSMAN=0 */ - char *env; + int sysman_maybe_missing = 0; /* 1 if ZES_ENABLE_SYSMAN=1 was NOT set early and zesInit() isn't available, 2 if ZES_ENABLE_SYSMAN=0 */ hwloc__levelzero_osdev_array_init(&oarray); @@ -617,13 +616,23 @@ hwloc_levelzero_discover(struct hwloc_backend *backend, struct hwloc_disc_status if (filter == HWLOC_TYPE_FILTER_KEEP_NONE) return 0; +#ifdef HWLOC_HAVE_ZESINIT + res = zesInit(0); + if (res != ZE_RESULT_SUCCESS) { + if (HWLOC_SHOW_ALL_ERRORS()) { + fprintf(stderr, "Failed to initialize LevelZero in zesInit(): 0x%x\n", (unsigned)res); + } + return 0; + } +#else /* !HWLOC_HAVE_ZESINIT */ /* Tell L0 to create sysman devices. * If somebody already initialized L0 without Sysman, * zesDeviceGetProperties() will fail and warn in hwloc__levelzero_properties_get(). * The lib constructor and Windows DllMain tried to set ZES_ENABLE_SYSMAN=1 early (see topology.c), * we try again in case they didn't. */ - env = getenv("ZES_ENABLE_SYSMAN"); + { + char *env = getenv("ZES_ENABLE_SYSMAN"); if (!env) { /* setenv() is safer than putenv() but not available on Windows */ #ifdef HWLOC_WIN_SYS @@ -636,6 +645,8 @@ hwloc_levelzero_discover(struct hwloc_backend *backend, struct hwloc_disc_status } else if (!atoi(env)) { sysman_maybe_missing = 2; } + } +#endif /* !HWLOC_HAVE_ZESINIT */ res = zeInit(0); if (res != ZE_RESULT_SUCCESS) { diff --git a/hwloc/topology.c b/hwloc/topology.c index dccb5cde71..b71d71c016 100644 --- a/hwloc/topology.c +++ b/hwloc/topology.c @@ -54,9 +54,10 @@ #endif -#ifdef HWLOC_HAVE_LEVELZERO +#if (defined HWLOC_HAVE_LEVELZERO) && !(defined HWLOC_HAVE_ZESINIT) /* * Define ZES_ENABLE_SYSMAN=1 early so that the LevelZero backend gets Sysman enabled. + * This is only for old releases (<1.5) without zesInit(). * * Only if the levelzero was enabled in this build so that we don't enable sysman * for external levelzero users when hwloc doesn't need it. If somebody ever loads @@ -101,7 +102,7 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved) return TRUE; } #endif -#endif /* HWLOC_HAVE_LEVELZERO */ +#endif /* HWLOC_HAVE_LEVELZERO && !HWLOC_HAVE_ZESINIT */ unsigned hwloc_get_api_version(void) diff --git a/include/hwloc/levelzero.h b/include/hwloc/levelzero.h index 64f6fe86c0..d9b070037e 100644 --- a/include/hwloc/levelzero.h +++ b/include/hwloc/levelzero.h @@ -44,8 +44,9 @@ extern "C" { * the Level Zero device \p device. * * Topology \p topology and device \p device must match the local machine. - * The Level Zero must have been initialized with Sysman enabled - * (ZES_ENABLE_SYSMAN=1 in the environment). + * The Level Zero library must have been initialized with Sysman enabled + * (by calling zesInit(0) in versions >=1.5, + * or by setting ZES_ENABLE_SYSMAN=1 in the environment). * I/O devices detection and the Level Zero component are not needed in the * topology. * diff --git a/tests/hwloc/levelzero.c b/tests/hwloc/levelzero.c index 6154f8860a..657675b3d0 100644 --- a/tests/hwloc/levelzero.c +++ b/tests/hwloc/levelzero.c @@ -1,5 +1,5 @@ /* - * Copyright © 2021 Inria. All rights reserved. + * Copyright © 2021-2023 Inria. All rights reserved. * See COPYING in top-level directory. */ @@ -22,7 +22,15 @@ int main(void) ze_result_t res; int err = 0; +#ifdef HWLOC_HAVE_ZESINIT + zesInit(0); + if (res != ZE_RESULT_SUCCESS) { + fprintf(stderr, "Failed to initialize LevelZero in zesInit(): %d\n", (int)res); + return 0; + } +#else putenv((char *) "ZES_ENABLE_SYSMAN=1"); +#endif res = zeInit(0); if (res != ZE_RESULT_SUCCESS) {