optimizer icon indicating copy to clipboard operation
optimizer copied to clipboard

ExtractConstantToInitializer fails when Constant uses value_int attribute

Open mcollinswisc opened this issue 7 months ago • 2 comments
trafficstars

The Constant operator's schema defines multiple attributes that may be used to specify the value of the output, including value but also sparse_value, value_int, value_strings, etc. It specifies:

Exactly one of the provided attributes, either value, sparse_value, or value_* must be specified.

https://github.com/onnx/onnx/blob/main/docs/Operators.md#Constant

The optimizer currently fails when given a Constant node with value_int specified instead of value, giving error:

/home/mcollins/repo/optimizer/third_party/onnx/onnx/common/ir.h:274: find: Assertion `!required || it != values_.end()` failed: /home/mcollins/repo/optimizer/third_party/onnx/onnx/common/ir.h:278: find: required undefined attribute 'value'

I think the problem is that the transform just tries to grab the value attribute here: https://github.com/onnx/optimizer/blob/278b7197ce6f6636fb95ff8d2ac5557c1e056de7/onnxoptimizer/passes/extract_constant_to_initializer.h#L38 and doesn't check whether value is present or whether one of the other attributes is specified instead.

The graph to reproduce this can be generated with a script:

import onnx

constant_node = onnx.helper.make_node(
    op_type="Constant",
    inputs=[],
    outputs=["const"],
    value_int=42,
)
ident_node = onnx.helper.make_node(
    op_type="Identity",
    inputs=["const"],
    outputs=["y"],
)
output_info = onnx.helper.make_tensor_value_info(
    "y", onnx.TensorProto.INT64, []
)
graph = onnx.helper.make_graph(
    nodes=[constant_node, ident_node],
    inputs=[],
    outputs=[output_info],
    name='test-graph',
)
model = onnx.helper.make_model(graph)

onnx.save(model, "constant_test_case.onnx")

and running:

./onnx_optimizer_exec constant_test_case.onnx /tmp/sim.onnx

If I break at the error the stack trace is

0x00005555555f3953 in onnx::Attributes<onnx::Node>::find(onnx::Symbol, bool) const [clone .constprop.1] ()
(gdb) backtrace
#0  0x00005555555f3953 in onnx::Attributes<onnx::Node>::find(onnx::Symbol, bool) const [clone .constprop.1]
    ()
#1  0x0000555555621582 in onnx::optimization::ExtractConstantToInitializer::runTransform(onnx::Node*, onnx::Graph&, onnx::optimization::NodeDestroyType&) ()
#2  0x00005555556306d5 in onnx::optimization::PredicateBasedPass::_runPassInternal(onnx::Graph&) ()
#3  0x0000555555630f30 in onnx::optimization::PredicateBasedPass::runPass(onnx::Graph&) ()
#4  0x0000555555631956 in onnx::optimization::GeneralPassManager::run(onnx::Graph&) ()
#5  0x000055555562fa72 in onnx::optimization::Optimizer::optimize(onnx::ModelProto const&) ()
#6  0x00005555555fa70e in onnx::optimization::Optimize(onnx::ModelProto const&, std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > const&) ()
#7  0x00005555555ea9ab in main ()

mcollinswisc avatar Mar 26 '25 01:03 mcollinswisc