Skip to content

Commit 84dc26e

Browse files
authored
fix(hipdnn): fail fast on plan-only override execute without override enabled (#8881)
## Summary The frontend override `execute()` overload fails fast when override args are supplied to a graph that did not enable override shapes — but only for full graphs. The plan-only [deserialize_compiled_plan](https://github.com/ROCm/rocm-libraries/blob/f1230db5ef05ba6cf6413741a1b58b6a80473a8a/projects/hipdnn/frontend/include/hipdnn_frontend/Graph.hpp#L1571) branch skipped the override-enabled check, so misuse on a plan-only object was only caught later at the backend dispatch guard. This makes the plan-only branch fail fast in the frontend, matching the full-graph branch. Part of the overridable tensor shapes work ([RFC 0008](https://github.com/ROCm/rocm-libraries/blob/develop/projects/hipdnn/docs/rfcs/0008_OverridableTensorShapesDesign.md)). JIRA ID : ALMIOPEN-2244 ## Risk Assessment Medium risk. Adds a read-only backend execution-plan attribute (API addition) and changes the plan-only override-execute path to reject earlier. The new rejection only fires for misuse the backend dispatch guard already rejected authoritatively, so no legitimate path changes: plan-only overrides on an override-enabled plan still execute, and full-graph behavior is unchanged. No serialization format change. Blast radius is ASIC-independent (see below), so passing PR CI is sufficient. ## Testing Summary - Backend unit tests: new attribute round-trips through deserialize → `getAttribute` for both flag states; existing plan-descriptor, serialization, and enum-string suites unaffected. - Frontend GPU integration tests: new plan-only fail-fast regression (rejects with `INVALID_VALUE` and never dispatches to the provider); full override-execute suite for no regressions. - Commit hooks (clang-format, whitespace) on all changed files. ## Testing Checklist - [x] hipDNN backend unit tests - `hipdnn_backend_tests --gtest_filter='TestExecutionPlanDescriptor.*:*SerializationApi*:*BackendEnumStringUtils*:*IsOverrideShapeEnabledExt*'` - ASICs: gfx90a - Status: Passed (74) - [x] hipDNN frontend override integration tests - `hipdnn_public_frontend_tests --gtest_filter='*Override*'` - ASICs: gfx90a - Status: Passed (35) - [x] Commit hooks - `pre-commit run --files <changed>` - Status: Passed - [ ] PR CI - GitHub PR checks - Status: Pending ## Technical Changes - Add read-only `HIPDNN_ATTR_EXECUTION_PLAN_IS_OVERRIDE_SHAPE_ENABLED_EXT` with a `getAttribute` case on `ExecutionPlanDescriptor` (mirrors `ENGINE_GLOBAL_INDEX_EXT`; no serialization change) plus its enum-name mapping. The attribute is required because the override-enabled flag, while already preserved across the plan round-trip in the backend (serialized into the plan flatbuffer, restored on deserialize), was unreachable from the header-only frontend: `getAttribute` did not surface it, `deserialize_compiled_plan` hard-coded it to `false`, and no operation-graph or engine-config descriptor is reconstructed on the plan-only path. The only no-new-attribute alternative — parsing the backend plan flatbuffer in the frontend — would couple the frontend to the backend wire format and version gate. - Recover the flag in `deserialize_compiled_plan` via a new `getExecutionPlanOverrideShapeEnabled` frontend helper instead of forcing `false`. - Reject override args in the plan-only branch of the override `execute()` overload with `INVALID_VALUE`, short-circuiting before any provider dispatch. - Add backend tests for the attribute (both flag states) and enum-name mapping, and a frontend GPU regression test for the plan-only fail-fast.
1 parent 039eba8 commit 84dc26e

9 files changed

Lines changed: 293 additions & 19 deletions

File tree

projects/hipdnn/backend/include/HipdnnBackendAttributeName.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,10 @@ typedef enum
163163
/** @brief Global index of the engine backing this finalized execution plan (read-only) */
164164
HIPDNN_ATTR_EXECUTION_PLAN_ENGINE_GLOBAL_INDEX_EXT = 309,
165165

166+
/** @brief Whether execute-time override shapes are enabled for this plan (bool, read-only,
167+
* extension) */
168+
HIPDNN_ATTR_EXECUTION_PLAN_IS_OVERRIDE_SHAPE_ENABLED_EXT = 310,
169+
166170
/** @} */
167171

168172
/**

projects/hipdnn/backend/src/BackendEnumStringUtils.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -322,6 +322,8 @@ inline const char* hipdnnGetAttributeNameString(hipdnnBackendAttributeName_t att
322322
return "HIPDNN_ATTR_EXECUTION_PLAN_TENSOR_UIDS_EXT";
323323
case HIPDNN_ATTR_EXECUTION_PLAN_ENGINE_GLOBAL_INDEX_EXT:
324324
return "HIPDNN_ATTR_EXECUTION_PLAN_ENGINE_GLOBAL_INDEX_EXT";
325+
case HIPDNN_ATTR_EXECUTION_PLAN_IS_OVERRIDE_SHAPE_ENABLED_EXT:
326+
return "HIPDNN_ATTR_EXECUTION_PLAN_IS_OVERRIDE_SHAPE_ENABLED_EXT";
325327

326328
case HIPDNN_ATTR_INTERMEDIATE_INFO_UNIQUE_ID:
327329
return "HIPDNN_ATTR_INTERMEDIATE_INFO_UNIQUE_ID";

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

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,15 @@ void ExecutionPlanDescriptor::getAttribute(hipdnnBackendAttributeName_t attribut
119119
arrayOfElements,
120120
"ExecutionPlanDescriptor failed to get engine global index");
121121
break;
122+
case HIPDNN_ATTR_EXECUTION_PLAN_IS_OVERRIDE_SHAPE_ENABLED_EXT:
123+
getScalar(isOverrideShapeEnabled(),
124+
HIPDNN_TYPE_BOOLEAN,
125+
attributeType,
126+
requestedElementCount,
127+
elementCount,
128+
arrayOfElements,
129+
"ExecutionPlanDescriptor failed to get override shape enabled flag");
130+
break;
122131
case HIPDNN_ATTR_EXECUTION_PLAN_HANDLE:
123132
case HIPDNN_ATTR_EXECUTION_PLAN_COMPUTED_INTERMEDIATE_UIDS:
124133
case HIPDNN_ATTR_EXECUTION_PLAN_RUN_ONLY_INTERMEDIATE_UIDS:

projects/hipdnn/backend/tests/TestBackendEnumStringUtils.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,11 @@ TEST(TestBackendEnumStringUtils, GetBackendAttributeName)
141141
"HIPDNN_ATTR_EXECUTION_PLAN_DEVICEPROP");
142142
EXPECT_STREQ(hipdnnGetAttributeNameString(HIPDNN_ATTR_EXECUTION_PLAN_TENSOR_UIDS_EXT),
143143
"HIPDNN_ATTR_EXECUTION_PLAN_TENSOR_UIDS_EXT");
144+
EXPECT_STREQ(hipdnnGetAttributeNameString(HIPDNN_ATTR_EXECUTION_PLAN_ENGINE_GLOBAL_INDEX_EXT),
145+
"HIPDNN_ATTR_EXECUTION_PLAN_ENGINE_GLOBAL_INDEX_EXT");
146+
EXPECT_STREQ(
147+
hipdnnGetAttributeNameString(HIPDNN_ATTR_EXECUTION_PLAN_IS_OVERRIDE_SHAPE_ENABLED_EXT),
148+
"HIPDNN_ATTR_EXECUTION_PLAN_IS_OVERRIDE_SHAPE_ENABLED_EXT");
144149

145150
EXPECT_STREQ(hipdnnGetAttributeNameString(HIPDNN_ATTR_INTERMEDIATE_INFO_UNIQUE_ID),
146151
"HIPDNN_ATTR_INTERMEDIATE_INFO_UNIQUE_ID");

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

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -505,6 +505,54 @@ TEST_F(TestExecutionPlanDescriptor, GetEngineGlobalIndexExtReturnsDeserializedEn
505505
ASSERT_EQ(engineGlobalIndex, ENGINE_ID);
506506
}
507507

508+
TEST_F(TestExecutionPlanDescriptor, GetIsOverrideShapeEnabledExtReturnsDeserializedFlagFalse)
509+
{
510+
auto plan = getExecutionPlanDescriptor();
511+
auto serializedPlan = makeSerializedPlan(1, 1024, true, true, false, false, false);
512+
513+
EXPECT_CALL(*_mockEnginePluginResourceManager,
514+
createExecutionContextFromSerialized(ENGINE_ID, _))
515+
.WillOnce([](int64_t, const hipdnnPluginConstData_t*) { return getExecutionContext(); });
516+
EXPECT_CALL(*_mockEnginePluginResourceManager, destroyExecutionContext(_, _));
517+
518+
ASSERT_NO_THROW(plan->deserializeBackendPlan(
519+
_mockEnginePluginResourceManager, serializedPlan.data(), serializedPlan.size()));
520+
521+
bool isOverrideShapeEnabled = true;
522+
int64_t count = 0;
523+
ASSERT_NO_THROW(plan->getAttribute(HIPDNN_ATTR_EXECUTION_PLAN_IS_OVERRIDE_SHAPE_ENABLED_EXT,
524+
HIPDNN_TYPE_BOOLEAN,
525+
1,
526+
&count,
527+
&isOverrideShapeEnabled));
528+
ASSERT_EQ(count, 1);
529+
ASSERT_FALSE(isOverrideShapeEnabled);
530+
}
531+
532+
TEST_F(TestExecutionPlanDescriptor, GetIsOverrideShapeEnabledExtReturnsDeserializedFlagTrue)
533+
{
534+
auto plan = getExecutionPlanDescriptor();
535+
auto serializedPlan = makeSerializedPlan(1, 1024, true, true, false, false, true);
536+
537+
EXPECT_CALL(*_mockEnginePluginResourceManager,
538+
createExecutionContextFromSerialized(ENGINE_ID, _))
539+
.WillOnce([](int64_t, const hipdnnPluginConstData_t*) { return getExecutionContext(); });
540+
EXPECT_CALL(*_mockEnginePluginResourceManager, destroyExecutionContext(_, _));
541+
542+
ASSERT_NO_THROW(plan->deserializeBackendPlan(
543+
_mockEnginePluginResourceManager, serializedPlan.data(), serializedPlan.size()));
544+
545+
bool isOverrideShapeEnabled = false;
546+
int64_t count = 0;
547+
ASSERT_NO_THROW(plan->getAttribute(HIPDNN_ATTR_EXECUTION_PLAN_IS_OVERRIDE_SHAPE_ENABLED_EXT,
548+
HIPDNN_TYPE_BOOLEAN,
549+
1,
550+
&count,
551+
&isOverrideShapeEnabled));
552+
ASSERT_EQ(count, 1);
553+
ASSERT_TRUE(isOverrideShapeEnabled);
554+
}
555+
508556
TEST_F(TestExecutionPlanDescriptor, SerializeRejectsUnfinalizedPlan)
509557
{
510558
auto plan = getExecutionPlanDescriptor();

projects/hipdnn/frontend/include/hipdnn_frontend/Graph.hpp

Lines changed: 33 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1485,7 +1485,11 @@ class Graph : public INode
14851485
// A deserialized compiled plan is finalized by construction and can be re-serialized.
14861486
_executionPlanFinalized = true;
14871487
// Recover the engine backing the attached plan for the serialize capability gate.
1488-
_selectedEngineId = detail::getExecutionPlanEngineId(_executionPlanDesc->get());
1488+
_selectedEngineId = detail::getNullableAttrScalar<int64_t>(
1489+
_executionPlanDesc->get(),
1490+
HIPDNN_ATTR_EXECUTION_PLAN_ENGINE_GLOBAL_INDEX_EXT,
1491+
HIPDNN_TYPE_INT64,
1492+
"execution plan engine global index");
14891493
}
14901494
else
14911495
{
@@ -1580,11 +1584,20 @@ class Graph : public INode
15801584
// A deserialized compiled plan is finalized by construction and can be re-serialized.
15811585
_executionPlanFinalized = true;
15821586
// Recover the engine backing the attached plan for the serialize capability gate.
1583-
_selectedEngineId = detail::getExecutionPlanEngineId(_executionPlanDesc->get());
1587+
_selectedEngineId = detail::getNullableAttrScalar<int64_t>(
1588+
_executionPlanDesc->get(),
1589+
HIPDNN_ATTR_EXECUTION_PLAN_ENGINE_GLOBAL_INDEX_EXT,
1590+
HIPDNN_TYPE_INT64,
1591+
"execution plan engine global index");
15841592
_engineConfigDesc.reset();
15851593
resetGraphDesc();
15861594
_sub_nodes.clear();
1587-
_isOverrideShapeEnabled = false;
1595+
_isOverrideShapeEnabled = detail::getNullableAttrScalar<bool>(
1596+
_executionPlanDesc->get(),
1597+
HIPDNN_ATTR_EXECUTION_PLAN_IS_OVERRIDE_SHAPE_ENABLED_EXT,
1598+
HIPDNN_TYPE_BOOLEAN,
1599+
"execution plan override shape enabled flag")
1600+
.value_or(false);
15881601

15891602
return {};
15901603
}
@@ -2024,8 +2037,10 @@ class Graph : public INode
20242037
/**
20252038
* @brief Execute with per-tensor runtime shape/stride overrides.
20262039
*
2027-
* Graph-backed objects require `set_override_shape_enabled(true)`. Objects
2028-
* restored from compiled-plan bytes receive structural validation only.
2040+
* Both graph-backed and plan-only (compiled-plan-deserialized) objects require
2041+
* the plan to have been built with `set_override_shape_enabled(true)`; otherwise
2042+
* the call fails fast with `INVALID_VALUE`. Plan-only objects additionally receive
2043+
* structural validation only (no graph-aware shape checks).
20292044
* Empty override arrays dispatch through the non-override path.
20302045
*/
20312046
Error execute(hipdnnHandle_t handle,
@@ -2054,6 +2069,19 @@ class Graph : public INode
20542069
const bool planOnly = _sub_nodes.empty();
20552070
if(planOnly)
20562071
{
2072+
if(!_isOverrideShapeEnabled)
2073+
{
2074+
HIPDNN_FE_LOG_INFO("Override execute called on plan-only graph "
2075+
<< graph_attributes.get_name()
2076+
<< " deserialized from a plan that was not built with "
2077+
"set_override_shape_enabled(true).");
2078+
return {ErrorCode::INVALID_VALUE,
2079+
"Graph::execute override overload called on a compiled plan that was "
2080+
"not built with set_override_shape_enabled(true). The override flag "
2081+
"must be set at build time before per-execute overrides are "
2082+
"supplied."};
2083+
}
2084+
20572085
HIPDNN_CHECK_ERROR(detail::validatePlanOnlyOverrideArguments(
20582086
overrideUids, overrideShapes, overrideStrides));
20592087
}

projects/hipdnn/frontend/include/hipdnn_frontend/detail/DescriptorUnpackHelpers.hpp

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -97,24 +97,20 @@ template <typename T>
9797
return {};
9898
}
9999

100-
/// Returns the global index of the engine backing a finalized execution-plan
101-
/// descriptor, or std::nullopt if the backend cannot report it. Lets callers
102-
/// recover the engine of a plan attached via deserialize so a later
103-
/// serialize() can re-query that engine's plan-serialization capability.
104-
[[nodiscard]] inline std::optional<int64_t>
105-
getExecutionPlanEngineId(hipdnnBackendDescriptor_t planDesc)
100+
/// Gets a scalar attribute, returning std::nullopt when the backend cannot
101+
/// report it instead of surfacing an error.
102+
template <typename T>
103+
[[nodiscard]] inline std::optional<T> getNullableAttrScalar(hipdnnBackendDescriptor_t desc,
104+
hipdnnBackendAttributeName_t attrName,
105+
hipdnnBackendAttributeType_t attrType,
106+
const std::string& errorContext)
106107
{
107-
int64_t engineId = 0;
108-
if(getDescriptorAttrScalar<int64_t>(planDesc,
109-
HIPDNN_ATTR_EXECUTION_PLAN_ENGINE_GLOBAL_INDEX_EXT,
110-
HIPDNN_TYPE_INT64,
111-
engineId,
112-
"execution plan engine global index")
113-
.is_bad())
108+
T value{};
109+
if(getDescriptorAttrScalar<T>(desc, attrName, attrType, value, errorContext).is_bad())
114110
{
115111
return std::nullopt;
116112
}
117-
return engineId;
113+
return value;
118114
}
119115

120116
/// Gets a string attribute (char array) from a backend descriptor.

projects/hipdnn/frontend/tests/TestGraph.cpp

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -636,6 +636,33 @@ TEST_F(TestGraph, DeserializeCompiledPlanClearsFrontendGraphState)
636636
}
637637

