pytorch
400 строк · 16.0 Кб
1
2
3
4
5from caffe2.python import core6import caffe2.python.hypothesis_test_util as hu7import caffe2.python.serialized_test.serialized_test_util as serial8from hypothesis import assume, given, settings9import hypothesis.strategies as st10import numpy as np11
12
13class TestBooleanMaskOp(serial.SerializedTestCase):14@given(x=hu.tensor1d(min_len=1,15max_len=100,16elements=hu.floats(min_value=0.5, max_value=1.0)),17**hu.gcs_cpu_only)18@settings(deadline=10000)19def test_boolean_mask_gradient(self, x, gc, dc):20op = core.CreateOperator("BooleanMask",21["data", "mask"],22"masked_data")23mask = np.random.choice(a=[True, False], size=x.shape[0])24expected_gradient = np.copy(mask).astype(int)25self.assertDeviceChecks(dc, op, [x, mask], [0])26self.assertGradientChecks(gc, op, [x, mask], 0, [0])27
28
29@given(x=hu.tensor1d(min_len=1,30max_len=5,31elements=hu.floats(min_value=0.5, max_value=1.0)),32**hu.gcs)33@settings(deadline=10000)34def test_boolean_mask(self, x, gc, dc):35op = core.CreateOperator("BooleanMask",36["data", "mask"],37"masked_data")38mask = np.random.choice(a=[True, False], size=x.shape[0])39
40def ref(x, mask):41return (x[mask],)42self.assertReferenceChecks(gc, op, [x, mask], ref)43self.assertDeviceChecks(dc, op, [x, mask], [0])44
45@given(x=hu.tensor1d(min_len=1,46max_len=5,47elements=hu.floats(min_value=0.5, max_value=1.0)),48**hu.gcs)49def test_boolean_mask_indices(self, x, gc, dc):50op = core.CreateOperator("BooleanMask",51["data", "mask"],52["masked_data", "masked_indices"])53mask = np.random.choice(a=[True, False], size=x.shape[0])54
55def ref(x, mask):56return (x[mask], np.where(mask)[0])57
58self.assertReferenceChecks(gc, op, [x, mask], ref)59self.assertDeviceChecks(dc, op, [x, mask], [0])60
61@staticmethod62def _dtype_conversion(x, dtype, gc, dc):63"""SequenceMask only supports fp16 with CUDA/ROCm."""64if dtype == np.float16:65assume(core.IsGPUDeviceType(gc.device_type))66dc = [d for d in dc if core.IsGPUDeviceType(d.device_type)]67x = x.astype(dtype)68return x, dc69
70@given(x=hu.tensor(min_dim=2,71max_dim=5,72elements=hu.floats(min_value=0.5, max_value=1.0)),73dtype=st.sampled_from([np.float32, np.float16]),74**hu.gcs)75def test_sequence_mask_with_lengths(self, x, dtype, gc, dc):76x, dc = self._dtype_conversion(x, dtype, gc, dc)77# finite fill value needed for gradient check78fill_val = 1e-3 if dtype == np.float16 else 1e-979op = core.CreateOperator("SequenceMask",80["data", "lengths"],81["masked_data"],82mode="sequence",83axis=len(x.shape) - 1,84fill_val=fill_val)85elem_dim = x.shape[-1]86leading_dim = 187for dim in x.shape[:-1]:88leading_dim *= dim89lengths = np.random.randint(0, elem_dim, [leading_dim])\90.astype(np.int32)91
92def ref(x, lengths):93ref = np.reshape(x, [leading_dim, elem_dim])94for i in range(leading_dim):95for j in range(elem_dim):96if j >= lengths[i]:97ref[i, j] = fill_val98return [ref.reshape(x.shape)]99
100self.assertReferenceChecks(gc, op, [x, lengths], ref)101self.assertDeviceChecks(dc, op, [x, lengths], [0])102
103@given(x=hu.tensor(min_dim=2,104max_dim=5,105elements=hu.floats(min_value=0.5, max_value=1.0)),106dtype=st.sampled_from([np.float32, np.float16]),107**hu.gcs)108@settings(deadline=10000)109def test_sequence_mask_with_window(self, x, dtype, gc, dc):110x, dc = self._dtype_conversion(x, dtype, gc, dc)111# finite fill value needed for gradient check112fill_val = 1e-3 if dtype == np.float16 else 1e-9113radius = 2114op = core.CreateOperator("SequenceMask",115["data", "centers"],116["masked_data"],117mode="window",118radius=radius,119axis=len(x.shape) - 1,120fill_val=fill_val)121elem_dim = x.shape[-1]122leading_dim = 1123for dim in x.shape[:-1]:124leading_dim *= dim125centers = np.random.randint(0, elem_dim, [leading_dim])\126.astype(np.int32)127
128def ref(x, centers):129ref = np.reshape(x, [leading_dim, elem_dim])130for i in range(leading_dim):131for j in range(elem_dim):132if j > centers[i] + radius or j < centers[i] - radius:133ref[i, j] = fill_val134return [ref.reshape(x.shape)]135
136self.assertReferenceChecks(gc, op, [x, centers], ref)137self.assertDeviceChecks(dc, op, [x, centers], [0])138
139# Gradient check with np.float16 is found to be flakey, disable for now140# with high threshold (to repro, set threshold to 0.4).141threshold = 1.0 if dtype == np.float16 else 0.005142self.assertGradientChecks(gc, op, [x, centers], 0, [0],143threshold=threshold)144
145@given(x=hu.tensor(min_dim=2,146max_dim=5,147elements=hu.floats(min_value=0.5, max_value=1.0)),148mode=st.sampled_from(['upper', 'lower', 'upperdiag', 'lowerdiag']),149dtype=st.sampled_from([np.float32, np.float16]),150**hu.gcs)151@settings(deadline=10000)152def test_sequence_mask_triangle(self, x, mode, dtype, gc, dc):153x, dc = self._dtype_conversion(x, dtype, gc, dc)154# finite fill value needed for gradient check155fill_val = 1e-3 if dtype == np.float16 else 1e-9156op = core.CreateOperator("SequenceMask",157["data"],158["masked_data"],159mode=mode,160axis=len(x.shape) - 1,161fill_val=fill_val)162elem_dim = x.shape[-1]163leading_dim = 1164for dim in x.shape[:-1]:165leading_dim *= dim166
167if mode == 'upper':168def compare(i, j):169return j > i170elif mode == 'lower':171def compare(i, j):172return j < i173elif mode == 'upperdiag':174def compare(i, j):175return j >= i176elif mode == 'lowerdiag':177def compare(i, j):178return j <= i179
180def ref(x):181ref = np.reshape(x, [leading_dim, elem_dim])182for i in range(leading_dim):183for j in range(elem_dim):184if compare(i, j):185ref[i, j] = fill_val186return [ref.reshape(x.shape)]187
188self.assertReferenceChecks(gc, op, [x], ref)189self.assertDeviceChecks(dc, op, [x], [0])190
191# Gradient check with np.float16 is found to be flakey, disable for now192# with high threshold (to repro, set threshold to 0.4).193threshold = 1.0 if dtype == np.float16 else 0.005194stepsize = 0.1 if dtype == np.float16 else 0.05195self.assertGradientChecks(gc, op, [x], 0, [0],196threshold=threshold, stepsize=stepsize)197
198@given(x=hu.tensor(min_dim=2,199max_dim=5,200elements=hu.floats(min_value=0.5, max_value=1.0)),201dtype=st.sampled_from([np.float32, np.float16]),202**hu.gcs)203@settings(deadline=10000)204def test_sequence_mask_batching_lengths(self, x, dtype, gc, dc):205x, dc = self._dtype_conversion(x, dtype, gc, dc)206# finite fill value needed for gradient check207fill_val = 1e-3 if dtype == np.float16 else 1e-9208# choose _different_ batch and axis dimensions, w/ axis != 0.209axis = 0210batch = 0211while axis == 0 or axis < batch:212inds = np.arange(len(x.shape))213np.random.shuffle(inds)214batch = inds[0]215axis = inds[1]216op = core.CreateOperator("SequenceMask",217["data", "lengths"],218["masked_data"],219mode='sequence',220axis=axis,221fill_val=fill_val,222batch=batch)223
224before = int(np.prod(x.shape[:batch + 1]))225between = int(np.prod(x.shape[batch + 1:axis]))226after = int(np.prod(x.shape[axis:]))227
228lengths = np.random.randint(0, after, [between])\229.astype(np.int32)230
231def ref(z, l):232w = np.reshape(z, [before, between, after])233
234for b in range(before):235r = w[b, :, :]236for i in range(between):237for j in range(after):238if j >= l[i]:239r[i, j] = fill_val240return [w.reshape(z.shape)]241
242self.assertReferenceChecks(gc, op, [x, lengths], ref)243self.assertDeviceChecks(dc, op, [x, lengths], [0])244
245# Gradient check with np.float16 is found to be flakey, disable for now246# with high threshold (to repro, set threshold to 0.4).247threshold = 1.0 if dtype == np.float16 else 0.005248self.assertGradientChecks(gc, op, [x, lengths], 0, [0],249threshold=threshold)250
251@given(x=hu.tensor(min_dim=4,252max_dim=4,253elements=hu.floats(min_value=0.5, max_value=1.0)),254dtype=st.sampled_from([np.float32, np.float16]),255**hu.gcs)256@settings(deadline=10000)257def test_sequence_mask_batching_window(self, x, dtype, gc, dc):258x, dc = self._dtype_conversion(x, dtype, gc, dc)259# finite fill value needed for gradient check260fill_val = 1e-3 if dtype == np.float16 else 1e-9261radius = 1262# choose _different_ batch and axis dimensions, w/ axis != 0.263axis = 0264batch = 0265while axis == 0 or axis < batch:266inds = np.arange(len(x.shape))267np.random.shuffle(inds)268batch = inds[0]269axis = inds[1]270op = core.CreateOperator("SequenceMask",271["data", "centers"],272["masked_data"],273mode='window',274radius=radius,275axis=axis,276fill_val=fill_val,277batch=batch)278
279before = int(np.prod(x.shape[:batch + 1]))280between = int(np.prod(x.shape[batch + 1:axis]))281after = int(np.prod(x.shape[axis:]))282
283centers = np.random.randint(0, after, [between])\284.astype(np.int32)285
286def ref(z, c):287w = np.reshape(z, [before, between, after])288
289for b in range(before):290r = w[b, :, :]291for i in range(between):292for j in range(after):293if j > c[i] + radius or j < c[i] - radius:294r[i, j] = fill_val295return [w.reshape(z.shape)]296
297self.assertReferenceChecks(gc, op, [x, centers], ref)298self.assertDeviceChecks(dc, op, [x, centers], [0])299
300# Gradient check with np.float16 is found to be flakey, disable for now301# with high threshold (to repro, set threshold to 0.4).302threshold = 1.0 if dtype == np.float16 else 0.005303self.assertGradientChecks(gc, op, [x, centers], 0, [0],304threshold=threshold)305
306@given(x=hu.tensor(min_dim=3,307max_dim=5,308elements=hu.floats(min_value=0.5, max_value=1.0)),309mode=st.sampled_from(['upper', 'lower', 'upperdiag', 'lowerdiag']),310dtype=st.sampled_from([np.float32, np.float16]),311**hu.gcs)312@settings(deadline=10000)313def test_sequence_mask_batching_triangle(self, x, mode, dtype, gc, dc):314x, dc = self._dtype_conversion(x, dtype, gc, dc)315# finite fill value needed for gradient check316fill_val = 1e-3 if dtype == np.float16 else 1e-9317# choose _different_ batch and axis dimensions, w/ axis != 0.318axis = 0319batch = 0320while axis == 0 or axis < batch:321inds = np.arange(len(x.shape))322np.random.shuffle(inds)323batch = inds[0]324axis = inds[1]325op = core.CreateOperator("SequenceMask",326["data"],327["masked_data"],328mode=mode,329axis=axis,330fill_val=fill_val,331batch=batch)332
333if mode == 'upper':334def compare(i, j):335return j > i336elif mode == 'lower':337def compare(i, j):338return j < i339elif mode == 'upperdiag':340def compare(i, j):341return j >= i342elif mode == 'lowerdiag':343def compare(i, j):344return j <= i345
346def ref(z):347before = int(np.prod(z.shape[:batch + 1]))348between = int(np.prod(z.shape[batch + 1:axis]))349after = int(np.prod(z.shape[axis:]))350
351w = np.reshape(z, [before, between, after])352
353for b in range(before):354r = w[b, :, :]355for i in range(between):356for j in range(after):357if compare(i, j):358r[i, j] = fill_val359return [w.reshape(z.shape)]360
361self.assertReferenceChecks(gc, op, [x], ref)362self.assertDeviceChecks(dc, op, [x], [0])363
364# Gradient check with np.float16 is found to be flakey, disable for now365# with high threshold (to repro, set threshold to 0.4).366threshold = 1.0 if dtype == np.float16 else 0.005367stepsize = 0.1 if dtype == np.float16 else 0.05368self.assertGradientChecks(gc, op, [x], 0, [0],369threshold=threshold, stepsize=stepsize)370
371@given(x=hu.tensor(min_dim=3,372max_dim=5,373elements=hu.floats(min_value=0.5, max_value=1.0)),374dtype=st.sampled_from([np.float32, np.float16]),375**hu.gcs)376def test_sequence_mask_repeated(self, x, dtype, gc, dc):377x, dc = self._dtype_conversion(x, dtype, gc, dc)378# finite fill value needed for gradient check379fill_val = 1e-3 if dtype == np.float16 else 1e-9380op = core.CreateOperator("SequenceMask",381["data", "lengths"],382["masked_data"],383mode="sequence",384axis=len(x.shape) - 2,385repeat_from_axis=-1,386fill_val=fill_val)387
388elem_dim = x.shape[-2]389leading_dim = 1390for dim in x.shape[:-2]:391leading_dim *= dim392lengths = np.random.randint(0, elem_dim, [leading_dim])\393.astype(np.int32)394
395def ref(x, lengths):396ref = np.reshape(x, [leading_dim, elem_dim, -1])397for i in range(leading_dim):398for j in range(elem_dim):399if j >= lengths[i]:400ref[i, j, :] = fill_val401return [ref.reshape(x.shape)]402
403self.assertReferenceChecks(gc, op, [x, lengths], ref)404self.assertDeviceChecks(dc, op, [x, lengths], [0])405