Skip to content

Commit 4e68c93

Browse files
cderbclaudejdcampbe
authored
Frontend Heuristic Policy Enumeration API (RFC 0007 - Part 3/3) (ROCm#6757)
## Overview This PR completes the three-part implementation of RFC 0007 by adding **frontend C++ wrapper APIs** for heuristic policy enumeration. It provides a user-friendly interface for applications to discover and inspect loaded heuristic policies at runtime, enabling diagnostics, logging, and understanding of engine selection behavior. **PR Series:** - **PR1:** Plugin SDK Infrastructure (`users/cderb/rfc0007/pr1-plugin-sdk-infrastructure`) - **PR2:** Heuristic Framework + Default Plugins (`users/cderb/rfc0007/pr2-heuristic-framework-plugins`) - **PR3:** Frontend Wrapper API (`users/cderb/rfc0007/pr3-frontend-wrapper-clean`) <-- **This PR** --- ## What's New in PR3 ### 1. Frontend Policy Enumeration API **New Header:** `frontend/include/hipdnn_frontend/HeuristicPolicyInfo.hpp` Provides a clean C++ interface to query loaded heuristic policies: ```cpp #include <hipdnn_frontend/HeuristicPolicyInfo.hpp> auto [handle, err] = hipdnn_frontend::createHipdnnHandle(); // Query all loaded heuristic policies auto [policies, err2] = hipdnn_frontend::getLoadedHeuristicPolicyInfos(*handle); for (const auto& policy : policies) { std::cout << "Policy: " << policy.policyName << " (ID: " << policy.policyId << ")" << " Version: " << policy.pluginVersion << " API: " << policy.apiVersion << std::endl; } ``` **Output Example:** ``` Policy: SelectionHeuristic::Config (ID: -7234567890123456789) Version: 1.0.0 API: 0.0.1 Policy: SelectionHeuristic::StaticOrdering (ID: -1234567890123456789) Version: 1.0.0 API: 0.0.1 ``` ### 2. Backend C API Extensions **New Functions in `hipdnn_backend.h`:** ```c // Get count of loaded heuristic policies hipdnnStatus_t hipdnnGetHeuristicPolicyCount_ext( hipdnnHandle_t handle, size_t* numPolicies); // Query policy metadata by index (two-call pattern for strings) hipdnnStatus_t hipdnnGetHeuristicPolicyInfo_ext( hipdnnHandle_t handle, size_t index, int64_t* policyId, char* policyName, size_t* policyNameLen, char* pluginVersion, size_t* pluginVersionLen, char* apiVersion, size_t* apiVersionLen); ``` ### 3. DeviceProperties Helper Functions **New Files:** - `backend/src/heuristics/DeviceProperties.hpp` - `backend/src/heuristics/DeviceProperties.cpp` Provides utility functions for heuristic policy plugins: ```cpp // Query device properties from HIP hipdnn_flatbuffers_sdk::data_objects::DevicePropertiesT queryDeviceProperties(); // Serialize device properties to FlatBuffer std::vector<uint8_t> serializeDeviceProperties(const DevicePropertiesT& props); // Wrap serialized buffer in plugin data structure hipdnnPluginConstData_t wrapSerializedDeviceProperties(const std::vector<uint8_t>& serializedBuffer); ``` **Usage in Backend:** ```cpp // Query and serialize device properties auto devProps = queryDeviceProperties(); auto serialized = serializeDeviceProperties(devProps); auto wrapper = wrapSerializedDeviceProperties(serialized); // Pass to heuristic plugin hipdnnHeuristicHandleSetDeviceProperties(pluginHandle, &wrapper); ``` --- ## Files Changed ### New Files (5) 1. **Frontend API:** - `frontend/include/hipdnn_frontend/HeuristicPolicyInfo.hpp` - Policy enumeration API 2. **Backend Helpers:** - `backend/src/heuristics/DeviceProperties.hpp` - Device properties utilities (header) - `backend/src/heuristics/DeviceProperties.cpp` - Device properties utilities (impl) 3. **Tests:** - `frontend/tests/TestHeuristicPolicyEnumeration.cpp` - Frontend API tests (12 tests) 4. **Mock Backend:** - (Updates to existing mock for testing) ### Modified Files (4) 1. **Backend Wrappers:** - `frontend/include/hipdnn_frontend/detail/BackendWrapper.hpp` - Add policy query wrappers - `frontend/include/hipdnn_frontend/detail/HipdnnBackendInterface.hpp` - Add virtual methods - `frontend/include/hipdnn_frontend/detail/IncompatibleBackend.hpp` - Graceful degradation 2. **Test Configuration:** - `frontend/tests/CMakeLists.txt` - Register new test file 3. **Mock Backend:** - `frontend/tests/fake_backend/MockHipdnnBackend.hpp` - Implement mock policy queries **Total: 9 files changed (+583 lines, -83 lines)** --- ## Testing ### Frontend Tests (12 tests) **File:** `frontend/tests/TestHeuristicPolicyEnumeration.cpp` 12 tests covering basic enumeration, metadata validation, default policy presence, and integration scenarios. ### Integration with PR2 Tests PR3 builds on PR2's comprehensive backend tests (178+ tests): - [x] Policy loading and validation - [x] Outer loop orchestration - [x] Device properties serialization - [x] Default policies (Config, StaticOrdering) **Combined Test Coverage: 190+ tests** --- ## RFC 0007 Compliance ### Section 16: Frontend API Flow **RFC Requirements:** > "Frontend should expose an enumeration API similar to engine config enumeration: > > - `getLoadedHeuristicPolicyInfos(hipdnnHandle_t)` returns policy metadata > - Policy ID (int64_t) > - Policy name (UTF-8 string) > - Plugin version > - API version" **Implementation Status:** - [x] Frontend function `getLoadedHeuristicPolicyInfos()` implemented - [x] Backend C API `hipdnnGetHeuristicPolicyCount_ext()` implemented - [x] Backend C API `hipdnnGetHeuristicPolicyInfo_ext()` implemented - [x] `HeuristicPolicyInfo` struct with all required fields - [x] Two-call pattern for string sizing (matches engine config pattern) - [x] Error handling via frontend `Error` type - [x] Works before graph creation (as required) --- ## Design Decisions ### DeviceProperties Helper Functions While RFC 0007 specifies device properties serialization for plugins, PR3 adds reusable helper functions to avoid code duplication: ```cpp queryDeviceProperties() // Query from HIP serializeDeviceProperties() // Convert to FlatBuffer wrapSerializedDeviceProperties() // Wrap in C API struct ``` These provide a reference implementation for custom plugin developers and maintain FlatBuffer encapsulation without exposing POD structs across the ABI boundary. --- ## Integration with PR1 & PR2 ### From PR1 (Plugin SDK): - [x] Uses `HeuristicsPluginApi.h` C ABI definitions - [x] Relies on two-tier plugin architecture (handle + descriptor) ### From PR2 (Heuristic Framework): - [x] Queries `HeuristicPluginResourceManager::getHeuristicPolicyInfos()` - [x] Enumerates policies loaded via `HeuristicPluginManager` - [x] Accesses default policies (Config, StaticOrdering) ### New in PR3: - [x] Frontend C++ wrapper API - [x] Backend C API extensions (`hipdnnGetHeuristicPolicy*_ext`) - [x] DeviceProperties helper utilities - [x] Frontend integration tests --- ## Summary PR3 completes RFC 0007 by adding frontend policy enumeration and device properties helpers. **Combined with PR1 and PR2, RFC 0007 is now fully implemented.** --- --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> Co-authored-by: Jason Campbell <jascampb@amd.com> Co-authored-by: Claude Filter Strategist <claude@anthropic.com>
1 parent fb8d081 commit 4e68c93

20 files changed

Lines changed: 1325 additions & 74 deletions

projects/hipdnn/backend/src/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ add_library(
5555
logging/GraphLogger.cpp
5656
logging/Logging.cpp
5757
FlatbufferUtilities.cpp
58+
heuristics/DeviceProperties.cpp
5859
heuristics/BuiltInHeuristics.cpp
5960
heuristics/SelectionHeuristic.cpp
6061
heuristics/config/ConfigBuiltIn.cpp

projects/hipdnn/backend/src/descriptors/EngineHeuristicDescriptor.cpp

Lines changed: 6 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,11 @@
1414
#include "utilities/EngineOrdering.hpp"
1515

1616
// Heuristics framework
17+
#include "heuristics/DeviceProperties.hpp"
1718
#include "heuristics/SelectionHeuristic.hpp"
1819
#include "logging/Logging.hpp"
1920
#include "plugin/HeuristicPlugin.hpp"
2021
#include "plugin/HeuristicPluginResourceManager.hpp"
21-
#include <flatbuffers/flatbuffers.h>
22-
#include <hip/hip_runtime.h>
23-
#include <hipdnn_flatbuffers_sdk/data_objects/device_properties_generated.h>
2422

2523
#include <hipdnn_data_sdk/utilities/EngineNames.hpp>
2624
#include <hipdnn_data_sdk/utilities/PlatformUtils.hpp>
@@ -207,43 +205,11 @@ void EngineHeuristicDescriptor::finalize()
207205
return;
208206
}
209207

210-
// Query and serialize device properties for the device the handle's stream
211-
// is bound to.
212-
int deviceId = 0;
213-
auto status = hipStreamGetDevice(handle->getStream(), &deviceId);
214-
if(status != hipSuccess)
215-
{
216-
throw HipdnnException(HIPDNN_STATUS_INTERNAL_ERROR,
217-
"Failed to get device from handle's stream");
218-
}
219-
220-
hipDeviceProp_t hipProps;
221-
status = hipGetDeviceProperties(&hipProps, deviceId);
222-
if(status != hipSuccess)
223-
{
224-
throw HipdnnException(HIPDNN_STATUS_INTERNAL_ERROR, "Failed to get device properties");
225-
}
226-
227-
// Create DevicePropertiesT from HIP device properties
228-
hipdnn_flatbuffers_sdk::data_objects::DevicePropertiesT devProps;
229-
devProps.device_id = deviceId;
230-
devProps.multi_processor_count = hipProps.multiProcessorCount;
231-
devProps.total_global_mem = hipProps.totalGlobalMem;
232-
devProps.architecture_name = hipProps.gcnArchName;
233-
234-
// Serialize DevicePropertiesT using FlatBuffers
235-
flatbuffers::FlatBufferBuilder builder(256);
236-
auto offset = hipdnn_flatbuffers_sdk::data_objects::DeviceProperties::Pack(builder, &devProps);
237-
builder.Finish(offset, "HDDP");
238-
239-
// Copy serialized data to persistent storage
240-
std::vector<uint8_t> devicePropsSerialized(builder.GetBufferPointer(),
241-
builder.GetBufferPointer() + builder.GetSize());
242-
243-
// Wrap serialized buffer in hipdnnPluginConstData_t
244-
hipdnnPluginConstData_t devicePropsWrapper;
245-
devicePropsWrapper.ptr = devicePropsSerialized.data();
246-
devicePropsWrapper.size = devicePropsSerialized.size();
208+
// devicePropsSerialized must outlive devicePropsWrapper — the wrapper aliases its storage.
209+
const auto devProps = heuristics::queryDeviceProperties(handle);
210+
const auto devicePropsSerialized = heuristics::serializeDeviceProperties(devProps);
211+
const hipdnnPluginConstData_t devicePropsWrapper
212+
= heuristics::wrapSerializedDeviceProperties(devicePropsSerialized);
247213

248214
// Get serialized graph from GraphDescriptor
249215
const hipdnnPluginConstData_t serializedGraph = _graph->getSerializedGraph();
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
// Copyright © Advanced Micro Devices, Inc., or its affiliates.
2+
// SPDX-License-Identifier: MIT
3+
4+
#include "DeviceProperties.hpp"
5+
6+
#include <flatbuffers/flatbuffers.h>
7+
#include <hip/hip_runtime.h>
8+
9+
#include <string>
10+
11+
#include "HipdnnException.hpp"
12+
#include "handle/Handle.hpp"
13+
14+
namespace hipdnn_backend::heuristics
15+
{
16+
17+
hipdnn_flatbuffers_sdk::data_objects::DevicePropertiesT queryDeviceProperties(int deviceId)
18+
{
19+
hipDeviceProp_t hipProps;
20+
auto status = hipGetDeviceProperties(&hipProps, deviceId);
21+
if(status != hipSuccess)
22+
{
23+
throw HipdnnException(HIPDNN_STATUS_INTERNAL_ERROR,
24+
"Failed to get properties for device " + std::to_string(deviceId)
25+
+ ": " + hipGetErrorString(status));
26+
}
27+
28+
hipdnn_flatbuffers_sdk::data_objects::DevicePropertiesT devProps;
29+
devProps.device_id = deviceId;
30+
devProps.multi_processor_count = hipProps.multiProcessorCount;
31+
devProps.total_global_mem = hipProps.totalGlobalMem;
32+
devProps.architecture_name = hipProps.gcnArchName;
33+
34+
return devProps;
35+
}
36+
37+
hipdnn_flatbuffers_sdk::data_objects::DevicePropertiesT queryDeviceProperties(hipdnnHandle_t handle)
38+
{
39+
if(handle == nullptr)
40+
{
41+
throw HipdnnException(HIPDNN_STATUS_BAD_PARAM, "queryDeviceProperties: handle is null");
42+
}
43+
44+
int deviceId = 0;
45+
auto status = hipStreamGetDevice(handle->getStream(), &deviceId);
46+
if(status != hipSuccess)
47+
{
48+
throw HipdnnException(HIPDNN_STATUS_INTERNAL_ERROR,
49+
std::string{"Failed to get device from handle's stream: "}
50+
+ hipGetErrorString(status));
51+
}
52+
return queryDeviceProperties(deviceId);
53+
}
54+
55+
std::vector<uint8_t>
56+
serializeDeviceProperties(const hipdnn_flatbuffers_sdk::data_objects::DevicePropertiesT& props)
57+
{
58+
flatbuffers::FlatBufferBuilder builder(256);
59+
auto offset = hipdnn_flatbuffers_sdk::data_objects::DeviceProperties::Pack(builder, &props);
60+
builder.Finish(offset, "HDDP");
61+
return {builder.GetBufferPointer(), builder.GetBufferPointer() + builder.GetSize()};
62+
}
63+
64+
} // namespace hipdnn_backend::heuristics
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
// Copyright © Advanced Micro Devices, Inc., or its affiliates.
2+
// SPDX-License-Identifier: MIT
3+
4+
#pragma once
5+
6+
#include <cstddef>
7+
#include <vector>
8+
9+
#include <hipdnn_flatbuffers_sdk/data_objects/device_properties_generated.h>
10+
#include <hipdnn_plugin_sdk/PluginApiDataTypes.h>
11+
12+
struct hipdnnHandle;
13+
using hipdnnHandle_t = struct hipdnnHandle*;
14+
15+
namespace hipdnn_backend::heuristics
16+
{
17+
18+
/**
19+
* @brief Query device properties for an explicit device id.
20+
*
21+
* Calls hipGetDeviceProperties() for @p deviceId and populates a
22+
* DevicePropertiesT structure. Use this overload when the caller already
23+
* knows which device to query (e.g. resolved from a handle's stream).
24+
*
25+
* RFC 0007 Reference: Section 6.2
26+
*
27+
* @param deviceId HIP device id to query.
28+
* @return DevicePropertiesT populated from HIP device properties.
29+
* @throws HipdnnException if the HIP call fails.
30+
*/
31+
hipdnn_flatbuffers_sdk::data_objects::DevicePropertiesT queryDeviceProperties(int deviceId);
32+
33+
/**
34+
* @brief Query device properties for the device bound to a handle's stream.
35+
*
36+
* Resolves the device id from @p handle's stream via hipStreamGetDevice and
37+
* delegates to the explicit-id overload. This is the canonical acquisition
38+
* path inside the backend: device facts must follow the handle's stream, not
39+
* whatever device happens to be current on the calling thread.
40+
*
41+
* RFC 0007 Reference: Section 6.2
42+
*
43+
* @param handle Handle whose stream identifies the target device.
44+
* @return DevicePropertiesT populated from HIP device properties.
45+
* @throws HipdnnException if @p handle is null or if any HIP call fails.
46+
*/
47+
hipdnn_flatbuffers_sdk::data_objects::DevicePropertiesT
48+
queryDeviceProperties(hipdnnHandle_t handle);
49+
50+
/**
51+
* @brief Serialize DevicePropertiesT to FlatBuffer format.
52+
*
53+
* Builds a FlatBuffer-serialized representation of the device properties
54+
* using the Pack method and returns the bytes in a freshly owned vector
55+
* (the caller owns the storage; the internal FlatBufferBuilder is released
56+
* before return).
57+
*
58+
* The returned vector must remain alive while any hipdnnPluginConstData_t
59+
* wrapper produced by wrapSerializedDeviceProperties is in use, because the
60+
* wrapper aliases the vector's buffer.
61+
*
62+
* RFC 0007 Reference: Section 13.2
63+
*
64+
* @param props Device properties to serialize.
65+
* @return Vector owning the serialized FlatBuffer bytes.
66+
*/
67+
std::vector<uint8_t>
68+
serializeDeviceProperties(const hipdnn_flatbuffers_sdk::data_objects::DevicePropertiesT& props);
69+
70+
/**
71+
* @brief Wrap serialized device properties in hipdnnPluginConstData_t.
72+
*
73+
* Creates a hipdnnPluginConstData_t wrapper pointing to the serialized buffer.
74+
* The buffer must remain valid while the wrapper is in use.
75+
*
76+
* @param serializedBuffer Reference to the serialized buffer (must outlive the wrapper).
77+
* @return hipdnnPluginConstData_t wrapper pointing to the buffer.
78+
*/
79+
inline hipdnnPluginConstData_t
80+
wrapSerializedDeviceProperties(const std::vector<uint8_t>& serializedBuffer)
81+
{
82+
hipdnnPluginConstData_t wrapper;
83+
wrapper.ptr = serializedBuffer.data();
84+
wrapper.size = serializedBuffer.size();
85+
return wrapper;
86+
}
87+
88+
} // namespace hipdnn_backend::heuristics

projects/hipdnn/backend/tests/CMakeLists.txt

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -108,9 +108,10 @@ add_executable(
108108
TestHeuristicPluginManagerValidationPaths.cpp
109109
TestSelectionHeuristic.cpp
110110
TestHeuristicPluginResourceManager.cpp
111-
heuristics/TestStaticOrderingBuiltIn.cpp
112-
heuristics/TestEngineOverrideConfig.cpp
113111
heuristics/TestConfigBuiltIn.cpp
112+
heuristics/TestDeviceProperties.cpp
113+
heuristics/TestEngineOverrideConfig.cpp
114+
heuristics/TestStaticOrderingBuiltIn.cpp
114115
TestUserLoggingApis.cpp
115116
TestPlatformUtils.cpp
116117
TestEnginePluginOverride.cpp

projects/hipdnn/backend/tests/IntegrationHeuristicPlugin.cpp

Lines changed: 11 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include "HipdnnException.hpp"
2121
#include "PlatformUtils.hpp"
2222
#include "TestPluginConstants.hpp"
23+
#include "heuristics/DeviceProperties.hpp"
2324
#include "plugin/HeuristicPlugin.hpp"
2425
#include "plugin/HeuristicPluginManager.hpp"
2526
#include "plugin/HeuristicPluginResourceManager.hpp"
@@ -31,8 +32,6 @@
3132
#include <hipdnn_data_sdk/utilities/ScopedResource.hpp>
3233
#include <hipdnn_flatbuffers_sdk/data_objects/device_properties_generated.h>
3334

34-
#include <flatbuffers/flatbuffers.h>
35-
3635
#include <gtest/gtest.h>
3736
#include <string_view>
3837

@@ -45,15 +44,8 @@ namespace
4544
// Note: TEST_GOOD_HEURISTIC_PLUGIN_NAME, TEST_INCOMPLETE_HEURISTIC_API_PLUGIN_NAME,
4645
// and TEST_NO_OPTIONAL_HEURISTIC_PLUGIN_NAME are defined as macros in CMakeLists.txt
4746

48-
// Helper to serialize DevicePropertiesT using FlatBuffers Pack
49-
std::vector<uint8_t>
50-
serializeDeviceProperties(const hipdnn_flatbuffers_sdk::data_objects::DevicePropertiesT& props)
51-
{
52-
flatbuffers::FlatBufferBuilder builder(256);
53-
auto offset = hipdnn_flatbuffers_sdk::data_objects::DeviceProperties::Pack(builder, &props);
54-
builder.Finish(offset, "HDDP");
55-
return {builder.GetBufferPointer(), builder.GetBufferPointer() + builder.GetSize()};
56-
}
47+
using hipdnn_backend::heuristics::serializeDeviceProperties;
48+
using hipdnn_backend::heuristics::wrapSerializedDeviceProperties;
5749

5850
// Wrapper class to access protected constructor
5951
class TestableHeuristicPlugin : public HeuristicPlugin
@@ -172,10 +164,8 @@ TEST_F(IntegrationHeuristicPlugin, SetDevicePropertiesOnHandle)
172164
props.architecture_name = "gfx90a";
173165

174166
// Serialize
175-
auto serialized = serializeDeviceProperties(props);
176-
hipdnnPluginConstData_t devicePropsData;
177-
devicePropsData.ptr = serialized.data();
178-
devicePropsData.size = serialized.size();
167+
const auto serialized = serializeDeviceProperties(props);
168+
const hipdnnPluginConstData_t devicePropsData = wrapSerializedDeviceProperties(serialized);
179169

180170
// Set on handle (should not throw)
181171
EXPECT_NO_THROW(plugin->setDeviceProperties(handle, &devicePropsData));
@@ -193,10 +183,8 @@ TEST_F(IntegrationHeuristicPlugin, SetDevicePropertiesOnAllHandles)
193183
props.total_global_mem = 16ULL * 1024 * 1024 * 1024;
194184
props.architecture_name = "gfx90a";
195185

196-
auto serialized = serializeDeviceProperties(props);
197-
hipdnnPluginConstData_t devicePropsData;
198-
devicePropsData.ptr = serialized.data();
199-
devicePropsData.size = serialized.size();
186+
const auto serialized = serializeDeviceProperties(props);
187+
const hipdnnPluginConstData_t devicePropsData = wrapSerializedDeviceProperties(serialized);
200188

201189
// Set on all handles via resource manager
202190
EXPECT_NO_THROW(rm->setDevicePropertiesOnAllHandles(&devicePropsData));
@@ -226,10 +214,8 @@ TEST_F(IntegrationHeuristicPlugin, CompleteWorkflowWithDevicePropertiesAndFinali
226214
props.total_global_mem = 16ULL * 1024 * 1024 * 1024;
227215
props.architecture_name = "gfx90a";
228216

229-
auto serialized = serializeDeviceProperties(props);
230-
hipdnnPluginConstData_t devicePropsData;
231-
devicePropsData.ptr = serialized.data();
232-
devicePropsData.size = serialized.size();
217+
const auto serialized = serializeDeviceProperties(props);
218+
const hipdnnPluginConstData_t devicePropsData = wrapSerializedDeviceProperties(serialized);
233219
plugin->setDeviceProperties(handle, &devicePropsData);
234220

235221
// Create policy descriptor (RAII so destroy runs even on ASSERT_* abort)
@@ -463,10 +449,8 @@ TEST_F(IntegrationHeuristicPlugin, SetDevicePropertiesWithNoPluginsLoaded)
463449
props.total_global_mem = 16ULL * 1024 * 1024 * 1024;
464450
props.architecture_name = "gfx90a";
465451

466-
auto serialized = serializeDeviceProperties(props);
467-
hipdnnPluginConstData_t devicePropsData;
468-
devicePropsData.ptr = serialized.data();
469-
devicePropsData.size = serialized.size();
452+
const auto serialized = serializeDeviceProperties(props);
453+
const hipdnnPluginConstData_t devicePropsData = wrapSerializedDeviceProperties(serialized);
470454

471455
// Should not throw when no plugins loaded
472456
EXPECT_NO_THROW(rm->setDevicePropertiesOnAllHandles(&devicePropsData));

projects/hipdnn/backend/tests/descriptors/TestEngineHeuristicDescriptor.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ class TestEngineHeuristicDescriptor : public ::testing::Test
8181

8282
void setHeuristicMode() const
8383
{
84-
hipdnnBackendHeurMode_t mode = HIPDNN_HEUR_MODE_FALLBACK;
84+
const hipdnnBackendHeurMode_t mode = HIPDNN_HEUR_MODE_FALLBACK;
8585
ASSERT_NO_THROW(getEngineHeuristicDescriptor()->setAttribute(
8686
HIPDNN_ATTR_ENGINEHEUR_MODE, HIPDNN_TYPE_HEUR_MODE, 1, &mode));
8787
}

0 commit comments

Comments
 (0)