638638
#ifdef HIPDNN_ENABLE_SDPA
639+
// Sets the override-shape-enabled attribute query that deserialize_compiled_plan
640+
// issues on the restored execution plan, letting plan-only tests choose whether the
641+
// restored plan reports override shapes as enabled. Uses ON_CALL so the sibling
642+
// engine-id query on the same descriptor stays uninteresting under NiceMock.
643+
static void setPlanOverrideShapeEnabledQuery(::testing::NiceMock<Mock_hipdnn_backend>& mockBackend,
644+
hipdnnBackendDescriptor_t executionPlan,
645+
bool enabled)
646+
{
647+
ON_CALL(mockBackend,
648+
backendGetAttribute(executionPlan,
649+
HIPDNN_ATTR_EXECUTION_PLAN_IS_OVERRIDE_SHAPE_ENABLED_EXT,
650+
HIPDNN_TYPE_BOOLEAN,
651+
1,
652+
_,
653+
_))
654+
.WillByDefault([enabled](hipdnnBackendDescriptor_t,
655+
hipdnnBackendAttributeName_t,
656+
hipdnnBackendAttributeType_t,
657+
int64_t,
658+
int64_t* elementCount,
659+
void* arrayOfElements) {
660+
*elementCount = 1;
661+
*static_cast<bool*>(arrayOfElements) = enabled;
662+
return HIPDNN_STATUS_SUCCESS;
663+
});
664+
}
665+
639666
TEST_F(TestGraph, PlanOnlyOverrideExecuteWritesOverrideVariantPackAttributes)
640667
{
641668
Graph graph;
@@ -651,6 +678,7 @@ TEST_F(TestGraph, PlanOnlyOverrideExecuteWritesOverrideVariantPackAttributes)
651678
*descriptor = executionPlan;
652679
return HIPDNN_STATUS_SUCCESS;
653680
});
681+
setPlanOverrideShapeEnabledQuery(*_mockBackend, executionPlan, true);
654682
ASSERT_TRUE(graph.from_compiled_plan_binary(_handle, serializedPlan).is_good());
655683

