Copy the input in thresholded_relu's value_inference - #2795
Open
LeSingh1 wants to merge 1 commit into
Open
Conversation
value_inference aliases the input's array and then writes through it:
y = self.x.val
y[y < self.alpha.val] = 0
return y
so folding a thresholded_relu overwrites the value of its input const. Every
sibling op in the file (elu, leaky_relu, softplus_parametric) copies first.
When the const is also used as a weight elsewhere, that weight is silently
replaced with the thresholded values:
@mb.program(input_specs=[mb.TensorSpec(shape=(2, 2))])
def prog(x):
w = mb.const(val=np.array([[-1., .5], [2., -3.]], dtype=np.float32))
y = mb.matmul(x=x, y=w)
z = mb.thresholded_relu(x=w, alpha=1.0)
return mb.add(x=y, y=z)
matmul's weight becomes [[0., 0.], [2., 0.]]
The caller's own numpy array is clobbered too, since the const does not copy it.
Use np.copy, matching the other activation ops.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
thresholded_relu.value_inferencealiases its input's array and then writes through it:Every sibling op in the same file copies first —
elu(line 107),leaky_relu(line 210),softplus_parametric(lines 497-498) all start withnp.copy(...).thresholded_reludoes not, so constant-folding it overwrites the value of its input const.When that const is also used elsewhere — as a weight, say — the weight is silently replaced with the thresholded values:
matmul's weight operand[[0.0, 0.0], [2.0, 0.0]][[-1.0, 0.5], [2.0, -3.0]]The corrupted array is what gets serialized into the weight blob. The caller's own numpy array is clobbered as well, since the const does not copy it on the way in.
Fix
y = np.copy(self.x.val), matching the other activation ops in the file.Tests
In
TestThresholdedReLU(ops/tests/iOS14/test_activation.py):test_builder_eval_does_not_mutate_input— the input array must be unchanged after folding, and the folded value must still be correct.test_builder_eval_does_not_corrupt_shared_const— the shared-weight program above;matmul's operand must keep its original value.Both fail on
mainand pass with the fix.The existing
test_builder_evalis untouched and still passes. It happens to compute its expected value asy = x_val; y[y < 2.0] = 0on the same arrayvalue_inferencewas mutating, which is why it never caught this.I ran all of
ops/tests/iOS14/test_activation.pybefore and after; the pre-existing failure set is identical, 188 either way (this environment cannot load CoreML.framework, so therun_compare_buildertests fail there regardless).