mirror of
https://github.com/intel/compute-runtime.git
synced 2026-01-05 09:09:04 +08:00
refactor: Move Sysman APIs to level_zero/sysman/source/api
Signed-off-by: Jitendra Sharma <jitendra.sharma@intel.com>
This commit is contained in:
committed by
Compute-Runtime-Automation
parent
55585b1fd8
commit
541e4e57f6
17
level_zero/sysman/source/api/scheduler/CMakeLists.txt
Normal file
17
level_zero/sysman/source/api/scheduler/CMakeLists.txt
Normal file
@@ -0,0 +1,17 @@
|
||||
#
|
||||
# Copyright (C) 2020-2023 Intel Corporation
|
||||
#
|
||||
# SPDX-License-Identifier: MIT
|
||||
#
|
||||
|
||||
target_sources(${L0_STATIC_LIB_NAME}
|
||||
PRIVATE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/sysman_os_scheduler.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/sysman_scheduler.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/sysman_scheduler.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/sysman_scheduler_imp.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/sysman_scheduler_imp.h
|
||||
)
|
||||
|
||||
add_subdirectories()
|
||||
25
level_zero/sysman/source/api/scheduler/linux/CMakeLists.txt
Normal file
25
level_zero/sysman/source/api/scheduler/linux/CMakeLists.txt
Normal file
@@ -0,0 +1,25 @@
|
||||
#
|
||||
# Copyright (C) 2020-2023 Intel Corporation
|
||||
#
|
||||
# SPDX-License-Identifier: MIT
|
||||
#
|
||||
|
||||
if(UNIX)
|
||||
target_sources(${L0_STATIC_LIB_NAME}
|
||||
PRIVATE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/sysman_os_scheduler_imp.h
|
||||
)
|
||||
|
||||
if(NEO_ENABLE_i915_PRELIM_DETECTION)
|
||||
target_sources(${L0_STATIC_LIB_NAME}
|
||||
PRIVATE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/sysman_os_scheduler_imp_prelim.cpp
|
||||
)
|
||||
else()
|
||||
target_sources(${L0_STATIC_LIB_NAME}
|
||||
PRIVATE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/sysman_os_scheduler_imp.cpp
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
@@ -0,0 +1,417 @@
|
||||
/*
|
||||
* Copyright (C) 2020-2023 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#include "level_zero/sysman/source/api/scheduler/linux/sysman_os_scheduler_imp.h"
|
||||
|
||||
#include "shared/source/debug_settings/debug_settings_manager.h"
|
||||
#include "shared/source/os_interface/linux/engine_info.h"
|
||||
|
||||
#include "level_zero/sysman/source/linux/sysman_fs_access.h"
|
||||
#include "level_zero/sysman/source/linux/zes_os_sysman_imp.h"
|
||||
#include "level_zero/sysman/source/shared/linux/sysman_kmd_interface.h"
|
||||
#include "level_zero/sysman/source/sysman_const.h"
|
||||
|
||||
namespace L0 {
|
||||
namespace Sysman {
|
||||
|
||||
static ze_result_t readSchedulerValueFromSysfs(SysfsName schedulerSysfsName,
|
||||
LinuxSysmanImp *pSysmanImp,
|
||||
uint32_t subdeviceId,
|
||||
ze_bool_t getDefault,
|
||||
std::vector<std::string> &listOfEngines,
|
||||
zes_engine_type_flag_t engineType,
|
||||
uint64_t &readValue) {
|
||||
ze_result_t result = ZE_RESULT_ERROR_UNKNOWN;
|
||||
uint32_t i = 0;
|
||||
std::vector<uint64_t> readValueVec(listOfEngines.size());
|
||||
std::string path = "";
|
||||
auto pSysmanKmdInterface = pSysmanImp->getSysmanKmdInterface();
|
||||
auto engineBasePath = pSysmanKmdInterface->getEngineBasePath(subdeviceId);
|
||||
auto sysfsName = pSysmanKmdInterface->getSysfsFilePath(schedulerSysfsName, subdeviceId, false);
|
||||
for (const auto &engineName : listOfEngines) {
|
||||
if (getDefault) {
|
||||
path = engineBasePath + "/" + engineName + "/" + ".defaults/" + sysfsName;
|
||||
} else {
|
||||
path = engineBasePath + "/" + engineName + "/" + sysfsName;
|
||||
}
|
||||
result = pSysmanImp->getSysfsAccess().read(path, readValue);
|
||||
if (result == ZE_RESULT_SUCCESS) {
|
||||
pSysmanKmdInterface->convertSysfsValueUnit(SysmanKmdInterface::microSecond,
|
||||
pSysmanKmdInterface->getNativeUnit(schedulerSysfsName),
|
||||
readValue, readValue);
|
||||
readValueVec[i] = readValue;
|
||||
i++;
|
||||
} else {
|
||||
if (result == ZE_RESULT_ERROR_NOT_AVAILABLE) {
|
||||
result = ZE_RESULT_ERROR_UNSUPPORTED_FEATURE;
|
||||
}
|
||||
NEO::printDebugString(NEO::DebugManager.flags.PrintDebugMessages.get(), stderr, "Error@ %s(): Failed to read from %s and returning error:0x%x \n", __FUNCTION__, path.c_str(), result);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
// For compute engines with different timeout values, use the maximum value
|
||||
if (schedulerSysfsName == SysfsName::syfsNameSchedulerTimeout && engineType == ZES_ENGINE_TYPE_FLAG_COMPUTE) {
|
||||
readValue = *std::max_element(readValueVec.begin(), readValueVec.end());
|
||||
return result;
|
||||
}
|
||||
|
||||
// check if all engines of the same type have the same scheduling param values
|
||||
if (std::adjacent_find(readValueVec.begin(), readValueVec.end(), std::not_equal_to<>()) == readValueVec.end()) {
|
||||
readValue = readValueVec[0];
|
||||
return result;
|
||||
} else {
|
||||
return ZE_RESULT_ERROR_UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
static ze_result_t writeSchedulerValueToSysfs(SysfsName schedulerSysfsName,
|
||||
LinuxSysmanImp *pSysmanImp,
|
||||
uint32_t subdeviceId,
|
||||
std::vector<std::string> &listOfEngines,
|
||||
zes_engine_type_flag_t engineType,
|
||||
uint64_t writeValue) {
|
||||
ze_result_t result = ZE_RESULT_ERROR_UNKNOWN;
|
||||
auto pSysmanKmdInterface = pSysmanImp->getSysmanKmdInterface();
|
||||
auto sysfsName = pSysmanKmdInterface->getSysfsFilePath(schedulerSysfsName, subdeviceId, false);
|
||||
pSysmanKmdInterface->convertSysfsValueUnit(pSysmanKmdInterface->getNativeUnit(schedulerSysfsName),
|
||||
SysmanKmdInterface::microSecond, writeValue, writeValue);
|
||||
auto engineBasePath = pSysmanKmdInterface->getEngineBasePath(subdeviceId);
|
||||
for (const auto &engineName : listOfEngines) {
|
||||
auto path = engineBasePath + "/" + engineName + "/" + sysfsName;
|
||||
result = pSysmanImp->getSysfsAccess().write(path, writeValue);
|
||||
if (result != ZE_RESULT_SUCCESS) {
|
||||
if (result == ZE_RESULT_ERROR_NOT_AVAILABLE) {
|
||||
result = ZE_RESULT_ERROR_UNSUPPORTED_FEATURE;
|
||||
}
|
||||
NEO::printDebugString(NEO::DebugManager.flags.PrintDebugMessages.get(), stderr, "Error@ %s(): Failed to write into %s and returning error:0x%x \n", __FUNCTION__, path.c_str(), result);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
ze_result_t LinuxSchedulerImp::getCurrentMode(zes_sched_mode_t *pMode) {
|
||||
uint64_t timeout = 0;
|
||||
uint64_t timeslice = 0;
|
||||
uint64_t heartbeat = 0;
|
||||
ze_result_t result = getPreemptTimeout(timeout, false);
|
||||
if (result != ZE_RESULT_SUCCESS) {
|
||||
NEO::printDebugString(NEO::DebugManager.flags.PrintDebugMessages.get(), stderr, "Error@ %s(): Failed to get preempt timeout and returning error:0x%x \n", __FUNCTION__, result);
|
||||
return result;
|
||||
}
|
||||
result = getTimesliceDuration(timeslice, false);
|
||||
if (result != ZE_RESULT_SUCCESS) {
|
||||
NEO::printDebugString(NEO::DebugManager.flags.PrintDebugMessages.get(), stderr, "Error@ %s(): Failed to get timeslice duration and returning error:0x%x \n", __FUNCTION__, result);
|
||||
return result;
|
||||
}
|
||||
result = getHeartbeatInterval(heartbeat, false);
|
||||
if (result != ZE_RESULT_SUCCESS) {
|
||||
NEO::printDebugString(NEO::DebugManager.flags.PrintDebugMessages.get(), stderr, "Error@ %s(): Failed to get heartbeat interval and returning error:0x%x \n", __FUNCTION__, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
if (timeslice > 0) {
|
||||
*pMode = ZES_SCHED_MODE_TIMESLICE;
|
||||
} else {
|
||||
if (timeout > 0) {
|
||||
*pMode = ZES_SCHED_MODE_TIMEOUT;
|
||||
} else {
|
||||
auto pSysmanKmdInterface = pLinuxSysmanImp->getSysmanKmdInterface();
|
||||
if (pSysmanKmdInterface->useDefaultMaximumWatchdogTimeoutForExclusiveMode()) {
|
||||
|
||||
uint64_t defaultHeartbeatInterval = 0;
|
||||
result = readSchedulerValueFromSysfs(SysfsName::syfsNameSchedulerWatchDogTimeoutMaximum,
|
||||
pLinuxSysmanImp, subdeviceId, true,
|
||||
listOfEngines, engineType, defaultHeartbeatInterval);
|
||||
if (result != ZE_RESULT_SUCCESS) {
|
||||
NEO::printDebugString(NEO::DebugManager.flags.PrintDebugMessages.get(), stderr, "Error@ %s(): Failed to get default heartbeat interval and returning error:0x%x \n", __FUNCTION__, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
// If default maximum value is used, then heartbeat is expected to be
|
||||
// set to the default maximum
|
||||
if (heartbeat == defaultHeartbeatInterval) {
|
||||
*pMode = ZES_SCHED_MODE_EXCLUSIVE;
|
||||
} else {
|
||||
*pMode = ZES_SCHED_MODE_FORCE_UINT32;
|
||||
result = ZE_RESULT_ERROR_UNKNOWN;
|
||||
}
|
||||
} else {
|
||||
if (heartbeat == 0) {
|
||||
// If we are here, it means heartbeat = 0, timeout = 0, timeslice = 0.
|
||||
*pMode = ZES_SCHED_MODE_EXCLUSIVE;
|
||||
} else {
|
||||
// If we are here it means heartbeat > 0, timeout = 0, timeslice = 0.
|
||||
// And we dont know what that mode is.
|
||||
*pMode = ZES_SCHED_MODE_FORCE_UINT32;
|
||||
result = ZE_RESULT_ERROR_UNKNOWN;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
ze_result_t LinuxSchedulerImp::setExclusiveModeImp() {
|
||||
uint64_t timeslice = 0, timeout = 0, heartbeat = 0;
|
||||
ze_result_t result = setPreemptTimeout(timeout);
|
||||
if (result != ZE_RESULT_SUCCESS) {
|
||||
NEO::printDebugString(NEO::DebugManager.flags.PrintDebugMessages.get(), stderr, "Error@ %s(): Failed to set preempt timeout and returning error:0x%x \n", __FUNCTION__, result);
|
||||
return result;
|
||||
}
|
||||
result = setTimesliceDuration(timeslice);
|
||||
if (result != ZE_RESULT_SUCCESS) {
|
||||
NEO::printDebugString(NEO::DebugManager.flags.PrintDebugMessages.get(), stderr, "Error@ %s(): Failed to set timeslice duration and returning error:0x%x \n", __FUNCTION__, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
auto pSysmanKmdInterface = pLinuxSysmanImp->getSysmanKmdInterface();
|
||||
if (pSysmanKmdInterface->useDefaultMaximumWatchdogTimeoutForExclusiveMode()) {
|
||||
|
||||
result = readSchedulerValueFromSysfs(SysfsName::syfsNameSchedulerWatchDogTimeoutMaximum,
|
||||
pLinuxSysmanImp, subdeviceId, true,
|
||||
listOfEngines, engineType, heartbeat);
|
||||
if (result != ZE_RESULT_SUCCESS) {
|
||||
NEO::printDebugString(NEO::DebugManager.flags.PrintDebugMessages.get(), stderr, "Error@ %s(): Failed to get default heartbeat interval and returning error:0x%x \n", __FUNCTION__, result);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
result = setHeartbeatInterval(heartbeat);
|
||||
return result;
|
||||
}
|
||||
|
||||
ze_result_t LinuxSchedulerImp::setExclusiveMode(ze_bool_t *pNeedReload) {
|
||||
*pNeedReload = false;
|
||||
|
||||
zes_sched_mode_t currMode;
|
||||
ze_result_t result = getCurrentMode(&currMode);
|
||||
if (result != ZE_RESULT_SUCCESS) {
|
||||
NEO::printDebugString(NEO::DebugManager.flags.PrintDebugMessages.get(), stderr, "Error@ %s(): Failed to get current mode and returning error:0x%x \n", __FUNCTION__, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
if (currMode == ZES_SCHED_MODE_COMPUTE_UNIT_DEBUG) {
|
||||
// Unset this mode
|
||||
result = disableComputeUnitDebugMode(pNeedReload);
|
||||
if (result != ZE_RESULT_SUCCESS) {
|
||||
NEO::printDebugString(NEO::DebugManager.flags.PrintDebugMessages.get(), stderr, "Error@ %s(): Failed to diasble COMPUTE_UNIT_DEBUG mode and returning error:0x%x \n", __FUNCTION__, result);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
return setExclusiveModeImp();
|
||||
}
|
||||
|
||||
ze_result_t LinuxSchedulerImp::getTimeoutModeProperties(ze_bool_t getDefaults, zes_sched_timeout_properties_t *pConfig) {
|
||||
uint64_t heartbeat = 0;
|
||||
ze_result_t result = getHeartbeatInterval(heartbeat, getDefaults);
|
||||
if (result != ZE_RESULT_SUCCESS) {
|
||||
NEO::printDebugString(NEO::DebugManager.flags.PrintDebugMessages.get(), stderr, "Error@ %s(): Failed to get heart beat interval and returning error:0x%x \n", __FUNCTION__, result);
|
||||
return result;
|
||||
}
|
||||
pConfig->watchdogTimeout = heartbeat;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
ze_result_t LinuxSchedulerImp::getTimesliceModeProperties(ze_bool_t getDefaults, zes_sched_timeslice_properties_t *pConfig) {
|
||||
uint64_t timeout = 0, timeslice = 0;
|
||||
ze_result_t result = getPreemptTimeout(timeout, getDefaults);
|
||||
if (result != ZE_RESULT_SUCCESS) {
|
||||
NEO::printDebugString(NEO::DebugManager.flags.PrintDebugMessages.get(), stderr, "Error@ %s(): Failed to get preempt timeout and returning error:0x%x \n", __FUNCTION__, result);
|
||||
return result;
|
||||
}
|
||||
result = getTimesliceDuration(timeslice, getDefaults);
|
||||
if (result != ZE_RESULT_SUCCESS) {
|
||||
NEO::printDebugString(NEO::DebugManager.flags.PrintDebugMessages.get(), stderr, "Error@ %s(): Failed to get timeslice duration and returning error:0x%x \n", __FUNCTION__, result);
|
||||
return result;
|
||||
}
|
||||
pConfig->interval = timeslice;
|
||||
pConfig->yieldTimeout = timeout;
|
||||
return result;
|
||||
}
|
||||
|
||||
ze_result_t LinuxSchedulerImp::setTimeoutMode(zes_sched_timeout_properties_t *pProperties, ze_bool_t *pNeedReload) {
|
||||
*pNeedReload = false;
|
||||
zes_sched_mode_t currMode;
|
||||
ze_result_t result = getCurrentMode(&currMode);
|
||||
if (result != ZE_RESULT_SUCCESS) {
|
||||
NEO::printDebugString(NEO::DebugManager.flags.PrintDebugMessages.get(), stderr, "Error@ %s(): Failed to get current mode and returning error:0x%x \n", __FUNCTION__, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
if (pProperties->watchdogTimeout < minTimeoutModeHeartbeat) {
|
||||
// watchdogTimeout(in usec) less than 5000 would be computed to
|
||||
// 0 milli seconds preempt timeout, and then after returning from
|
||||
// this method, we would end up in EXCLUSIVE mode
|
||||
return ZE_RESULT_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
if (currMode == ZES_SCHED_MODE_COMPUTE_UNIT_DEBUG) {
|
||||
// Unset this mode
|
||||
result = disableComputeUnitDebugMode(pNeedReload);
|
||||
if (result != ZE_RESULT_SUCCESS) {
|
||||
NEO::printDebugString(NEO::DebugManager.flags.PrintDebugMessages.get(), stderr, "Error@ %s(): Failed to diasble COMPUTE_UNIT_DEBUG mode and returning error:0x%x \n", __FUNCTION__, result);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
result = setHeartbeatInterval(pProperties->watchdogTimeout);
|
||||
if (result != ZE_RESULT_SUCCESS) {
|
||||
NEO::printDebugString(NEO::DebugManager.flags.PrintDebugMessages.get(), stderr, "Error@ %s(): Failed to set heartbeat interval and returning error:0x%x \n", __FUNCTION__, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
uint64_t timeout = (pProperties->watchdogTimeout) / 5;
|
||||
result = setPreemptTimeout(timeout);
|
||||
if (result != ZE_RESULT_SUCCESS) {
|
||||
NEO::printDebugString(NEO::DebugManager.flags.PrintDebugMessages.get(), stderr, "Error@ %s(): Failed to set preempt timeout and returning error:0x%x \n", __FUNCTION__, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
uint64_t timeslice = 0;
|
||||
result = setTimesliceDuration(timeslice);
|
||||
if (result != ZE_RESULT_SUCCESS) {
|
||||
NEO::printDebugString(NEO::DebugManager.flags.PrintDebugMessages.get(), stderr, "Error@ %s(): Failed to set timeslice duration and returning error:0x%x \n", __FUNCTION__, result);
|
||||
return result;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
ze_result_t LinuxSchedulerImp::setTimesliceMode(zes_sched_timeslice_properties_t *pProperties, ze_bool_t *pNeedReload) {
|
||||
if (pProperties->interval < minTimeoutInMicroSeconds) {
|
||||
// interval(in usec) less than 1000 would be computed to
|
||||
// 0 milli seconds interval.
|
||||
return ZE_RESULT_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
*pNeedReload = false;
|
||||
|
||||
zes_sched_mode_t currMode;
|
||||
ze_result_t result = getCurrentMode(&currMode);
|
||||
if (result != ZE_RESULT_SUCCESS) {
|
||||
NEO::printDebugString(NEO::DebugManager.flags.PrintDebugMessages.get(), stderr, "Error@ %s(): Failed to get current mode and returning error:0x%x \n", __FUNCTION__, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
if (currMode == ZES_SCHED_MODE_COMPUTE_UNIT_DEBUG) {
|
||||
// Unset this mode
|
||||
result = disableComputeUnitDebugMode(pNeedReload);
|
||||
if (result != ZE_RESULT_SUCCESS) {
|
||||
NEO::printDebugString(NEO::DebugManager.flags.PrintDebugMessages.get(), stderr, "Error@ %s(): Failed to diasble COMPUTE_UNIT_DEBUG mode and returning error:0x%x \n", __FUNCTION__, result);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
result = setPreemptTimeout(pProperties->yieldTimeout);
|
||||
if (result != ZE_RESULT_SUCCESS) {
|
||||
NEO::printDebugString(NEO::DebugManager.flags.PrintDebugMessages.get(), stderr, "Error@ %s(): Failed to set preempt timeout and returning error:0x%x \n", __FUNCTION__, result);
|
||||
return result;
|
||||
}
|
||||
result = setTimesliceDuration(pProperties->interval);
|
||||
if (result != ZE_RESULT_SUCCESS) {
|
||||
NEO::printDebugString(NEO::DebugManager.flags.PrintDebugMessages.get(), stderr, "Error@ %s(): Failed to set timeslice duration and returning error:0x%x \n", __FUNCTION__, result);
|
||||
return result;
|
||||
}
|
||||
uint64_t heartbeat = 2500 * (pProperties->interval);
|
||||
return setHeartbeatInterval(heartbeat);
|
||||
}
|
||||
|
||||
ze_result_t LinuxSchedulerImp::getProperties(zes_sched_properties_t &schedProperties) {
|
||||
schedProperties.onSubdevice = onSubdevice;
|
||||
schedProperties.subdeviceId = subdeviceId;
|
||||
schedProperties.canControl = canControlScheduler();
|
||||
schedProperties.engines = this->engineType;
|
||||
schedProperties.supportedModes = (1 << ZES_SCHED_MODE_TIMEOUT) | (1 << ZES_SCHED_MODE_TIMESLICE) | (1 << ZES_SCHED_MODE_EXCLUSIVE);
|
||||
return ZE_RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
ze_result_t LinuxSchedulerImp::getPreemptTimeout(uint64_t &timeout, ze_bool_t getDefault) {
|
||||
|
||||
return readSchedulerValueFromSysfs(SysfsName::syfsNameSchedulerTimeout,
|
||||
pLinuxSysmanImp, subdeviceId, getDefault,
|
||||
listOfEngines, engineType, timeout);
|
||||
}
|
||||
|
||||
ze_result_t LinuxSchedulerImp::getTimesliceDuration(uint64_t ×lice, ze_bool_t getDefault) {
|
||||
|
||||
return readSchedulerValueFromSysfs(SysfsName::syfsNameSchedulerTimeslice,
|
||||
pLinuxSysmanImp, subdeviceId, getDefault,
|
||||
listOfEngines, engineType, timeslice);
|
||||
}
|
||||
|
||||
ze_result_t LinuxSchedulerImp::getHeartbeatInterval(uint64_t &heartbeat, ze_bool_t getDefault) {
|
||||
|
||||
return readSchedulerValueFromSysfs(SysfsName::syfsNameSchedulerWatchDogTimeout,
|
||||
pLinuxSysmanImp, subdeviceId, getDefault,
|
||||
listOfEngines, engineType, heartbeat);
|
||||
}
|
||||
|
||||
ze_result_t LinuxSchedulerImp::setPreemptTimeout(uint64_t timeout) {
|
||||
|
||||
return writeSchedulerValueToSysfs(SysfsName::syfsNameSchedulerTimeout,
|
||||
pLinuxSysmanImp, subdeviceId,
|
||||
listOfEngines, engineType, timeout);
|
||||
}
|
||||
|
||||
ze_result_t LinuxSchedulerImp::setTimesliceDuration(uint64_t timeslice) {
|
||||
|
||||
return writeSchedulerValueToSysfs(SysfsName::syfsNameSchedulerTimeslice,
|
||||
pLinuxSysmanImp, subdeviceId,
|
||||
listOfEngines, engineType, timeslice);
|
||||
}
|
||||
|
||||
ze_result_t LinuxSchedulerImp::setHeartbeatInterval(uint64_t heartbeat) {
|
||||
|
||||
return writeSchedulerValueToSysfs(SysfsName::syfsNameSchedulerWatchDogTimeout,
|
||||
pLinuxSysmanImp, subdeviceId,
|
||||
listOfEngines, engineType, heartbeat);
|
||||
}
|
||||
|
||||
ze_bool_t LinuxSchedulerImp::canControlScheduler() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
ze_result_t LinuxSchedulerImp::setComputeUnitDebugMode(ze_bool_t *pNeedReload) {
|
||||
*pNeedReload = false;
|
||||
return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE;
|
||||
}
|
||||
|
||||
bool LinuxSchedulerImp::isComputeUnitDebugModeEnabled() {
|
||||
return false;
|
||||
}
|
||||
|
||||
ze_result_t LinuxSchedulerImp::disableComputeUnitDebugMode(ze_bool_t *pNeedReload) {
|
||||
*pNeedReload = false;
|
||||
return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE;
|
||||
}
|
||||
|
||||
ze_result_t OsScheduler::getNumEngineTypeAndInstances(
|
||||
std::map<zes_engine_type_flag_t, std::vector<std::string>> &mapOfEngines, OsSysman *pOsSysman, ze_bool_t onSubDevice, uint32_t subDeviceId) {
|
||||
LinuxSysmanImp *pLinuxSysmanImp = static_cast<LinuxSysmanImp *>(pOsSysman);
|
||||
auto pSysfsAccess = &pLinuxSysmanImp->getSysfsAccess();
|
||||
auto pSysmanKmdInterface = pLinuxSysmanImp->getSysmanKmdInterface();
|
||||
return pSysmanKmdInterface->getNumEngineTypeAndInstances(mapOfEngines, pLinuxSysmanImp, pSysfsAccess,
|
||||
onSubDevice, subDeviceId);
|
||||
}
|
||||
|
||||
LinuxSchedulerImp::LinuxSchedulerImp(
|
||||
OsSysman *pOsSysman, zes_engine_type_flag_t type, std::vector<std::string> &listOfEngines, ze_bool_t isSubdevice,
|
||||
uint32_t subdeviceId) : engineType(type), onSubdevice(isSubdevice), subdeviceId(subdeviceId) {
|
||||
pLinuxSysmanImp = static_cast<LinuxSysmanImp *>(pOsSysman);
|
||||
pSysfsAccess = &pLinuxSysmanImp->getSysfsAccess();
|
||||
this->listOfEngines = listOfEngines;
|
||||
}
|
||||
|
||||
std::unique_ptr<OsScheduler> OsScheduler::create(
|
||||
OsSysman *pOsSysman, zes_engine_type_flag_t type, std::vector<std::string> &listOfEngines, ze_bool_t isSubdevice, uint32_t subdeviceId) {
|
||||
std::unique_ptr<LinuxSchedulerImp> pLinuxSchedulerImp = std::make_unique<LinuxSchedulerImp>(pOsSysman, type, listOfEngines, isSubdevice, subdeviceId);
|
||||
return pLinuxSchedulerImp;
|
||||
}
|
||||
|
||||
} // namespace Sysman
|
||||
} // namespace L0
|
||||
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Copyright (C) 2020-2023 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "shared/source/os_interface/linux/drm_neo.h"
|
||||
|
||||
#include "level_zero/sysman/source/api/scheduler/sysman_scheduler_imp.h"
|
||||
#include "level_zero/sysman/source/linux/zes_os_sysman_imp.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace L0 {
|
||||
namespace Sysman {
|
||||
class SysfsAccess;
|
||||
|
||||
// Following below mappings of scheduler properties with sysfs nodes
|
||||
// zes_sched_timeslice_properties_t.interval = timeslice_duration_ms
|
||||
// zes_sched_timeslice_properties_t.yieldTimeout = preempt_timeout_ms
|
||||
// zes_sched_timeout_properties_t. watchdogTimeout = heartbeat_interval_ms
|
||||
class LinuxSchedulerImp : public OsScheduler, NEO::NonCopyableOrMovableClass {
|
||||
public:
|
||||
ze_result_t setExclusiveMode(ze_bool_t *pNeedReload) override;
|
||||
ze_result_t getCurrentMode(zes_sched_mode_t *pMode) override;
|
||||
ze_result_t getTimeoutModeProperties(ze_bool_t getDefaults, zes_sched_timeout_properties_t *pConfig) override;
|
||||
ze_result_t getTimesliceModeProperties(ze_bool_t getDefaults, zes_sched_timeslice_properties_t *pConfig) override;
|
||||
ze_result_t setTimeoutMode(zes_sched_timeout_properties_t *pProperties, ze_bool_t *pNeedReload) override;
|
||||
ze_result_t setTimesliceMode(zes_sched_timeslice_properties_t *pProperties, ze_bool_t *pNeedReload) override;
|
||||
ze_result_t getProperties(zes_sched_properties_t &properties) override;
|
||||
ze_result_t setComputeUnitDebugMode(ze_bool_t *pNeedReload) override;
|
||||
LinuxSchedulerImp() = default;
|
||||
LinuxSchedulerImp(OsSysman *pOsSysman, zes_engine_type_flag_t type,
|
||||
std::vector<std::string> &listOfEngines, ze_bool_t isSubdevice, uint32_t subdeviceId);
|
||||
~LinuxSchedulerImp() override = default;
|
||||
static const std::string engineDir;
|
||||
|
||||
protected:
|
||||
LinuxSysmanImp *pLinuxSysmanImp = nullptr;
|
||||
SysfsAccess *pSysfsAccess = nullptr;
|
||||
zes_engine_type_flag_t engineType = ZES_ENGINE_TYPE_FLAG_OTHER;
|
||||
ze_bool_t onSubdevice = 0;
|
||||
uint32_t subdeviceId = 0;
|
||||
ze_result_t setExclusiveModeImp();
|
||||
ze_result_t updateComputeUnitDebugNode(uint64_t val);
|
||||
ze_result_t getPreemptTimeout(uint64_t &timeout, ze_bool_t getDefault);
|
||||
ze_result_t getTimesliceDuration(uint64_t ×lice, ze_bool_t getDefault);
|
||||
ze_result_t getHeartbeatInterval(uint64_t &heartbeat, ze_bool_t getDefault);
|
||||
ze_result_t setPreemptTimeout(uint64_t timeout);
|
||||
ze_result_t setTimesliceDuration(uint64_t timeslice);
|
||||
ze_result_t setHeartbeatInterval(uint64_t heartbeat);
|
||||
ze_bool_t canControlScheduler();
|
||||
ze_result_t disableComputeUnitDebugMode(ze_bool_t *pNeedReload);
|
||||
bool isComputeUnitDebugModeEnabled();
|
||||
|
||||
private:
|
||||
static const std::string preemptTimeoutMilliSecs;
|
||||
static const std::string defaultPreemptTimeouttMilliSecs;
|
||||
static const std::string timesliceDurationMilliSecs;
|
||||
static const std::string defaultTimesliceDurationMilliSecs;
|
||||
static const std::string heartbeatIntervalMilliSecs;
|
||||
static const std::string defaultHeartbeatIntervalMilliSecs;
|
||||
static const std::string enableEuDebug;
|
||||
std::vector<std::string> listOfEngines = {};
|
||||
};
|
||||
|
||||
} // namespace Sysman
|
||||
} // namespace L0
|
||||
@@ -0,0 +1,571 @@
|
||||
/*
|
||||
* Copyright (C) 2022-2023 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#include "shared/source/debug_settings/debug_settings_manager.h"
|
||||
#include "shared/source/os_interface/linux/engine_info.h"
|
||||
#include "shared/source/os_interface/linux/i915_prelim.h"
|
||||
|
||||
#include "level_zero/sysman/source/api/scheduler/linux/sysman_os_scheduler_imp.h"
|
||||
#include "level_zero/sysman/source/linux/sysman_fs_access.h"
|
||||
#include "level_zero/sysman/source/linux/zes_os_sysman_imp.h"
|
||||
#include "level_zero/sysman/source/sysman_const.h"
|
||||
|
||||
namespace L0 {
|
||||
namespace Sysman {
|
||||
|
||||
const std::string LinuxSchedulerImp::preemptTimeoutMilliSecs("preempt_timeout_ms");
|
||||
const std::string LinuxSchedulerImp::defaultPreemptTimeouttMilliSecs(".defaults/preempt_timeout_ms");
|
||||
const std::string LinuxSchedulerImp::timesliceDurationMilliSecs("timeslice_duration_ms");
|
||||
const std::string LinuxSchedulerImp::defaultTimesliceDurationMilliSecs(".defaults/timeslice_duration_ms");
|
||||
const std::string LinuxSchedulerImp::heartbeatIntervalMilliSecs("heartbeat_interval_ms");
|
||||
const std::string LinuxSchedulerImp::defaultHeartbeatIntervalMilliSecs(".defaults/heartbeat_interval_ms");
|
||||
const std::string LinuxSchedulerImp::engineDir("engine");
|
||||
const std::string LinuxSchedulerImp::enableEuDebug("prelim_enable_eu_debug");
|
||||
constexpr uint16_t milliSecsToMicroSecs = 1000;
|
||||
|
||||
static const std::map<__u16, std::string> i915EngineClassToSysfsEngineMap = {
|
||||
{drm_i915_gem_engine_class::I915_ENGINE_CLASS_RENDER, "rcs"},
|
||||
{static_cast<__u16>(drm_i915_gem_engine_class::I915_ENGINE_CLASS_COMPUTE), "ccs"},
|
||||
{drm_i915_gem_engine_class::I915_ENGINE_CLASS_COPY, "bcs"},
|
||||
{drm_i915_gem_engine_class::I915_ENGINE_CLASS_VIDEO, "vcs"},
|
||||
{drm_i915_gem_engine_class::I915_ENGINE_CLASS_VIDEO_ENHANCE, "vecs"}};
|
||||
|
||||
static const std::map<std::string, zes_engine_type_flag_t> sysfsEngineMapToLevel0EngineType = {
|
||||
{"rcs", ZES_ENGINE_TYPE_FLAG_RENDER},
|
||||
{"ccs", ZES_ENGINE_TYPE_FLAG_COMPUTE},
|
||||
{"bcs", ZES_ENGINE_TYPE_FLAG_DMA},
|
||||
{"vcs", ZES_ENGINE_TYPE_FLAG_MEDIA},
|
||||
{"vecs", ZES_ENGINE_TYPE_FLAG_OTHER}};
|
||||
|
||||
static const std::multimap<zes_engine_type_flag_t, std::string> level0EngineTypeToSysfsEngineMap = {
|
||||
{ZES_ENGINE_TYPE_FLAG_RENDER, "rcs"},
|
||||
{ZES_ENGINE_TYPE_FLAG_COMPUTE, "ccs"},
|
||||
{ZES_ENGINE_TYPE_FLAG_DMA, "bcs"},
|
||||
{ZES_ENGINE_TYPE_FLAG_MEDIA, "vcs"},
|
||||
{ZES_ENGINE_TYPE_FLAG_OTHER, "vecs"}};
|
||||
|
||||
static const std::map<std::string, __u16> sysfsEngineMapToi915EngineClass = {
|
||||
{"rcs", drm_i915_gem_engine_class::I915_ENGINE_CLASS_RENDER},
|
||||
{"ccs", static_cast<__u16>(drm_i915_gem_engine_class::I915_ENGINE_CLASS_COMPUTE)},
|
||||
{"bcs", drm_i915_gem_engine_class::I915_ENGINE_CLASS_COPY},
|
||||
{"vcs", drm_i915_gem_engine_class::I915_ENGINE_CLASS_VIDEO},
|
||||
{"vecs", drm_i915_gem_engine_class::I915_ENGINE_CLASS_VIDEO_ENHANCE}};
|
||||
|
||||
ze_result_t LinuxSchedulerImp::getCurrentMode(zes_sched_mode_t *pMode) {
|
||||
uint64_t timeout = 0;
|
||||
uint64_t timeslice = 0;
|
||||
uint64_t heartbeat = 0;
|
||||
ze_result_t result = getPreemptTimeout(timeout, false);
|
||||
if (result != ZE_RESULT_SUCCESS) {
|
||||
NEO::printDebugString(NEO::DebugManager.flags.PrintDebugMessages.get(), stderr, "Error@ %s(): Failed to get preempt timeout and returning error:0x%x \n", __FUNCTION__, result);
|
||||
return result;
|
||||
}
|
||||
result = getTimesliceDuration(timeslice, false);
|
||||
if (result != ZE_RESULT_SUCCESS) {
|
||||
NEO::printDebugString(NEO::DebugManager.flags.PrintDebugMessages.get(), stderr, "Error@ %s(): Failed to get timeslice duration and returning error:0x%x \n", __FUNCTION__, result);
|
||||
return result;
|
||||
}
|
||||
result = getHeartbeatInterval(heartbeat, false);
|
||||
if (result != ZE_RESULT_SUCCESS) {
|
||||
NEO::printDebugString(NEO::DebugManager.flags.PrintDebugMessages.get(), stderr, "Error@ %s(): Failed to get heartbeat interval and returning error:0x%x \n", __FUNCTION__, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
if (timeslice > 0) {
|
||||
*pMode = ZES_SCHED_MODE_TIMESLICE;
|
||||
} else {
|
||||
if (timeout > 0) {
|
||||
*pMode = ZES_SCHED_MODE_TIMEOUT;
|
||||
} else {
|
||||
if (heartbeat == 0) {
|
||||
// If we are here, it means heartbeat = 0, timeout = 0, timeslice = 0.
|
||||
if (isComputeUnitDebugModeEnabled()) {
|
||||
*pMode = ZES_SCHED_MODE_COMPUTE_UNIT_DEBUG;
|
||||
} else {
|
||||
*pMode = ZES_SCHED_MODE_EXCLUSIVE;
|
||||
}
|
||||
} else {
|
||||
// If we are here it means heartbeat > 0, timeout = 0, timeslice = 0.
|
||||
// And we dont know what that mode is.
|
||||
*pMode = ZES_SCHED_MODE_FORCE_UINT32;
|
||||
result = ZE_RESULT_ERROR_UNKNOWN;
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
ze_result_t LinuxSchedulerImp::setExclusiveModeImp() {
|
||||
uint64_t timeslice = 0, timeout = 0, heartbeat = 0;
|
||||
ze_result_t result = setPreemptTimeout(timeout);
|
||||
if (result != ZE_RESULT_SUCCESS) {
|
||||
NEO::printDebugString(NEO::DebugManager.flags.PrintDebugMessages.get(), stderr, "Error@ %s(): Failed to set preempt timeout and returning error:0x%x \n", __FUNCTION__, result);
|
||||
return result;
|
||||
}
|
||||
result = setTimesliceDuration(timeslice);
|
||||
if (result != ZE_RESULT_SUCCESS) {
|
||||
NEO::printDebugString(NEO::DebugManager.flags.PrintDebugMessages.get(), stderr, "Error@ %s(): Failed to set timeslice duration and returning error:0x%x \n", __FUNCTION__, result);
|
||||
return result;
|
||||
}
|
||||
result = setHeartbeatInterval(heartbeat);
|
||||
return result;
|
||||
}
|
||||
|
||||
ze_result_t LinuxSchedulerImp::setExclusiveMode(ze_bool_t *pNeedReload) {
|
||||
*pNeedReload = false;
|
||||
|
||||
zes_sched_mode_t currMode;
|
||||
ze_result_t result = getCurrentMode(&currMode);
|
||||
if (result != ZE_RESULT_SUCCESS) {
|
||||
NEO::printDebugString(NEO::DebugManager.flags.PrintDebugMessages.get(), stderr, "Error@ %s(): Failed to get current mode and returning error:0x%x \n", __FUNCTION__, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
if (currMode == ZES_SCHED_MODE_COMPUTE_UNIT_DEBUG) {
|
||||
// Unset this mode
|
||||
result = disableComputeUnitDebugMode(pNeedReload);
|
||||
if (result != ZE_RESULT_SUCCESS) {
|
||||
NEO::printDebugString(NEO::DebugManager.flags.PrintDebugMessages.get(), stderr, "Error@ %s(): Failed to diasble COMPUTE_UNIT_DEBUG mode and returning error:0x%x \n", __FUNCTION__, result);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
return setExclusiveModeImp();
|
||||
}
|
||||
|
||||
ze_result_t LinuxSchedulerImp::getTimeoutModeProperties(ze_bool_t getDefaults, zes_sched_timeout_properties_t *pConfig) {
|
||||
uint64_t heartbeat = 0;
|
||||
ze_result_t result = getHeartbeatInterval(heartbeat, getDefaults);
|
||||
if (result != ZE_RESULT_SUCCESS) {
|
||||
NEO::printDebugString(NEO::DebugManager.flags.PrintDebugMessages.get(), stderr, "Error@ %s(): Failed to get heart beat interval and returning error:0x%x \n", __FUNCTION__, result);
|
||||
return result;
|
||||
}
|
||||
pConfig->watchdogTimeout = heartbeat;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
ze_result_t LinuxSchedulerImp::getTimesliceModeProperties(ze_bool_t getDefaults, zes_sched_timeslice_properties_t *pConfig) {
|
||||
uint64_t timeout = 0, timeslice = 0;
|
||||
ze_result_t result = getPreemptTimeout(timeout, getDefaults);
|
||||
if (result != ZE_RESULT_SUCCESS) {
|
||||
NEO::printDebugString(NEO::DebugManager.flags.PrintDebugMessages.get(), stderr, "Error@ %s(): Failed to get preempt timeout and returning error:0x%x \n", __FUNCTION__, result);
|
||||
return result;
|
||||
}
|
||||
result = getTimesliceDuration(timeslice, getDefaults);
|
||||
if (result != ZE_RESULT_SUCCESS) {
|
||||
NEO::printDebugString(NEO::DebugManager.flags.PrintDebugMessages.get(), stderr, "Error@ %s(): Failed to get timeslice duration and returning error:0x%x \n", __FUNCTION__, result);
|
||||
return result;
|
||||
}
|
||||
pConfig->interval = timeslice;
|
||||
pConfig->yieldTimeout = timeout;
|
||||
return result;
|
||||
}
|
||||
|
||||
ze_result_t LinuxSchedulerImp::setTimeoutMode(zes_sched_timeout_properties_t *pProperties, ze_bool_t *pNeedReload) {
|
||||
*pNeedReload = false;
|
||||
zes_sched_mode_t currMode;
|
||||
ze_result_t result = getCurrentMode(&currMode);
|
||||
if (result != ZE_RESULT_SUCCESS) {
|
||||
NEO::printDebugString(NEO::DebugManager.flags.PrintDebugMessages.get(), stderr, "Error@ %s(): Failed to get current mode and returning error:0x%x \n", __FUNCTION__, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
if (pProperties->watchdogTimeout < minTimeoutModeHeartbeat) {
|
||||
// watchdogTimeout(in usec) less than 5000 would be computed to
|
||||
// 0 milli seconds preempt timeout, and then after returning from
|
||||
// this method, we would end up in EXCLUSIVE mode
|
||||
return ZE_RESULT_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
if (currMode == ZES_SCHED_MODE_COMPUTE_UNIT_DEBUG) {
|
||||
// Unset this mode
|
||||
result = disableComputeUnitDebugMode(pNeedReload);
|
||||
if (result != ZE_RESULT_SUCCESS) {
|
||||
// failed to disable compute unit debug mode
|
||||
NEO::printDebugString(NEO::DebugManager.flags.PrintDebugMessages.get(), stderr, "Error@ %s(): Failed to diasble COMPUTE_UNIT_DEBUG mode and returning error:0x%x \n", __FUNCTION__, result);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
result = setHeartbeatInterval(pProperties->watchdogTimeout);
|
||||
if (result != ZE_RESULT_SUCCESS) {
|
||||
NEO::printDebugString(NEO::DebugManager.flags.PrintDebugMessages.get(), stderr, "Error@ %s(): Failed to set heartbeat interval and returning error:0x%x \n", __FUNCTION__, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
uint64_t timeout = (pProperties->watchdogTimeout) / 5;
|
||||
result = setPreemptTimeout(timeout);
|
||||
if (result != ZE_RESULT_SUCCESS) {
|
||||
NEO::printDebugString(NEO::DebugManager.flags.PrintDebugMessages.get(), stderr, "Error@ %s(): Failed to set preempt timeout and returning error:0x%x \n", __FUNCTION__, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
uint64_t timeslice = 0;
|
||||
result = setTimesliceDuration(timeslice);
|
||||
if (result != ZE_RESULT_SUCCESS) {
|
||||
NEO::printDebugString(NEO::DebugManager.flags.PrintDebugMessages.get(), stderr, "Error@ %s(): Failed to set timeslice duration and returning error:0x%x \n", __FUNCTION__, result);
|
||||
return result;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
ze_result_t LinuxSchedulerImp::setTimesliceMode(zes_sched_timeslice_properties_t *pProperties, ze_bool_t *pNeedReload) {
|
||||
if (pProperties->interval < minTimeoutInMicroSeconds) {
|
||||
// interval(in usec) less than 1000 would be computed to
|
||||
// 0 milli seconds interval.
|
||||
return ZE_RESULT_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
*pNeedReload = false;
|
||||
|
||||
zes_sched_mode_t currMode;
|
||||
ze_result_t result = getCurrentMode(&currMode);
|
||||
if (result != ZE_RESULT_SUCCESS) {
|
||||
NEO::printDebugString(NEO::DebugManager.flags.PrintDebugMessages.get(), stderr, "Error@ %s(): Failed to get current mode and returning error:0x%x \n", __FUNCTION__, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
if (currMode == ZES_SCHED_MODE_COMPUTE_UNIT_DEBUG) {
|
||||
// Unset this mode
|
||||
result = disableComputeUnitDebugMode(pNeedReload);
|
||||
if (result != ZE_RESULT_SUCCESS) {
|
||||
NEO::printDebugString(NEO::DebugManager.flags.PrintDebugMessages.get(), stderr, "Error@ %s(): Failed to diasble COMPUTE_UNIT_DEBUG mode and returning error:0x%x \n", __FUNCTION__, result);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
result = setPreemptTimeout(pProperties->yieldTimeout);
|
||||
if (result != ZE_RESULT_SUCCESS) {
|
||||
NEO::printDebugString(NEO::DebugManager.flags.PrintDebugMessages.get(), stderr, "Error@ %s(): Failed to set preempt timeout and returning error:0x%x \n", __FUNCTION__, result);
|
||||
return result;
|
||||
}
|
||||
result = setTimesliceDuration(pProperties->interval);
|
||||
if (result != ZE_RESULT_SUCCESS) {
|
||||
NEO::printDebugString(NEO::DebugManager.flags.PrintDebugMessages.get(), stderr, "Error@ %s(): Failed to set timeslice duration and returning error:0x%x \n", __FUNCTION__, result);
|
||||
return result;
|
||||
}
|
||||
uint64_t heartbeat = 2500 * (pProperties->interval);
|
||||
return setHeartbeatInterval(heartbeat);
|
||||
}
|
||||
|
||||
ze_result_t LinuxSchedulerImp::getProperties(zes_sched_properties_t &schedProperties) {
|
||||
schedProperties.onSubdevice = onSubdevice;
|
||||
schedProperties.subdeviceId = subdeviceId;
|
||||
schedProperties.canControl = canControlScheduler();
|
||||
schedProperties.engines = this->engineType;
|
||||
schedProperties.supportedModes = (1 << ZES_SCHED_MODE_TIMEOUT) | (1 << ZES_SCHED_MODE_TIMESLICE) | (1 << ZES_SCHED_MODE_EXCLUSIVE);
|
||||
return ZE_RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
ze_result_t LinuxSchedulerImp::getPreemptTimeout(uint64_t &timeout, ze_bool_t getDefault) {
|
||||
ze_result_t result = ZE_RESULT_ERROR_UNKNOWN;
|
||||
uint32_t i = 0;
|
||||
std::vector<uint64_t> timeoutVec = {};
|
||||
std::string path = "";
|
||||
timeoutVec.resize(listOfEngines.size());
|
||||
for (const auto &engineName : listOfEngines) {
|
||||
if (getDefault) {
|
||||
path = engineDir + "/" + engineName + "/" + defaultPreemptTimeouttMilliSecs;
|
||||
result = pSysfsAccess->read(path, timeout);
|
||||
} else {
|
||||
path = engineDir + "/" + engineName + "/" + preemptTimeoutMilliSecs;
|
||||
result = pSysfsAccess->read(path, timeout);
|
||||
}
|
||||
if (result == ZE_RESULT_SUCCESS) {
|
||||
timeout = timeout * milliSecsToMicroSecs;
|
||||
timeoutVec[i] = timeout;
|
||||
i++;
|
||||
} else {
|
||||
if (result == ZE_RESULT_ERROR_NOT_AVAILABLE) {
|
||||
result = ZE_RESULT_ERROR_UNSUPPORTED_FEATURE;
|
||||
}
|
||||
NEO::printDebugString(NEO::DebugManager.flags.PrintDebugMessages.get(), stderr, "Error@ %s(): Failed to read preempt timeout from %s and returning error:0x%x \n", __FUNCTION__, path.c_str(), result);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
if (engineType == ZES_ENGINE_TYPE_FLAG_COMPUTE) {
|
||||
timeout = *std::max_element(timeoutVec.begin(), timeoutVec.end());
|
||||
return result;
|
||||
}
|
||||
|
||||
// check if all engines of the same type have the same scheduling param values
|
||||
if (std::adjacent_find(timeoutVec.begin(), timeoutVec.end(), std::not_equal_to<>()) == timeoutVec.end()) {
|
||||
timeout = timeoutVec[0];
|
||||
return result;
|
||||
} else {
|
||||
return ZE_RESULT_ERROR_UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
ze_result_t LinuxSchedulerImp::getTimesliceDuration(uint64_t ×lice, ze_bool_t getDefault) {
|
||||
ze_result_t result = ZE_RESULT_ERROR_UNKNOWN;
|
||||
uint32_t i = 0;
|
||||
std::vector<uint64_t> timesliceVec = {};
|
||||
std::string path = "";
|
||||
timesliceVec.resize(listOfEngines.size());
|
||||
for (const auto &engineName : listOfEngines) {
|
||||
if (getDefault) {
|
||||
path = engineDir + "/" + engineName + "/" + defaultTimesliceDurationMilliSecs;
|
||||
result = pSysfsAccess->read(path, timeslice);
|
||||
} else {
|
||||
path = engineDir + "/" + engineName + "/" + timesliceDurationMilliSecs;
|
||||
result = pSysfsAccess->read(path, timeslice);
|
||||
}
|
||||
if (result == ZE_RESULT_SUCCESS) {
|
||||
timeslice = timeslice * milliSecsToMicroSecs;
|
||||
timesliceVec[i] = timeslice;
|
||||
i++;
|
||||
} else {
|
||||
if (result == ZE_RESULT_ERROR_NOT_AVAILABLE) {
|
||||
result = ZE_RESULT_ERROR_UNSUPPORTED_FEATURE;
|
||||
}
|
||||
NEO::printDebugString(NEO::DebugManager.flags.PrintDebugMessages.get(), stderr, "Error@ %s(): Failed to read timeslice duration from %s and returning error:0x%x \n", __FUNCTION__, path.c_str(), result);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
// check if all engines of the same type have the same scheduling param values
|
||||
if (std::adjacent_find(timesliceVec.begin(), timesliceVec.end(), std::not_equal_to<>()) == timesliceVec.end()) {
|
||||
timeslice = timesliceVec[0];
|
||||
return result;
|
||||
} else {
|
||||
return ZE_RESULT_ERROR_UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
ze_result_t LinuxSchedulerImp::getHeartbeatInterval(uint64_t &heartbeat, ze_bool_t getDefault) {
|
||||
ze_result_t result = ZE_RESULT_ERROR_UNKNOWN;
|
||||
uint32_t i = 0;
|
||||
std::vector<uint64_t> heartbeatVec = {};
|
||||
std::string path = "";
|
||||
heartbeatVec.resize(listOfEngines.size());
|
||||
for (const auto &engineName : listOfEngines) {
|
||||
if (getDefault) {
|
||||
path = engineDir + "/" + engineName + "/" + defaultHeartbeatIntervalMilliSecs;
|
||||
result = pSysfsAccess->read(path, heartbeat);
|
||||
} else {
|
||||
path = engineDir + "/" + engineName + "/" + heartbeatIntervalMilliSecs;
|
||||
result = pSysfsAccess->read(path, heartbeat);
|
||||
}
|
||||
if (result == ZE_RESULT_SUCCESS) {
|
||||
heartbeat = heartbeat * milliSecsToMicroSecs;
|
||||
heartbeatVec[i] = heartbeat;
|
||||
i++;
|
||||
} else {
|
||||
if (result == ZE_RESULT_ERROR_NOT_AVAILABLE) {
|
||||
result = ZE_RESULT_ERROR_UNSUPPORTED_FEATURE;
|
||||
}
|
||||
NEO::printDebugString(NEO::DebugManager.flags.PrintDebugMessages.get(), stderr, "Error@ %s(): Failed to read heartbeat interval from %s and returning error:0x%x \n", __FUNCTION__, path.c_str(), result);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
// check if all engines of the same type have the same scheduling param values
|
||||
if (std::adjacent_find(heartbeatVec.begin(), heartbeatVec.end(), std::not_equal_to<>()) == heartbeatVec.end()) {
|
||||
heartbeat = heartbeatVec[0];
|
||||
return result;
|
||||
} else {
|
||||
return ZE_RESULT_ERROR_UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
ze_result_t LinuxSchedulerImp::setPreemptTimeout(uint64_t timeout) {
|
||||
timeout = timeout / milliSecsToMicroSecs;
|
||||
ze_result_t result = ZE_RESULT_ERROR_UNKNOWN;
|
||||
for (const auto &engineName : listOfEngines) {
|
||||
result = pSysfsAccess->write(engineDir + "/" + engineName + "/" + preemptTimeoutMilliSecs, timeout);
|
||||
if (result != ZE_RESULT_SUCCESS) {
|
||||
if (result == ZE_RESULT_ERROR_NOT_AVAILABLE) {
|
||||
result = ZE_RESULT_ERROR_UNSUPPORTED_FEATURE;
|
||||
}
|
||||
NEO::printDebugString(NEO::DebugManager.flags.PrintDebugMessages.get(), stderr, "Error@ %s(): Failed to write Preempt timeout into engineDir/%s/preemptTimeoutMilliSecs and returning error:0x%x \n", __FUNCTION__, engineName.c_str(), result);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
ze_result_t LinuxSchedulerImp::setTimesliceDuration(uint64_t timeslice) {
|
||||
timeslice = timeslice / milliSecsToMicroSecs;
|
||||
ze_result_t result = ZE_RESULT_ERROR_UNKNOWN;
|
||||
for (const auto &engineName : listOfEngines) {
|
||||
result = pSysfsAccess->write(engineDir + "/" + engineName + "/" + timesliceDurationMilliSecs, timeslice);
|
||||
if (result != ZE_RESULT_SUCCESS) {
|
||||
if (result == ZE_RESULT_ERROR_NOT_AVAILABLE) {
|
||||
result = ZE_RESULT_ERROR_UNSUPPORTED_FEATURE;
|
||||
}
|
||||
NEO::printDebugString(NEO::DebugManager.flags.PrintDebugMessages.get(), stderr, "Error@ %s(): Failed to write Timeslice duration into engineDir/%s/timesliceDurationMilliSecs and returning error:0x%x \n", __FUNCTION__, engineName.c_str(), result);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
ze_result_t LinuxSchedulerImp::setHeartbeatInterval(uint64_t heartbeat) {
|
||||
heartbeat = heartbeat / milliSecsToMicroSecs;
|
||||
ze_result_t result = ZE_RESULT_ERROR_UNKNOWN;
|
||||
for (const auto &engineName : listOfEngines) {
|
||||
result = pSysfsAccess->write(engineDir + "/" + engineName + "/" + heartbeatIntervalMilliSecs, heartbeat);
|
||||
if (result != ZE_RESULT_SUCCESS) {
|
||||
if (result == ZE_RESULT_ERROR_NOT_AVAILABLE) {
|
||||
result = ZE_RESULT_ERROR_UNSUPPORTED_FEATURE;
|
||||
}
|
||||
NEO::printDebugString(NEO::DebugManager.flags.PrintDebugMessages.get(), stderr, "Error@ %s(): Failed to write Heartbeat interval into engineDir/%s/heartbeatIntervalMilliSecs and returning error:0x%x \n", __FUNCTION__, engineName.c_str(), result);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
ze_bool_t LinuxSchedulerImp::canControlScheduler() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
ze_result_t LinuxSchedulerImp::updateComputeUnitDebugNode(uint64_t val) {
|
||||
// I915 will be reloaded if we toggle value of enableEuDebug
|
||||
// Hence for gracefull handling close all i915 clients before toggling enableEuDebug
|
||||
pLinuxSysmanImp->releaseSysmanDeviceResources();
|
||||
ze_result_t result = pLinuxSysmanImp->gpuProcessCleanup();
|
||||
if (ZE_RESULT_SUCCESS != result) {
|
||||
NEO::printDebugString(NEO::DebugManager.flags.PrintDebugMessages.get(), stderr,
|
||||
"updateComputeUnitDebugNode: gpuProcessCleanup() failed with error code: %ld\n", result);
|
||||
return result;
|
||||
}
|
||||
result = pSysfsAccess->write(enableEuDebug, val);
|
||||
if (result != ZE_RESULT_SUCCESS) {
|
||||
NEO::printDebugString(NEO::DebugManager.flags.PrintDebugMessages.get(), stderr,
|
||||
"updateComputeUnitDebugNode: Write to sysfs node %s failed with error code: %ld\n", enableEuDebug.c_str(), result);
|
||||
}
|
||||
pLinuxSysmanImp->reInitSysmanDeviceResources();
|
||||
return result;
|
||||
}
|
||||
|
||||
ze_result_t LinuxSchedulerImp::setComputeUnitDebugMode(ze_bool_t *pNeedReload) {
|
||||
auto result = setExclusiveModeImp();
|
||||
if (result != ZE_RESULT_SUCCESS) {
|
||||
NEO::printDebugString(NEO::DebugManager.flags.PrintDebugMessages.get(), stderr,
|
||||
"setComputeUnitDebugMode: Exclusive mode set(precontiion to set Debug mode) failed. Error code: %ld\n", result);
|
||||
return result;
|
||||
}
|
||||
|
||||
*pNeedReload = false;
|
||||
uint64_t val = 1;
|
||||
auto ret = pSysfsAccess->canWrite(enableEuDebug);
|
||||
if (ret != ZE_RESULT_SUCCESS) {
|
||||
NEO::printDebugString(NEO::DebugManager.flags.PrintDebugMessages.get(), stderr,
|
||||
"setComputeUnitDebugMode: sysfs node %s not writable. Error code: %ld\n", enableEuDebug.c_str(), result);
|
||||
return ret;
|
||||
}
|
||||
return updateComputeUnitDebugNode(val);
|
||||
}
|
||||
|
||||
bool LinuxSchedulerImp::isComputeUnitDebugModeEnabled() {
|
||||
uint64_t val = 0;
|
||||
auto result = pSysfsAccess->read(enableEuDebug, val);
|
||||
if (result != ZE_RESULT_SUCCESS) {
|
||||
NEO::printDebugString(NEO::DebugManager.flags.PrintDebugMessages.get(), stderr,
|
||||
"isComputeUnitDebugModeEnabled: Read from sysfs node %s failed with error code: %ld\n", enableEuDebug.c_str(), result);
|
||||
return false;
|
||||
}
|
||||
return (val == 0) ? false : true;
|
||||
}
|
||||
|
||||
ze_result_t LinuxSchedulerImp::disableComputeUnitDebugMode(ze_bool_t *pNeedReload) {
|
||||
*pNeedReload = false;
|
||||
uint64_t val = 0;
|
||||
return updateComputeUnitDebugNode(val);
|
||||
}
|
||||
|
||||
static ze_result_t getNumEngineTypeAndInstancesForSubDevices(std::map<zes_engine_type_flag_t, std::vector<std::string>> &mapOfEngines,
|
||||
LinuxSysmanImp *pLinuxSysmanImp, uint32_t subdeviceId) {
|
||||
auto pDrm = pLinuxSysmanImp->getDrm();
|
||||
NEO::EngineInfo *engineInfo = nullptr;
|
||||
{
|
||||
auto hwDeviceId = pLinuxSysmanImp->getSysmanHwDeviceIdInstance();
|
||||
engineInfo = pDrm->getEngineInfo();
|
||||
}
|
||||
|
||||
if (engineInfo == nullptr) {
|
||||
return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE;
|
||||
}
|
||||
std::vector<NEO::EngineClassInstance> listOfEngines;
|
||||
engineInfo->getListOfEnginesOnATile(subdeviceId, listOfEngines);
|
||||
for (const auto &engine : listOfEngines) {
|
||||
auto sysfEngineString = i915EngineClassToSysfsEngineMap.find(static_cast<drm_i915_gem_engine_class>(engine.engineClass));
|
||||
if (sysfEngineString == i915EngineClassToSysfsEngineMap.end()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
std::string sysfsEngineDirNode = sysfEngineString->second + std::to_string(engine.engineInstance);
|
||||
auto level0EngineType = sysfsEngineMapToLevel0EngineType.find(sysfEngineString->second);
|
||||
auto ret = mapOfEngines.find(level0EngineType->second);
|
||||
if (ret != mapOfEngines.end()) {
|
||||
ret->second.push_back(sysfsEngineDirNode);
|
||||
} else {
|
||||
std::vector<std::string> engineVec = {};
|
||||
engineVec.push_back(sysfsEngineDirNode);
|
||||
mapOfEngines.emplace(level0EngineType->second, engineVec);
|
||||
}
|
||||
}
|
||||
return ZE_RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
static ze_result_t getNumEngineTypeAndInstancesForDevice(std::map<zes_engine_type_flag_t, std::vector<std::string>> &mapOfEngines, SysfsAccess *pSysfsAccess) {
|
||||
std::vector<std::string> localListOfAllEngines = {};
|
||||
auto result = pSysfsAccess->scanDirEntries(LinuxSchedulerImp::engineDir, localListOfAllEngines);
|
||||
if (ZE_RESULT_SUCCESS != result) {
|
||||
if (result == ZE_RESULT_ERROR_NOT_AVAILABLE) {
|
||||
result = ZE_RESULT_ERROR_UNSUPPORTED_FEATURE;
|
||||
}
|
||||
NEO::printDebugString(NEO::DebugManager.flags.PrintDebugMessages.get(), stderr, "Error@ %s(): Failed to scan directory entries to list all engines and returning error:0x%x \n", __FUNCTION__, result);
|
||||
return result;
|
||||
}
|
||||
for_each(localListOfAllEngines.begin(), localListOfAllEngines.end(),
|
||||
[&](std::string &mappedEngine) {
|
||||
for (auto itr = level0EngineTypeToSysfsEngineMap.begin(); itr != level0EngineTypeToSysfsEngineMap.end(); itr++) {
|
||||
char digits[] = "0123456789";
|
||||
auto mappedEngineName = mappedEngine.substr(0, mappedEngine.find_first_of(digits, 0));
|
||||
if (0 == mappedEngineName.compare(itr->second.c_str())) {
|
||||
auto ret = mapOfEngines.find(itr->first);
|
||||
if (ret != mapOfEngines.end()) {
|
||||
ret->second.push_back(mappedEngine);
|
||||
} else {
|
||||
std::vector<std::string> engineVec = {};
|
||||
engineVec.push_back(mappedEngine);
|
||||
mapOfEngines.emplace(itr->first, engineVec);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
ze_result_t OsScheduler::getNumEngineTypeAndInstances(
|
||||
std::map<zes_engine_type_flag_t, std::vector<std::string>> &mapOfEngines, OsSysman *pOsSysman, ze_bool_t onSubDevice, uint32_t subDeviceId) {
|
||||
LinuxSysmanImp *pLinuxSysmanImp = static_cast<LinuxSysmanImp *>(pOsSysman);
|
||||
auto pSysfsAccess = &pLinuxSysmanImp->getSysfsAccess();
|
||||
if (onSubDevice) {
|
||||
return getNumEngineTypeAndInstancesForSubDevices(mapOfEngines, pLinuxSysmanImp, subDeviceId);
|
||||
}
|
||||
return getNumEngineTypeAndInstancesForDevice(mapOfEngines, pSysfsAccess);
|
||||
}
|
||||
|
||||
LinuxSchedulerImp::LinuxSchedulerImp(
|
||||
OsSysman *pOsSysman, zes_engine_type_flag_t type, std::vector<std::string> &listOfEngines, ze_bool_t isSubdevice,
|
||||
uint32_t subdeviceId) : engineType(type), onSubdevice(isSubdevice), subdeviceId(subdeviceId) {
|
||||
pLinuxSysmanImp = static_cast<LinuxSysmanImp *>(pOsSysman);
|
||||
pSysfsAccess = &pLinuxSysmanImp->getSysfsAccess();
|
||||
this->listOfEngines = listOfEngines;
|
||||
}
|
||||
|
||||
std::unique_ptr<OsScheduler> OsScheduler::create(
|
||||
OsSysman *pOsSysman, zes_engine_type_flag_t type, std::vector<std::string> &listOfEngines, ze_bool_t isSubdevice, uint32_t subdeviceId) {
|
||||
std::unique_ptr<LinuxSchedulerImp> pLinuxSchedulerImp = std::make_unique<LinuxSchedulerImp>(pOsSysman, type, listOfEngines, isSubdevice, subdeviceId);
|
||||
return pLinuxSchedulerImp;
|
||||
}
|
||||
|
||||
} // namespace Sysman
|
||||
} // namespace L0
|
||||
38
level_zero/sysman/source/api/scheduler/sysman_os_scheduler.h
Normal file
38
level_zero/sysman/source/api/scheduler/sysman_os_scheduler.h
Normal file
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright (C) 2020-2023 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <level_zero/zes_api.h>
|
||||
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace L0 {
|
||||
namespace Sysman {
|
||||
struct OsSysman;
|
||||
|
||||
class OsScheduler {
|
||||
public:
|
||||
virtual ze_result_t getCurrentMode(zes_sched_mode_t *pMode) = 0;
|
||||
virtual ze_result_t getTimeoutModeProperties(ze_bool_t getDefaults, zes_sched_timeout_properties_t *pConfig) = 0;
|
||||
virtual ze_result_t getTimesliceModeProperties(ze_bool_t getDefaults, zes_sched_timeslice_properties_t *pConfig) = 0;
|
||||
virtual ze_result_t setTimeoutMode(zes_sched_timeout_properties_t *pProperties, ze_bool_t *pNeedReload) = 0;
|
||||
virtual ze_result_t setTimesliceMode(zes_sched_timeslice_properties_t *pProperties, ze_bool_t *pNeedReload) = 0;
|
||||
virtual ze_result_t setExclusiveMode(ze_bool_t *pNeedReload) = 0;
|
||||
virtual ze_result_t setComputeUnitDebugMode(ze_bool_t *pNeedReload) = 0;
|
||||
virtual ze_result_t getProperties(zes_sched_properties_t &properties) = 0;
|
||||
static std::unique_ptr<OsScheduler> create(OsSysman *pOsSysman, zes_engine_type_flag_t engineType, std::vector<std::string> &listOfEngines,
|
||||
ze_bool_t isSubdevice, uint32_t subdeviceId);
|
||||
static ze_result_t getNumEngineTypeAndInstances(std::map<zes_engine_type_flag_t, std::vector<std::string>> &listOfEngines,
|
||||
OsSysman *pOsSysman, ze_bool_t onSubDevice, uint32_t subDeviceId);
|
||||
virtual ~OsScheduler() = default;
|
||||
};
|
||||
|
||||
} // namespace Sysman
|
||||
} // namespace L0
|
||||
66
level_zero/sysman/source/api/scheduler/sysman_scheduler.cpp
Normal file
66
level_zero/sysman/source/api/scheduler/sysman_scheduler.cpp
Normal file
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright (C) 2020-2023 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#include "level_zero/sysman/source/api/scheduler/sysman_scheduler_imp.h"
|
||||
#include "level_zero/sysman/source/os_sysman.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
namespace L0 {
|
||||
namespace Sysman {
|
||||
|
||||
SchedulerHandleContext::SchedulerHandleContext(OsSysman *pOsSysman) {
|
||||
this->pOsSysman = pOsSysman;
|
||||
}
|
||||
|
||||
SchedulerHandleContext::~SchedulerHandleContext() {
|
||||
handleList.clear();
|
||||
}
|
||||
|
||||
void SchedulerHandleContext::createHandle(zes_engine_type_flag_t engineType, std::vector<std::string> &listOfEngines, ze_bool_t onSubDevice, uint32_t subDeviceId) {
|
||||
std::unique_ptr<Scheduler> pScheduler = std::make_unique<SchedulerImp>(pOsSysman, engineType, listOfEngines, onSubDevice, subDeviceId);
|
||||
handleList.push_back(std::move(pScheduler));
|
||||
}
|
||||
|
||||
void SchedulerHandleContext::init(uint32_t subDeviceCount) {
|
||||
|
||||
if (subDeviceCount > 0) {
|
||||
for (uint32_t subDeviceId = 0; subDeviceId < subDeviceCount; subDeviceId++) {
|
||||
std::map<zes_engine_type_flag_t, std::vector<std::string>> engineTypeInstance = {};
|
||||
OsScheduler::getNumEngineTypeAndInstances(engineTypeInstance, pOsSysman, true, subDeviceId);
|
||||
for (auto itr = engineTypeInstance.begin(); itr != engineTypeInstance.end(); ++itr) {
|
||||
createHandle(itr->first, itr->second, true, subDeviceId);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
std::map<zes_engine_type_flag_t, std::vector<std::string>> engineTypeInstance = {};
|
||||
OsScheduler::getNumEngineTypeAndInstances(engineTypeInstance, pOsSysman, false, 0);
|
||||
for (auto itr = engineTypeInstance.begin(); itr != engineTypeInstance.end(); ++itr) {
|
||||
createHandle(itr->first, itr->second, false, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ze_result_t SchedulerHandleContext::schedulerGet(uint32_t *pCount, zes_sched_handle_t *phScheduler) {
|
||||
std::call_once(initSchedulerOnce, [this]() {
|
||||
this->init(pOsSysman->getSubDeviceCount());
|
||||
});
|
||||
uint32_t handleListSize = static_cast<uint32_t>(handleList.size());
|
||||
uint32_t numToCopy = std::min(*pCount, handleListSize);
|
||||
if (0 == *pCount || *pCount > handleListSize) {
|
||||
*pCount = handleListSize;
|
||||
}
|
||||
if (nullptr != phScheduler) {
|
||||
for (uint32_t i = 0; i < numToCopy; i++) {
|
||||
phScheduler[i] = handleList[i]->toHandle();
|
||||
}
|
||||
}
|
||||
return ZE_RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
} // namespace Sysman
|
||||
} // namespace L0
|
||||
55
level_zero/sysman/source/api/scheduler/sysman_scheduler.h
Normal file
55
level_zero/sysman/source/api/scheduler/sysman_scheduler.h
Normal file
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright (C) 2020-2023 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "shared/source/helpers/non_copyable_or_moveable.h"
|
||||
|
||||
#include "level_zero/api/sysman/zes_handles_struct.h"
|
||||
#include <level_zero/zes_api.h>
|
||||
|
||||
#include <map>
|
||||
#include <mutex>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace L0 {
|
||||
namespace Sysman {
|
||||
struct OsSysman;
|
||||
class Scheduler : _zes_sched_handle_t {
|
||||
public:
|
||||
virtual ze_result_t schedulerGetProperties(zes_sched_properties_t *pProperties) = 0;
|
||||
virtual ze_result_t getCurrentMode(zes_sched_mode_t *pMode) = 0;
|
||||
virtual ze_result_t getTimeoutModeProperties(ze_bool_t getDefaults, zes_sched_timeout_properties_t *pConfig) = 0;
|
||||
virtual ze_result_t getTimesliceModeProperties(ze_bool_t getDefaults, zes_sched_timeslice_properties_t *pConfig) = 0;
|
||||
virtual ze_result_t setTimeoutMode(zes_sched_timeout_properties_t *pProperties, ze_bool_t *pNeedReload) = 0;
|
||||
virtual ze_result_t setTimesliceMode(zes_sched_timeslice_properties_t *pProperties, ze_bool_t *pNeedReload) = 0;
|
||||
virtual ze_result_t setExclusiveMode(ze_bool_t *pNeedReload) = 0;
|
||||
virtual ze_result_t setComputeUnitDebugMode(ze_bool_t *pNeedReload) = 0;
|
||||
|
||||
static Scheduler *fromHandle(zes_sched_handle_t handle) {
|
||||
return static_cast<Scheduler *>(handle);
|
||||
}
|
||||
inline zes_sched_handle_t toHandle() { return this; }
|
||||
bool initSuccess = false;
|
||||
};
|
||||
|
||||
struct SchedulerHandleContext : NEO::NonCopyableOrMovableClass {
|
||||
SchedulerHandleContext(OsSysman *pOsSysman);
|
||||
~SchedulerHandleContext();
|
||||
void init(uint32_t subDeviceCount);
|
||||
ze_result_t schedulerGet(uint32_t *pCount, zes_sched_handle_t *phScheduler);
|
||||
|
||||
OsSysman *pOsSysman = nullptr;
|
||||
std::vector<std::unique_ptr<Scheduler>> handleList = {};
|
||||
|
||||
private:
|
||||
void createHandle(zes_engine_type_flag_t engineType, std::vector<std::string> &listOfEngines, ze_bool_t onSubDevice, uint32_t subDeviceId);
|
||||
std::once_flag initSchedulerOnce;
|
||||
};
|
||||
|
||||
} // namespace Sysman
|
||||
} // namespace L0
|
||||
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright (C) 2020-2023 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#include "level_zero/sysman/source/api/scheduler/sysman_scheduler_imp.h"
|
||||
|
||||
#include "shared/source/helpers/debug_helpers.h"
|
||||
|
||||
#include "level_zero/sysman/source/sysman_const.h"
|
||||
#include "level_zero/sysman/source/sysman_device_imp.h"
|
||||
|
||||
namespace L0 {
|
||||
namespace Sysman {
|
||||
|
||||
ze_result_t SchedulerImp::setExclusiveMode(ze_bool_t *pNeedReload) {
|
||||
return pOsScheduler->setExclusiveMode(pNeedReload);
|
||||
}
|
||||
|
||||
ze_result_t SchedulerImp::setComputeUnitDebugMode(ze_bool_t *pNeedReload) {
|
||||
return pOsScheduler->setComputeUnitDebugMode(pNeedReload);
|
||||
}
|
||||
|
||||
ze_result_t SchedulerImp::getCurrentMode(zes_sched_mode_t *pMode) {
|
||||
return pOsScheduler->getCurrentMode(pMode);
|
||||
}
|
||||
|
||||
ze_result_t SchedulerImp::getTimeoutModeProperties(ze_bool_t getDefaults, zes_sched_timeout_properties_t *pConfig) {
|
||||
return pOsScheduler->getTimeoutModeProperties(getDefaults, pConfig);
|
||||
}
|
||||
|
||||
ze_result_t SchedulerImp::getTimesliceModeProperties(ze_bool_t getDefaults, zes_sched_timeslice_properties_t *pConfig) {
|
||||
return pOsScheduler->getTimesliceModeProperties(getDefaults, pConfig);
|
||||
}
|
||||
|
||||
ze_result_t SchedulerImp::setTimeoutMode(zes_sched_timeout_properties_t *pProperties, ze_bool_t *pNeedReload) {
|
||||
return pOsScheduler->setTimeoutMode(pProperties, pNeedReload);
|
||||
}
|
||||
|
||||
ze_result_t SchedulerImp::setTimesliceMode(zes_sched_timeslice_properties_t *pProperties, ze_bool_t *pNeedReload) {
|
||||
return pOsScheduler->setTimesliceMode(pProperties, pNeedReload);
|
||||
}
|
||||
|
||||
ze_result_t SchedulerImp::schedulerGetProperties(zes_sched_properties_t *pProperties) {
|
||||
*pProperties = properties;
|
||||
return ZE_RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
void SchedulerImp::init() {
|
||||
pOsScheduler->getProperties(this->properties);
|
||||
}
|
||||
|
||||
SchedulerImp::SchedulerImp(OsSysman *pOsSysman, zes_engine_type_flag_t engineType, std::vector<std::string> &listOfEngines, ze_bool_t onSubDevice, uint32_t subDeviceId) {
|
||||
pOsScheduler = OsScheduler::create(pOsSysman, engineType, listOfEngines, onSubDevice, subDeviceId);
|
||||
UNRECOVERABLE_IF(nullptr == pOsScheduler);
|
||||
init();
|
||||
};
|
||||
|
||||
SchedulerImp::~SchedulerImp() = default;
|
||||
|
||||
} // namespace Sysman
|
||||
} // namespace L0
|
||||
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright (C) 2020-2023 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "shared/source/helpers/non_copyable_or_moveable.h"
|
||||
|
||||
#include "level_zero/sysman/source/api/scheduler/sysman_os_scheduler.h"
|
||||
#include "level_zero/sysman/source/api/scheduler/sysman_scheduler.h"
|
||||
#include <level_zero/zes_api.h>
|
||||
|
||||
namespace L0 {
|
||||
namespace Sysman {
|
||||
|
||||
class SchedulerImp : public Scheduler, NEO::NonCopyableOrMovableClass {
|
||||
public:
|
||||
void init();
|
||||
ze_result_t schedulerGetProperties(zes_sched_properties_t *pProperties) override;
|
||||
ze_result_t getCurrentMode(zes_sched_mode_t *pMode) override;
|
||||
ze_result_t getTimeoutModeProperties(ze_bool_t getDefaults, zes_sched_timeout_properties_t *pConfig) override;
|
||||
ze_result_t getTimesliceModeProperties(ze_bool_t getDefaults, zes_sched_timeslice_properties_t *pConfig) override;
|
||||
ze_result_t setTimeoutMode(zes_sched_timeout_properties_t *pProperties, ze_bool_t *pNeedReload) override;
|
||||
ze_result_t setTimesliceMode(zes_sched_timeslice_properties_t *pProperties, ze_bool_t *pNeedReload) override;
|
||||
ze_result_t setExclusiveMode(ze_bool_t *pNeedReload) override;
|
||||
ze_result_t setComputeUnitDebugMode(ze_bool_t *pNeedReload) override;
|
||||
|
||||
SchedulerImp() = default;
|
||||
std::unique_ptr<OsScheduler> pOsScheduler;
|
||||
SchedulerImp(OsSysman *pOsSysman, zes_engine_type_flag_t type, std::vector<std::string> &listOfEngines, ze_bool_t onSubDevice, uint32_t subDeviceId);
|
||||
~SchedulerImp() override;
|
||||
|
||||
private:
|
||||
zes_sched_properties_t properties = {};
|
||||
};
|
||||
|
||||
} // namespace Sysman
|
||||
} // namespace L0
|
||||
@@ -0,0 +1,14 @@
|
||||
#
|
||||
# Copyright (C) 2020-2023 Intel Corporation
|
||||
#
|
||||
# SPDX-License-Identifier: MIT
|
||||
#
|
||||
|
||||
if(WIN32)
|
||||
target_sources(${L0_STATIC_LIB_NAME}
|
||||
PRIVATE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/sysman_os_scheduler_imp.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/sysman_os_scheduler_imp.cpp
|
||||
)
|
||||
endif()
|
||||
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright (C) 2020-2023 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#include "level_zero/sysman/source/api/scheduler/windows/sysman_os_scheduler_imp.h"
|
||||
|
||||
#include "level_zero/sysman/source/api/scheduler/sysman_scheduler_imp.h"
|
||||
|
||||
namespace L0 {
|
||||
namespace Sysman {
|
||||
|
||||
ze_result_t WddmSchedulerImp::getCurrentMode(zes_sched_mode_t *pMode) {
|
||||
return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE;
|
||||
}
|
||||
|
||||
ze_result_t WddmSchedulerImp::getTimeoutModeProperties(ze_bool_t getDefaults, zes_sched_timeout_properties_t *pConfig) {
|
||||
return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE;
|
||||
}
|
||||
|
||||
ze_result_t WddmSchedulerImp::getTimesliceModeProperties(ze_bool_t getDefaults, zes_sched_timeslice_properties_t *pConfig) {
|
||||
return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE;
|
||||
}
|
||||
|
||||
ze_result_t WddmSchedulerImp::setTimeoutMode(zes_sched_timeout_properties_t *pProperties, ze_bool_t *pNeedReload) {
|
||||
return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE;
|
||||
}
|
||||
|
||||
ze_result_t WddmSchedulerImp::setTimesliceMode(zes_sched_timeslice_properties_t *pProperties, ze_bool_t *pNeedReload) {
|
||||
return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE;
|
||||
}
|
||||
|
||||
ze_result_t WddmSchedulerImp::setExclusiveMode(ze_bool_t *pNeedReload) {
|
||||
return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE;
|
||||
}
|
||||
|
||||
ze_result_t WddmSchedulerImp::getProperties(zes_sched_properties_t &properties) {
|
||||
return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE;
|
||||
}
|
||||
|
||||
ze_result_t WddmSchedulerImp::setComputeUnitDebugMode(ze_bool_t *pNeedReload) {
|
||||
return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE;
|
||||
}
|
||||
|
||||
ze_result_t OsScheduler::getNumEngineTypeAndInstances(std::map<zes_engine_type_flag_t, std::vector<std::string>> &listOfEngines,
|
||||
OsSysman *pOsSysman, ze_bool_t onSubDevice, uint32_t subDeviceId) {
|
||||
return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE;
|
||||
}
|
||||
|
||||
std::unique_ptr<OsScheduler> OsScheduler::create(
|
||||
OsSysman *pOsSysman, zes_engine_type_flag_t type, std::vector<std::string> &listOfEngines, ze_bool_t isSubdevice, uint32_t subdeviceId) {
|
||||
std::unique_ptr<WddmSchedulerImp> pWddmSchedulerImp = std::make_unique<WddmSchedulerImp>();
|
||||
return pWddmSchedulerImp;
|
||||
}
|
||||
|
||||
} // namespace Sysman
|
||||
} // namespace L0
|
||||
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright (C) 2020-2023 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "level_zero/sysman/source/api/scheduler/sysman_scheduler_imp.h"
|
||||
|
||||
namespace L0 {
|
||||
namespace Sysman {
|
||||
|
||||
class WddmSchedulerImp : public OsScheduler {
|
||||
public:
|
||||
ze_result_t getCurrentMode(zes_sched_mode_t *pMode) override;
|
||||
ze_result_t getTimeoutModeProperties(ze_bool_t getDefaults, zes_sched_timeout_properties_t *pConfig) override;
|
||||
ze_result_t getTimesliceModeProperties(ze_bool_t getDefaults, zes_sched_timeslice_properties_t *pConfig) override;
|
||||
ze_result_t setTimeoutMode(zes_sched_timeout_properties_t *pProperties, ze_bool_t *pNeedReload) override;
|
||||
ze_result_t setTimesliceMode(zes_sched_timeslice_properties_t *pProperties, ze_bool_t *pNeedReload) override;
|
||||
ze_result_t setExclusiveMode(ze_bool_t *pNeedReload) override;
|
||||
ze_result_t setComputeUnitDebugMode(ze_bool_t *pNeedReload) override;
|
||||
ze_result_t getProperties(zes_sched_properties_t &properties) override;
|
||||
};
|
||||
|
||||
} // namespace Sysman
|
||||
} // namespace L0
|
||||
Reference in New Issue
Block a user