Skip to content

Commit

Permalink
levelzero: use zesInit() when available
Browse files Browse the repository at this point in the history
When zesInit() is available (starting in specs 1.5), we don't need
all the stuff to set ZES_ENABLE_SYSMAN=1 in the environment anymore.

Unfortunately  zesInit() is available but returns an error in current
runtimes. Hence we'd need AC_TRY_RUN() to be sure we can enable it
and disable the ZES_ENABLE_SYSMAN=1 stuff.

Signed-off-by: Brice Goglin <Brice.Goglin@inria.fr>
  • Loading branch information
bgoglin committed Jun 9, 2023
1 parent cc2a17d commit 22f89c0
Show file tree
Hide file tree
Showing 5 changed files with 32 additions and 9 deletions.
2 changes: 2 additions & 0 deletions config/hwloc.m4
Expand Up @@ -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
Expand All @@ -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])
Expand Down
19 changes: 15 additions & 4 deletions 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.
*/

Expand Down Expand Up @@ -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);

Expand All @@ -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
Expand All @@ -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) {
Expand Down
5 changes: 3 additions & 2 deletions hwloc/topology.c
Expand Up @@ -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
Expand Down Expand Up @@ -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)
Expand Down
5 changes: 3 additions & 2 deletions include/hwloc/levelzero.h
Expand Up @@ -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.
*
Expand Down
10 changes: 9 additions & 1 deletion 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.
*/

Expand All @@ -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) {
Expand Down

0 comments on commit 22f89c0

Please sign in to comment.