You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Discipline.add_output appends a second VariableMetaData typed kResidual for implicit disciplines, but never registers it in _declared. The duplicate-name guard therefore covers the output and not its residual.
The guard is asymmetric._declared is the index that makes the duplicate check cheap rather than a quadratic scan (added in Speed up serialization and remove the quadratic metadata scans #74). A residual entry can be created that the guard does not know about, so the two lists can drift.
preallocate_partials resolves shapes against the wrong entry. Both server (discipline_server.py) and client (discipline_client.py) build shapes = {var.name: tuple(var.shape) for var in ..._var_meta}, keyed on name alone. The residual comes later in the list, so it overwrites the output. The shapes are identical today, so this is benign -- but it means the partial-shape lookup for ('x','x') silently resolves against the residual metadata, and it will stop being benign if the two ever diverge.
A dead assignment.res_meta.type is set to kOutput and then immediately to kResidual. Harmless, but it suggests the block was edited without being reread.
Proposed fix
Register the residual key alongside the output, drop the dead assignment, and consider keying the shapes dicts in preallocate_partials and _recover_partials on (type, name) rather than name so the lookup is unambiguous. SetVariableShapes already indexes by (type, name) for exactly this reason (discipline_server.py), so the two sites would then agree.
Notes
Found while tracing the implicit stack for #76. Pre-existing on main.
Problem
Discipline.add_outputappends a secondVariableMetaDatatypedkResidualfor implicit disciplines, but never registers it in_declared. The duplicate-name guard therefore covers the output and not its residual.philote_mdo/general/discipline.py(main, lines 218-227):Confirmed on an implicit discipline declaring one output:
Consequences
_declaredis the index that makes the duplicate check cheap rather than a quadratic scan (added in Speed up serialization and remove the quadratic metadata scans #74). A residual entry can be created that the guard does not know about, so the two lists can drift.preallocate_partialsresolves shapes against the wrong entry. Both server (discipline_server.py) and client (discipline_client.py) buildshapes = {var.name: tuple(var.shape) for var in ..._var_meta}, keyed on name alone. The residual comes later in the list, so it overwrites the output. The shapes are identical today, so this is benign -- but it means the partial-shape lookup for('x','x')silently resolves against the residual metadata, and it will stop being benign if the two ever diverge.res_meta.typeis set tokOutputand then immediately tokResidual. Harmless, but it suggests the block was edited without being reread.Proposed fix
Register the residual key alongside the output, drop the dead assignment, and consider keying the
shapesdicts inpreallocate_partialsand_recover_partialson(type, name)rather thannameso the lookup is unambiguous.SetVariableShapesalready indexes by(type, name)for exactly this reason (discipline_server.py), so the two sites would then agree.Notes
Found while tracing the implicit stack for #76. Pre-existing on
main.