656684
std::unordered_map<int64_t, void*> variantPack;
@@ -838,6 +866,7 @@ TEST_F(TestGraph, PlanOnlyOverrideExecuteRejectsStructuralValidationBeforeBacken
838866
*descriptor = executionPlan;
839867
return HIPDNN_STATUS_SUCCESS;
840868
});
869+
setPlanOverrideShapeEnabledQuery(*_mockBackend, executionPlan, true);
841870
ASSERT_TRUE(graph.from_compiled_plan_binary(_handle, serializedPlan).is_good());
842871

843872
std::unordered_map<int64_t, void*> variantPack;
@@ -870,6 +899,7 @@ TEST_F(TestGraph, PlanOnlyOverrideExecutePropagatesOverrideAttributeFailure)
870899
*descriptor = executionPlan;
871900
return HIPDNN_STATUS_SUCCESS;
872901
});
902+
setPlanOverrideShapeEnabledQuery(*_mockBackend, executionPlan, true);
873903
ASSERT_TRUE(graph.from_compiled_plan_binary(_handle, serializedPlan).is_good());
874904

875905
std::unordered_map<int64_t, void*> variantPack;
@@ -901,6 +931,74 @@ TEST_F(TestGraph, PlanOnlyOverrideExecutePropagatesOverrideAttributeFailure)
901931

