# Copyright (c) 2020 PaddlePaddle Authors. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. """ mpc math op layers. """ from ..framework import MpcVariable from ..framework import check_mpc_variable_and_dtype from ..mpc_layer_helper import MpcLayerHelper from .ml import reshape __all__ = [ 'mean', 'square', 'sum', 'square_error_cost', 'reduce_sum' ] def mean(x, name=None): """ Mean Operator calculates the mean of all elements in X. Args: x(MpcVariable): (Tensor) The input of mean op name(basestring|None): Name of the output. Returns: out(MpcVariable): (Tensor) The output of mean op Examples: todo """ helper = MpcLayerHelper("mean", **locals()) check_mpc_variable_and_dtype(x, 'x', ['int64'], 'mean') if name is None: out = helper.create_mpc_variable_for_type_inference(dtype=x.dtype) else: out = helper.create_mpc_variable( name=name, dtype=x.dtype, persistable=False) helper.append_op( type="mpc_mean", inputs={"X": x}, attrs={}, outputs={"Out": out}) return out def square(x, name=None): """ square Operator calculates the square of each element in X. Args: x(MpcVariable): (Tensor) The input of square op name(basestring|None): Name of the output. Returns: out(MpcVariable): (Tensor) The output of square op Examples: todo """ helper = MpcLayerHelper("square", **locals()) check_mpc_variable_and_dtype(x, 'x', ['int64'], 'square') if name is None: out = helper.create_mpc_variable_for_type_inference(dtype=x.dtype) else: out = helper.create_mpc_variable( name=name, dtype=x.dtype, persistable=False) helper.append_op( type="mpc_square", inputs={"X": x}, attrs={}, outputs={"Out": out}) return out def sum(x): """ Sum Operator calculates the sum of all elements in X. Args: x (MpcVariable|list(MpcVariable)) The input of sum op name(basestring|None): Name of the output. Returns: out(MpcVariable): (Tensor) The output of mean op Examples: todo """ helper = MpcLayerHelper("sum", **locals()) out = helper.create_mpc_variable_for_type_inference(dtype=helper.input_dtype('x')) helper.append_op( type="mpc_sum", inputs={"X": x}, outputs={"Out": out}, attrs={'use_mkldnn': False}) return out def square_error_cost(input, label): """ This op accepts input predictions and target label and returns the squared error cost. For predictions label, and target label, the equation is: .. math:: Out = (input - label)^2 Parameters: input (MpcVariable): Input tensor, the data type should be float32. label (MpcVariable): Label tensor, the data type should be float32. Returns: The tensor variable storing the element-wise squared error \ difference between input and label. Return type: MpcVariable. Examples: todo """ helper = MpcLayerHelper('square_error_cost', **locals()) minus_out = helper.create_mpc_variable_for_type_inference(dtype=input.dtype) helper.append_op( type='mpc_elementwise_sub', inputs={'X': [input], 'Y': [label]}, outputs={'Out': [minus_out]}) square_out = helper.create_mpc_variable_for_type_inference(dtype=input.dtype) helper.append_op( type='mpc_square', inputs={'X': [minus_out]}, outputs={'Out': [square_out]}) return square_out def reduce_sum(input, dim=None, keep_dim=False, name=None): """ Computes the sum of tensor elements over the given dimension. Args: input (MpcVariable) The input of sum op name(basestring|None): Name of the output. dim (list|int, optional): The dimensions along which the sum is performed. If :attr:`None`, sum all elements of :attr:`input` and return a Tensor variable with a single element, otherwise must be in the range :math:`[-rank(input), rank(input))`. If :math:`dim[i] < 0`, the dimension to reduce is :math:`rank + dim[i]`. NOTE: 'dim' should not contain 0, becausedims[0] is share number. keep_dim (bool, optional): Whether to reserve the reduced dimension in the output Tensor. The result tensor will have one fewer dimension than the :attr:`input` unless :attr:`keep_dim` is true, default value is False. name(str, optional): The default value is None. Normally there is no need for user to set this property. For more information, please refer to :ref:`api_guide_Name` Returns: Variable: Tensor, results of summation operation on the specified dim of input tensor, it's data type is the same as input's Tensor. Raises: TypeError, if out data type is different with the input data type. Returns: out(MpcVariable): (Tensor) The output of mean op Examples: .. code-block:: python import paddle_fl.mpc as pfl_mpc pfl_mpc.init("aby3", int(args.role), "localhost", args.server, int(args.port)) data_1 = pfl_mpc.data(name='x', shape=[3, 3], dtype='int64') pfl_mpc.layers.reshape(data_1, [1, 2]) # shape: [2, 1, 1] # data_1 = np.full(shape=(3, 4), fill_value=2) # reduce_sum: 24 """ if dim is not None and not isinstance(dim, list): dim = [dim] if dim != None and dim != []: if 0 in dim: raise ValueError( "'dim' should not contain 0, because dim[0] is share number." ) else: dim = [i for i in range(len(input.shape))][1:] attrs = { 'dim': dim, 'keep_dim': keep_dim, 'reduce_all': False } check_mpc_variable_and_dtype( input, 'input', ['int64'], 'reduce_sum') helper = MpcLayerHelper('reduce_sum', **locals()) out = helper.create_mpc_variable_for_type_inference(dtype=helper.input_dtype()) helper.append_op( type='reduce_sum', inputs={'X': input}, outputs={'Out': out}, attrs=attrs) if out.shape == (2,): out = reshape(out, list(out.shape) + [1]) return out