def test_slice(): element_type = Type.f32 shape = Shape([6, 6]) A = Parameter(element_type, shape) parameter_list = [A] input_arr = np.arange(36, dtype=np.float32).reshape(6, 6) lower_bounds = [1, 1] upper_bounds = [5, 5] function = Function( NodeVector( [Slice(A, Coordinate(lower_bounds), Coordinate(upper_bounds))]), parameter_list, 'test') backend = Backend.create(pytest.config.getoption('backend')) a = backend.create_tensor(element_type, shape) result = backend.create_tensor(element_type, Shape([4, 4])) a.write(util.numpy_to_c(input_arr), 0, 36 * 4) result_arr = np.zeros(16, dtype=np.float32).reshape(4, 4) result.write(util.numpy_to_c(result_arr), 0, 16 * 4) handle = backend.compile(function) handle.call([result], [a]) result.read(util.numpy_to_c(result_arr), 0, 64) result_arr_ref = input_arr[lower_bounds[0]:upper_bounds[0], lower_bounds[1]:upper_bounds[1]] assert np.allclose(result_arr, result_arr_ref) #test with strides strides = [1, 2] function = Function( NodeVector([ Slice(A, Coordinate(lower_bounds), Coordinate(upper_bounds), Strides(strides)) ]), parameter_list, 'test') backend = Backend.create(pytest.config.getoption('backend')) result = backend.create_tensor(element_type, Shape([4, 2])) result_arr = np.zeros(8, dtype=np.float32).reshape(4, 2) result.write(util.numpy_to_c(result_arr), 0, 8 * 4) handle = backend.compile(function) handle.call([result], [a]) result.read(util.numpy_to_c(result_arr), 0, 32) result_arr_ref = result_arr_ref[::strides[0], ::strides[1]] assert np.allclose(result_arr, result_arr_ref)
def test_convolution_with_data_dilation(): element_type = Type.f32 image_shape = Shape([1, 1, 10, 10]) filter_shape = Shape([1, 1, 3, 3]) A = Parameter(element_type, image_shape) B = Parameter(element_type, filter_shape) parameter_list = [A, B] image_arr = np.arange(100, dtype=np.float32).reshape(1, 1, 10, 10) filter_arr = np.ones(9, dtype=np.float32).reshape(1, 1, 3, 3) strides = [1, 1] dilation = [1, 1] padding_below = [0, 0] padding_above = [0, 0] data_dilation = [2, 2] function = Function([ Convolution(A, B, Strides(strides), Strides(dilation), CoordinateDiff(padding_below), CoordinateDiff(padding_above), Strides(data_dilation)) ], parameter_list, 'test') backend = Backend.create(test.BACKEND_NAME) a = backend.create_tensor(element_type, image_shape) b = backend.create_tensor(element_type, filter_shape) a.write(util.numpy_to_c(image_arr), 10 * 10 * 4) b.write(util.numpy_to_c(filter_arr), 3 * 3 * 4) result_arr = np.zeros(17 * 17, dtype=np.float32).reshape(1, 1, 17, 17) result = backend.create_tensor(element_type, Shape([1, 1, 17, 17])) result.write(util.numpy_to_c(result_arr), 17 * 17 * 4) handle = backend.compile(function) handle.call([result], [a, b]) result.read(util.numpy_to_c(result_arr), 17 * 17 * 4) result_arr_ref = convolution2d(image_arr[0][0], filter_arr[0][0], strides, dilation, padding_below, padding_above, data_dilation).reshape(1, 1, 17, 17) assert np.allclose(result_arr, result_arr_ref)
def convolution(x, # type: Node weights, # type: Node strides=None, # type: List[int] dilation=None, # type: List[int] padding_above=None, # type: List[int] padding_below=None, # type: List[int] name=None, # type: str ): # type: (...) -> Node """Return convolution node.""" if strides is None: strides = [1] * (len(x.shape) - 2) # Default to as many 1s as spatial dimensions of input. if dilation is None: dilation = [1] * (len(x.shape) - 2) if padding_above is None: padding_above = [0] * (len(x.shape) - 2) if padding_below is None: padding_below = [0] * (len(x.shape) - 2) return Convolution(x, weights, Strides(strides), Strides(dilation), CoordinateDiff(padding_above), CoordinateDiff(padding_below))
def convolution_backprop_data(data_batch_shape, # type: TensorShape filters, # type: Node output_delta, # type: Node window_movement_strides_forward=None, # type: List[int] window_dilation_strides_forward=None, # type: List[int] padding_below_forward=None, # type: List[int] padding_above_forward=None, # type: List[int] data_dilation_strides_forward=None, # type: List[int] name=None, # type: str ): # type: (...) -> Node """Return node performing a batched-convolution data batch-backprop operation. :param data_batch_shape: The shape of the data batch from forward-prop. :param filters: The node producing the filters from forward-prop. :param output_delta: The node producing output delta. :param window_movement_strides_forward: The window movement strides from forward-prop. :param window_dilation_strides_forward: The window dilation strides from forward-prop. :param padding_below_forward: The padding-below sizes from forward-prop. :param padding_above_forward: The padding-above sizes from forward-prop. :param data_dilation_strides_forward: The data dilation strides from forward-prop. """ spatial_dim_count = len(data_batch_shape) - 2 if window_movement_strides_forward is None: window_movement_strides_forward = [1] * spatial_dim_count if window_dilation_strides_forward is None: window_dilation_strides_forward = [1] * spatial_dim_count if padding_below_forward is None: padding_below_forward = [0] * spatial_dim_count if padding_above_forward is None: padding_above_forward = [0] * spatial_dim_count if data_dilation_strides_forward is None: data_dilation_strides_forward = [1] * spatial_dim_count return ConvolutionBackpropData(Shape(data_batch_shape), filters, output_delta, Strides(window_movement_strides_forward), Strides(window_dilation_strides_forward), CoordinateDiff(padding_below_forward), CoordinateDiff(padding_above_forward), Strides(data_dilation_strides_forward))
def test_replace_slice(): element_type = Type.f32 A = Parameter(element_type, Shape([6, 4])) B = Parameter(element_type, Shape([3, 2])) parameter_list = [A, B] input_arr_a = np.zeros(24, dtype=np.float32).reshape(6, 4) input_arr_b = np.ones(6, dtype=np.float32).reshape(3, 2) lower_bounds = [0, 1] upper_bounds = [3, 3] function = Function(NodeVector([ReplaceSlice(A, B, Coordinate(lower_bounds), Coordinate(upper_bounds))]), parameter_list, 'test') backend = Backend.create(test.BACKEND_NAME) a = backend.create_tensor(element_type, Shape([6, 4])) b = backend.create_tensor(element_type, Shape([3, 2])) result = backend.create_tensor(element_type, Shape([6, 4])) a.write(util.numpy_to_c(input_arr_a), 0, 24*4) b.write(util.numpy_to_c(input_arr_b), 0, 6*4) result_arr = np.zeros(24, dtype=np.float32).reshape(6, 4) result.write(util.numpy_to_c(result_arr), 0, 24*4) handle = backend.compile(function) handle.call([result], [a, b]) result.read(util.numpy_to_c(result_arr), 0, 24*4) result_arr_ref = np.copy(input_arr_a) result_arr_ref[lower_bounds[0]:upper_bounds[0], lower_bounds[1]:upper_bounds[1]] = input_arr_b assert np.allclose(result_arr, result_arr_ref) #test with strides lower_bounds = [0, 0] upper_bounds = [5, 3] strides = [2, 2] function = Function(NodeVector([ReplaceSlice(A, B, Coordinate(lower_bounds), Coordinate(upper_bounds), Strides(strides))]), parameter_list, 'test') backend = Backend.create(test.BACKEND_NAME) handle = backend.compile(function) handle.call([result], [a, b]) result.read(util.numpy_to_c(result_arr), 0, 24*4) result_arr_ref = np.copy(input_arr_a) result_arr_ref[::strides[0], ::strides[1]] = input_arr_b assert np.allclose(result_arr, result_arr_ref)
def convolution(data_batch, # type: Node filter_weights, # type: Node filter_strides=None, # type: List[int] filter_dilation_strides=None, # type: List[int] padding_below=None, # type: List[int] padding_above=None, # type: List[int] data_dilation_strides=None, # type: List[int] name=None, # type: str ): # type: (...) -> Node """Return node performing batched convolution operation. :param data_batch: The node providing data batch tensor. :param filter_weights: The node providing filters tensor. :param filter_strides: The kernel window movement strides. :param filter_dilation_strides: The filters dilation strides. :param padding_below: The number of zero padding elements to add on each axis below 0 coordinate. :param padding_above: The number of zero padding elements to add on each axis above max coordinate. :param data_dilation_strides: The data batch dilation strides. :param name: The optional new name for output node. :return: New node performing batched convolution operation. """ spatial_dim_count = len(data_batch.shape) - 2 if filter_strides is None: filter_strides = [1] * spatial_dim_count if filter_dilation_strides is None: filter_dilation_strides = [1] * spatial_dim_count if padding_above is None: padding_above = [0] * spatial_dim_count if padding_below is None: padding_below = [0] * spatial_dim_count if data_dilation_strides is None: data_dilation_strides = [1] * spatial_dim_count return Convolution(data_batch, filter_weights, Strides(filter_strides), Strides(filter_dilation_strides), CoordinateDiff(padding_below), CoordinateDiff(padding_above), Strides(data_dilation_strides))
def test_convolution_with_data_dilation(): element_type = Type.f32 image_shape = Shape([1, 1, 10, 10]) filter_shape = Shape([1, 1, 3, 3]) A = Parameter(element_type, image_shape) B = Parameter(element_type, filter_shape) parameter_list = [A, B] image_arr = np.arange(100, dtype=np.float32).reshape(1, 1, 10, 10) filter_arr = np.ones(9, dtype=np.float32).reshape(1, 1, 3, 3) strides = [1, 1] dilation = [1, 1] padding_below = [0, 0] padding_above = [0, 0] data_dilation = [2, 2] function = Function(NodeVector([Convolution(A, B, Strides(strides), Strides(dilation), CoordinateDiff(padding_below), CoordinateDiff(padding_above), Strides(data_dilation))]), parameter_list, 'test') backend, cf = make_backend_call_frame(function) a = backend.make_primary_tensor_view(element_type, image_shape) b = backend.make_primary_tensor_view(element_type, filter_shape) a.write(util.numpy_to_c(image_arr), 0, 10*10*4) b.write(util.numpy_to_c(filter_arr), 0, 3*3*4) result_arr = np.zeros(17*17, dtype=np.float32).reshape(1, 1, 17, 17) result = backend.make_primary_tensor_view(element_type, Shape([1, 1, 17, 17])) result.write(util.numpy_to_c(result_arr), 0, 17*17*4) cf.call([a, b], [result]) result.read(util.numpy_to_c(result_arr), 0, 17*17*4) result_arr_ref = convolution2d(image_arr[0][0], filter_arr[0][0], strides, dilation, padding_below, padding_above, data_dilation).reshape(1, 1, 17, 17) assert np.allclose(result_arr, result_arr_ref)
def visit(self, op, inputs): self.computation.set_op_rank(op) # op.args[0] : inputs # op.pool_params # op.channel_axes # op.spatial_axes if 'max' == op.pool_params['op']: """ print(op.pool_params) print(inputs.axes) print(op.axes) """ ngraph_pool = PyngMaxPool( self.computation.lookup_cpp_op(inputs), Shape([op.pool_params['R'], op.pool_params['S']]), Strides([op.pool_params['str_h'], op.pool_params['str_w']]), Shape([op.pool_params['pad_h'], op.pool_params['pad_w']]), Shape([op.pool_params['pad_h'], op.pool_params['pad_w']])) self.computation.register_cpp_op(op, ngraph_pool, set_name=False) elif 'avg' == op.pool_params['op']: ngraph_pool = PyngAvgPool( self.computation.lookup_cpp_op(inputs), Shape([op.pool_params['R'], op.pool_params['S']]), Strides([op.pool_params['str_h'], op.pool_params['str_w']]), Shape([op.pool_params['pad_h'], op.pool_params['pad_w']]), Shape([op.pool_params['pad_h'], op.pool_params['pad_w']]), True) """ print(list(op.axes.lengths)) print(ngraph_pool.get_output_shape(0)) """ self.computation.register_cpp_op(op, ngraph_pool) else: raise RuntimeError("Unsupported pooling type: " + op.pool_params['op'])
def test_slice(): element_type = Type.f32 shape = Shape([6, 6]) A = Parameter(element_type, shape) parameter_list = [A] input_arr = np.arange(36, dtype=np.float32).reshape(6, 6) lower_bounds = [1, 1] upper_bounds = [5, 5] function = Function(NodeVector([Slice(A, Coordinate(lower_bounds), Coordinate(upper_bounds))]), parameter_list, 'test') backend, cf = make_backend_call_frame(function) a = backend.make_primary_tensor_view(element_type, shape) result = backend.make_primary_tensor_view(element_type, Shape([4, 4])) a.write(util.numpy_to_c(input_arr), 0, 36*4) result_arr = np.zeros(16, dtype=np.float32).reshape(4, 4) result.write(util.numpy_to_c(result_arr), 0, 16*4) cf.call([a], [result]) result.read(util.numpy_to_c(result_arr), 0, 64) result_arr_ref = input_arr[lower_bounds[0]:upper_bounds[0], lower_bounds[1]:upper_bounds[1]] assert np.allclose(result_arr, result_arr_ref) #test with strides strides = [1, 2] function = Function(NodeVector([Slice(A, Coordinate(lower_bounds), Coordinate(upper_bounds), Strides(strides))]), parameter_list, 'test') backend, cf = make_backend_call_frame(function) result = backend.make_primary_tensor_view(element_type, Shape([4, 2])) result_arr = np.zeros(8, dtype=np.float32).reshape(4, 2) result.write(util.numpy_to_c(result_arr), 0, 8*4) cf.call([a], [result]) result.read(util.numpy_to_c(result_arr), 0, 32) result_arr_ref = result_arr_ref[::strides[0], ::strides[1]] assert np.allclose(result_arr, result_arr_ref)
def slice(node, lower_bounds, upper_bounds, strides=None, name=None): # type: (Node, List[int], List[int], List[int], str) -> Node """Take a slice of an input tensor, (sub-tensor) that resides within a bounding box. Optionally this function may be provided with stride along each axis. :param node: The tensor we want to slice. :param lower_bounds: The (inclusive) lower-bound coordinates for the tensor slice. :param upper_bounds: The (exclusive) upper-bound coordinates for the tensor slice. :param strides: The strides for the tensor slice. :param name: Optional name for the output node. :return: Return node that represents a slice of input nodes data. """ if strides is None: return Slice(node, Coordinate(lower_bounds), Coordinate(upper_bounds)) else: return Slice(node, Coordinate(lower_bounds), Coordinate(upper_bounds), Strides(strides))
def max_pool(x, # type: Node window_shape, # type: TensorShape strides=None, # type: List[int] padding_above=None, # type: List[int] padding_below=None, # type: List[int] name=None, # type: str ): # type: (...) -> Node """Return max pooling node.""" if strides is None: strides = [1] * len(window_shape) # Default to as many 1s as spatial dimensions of input. if padding_above is None: padding_above = [0] * len(window_shape) if padding_below is None: padding_below = [0] * len(window_shape) return MaxPool(x, Shape(window_shape), Strides(strides), Shape(padding_above), Shape(padding_below))
def avg_pool(x, # type: Node window_shape, # type: TensorShape strides=None, # type: List[int] padding_above=None, # type: List[int] padding_below=None, # type: List[int] zero_pad=True, # type: bool name=None, # type: str ): # type: (...) -> Node """Return average pooling node.""" if strides is None: strides = [1] * len(window_shape) # Default to as many 1s as spatial dimensions of input. if padding_above is None: padding_above = [0] * len(window_shape) if padding_below is None: padding_below = [0] * len(window_shape) return AvgPool(x, Shape(window_shape), Strides(strides), Shape(padding_above), Shape(padding_below), zero_pad)
def replace_slice(dest_node, # type: Node src_node, # type: Node lower_bounds, # type: List[int] upper_bounds, # type: List[int] strides=None, # type: List[int] name=None, # type: str ): # type: (...) -> Node """Return a copy of `dest_node` with the specified slice overwritten by the `src_node` data. :param dest_node: The node providing data to be overwritten by the specified slice. :param src_node: The node providing data for overwriting. :param lower_bounds: The (inclusive) lower-bound coordinates for the replaced slice. :param upper_bounds: The (exclusive) upper-bound coordinates for the replaced slice. :param strides: The strides for the replaced slice. :param name: The optional name for the output new node. :return: The new node with copy of `dest_node` with the specified slice overwritten by the `src_node`. """ if strides is None: return ReplaceSlice(dest_node, src_node, Coordinate(lower_bounds), Coordinate(upper_bounds)) else: return ReplaceSlice(dest_node, src_node, Coordinate(lower_bounds), Coordinate(upper_bounds), Strides(strides))
def visit(self, op, x): self.computation.set_op_rank(op) # op.args[0] : x # op.slices lowers = [] uppers = [] strides = [] axes_to_remove = [] for axis, s in zip(x.axes, op.slices): if isinstance(s, int): lowers.append(s) uppers.append(s + 1) strides.append(1) axes_to_remove.append(axis) else: if s.start is None: lowers.append(0) else: lowers.append(s.start) if s.step is None: strides.append(1) else: strides.append(s.step) if s.stop is None: uppers.append(axis.length) else: uppers.append(s.stop) op_element_type = self.computation.lookup_cpp_op(x) ngraph_sliced = PyngSlice(op_element_type, Coordinate(lowers), Coordinate(uppers), Strides(strides)) if axes_to_remove: ngraph_sliced = PyngReshape( ngraph_sliced, AxisVector(list(range(0, len(x.axes)))), Shape(list(op.axes.lengths))) self.computation.register_cpp_op(op, ngraph_sliced)
def test_max_pool(): #test 1d element_type = Type.f32 shape = Shape([1, 1, 10]) A = Parameter(element_type, shape) parameter_list = [A] input_arr = np.arange(10, dtype=np.float32).reshape(1, 1, 10) window_shape = [3] function = Function([MaxPool(A, Shape(window_shape))], parameter_list, 'test') backend = Backend.create(test.BACKEND_NAME) a = backend.create_tensor(element_type, shape) result = backend.create_tensor(element_type, Shape([1, 1, 8])) a.write(util.numpy_to_c(input_arr), 10 * 4) result_arr = np.zeros(8, dtype=np.float32).reshape(1, 1, 8) result.write(util.numpy_to_c(result_arr), 8 * 4) handle = backend.compile(function) handle.call([result], [a]) result.read(util.numpy_to_c(result_arr), 32) result_arr_ref = (np.arange(8) + 2).reshape(1, 1, 8) assert np.allclose(result_arr, result_arr_ref) #test 1d with strides strides = [2] function = Function([MaxPool(A, Shape(window_shape), Strides(strides))], parameter_list, 'test') backend = Backend.create(test.BACKEND_NAME) size = 4 result = backend.create_tensor(element_type, Shape([1, 1, size])) result_arr = np.zeros(size, dtype=np.float32).reshape(1, 1, size) result.write(util.numpy_to_c(result_arr), size * 4) handle = backend.compile(function) handle.call([result], [a]) result.read(util.numpy_to_c(result_arr), size * 4) result_arr_ref = ((np.arange(size) + 1) * 2).reshape(1, 1, size) assert np.allclose(result_arr, result_arr_ref) #test 2d element_type = Type.f32 shape = Shape([1, 1, 10, 10]) A = Parameter(element_type, shape) parameter_list = [A] input_arr = np.arange(100, dtype=np.float32).reshape(1, 1, 10, 10) window_shape = [3, 3] function = Function([MaxPool(A, Shape(window_shape))], parameter_list, 'test') backend = Backend.create(test.BACKEND_NAME) a = backend.create_tensor(element_type, shape) result = backend.create_tensor(element_type, Shape([1, 1, 8, 8])) a.write(util.numpy_to_c(input_arr), 10 * 10 * 4) result_arr = np.zeros(64, dtype=np.float32).reshape(1, 1, 8, 8) result.write(util.numpy_to_c(result_arr), 8 * 8 * 4) handle = backend.compile(function) handle.call([result], [a]) result.read(util.numpy_to_c(result_arr), 8 * 8 * 4) result_arr_ref = ((np.arange(100).reshape(10, 10))[2:, 2:]).reshape(1, 1, 8, 8) assert np.allclose(result_arr, result_arr_ref) #test 2d with strides strides = [2, 2] function = Function([MaxPool(A, Shape(window_shape), Strides(strides))], parameter_list, 'test') backend = Backend.create(test.BACKEND_NAME) size = 4 result = backend.create_tensor(element_type, Shape([1, 1, size, size])) result_arr = np.zeros(size * size, dtype=np.float32).reshape(1, 1, size, size) result.write(util.numpy_to_c(result_arr), size * size * 4) handle = backend.compile(function) handle.call([result], [a]) result.read(util.numpy_to_c(result_arr), size * size * 4) result_arr_ref = ((np.arange(100).reshape(10, 10))[2::2, 2::2]).reshape( 1, 1, size, size) assert np.allclose(result_arr, result_arr_ref)
def test_max_pool(): #test 1d element_type = Type.f32 shape = Shape([1, 1, 10]) A = Parameter(element_type, shape) parameter_list = [A] input_arr = np.arange(10, dtype=np.float32).reshape(1, 1, 10) window_shape = [3] function = Function(NodeVector([MaxPool(A, Shape(window_shape))]), parameter_list, 'test') backend, cf = make_backend_call_frame(function) a = backend.make_primary_tensor_view(element_type, shape) result = backend.make_primary_tensor_view(element_type, Shape([1, 1, 8])) a.write(util.numpy_to_c(input_arr), 0, 10 * 4) result_arr = np.zeros(8, dtype=np.float32).reshape(1, 1, 8) result.write(util.numpy_to_c(result_arr), 0, 8 * 4) cf.call([result], [a]) result.read(util.numpy_to_c(result_arr), 0, 32) result_arr_ref = (np.arange(8) + 2).reshape(1, 1, 8) assert np.allclose(result_arr, result_arr_ref) #test 1d with strides strides = [2] function = Function( NodeVector([MaxPool(A, Shape(window_shape), Strides(strides))]), parameter_list, 'test') backend, cf = make_backend_call_frame(function) size = 4 result = backend.make_primary_tensor_view(element_type, Shape([1, 1, size])) result_arr = np.zeros(size, dtype=np.float32).reshape(1, 1, size) result.write(util.numpy_to_c(result_arr), 0, size * 4) cf.call([result], [a]) result.read(util.numpy_to_c(result_arr), 0, size * 4) result_arr_ref = ((np.arange(size) + 1) * 2).reshape(1, 1, size) assert np.allclose(result_arr, result_arr_ref) #test 2d element_type = Type.f32 shape = Shape([1, 1, 10, 10]) A = Parameter(element_type, shape) parameter_list = [A] input_arr = np.arange(100, dtype=np.float32).reshape(1, 1, 10, 10) window_shape = [3, 3] function = Function(NodeVector([MaxPool(A, Shape(window_shape))]), parameter_list, 'test') backend, cf = make_backend_call_frame(function) a = backend.make_primary_tensor_view(element_type, shape) result = backend.make_primary_tensor_view(element_type, Shape([1, 1, 8, 8])) a.write(util.numpy_to_c(input_arr), 0, 10 * 10 * 4) result_arr = np.zeros(64, dtype=np.float32).reshape(1, 1, 8, 8) result.write(util.numpy_to_c(result_arr), 0, 8 * 8 * 4) cf.call([result], [a]) result.read(util.numpy_to_c(result_arr), 0, 8 * 8 * 4) result_arr_ref = ((np.arange(100).reshape(10, 10))[2:, 2:]).reshape(1, 1, 8, 8) assert np.allclose(result_arr, result_arr_ref) #test 2d with strides strides = [2, 2] function = Function( NodeVector([MaxPool(A, Shape(window_shape), Strides(strides))]), parameter_list, 'test') backend, cf = make_backend_call_frame(function) size = 4 result = backend.make_primary_tensor_view(element_type, Shape([1, 1, size, size])) result_arr = np.zeros(size * size, dtype=np.float32).reshape(1, 1, size, size) result.write(util.numpy_to_c(result_arr), 0, size * size * 4) cf.call([result], [a]) result.read(util.numpy_to_c(result_arr), 0, size * size * 4) result_arr_ref = ((np.arange(100).reshape(10, 10))[2::2, 2::2]).reshape( 1, 1, size, size) assert np.allclose(result_arr, result_arr_ref)
def visit(self, op, delta): self.computation.set_op_rank(op) # op.args[0] : delta # op.fprop # op.inputs if 'max' == op.pool_params['op']: """ MaxPoolBackprop(const std::shared_ptr<Node>& arg_forward, const std::shared_ptr<Node>& delta, const Shape& window_shape, const Strides& window_movement_strides, const Shape& padding_below, const Shape& padding_above, const std::shared_ptr<op::MaxPool>& forward_op = nullptr); """ """ print(delta.axes) print(op.inputs.axes) print(op.axes) """ inputs = op.inputs ngraph_fprop = self.computation.lookup_cpp_op(op.fprop) ngraph_pool = PyngMaxPoolBackprop( self.computation.lookup_cpp_op(inputs), self.computation.lookup_cpp_op(delta), Shape([op.fprop.pool_params['R'], op.fprop.pool_params['S']]), Strides([ op.fprop.pool_params['str_h'], op.fprop.pool_params['str_w'] ]), Shape([ op.fprop.pool_params['pad_h'], op.fprop.pool_params['pad_w'] ]), Shape([ op.fprop.pool_params['pad_h'], op.fprop.pool_params['pad_w'] ]), ngraph_fprop) self.computation.register_cpp_op(op, ngraph_pool) elif 'avg' == op.pool_params['op']: """ AvgPoolBackprop(const Shape& forward_arg_shape, const std::shared_ptr<Node>& delta, const Shape& window_shape, const Strides& window_movement_strides, const Shape& padding_below, const Shape& padding_above); """ """ print(delta.axes) print(op.inputs.axes) print(op.axes) """ inputs = op.inputs ngraph_pool = PyngAvgPoolBackprop( Shape(list(inputs.axes.lengths)), self.computation.lookup_cpp_op(delta), Shape([op.fprop.pool_params['R'], op.fprop.pool_params['S']]), Strides([ op.fprop.pool_params['str_h'], op.fprop.pool_params['str_w'] ]), Shape([ op.fprop.pool_params['pad_h'], op.fprop.pool_params['pad_w'] ]), Shape([ op.fprop.pool_params['pad_h'], op.fprop.pool_params['pad_w'] ]), True) self.computation.register_cpp_op(op, ngraph_pool, set_name=False) else: raise RuntimeError("Unsupported pooling type: " + op.pool_params['op'])
def test_convolution_with_padding(): element_type = Type.f32 image_shape = Shape([1, 1, 10, 10]) filter_shape = Shape([1, 1, 3, 3]) A = Parameter(element_type, image_shape) B = Parameter(element_type, filter_shape) parameter_list = [A, B] image_arr = np.arange(100, dtype=np.float32).reshape(1, 1, 10, 10) filter_arr = np.zeros(9, dtype=np.float32).reshape(1, 1, 3, 3) filter_arr[0][0][1][1] = 1 strides = [1, 1] dilation = [2, 2] padding_below = [0, 0] padding_above = [0, 0] function = Function( NodeVector([ Convolution(A, B, Strides(strides), Strides(dilation), CoordinateDiff(padding_below), CoordinateDiff(padding_above)) ]), parameter_list, 'test') backend = Backend.create(pytest.config.getoption('backend')) a = backend.create_tensor(element_type, image_shape) b = backend.create_tensor(element_type, filter_shape) a.write(util.numpy_to_c(image_arr), 0, 10 * 10 * 4) b.write(util.numpy_to_c(filter_arr), 0, 3 * 3 * 4) result_arr = np.zeros(36, dtype=np.float32).reshape(1, 1, 6, 6) result = backend.create_tensor(element_type, Shape([1, 1, 6, 6])) result.write(util.numpy_to_c(result_arr), 0, 6 * 6 * 4) backend.call(backend.compile(function), [result], [a, b]) result.read(util.numpy_to_c(result_arr), 0, 6 * 6 * 4) result_arr_ref = convolution2d(image_arr[0][0], filter_arr[0][0], strides, dilation, padding_below, padding_above).reshape(1, 1, 6, 6) assert np.allclose(result_arr, result_arr_ref) # test with non-zero padding element_type = Type.f32 image_shape = Shape([1, 1, 10, 10]) filter_shape = Shape([1, 1, 3, 3]) A = Parameter(element_type, image_shape) B = Parameter(element_type, filter_shape) parameter_list = [A, B] image_arr = np.arange(100, dtype=np.float32).reshape(1, 1, 10, 10) filter_arr = (np.ones(9, dtype=np.float32).reshape(1, 1, 3, 3)) * -1 filter_arr[0][0][1][1] = 1 strides = [1, 1] dilation = [2, 2] padding_below = [2, 1] padding_above = [1, 2] function = Function( NodeVector([ Convolution(A, B, Strides(strides), Strides(dilation), CoordinateDiff(padding_below), CoordinateDiff(padding_above)) ]), parameter_list, 'test') backend = Backend.create(pytest.config.getoption('backend')) a = backend.create_tensor(element_type, image_shape) b = backend.create_tensor(element_type, filter_shape) a.write(util.numpy_to_c(image_arr), 0, 10 * 10 * 4) b.write(util.numpy_to_c(filter_arr), 0, 3 * 3 * 4) result_arr = np.zeros(81, dtype=np.float32).reshape(1, 1, 9, 9) result = backend.create_tensor(element_type, Shape([1, 1, 9, 9])) result.write(util.numpy_to_c(result_arr), 0, 9 * 9 * 4) backend.call(backend.compile(function), [result], [a, b]) result.read(util.numpy_to_c(result_arr), 0, 9 * 9 * 4) result_arr_ref = convolution2d(image_arr[0][0], filter_arr[0][0], strides, dilation, padding_below, padding_above).reshape(1, 1, 9, 9) assert np.allclose(result_arr, result_arr_ref)