SmartShiftEco
Navigation: Programming with ADLX → ADLX Samples → C++ Samples → Power Tuning
Demonstrates how to control AMD SmartShift Eco when programming with ADLX.
Command Prompts
| Command Prompt | Description |
|---|---|
| 1 | Display AMD SmartShift Eco support. |
| 2 | Display AMD SmartShift Eco enabled state. |
| 3 | Set AMD SmartShift Eco enabled state. |
| 4 | Display AMD SmartShift Eco inactive state. |
| 5 | Display AMD GPU connect support. |
| 6 | Display GPU power state. |
| 7 | Power on a GPU. |
| 8 | Power off a GPU. |
| 9 | Abort power off a GPU. |
| A | Display get application list support. |
| B | Get application list. |
| M/m | Show this menu. |
| Q/q | Quit. |
Sample Path
/Samples/CPP/PowerTuning/SmartShiftEco
C++
Code
C++
//// Copyright Advanced Micro Devices, Inc. All rights reserved.////-------------------------------------------------------------------------------------------------
/// \file mainSmartShiftEco.cpp/// \brief Demonstrates how to control AMD SmartShift Eco when programming with ADLX.
#include "SDK/ADLXHelper/Windows/Cpp/ADLXHelper.h"#include "SDK/Include/IPowerTuning1.h"#include "SDK/Include/IApplications.h"#include "SDK/Include/ISystem2.h"#include "SDK/Include/IApplications.h"#include <iostream>
// Use ADLX namespaceusing namespace adlx;
// ADLXHelper instance// No outstanding interfaces from ADLX must exist when ADLX is destroyed.// Use global variables to ensure validity of the interface.static ADLXHelper g_ADLXHelp;
// Main menuvoid MainMenu();
// Menu action controlvoid MenuControl(IADLXPowerTuningServices1Ptr powerTuningServices, IADLXSmartShiftEcoPtr smartShiftEco);
// Wait for exit with error messageint WaitAndExit(const char* msg, const int retCode);
// Display AMD SmartShift Eco supportvoid ShowSmartShiftEcoSupport(IADLXSmartShiftEcoPtr smartShiftEco);
// Display AMD SmartShift Eco enabled statevoid ShowSmartShiftEcoEnabledState(IADLXSmartShiftEcoPtr smartShiftEco);
// Set AMD SmartShift Eco enabled statevoid SetSmartShiftEcoEnabledState(IADLXSmartShiftEcoPtr smartShiftEco);
// Display AMD SmartShift Eco active statevoid ShowSmartShiftEcoInactiveState(IADLXSmartShiftEcoPtr smartShiftEco);
// Display AMD GPU connect supportvoid ShowGPUConnectSupport(IADLXPowerTuningServices1Ptr powerTuningService);
// Use functions of GPU connectvoid UseGPUConnectFunctions(IADLXPowerTuningServices1Ptr powerTuningService, char num);
// Display GPU power statevoid ShowGPUPowerState(IADLXGPU2Ptr gpu);
// Power on a GPUvoid PowerOnGPU(IADLXGPU2Ptr gpu);
// Power off a GPUvoid PowerOffGPU(IADLXGPU2Ptr gpu);
// Abort power off a GPUvoid AbortPowerOffGPU(IADLXGPU2Ptr gpu);
// Set power control to defaultvoid SetPowerControlToDefault(IADLXSmartShiftEcoPtr smartShiftEco);
// Display get application list supportvoid ShowGetApplicationListSupport(IADLXGPU2Ptr gpu);
// Get application listvoid GetApplicationList(IADLXGPU2Ptr gpu);
class GPUAppsListChangedCallBack : public IADLXGPUAppsListEventListener{public: adlx_bool ADLX_STD_CALL OnGPUAppsListChanged(IADLXGPU2* pGPU, IADLXApplicationList* pApplications) { // Using pGPU ... // Using pApplications ...
return true; }};
HANDLE smartShiftEcoChangedBlockEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
class SmartShiftEcoChangedCallBack : public IADLXPowerTuningChangedListener{public: adlx_bool ADLX_STD_CALL OnPowerTuningChanged(IADLXPowerTuningChangedEvent* pPowerTuningChangedEvent) { IADLXPowerTuningChangedEvent1Ptr pPowerTuningChangedEvent1 = nullptr; pPowerTuningChangedEvent->QueryInterface(IADLXPowerTuningChangedEvent1::IID(), reinterpret_cast<void**>(&pPowerTuningChangedEvent1)); if (pPowerTuningChangedEvent1->IsSmartShiftEcoChanged()) { std::cout << "\tSmartShiftEcoChanged" << std::endl; } SetEvent(smartShiftEcoChangedBlockEvent); return true; }};
int main(){ ADLX_RESULT res = ADLX_FAIL;
// Initialize ADLX res = g_ADLXHelp.Initialize(); if (ADLX_SUCCEEDED(res)) { // Get IADLXSystem1 interface via IADLXSystem::QueryInterface IADLXSystem2Ptr system2; res = g_ADLXHelp.GetSystemServices()->QueryInterface(IADLXSystem2::IID(), reinterpret_cast<void**>(&system2)); if (ADLX_SUCCEEDED(res)) { // Add GPU applications list event listener IADLXGPUAppsListChangedHandlingPtr appsListHandle; res = system2->GetGPUAppsListChangedHandling(&appsListHandle); IADLXGPUAppsListEventListener* gpuAppsListChangedCallBack = new GPUAppsListChangedCallBack{}; auto addListenerResult1 = ADLX_FAIL; if (ADLX_SUCCEEDED(res)) addListenerResult1 = appsListHandle->AddGPUAppsListEventListener(gpuAppsListChangedCallBack); // Get power tuning service IADLXPowerTuningServicesPtr powerTuningService; res = system2->GetPowerTuningServices(&powerTuningService); if (ADLX_SUCCEEDED(res)) { // Get power tuning service 1 IADLXPowerTuningServices1Ptr powerTuningService1(powerTuningService); if (NULL != powerTuningService1) { // Add power tuning changed listener IADLXPowerTuningChangedHandlingPtr powerTuningChangedHandle; res = powerTuningService1->GetPowerTuningChangedHandling(&powerTuningChangedHandle); IADLXPowerTuningChangedListener* smartShiftEcoChangedCallBack = new SmartShiftEcoChangedCallBack{}; auto addListenerResult2 = ADLX_FAIL; if (ADLX_SUCCEEDED(res)) addListenerResult2 = powerTuningChangedHandle->AddPowerTuningEventListener(smartShiftEcoChangedCallBack); // Get AMD SmartShift Eco interface IADLXSmartShiftEcoPtr smartShiftEco; res = powerTuningService1->GetSmartShiftEco(&smartShiftEco); if (ADLX_SUCCEEDED(res)) { // Display main menu options MainMenu(); // Get and execute the choice MenuControl(powerTuningService1, smartShiftEco); } else std::cout << "Failed to get AMD SmartShift Eco interface" << std::endl; // Remove power tuning changed listener if (ADLX_SUCCEEDED(addListenerResult2)) powerTuningChangedHandle->RemovePowerTuningEventListener(smartShiftEcoChangedCallBack); delete smartShiftEcoChangedCallBack; smartShiftEcoChangedCallBack = nullptr; } else std::cout << "Failed to get power tuning service 1" << std::endl; } else std::cout << "Failed to get power tuning service" << std::endl; // Remove GPU applications list event listener if (ADLX_SUCCEEDED(addListenerResult1)) appsListHandle->RemoveGPUAppsListEventListener(gpuAppsListChangedCallBack); delete gpuAppsListChangedCallBack; gpuAppsListChangedCallBack = nullptr; } else std::cout << "Failed to get IADLXSystem2" << std::endl; } else return WaitAndExit("\tg_ADLXHelp initialize failed", 0);
// Destroy ADLX res = g_ADLXHelp.Terminate(); std::cout << "Destroy ADLX res: " << res << std::endl;
// Pause to see the print out system("pause");
return 0;}
void MainMenu(){ std::cout << "\tChoose from the following options:" << std::endl; std::cout << "\t->Press 1 to display AMD SmartShift Eco support" << std::endl; std::cout << "\t->Press 2 to display AMD SmartShift Eco enabled state" << std::endl; std::cout << "\t->Press 3 to set AMD SmartShift Eco enabled state" << std::endl; std::cout << "\t->Press 4 to display AMD SmartShift Eco inactive state" << std::endl; std::cout << "\t->Press 5 to display AMD GPU connect support" << std::endl; std::cout << "\t->Press 6 to display GPU power state" << std::endl; std::cout << "\t->Press 7 to power on a GPU" << std::endl; std::cout << "\t->Press 8 to power off a GPU" << std::endl; std::cout << "\t->Press 9 to abort power off a GPU" << std::endl; std::cout << "\t->Press A to set power control to default" << std::endl; std::cout << "\t->Press B to display get application list support" << std::endl; std::cout << "\t->Press C to get application list" << std::endl; std::cout << "\t->Press Q/q to terminate the application" << std::endl; std::cout << "\t->Press M/m to display main menu options" << std::endl;}
void MenuControl(IADLXPowerTuningServices1Ptr powerTuningServices, IADLXSmartShiftEcoPtr smartShiftEco){ int num = 0; while ((num = getchar()) != 'q' && num != 'Q') { switch (num) { case '1': // Display AMD SmartShift Eco support ShowSmartShiftEcoSupport(smartShiftEco); break;
case '2': // Display AMD SmartShift Eco enabled state ShowSmartShiftEcoEnabledState(smartShiftEco); break;
case '3': // Set AMD SmartShift Eco enabled state SetSmartShiftEcoEnabledState(smartShiftEco); break;
case '4': // Display AMD SmartShift Eco inactive state ShowSmartShiftEcoInactiveState(smartShiftEco); break;
case '5': // Display AMD GPU connect support ShowGPUConnectSupport(powerTuningServices); break;
case 'A': // Set power control to default SetPowerControlToDefault(smartShiftEco); break;
case '6': case '7': case '8': case '9': case 'B': case 'C': UseGPUConnectFunctions(powerTuningServices, num); break;
case 'm': // Display menu options case 'M': MainMenu(); break;
default: break; } }}
int WaitAndExit(const char* msg, const int retCode){ // Printout the message and pause to see it before returning the desired code if (nullptr != msg) std::cout << msg << std::endl;
system("pause"); return retCode;}
// Display AMD SmartShift Eco supportvoid ShowSmartShiftEcoSupport(IADLXSmartShiftEcoPtr smartShiftEco){ adlx_bool supported = false; ADLX_RESULT res = smartShiftEco->IsSupported(&supported); if (ADLX_SUCCEEDED(res)) std::cout << "\tIs AMD SmartShift Eco supported: " << supported << std::endl;}
// Display AMD SmartShift Eco enabled statevoid ShowSmartShiftEcoEnabledState(IADLXSmartShiftEcoPtr smartShiftEco){ adlx_bool supported = false; ADLX_RESULT res = smartShiftEco->IsSupported(&supported); if (ADLX_SUCCEEDED(res) && supported) { adlx_bool enabled = false; ADLX_RESULT res = smartShiftEco->IsEnabled(&enabled); if (ADLX_SUCCEEDED(res)) std::cout << "\tIs AMD SmartShift Eco enabled: " << enabled << std::endl; } else { std::cout << "\tReturn code is: " << res << "(0 means success)" << std::endl; }}
// Set AMD SmartShift Eco enabled statevoid SetSmartShiftEcoEnabledState(IADLXSmartShiftEcoPtr smartShiftEco){ adlx_bool supported = false; ADLX_RESULT res = smartShiftEco->IsSupported(&supported); if (ADLX_SUCCEEDED(res) && supported) { adlx_bool enabled = false; ADLX_RESULT res = smartShiftEco->IsEnabled(&enabled); if (ADLX_SUCCEEDED(res)) std::cout << "\tCurrent AMD SmartShift Eco enable state is: " << enabled << std::endl; res = smartShiftEco->SetEnabled(!enabled); if (ADLX_SUCCEEDED(res)) { WaitForSingleObject(smartShiftEcoChangedBlockEvent, 5000); ResetEvent(smartShiftEcoChangedBlockEvent); std::cout << "\tSet AMD SmartShift Eco enabled state to: " << !enabled << std::endl; } res = smartShiftEco->IsEnabled(&enabled); if (ADLX_SUCCEEDED(res)) std::cout << "\tAfter set, the AMD SmartShift Eco enable state is: " << enabled << std::endl; } else { std::cout << "\tReturn code is: " << res << "(0 means success)" << std::endl; }}
// Display AMD SmartShift Eco inactive statevoid ShowSmartShiftEcoInactiveState(IADLXSmartShiftEcoPtr smartShiftEco){ adlx_bool supported = false; ADLX_RESULT res = smartShiftEco->IsSupported(&supported); if (ADLX_SUCCEEDED(res) && supported) { adlx_bool enabled = false; ADLX_RESULT res = smartShiftEco->IsEnabled(&enabled); if (ADLX_SUCCEEDED(res) && enabled) { adlx_bool inactive = false; ADLX_RESULT res = smartShiftEco->IsInactive(&inactive); std::cout << "\tIs AMD SmartShift Eco inactive: " << inactive << std::endl; if (inactive) { ADLX_SMARTSHIFT_ECO_INACTIVE_REASON reason = INACTIVE_REASON_UNKNOWN; ADLX_RESULT res = smartShiftEco->GetInactiveReason(&reason); if (ADLX_SUCCEEDED(res)) { std::cout << "\tAMD SmartShift Eco inactive reason: " << reason << std::endl; } } } } else { std::cout << "\tReturn code is: " << res << "(0 means success)" << std::endl; }}
// Display AMD GPU connect supportvoid ShowGPUConnectSupport(IADLXPowerTuningServices1Ptr powerTuningService){ adlx_bool supported = false; ADLX_RESULT res = powerTuningService->IsGPUConnectSupported(&supported); if (ADLX_SUCCEEDED(res)) std::cout << "\tIs GPU connect supported: " << supported << std::endl;}
// Use functions of GPU connectvoid UseGPUConnectFunctions(IADLXPowerTuningServices1Ptr powerTuningService, char num){ adlx_bool supported = false; ADLX_RESULT res = powerTuningService->IsGPUConnectSupported(&supported); if (ADLX_SUCCEEDED(res) && supported) { IADLXGPU2ListPtr gpuList = nullptr; res = powerTuningService->GetGPUConnectGPUs(&gpuList); if (ADLX_SUCCEEDED(res) && !gpuList->Empty()) { // Use the first GPU IADLXGPU2Ptr gpu = nullptr; res = gpuList->At(gpuList->Begin(), &gpu); if (ADLX_SUCCEEDED(res)) { switch (num) { case '6': // Display GPU power state ShowGPUPowerState(gpu); break;
case '7': // Power on a GPU PowerOnGPU(gpu); break;
case '8': // Power off a GPU PowerOffGPU(gpu); break;
case '9': // Abort power off a GPU AbortPowerOffGPU(gpu); break;
case 'B': // Display get application list support ShowGetApplicationListSupport(gpu); break;
case 'C': // Get application list GetApplicationList(gpu); break;
default: break; }
} } else std::cout << "\tNot found GPU support GPU connect" << std::endl; } else std::cout << "\tGPU connect is not supported" << std::endl;}
// Display GPU power statevoid ShowGPUPowerState(IADLXGPU2Ptr gpu){ adlx_bool state = false; ADLX_RESULT res = gpu->IsPowerOff(&state); if (ADLX_SUCCEEDED(res)) std::cout << "\tIs GPU power off: " << state << std::endl;}
// Power on a GPUvoid PowerOnGPU(IADLXGPU2Ptr gpu){ adlx_bool state = false; ADLX_RESULT res = gpu->IsPowerOff(&state); if (ADLX_SUCCEEDED(res)) std::cout << "\tCurrent the GPU power state is: " << (state ? "OFF" : "ON") << std::endl; res = gpu->PowerOn(); if (ADLX_SUCCEEDED(res)) std::cout << "\tPower on the GPU" << std::endl; res = gpu->IsPowerOff(&state); if (ADLX_SUCCEEDED(res)) std::cout << "\tAfter set, the GPU power state is: " << (state ? "OFF" : "ON") << std::endl;}
class GPUConnectChangedCallBack : public IADLXGPUConnectChangedListener{public: adlx_bool ADLX_STD_CALL OnGPUConnectChanged(IADLXGPUConnectChangedEvent* pGPUConnectChangedEvent) { if (pGPUConnectChangedEvent->IsGPUPowerChanged()) std::cout << "\tGPU power changed" << std::endl; if (pGPUConnectChangedEvent->IsGPUAppsListChanged()) { std::cout << "\tGPU applications list changed" << std::endl; IADLXGPU2Ptr gpu; ADLX_RESULT res = pGPUConnectChangedEvent->GetGPU(&gpu); if (ADLX_SUCCEEDED(res)) { IADLXApplicationListPtr appList; res = gpu->GetApplications(&appList); if (ADLX_SUCCEEDED(res)) { for (auto it = appList->Begin(); it != appList->End(); ++it) { IADLXApplicationPtr app; res = appList->At(it, &app); if (ADLX_SUCCEEDED(res)) { adlx_ulong pid = 0; res = app->ProcessID(&pid); if (ADLX_SUCCEEDED(res)) std::cout << "\tThe process ID of the process running on the GPU is: " << pid << std::endl;
const wchar_t* name = nullptr; res = app->Name(&name); if (ADLX_SUCCEEDED(res)) std::cout << "\tThe name of the process running on the GPU is: " << name << std::endl;
const wchar_t* fullPath = nullptr; res = app->FullPath(&fullPath); if (ADLX_SUCCEEDED(res)) std::cout << "\tThe full path of the process running on the GPU is: " << fullPath << std::endl;
ADLX_APP_GPU_DEPENDENCY type = ADLX_APP_GPU_DEPENDENCY::APP_GPU_UNKNOWN; res = app->GPUDependencyType(&type); if (ADLX_SUCCEEDED(res)) { if (type == ADLX_APP_GPU_DEPENDENCY::APP_GPU_BOUND) std::cout << "\tThe GPU dependency type of the process running on the GPU is: APP_GPU_BOUND" << std::endl; else if (type == ADLX_APP_GPU_DEPENDENCY::APP_GPU_NOT_BOUND) std::cout << "\tThe GPU dependency type of the process running on the GPU is: APP_GPU_NOT_BOUND" << std::endl; else std::cout << "\tThe GPU dependency type of the process running on the GPU is: APP_GPU_UNKNOWN" << std::endl; } } } } } } ADLX_RESULT res = ADLX_FAIL; if (pGPUConnectChangedEvent->IsGPUPowerChangeError(&res)) { if (res == ADLX_TIMEOUT_OPERATION) std::cout << "\tGPU power change error, timeout operation" << std::endl; else std::cout << "\tGPU power change error, result is: " << res << std::endl; }
return true; }};
static GPUConnectChangedCallBack callBack;
// Power off a GPUvoid PowerOffGPU(IADLXGPU2Ptr gpu){ adlx_bool state = false; ADLX_RESULT res = gpu->IsPowerOff(&state); if (ADLX_SUCCEEDED(res)) std::cout << "\tCurrent the GPU power state is: " << (state ? "OFF" : "ON") << std::endl;
res = gpu->StartPowerOff(&callBack, 10000); if (ADLX_SUCCEEDED(res)) std::cout << "\tPower off the GPU" << std::endl; else if (res == ADLX_GPU_IN_USE) { std::cout << "\tStart power off the GPU, but GPU is in use, wait for 10 seconds" << std::endl; std::cout << "\tPress 9 can abort power off GPU during this time" << std::endl; }}
// Abort power off a GPUvoid AbortPowerOffGPU(IADLXGPU2Ptr gpu){ ADLX_RESULT res = gpu->AbortPowerOff(); if (ADLX_SUCCEEDED(res)) std::cout << "\tAbort power off GPU successfully" << std::endl;}
// Set power control to defaultvoid SetPowerControlToDefault(IADLXSmartShiftEcoPtr smartShiftEco){ adlx_bool supported = false; ADLX_RESULT res = smartShiftEco->IsSupported(&supported); if (ADLX_SUCCEEDED(res) && supported) { // The default power control policy is to enable AMD SmartShift Eco res = smartShiftEco->SetEnabled(true); if (ADLX_SUCCEEDED(res)) std::cout << "\tSet Power control to default" << std::endl; } else { std::cout << "\tGPU connect is not supported" << std::endl; }}
// Display get application list supportvoid ShowGetApplicationListSupport(IADLXGPU2Ptr gpu){ adlx_bool supported = false; ADLX_RESULT res = gpu->IsSupportedApplicationList(&supported); if (ADLX_SUCCEEDED(res)) std::cout << "\tIs application list Supported: " << supported << std::endl;}
// Get application listvoid GetApplicationList(IADLXGPU2Ptr gpu){ adlx_bool supported = false; ADLX_RESULT res = gpu->IsSupportedApplicationList(&supported); if (ADLX_SUCCEEDED(res) && supported) { IADLXApplicationListPtr appList; res = gpu->GetApplications(&appList); if (ADLX_SUCCEEDED(res)) { for (auto it = appList->Begin(); it != appList->End(); ++it) { IADLXApplicationPtr app; res = appList->At(it, &app); if (ADLX_SUCCEEDED(res)) { adlx_ulong pid = 0; res = app->ProcessID(&pid); if (ADLX_SUCCEEDED(res)) std::cout << "\tThe process ID of the process running on the GPU is: " << pid << std::endl;
const wchar_t* name = nullptr; res = app->Name(&name); if (ADLX_SUCCEEDED(res)) std::wcout << "\tThe name of the process running on the GPU is: " << name << std::endl;
const wchar_t* fullPath = nullptr; res = app->FullPath(&fullPath); if (ADLX_SUCCEEDED(res)) std::wcout << "\tThe full path of the process running on the GPU is: " << fullPath << std::endl;
ADLX_APP_GPU_DEPENDENCY type = ADLX_APP_GPU_DEPENDENCY::APP_GPU_UNKNOWN; res = app->GPUDependencyType(&type); if (ADLX_SUCCEEDED(res)) { if (type == ADLX_APP_GPU_DEPENDENCY::APP_GPU_BOUND) std::cout << "\tThe GPU dependency type of the process running on the GPU is: APP_GPU_BOUND" << std::endl; else if (type == ADLX_APP_GPU_DEPENDENCY::APP_GPU_NOT_BOUND) std::cout << "\tThe GPU dependency type of the process running on the GPU is: APP_GPU_NOT_BOUND" << std::endl; else std::cout << "\tThe GPU dependency type of the process running on the GPU is: APP_GPU_UNKNOWN" << std::endl; } } } } }}See Also: ADLX Macro, ADLX Enums