|
13 | 13 | #include "DSP/QnnDspCommon.h" |
14 | 14 | #include "HTP/QnnHtpCommon.h" |
15 | 15 | #include "HTP/QnnHtpContext.h" |
16 | | -#include "HTP/QnnHtpPerfInfrastructure.h" |
17 | 16 | #include "HTP/QnnHtpSystemContext.h" |
18 | 17 | #include "IR/QnnIrCommon.h" |
19 | 18 | #include "IR/QnnIrGraph.h" |
@@ -1354,192 +1353,50 @@ Status QnnBackendManager::CreateHtpPowerCfgId(uint32_t device_id, uint32_t core_ |
1354 | 1353 | return Status::OK(); |
1355 | 1354 | } |
1356 | 1355 |
|
1357 | | -Status QnnBackendManager::SetHtpPowerConfig(uint32_t htp_power_config_client_id, |
1358 | | - HtpPerformanceMode htp_performance_mode) { |
| 1356 | +Status QnnBackendManager::SetRpcPowerConfigs(uint32_t htp_power_config_client_id, |
| 1357 | + uint32_t rpc_polling_time, |
| 1358 | + uint32_t rpc_control_latency) { |
1359 | 1359 | // This function is called in QNN EP's OnRunStart() even if QNN backend setup failed and the model is assigned |
1360 | 1360 | // to a different EP. Therefore, we have to check that backend setup actually completed before trying to |
1361 | 1361 | // set an HTP power config ID. Otherwise, this causes a segfault because the QNN backend lib is unloaded. |
1362 | 1362 | ORT_RETURN_IF_NOT(backend_setup_completed_, "Cannot set HTP power config ID if backend setup is not complete."); |
1363 | | - QnnDevice_Infrastructure_t qnn_device_infra = nullptr; |
1364 | | - auto status = qnn_interface_.deviceGetInfrastructure(&qnn_device_infra); |
1365 | | - ORT_RETURN_IF(QNN_SUCCESS != status, "backendGetPerfInfrastructure failed."); |
1366 | | - |
1367 | | - auto* htp_infra = static_cast<QnnHtpDevice_Infrastructure_t*>(qnn_device_infra); |
1368 | | - ORT_RETURN_IF(QNN_HTP_DEVICE_INFRASTRUCTURE_TYPE_PERF != htp_infra->infraType, |
1369 | | - "HTP infra type = ", htp_infra->infraType, ", which is not perf infra type."); |
1370 | | - QnnHtpDevice_PerfInfrastructure_t& htp_perf_infra = htp_infra->perfInfra; |
1371 | 1363 |
|
1372 | | - constexpr const int kNumConfigs = 1; |
1373 | | - std::vector<QnnHtpPerfInfrastructure_PowerConfig_t> power_configs( |
1374 | | - kNumConfigs); |
1375 | | - QnnHtpPerfInfrastructure_PowerConfig_t& dcvs_config = power_configs[0]; |
1376 | | - dcvs_config.option = QNN_HTP_PERF_INFRASTRUCTURE_POWER_CONFIGOPTION_DCVS_V3; |
1377 | | - QnnHtpPerfInfrastructure_DcvsV3_t& dcvs_v3 = dcvs_config.dcvsV3Config; |
1378 | | - dcvs_v3.contextId = htp_power_config_client_id; |
1379 | | - dcvs_v3.setSleepDisable = 0; |
1380 | | - dcvs_v3.sleepDisable = 0; |
1381 | | - dcvs_v3.setDcvsEnable = 1; |
1382 | | - dcvs_v3.powerMode = QNN_HTP_PERF_INFRASTRUCTURE_POWERMODE_PERFORMANCE_MODE; |
1383 | | - // choose performance mode |
1384 | | - switch (htp_performance_mode) { |
1385 | | - case HtpPerformanceMode::kHtpBurst: |
1386 | | - dcvs_v3.setSleepLatency = 1; // true |
1387 | | - dcvs_v3.sleepLatency = kSleepMinLatency; |
1388 | | - dcvs_v3.dcvsEnable = kDcvsDisable; |
1389 | | - dcvs_v3.setBusParams = 1; |
1390 | | - dcvs_v3.busVoltageCornerMin = DCVS_VOLTAGE_VCORNER_MAX_VOLTAGE_CORNER; |
1391 | | - dcvs_v3.busVoltageCornerTarget = DCVS_VOLTAGE_VCORNER_MAX_VOLTAGE_CORNER; |
1392 | | - dcvs_v3.busVoltageCornerMax = DCVS_VOLTAGE_VCORNER_MAX_VOLTAGE_CORNER; |
1393 | | - dcvs_v3.setCoreParams = 1; |
1394 | | - dcvs_v3.coreVoltageCornerMin = DCVS_VOLTAGE_VCORNER_MAX_VOLTAGE_CORNER; |
1395 | | - dcvs_v3.coreVoltageCornerTarget = DCVS_VOLTAGE_VCORNER_MAX_VOLTAGE_CORNER; |
1396 | | - dcvs_v3.coreVoltageCornerMax = DCVS_VOLTAGE_VCORNER_MAX_VOLTAGE_CORNER; |
1397 | | - break; |
1398 | | - case HtpPerformanceMode::kHtpSustainedHighPerformance: |
1399 | | - case HtpPerformanceMode::kHtpHighPerformance: |
1400 | | - dcvs_v3.setSleepLatency = 1; // true |
1401 | | - dcvs_v3.sleepLatency = kSleepLowLatency; |
1402 | | - dcvs_v3.dcvsEnable = kDcvsDisable; |
1403 | | - dcvs_v3.setBusParams = 1; |
1404 | | - dcvs_v3.busVoltageCornerMin = DCVS_VOLTAGE_VCORNER_TURBO; |
1405 | | - dcvs_v3.busVoltageCornerTarget = DCVS_VOLTAGE_VCORNER_TURBO; |
1406 | | - dcvs_v3.busVoltageCornerMax = DCVS_VOLTAGE_VCORNER_TURBO; |
1407 | | - dcvs_v3.setCoreParams = 1; |
1408 | | - dcvs_v3.coreVoltageCornerMin = DCVS_VOLTAGE_VCORNER_TURBO; |
1409 | | - dcvs_v3.coreVoltageCornerTarget = DCVS_VOLTAGE_VCORNER_TURBO; |
1410 | | - dcvs_v3.coreVoltageCornerMax = DCVS_VOLTAGE_VCORNER_TURBO; |
1411 | | - break; |
1412 | | - case HtpPerformanceMode::kHtpBalanced: |
1413 | | - dcvs_v3.setSleepLatency = 1; // true |
1414 | | - dcvs_v3.sleepLatency = kSleepMediumLatency; |
1415 | | - dcvs_v3.dcvsEnable = kDcvsEnable; |
1416 | | - dcvs_v3.setBusParams = 1; |
1417 | | - dcvs_v3.busVoltageCornerMin = DCVS_VOLTAGE_VCORNER_NOM_PLUS; |
1418 | | - dcvs_v3.busVoltageCornerTarget = DCVS_VOLTAGE_VCORNER_NOM_PLUS; |
1419 | | - dcvs_v3.busVoltageCornerMax = DCVS_VOLTAGE_VCORNER_NOM_PLUS; |
1420 | | - dcvs_v3.setCoreParams = 1; |
1421 | | - dcvs_v3.coreVoltageCornerMin = DCVS_VOLTAGE_VCORNER_NOM_PLUS; |
1422 | | - dcvs_v3.coreVoltageCornerTarget = DCVS_VOLTAGE_VCORNER_NOM_PLUS; |
1423 | | - dcvs_v3.coreVoltageCornerMax = DCVS_VOLTAGE_VCORNER_NOM_PLUS; |
1424 | | - break; |
1425 | | - case HtpPerformanceMode::kHtpLowBalanced: |
1426 | | - dcvs_v3.setSleepLatency = 1; // true |
1427 | | - dcvs_v3.sleepLatency = kSleepMediumLatency; |
1428 | | - dcvs_v3.dcvsEnable = kDcvsEnable; |
1429 | | - dcvs_v3.setBusParams = 1; |
1430 | | - dcvs_v3.busVoltageCornerMin = DCVS_VOLTAGE_VCORNER_NOM; |
1431 | | - dcvs_v3.busVoltageCornerTarget = DCVS_VOLTAGE_VCORNER_NOM; |
1432 | | - dcvs_v3.busVoltageCornerMax = DCVS_VOLTAGE_VCORNER_NOM; |
1433 | | - dcvs_v3.setCoreParams = 1; |
1434 | | - dcvs_v3.coreVoltageCornerMin = DCVS_VOLTAGE_VCORNER_NOM; |
1435 | | - dcvs_v3.coreVoltageCornerTarget = DCVS_VOLTAGE_VCORNER_NOM; |
1436 | | - dcvs_v3.coreVoltageCornerMax = DCVS_VOLTAGE_VCORNER_NOM; |
1437 | | - break; |
1438 | | - case HtpPerformanceMode::kHtpHighPowerSaver: |
1439 | | - dcvs_v3.setSleepLatency = 1; // true |
1440 | | - dcvs_v3.sleepLatency = kSleepMediumLatency; |
1441 | | - dcvs_v3.dcvsEnable = kDcvsEnable; |
1442 | | - dcvs_v3.setBusParams = 1; |
1443 | | - dcvs_v3.busVoltageCornerMin = DCVS_VOLTAGE_VCORNER_SVS_PLUS; |
1444 | | - dcvs_v3.busVoltageCornerTarget = DCVS_VOLTAGE_VCORNER_SVS_PLUS; |
1445 | | - dcvs_v3.busVoltageCornerMax = DCVS_VOLTAGE_VCORNER_SVS_PLUS; |
1446 | | - dcvs_v3.setCoreParams = 1; |
1447 | | - dcvs_v3.coreVoltageCornerMin = DCVS_VOLTAGE_VCORNER_SVS_PLUS; |
1448 | | - dcvs_v3.coreVoltageCornerTarget = DCVS_VOLTAGE_VCORNER_SVS_PLUS; |
1449 | | - dcvs_v3.coreVoltageCornerMax = DCVS_VOLTAGE_VCORNER_SVS_PLUS; |
1450 | | - break; |
1451 | | - case HtpPerformanceMode::kHtpPowerSaver: |
1452 | | - dcvs_v3.setSleepLatency = 1; // true |
1453 | | - dcvs_v3.sleepLatency = kSleepMediumLatency; |
1454 | | - dcvs_v3.dcvsEnable = kDcvsEnable; |
1455 | | - dcvs_v3.setBusParams = 1; |
1456 | | - dcvs_v3.busVoltageCornerMin = DCVS_VOLTAGE_VCORNER_SVS; |
1457 | | - dcvs_v3.busVoltageCornerTarget = DCVS_VOLTAGE_VCORNER_SVS; |
1458 | | - dcvs_v3.busVoltageCornerMax = DCVS_VOLTAGE_VCORNER_SVS; |
1459 | | - dcvs_v3.setCoreParams = 1; |
1460 | | - dcvs_v3.coreVoltageCornerMin = DCVS_VOLTAGE_VCORNER_SVS; |
1461 | | - dcvs_v3.coreVoltageCornerTarget = DCVS_VOLTAGE_VCORNER_SVS; |
1462 | | - dcvs_v3.coreVoltageCornerMax = DCVS_VOLTAGE_VCORNER_SVS; |
1463 | | - break; |
1464 | | - case HtpPerformanceMode::kHtpLowPowerSaver: |
1465 | | - dcvs_v3.setSleepLatency = 1; // true |
1466 | | - dcvs_v3.sleepLatency = kSleepMediumLatency; |
1467 | | - dcvs_v3.dcvsEnable = kDcvsEnable; |
1468 | | - dcvs_v3.setBusParams = 1; |
1469 | | - dcvs_v3.busVoltageCornerMin = DCVS_VOLTAGE_VCORNER_SVS2; |
1470 | | - dcvs_v3.busVoltageCornerTarget = DCVS_VOLTAGE_VCORNER_SVS2; |
1471 | | - dcvs_v3.busVoltageCornerMax = DCVS_VOLTAGE_VCORNER_SVS2; |
1472 | | - dcvs_v3.setCoreParams = 1; |
1473 | | - dcvs_v3.coreVoltageCornerMin = DCVS_VOLTAGE_VCORNER_SVS2; |
1474 | | - dcvs_v3.coreVoltageCornerTarget = DCVS_VOLTAGE_VCORNER_SVS2; |
1475 | | - dcvs_v3.coreVoltageCornerMax = DCVS_VOLTAGE_VCORNER_SVS2; |
1476 | | - break; |
1477 | | - case HtpPerformanceMode::kHtpExtremePowerSaver: |
1478 | | - dcvs_v3.powerMode = QNN_HTP_PERF_INFRASTRUCTURE_POWERMODE_POWER_SAVER_MODE; |
1479 | | - dcvs_v3.setSleepLatency = 1; // true |
1480 | | - dcvs_v3.sleepLatency = kSleepMediumLatency; |
1481 | | - dcvs_v3.dcvsEnable = kDcvsEnable; |
1482 | | - dcvs_v3.setBusParams = 1; |
1483 | | - dcvs_v3.busVoltageCornerMin = DCVS_VOLTAGE_CORNER_DISABLE; |
1484 | | - dcvs_v3.busVoltageCornerTarget = DCVS_VOLTAGE_CORNER_DISABLE; |
1485 | | - dcvs_v3.busVoltageCornerMax = DCVS_VOLTAGE_CORNER_DISABLE; |
1486 | | - dcvs_v3.setCoreParams = 1; |
1487 | | - dcvs_v3.coreVoltageCornerMin = DCVS_VOLTAGE_CORNER_DISABLE; |
1488 | | - dcvs_v3.coreVoltageCornerTarget = DCVS_VOLTAGE_CORNER_DISABLE; |
1489 | | - dcvs_v3.coreVoltageCornerMax = DCVS_VOLTAGE_CORNER_DISABLE; |
1490 | | - break; |
1491 | | - default: |
1492 | | - ORT_THROW("Invalid performance profile %d", static_cast<int>(htp_performance_mode)); |
1493 | | - break; |
1494 | | - } |
1495 | | - std::vector<const QnnHtpPerfInfrastructure_PowerConfig_t*> perf_power_configs_ptr = ObtainNullTermPtrVector(power_configs); |
1496 | | - status = htp_perf_infra.setPowerConfig(htp_power_config_client_id, perf_power_configs_ptr.data()); |
1497 | | - ORT_RETURN_IF(QNN_SUCCESS != status, "setPowerConfig failed for HTP performance mode."); |
| 1364 | + std::lock_guard<std::mutex> lock(htp_power_config_mutex_); |
| 1365 | + ORT_RETURN_IF_ERROR(htp_power_config_manager_.AddRpcPollingTime(rpc_polling_time)); |
| 1366 | + ORT_RETURN_IF_ERROR(htp_power_config_manager_.AddRpcControlLatency(rpc_control_latency)); |
| 1367 | + ORT_RETURN_IF_ERROR(htp_power_config_manager_.SetPowerConfig(htp_power_config_client_id, GetQnnInterface())); |
1498 | 1368 |
|
1499 | 1369 | return Status::OK(); |
1500 | 1370 | } |
1501 | 1371 |
|
1502 | | -Status QnnBackendManager::SetRpcPowerConfigs(uint32_t htp_power_config_client_id, |
1503 | | - uint32_t rpc_control_latency, |
1504 | | - uint32_t rpc_polling_time) { |
| 1372 | +Status QnnBackendManager::SetHtpPerformanceMode(uint32_t htp_power_config_client_id, |
| 1373 | + HtpPerformanceMode htp_performance_mode) { |
1505 | 1374 | // This function is called in QNN EP's OnRunStart() even if QNN backend setup failed and the model is assigned |
1506 | 1375 | // to a different EP. Therefore, we have to check that backend setup actually completed before trying to |
1507 | | - // set RPC control latency. Otherwise, this causes a segfault because the QNN backend library is unloaded. |
1508 | | - ORT_RETURN_IF_NOT(backend_setup_completed_, "Cannot set HTP RPC control latency if backend setup is not complete."); |
1509 | | - |
1510 | | - constexpr int kNumRpcPollingPowerConfigs = 2; |
1511 | | - std::vector<QnnHtpPerfInfrastructure_PowerConfig_t> rpc_power_configs; |
1512 | | - rpc_power_configs.reserve(kNumRpcPollingPowerConfigs); |
| 1376 | + // set an HTP power config ID. Otherwise, this causes a segfault because the QNN backend lib is unloaded. |
| 1377 | + ORT_RETURN_IF_NOT(backend_setup_completed_, "Cannot set HTP power config ID if backend setup is not complete."); |
1513 | 1378 |
|
1514 | | - // Set rpc control latency here |
1515 | | - if (rpc_control_latency != 0) { |
1516 | | - auto& rpc_control_latency_cfg = rpc_power_configs.emplace_back(); |
1517 | | - rpc_control_latency_cfg.option = QNN_HTP_PERF_INFRASTRUCTURE_POWER_CONFIGOPTION_RPC_CONTROL_LATENCY; |
1518 | | - rpc_control_latency_cfg.rpcControlLatencyConfig = rpc_control_latency; |
1519 | | - } |
| 1379 | + std::lock_guard<std::mutex> lock(htp_power_config_mutex_); |
| 1380 | + ORT_RETURN_IF_ERROR(htp_power_config_manager_.AddHtpPerformanceMode(htp_performance_mode, htp_power_config_client_id)); |
| 1381 | + ORT_RETURN_IF_ERROR(htp_power_config_manager_.SetPowerConfig(htp_power_config_client_id, GetQnnInterface())); |
1520 | 1382 |
|
1521 | | - // Note: v68 does not support rpc polling mode |
1522 | | - if (rpc_polling_time != 0) { |
1523 | | - auto& rpc_polling_time_cfg = rpc_power_configs.emplace_back(); |
1524 | | - rpc_polling_time_cfg.option = QNN_HTP_PERF_INFRASTRUCTURE_POWER_CONFIGOPTION_RPC_POLLING_TIME; |
1525 | | - rpc_polling_time_cfg.rpcPollingTimeConfig = rpc_polling_time; |
1526 | | - } |
1527 | | - |
1528 | | - if (rpc_power_configs.size() > 0) { |
1529 | | - QnnDevice_Infrastructure_t qnn_device_infra = nullptr; |
1530 | | - auto status = qnn_interface_.deviceGetInfrastructure(&qnn_device_infra); |
1531 | | - ORT_RETURN_IF(QNN_SUCCESS != status, "backendGetPerfInfrastructure failed."); |
| 1383 | + return Status::OK(); |
| 1384 | +} |
1532 | 1385 |
|
1533 | | - auto* htp_infra = static_cast<QnnHtpDevice_Infrastructure_t*>(qnn_device_infra); |
1534 | | - ORT_RETURN_IF(QNN_HTP_DEVICE_INFRASTRUCTURE_TYPE_PERF != htp_infra->infraType, |
1535 | | - "HTP infra type = ", htp_infra->infraType, ", which is not perf infra type."); |
1536 | | - QnnHtpDevice_PerfInfrastructure_t& htp_perf_infra = htp_infra->perfInfra; |
| 1386 | +Status QnnBackendManager::SetHtpPowerConfigs(uint32_t htp_power_config_client_id, |
| 1387 | + HtpPerformanceMode htp_performance_mode, |
| 1388 | + uint32_t rpc_polling_time, |
| 1389 | + uint32_t rpc_control_latency) { |
| 1390 | + // This function is called in QNN EP's OnRunStart() even if QNN backend setup failed and the model is assigned |
| 1391 | + // to a different EP. Therefore, we have to check that backend setup actually completed before trying to |
| 1392 | + // set an HTP power config ID. Otherwise, this causes a segfault because the QNN backend lib is unloaded. |
| 1393 | + ORT_RETURN_IF_NOT(backend_setup_completed_, "Cannot set HTP power config ID if backend setup is not complete."); |
1537 | 1394 |
|
1538 | | - std::vector<const QnnHtpPerfInfrastructure_PowerConfig_t*> perf_power_configs_ptr = |
1539 | | - ObtainNullTermPtrVector(rpc_power_configs); |
1540 | | - status = htp_perf_infra.setPowerConfig(htp_power_config_client_id, perf_power_configs_ptr.data()); |
1541 | | - ORT_RETURN_IF(QNN_SUCCESS != status, "setPowerConfig failed for RPC control latency."); |
1542 | | - } |
| 1395 | + std::lock_guard<std::mutex> lock(htp_power_config_mutex_); |
| 1396 | + ORT_RETURN_IF_ERROR(htp_power_config_manager_.AddRpcPollingTime(rpc_polling_time)); |
| 1397 | + ORT_RETURN_IF_ERROR(htp_power_config_manager_.AddRpcControlLatency(rpc_control_latency)); |
| 1398 | + ORT_RETURN_IF_ERROR(htp_power_config_manager_.AddHtpPerformanceMode(htp_performance_mode, htp_power_config_client_id)); |
| 1399 | + ORT_RETURN_IF_ERROR(htp_power_config_manager_.SetPowerConfig(htp_power_config_client_id, GetQnnInterface())); |
1543 | 1400 |
|
1544 | 1401 | return Status::OK(); |
1545 | 1402 | } |
|
0 commit comments