Caffe2 - Python API
A deep learning, cross platform ML framework
test_pytorch_onnx_caffe2.py
1 from __future__ import absolute_import
2 from __future__ import division
3 from __future__ import print_function
4 from __future__ import unicode_literals
5 
6 from functools import wraps
7 import numpy as np
8 import sys
9 import unittest
10 import itertools
11 
12 import torch.onnx
14 from torch import nn
15 from torch.autograd import Variable, function
16 import torch.utils.model_zoo as model_zoo
17 from torch.nn.utils import rnn as rnn_utils
18 from debug_embed_params import run_embed_params
19 import io
20 
21 # Import various models for testing
22 from torchvision.models.alexnet import alexnet
23 from torchvision.models.inception import inception_v3
24 from torchvision.models.densenet import densenet121
25 from torchvision.models.resnet import resnet50
26 from torchvision.models.vgg import vgg16, vgg16_bn, vgg19, vgg19_bn
27 
28 from model_defs.squeezenet import SqueezeNet
29 from model_defs.super_resolution import SuperResolutionNet
30 from model_defs.srresnet import SRResNet
31 import model_defs.dcgan as dcgan
32 import model_defs.word_language_model as word_language_model
33 from model_defs.mnist import MNIST
34 from model_defs.lstm_flattening_result import LstmFlatteningResult
35 from model_defs.rnn_model_with_packed_sequence import RnnModelWithPackedSequence
36 
37 import onnx
38 import caffe2.python.onnx.backend as c2
39 
40 from test_pytorch_common import skipIfTravis, skipIfNoLapack, skipIfNoCuda
41 import verify
42 
43 skip = unittest.skip
44 
45 
46 def skipIfEmbed(func):
47  def wrapper(self):
48  if self.embed_params:
49  raise unittest.SkipTest("Skip embed_params verify test")
50  return func(self)
51  return wrapper
52 
53 
54 # def import_model(proto, input, workspace=None, use_gpu=True):
55 # model_def = onnx.ModelProto.FromString(proto)
56 # onnx.checker.check_model(model_def)
57 #
58 # if workspace is None:
59 # workspace = {}
60 # if isinstance(input, tuple):
61 # for i in range(len(input)):
62 # workspace[model_def.graph.input[i]] = input[i]
63 # else:
64 # workspace[model_def.graph.input[0]] = input
65 #
66 # caffe2_out_workspace = c2.run_model(
67 # init_graph=None,
68 # predict_graph=graph_def,
69 # inputs=workspace,
70 # use_gpu=use_gpu)
71 # caffe2_out = caffe2_out_workspace[0]
72 # return caffe2_out
73 
74 
75 def do_export(model, inputs, *args, **kwargs):
76  f = io.BytesIO()
77  out = torch.onnx._export(model, inputs, f, *args, **kwargs)
78  return f.getvalue(), out
79 
80 
81 torch.set_default_tensor_type('torch.FloatTensor')
82 try:
83  import torch
84 except ImportError:
85  print('Cannot import torch, hence caffe2-torch test will not run.')
86  sys.exit(0)
87 
88 
89 BATCH_SIZE = 2
90 
91 RNN_BATCH_SIZE = 7
92 RNN_SEQUENCE_LENGTH = 11
93 RNN_INPUT_SIZE = 5
94 RNN_HIDDEN_SIZE = 3
95 
96 model_urls = {
97  'alexnet': 'https://download.pytorch.org/models/alexnet-owt-4df8aa71.pth',
98  'dcgan_b': 'https://s3.amazonaws.com/pytorch/test_data/export/netG_bedroom_epoch_1-0649e76b.pth',
99  'dcgan_f': 'https://s3.amazonaws.com/pytorch/test_data/export/netG_faces_epoch_49-d86035a6.pth',
100  'densenet121': 'https://download.pytorch.org/models/densenet121-d66d3027.pth',
101  'inception_v3_google': 'https://download.pytorch.org/models/inception_v3_google-1a9a5a14.pth',
102  'resnet50': 'https://download.pytorch.org/models/resnet50-19c8e357.pth',
103  'srresNet': 'https://s3.amazonaws.com/pytorch/demos/srresnet-e10b2039.pth',
104  'super_resolution': 'https://s3.amazonaws.com/pytorch/test_data/export/superres_epoch100-44c6958e.pth',
105  'squeezenet1_0': 'https://download.pytorch.org/models/squeezenet1_0-a815701f.pth',
106  'squeezenet1_1': 'https://download.pytorch.org/models/squeezenet1_1-f364aa15.pth',
107  'vgg16': 'https://download.pytorch.org/models/vgg16-397923af.pth',
108  'vgg19': 'https://download.pytorch.org/models/vgg19-dcbb9e9d.pth',
109 }
110 
111 
112 class TestCaffe2Backend(unittest.TestCase):
113  embed_params = False
114 
115  def setUp(self):
116  torch.manual_seed(0)
118  torch.cuda.manual_seed_all(0)
119  np.random.seed(seed=0)
120 
121  def convert_cuda(self, model, input):
122  cuda_model = model.cuda()
123  # input might be nested - we want to move everything to GPU
124  cuda_input = function._nested_map(
125  lambda o: isinstance(o, Variable) or torch.is_tensor(o),
126  lambda o: o.cuda())(input)
127  return cuda_model, cuda_input
128 
129  def run_debug_test(self, model, train, batch_size, state_dict=None,
130  input=None, use_gpu=True, example_outputs=None):
131  """
132  # TODO: remove this from the final release version
133  This test is for our debugging only for the case where
134  embed_params=False
135  """
136  if not isinstance(model, torch.jit.ScriptModule):
137  model.train(train)
138  if state_dict is not None:
139  model.load_state_dict(state_dict)
140 
141  # Either user specified input or random (deterministic) input
142  if input is None:
143  input = torch.randn(batch_size, 3, 224, 224, requires_grad=True)
144  if use_gpu:
145  model, input = self.convert_cuda(model, input)
146 
147  onnxir, torch_out = do_export(model, input, export_params=self.embed_params, verbose=False,
148  example_outputs=example_outputs)
149  if isinstance(torch_out, torch.autograd.Variable):
150  torch_out = (torch_out,)
151 
152  caffe2_out = run_embed_params(onnxir, model, input, state_dict, use_gpu)
153  for _, (x, y) in enumerate(zip(torch_out, caffe2_out)):
154  np.testing.assert_almost_equal(x.data.cpu().numpy(), y, decimal=3)
155 
156  def run_actual_test(self, model, train, batch_size, state_dict=None,
157  input=None, use_gpu=True, rtol=0.001, atol=1e-7,
158  example_outputs=None):
159  """
160  This is what the user facing version will look like
161  """
162  # set the training/test mode for the model
163  if not isinstance(model, torch.jit.ScriptModule):
164  model.train(train)
165  # use the pre-trained model params if available
166  if state_dict is not None:
167  model.load_state_dict(state_dict)
168 
169  # Either user specified input or random (deterministic) input
170  if input is None:
171  input = torch.randn(batch_size, 3, 224, 224, requires_grad=True)
172  # GPU-ize the model, if requested
173  if use_gpu:
174  model, input = self.convert_cuda(model, input)
175 
176  # Verify the model runs the same in Caffe2
177  verify.verify(model, input, c2, rtol=rtol, atol=atol)
178 
179  def run_model_test(self, model, train, batch_size, state_dict=None,
180  input=None, use_gpu=True, rtol=0.001, atol=1e-7,
181  example_outputs=None):
182  use_gpu_ = torch.cuda.is_available() and use_gpu
183  if self.embed_params:
184  self.run_actual_test(model, train, batch_size, state_dict, input,
185  use_gpu=use_gpu_, rtol=rtol, atol=atol,
186  example_outputs=example_outputs)
187  else:
188  self.run_debug_test(model, train, batch_size, state_dict, input,
189  use_gpu=use_gpu_, example_outputs=example_outputs)
190 
191  def test_linear(self):
192  class MyModel(torch.nn.Module):
193  def __init__(self):
194  super(MyModel, self).__init__()
195  self.many_fc = nn.Sequential(
196  nn.Linear(4, 5, bias=True),
197  nn.ReLU(inplace=True),
198  nn.Linear(5, 6, bias=True),
199  nn.ReLU(inplace=True),
200  nn.Linear(6, 7, bias=True),
201  )
202 
203  def forward(self, input):
204  return self.many_fc(input)
205 
206  model = MyModel()
207  input = torch.randn(3, 4, requires_grad=True)
208  self.run_model_test(model, train=False, batch_size=0, input=input)
209 
210  def test_lstm_cell(self):
211  model = nn.LSTMCell(RNN_INPUT_SIZE, RNN_HIDDEN_SIZE)
212  input = torch.randn(BATCH_SIZE, RNN_INPUT_SIZE)
213  h0 = torch.randn(BATCH_SIZE, RNN_HIDDEN_SIZE)
214  c0 = torch.randn(BATCH_SIZE, RNN_HIDDEN_SIZE)
215  self.run_model_test(model, train=False, batch_size=BATCH_SIZE, input=(input, (h0, c0)), use_gpu=False)
216 
217  def test_gru_cell(self):
218  model = nn.GRUCell(RNN_INPUT_SIZE, RNN_HIDDEN_SIZE)
219  input = torch.randn(BATCH_SIZE, RNN_INPUT_SIZE)
220  h0 = torch.randn(BATCH_SIZE, RNN_HIDDEN_SIZE)
221  self.run_model_test(model, train=False, batch_size=BATCH_SIZE, input=(input, h0), use_gpu=False)
222 
223  def _dispatch_rnn_test(self, name, *args, **kwargs):
224  if name == 'elman':
225  self._elman_rnn_test(*args, **kwargs)
226  if name == 'lstm':
227  self._lstm_test(*args, **kwargs)
228  if name == 'gru':
229  self._gru_test(*args, **kwargs)
230 
231  def _elman_rnn_test(self, layers, nonlinearity, bidirectional,
232  initial_state, packed_sequence, dropout):
233  model = nn.RNN(RNN_INPUT_SIZE, RNN_HIDDEN_SIZE,
234  layers,
235  nonlinearity=nonlinearity,
236  bidirectional=bidirectional,
237  dropout=dropout)
238 
239  if packed_sequence == 1:
240  model = RnnModelWithPackedSequence(model, False)
241  if packed_sequence == 2:
242  model = RnnModelWithPackedSequence(model, True)
243 
244  def make_input(batch_size):
245  seq_lengths = np.random.randint(1, RNN_SEQUENCE_LENGTH + 1, size=batch_size)
246  seq_lengths = list(reversed(sorted(map(int, seq_lengths))))
247  inputs = [torch.randn(l, RNN_INPUT_SIZE) for l in seq_lengths]
248  inputs = rnn_utils.pad_sequence(inputs)
249  if packed_sequence == 2:
250  inputs = inputs.transpose(0, 1)
251  inputs = [inputs]
252 
253  directions = 2 if bidirectional else 1
254 
255  if initial_state:
256  h0 = torch.randn(directions * layers, batch_size, RNN_HIDDEN_SIZE)
257  inputs.append(h0)
258  if packed_sequence != 0:
259  inputs.append(torch.IntTensor(seq_lengths))
260  if len(inputs) == 1:
261  input = inputs[0]
262  else:
263  input = tuple(inputs)
264  return input
265 
266  input = make_input(RNN_BATCH_SIZE)
267  self.run_model_test(model, train=False, batch_size=RNN_BATCH_SIZE, input=input, use_gpu=False, atol=1e-7)
268 
269  # test that the model still runs with a different batch size
270  onnxir, _ = do_export(model, input)
271  other_input = make_input(RNN_BATCH_SIZE + 1)
272  _ = run_embed_params(onnxir, model, other_input, use_gpu=False)
273 
274  def _lstm_test(self, layers, bidirectional, initial_state,
275  packed_sequence, dropout):
276  model = LstmFlatteningResult(
277  RNN_INPUT_SIZE, RNN_HIDDEN_SIZE, layers,
278  bidirectional=bidirectional, dropout=dropout)
279  if packed_sequence == 1:
280  model = RnnModelWithPackedSequence(model, False)
281  if packed_sequence == 2:
282  model = RnnModelWithPackedSequence(model, True)
283 
284  def make_input(batch_size):
285  seq_lengths = np.random.randint(1, RNN_SEQUENCE_LENGTH + 1, size=batch_size)
286  seq_lengths = list(reversed(sorted(map(int, seq_lengths))))
287  inputs = [torch.randn(l, RNN_INPUT_SIZE) for l in seq_lengths]
288  inputs = rnn_utils.pad_sequence(inputs)
289  if packed_sequence == 2:
290  inputs = inputs.transpose(0, 1)
291  inputs = [inputs]
292 
293  directions = 2 if bidirectional else 1
294 
295  if initial_state:
296  h0 = torch.randn(directions * layers, batch_size, RNN_HIDDEN_SIZE)
297  c0 = torch.randn(directions * layers, batch_size, RNN_HIDDEN_SIZE)
298  inputs.append((h0, c0))
299  if packed_sequence != 0:
300  inputs.append(torch.IntTensor(seq_lengths))
301  if len(inputs) == 1:
302  input = inputs[0]
303  else:
304  input = tuple(inputs)
305  return input
306 
307  input = make_input(RNN_BATCH_SIZE)
308  self.run_model_test(model, train=False, batch_size=RNN_BATCH_SIZE, input=input, use_gpu=False)
309 
310  # test that the model still runs with a different batch size
311  onnxir, _ = do_export(model, input)
312  other_input = make_input(RNN_BATCH_SIZE + 1)
313  _ = run_embed_params(onnxir, model, other_input, use_gpu=False)
314 
315  def _gru_test(self, layers, bidirectional, initial_state,
316  packed_sequence, dropout):
317  model = nn.GRU(RNN_INPUT_SIZE, RNN_HIDDEN_SIZE, layers,
318  bidirectional=bidirectional, dropout=dropout)
319  if packed_sequence == 1:
320  model = RnnModelWithPackedSequence(model, False)
321  if packed_sequence == 2:
322  model = RnnModelWithPackedSequence(model, True)
323 
324  def make_input(batch_size):
325  seq_lengths = np.random.randint(1, RNN_SEQUENCE_LENGTH + 1, size=batch_size)
326  seq_lengths = list(reversed(sorted(map(int, seq_lengths))))
327  inputs = [torch.randn(l, RNN_INPUT_SIZE) for l in seq_lengths]
328  inputs = rnn_utils.pad_sequence(inputs)
329  if packed_sequence == 2:
330  inputs = inputs.transpose(0, 1)
331  inputs = [inputs]
332 
333  directions = 2 if bidirectional else 1
334 
335  if initial_state:
336  h0 = torch.randn(directions * layers, batch_size, RNN_HIDDEN_SIZE)
337  inputs.append(h0)
338  if packed_sequence != 0:
339  inputs.append(torch.IntTensor(seq_lengths))
340  if len(inputs) == 1:
341  input = inputs[0]
342  else:
343  input = tuple(inputs)
344  return input
345 
346  input = make_input(RNN_BATCH_SIZE)
347  self.run_model_test(model, train=False, batch_size=RNN_BATCH_SIZE, input=input, use_gpu=False)
348 
349  # test that the model still runs with a different batch size
350  onnxir, _ = do_export(model, input)
351  other_input = make_input(RNN_BATCH_SIZE + 1)
352  _ = run_embed_params(onnxir, model, other_input, use_gpu=False)
353 
354  def test_rnn_init_predict_split(self):
355  model = nn.LSTM(RNN_INPUT_SIZE, RNN_HIDDEN_SIZE, 3, bidirectional=True)
356  seq_lengths = np.random.randint(1, RNN_SEQUENCE_LENGTH + 1, size=7)
357  seq_lengths = list(reversed(sorted(map(int, seq_lengths))))
358  input = [torch.randn(l, RNN_INPUT_SIZE) for l in seq_lengths]
359  input = rnn_utils.pad_sequence(input)
360 
361  # Test that we are correctly splitting between init and
362  # predict net. When we embed parameters, there should be more
363  # ops in the init net.
364  mp = onnx.ModelProto.FromString(do_export(model, input, export_params=self.embed_params)[0])
365  prepared = c2.prepare(mp, device='CPU')
366  if self.embed_params:
367  assert len(prepared.init_net.op) == 875
368  assert len(prepared.predict_net.op) == 130
369  else:
370  assert len(prepared.init_net.op) == 8
371  assert len(prepared.predict_net.op) == 997
372 
373  def test_alexnet(self):
374  state_dict = model_zoo.load_url(model_urls['alexnet'], progress=False)
375  self.run_model_test(alexnet(), train=False, batch_size=BATCH_SIZE,
376  state_dict=state_dict, atol=1e-3)
377 
378  @skipIfNoCuda
379  def test_dcgan(self):
380  # dcgan is flaky on some seeds, see:
381  # https://github.com/ProjectToffee/onnx/pull/70
382  torch.manual_seed(1)
384  torch.cuda.manual_seed_all(1)
385 
386  netD = dcgan._netD(1)
387  netD.apply(dcgan.weights_init)
388  input = torch.randn(BATCH_SIZE, 3, dcgan.imgsz, dcgan.imgsz)
389  self.run_model_test(netD, train=False, batch_size=BATCH_SIZE,
390  input=input)
391 
392  netG = dcgan._netG(1)
393  netG.apply(dcgan.weights_init)
394  state_dict = model_zoo.load_url(model_urls['dcgan_b'], progress=False)
395  # state_dict = model_zoo.load_url(model_urls['dcgan_f'], progress=False)
396  noise = torch.randn(BATCH_SIZE, dcgan.nz, 1, 1).normal_(0, 1)
397  self.run_model_test(netG, train=False, batch_size=BATCH_SIZE,
398  input=noise, state_dict=state_dict, rtol=1e-2, atol=1e-6)
399 
400  @unittest.skipIf(not torch.cuda.is_available(),
401  "model on net has cuda in it, awaiting fix")
402  def test_densenet(self):
403  state_dict = model_zoo.load_url(model_urls['densenet121'], progress=False)
404  self.run_model_test(densenet121(), train=False, batch_size=BATCH_SIZE,
405  state_dict=state_dict, atol=1e-7)
406 
407  @skip("doesn't match exactly...")
408  # TODO: figure out the numerical instabilities
409  def test_inception(self):
410  x = torch.randn(BATCH_SIZE, 3, 299, 299, requires_grad=True)
411  # state_dict = model_zoo.load_url(model_urls['inception_v3_google'], progress=False)
412  state_dict = None
413  self.run_model_test(inception_v3(), train=False, batch_size=BATCH_SIZE,
414  state_dict=state_dict, input=x)
415 
416  def test_resnet(self):
417  state_dict = model_zoo.load_url(model_urls['resnet50'], progress=False)
418  self.run_model_test(resnet50(), train=False, batch_size=BATCH_SIZE,
419  state_dict=state_dict, atol=1e-6)
420 
421  def test_squeezenet(self):
422  sqnet_v1_1 = SqueezeNet(version=1.1)
423  state_dict = model_zoo.load_url(model_urls['squeezenet1_1'], progress=False)
424  # state_dict = model_zoo.load_url(model_urls['squeezenet1_0'], progress=False)
425  self.run_model_test(sqnet_v1_1, train=False, batch_size=BATCH_SIZE,
426  state_dict=state_dict)
427 
428  # @skip('takes long to run, LAPACK needed for gpu')
429  @skipIfNoLapack
430  @unittest.skip("This model takes too much memory")
431  def test_srresnet(self):
432  super_resolution_net = SRResNet(
433  rescale_factor=4, n_filters=64, n_blocks=8)
434  state_dict = model_zoo.load_url(model_urls['srresNet'], progress=False)
435  x = torch.randn(1, 3, 224, 224, requires_grad=True)
436  self.run_model_test(super_resolution_net, train=False,
437  batch_size=1, state_dict=state_dict,
438  input=x, use_gpu=False)
439 
440  @skipIfTravis
441  @skipIfNoLapack
442  @skipIfNoCuda
443  def test_super_resolution(self):
444  super_resolution_net = SuperResolutionNet(upscale_factor=3)
445  state_dict = model_zoo.load_url(model_urls['super_resolution'], progress=False)
446  x = torch.randn(1, 1, 224, 224, requires_grad=True)
447  self.run_model_test(super_resolution_net, train=False,
448  batch_size=BATCH_SIZE, state_dict=state_dict,
449  input=x, use_gpu=False, atol=1e-6)
450 
451  @unittest.skip("This model takes too much memory")
452  def test_vgg16(self):
453  state_dict = model_zoo.load_url(model_urls['vgg16'], progress=False)
454  self.run_model_test(vgg16(), train=False, batch_size=BATCH_SIZE,
455  state_dict=state_dict)
456 
457  @skip("disable to run tests faster...")
458  def test_vgg16_bn(self):
459  self.run_model_test(vgg16_bn(), train=False,
460  batch_size=BATCH_SIZE)
461 
462  @skip("disable to run tests faster...")
463  def test_vgg19(self):
464  state_dict = model_zoo.load_url(model_urls['vgg19'], progress=False)
465  self.run_model_test(vgg19(), train=False, batch_size=BATCH_SIZE,
466  state_dict=state_dict)
467 
468  @skip("disable to run tests faster...")
469  def test_vgg19_bn(self):
470  self.run_model_test(vgg19_bn(), train=False,
471  batch_size=BATCH_SIZE)
472 
473  def run_word_language_model(self, model_name):
474  ntokens = 50
475  emsize = 5
476  nhid = 5
477  nlayers = 5
478  dropout = 0.2
479  tied = False
480  batchsize = 5
481  model = word_language_model.RNNModel(model_name, ntokens, emsize,
482  nhid, nlayers, dropout, tied,
483  batchsize)
484  x = torch.arange(0, ntokens).long().view(-1, batchsize)
485  # Only support CPU version, since tracer is not working in GPU RNN.
486  self.run_model_test(model, train=False, input=(x, model.hidden),
487  batch_size=batchsize, use_gpu=False)
488 
489  def test_word_language_model_RNN_TANH(self):
490  self.run_word_language_model("RNN_TANH")
491 
492  def test_word_language_model_RNN_RELU(self):
493  self.run_word_language_model("RNN_RELU")
494 
495  def test_word_language_model_LSTM(self):
496  self.run_word_language_model("LSTM")
497 
498  def test_word_language_model_GRU(self):
499  self.run_word_language_model("GRU")
500 
501  def test_batchnorm1d_special(self):
502  c = torch.randn(BATCH_SIZE, 224)
503  model = nn.BatchNorm1d(224)
504  self.run_model_test(model, train=True, input=c, batch_size=BATCH_SIZE)
505 
506  def test_batchnorm2d_noaffine(self):
507  c = torch.randn(128, 128, 1, 1)
508  model = nn.BatchNorm2d(128, affine=False)
509  self.run_model_test(model, train=False, input=c, batch_size=BATCH_SIZE)
510 
511  def test_constant(self):
512  c = torch.randn(BATCH_SIZE, 3, 224, 224)
513 
514  class MyModel(torch.nn.Module):
515  def __init__(self):
516  super(MyModel, self).__init__()
517 
518  def forward(self, input):
519  return input + c.type_as(input)
520 
521  self.run_model_test(MyModel(), train=False, batch_size=BATCH_SIZE)
522 
523  def test_consumed_bn(self):
524  underlying = nn.BatchNorm2d(3)
525  self.run_model_test(underlying, train=True, batch_size=BATCH_SIZE)
526 
527  def _test_index_generic(self, fn):
528  class MyModel(torch.nn.Module):
529  def __init__(self):
530  super(MyModel, self).__init__()
531 
532  def forward(self, input):
533  return fn(input)
534 
535  m1 = torch.randn(3, 4)
536  self.run_model_test(MyModel(), input=m1, train=False, batch_size=BATCH_SIZE)
537 
538  def test_index_1d(self):
539  self._test_index_generic(lambda input: input[0])
540 
541  def test_index_2d_1dimslice(self):
542  self._test_index_generic(lambda input: input[0:1, :])
543 
544  def test_index_2d_sliceint(self):
545  self._test_index_generic(lambda input: input[1, :])
546 
547  def test_index_2d_neg_slice(self):
548  self._test_index_generic(lambda input: input[0:-1, :])
549 
550  # TODO: Slicing along two dimensions is currently unsupported by the caffe2
551  # backend. Revisit if this becomes supported in the future.
552  """
553  def test_index_2d_2dimslice(self):
554  self._test_index_generic(lambda input: input[0:1, 0:1])
555  """
556  """
557  def test_index_2d_neg_slice2dim(self):
558  self._test_index_generic(lambda input: input[0:-1, 0:-1])
559  """
560 
561  def test_chunk(self):
562  class MyModel(torch.nn.Module):
563  def __init__(self):
564  super(MyModel, self).__init__()
565 
566  def forward(self, input):
567  # TODO: Why index? This returns a tuple and test runner doesn't
568  # support tuple comparison.
569  return input.chunk(8, dim=2)[-1]
570  self.run_model_test(MyModel(), train=False, batch_size=BATCH_SIZE)
571 
572  def test_sqrt(self):
573  class MyModel(torch.nn.Module):
574  def __init__(self):
575  super(MyModel, self).__init__()
576 
577  def forward(self, input):
578  return input.sqrt()
579  input = torch.empty(BATCH_SIZE, 10, 10).uniform_(4, 9)
580  self.run_model_test(MyModel(), train=False, input=input, batch_size=BATCH_SIZE)
581 
582  def test_log(self):
583  class MyModel(torch.nn.Module):
584  def __init__(self):
585  super(MyModel, self).__init__()
586 
587  def forward(self, input):
588  return input.log()
589  input = torch.empty(BATCH_SIZE, 10, 10).uniform_(4, 9)
590  self.run_model_test(MyModel(), train=False, input=input, batch_size=BATCH_SIZE)
591 
592  def test_erf(self):
593  class MyModel(torch.nn.Module):
594  def __init__(self):
595  super(MyModel, self).__init__()
596 
597  def forward(self, input):
598  return input.erf()
599  input = torch.empty(BATCH_SIZE, 10, 10).uniform_(4, 9)
600  self.run_model_test(MyModel(), train=False, input=input, batch_size=BATCH_SIZE)
601 
602  def test_trigonometry(self):
603  def test_func(name):
604  class MyModel(torch.nn.Module):
605  def __init__(self):
606  super(MyModel, self).__init__()
607 
608  def forward(self, input):
609  return getattr(input, name)()
610  input = torch.empty(BATCH_SIZE, 10, 10).uniform_()
611  self.run_model_test(MyModel(), train=False, input=input, batch_size=BATCH_SIZE)
612 
613  test_func('cos')
614  test_func('sin')
615  test_func('tan')
616  test_func('acos')
617  test_func('asin')
618  test_func('atan')
619 
620  def test_addconstant(self):
621  class MyModel(torch.nn.Module):
622  def __init__(self):
623  super(MyModel, self).__init__()
624 
625  def forward(self, input):
626  # TODO: Why index? This returns a tuple and test runner doesn't
627  # support tuple comparison.
628  return input + 1
629  self.run_model_test(MyModel(), train=False, batch_size=BATCH_SIZE)
630 
631  def test_subconstant(self):
632  class MyModel(torch.nn.Module):
633  def __init__(self):
634  super(MyModel, self).__init__()
635 
636  def forward(self, input):
637  # TODO: Why index? This returns a tuple and test runner doesn't
638  # support tuple comparison.
639  return input - 1
640  self.run_model_test(MyModel(), train=False, batch_size=BATCH_SIZE)
641 
642  def test_embedding(self):
643  model = nn.Embedding(10, 3, padding_idx=-1)
644  input = torch.LongTensor(list(range(10))[::-1])
645  self.run_model_test(model, train=False, input=input, batch_size=BATCH_SIZE)
646 
647  def test_constantpad2d(self):
648  model = nn.ConstantPad2d((1, 2, 3, 4), 3.5)
649  self.run_model_test(model, train=False, batch_size=BATCH_SIZE)
650 
651  def test_reflectionpad2d(self):
652  model = nn.ReflectionPad2d((1, 2, 3, 4))
653  self.run_model_test(model, train=False, batch_size=BATCH_SIZE)
654 
655  def test_replicationpad2d(self):
656  model = nn.ReplicationPad2d((1, 2, 3, 4))
657  self.run_model_test(model, train=False, batch_size=BATCH_SIZE)
658 
659  def test_maxpool2d(self):
660  model = nn.MaxPool2d(5, padding=(1, 2))
661  self.run_model_test(model, train=False, batch_size=BATCH_SIZE)
662 
663  def test_maxpool2d_single_padding(self):
664  model = nn.MaxPool2d(5, padding=2)
665  self.run_model_test(model, train=False, batch_size=BATCH_SIZE)
666 
667  def test_maxpool1d_ceil(self):
668  model = nn.MaxPool1d(3, 2, ceil_mode=True)
669  x = torch.randn(20, 16, 50, requires_grad=True)
670  self.run_model_test(model, train=False, input=x, batch_size=BATCH_SIZE)
671 
672  def test_maxpool2d_ceil(self):
673  model = nn.MaxPool2d(3, 2, ceil_mode=True)
674  x = torch.randn(20, 16, 50, 32, requires_grad=True)
675  self.run_model_test(model, train=False, input=x, batch_size=BATCH_SIZE)
676 
677  def test_maxpool3d_ceil(self):
678  model = nn.MaxPool3d(3, 2, ceil_mode=True)
679  x = torch.randn(20, 16, 50, 44, 31, requires_grad=True)
680  self.run_model_test(model, train=False, input=x, batch_size=BATCH_SIZE)
681 
682  @unittest.skip("C2 and PyTorch have small difference in padding implementation")
683  def test_avgpool2d(self):
684  model = nn.AvgPool2d(5, padding=(2))
685  self.run_model_test(model, train=False, batch_size=BATCH_SIZE)
686 
687  def test_avgpool2d_with_count_include_pad_set_false(self):
688  model = nn.AvgPool2d(7, padding=(2), count_include_pad=False)
689  self.run_model_test(model, train=False, batch_size=BATCH_SIZE)
690 
691  def test_avgpool2d_with_count_include_pad_set_true(self):
692  model = nn.AvgPool2d(7, padding=(2), count_include_pad=True)
693  self.run_model_test(model, train=False, batch_size=BATCH_SIZE)
694 
695  def test_avgpool2d_no_padding(self):
696  model = nn.AvgPool2d(5)
697  self.run_model_test(model, train=False, batch_size=BATCH_SIZE)
698 
699  def test_avg_pool1D_ceil(self):
700  model = torch.nn.AvgPool1d(3, 2, ceil_mode=True)
701  x = torch.randn(1, 1, 7, requires_grad=True)
702  self.run_model_test(model, train=False, input=x, batch_size=BATCH_SIZE)
703 
704  def test_avg_pool2D_ceil(self):
705  model = torch.nn.AvgPool2d(3, 2, ceil_mode=True)
706  x = torch.randn(20, 16, 50, 32, requires_grad=True)
707  self.run_model_test(model, train=False, input=x, batch_size=BATCH_SIZE)
708 
709  def test_avg_pool3D_ceil(self):
710  model = torch.nn.AvgPool3d(3, 2, ceil_mode=True)
711  x = torch.randn(20, 16, 50, 44, 31, requires_grad=True)
712  self.run_model_test(model, train=False, input=x, batch_size=BATCH_SIZE)
713 
714  def test_adaptive_avg_pool1D(self):
715  model = torch.nn.AdaptiveAvgPool1d((5))
716  x = torch.randn(20, 16, 50, requires_grad=True)
717  self.run_model_test(model, train=False, input=x, batch_size=BATCH_SIZE)
718 
719  def test_adaptive_avg_pool2D(self):
720  model = torch.nn.AdaptiveAvgPool2d((5, 4))
721  x = torch.randn(20, 16, 50, 32, requires_grad=True)
722  self.run_model_test(model, train=False, input=x, batch_size=BATCH_SIZE)
723 
724  def test_adaptive_avg_pool3D(self):
725  model = torch.nn.AdaptiveAvgPool3d((5, 4, 3))
726  x = torch.randn(20, 16, 50, 44, 30, requires_grad=True)
727  self.run_model_test(model, train=False, input=x, batch_size=BATCH_SIZE)
728 
729  def test_adaptive_max_pool1D(self):
730  model = torch.nn.AdaptiveMaxPool1d((5))
731  x = torch.randn(20, 16, 50, requires_grad=True)
732  self.run_model_test(model, train=False, input=x, batch_size=BATCH_SIZE)
733 
734  def test_adaptive_max_pool2D(self):
735  model = torch.nn.AdaptiveMaxPool2d((5, 4))
736  x = torch.randn(20, 16, 50, 32, requires_grad=True)
737  self.run_model_test(model, train=False, input=x, batch_size=BATCH_SIZE)
738 
739  def test_adaptive_max_pool3D(self):
740  model = torch.nn.AdaptiveMaxPool3d((5, 4, 3))
741  x = torch.randn(20, 16, 50, 44, 30, requires_grad=True)
742  self.run_model_test(model, train=False, input=x, batch_size=BATCH_SIZE)
743 
744  def test_weight_norm(self):
745  model = nn.utils.weight_norm(nn.Conv1d(1, 1, 3))
746  input = torch.randn(1, 1, 5, requires_grad=True)
747  self.run_model_test(
748  model, train=True, batch_size=0, input=input, use_gpu=False
749  )
750 
751  def test_mnist(self):
752  model = MNIST()
753  input = torch.randn(BATCH_SIZE, 1, 28, 28)
754  state_dict = None
755  # TODO: test with state_dict
756  self.run_model_test(model, train=False, input=input, batch_size=BATCH_SIZE,
757  state_dict=state_dict)
758 
759  def test_mm(self):
760  class MyModel(torch.nn.Module):
761  def __init__(self):
762  super(MyModel, self).__init__()
763 
764  def forward(self, m1, m2):
765  return torch.mm(m1, m2)
766  m1 = torch.randn(3, 4)
767  m2 = torch.randn(4, 5)
768  self.run_model_test(MyModel(), train=False, input=(m1, m2), batch_size=BATCH_SIZE, use_gpu=False)
769 
770  def test_addmm(self):
771  class MyModel(torch.nn.Module):
772  def __init__(self):
773  super(MyModel, self).__init__()
774 
775  def forward(self, ma, m1, m2):
776  return torch.addmm(ma, m1, m2)
777  ma = torch.randn(5)
778  m1 = torch.randn(3, 4)
779  m2 = torch.randn(4, 5)
780  self.run_model_test(MyModel(), train=False, input=(ma, m1, m2), batch_size=BATCH_SIZE, use_gpu=False)
781 
782  # test for a pytorch optimization pass, see https://github.com/pytorch/pytorch/pull/7872
783  def test_consecutive_transposes(self):
784  class MyModel(torch.nn.Module):
785  def __init__(self):
786  super(MyModel, self).__init__()
787 
788  def forward(self, x):
789  return x.transpose(1, 2).transpose(2, 3)
790  x = torch.randn(5, 6, 7, 8)
791  self.run_model_test(MyModel(), train=False, input=x, batch_size=BATCH_SIZE, use_gpu=False)
792 
793  def test_sum(self):
794  shape = (3, 4, 5)
795  for params in [{}] + [{'dim': i} for i in range(len(shape))]:
796  class MyModel(torch.nn.Module):
797  def __init__(self):
798  super(MyModel, self).__init__()
799 
800  def forward(self, x):
801  return torch.sum(x, **params)
802  x = torch.randn(*shape)
803  self.run_model_test(MyModel(), train=False, input=(x), batch_size=BATCH_SIZE, use_gpu=False)
804 
805  def test_cumsum(self):
806  shape = (3, 4, 5)
807  for params in [{'dim': i} for i in range(len(shape))]:
808  class MyModel(torch.nn.Module):
809  def __init__(self):
810  super(MyModel, self).__init__()
811 
812  def forward(self, x):
813  return torch.cumsum(x, **params)
814  x = torch.randn(*shape)
815  self.run_model_test(MyModel(), train=False, input=(x), batch_size=BATCH_SIZE, use_gpu=False)
816 
817  def test_layer_norm(self):
818  shape = (20, 5, 10, 10)
819 
820  class MyModel(torch.nn.Module):
821  def __init__(self):
822  super(MyModel, self).__init__()
823  self.ln = torch.nn.LayerNorm([5, 10, 10])
824 
825  def forward(self, x):
826  return self.ln(x)
827 
828  x = torch.randn(*shape)
829  self.run_model_test(MyModel(), train=False, input=(x,), batch_size=BATCH_SIZE, use_gpu=False)
830 
831  def test_repeat(self):
832  class MyModel(torch.nn.Module):
833  def __init__(self):
834  super(MyModel, self).__init__()
835 
836  def forward(self, x):
837  return x.repeat(1, 2, 3, 4)
838 
839  x = torch.randn(4, 3, 2, 1, requires_grad=True)
840  self.run_model_test(MyModel(), train=False, input=(x), batch_size=BATCH_SIZE, use_gpu=False)
841 
842  @unittest.skip("Temporary - waiting for https://github.com/onnx/onnx/pull/1773.")
843  def test_upsample(self):
844  x = torch.randn(1, 2, 3, 4, requires_grad=True)
845  model = nn.Upsample(scale_factor=2, mode='nearest')
846  self.run_model_test(model, train=False, input=(x),
847  batch_size=BATCH_SIZE, use_gpu=False)
848 
849  def test_repeat_dim_overflow(self):
850  class MyModel(torch.nn.Module):
851  def __init__(self):
852  super(MyModel, self).__init__()
853 
854  def forward(self, x):
855  return x.repeat(1, 2, 3, 4)
856 
857  x = torch.randn(1, 2, requires_grad=True)
858  self.run_model_test(MyModel(), train=False, input=(x), batch_size=BATCH_SIZE, use_gpu=False)
859 
860  def test_repeat_dynamic(self):
861  class MyModel(torch.nn.Module):
862  def __init__(self):
863  super(MyModel, self).__init__()
864 
865  def forward(self, x, y):
866  return x.repeat(y.size()[0] / 2, y.size()[1] * 2)
867 
868  x = torch.randn(1, 2, requires_grad=True)
869  y = torch.randn(2, 4, requires_grad=True)
870  self.run_model_test(MyModel(), train=False, input=(x, y), batch_size=BATCH_SIZE, use_gpu=False)
871 
872  def test_mean(self):
873  shape = (3, 4, 5)
874  for params in [{}] + [{'dim': i} for i in range(len(shape))]:
875  class MyModel(torch.nn.Module):
876  def __init__(self):
877  super(MyModel, self).__init__()
878 
879  def forward(self, x):
880  return torch.mean(x, **params)
881  x = torch.randn(*shape)
882  self.run_model_test(MyModel(), train=False, input=(x), batch_size=BATCH_SIZE, use_gpu=False)
883 
884  # TODO: Add test cases for prod once Caffe2 has support for ReduceProd
885  def test_softmax(self):
886  for i in range(7)[2:]:
887  model = nn.Softmax(dim=i - 1)
888  dims = [2] * (i - 2) + [3, 4]
889  input = torch.ones(*dims, requires_grad=True)
890  self.run_model_test(model, train=False, batch_size=BATCH_SIZE, input=input)
891 
892  def test_logsoftmax(self):
893  for i in range(7)[2:]:
894  model = nn.LogSoftmax(dim=i - 1)
895  dims = [2] * (i - 2) + [3, 4]
896  input = torch.ones(*dims, requires_grad=True)
897  self.run_model_test(model, train=False, batch_size=BATCH_SIZE, input=input)
898 
899  def test_randn(self):
900  x = torch.randn(1, 2, 3, 4)
901 
902  class MyModule(torch.nn.Module):
903  def forward(self, x):
904  return (torch.randn(1, 2, 3, 4) + x).shape
905  self.run_model_test(MyModule(), train=False, input=(x),
906  batch_size=BATCH_SIZE, use_gpu=False)
907 
908  def test_convtranspose(self):
909  model = nn.ConvTranspose2d(3, 3, 3, stride=3, bias=False, padding=1, output_padding=2)
910  self.run_model_test(model, train=False, batch_size=BATCH_SIZE, atol=1e-7)
911 
912  def test_unsqueeze(self):
913  shape = (3, 4, 5)
914  for dim in range(len(shape) + 1):
915  class MyModel(torch.nn.Module):
916  def __init__(self):
917  super(MyModel, self).__init__()
918 
919  def forward(self, x):
920  return x.unsqueeze(dim)
921  x = torch.randn(*shape)
922  self.run_model_test(MyModel(), train=False, input=(x), batch_size=BATCH_SIZE, atol=1e-7)
923 
924  # NB: InstanceNorm model includes unused weights, so skip this in TestCaffe2BackendEmbed
925  # TODO: We should have another pass to eliminate the unused initializers in ONNX models.
926  @skipIfEmbed
927  def test_instance_norm(self):
928  underlying = nn.InstanceNorm2d(3)
929  self.run_model_test(underlying, train=False, batch_size=BATCH_SIZE)
930 
931  def test_pixel_shuffle(self):
932  underlying = nn.PixelShuffle(4)
933  shape = (1, 64, 5, 5)
934  input = Variable(torch.randn(*shape),
935  requires_grad=True)
936  self.run_model_test(underlying, train=False, input=(input),
937  batch_size=BATCH_SIZE)
938 
939  def test_dynamic_sizes(self):
940  class MyModel(torch.nn.Module):
941  def __init__(self):
942  super(MyModel, self).__init__()
943 
944  def forward(self, x):
946  new_shape = torch.cat((torch.LongTensor([-1]), shape[0].view(1)))
948  x = torch.randn(3, 5, 7)
949  self.run_model_test(MyModel(), train=False, input=x, batch_size=BATCH_SIZE, use_gpu=False)
950 
951  def test_advanced_broadcast(self):
952  class MyModel(torch.nn.Module):
953  def __init__(self):
954  super(MyModel, self).__init__()
955 
956  def forward(self, x, y):
957  return torch.mul(x, y)
958  x = torch.randn(1, 5, 10)
959  y = torch.randn(1, 5, 1)
960  self.run_model_test(MyModel(), train=False, input=(x, y), batch_size=BATCH_SIZE, use_gpu=False)
961 
962  def test_int8_export(self):
963  class MyModel(torch.nn.Module):
964  def __init__(self):
965  super(MyModel, self).__init__()
966  self.param = torch.ByteTensor(3, 4).random_()
967 
968  def forward(self, x):
969  return x * self.param.float()
970 
971  import io
972  f = io.BytesIO()
973  from torch.onnx import ExportTypes
974  torch.onnx._export(MyModel(), (torch.rand(3, 4),), f, verbose=True, export_type=ExportTypes.ZIP_ARCHIVE)
975 
976  X = np.random.rand(3, 4).astype(np.float32)
977 
978  f.seek(0)
979  import caffe2.python.onnx.backend as c2
980  model = c2.prepare_zip_archive(f)
981  model.run(X)
982 
983  def test_neg_slice(self):
984  class NegSlice(torch.nn.Module):
985  def forward(self, x):
986  return x[-1, :, :]
987 
988  x = torch.randn(3, 4, 5)
989  self.run_model_test(NegSlice(), train=False, input=(x,), batch_size=BATCH_SIZE, use_gpu=False)
990 
991  def test_neg_slice_large(self):
992  class NegSlice(torch.nn.Module):
993  def forward(self, x):
994  return x[:, :, :, :, -3]
995 
996  x = torch.randn(3, 4, 5, 6, 7)
997  self.run_model_test(NegSlice(), train=False, input=(x,), batch_size=BATCH_SIZE, use_gpu=False)
998 
999  @unittest.skip('https://github.com/pytorch/pytorch/issues/10984')
1000  def test_neg_slice_large_negone(self):
1001  class NegSlice(torch.nn.Module):
1002  def forward(self, x):
1003  return x[:, :, :, :, -1]
1004 
1005  x = torch.randn(3, 4, 5, 6, 7)
1006  self.run_model_test(NegSlice(), train=False, input=(x,), batch_size=BATCH_SIZE, use_gpu=False)
1007 
1008  def test_dynamic_slice(self):
1009  class DynamicSliceExportMod(torch.nn.Module):
1010  def forward(self, x):
1011  results = []
1012  for i in range(4):
1013  results.append(x[:x.size(0) - i, i:x.size(2), i:3])
1014  return tuple(results)
1015 
1016  x = torch.rand(5, 5, 5)
1017  self.run_model_test(DynamicSliceExportMod(), train=False, input=(x,), batch_size=BATCH_SIZE, use_gpu=False)
1018 
1019  def test_dynamic_slice_to_the_end(self):
1020  class DynamicSliceExportMod(torch.nn.Module):
1021  def forward(self, x):
1022  results = []
1023  for i in range(4):
1024  results.append(x[:, i:, x.size(2) - 5])
1025  return tuple(results)
1026 
1027  x = torch.rand(5, 5, 5)
1028  self.run_model_test(DynamicSliceExportMod(), train=False, input=(x,), batch_size=BATCH_SIZE, use_gpu=False)
1029 
1030  def test_tensor_factories(self):
1031  class TensorFactory(torch.nn.Module):
1032  def forward(self, x):
1033  return torch.zeros(x.size()) + torch.ones(x.size())
1034 
1035  x = torch.randn(2, 3, 4)
1036  self.run_model_test(TensorFactory(), train=False, input=(x,), batch_size=BATCH_SIZE, use_gpu=False)
1037 
1038  def test_where_functional(self):
1039  class WhereFunctional(torch.nn.Module):
1040  def forward(self, x):
1041  return torch.where(x > 2.0, x, torch.neg(x))
1042 
1043  x = torch.randn(3, 4)
1044  self.run_model_test(WhereFunctional(), train=False, input=(x,), batch_size=BATCH_SIZE, use_gpu=False)
1045 
1046  def test_where_method(self):
1047  class WhereMethod(torch.nn.Module):
1048  def forward(self, x):
1049  return x.where(x > 2.0, torch.neg(x))
1050 
1051  x = torch.randn(3, 4)
1052  self.run_model_test(WhereMethod(), train=False, input=(x,), batch_size=BATCH_SIZE, use_gpu=False)
1053 
1054  def test_data_dependent_zeros_factory(self):
1055  class ZerosFactory(torch.nn.Module):
1056  def forward(self, input):
1057  return torch.cat([input, torch.zeros(input.size(0), 1).type_as(input)], dim=1)
1058 
1059  x = torch.zeros(3, 4)
1060  self.run_model_test(ZerosFactory(), train=False, input=(x,), batch_size=BATCH_SIZE, use_gpu=False)
1061 
1062  def test_implicit_expand(self):
1063  class ImplicitExpandExportMod(torch.nn.Module):
1064  def forward(self, x):
1065  return x + 1
1066 
1067  x = torch.randn(3, 4)
1068  self.run_model_test(ImplicitExpandExportMod(), train=False, input=(x,), batch_size=BATCH_SIZE, use_gpu=False)
1069 
1070  def test_reduce_sum(self):
1071  class ReduceSumNegativeIndices(torch.nn.Module):
1072  def forward(self, x):
1073  return x.sum(-1)
1074 
1075  x = torch.randn(2, 3, 4)
1076  self.run_model_test(ReduceSumNegativeIndices(), train=False, input=(x,), batch_size=BATCH_SIZE, use_gpu=False)
1077 
1078  def test_group_norm(self):
1079  c = torch.randn(BATCH_SIZE, 6, 224)
1080  model = nn.GroupNorm(3, 6)
1081  self.run_model_test(model, train=True, input=c, batch_size=BATCH_SIZE)
1082 
1083  def test_rsub(self):
1084  class RsubModel(torch.nn.Module):
1085  def forward(self, x):
1086  return 1 - x
1087 
1088  x = torch.randn(1, 2)
1089  self.run_model_test(RsubModel(), train=False, input=(x,),
1090  batch_size=BATCH_SIZE, use_gpu=False)
1091 
1092  def test_isnan(self):
1093  class IsNaNModel(torch.nn.Module):
1094  def forward(self, input):
1095  return torch.isnan(input)
1096 
1097  x = torch.tensor([1.0, float('nan'), 2.0])
1098  self.run_model_test(IsNaNModel(), train=False, input=x, batch_size=BATCH_SIZE, use_gpu=False)
1099 
1100  def test_flatten(self):
1101  class FlattenModel(torch.nn.Module):
1102  def forward(self, input):
1103  return torch.flatten(input)
1104 
1105  x = torch.randn(1, 2, 3, 4, requires_grad=True)
1106  self.run_model_test(FlattenModel(), train=False, input=x, batch_size=BATCH_SIZE)
1107 
1108  def test_flatten2D(self):
1109  class FlattenModel(torch.nn.Module):
1110  def forward(self, input):
1111  return torch.flatten(input, 1)
1112 
1113  x = torch.randn(1, 2, 3, 4, requires_grad=True)
1114  self.run_model_test(FlattenModel(), train=False, input=x, batch_size=BATCH_SIZE)
1115 
1116  def test_argmax(self):
1117  class ArgmaxModel(torch.nn.Module):
1118  def forward(self, input):
1119  return torch.argmax(input, dim=1)
1120 
1121  x = torch.randn(4, 4, requires_grad=True)
1122  self.run_model_test(ArgmaxModel(), train=False, input=x, batch_size=BATCH_SIZE)
1123 
1124  def test_argmin(self):
1125  class ArgminModel(torch.nn.Module):
1126  def forward(self, input):
1127  return torch.argmin(input, dim=1)
1128 
1129  x = torch.randn(4, 4, requires_grad=True)
1130  self.run_model_test(ArgminModel(), train=False, input=x, batch_size=BATCH_SIZE)
1131 
1132  def test_reshape(self):
1133  class ReshapeModel(torch.nn.Module):
1134  def forward(self, input):
1135  return input.reshape(1, 1)
1136 
1137  x = torch.randn(1, requires_grad=True)
1138  self.run_model_test(ReshapeModel(), train=False, input=x, batch_size=BATCH_SIZE)
1139 
1140  def test_reshape_as(self):
1141  class ReshapeAsModel(torch.nn.Module):
1142  def forward(self, input):
1143  y = torch.randn(3, 1, 2, 1, requires_grad=False)
1144  return input.reshape_as(y)
1145 
1146  x = torch.randn(2, 3, requires_grad=True)
1147  self.run_model_test(ReshapeAsModel(), train=False, input=x, batch_size=BATCH_SIZE)
1148 
1149  def test_narrow(self):
1150  class NarrowModel(torch.nn.Module):
1151  def forward(self, input):
1152  return torch.narrow(input, 0, 0, 2)
1153 
1154  x = torch.randn(3, 3, requires_grad=True)
1155  self.run_model_test(NarrowModel(), train=False, input=x, batch_size=BATCH_SIZE)
1156 
1157 # a bit of metaprogramming to set up all the rnn tests
1158 
1159 
1160 def make_test(name, base, layer, bidirectional, initial_state,
1161  variable_length, dropout,
1162  **extra_kwargs):
1163  test_name = str('_'.join([
1164  'test', name, layer[1],
1165  bidirectional[1], initial_state[1],
1166  variable_length[1], dropout[1]
1167  ]))
1168 
1169  def f(self):
1170  self._dispatch_rnn_test(
1171  base,
1172  layers=layer[0],
1173  bidirectional=bidirectional[0],
1174  initial_state=initial_state[0],
1175  packed_sequence=variable_length[0],
1176  dropout=dropout[0],
1177  **extra_kwargs)
1178 
1179  f.__name__ = test_name
1180  setattr(TestCaffe2Backend, f.__name__, f)
1181 
1182 
1183 def setup_rnn_tests():
1184  layers_opts = [
1185  (1, 'unilayer'),
1186  (3, 'trilayer')
1187  ]
1188  bidirectional_opts = [
1189  (False, 'forward'),
1190  (True, 'bidirectional')
1191  ]
1192  initial_state_opts = [
1193  (True, 'with_initial_state'),
1194  (False, 'no_initial_state')
1195  ]
1196  variable_length_opts = [
1197  (0, 'without_sequence_lengths'),
1198  (1, 'with_variable_length_sequences'),
1199  (2, 'with_batch_first_sequence_lengths')
1200  ]
1201  dropout_opts = [
1202  (0.2, 'with_dropout'),
1203  (0.0, 'without_dropout')
1204  ]
1205  test_count = 0
1206  for (layer, bidirectional, initial_state, variable_length, dropout) in \
1207  itertools.product(
1208  layers_opts,
1209  bidirectional_opts,
1210  initial_state_opts,
1211  variable_length_opts,
1212  dropout_opts,
1213  ):
1214 
1215  for base, name, extra_kwargs in (
1216  ('elman', 'elman_relu', {'nonlinearity': u'relu'}),
1217  ('elman', 'elman_tanh', {'nonlinearity': u'tanh'}),
1218  ('lstm', 'lstm', {}),
1219  ('gru', 'gru', {})
1220  ):
1221  make_test(name, base, layer, bidirectional, initial_state,
1222  variable_length, dropout,
1223  **extra_kwargs)
1224  test_count += 1
1225 
1226  # sanity check that a representative example does exist
1227  TestCaffe2Backend.test_gru_trilayer_forward_with_initial_state_without_sequence_lengths_with_dropout
1228 
1229  # make sure no one accidentally disables all the tests without
1230  # noticing
1231  assert test_count == 192, test_count
1232 setup_rnn_tests()
1233 
1234 # add the same test suite as above, but switch embed_params=False
1235 # to embed_params=True
1236 TestCaffe2BackendEmbed = type(str("TestCaffe2BackendEmbed"),
1237  (unittest.TestCase,),
1238  dict(TestCaffe2Backend.__dict__, embed_params=True))
1239 
1240 
1241 if __name__ == '__main__':
1242  unittest.main()
def reshape_from_tensor_shape(x, shape)
Definition: operators.py:19
def _lstm_test(self, layers, bidirectional, initial_state, packed_sequence, dropout)
def is_available()
Definition: __init__.py:45
def _elman_rnn_test(self, layers, nonlinearity, bidirectional, initial_state, packed_sequence, dropout)
def verify(model, args, backend, verbose=False, training=False, rtol=1e-3, atol=1e-7, test_args=2)
Definition: verify.py:241
def is_tensor(obj)
Definition: __init__.py:114
def _export(args, kwargs)
Definition: __init__.py:20
def run_debug_test(self, model, train, batch_size, state_dict=None, input=None, use_gpu=True, example_outputs=None)
def run_actual_test(self, model, train, batch_size, state_dict=None, input=None, use_gpu=True, rtol=0.001, atol=1e-7, example_outputs=None)
def run_model_test(self, model, train, batch_size, state_dict=None, input=None, use_gpu=True, rtol=0.001, atol=1e-7, example_outputs=None)
def set_default_tensor_type(t)
Definition: __init__.py:132
def shape_as_tensor(x)
Definition: operators.py:15
def _gru_test(self, layers, bidirectional, initial_state, packed_sequence, dropout)