| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120 |
- ## @package device_checker
- # Module caffe2.python.device_checker
- import numpy as np
- import copy
- from caffe2.python import workspace
- from caffe2.python.core import InferOpBlobDevicesAsDict
- from future.utils import viewitems
- class DeviceChecker(object):
- """A device checker in Python to check consistency across multiple devices.
- This is not the most efficient way to check devices, as the Python interface
- will involve a lot of copies back and forth operations. Use at your own risk.
- """
- def __init__(self, threshold, device_options):
- self._threshold = threshold
- self._device_options = device_options
- def CheckSimple(self, op, inputs, outputs_to_check,
- input_device_options=None):
- """Checks the operator with different device implementations.
- Inputs:
- op: the operator to be checked.
- inputs: the input data in numpy arrays.
- outputs_to_check: the outputs to check between devices.
- input_device_options: a mapping from input name to a device to use
- (instead of self._device_options)
- Outputs:
- boolean: True if it passes, False if it does not pass.
- """
- op = copy.deepcopy(op)
- # Entering the checker workspace
- old_ws_name = workspace.CurrentWorkspace()
- results = []
- workspace.SwitchWorkspace("_device_check_", True)
- for i, device_option in enumerate(self._device_options):
- op.device_option.CopyFrom(device_option)
- _input_device_options = input_device_options or \
- InferOpBlobDevicesAsDict(op)[0]
- print(_input_device_options)
- for i, arr in enumerate(inputs):
- workspace.FeedBlob(
- op.input[i], np.array(arr),
- _input_device_options.get(op.input[i], device_option)
- )
- workspace.RunOperatorOnce(op)
- results.append(
- [workspace.FetchBlob(op.output[idx])
- for idx in outputs_to_check])
- # Everything is done, reset the workspace.
- workspace.ResetWorkspace()
- # After running on all devices, check correctness
- success = True
- for i in range(1, len(self._device_options)):
- for j in range(len(outputs_to_check)):
- x = results[i][j]
- y = results[0][j]
- if not np.allclose(x, y,
- atol=self._threshold, rtol=self._threshold):
- print('Failure in checking device option {}'
- ' and output {}. The outputs are:'
- .format(i, op.output[outputs_to_check[j]]))
- print(x.flatten())
- print(y.flatten())
- print(np.max(np.abs(x - y)))
- success = False
- # else:
- # print ('Passed device pair (0, %d), %s %s' %
- # (i, outputs_to_check[j], y.shape))
- workspace.SwitchWorkspace(old_ws_name)
- return success
- def CheckNet(self, net, inputs=None, blobs_to_check=None, ignore=None):
- """Checks a network by inspecting all of its intermediate results, and
- see if things match.
- """
- if inputs is None:
- inputs = {}
- if ignore is None:
- ignore = set()
- old_ws_name = workspace.CurrentWorkspace()
- results = []
- if blobs_to_check is None:
- blobs_to_check = sum([list(op.output) for op in net.op], [])
- blobs_to_check = [b for b in blobs_to_check if b not in ignore]
- workspace.SwitchWorkspace("_device_check_", True)
- for device_option in self._device_options:
- for name, arr in viewitems(inputs):
- # print 'feeding', name
- workspace.FeedBlob(name, arr, device_option)
- for op in net.op:
- op.device_option.CopyFrom(device_option)
- workspace.RunNetOnce(net)
- results.append(
- [workspace.FetchBlob(name) for name in blobs_to_check]
- )
- # After running on all devices, check correctness
- success = True
- for i in range(1, len(results)):
- for j in range(len(blobs_to_check)):
- x = results[i][j]
- y = results[0][j]
- if not np.allclose(x, y,
- atol=self._threshold, rtol=self._threshold):
- print('Failure in checking device option {}'
- ' and output {}. The outputs are:'
- .format(i, blobs_to_check[j]))
- print(x.flatten())
- print(y.flatten())
- print(np.max(np.abs(x - y)))
- success = False
- # else:
- # print ('Passed device pair (%d, %d), %s %s: %s' %
- # (i, j, blobs_to_check[j], y.shape,
- # str(y.flatten())))
- workspace.SwitchWorkspace(old_ws_name)
- return success
|