2
import caffe2.python.fakelowp.init_shared_libs # noqa
3
from caffe2.proto import caffe2_pb2
4
from caffe2.python import core
5
from caffe2.python import workspace
6
from caffe2.python.onnx.onnxifi import onnxifi_caffe2_net
7
from caffe2.python.fakelowp.test_utils import print_test_debug_info
8
from hypothesis import given, settings
9
from hypothesis import strategies as st
10
import caffe2.python.serialized_test.serialized_test_util as serial
13
core.GlobalInit(["caffe2",
14
"--glow_global_fp16=1",
15
"--glow_global_fused_scale_offset_fp16=1",
16
"--glow_global_force_sls_fp16_accum=1"])
18
GLOW_LOWERED_BATCHNORM = False
21
# Test the lowered LayerNorm op
22
class LayerNorm(serial.SerializedTestCase):
24
@given(seed=st.integers(0, 65535),
25
batch_size=st.integers(min_value=1, max_value=50),
26
size=st.integers(min_value=2, max_value=128),
27
epsilon=st.floats(min_value=1e-4, max_value=1e-3),
28
elementwise_affine=st.booleans())
29
@settings(deadline=datetime.timedelta(seconds=10))
30
def test_layernorm(self, seed, batch_size, size, epsilon, elementwise_affine):
33
workspace.ResetWorkspace()
36
dims = np.array(([batch_size, size]))
37
X = np.random.uniform(size=dims).astype(np.float32) - 0.5
38
gamma = np.random.randn(*X.shape[axis:]).astype(np.float32)
39
beta = np.random.randn(*X.shape[axis:]).astype(np.float32)
41
pred_net = caffe2_pb2.NetDef()
42
pred_net.name = "pred"
43
pred_net.external_input.extend(["X", "gamma", "beta"])
44
pred_net.external_output.extend(["Y", "mean", "rstd"])
45
pred_net.op.add().CopyFrom(
48
["X", "gamma", "beta"] if elementwise_affine else ["X"],
49
["Y", "mean", "rstd"],
52
elementwise_affine=elementwise_affine
56
pred_net_ref = caffe2_pb2.NetDef()
57
pred_net_ref.name = "pred_ref"
58
pred_net_ref.external_input.extend(["X", "gamma", "beta"])
59
pred_net_ref.external_output.extend(["Y", "mean", "rstd"])
60
pred_net_ref.op.add().CopyFrom(
62
"LayerNormFakeFP16NNPI",
63
["X", "gamma", "beta"] if elementwise_affine else ["X"],
64
["Y", "mean", "rstd"],
67
elementwise_affine=elementwise_affine
71
shape_hits = {"X": X.shape, "gamma": gamma.shape, "beta": beta.shape}
72
pred_net_onnxified = onnxifi_caffe2_net(
79
num_onnxified_ops = sum(
80
1 if o.type == "Onnxifi" else 0 for o in pred_net_onnxified.op)
81
np.testing.assert_equal(num_onnxified_ops, 1)
83
workspace.FeedBlob("X", X)
84
workspace.FeedBlob("gamma", gamma)
85
workspace.FeedBlob("beta", beta)
87
workspace.CreateNet(pred_net_ref)
88
workspace.CreateNet(pred_net_onnxified)
90
workspace.RunNet(pred_net_ref.name)
91
Y_c2 = workspace.FetchBlob("Y")
93
dims1 = np.array(([1, *dims]))
94
X_glow = X.reshape(dims1)
95
workspace.FeedBlob("X", X_glow)
97
workspace.RunNet(pred_net_onnxified.name)
98
Y_glow = workspace.FetchBlob("Y")
100
if not np.allclose(Y_glow, Y_c2):
101
diff_Y = np.abs(Y_glow - Y_c2)
102
print_test_debug_info(
107
"batch_size": batch_size,
111
"elementwise_affine": elementwise_affine,
120
def _get_scale_zp(self, tensor):
121
tensor_max = np.max(tensor)
122
tensor_min = min(0, np.min(tensor))
123
scale = np.float32(np.float16((tensor_max - tensor_min) / 255.0))
125
scale = np.float32(1e-6)
126
zero_point = 0 - tensor_min / scale
127
zero_point = int(round(np.clip(zero_point, 0, 255.0)))
128
return (scale, zero_point)
130
def _layernorm_transform(self, X):
131
mean = np.mean(X, axis=1)
132
mean_exp = np.outer(mean, np.ones(X.shape[1]))
133
std = np.std(X, axis=1)
134
std_exp = np.outer(std, np.ones(X.shape[1]))
135
Y = (X - mean_exp) / std_exp
138
@given(seed=st.integers(0, 65535),
139
batch_size=st.integers(min_value=1, max_value=50),
140
size=st.integers(min_value=2, max_value=128),
141
epsilon=st.floats(min_value=1e-4, max_value=1e-3),
142
elementwise_affine=st.booleans())
143
@settings(deadline=datetime.timedelta(seconds=10))
144
# re-enable when T74553975 gets fixed
145
def test_fused_ln_quantize(self, seed, batch_size, size, epsilon, elementwise_affine):
148
# Reset the workspace
149
workspace.ResetWorkspace()
152
dims = np.array(([batch_size, size]))
153
X = np.random.uniform(size=dims).astype(np.float32) - 0.5
154
gamma = np.random.randn(*X.shape[axis:]).astype(np.float32)
155
beta = np.random.randn(*X.shape[axis:]).astype(np.float32)
157
Y = self._layernorm_transform(X)
158
scale, zp = self._get_scale_zp(Y)
160
pred_net = caffe2_pb2.NetDef()
161
pred_net.name = "pred"
162
pred_net.external_input.extend(["X", "gamma", "beta"])
163
pred_net.external_output.extend(["Y_q"])
164
pred_net.op.add().CopyFrom(
167
["X", "gamma", "beta"] if elementwise_affine else ["X"],
168
["Y", "mean", "rstd"],
171
elementwise_affine=elementwise_affine
174
pred_net.op.add().CopyFrom(
176
"Int8Quantize", ["Y"], ["Y_q"], Y_scale=scale, Y_zero_point=zp
181
pred_net_ref = caffe2_pb2.NetDef()
182
pred_net_ref.name = "pred_ref"
183
pred_net_ref.external_input.extend(["X", "gamma", "beta"])
184
pred_net_ref.external_output.extend(["Y_q"])
185
pred_net_ref.op.add().CopyFrom(
187
"LayerNormInt8QuantizeFakeNNPI",
188
["X", "gamma", "beta"] if elementwise_affine else ["X"],
189
["Y_q", "mean", "rstd"],
192
elementwise_affine=elementwise_affine,
193
Y_scale=scale, Y_zero_point=zp
196
shape_hits = {"X": X.shape, "gamma": gamma.shape, "beta": beta.shape}
197
pred_net_onnxified = onnxifi_caffe2_net(
204
num_onnxified_ops = sum(
205
1 if o.type == "Onnxifi" else 0 for o in pred_net_onnxified.op)
206
np.testing.assert_equal(num_onnxified_ops, 1)
208
workspace.FeedBlob("X", X)
209
workspace.FeedBlob("gamma", gamma)
210
workspace.FeedBlob("beta", beta)
212
workspace.CreateNet(pred_net_ref)
213
workspace.CreateNet(pred_net_onnxified)
215
workspace.RunNet(pred_net_ref.name)
216
Y_c2 = workspace.FetchInt8Blob("Y_q")
218
workspace.RunNet(pred_net_onnxified.name)
219
Y_glow = workspace.FetchInt8Blob("Y_q")
221
if not np.allclose(Y_glow.data, Y_c2.data) or \
222
Y_glow.scale != Y_c2.scale or Y_glow.zero_point != Y_c2.zero_point:
223
diff_Y = np.abs(Y_glow.data.astype(np.float32) - Y_c2.data.astype(np.float32))
224
print_test_debug_info(
229
"batch_size": batch_size,
233
"elementwise_affine": elementwise_affine,