902932
EXPECT_EQ(result.code, ErrorCode::HIPDNN_BACKEND_ERROR);
903933
}
934+
935+
TEST_F(TestGraph, DeserializeCompiledPlanRecoversOverrideShapeEnabledFlag)
936+
{
937+
const std::vector<uint8_t> serializedPlan{1, 2, 3};
938+
939+
auto enabledPlan = reinterpret_cast<hipdnnBackendDescriptor_t>(0x4567);
940+
EXPECT_CALL(*_mockBackend, backendCreateAndDeserializeExecutionPlanExt(_handle, _, _, _))
941+
.WillOnce(
942+
[enabledPlan](
943+
hipdnnHandle_t, hipdnnBackendDescriptor_t* descriptor, const uint8_t*, size_t) {
944+
*descriptor = enabledPlan;
945+
return HIPDNN_STATUS_SUCCESS;
946+
});
947+
setPlanOverrideShapeEnabledQuery(*_mockBackend, enabledPlan, true);
948+
949+
Graph enabledGraph;
950+
ASSERT_TRUE(enabledGraph.from_compiled_plan_binary(_handle, serializedPlan).is_good());
951+
EXPECT_TRUE(enabledGraph.is_override_shape_enabled());
952+
953+
auto disabledPlan = reinterpret_cast<hipdnnBackendDescriptor_t>(0x89ab);
954+
EXPECT_CALL(*_mockBackend, backendCreateAndDeserializeExecutionPlanExt(_handle, _, _, _))
955+
.WillOnce(
956+
[disabledPlan](
957+
hipdnnHandle_t, hipdnnBackendDescriptor_t* descriptor, const uint8_t*, size_t) {
958+
*descriptor = disabledPlan;
959+
return HIPDNN_STATUS_SUCCESS;
960+
});
961+
setPlanOverrideShapeEnabledQuery(*_mockBackend, disabledPlan, false);
962+
963+
Graph disabledGraph;
964+
ASSERT_TRUE(disabledGraph.from_compiled_plan_binary(_handle, serializedPlan).is_good());
965+
EXPECT_FALSE(disabledGraph.is_override_shape_enabled());
966+
}
967+
968+
TEST_F(TestGraph, PlanOnlyOverrideExecuteRejectedWhenOverrideShapeDisabled)
969+
{
970+
Graph graph;
971+
const std::vector<uint8_t> serializedPlan{1, 2, 3};
972+
auto executionPlan = reinterpret_cast<hipdnnBackendDescriptor_t>(0x4567);
973+
974+
EXPECT_CALL(*_mockBackend,
975+
backendCreateAndDeserializeExecutionPlanExt(
976+
_handle, _, serializedPlan.data(), serializedPlan.size()))
977+
.WillOnce(
978+
[executionPlan](
979+
hipdnnHandle_t, hipdnnBackendDescriptor_t* descriptor, const uint8_t*, size_t) {
980+
*descriptor = executionPlan;
981+
return HIPDNN_STATUS_SUCCESS;
982+
});
983+
setPlanOverrideShapeEnabledQuery(*_mockBackend, executionPlan, false);
984+
ASSERT_TRUE(graph.from_compiled_plan_binary(_handle, serializedPlan).is_good());
985+
986+
std::unordered_map<int64_t, void*> variantPack;
987+
variantPack[1] = reinterpret_cast<void*>(0x1000);
988+
const std::vector<int64_t> overrideUids{1};
989+
const std::vector<std::vector<int64_t>> overrideShapes{{2, 3}};
990+
const std::vector<std::vector<int64_t>> overrideStrides{{3, 1}};
991+
992+
// Fail-fast must reject before constructing a variant pack or dispatching.
993+
EXPECT_CALL(*_mockBackend, backendCreateDescriptor(HIPDNN_BACKEND_VARIANT_PACK_DESCRIPTOR, _))
994+
.Times(0);
995+
EXPECT_CALL(*_mockBackend, backendExecute(_, _, _)).Times(0);
996+
997+
auto result = graph.execute(
998+
_handle, variantPack, nullptr, overrideUids, overrideShapes, overrideStrides);
999+
1000+
EXPECT_EQ(result.code, ErrorCode::INVALID_VALUE) << result.get_message();
1001+
}
9041002
#endif
9051003

9061004
TEST_F(TestGraph, ValidateUnsetNodeComputeTypeSetGraphComputeType)

0 commit comments

Comments
 (0)