Sysman: Enhance Scheduler compute unit debug mode implementation

This change helps in achieving the following:
- Moves the OS specific code from scheduler_imp.cpp to os specific
files.
- Frees any drm resource, including level zero's before enabling/dis
-abling Debug mode. And once Debug mode is toggled, reinitialize of
level zero occurs.
- If current mode is Debug mode and any other mode is requested by user,
then new mode will be made effective by unsetting debug mode.

Related-To: LOCI-866

Signed-off-by: Jitendra Sharma <jitendra.sharma@intel.com>
This commit is contained in:
Jitendra Sharma
2022-11-01 15:59:58 +00:00
committed by Compute-Runtime-Automation
parent 6a6e17d48a
commit 391941c447
15 changed files with 953 additions and 225 deletions

View File

@@ -114,12 +114,13 @@ class SysfsAccess : protected FsAccess {
bool directoryExists(const std::string path) override;
bool isRootUser() override;
protected:
std::vector<std::string> deviceNames;
private:
SysfsAccess(const std::string file);
std::string fullPath(const std::string file);
std::vector<std::string> deviceNames;
std::string dirname;
static const std::string drmPath;
static const std::string devicesPath;

View File

@@ -259,6 +259,43 @@ void LinuxSysmanImp::getPidFdsForOpenDevice(ProcfsAccess *pProcfsAccess, SysfsAc
}
}
ze_result_t LinuxSysmanImp::gpuProcessCleanup() {
::pid_t myPid = pProcfsAccess->myProcessId();
std::vector<::pid_t> processes;
std::vector<int> myPidFds;
ze_result_t result = pProcfsAccess->listProcesses(processes);
if (ZE_RESULT_SUCCESS != result) {
NEO::printDebugString(NEO::DebugManager.flags.PrintDebugMessages.get(), stderr,
"gpuProcessCleanup: listProcesses() failed with error code: %ld\n", result);
return result;
}
for (auto &&pid : processes) {
std::vector<int> fds;
getPidFdsForOpenDevice(pProcfsAccess, pSysfsAccess, pid, fds);
if (pid == myPid) {
// L0 is expected to have this file open.
// Keep list of fds. Close before unbind.
myPidFds = fds;
continue;
}
if (!fds.empty()) {
pProcfsAccess->kill(pid);
}
}
for (auto &&fd : myPidFds) {
// Close open filedescriptors to the device
// before unbinding device.
// From this point forward, there is no
// graceful way to fail the reset call.
// All future ze calls by this process for this
// device will fail.
NEO::SysCalls::close(fd);
}
return ZE_RESULT_SUCCESS;
}
void LinuxSysmanImp::releaseSysmanDeviceResources() {
getSysmanDeviceImp()->pEngineHandleContext->releaseEngines();
getSysmanDeviceImp()->pRasHandleContext->releaseRasHandles();
@@ -326,6 +363,7 @@ ze_result_t LinuxSysmanImp::initDevice() {
return ZE_RESULT_SUCCESS;
}
// function to clear Hot-Plug interrupt enable bit in the slot control register
// this is required to prevent interrupts from being raised in the warm reset path.
void LinuxSysmanImp::clearHPIE(int fd) {

View File

@@ -71,6 +71,7 @@ class LinuxSysmanImp : public OsSysman, NEO::NonCopyableOrMovableClass {
MOCKABLE_VIRTUAL void getPidFdsForOpenDevice(ProcfsAccess *, SysfsAccess *, const ::pid_t, std::vector<int> &);
MOCKABLE_VIRTUAL ze_result_t osWarmReset();
MOCKABLE_VIRTUAL ze_result_t osColdReset();
ze_result_t gpuProcessCleanup();
std::string getAddressFromPath(std::string &rootPortPath);
decltype(&NEO::SysCalls::open) openFunction = NEO::SysCalls::open;
decltype(&NEO::SysCalls::close) closeFunction = NEO::SysCalls::close;

View File

@@ -20,6 +20,12 @@ const std::string LinuxSchedulerImp::defaultHeartbeatIntervalMilliSecs(".default
const std::string LinuxSchedulerImp::enableEuDebug("");
const std::string LinuxSchedulerImp::engineDir("engine");
static const std::multimap<zes_engine_type_flag_t, std::string> level0EngineTypeToSysfsEngineMap = {
{ZES_ENGINE_TYPE_FLAG_RENDER, "rcs"},
{ZES_ENGINE_TYPE_FLAG_DMA, "bcs"},
{ZES_ENGINE_TYPE_FLAG_MEDIA, "vcs"},
{ZES_ENGINE_TYPE_FLAG_OTHER, "vecs"}};
ze_result_t LinuxSchedulerImp::getProperties(zes_sched_properties_t &schedProperties) {
schedProperties.onSubdevice = onSubdevice;
schedProperties.subdeviceId = subdeviceId;
@@ -29,6 +35,183 @@ ze_result_t LinuxSchedulerImp::getProperties(zes_sched_properties_t &schedProper
return ZE_RESULT_SUCCESS;
}
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) {
return result;
}
result = getTimesliceDuration(timeslice, false);
if (result != ZE_RESULT_SUCCESS) {
return result;
}
result = getHeartbeatInterval(heartbeat, false);
if (result != ZE_RESULT_SUCCESS) {
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) {
return result;
}
result = setTimesliceDuration(timeslice);
if (result != ZE_RESULT_SUCCESS) {
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) {
return result;
}
if (currMode == ZES_SCHED_MODE_COMPUTE_UNIT_DEBUG) {
// Unset this mode
result = disableComputeUnitDebugMode(pNeedReload);
if (result != ZE_RESULT_SUCCESS) {
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) {
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) {
return result;
}
result = getTimesliceDuration(timeslice, getDefaults);
if (result != ZE_RESULT_SUCCESS) {
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) {
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) {
return result;
}
}
result = setHeartbeatInterval(pProperties->watchdogTimeout);
if (result != ZE_RESULT_SUCCESS) {
return result;
}
uint64_t timeout = (pProperties->watchdogTimeout) / 5;
result = setPreemptTimeout(timeout);
if (result != ZE_RESULT_SUCCESS) {
return result;
}
uint64_t timeslice = 0;
result = setTimesliceDuration(timeslice);
if (result != ZE_RESULT_SUCCESS) {
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) {
return result;
}
if (currMode == ZES_SCHED_MODE_COMPUTE_UNIT_DEBUG) {
// Unset this mode
result = disableComputeUnitDebugMode(pNeedReload);
if (result != ZE_RESULT_SUCCESS) {
return result;
}
}
result = setPreemptTimeout(pProperties->yieldTimeout);
if (result != ZE_RESULT_SUCCESS) {
return result;
}
result = setTimesliceDuration(pProperties->interval);
if (result != ZE_RESULT_SUCCESS) {
return result;
}
uint64_t heartbeat = 2500 * (pProperties->interval);
return setHeartbeatInterval(heartbeat);
}
ze_result_t LinuxSchedulerImp::getPreemptTimeout(uint64_t &timeout, ze_bool_t getDefault) {
ze_result_t result = ZE_RESULT_ERROR_UNKNOWN;
uint32_t i = 0;
@@ -176,11 +359,14 @@ ze_result_t LinuxSchedulerImp::setComputeUnitDebugMode(ze_bool_t *pNeedReload) {
return pSysfsAccess->write(enableEuDebug, 1);
}
static const std::multimap<zes_engine_type_flag_t, std::string> level0EngineTypeToSysfsEngineMap = {
{ZES_ENGINE_TYPE_FLAG_RENDER, "rcs"},
{ZES_ENGINE_TYPE_FLAG_DMA, "bcs"},
{ZES_ENGINE_TYPE_FLAG_MEDIA, "vcs"},
{ZES_ENGINE_TYPE_FLAG_OTHER, "vecs"}};
bool LinuxSchedulerImp::isComputeUnitDebugModeEnabled() {
return false;
}
ze_result_t LinuxSchedulerImp::disableComputeUnitDebugMode(ze_bool_t *pNeedReload) {
*pNeedReload = false;
return pSysfsAccess->write(enableEuDebug, 0);
}
static ze_result_t getNumEngineTypeAndInstancesForDevice(std::map<zes_engine_type_flag_t, std::vector<std::string>> &mapOfEngines, SysfsAccess *pSysfsAccess) {
std::vector<std::string> localListOfAllEngines = {};

View File

@@ -8,6 +8,7 @@
#pragma once
#include "shared/source/os_interface/linux/drm_neo.h"
#include "sysman/linux/os_sysman_imp.h"
#include "sysman/scheduler/scheduler_imp.h"
#include <string>
@@ -22,13 +23,12 @@ struct Device;
// zes_sched_timeout_properties_t. watchdogTimeout = heartbeat_interval_ms
class LinuxSchedulerImp : public OsScheduler, NEO::NonCopyableOrMovableClass {
public:
ze_result_t getPreemptTimeout(uint64_t &timeout, ze_bool_t getDefault) override;
ze_result_t getTimesliceDuration(uint64_t &timeslice, ze_bool_t getDefault) override;
ze_result_t getHeartbeatInterval(uint64_t &heartbeat, ze_bool_t getDefault) override;
ze_result_t setPreemptTimeout(uint64_t timeout) override;
ze_result_t setTimesliceDuration(uint64_t timeslice) override;
ze_result_t setHeartbeatInterval(uint64_t heartbeat) override;
ze_bool_t canControlScheduler() override;
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;
@@ -38,11 +38,23 @@ class LinuxSchedulerImp : public OsScheduler, NEO::NonCopyableOrMovableClass {
static const std::string engineDir;
protected:
LinuxSysmanImp *pLinuxSysmanImp = nullptr;
SysfsAccess *pSysfsAccess = nullptr;
Device *pDevice = 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 &timeslice, 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;

View File

@@ -8,6 +8,7 @@
#include "shared/source/os_interface/linux/engine_info.h"
#include "shared/source/os_interface/linux/i915_prelim.h"
#include "level_zero/core/source/device/device_imp.h"
#include "level_zero/tools/source/sysman/scheduler/linux/os_scheduler_imp.h"
#include "sysman/linux/os_sysman_imp.h"
@@ -52,6 +53,183 @@ static const std::map<std::string, __u16> sysfsEngineMapToi915EngineClass = {
{"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) {
return result;
}
result = getTimesliceDuration(timeslice, false);
if (result != ZE_RESULT_SUCCESS) {
return result;
}
result = getHeartbeatInterval(heartbeat, false);
if (result != ZE_RESULT_SUCCESS) {
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) {
return result;
}
result = setTimesliceDuration(timeslice);
if (result != ZE_RESULT_SUCCESS) {
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) {
return result;
}
if (currMode == ZES_SCHED_MODE_COMPUTE_UNIT_DEBUG) {
// Unset this mode
result = disableComputeUnitDebugMode(pNeedReload);
if (result != ZE_RESULT_SUCCESS) {
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) {
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) {
return result;
}
result = getTimesliceDuration(timeslice, getDefaults);
if (result != ZE_RESULT_SUCCESS) {
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) {
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) {
return result;
}
}
result = setHeartbeatInterval(pProperties->watchdogTimeout);
if (result != ZE_RESULT_SUCCESS) {
return result;
}
uint64_t timeout = (pProperties->watchdogTimeout) / 5;
result = setPreemptTimeout(timeout);
if (result != ZE_RESULT_SUCCESS) {
return result;
}
uint64_t timeslice = 0;
result = setTimesliceDuration(timeslice);
if (result != ZE_RESULT_SUCCESS) {
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) {
return result;
}
if (currMode == ZES_SCHED_MODE_COMPUTE_UNIT_DEBUG) {
// Unset this mode
result = disableComputeUnitDebugMode(pNeedReload);
if (result != ZE_RESULT_SUCCESS) {
return result;
}
}
result = setPreemptTimeout(pProperties->yieldTimeout);
if (result != ZE_RESULT_SUCCESS) {
return result;
}
result = setTimesliceDuration(pProperties->interval);
if (result != ZE_RESULT_SUCCESS) {
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;
@@ -209,10 +387,63 @@ 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
auto pDevice = pLinuxSysmanImp->getDeviceHandle();
auto devicePtr = static_cast<DeviceImp *>(pDevice);
NEO::ExecutionEnvironment *executionEnvironment = devicePtr->getNEODevice()->getExecutionEnvironment();
auto restorer = std::make_unique<L0::ExecutionEnvironmentRefCountRestore>(executionEnvironment);
pLinuxSysmanImp->releaseDeviceResources();
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->initDevice();
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;
return pSysfsAccess->write(enableEuDebug, val);
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,
@@ -289,7 +520,7 @@ ze_result_t OsScheduler::getNumEngineTypeAndInstances(
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) {
LinuxSysmanImp *pLinuxSysmanImp = static_cast<LinuxSysmanImp *>(pOsSysman);
pLinuxSysmanImp = static_cast<LinuxSysmanImp *>(pOsSysman);
pSysfsAccess = &pLinuxSysmanImp->getSysfsAccess();
this->listOfEngines = listOfEngines;
}

View File

@@ -18,14 +18,13 @@ using namespace std;
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 getPreemptTimeout(uint64_t &timeout, ze_bool_t getDefault) = 0;
virtual ze_result_t getTimesliceDuration(uint64_t &timeslice, ze_bool_t getDefault) = 0;
virtual ze_result_t getHeartbeatInterval(uint64_t &heartbeat, ze_bool_t getDefault) = 0;
virtual ze_result_t setPreemptTimeout(uint64_t timeout) = 0;
virtual ze_result_t setTimesliceDuration(uint64_t timeslice) = 0;
virtual ze_result_t setHeartbeatInterval(uint64_t heartbeat) = 0;
virtual ze_bool_t canControlScheduler() = 0;
virtual ze_result_t getProperties(zes_sched_properties_t &properties) = 0;
static OsScheduler *create(OsSysman *pOsSysman, zes_engine_type_flag_t engineType, std::vector<std::string> &listOfEngines,
ze_bool_t isSubdevice, uint32_t subdeviceId);

View File

@@ -14,129 +14,31 @@
namespace L0 {
ze_result_t SchedulerImp::setExclusiveMode(ze_bool_t *pNeedReload) {
uint64_t timeslice = 0, timeout = 0, heartbeat = 0;
*pNeedReload = false;
ze_result_t result = pOsScheduler->setPreemptTimeout(timeout);
if (result != ZE_RESULT_SUCCESS) {
return result;
}
result = pOsScheduler->setTimesliceDuration(timeslice);
if (result != ZE_RESULT_SUCCESS) {
return result;
}
result = pOsScheduler->setHeartbeatInterval(heartbeat);
return result;
return pOsScheduler->setExclusiveMode(pNeedReload);
}
ze_result_t SchedulerImp::setComputeUnitDebugMode(ze_bool_t *pNeedReload) {
auto result = setExclusiveMode(pNeedReload);
if (result != ZE_RESULT_SUCCESS) {
return result;
}
result = pOsScheduler->setComputeUnitDebugMode(pNeedReload);
return result;
return pOsScheduler->setComputeUnitDebugMode(pNeedReload);
}
ze_result_t SchedulerImp::getCurrentMode(zes_sched_mode_t *pMode) {
uint64_t timeout = 0;
uint64_t timeslice = 0;
ze_result_t result = pOsScheduler->getPreemptTimeout(timeout, false);
if (result != ZE_RESULT_SUCCESS) {
return result;
}
result = pOsScheduler->getTimesliceDuration(timeslice, false);
if (result != ZE_RESULT_SUCCESS) {
return result;
}
if (timeslice > 0) {
*pMode = ZES_SCHED_MODE_TIMESLICE;
} else {
if (timeout > 0) {
*pMode = ZES_SCHED_MODE_TIMEOUT;
} else {
*pMode = ZES_SCHED_MODE_EXCLUSIVE;
}
}
return result;
return pOsScheduler->getCurrentMode(pMode);
}
ze_result_t SchedulerImp::getTimeoutModeProperties(ze_bool_t getDefaults, zes_sched_timeout_properties_t *pConfig) {
uint64_t heartbeat = 0;
ze_result_t result = pOsScheduler->getHeartbeatInterval(heartbeat, getDefaults);
if (result != ZE_RESULT_SUCCESS) {
return result;
}
pConfig->watchdogTimeout = heartbeat;
return result;
return pOsScheduler->getTimeoutModeProperties(getDefaults, pConfig);
}
ze_result_t SchedulerImp::getTimesliceModeProperties(ze_bool_t getDefaults, zes_sched_timeslice_properties_t *pConfig) {
uint64_t timeout = 0, timeslice = 0;
ze_result_t result = pOsScheduler->getPreemptTimeout(timeout, getDefaults);
if (result != ZE_RESULT_SUCCESS) {
return result;
}
result = pOsScheduler->getTimesliceDuration(timeslice, getDefaults);
if (result != ZE_RESULT_SUCCESS) {
return result;
}
pConfig->interval = timeslice;
pConfig->yieldTimeout = timeout;
return result;
return pOsScheduler->getTimesliceModeProperties(getDefaults, pConfig);
}
ze_result_t SchedulerImp::setTimeoutMode(zes_sched_timeout_properties_t *pProperties, ze_bool_t *pNeedReload) {
zes_sched_mode_t currMode;
ze_result_t result = getCurrentMode(&currMode);
if (result != ZE_RESULT_SUCCESS) {
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;
}
*pNeedReload = false;
result = pOsScheduler->setHeartbeatInterval(pProperties->watchdogTimeout);
if ((currMode == ZES_SCHED_MODE_TIMEOUT) || (result != ZE_RESULT_SUCCESS)) {
return result;
}
uint64_t timeout = (pProperties->watchdogTimeout) / 5;
result = pOsScheduler->setPreemptTimeout(timeout);
if (result != ZE_RESULT_SUCCESS) {
return result;
}
uint64_t timeslice = 0;
result = pOsScheduler->setTimesliceDuration(timeslice);
if (result != ZE_RESULT_SUCCESS) {
return result;
}
return result;
return pOsScheduler->setTimeoutMode(pProperties, pNeedReload);
}
ze_result_t SchedulerImp::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;
ze_result_t result = pOsScheduler->setPreemptTimeout(pProperties->yieldTimeout);
if (result != ZE_RESULT_SUCCESS) {
return result;
}
result = pOsScheduler->setTimesliceDuration(pProperties->interval);
if (result != ZE_RESULT_SUCCESS) {
return result;
}
uint64_t heartbeat = 2500 * (pProperties->interval);
result = pOsScheduler->setHeartbeatInterval(heartbeat);
return result;
return pOsScheduler->setTimesliceMode(pProperties, pNeedReload);
}
ze_result_t SchedulerImp::schedulerGetProperties(zes_sched_properties_t *pProperties) {

View File

@@ -11,34 +11,30 @@
namespace L0 {
ze_result_t WddmSchedulerImp::getPreemptTimeout(uint64_t &timeout, ze_bool_t getDefault) {
ze_result_t WddmSchedulerImp::getCurrentMode(zes_sched_mode_t *pMode) {
return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE;
}
ze_result_t WddmSchedulerImp::getTimesliceDuration(uint64_t &timeslice, ze_bool_t getDefault) {
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::getHeartbeatInterval(uint64_t &heartbeat, ze_bool_t getDefault) {
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::setPreemptTimeout(uint64_t timeout) {
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::setTimesliceDuration(uint64_t timeslice) {
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::setHeartbeatInterval(uint64_t heartbeat) {
ze_result_t WddmSchedulerImp::setExclusiveMode(ze_bool_t *pNeedReload) {
return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE;
}
ze_bool_t WddmSchedulerImp::canControlScheduler() {
return 0;
}
ze_result_t WddmSchedulerImp::getProperties(zes_sched_properties_t &properties) {
return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE;
}

View File

@@ -13,15 +13,14 @@ namespace L0 {
class WddmSchedulerImp : public OsScheduler {
public:
ze_result_t getPreemptTimeout(uint64_t &timeout, ze_bool_t getDefault) override;
ze_result_t getTimesliceDuration(uint64_t &timeslice, ze_bool_t getDefault) override;
ze_result_t getHeartbeatInterval(uint64_t &heartbeat, ze_bool_t getDefault) override;
ze_result_t setPreemptTimeout(uint64_t timeout) override;
ze_result_t setTimesliceDuration(uint64_t timeslice) override;
ze_result_t setHeartbeatInterval(uint64_t heartbeat) override;
ze_bool_t canControlScheduler() override;
ze_result_t getProperties(zes_sched_properties_t &properties) 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;
ze_result_t getProperties(zes_sched_properties_t &properties) override;
};
} // namespace L0

View File

@@ -183,7 +183,70 @@ class SchedulerFileProperties {
}
};
class SchedulerSysfsAccess : public SysfsAccess {};
class MockSchedulerProcfsAccess : public ProcfsAccess {
public:
MockSchedulerProcfsAccess() = default;
const pid_t pid1 = 1234;
const pid_t pid2 = 1235;
const pid_t pid3 = 1236;
const pid_t pid4 = 1237;
ze_result_t listProcessesResult = ZE_RESULT_SUCCESS;
ze_result_t listProcesses(std::vector<::pid_t> &list) override {
if (listProcessesResult != ZE_RESULT_SUCCESS) {
return listProcessesResult;
}
list.push_back(pid1);
list.push_back(pid2);
list.push_back(pid3);
list.push_back(pid4);
return ZE_RESULT_SUCCESS;
}
ze_result_t getFileDescriptorsResult;
ze_result_t getFileDescriptors(const ::pid_t pid, std::vector<int> &list) override {
// push dummy fd numbers in list vector
if (pid == pid1) {
list.push_back(1);
list.push_back(2);
} else if (pid == pid2) {
list.push_back(1);
list.push_back(2);
} else if (pid == pid3) {
list.push_back(1);
list.push_back(2);
} else if (pid == pid4) {
list.push_back(1);
list.push_back(3);
}
return ZE_RESULT_SUCCESS;
}
ze_result_t getFileName(const ::pid_t pid, const int fd, std::string &val) override {
if (fd == 1) {
val = "/dev/null"; // assuming after opening /dev/null fd received is 1
return ZE_RESULT_SUCCESS;
}
if (fd == 2) {
val = "/dev/dri/renderD128"; // assuming after opening /dev/dri/renderD128 fd received is 2
return ZE_RESULT_SUCCESS;
}
if (fd == 3) {
val = "/dev/dummy"; // assuming after opening /dev/dummy fd received is 3
return ZE_RESULT_SUCCESS;
}
return ZE_RESULT_ERROR_NOT_AVAILABLE;
}
::pid_t myProcessId() override {
return pid2;
}
ADDMETHOD_NOBASE_VOIDRETURN(kill, (const ::pid_t pid));
};
//class SchedulerSysfsAccess : public SysfsAccess {};
typedef struct SchedulerConfigValues {
uint64_t defaultVal;
@@ -197,10 +260,21 @@ typedef struct SchedulerConfig {
uint64_t euDebugEnable;
} SchedulerConfig_t;
struct MockSchedulerSysfsAccess : public SchedulerSysfsAccess {
class CalledTimesUpdate {
public:
CalledTimesUpdate(int &calledTimes) : calledTimesVar(calledTimes) {}
~CalledTimesUpdate() {
calledTimesVar++;
}
private:
int &calledTimesVar;
};
struct MockSchedulerSysfsAccess : public SysfsAccess {
using SysfsAccess::deviceNames;
ze_result_t mockReadFileFailureError = ZE_RESULT_SUCCESS;
ze_result_t mockWriteFileStatus = ZE_RESULT_SUCCESS;
ze_result_t mockGetScanDirEntryError = ZE_RESULT_SUCCESS;
std::vector<ze_result_t> mockReadReturnValues{ZE_RESULT_SUCCESS, ZE_RESULT_SUCCESS, ZE_RESULT_SUCCESS, ZE_RESULT_ERROR_NOT_AVAILABLE};
@@ -252,6 +326,21 @@ struct MockSchedulerSysfsAccess : public SchedulerSysfsAccess {
return ZE_RESULT_ERROR_UNKNOWN;
}
ze_result_t canWrite(const std::string file) override {
SchedulerFileProperties fileProperties;
ze_result_t result = getFileProperties(file, fileProperties);
if (ZE_RESULT_SUCCESS == result) {
if (!fileProperties.getAvailability()) {
return ZE_RESULT_ERROR_NOT_AVAILABLE;
}
if (!fileProperties.hasMode(S_IWUSR)) {
return ZE_RESULT_ERROR_INSUFFICIENT_PERMISSIONS;
}
return result;
}
return ZE_RESULT_ERROR_UNKNOWN;
}
ze_result_t read(const std::string file, uint64_t &val) override {
if (mockReadReturnStatus == true) {
@@ -350,10 +439,15 @@ struct MockSchedulerSysfsAccess : public SchedulerSysfsAccess {
return ZE_RESULT_ERROR_NOT_AVAILABLE;
}
int writeCalled = 0;
std::vector<ze_result_t> writeResult{ZE_RESULT_SUCCESS};
ze_result_t write(const std::string file, const uint64_t val) override {
if (mockWriteFileStatus != ZE_RESULT_SUCCESS) {
return mockWriteFileStatus;
CalledTimesUpdate update(writeCalled); // increment this method's call count while exiting this method
if (writeCalled < static_cast<int>(writeResult.size())) {
if (writeResult[writeCalled] != ZE_RESULT_SUCCESS) {
// If we are here, it means test simply wants to validate failure values from this method
return writeResult[writeCalled];
}
}
if (mockGetValueForErrorWhileWrite == true) {
@@ -499,8 +593,13 @@ struct MockSchedulerSysfsAccess : public SchedulerSysfsAccess {
class PublicLinuxSchedulerImp : public L0::LinuxSchedulerImp {
public:
using LinuxSchedulerImp::isComputeUnitDebugModeEnabled;
using LinuxSchedulerImp::pDevice;
using LinuxSchedulerImp::pSysfsAccess;
using LinuxSchedulerImp::setExclusiveModeImp;
using LinuxSchedulerImp::setHeartbeatInterval;
using LinuxSchedulerImp::setPreemptTimeout;
using LinuxSchedulerImp::setTimesliceDuration;
using LinuxSchedulerImp::subdeviceId;
};

View File

@@ -40,6 +40,7 @@ class SysmanDeviceSchedulerFixture : public SysmanDeviceFixture {
std::unique_ptr<MockSchedulerSysfsAccess> pSysfsAccess;
SysfsAccess *pSysfsAccessOld = nullptr;
std::vector<ze_device_handle_t> deviceHandles;
PublicLinuxSchedulerImp *pLinuxSchedulerImp = nullptr;
void SetUp() override {
if (!sysmanUltsEnable) {
@@ -48,6 +49,7 @@ class SysmanDeviceSchedulerFixture : public SysmanDeviceFixture {
SysmanDeviceFixture::SetUp();
pSysfsAccessOld = pLinuxSysmanImp->pSysfsAccess;
pSysfsAccess = std::make_unique<MockSchedulerSysfsAccess>();
pSysfsAccess->deviceNames = {"card0", "controlD64", "renderD128"};
pLinuxSysmanImp->pSysfsAccess = pSysfsAccess.get();
for_each(listOfMockedEngines.begin(), listOfMockedEngines.end(),
[=](std::string engineName) {
@@ -123,6 +125,16 @@ class SysmanDeviceSchedulerFixture : public SysmanDeviceFixture {
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
return config;
}
void setComputeUnitDebugModeMock(zes_sched_handle_t hScheduler) {
auto pSchedulerImp = static_cast<SchedulerImp *>(Scheduler::fromHandle(hScheduler));
auto pOsScheduler = static_cast<PublicLinuxSchedulerImp *>(pSchedulerImp->pOsScheduler);
EXPECT_EQ(ZE_RESULT_SUCCESS, pOsScheduler->setExclusiveModeImp());
uint64_t val = 1;
pSysfsAccess->write(enableEuDebug, val);
EXPECT_EQ(ZES_SCHED_MODE_COMPUTE_UNIT_DEBUG, fixtureGetCurrentMode(hScheduler));
}
};
TEST_F(SysmanDeviceSchedulerFixture, GivenComponentCountZeroWhenCallingzesDeviceEnumSchedulersAndSysfsCanReadReturnsErrorThenZeroCountIsReturned) {
@@ -172,6 +184,19 @@ TEST_F(SysmanDeviceSchedulerFixture, GivenValidDeviceHandleWhenCallingzesSchedul
}
}
TEST_F(SysmanDeviceSchedulerFixture, GivenSomeInvalidSchedulerModeWhenCheckingForCurrentModeThenAPIReportUnknownMode) {
auto handles = getSchedHandles(handleComponentCount);
auto pSchedulerImp = static_cast<SchedulerImp *>(Scheduler::fromHandle(handles[0]));
auto pOsScheduler = static_cast<PublicLinuxSchedulerImp *>(pSchedulerImp->pOsScheduler);
uint64_t timeslice = 0, timeout = 0, heartbeat = 3000;
pOsScheduler->setPreemptTimeout(timeout);
pOsScheduler->setTimesliceDuration(timeslice);
pOsScheduler->setHeartbeatInterval(heartbeat);
zes_sched_mode_t mode;
EXPECT_EQ(ZE_RESULT_ERROR_UNKNOWN, zesSchedulerGetCurrentMode(handles[0], &mode));
EXPECT_EQ(ZES_SCHED_MODE_FORCE_UINT32, mode);
}
TEST_F(SysmanDeviceSchedulerFixture, GivenValidDeviceHandleWhenCallingzesSchedulerGetTimeoutModePropertiesThenVerifyzesSchedulerGetTimeoutModePropertiesForDifferingValues) {
auto handles = getSchedHandles(handleComponentCount);
@@ -341,6 +366,50 @@ TEST_F(SysmanDeviceSchedulerFixture, GivenValidDeviceHandleWhenCallingzesSchedul
}
}
TEST_F(SysmanDeviceSchedulerFixture, GivenCurrentModeIsDebugModeWhenCallingzesSchedulerSetTimeoutModeThenVerifyCallSucceeds) {
VariableBackup<ProcfsAccess *> backup(&pLinuxSysmanImp->pProcfsAccess);
auto pMockSchedulerProcfsAccess = new MockSchedulerProcfsAccess;
pLinuxSysmanImp->pProcfsAccess = pMockSchedulerProcfsAccess;
// First set compute unit debug mode
auto handles = getSchedHandles(handleComponentCount);
setComputeUnitDebugModeMock(handles[0]);
// Change mode to ZES_SCHED_MODE_EXCLUSIVE and validate
ze_bool_t needReboot;
zes_sched_timeout_properties_t setConfig;
setConfig.watchdogTimeout = 10000u;
EXPECT_EQ(ZE_RESULT_SUCCESS, zesSchedulerSetTimeoutMode(handles[0], &setConfig, &needReboot));
EXPECT_FALSE(needReboot);
auto getConfig = fixtureGetTimeoutModeProperties(handles[0], false);
EXPECT_EQ(getConfig.watchdogTimeout, setConfig.watchdogTimeout);
auto mode = fixtureGetCurrentMode(handles[0]);
EXPECT_EQ(mode, ZES_SCHED_MODE_TIMEOUT);
delete pMockSchedulerProcfsAccess;
}
TEST_F(SysmanDeviceSchedulerFixture, GivenCurrentModeIsDebugModeWhenSettingTimeoutModeAndDebugModeCantBeChangedThenVerifyCallFails) {
VariableBackup<ProcfsAccess *> backup(&pLinuxSysmanImp->pProcfsAccess);
auto pMockSchedulerProcfsAccess = new MockSchedulerProcfsAccess;
pLinuxSysmanImp->pProcfsAccess = pMockSchedulerProcfsAccess;
pMockSchedulerProcfsAccess->listProcessesResult = ZE_RESULT_ERROR_NOT_AVAILABLE; // Expect failure when calling gpuProcessCleanup()
// First set compute unit debug mode
auto handles = getSchedHandles(handleComponentCount);
setComputeUnitDebugModeMock(handles[0]);
// Change mode to ZES_SCHED_MODE_EXCLUSIVE and validate
ze_bool_t needReboot;
zes_sched_timeout_properties_t setConfig;
setConfig.watchdogTimeout = 10000u;
EXPECT_EQ(ZE_RESULT_ERROR_NOT_AVAILABLE, zesSchedulerSetTimeoutMode(handles[0], &setConfig, &needReboot));
EXPECT_FALSE(needReboot);
EXPECT_EQ(ZES_SCHED_MODE_COMPUTE_UNIT_DEBUG, fixtureGetCurrentMode(handles[0]));
delete pMockSchedulerProcfsAccess;
}
TEST_F(SysmanDeviceSchedulerFixture, GivenValidDeviceHandleWhenCallingzesSchedulerSetTimeoutModeWhenTimeoutLessThanMinimumThenVerifyzesSchedulerSetTimeoutModeCallFails) {
auto handles = getSchedHandles(handleComponentCount);
for (auto handle : handles) {
@@ -369,15 +438,14 @@ TEST_F(SysmanDeviceSchedulerFixture, GivenValidDeviceHandleWhenCallingzesSchedul
TEST_F(SysmanDeviceSchedulerFixture, GivenValidDeviceHandleWhenCallingzesSchedulerSetTimeoutModeWhenHeartBeatSettingFailsThenVerifyzesSchedulerSetTimeoutModeCallFails) {
for_each(listOfMockedEngines.begin(), listOfMockedEngines.end(),
[=](std::string engineName) {
pSysfsAccess->setFileProperties(engineName, heartbeatIntervalMilliSecs, false, S_IRUSR | S_IRGRP | S_IROTH | S_IWUSR);
pSysfsAccess->setFileProperties(engineName, heartbeatIntervalMilliSecs, true, S_IRUSR | S_IRGRP | S_IROTH);
});
auto handles = getSchedHandles(handleComponentCount);
for (auto handle : handles) {
ze_bool_t needReboot;
zes_sched_timeout_properties_t setTimeOutConfig;
setTimeOutConfig.watchdogTimeout = 10000u;
ze_result_t result = zesSchedulerSetTimeoutMode(handle, &setTimeOutConfig, &needReboot);
EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, result);
EXPECT_EQ(ZE_RESULT_ERROR_INSUFFICIENT_PERMISSIONS, zesSchedulerSetTimeoutMode(handle, &setTimeOutConfig, &needReboot));
}
}
@@ -444,6 +512,69 @@ TEST_F(SysmanDeviceSchedulerFixture, GivenValidDeviceHandleWhenCallingzesSchedul
}
}
TEST_F(SysmanDeviceSchedulerFixture, GivenCurrentModeIsDebugModeWhenCallingzesSchedulerSetTimesliceModeThenVerifyCallSucceeds) {
VariableBackup<ProcfsAccess *> backup(&pLinuxSysmanImp->pProcfsAccess);
auto pMockSchedulerProcfsAccess = new MockSchedulerProcfsAccess;
pLinuxSysmanImp->pProcfsAccess = pMockSchedulerProcfsAccess;
// First set compute unit debug mode
auto handles = getSchedHandles(handleComponentCount);
setComputeUnitDebugModeMock(handles[0]);
// Change mode to ZES_SCHED_MODE_EXCLUSIVE and validate
ze_bool_t needReboot;
zes_sched_timeslice_properties_t setConfig;
setConfig.interval = 1000u;
setConfig.yieldTimeout = 1000u;
EXPECT_EQ(ZE_RESULT_SUCCESS, zesSchedulerSetTimesliceMode(handles[0], &setConfig, &needReboot));
EXPECT_FALSE(needReboot);
auto getConfig = fixtureGetTimesliceModeProperties(handles[0], false);
EXPECT_EQ(getConfig.interval, setConfig.interval);
EXPECT_EQ(getConfig.yieldTimeout, setConfig.yieldTimeout);
auto mode = fixtureGetCurrentMode(handles[0]);
EXPECT_EQ(mode, ZES_SCHED_MODE_TIMESLICE);
delete pMockSchedulerProcfsAccess;
}
TEST_F(SysmanDeviceSchedulerFixture, GivenCurrentModeIsDebugModeWhenSettingTimesliceModeAndDebugModeCantBeChangedThenVerifyCallFails) {
VariableBackup<ProcfsAccess *> backup(&pLinuxSysmanImp->pProcfsAccess);
auto pMockSchedulerProcfsAccess = new MockSchedulerProcfsAccess;
pLinuxSysmanImp->pProcfsAccess = pMockSchedulerProcfsAccess;
pMockSchedulerProcfsAccess->listProcessesResult = ZE_RESULT_ERROR_NOT_AVAILABLE; // Expect failure when calling gpuProcessCleanup()
// First set compute unit debug mode
auto handles = getSchedHandles(handleComponentCount);
setComputeUnitDebugModeMock(handles[0]);
// Change mode to ZES_SCHED_MODE_EXCLUSIVE and validate
ze_bool_t needReboot;
zes_sched_timeslice_properties_t setConfig;
setConfig.interval = 1000u;
setConfig.yieldTimeout = 1000u;
EXPECT_EQ(ZE_RESULT_ERROR_NOT_AVAILABLE, zesSchedulerSetTimesliceMode(handles[0], &setConfig, &needReboot));
EXPECT_FALSE(needReboot);
EXPECT_EQ(ZES_SCHED_MODE_COMPUTE_UNIT_DEBUG, fixtureGetCurrentMode(handles[0]));
delete pMockSchedulerProcfsAccess;
}
TEST_F(SysmanDeviceSchedulerFixture, GivenGetCurrentModeFailsWhenCallingzesSchedulerSetTimesliceModeThenVerifyzesSchedulerSetTimesliceModeCallFails) {
for_each(listOfMockedEngines.begin(), listOfMockedEngines.end(),
[=](std::string engineName) {
pSysfsAccess->setFileProperties(engineName, preemptTimeoutMilliSecs, false, S_IRUSR | S_IRGRP | S_IROTH | S_IWUSR);
});
auto handles = getSchedHandles(handleComponentCount);
for (auto handle : handles) {
ze_bool_t needReboot;
zes_sched_timeslice_properties_t setConfig;
setConfig.interval = 1000u;
setConfig.yieldTimeout = 1000u;
EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, zesSchedulerSetTimesliceMode(handle, &setConfig, &needReboot));
EXPECT_FALSE(needReboot);
}
}
TEST_F(SysmanDeviceSchedulerFixture, GivenValidDeviceHandleWhenCallingzesSchedulerSetTimesliceModeWhenIntervalIsLessThanMinimumThenVerifyzesSchedulerSetTimesliceModeCallFails) {
auto handles = getSchedHandles(handleComponentCount);
for (auto handle : handles) {
@@ -472,7 +603,7 @@ TEST_F(SysmanDeviceSchedulerFixture, GivenValidDeviceHandleWhenCallingzesSchedul
}
}
TEST_F(SysmanDeviceSchedulerFixture, GivenValidDeviceHandleWhenCallingzesSchedulerSetTimesliceModeWhenNoAccessToHeartBeatIntervalThenVerifyzesSchedulerSetTimesliceModeCallFails) {
TEST_F(SysmanDeviceSchedulerFixture, GivenNoAccessToHeartBeatIntervalWhenSettingTimesliceModeThenThenVerifyzesSchedulerSetTimesliceModeCallFails) {
for_each(listOfMockedEngines.begin(), listOfMockedEngines.end(),
[=](std::string engineName) {
pSysfsAccess->setFileProperties(engineName, heartbeatIntervalMilliSecs, true, S_IRUSR | S_IRGRP | S_IROTH);
@@ -488,7 +619,19 @@ TEST_F(SysmanDeviceSchedulerFixture, GivenValidDeviceHandleWhenCallingzesSchedul
}
}
TEST_F(SysmanDeviceSchedulerFixture, GivenValidDeviceHandleWhenCallingzesSchedulerSetExclusiveModeThenVerifyzesSchedulerSetExclusiveModeCallSucceeds) {
TEST_F(SysmanDeviceSchedulerFixture, GivenHeartBeatIntervalFileNotPresentWhenSettingHeartbeatIntervalThenThenCallFails) {
for_each(listOfMockedEngines.begin(), listOfMockedEngines.end(),
[=](std::string engineName) {
pSysfsAccess->setFileProperties(engineName, heartbeatIntervalMilliSecs, false, S_IRUSR | S_IRGRP | S_IROTH);
});
auto handles = getSchedHandles(handleComponentCount);
auto pSchedulerImp = static_cast<SchedulerImp *>(Scheduler::fromHandle(handles[0]));
auto pOsScheduler = static_cast<PublicLinuxSchedulerImp *>(pSchedulerImp->pOsScheduler);
EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, pOsScheduler->setHeartbeatInterval(2000));
}
TEST_F(SysmanDeviceSchedulerFixture, GivenValidDeviceHandleWhenCallingzesSchedulerSetExclusiveModeThenVerifyCallSucceeds) {
auto handles = getSchedHandles(handleComponentCount);
for (auto handle : handles) {
ze_bool_t needReboot;
@@ -500,6 +643,43 @@ TEST_F(SysmanDeviceSchedulerFixture, GivenValidDeviceHandleWhenCallingzesSchedul
}
}
TEST_F(SysmanDeviceSchedulerFixture, GivenCurrentModeIsDebugModeWhenCallingzesSchedulerSetExclusiveModeThenVerifyCallSucceeds) {
VariableBackup<ProcfsAccess *> backup(&pLinuxSysmanImp->pProcfsAccess);
auto pMockSchedulerProcfsAccess = new MockSchedulerProcfsAccess;
pLinuxSysmanImp->pProcfsAccess = pMockSchedulerProcfsAccess;
// First set compute unit debug mode
auto handles = getSchedHandles(handleComponentCount);
ze_bool_t needReload;
setComputeUnitDebugModeMock(handles[0]);
// Change mode to ZES_SCHED_MODE_EXCLUSIVE and validate
EXPECT_EQ(ZE_RESULT_SUCCESS, zesSchedulerSetExclusiveMode(handles[0], &needReload));
EXPECT_FALSE(needReload);
EXPECT_EQ(ZES_SCHED_MODE_EXCLUSIVE, fixtureGetCurrentMode(handles[0]));
delete pMockSchedulerProcfsAccess;
}
TEST_F(SysmanDeviceSchedulerFixture, GivenCurrentModeIsDebugModeWhenSettingExclusiveModeAndDebugModeCantBeChangedThenVerifyCallFails) {
VariableBackup<ProcfsAccess *> backup(&pLinuxSysmanImp->pProcfsAccess);
auto pMockSchedulerProcfsAccess = new MockSchedulerProcfsAccess;
pLinuxSysmanImp->pProcfsAccess = pMockSchedulerProcfsAccess;
pMockSchedulerProcfsAccess->listProcessesResult = ZE_RESULT_ERROR_NOT_AVAILABLE; // Expect failure when calling gpuProcessCleanup()
// First set compute unit debug mode
auto handles = getSchedHandles(handleComponentCount);
ze_bool_t needReload;
setComputeUnitDebugModeMock(handles[0]);
// Change mode to ZES_SCHED_MODE_EXCLUSIVE and validate
EXPECT_EQ(ZE_RESULT_ERROR_NOT_AVAILABLE, zesSchedulerSetExclusiveMode(handles[0], &needReload));
EXPECT_FALSE(needReload);
EXPECT_EQ(ZES_SCHED_MODE_COMPUTE_UNIT_DEBUG, fixtureGetCurrentMode(handles[0]));
delete pMockSchedulerProcfsAccess;
}
TEST_F(SysmanDeviceSchedulerFixture, GivenValidDeviceHandleWhenCallingzesSchedulerSetExclusiveModeWhenPreEmptTimeoutNotAvailableThenVerifyzesSchedulerSetExclusiveModeCallFails) {
for_each(listOfMockedEngines.begin(), listOfMockedEngines.end(),
[=](std::string engineName) {
@@ -565,6 +745,19 @@ TEST_F(SysmanDeviceSchedulerFixture, GivenValidDeviceHandleWhenCallingzesSchedul
}
}
TEST_F(SysmanDeviceSchedulerFixture, GivenValidDeviceHandleWhenCallingzesSchedulerGetCurrentModeWhenHeartBeatIntervalNotAvailableThenFailureIsReturned) {
for_each(listOfMockedEngines.begin(), listOfMockedEngines.end(),
[=](std::string engineName) {
pSysfsAccess->setFileProperties(engineName, heartbeatIntervalMilliSecs, false, S_IRUSR | S_IRGRP | S_IROTH | S_IWUSR);
});
auto handles = getSchedHandles(handleComponentCount);
for (auto handle : handles) {
zes_sched_mode_t mode;
ze_result_t result = zesSchedulerGetCurrentMode(handle, &mode);
EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, result);
}
}
TEST_F(SysmanDeviceSchedulerFixture, GivenValidDeviceHandleWhenCallingzesSchedulerGetCurrentModeWhenTimeSliceDurationHasNoPermissionThenFailureIsReturned) {
for_each(listOfMockedEngines.begin(), listOfMockedEngines.end(),
[=](std::string engineName) {
@@ -579,19 +772,79 @@ TEST_F(SysmanDeviceSchedulerFixture, GivenValidDeviceHandleWhenCallingzesSchedul
}
TEST_F(SysmanDeviceSchedulerFixture, GivenValidDeviceHandleWhenCallingzesSchedulerSetComputeUnitDebugModeThenSuccessIsReturned) {
VariableBackup<ProcfsAccess *> backup(&pLinuxSysmanImp->pProcfsAccess);
auto pMockSchedulerProcfsAccess = new MockSchedulerProcfsAccess;
pLinuxSysmanImp->pProcfsAccess = pMockSchedulerProcfsAccess;
auto handles = getSchedHandles(handleComponentCount);
uint64_t val = 0;
pSysfsAccess->read(enableEuDebug, val);
EXPECT_EQ(val, 0u);
for (auto handle : handles) {
ze_bool_t needReload;
val = 0;
pSysfsAccess->write(enableEuDebug, val);
ze_result_t result = zesSchedulerSetComputeUnitDebugMode(handle, &needReload);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
pSysfsAccess->read(enableEuDebug, val);
EXPECT_EQ(val, 1u);
}
ze_bool_t needReload;
val = 0;
pSysfsAccess->write(enableEuDebug, val);
ze_result_t result = zesSchedulerSetComputeUnitDebugMode(handles[0], &needReload);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
pSysfsAccess->read(enableEuDebug, val);
EXPECT_EQ(val, 1u);
delete pMockSchedulerProcfsAccess;
}
TEST_F(SysmanDeviceSchedulerFixture, GivenGpuProcessCleanupFailedWhenCallingzesSchedulerSetComputeUnitDebugModeThenErrorIsReturned) {
VariableBackup<ProcfsAccess *> backup(&pLinuxSysmanImp->pProcfsAccess);
auto pMockSchedulerProcfsAccess = new MockSchedulerProcfsAccess;
pLinuxSysmanImp->pProcfsAccess = pMockSchedulerProcfsAccess;
pMockSchedulerProcfsAccess->listProcessesResult = ZE_RESULT_ERROR_NOT_AVAILABLE; // Expect failure when calling gpuProcessCleanup()
auto handles = getSchedHandles(handleComponentCount);
uint64_t val = 0;
pSysfsAccess->read(enableEuDebug, val);
EXPECT_EQ(val, 0u);
ze_bool_t needReload;
val = 0;
pSysfsAccess->write(enableEuDebug, val);
ze_result_t result = zesSchedulerSetComputeUnitDebugMode(handles[0], &needReload);
EXPECT_EQ(ZE_RESULT_ERROR_NOT_AVAILABLE, result);
pSysfsAccess->read(enableEuDebug, val);
EXPECT_EQ(val, 0u);
delete pMockSchedulerProcfsAccess;
}
TEST_F(SysmanDeviceSchedulerFixture, GivenEuDebugNodeWriteFailsWhenCallingzesSchedulerSetComputeUnitDebugModeThenErrorIsReturned) {
VariableBackup<ProcfsAccess *> backup(&pLinuxSysmanImp->pProcfsAccess);
auto pMockSchedulerProcfsAccess = new MockSchedulerProcfsAccess;
pLinuxSysmanImp->pProcfsAccess = pMockSchedulerProcfsAccess;
auto handles = getSchedHandles(handleComponentCount);
uint64_t val = 0;
pSysfsAccess->read(enableEuDebug, val);
EXPECT_EQ(val, 0u);
ze_bool_t needReload;
val = 0;
pSysfsAccess->write(enableEuDebug, val);
pSysfsAccess->writeCalled = 0; // Lets initialize write methods call times to zero from this point for this test
pSysfsAccess->writeResult.clear(); // Initialize write Results
pSysfsAccess->writeResult.push_back(ZE_RESULT_SUCCESS); // This write call would be success for setting exclusive mode
pSysfsAccess->writeResult.push_back(ZE_RESULT_SUCCESS); // This write call would be success for setting exclusive mode
pSysfsAccess->writeResult.push_back(ZE_RESULT_SUCCESS); // This write call would be success for setting exclusive mode
pSysfsAccess->writeResult.push_back(ZE_RESULT_ERROR_HANDLE_OBJECT_IN_USE); // Failure while writing eu debug enable node
ze_result_t result = zesSchedulerSetComputeUnitDebugMode(handles[0], &needReload);
EXPECT_EQ(ZE_RESULT_ERROR_HANDLE_OBJECT_IN_USE, result);
pSysfsAccess->read(enableEuDebug, val);
EXPECT_EQ(val, 0u);
delete pMockSchedulerProcfsAccess;
}
TEST_F(SysmanDeviceSchedulerFixture, GivenNodeRequiredToEnableEuDebugNotPresentWhenCheckingForDebugModeThenCallReturnsFalse) {
auto handles = getSchedHandles(handleComponentCount);
auto pSchedulerImp = static_cast<SchedulerImp *>(Scheduler::fromHandle(handles[0]));
auto pOsScheduler = static_cast<PublicLinuxSchedulerImp *>(pSchedulerImp->pOsScheduler);
std::string dummy;
pSysfsAccess->setFileProperties(dummy, enableEuDebug, false, S_IRUSR | S_IRGRP | S_IROTH | S_IWUSR);
EXPECT_FALSE(pOsScheduler->isComputeUnitDebugModeEnabled());
}
TEST_F(SysmanDeviceSchedulerFixture, GivenPrelimEnableEuDebugNodeNotAvailableWhenCallingzesSchedulerSetComputeUnitDebugModeThenErrorReturned) {
@@ -605,7 +858,22 @@ TEST_F(SysmanDeviceSchedulerFixture, GivenPrelimEnableEuDebugNodeNotAvailableWhe
}
}
TEST_F(SysmanDeviceSchedulerFixture, GivenExclusiveModeSetFailWhenCallingzesSchedulerSetComputeUnitDebugModeThenErrorReturned) {
TEST_F(SysmanDeviceSchedulerFixture, GivenExclusiveModeSetFailWhenCallingzesSchedulerSetComputeUnitDebugModeThenErrorReturned1) {
// Fail exclusive mode set due to preemptTimeoutMilliSecs file not available
for_each(listOfMockedEngines.begin(), listOfMockedEngines.end(),
[=](std::string engineName) {
pSysfsAccess->setFileProperties(engineName, preemptTimeoutMilliSecs, false, S_IRUSR | S_IRGRP | S_IROTH | S_IWUSR);
});
auto handles = getSchedHandles(handleComponentCount);
for (auto handle : handles) {
ze_bool_t needReload;
ze_result_t result = zesSchedulerSetComputeUnitDebugMode(handle, &needReload);
EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, result);
}
}
TEST_F(SysmanDeviceSchedulerFixture, GivenExclusiveModeSetFailWhenCallingzesSchedulerSetComputeUnitDebugModeThenErrorReturned2) {
// Fail exclusive mode set due to timesliceDurationMilliSecs file not available
for_each(listOfMockedEngines.begin(), listOfMockedEngines.end(),
[=](std::string engineName) {
pSysfsAccess->setFileProperties(engineName, timesliceDurationMilliSecs, false, S_IRUSR | S_IRGRP | S_IROTH | S_IWUSR);
@@ -668,7 +936,9 @@ TEST_F(SysmanDeviceSchedulerFixture, GivenValidDeviceHandleWhenCallingzesSchedul
setConfig.interval = 1000u;
setConfig.yieldTimeout = 1000u;
pSysfsAccess->mockWriteFileStatus = ZE_RESULT_ERROR_INSUFFICIENT_PERMISSIONS;
pSysfsAccess->writeCalled = 0; // Lets initialize write methods call times to zero from this point for this test
pSysfsAccess->writeResult.clear(); // Initialize write Results
pSysfsAccess->writeResult.push_back(ZE_RESULT_ERROR_INSUFFICIENT_PERMISSIONS);
ze_result_t result = zesSchedulerSetTimesliceMode(handle, &setConfig, &needReboot);
EXPECT_EQ(ZE_RESULT_ERROR_INSUFFICIENT_PERMISSIONS, result);

View File

@@ -9,6 +9,5 @@ if(WIN32)
PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt
${CMAKE_CURRENT_SOURCE_DIR}/test_zes_sysman_scheduler.cpp
${CMAKE_CURRENT_SOURCE_DIR}/mock_zes_sysman_scheduler.h
)
endif()

View File

@@ -1,32 +0,0 @@
/*
* Copyright (C) 2022 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#pragma once
#include "level_zero/tools/source/sysman/scheduler/os_scheduler.h"
#include "level_zero/tools/source/sysman/scheduler/scheduler_imp.h"
#include "level_zero/tools/test/unit_tests/sources/sysman/windows/mock_sysman_fixture.h"
namespace L0 {
namespace ult {
struct OsSchedulerMock : public OsScheduler {
OsSchedulerMock() = default;
ADDMETHOD_NOBASE(setComputeUnitDebugMode, ze_result_t, ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, (ze_bool_t * pNeedReload));
ADDMETHOD_NOBASE(getPreemptTimeout, ze_result_t, ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, (uint64_t & timeout, ze_bool_t getDefault));
ADDMETHOD_NOBASE(getTimesliceDuration, ze_result_t, ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, (uint64_t & timeslice, ze_bool_t getDefault));
ADDMETHOD_NOBASE(getHeartbeatInterval, ze_result_t, ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, (uint64_t & heartbeat, ze_bool_t getDefault));
ADDMETHOD_NOBASE(setPreemptTimeout, ze_result_t, ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, (uint64_t timeout));
ADDMETHOD_NOBASE(setTimesliceDuration, ze_result_t, ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, (uint64_t timeslice));
ADDMETHOD_NOBASE(setHeartbeatInterval, ze_result_t, ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, (uint64_t heartbeat));
ADDMETHOD_NOBASE(canControlScheduler, ze_bool_t, false, ());
ADDMETHOD_NOBASE(getProperties, ze_result_t, ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, (zes_sched_properties_t & properties));
};
} // namespace ult
} // namespace L0

View File

@@ -5,7 +5,9 @@
*
*/
#include "level_zero/tools/test/unit_tests/sources/sysman/scheduler/windows/mock_zes_sysman_scheduler.h"
#include "level_zero/tools/source/sysman/scheduler/os_scheduler.h"
#include "level_zero/tools/source/sysman/scheduler/scheduler_imp.h"
#include "level_zero/tools/test/unit_tests/sources/sysman/windows/mock_sysman_fixture.h"
extern bool sysmanUltsEnable;
@@ -16,7 +18,6 @@ namespace ult {
class ZesSchedulerFixture : public SysmanDeviceFixture {
protected:
std::unique_ptr<OsSchedulerMock> pOsSchedulerMock;
FirmwareUtil *pFwUtilInterfaceOld = nullptr;
void SetUp() override {
@@ -39,38 +40,64 @@ TEST_F(ZesSchedulerFixture, GivenComponentCountZeroWhenQueryingSchedulerHandlesT
EXPECT_EQ(count, 0u);
}
TEST_F(ZesSchedulerFixture, GivenSetExclusiveModeNotFailWhenTryingToSetComputeUnitDebugModeThenErrorIsReturned) {
TEST_F(ZesSchedulerFixture, GivenValidDeviceHandleWhenGettingCurrentModeThenErrorIsReturned) {
std::vector<std::string> listOfEngines = {"rcs0"};
auto pSchedulerImp = std::make_unique<SchedulerImp>(pOsSysman, ZES_ENGINE_TYPE_FLAG_RENDER, listOfEngines, device->toHandle());
auto pOsSchedulerBackup = pSchedulerImp->pOsScheduler;
auto pOsSchedulerMock = new OsSchedulerMock();
pSchedulerImp->pOsScheduler = pOsSchedulerMock;
ze_bool_t pNeedReload = false;
EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, pSchedulerImp->setComputeUnitDebugMode(&pNeedReload));
pSchedulerImp->pOsScheduler = pOsSchedulerBackup;
delete pOsSchedulerMock;
zes_sched_mode_t mode;
EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, pSchedulerImp->getCurrentMode(&mode));
}
TEST_F(ZesSchedulerFixture, GivenSetExclusiveModeNotSuccessWhenTryingToSetComputeUnitDebugModeThenErrorIsReturned) {
TEST_F(ZesSchedulerFixture, GivenValidDeviceHandleWhenGettingTimeoutModePropertiesThenErrorIsReturned) {
std::vector<std::string> listOfEngines = {"rcs0"};
auto pSchedulerImp = std::make_unique<SchedulerImp>(pOsSysman, ZES_ENGINE_TYPE_FLAG_RENDER, listOfEngines, device->toHandle());
auto pOsSchedulerBackup = pSchedulerImp->pOsScheduler;
auto pOsSchedulerMock = new OsSchedulerMock();
pOsSchedulerMock->setPreemptTimeoutResult = ZE_RESULT_SUCCESS;
pOsSchedulerMock->setTimesliceDurationResult = ZE_RESULT_SUCCESS;
pOsSchedulerMock->setHeartbeatIntervalResult = ZE_RESULT_SUCCESS;
pSchedulerImp->pOsScheduler = pOsSchedulerMock;
ze_bool_t pNeedReload = false;
EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, pSchedulerImp->setComputeUnitDebugMode(&pNeedReload));
pSchedulerImp->pOsScheduler = pOsSchedulerBackup;
delete pOsSchedulerMock;
ze_bool_t getDefaults = 0;
zes_sched_timeout_properties_t config;
EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, pSchedulerImp->getTimeoutModeProperties(getDefaults, &config));
}
TEST_F(ZesSchedulerFixture, whenCallingOsSpecificSetComputeUnitDebugModeThenErrorIsReturned) {
TEST_F(ZesSchedulerFixture, GivenValidDeviceHandleWhenGettingTimesliceModePropertiesThenErrorIsReturned) {
std::vector<std::string> listOfEngines = {"rcs0"};
auto pSchedulerImp = std::make_unique<SchedulerImp>(pOsSysman, ZES_ENGINE_TYPE_FLAG_RENDER, listOfEngines, device->toHandle());
ze_bool_t pNeedReload = false;
EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, pSchedulerImp->pOsScheduler->setComputeUnitDebugMode(&pNeedReload));
ze_bool_t getDefaults = 0;
zes_sched_timeslice_properties_t config;
EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, pSchedulerImp->getTimesliceModeProperties(getDefaults, &config));
}
TEST_F(ZesSchedulerFixture, GivenValidDeviceHandleWhenSettingTimeoutModeThenErrorIsReturned) {
std::vector<std::string> listOfEngines = {"rcs0"};
auto pSchedulerImp = std::make_unique<SchedulerImp>(pOsSysman, ZES_ENGINE_TYPE_FLAG_RENDER, listOfEngines, device->toHandle());
zes_sched_timeout_properties_t properties;
ze_bool_t needReload;
EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, pSchedulerImp->setTimeoutMode(&properties, &needReload));
}
TEST_F(ZesSchedulerFixture, GivenValidDeviceHandleWhenSettingTimesliceModeThenErrorIsReturned) {
std::vector<std::string> listOfEngines = {"rcs0"};
auto pSchedulerImp = std::make_unique<SchedulerImp>(pOsSysman, ZES_ENGINE_TYPE_FLAG_RENDER, listOfEngines, device->toHandle());
zes_sched_timeslice_properties_t properties;
ze_bool_t needReload;
EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, pSchedulerImp->setTimesliceMode(&properties, &needReload));
}
TEST_F(ZesSchedulerFixture, GivenValidDeviceHandleWhenSettingExclusiveModeThenErrorIsReturned) {
std::vector<std::string> listOfEngines = {"rcs0"};
auto pSchedulerImp = std::make_unique<SchedulerImp>(pOsSysman, ZES_ENGINE_TYPE_FLAG_RENDER, listOfEngines, device->toHandle());
ze_bool_t needReload;
EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, pSchedulerImp->setExclusiveMode(&needReload));
}
TEST_F(ZesSchedulerFixture, GivenValidDeviceHandleWhenSettingDebugModeThenErrorIsReturned) {
std::vector<std::string> listOfEngines = {"rcs0"};
auto pSchedulerImp = std::make_unique<SchedulerImp>(pOsSysman, ZES_ENGINE_TYPE_FLAG_RENDER, listOfEngines, device->toHandle());
ze_bool_t needReload;
EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, pSchedulerImp->setComputeUnitDebugMode(&needReload));
}
TEST_F(ZesSchedulerFixture, GivenValidDeviceHandleWhenGettingSchedulerPropertiesThenSuccessIsReturned) {
std::vector<std::string> listOfEngines = {"rcs0"};
auto pSchedulerImp = std::make_unique<SchedulerImp>(pOsSysman, ZES_ENGINE_TYPE_FLAG_RENDER, listOfEngines, device->toHandle());
zes_sched_properties_t properties;
EXPECT_EQ(ZE_RESULT_SUCCESS, pSchedulerImp->schedulerGetProperties(&properties));
}
} // namespace ult