Skip to content
13 changes: 13 additions & 0 deletions include/onnxruntime/core/session/onnxruntime_c_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,8 @@ typedef enum OrtOpAttrType {
ORT_OP_ATTR_FLOATS,
ORT_OP_ATTR_STRING,
ORT_OP_ATTR_STRINGS,
ORT_OP_ATTR_GRAPH,
ORT_OP_ATTR_GRAPHS,
} OrtOpAttrType;

//! @}
Expand Down Expand Up @@ -5887,6 +5889,17 @@ struct OrtApi {
*/
ORT_API2_STATUS(Node_GetAttributes, _In_ const OrtNode* node, _Outptr_ OrtArrayOfConstObjects** attributes);

/** \brief Get the attribute type as OrtOpAttrType from an OrtOpAttr.
*
* \param[in] attribute The OrtOpAttr instance.
* \param[out] type Output the attribute type as OrtOpAttrType.
*
* \snippet{doc} snippets.dox OrtStatus Return Value
*
* \since Version 1.23.
*/
ORT_API2_STATUS(OpAttr_GetType, _In_ const OrtOpAttr* attribute, _Out_ OrtOpAttrType* type);

/** \brief Get the subgraphs, as OrtGraph instances, contained by the given node.
*
* Certain operator types (e.g., If and Loop) contain nested subgraphs.
Expand Down
49 changes: 49 additions & 0 deletions onnxruntime/core/session/onnxruntime_c_api.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2856,6 +2856,54 @@ ORT_API_STATUS_IMPL(OrtApis::Node_GetAttributes, _In_ const OrtNode* node, _Outp
API_IMPL_END
}

ORT_API_STATUS_IMPL(OrtApis::OpAttr_GetType, _In_ const OrtOpAttr* attribute, _Out_ OrtOpAttrType* type) {
API_IMPL_BEGIN
const auto attr = attribute->attr_proto;
auto onnx_attr_type = attribute->attr_proto.type();
switch (onnx_attr_type) {
case ONNX_NAMESPACE::AttributeProto_AttributeType::AttributeProto_AttributeType_UNDEFINED: {
*type = OrtOpAttrType::ORT_OP_ATTR_UNDEFINED;
break;
}
case ONNX_NAMESPACE::AttributeProto_AttributeType::AttributeProto_AttributeType_INT: {
*type = OrtOpAttrType::ORT_OP_ATTR_INT;
break;
}
case ONNX_NAMESPACE::AttributeProto_AttributeType::AttributeProto_AttributeType_INTS: {
*type = OrtOpAttrType::ORT_OP_ATTR_INTS;
break;
}
case ONNX_NAMESPACE::AttributeProto_AttributeType::AttributeProto_AttributeType_FLOAT: {
*type = OrtOpAttrType::ORT_OP_ATTR_FLOAT;
break;
}
case ONNX_NAMESPACE::AttributeProto_AttributeType::AttributeProto_AttributeType_FLOATS: {
*type = OrtOpAttrType::ORT_OP_ATTR_FLOATS;
break;
}
case ONNX_NAMESPACE::AttributeProto_AttributeType::AttributeProto_AttributeType_STRING: {
*type = OrtOpAttrType::ORT_OP_ATTR_STRING;
break;
}
case ONNX_NAMESPACE::AttributeProto_AttributeType::AttributeProto_AttributeType_STRINGS: {
*type = OrtOpAttrType::ORT_OP_ATTR_STRINGS;
break;
}
case ONNX_NAMESPACE::AttributeProto_AttributeType::AttributeProto_AttributeType_GRAPH: {
*type = OrtOpAttrType::ORT_OP_ATTR_GRAPH;
break;
}
case ONNX_NAMESPACE::AttributeProto_AttributeType::AttributeProto_AttributeType_GRAPHS: {
*type = OrtOpAttrType::ORT_OP_ATTR_GRAPHS;
break;
}
default:
return OrtApis::CreateStatus(OrtErrorCode::ORT_INVALID_ARGUMENT, "Unexpected attribute type.");
}
return nullptr;
API_IMPL_END
}

ORT_API_STATUS_IMPL(OrtApis::Node_GetSubgraphs, _In_ const OrtNode* node, _Outptr_ OrtArrayOfConstObjects** subgraphs) {
API_IMPL_BEGIN
if (subgraphs == nullptr) {
Expand Down Expand Up @@ -3552,6 +3600,7 @@ static constexpr OrtApi ort_api_1_to_23 = {
&OrtApis::Node_GetOutputs,
&OrtApis::Node_GetImplicitInputs,
&OrtApis::Node_GetAttributes,
&OrtApis::OpAttr_GetType,
&OrtApis::Node_GetSubgraphs,
&OrtApis::Node_GetParentGraph,

Expand Down
1 change: 1 addition & 0 deletions onnxruntime/core/session/ort_apis.h
Original file line number Diff line number Diff line change
Expand Up @@ -663,6 +663,7 @@ ORT_API_STATUS_IMPL(Node_GetInputs, _In_ const OrtNode* node, _Outptr_ OrtArrayO
ORT_API_STATUS_IMPL(Node_GetOutputs, _In_ const OrtNode* node, _Outptr_ OrtArrayOfConstObjects** outputs);
ORT_API_STATUS_IMPL(Node_GetImplicitInputs, _In_ const OrtNode* node, _Outptr_ OrtArrayOfConstObjects** implicit_inputs);
ORT_API_STATUS_IMPL(Node_GetAttributes, _In_ const OrtNode* node, _Outptr_ OrtArrayOfConstObjects** attrs);
ORT_API_STATUS_IMPL(OpAttr_GetType, _In_ const OrtOpAttr* attribute, _Out_ OrtOpAttrType* type);
ORT_API_STATUS_IMPL(Node_GetSubgraphs, _In_ const OrtNode* node, _Outptr_ OrtArrayOfConstObjects** subgraphs);
ORT_API_STATUS_IMPL(Node_GetParentGraph, _In_ const OrtNode* node,
_Outptr_result_maybenull_ const OrtGraph** parent_graph);
Expand Down
47 changes: 46 additions & 1 deletion onnxruntime/test/ep_graph/test_ep_graph.cc
Original file line number Diff line number Diff line change
Expand Up @@ -459,11 +459,56 @@ static void CheckGraphCApi(const GraphViewer& graph_viewer, const OrtGraph& api_
ASSERT_ORTSTATUS_OK(ort_api.Node_GetAttributes(api_node, &api_node_attributes));
CheckArrayObjectType(api_node_attributes, ORT_TYPE_TAG_OrtOpAttr);

for (size_t attr_idx = 0; attr_idx < node_attrs.size(); attr_idx++) {
size_t attr_idx = 0;
for (const auto& node_attr : node_attrs) {
const OrtOpAttr* api_node_attr = nullptr;
ASSERT_ORTSTATUS_OK(ort_api.ArrayOfConstObjects_GetElementAt(api_node_attributes, attr_idx,
reinterpret_cast<const void**>(&api_node_attr)));
ASSERT_NE(api_node_attr, nullptr);

OrtOpAttrType api_node_attr_type = OrtOpAttrType::ORT_OP_ATTR_UNDEFINED;
ASSERT_ORTSTATUS_OK(ort_api.OpAttr_GetType(api_node_attr, &api_node_attr_type));

ONNX_NAMESPACE::AttributeProto_AttributeType node_attr_type = node_attr.second.type();
switch (node_attr_type) {
case ONNX_NAMESPACE::AttributeProto_AttributeType::AttributeProto_AttributeType_UNDEFINED: {
ASSERT_EQ(api_node_attr_type, OrtOpAttrType::ORT_OP_ATTR_UNDEFINED);
break;
}
case ONNX_NAMESPACE::AttributeProto_AttributeType::AttributeProto_AttributeType_INT: {
ASSERT_EQ(api_node_attr_type, OrtOpAttrType::ORT_OP_ATTR_INT);
break;
}
case ONNX_NAMESPACE::AttributeProto_AttributeType::AttributeProto_AttributeType_INTS: {
ASSERT_EQ(api_node_attr_type, OrtOpAttrType::ORT_OP_ATTR_INTS);
break;
}
case ONNX_NAMESPACE::AttributeProto_AttributeType::AttributeProto_AttributeType_FLOAT: {
ASSERT_EQ(api_node_attr_type, OrtOpAttrType::ORT_OP_ATTR_FLOAT);
break;
}
case ONNX_NAMESPACE::AttributeProto_AttributeType::AttributeProto_AttributeType_FLOATS: {
ASSERT_EQ(api_node_attr_type, OrtOpAttrType::ORT_OP_ATTR_FLOATS);
break;
}
case ONNX_NAMESPACE::AttributeProto_AttributeType::AttributeProto_AttributeType_STRING: {
ASSERT_EQ(api_node_attr_type, OrtOpAttrType::ORT_OP_ATTR_STRING);
break;
}
case ONNX_NAMESPACE::AttributeProto_AttributeType::AttributeProto_AttributeType_STRINGS: {
ASSERT_EQ(api_node_attr_type, OrtOpAttrType::ORT_OP_ATTR_STRINGS);
break;
}
case ONNX_NAMESPACE::AttributeProto_AttributeType::AttributeProto_AttributeType_GRAPH: {
ASSERT_EQ(api_node_attr_type, OrtOpAttrType::ORT_OP_ATTR_GRAPH);
break;
}
case ONNX_NAMESPACE::AttributeProto_AttributeType::AttributeProto_AttributeType_GRAPHS: {
ASSERT_EQ(api_node_attr_type, OrtOpAttrType::ORT_OP_ATTR_GRAPHS);
break;
}
}
attr_idx++;
}
}

Expand Down
Loading