from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
from __future__ import unicode_literals

import unittest

from hypothesis import given
import numpy as np

from caffe2.proto import caffe2_pb2
from caffe2.python import core, workspace
import caffe2.python.hypothesis_test_util as hu
import caffe2.python.serialized_test.serialized_test_util as serial


# TODO(jiayq): make them hypothesis tests for better coverage.
class TestElementwiseBroadcast(serial.SerializedTestCase):
    @given(**hu.gcs)
    def test_broadcast_Add(self, gc, dc):
        # Set broadcast and no axis, i.e. broadcasting last dimensions.
        X = np.random.rand(2, 3, 4, 5).astype(np.float32)
        Y = np.random.rand(4, 5).astype(np.float32)
        op = core.CreateOperator("Add", ["X", "Y"], "out", broadcast=1)
        workspace.FeedBlob("X", X)
        workspace.FeedBlob("Y", Y)
        workspace.RunOperatorOnce(op)
        out = workspace.FetchBlob("out")
        np.testing.assert_array_almost_equal(out, X + Y)
        self.assertDeviceChecks(dc, op, [X, Y], [0])
        self.assertGradientChecks(gc, op, [X, Y], 1, [0])

        # broadcasting intermediate dimensions
        X = np.random.rand(2, 3, 4, 5).astype(np.float32)
        Y = np.random.rand(3, 4).astype(np.float32)
        op = core.CreateOperator("Add", ["X", "Y"], "out", broadcast=1, axis=1)
        workspace.FeedBlob("X", X)
        workspace.FeedBlob("Y", Y)
        workspace.RunOperatorOnce(op)
        out = workspace.FetchBlob("out")
        np.testing.assert_array_almost_equal(out, X + Y[:, :, np.newaxis])
        self.assertDeviceChecks(dc, op, [X, Y], [0])
        self.assertGradientChecks(gc, op, [X, Y], 1, [0])

        # broadcasting the first dimension
        X = np.random.rand(2, 3, 4, 5).astype(np.float32)
        Y = np.random.rand(2).astype(np.float32)
        op = core.CreateOperator("Add", ["X", "Y"], "out", broadcast=1, axis=0)
        workspace.FeedBlob("X", X)
        workspace.FeedBlob("Y", Y)
        workspace.RunOperatorOnce(op)
        out = workspace.FetchBlob("out")
        np.testing.assert_array_almost_equal(
            out, X + Y[:, np.newaxis, np.newaxis, np.newaxis])
        self.assertDeviceChecks(dc, op, [X, Y], [0])
        self.assertGradientChecks(gc, op, [X, Y], 1, [0])

        # broadcasting with single elem dimensions at both ends
        X = np.random.rand(2, 3, 4, 5).astype(np.float32)
        Y = np.random.rand(1, 4, 1).astype(np.float32)
        op = core.CreateOperator("Add", ["X", "Y"], "out", broadcast=1, axis=1)
        workspace.FeedBlob("X", X)
        workspace.FeedBlob("Y", Y)
        workspace.RunOperatorOnce(op)
        out = workspace.FetchBlob("out")
        np.testing.assert_array_almost_equal(out, X + Y)
        self.assertDeviceChecks(dc, op, [X, Y], [0])
        self.assertGradientChecks(gc, op, [X, Y], 1, [0])

    @given(**hu.gcs)
    def test_broadcast_Mul(self, gc, dc):
        # Set broadcast and no axis, i.e. broadcasting last dimensions.
        X = np.random.rand(2, 3, 4, 5).astype(np.float32)
        Y = np.random.rand(4, 5).astype(np.float32)
        op = core.CreateOperator("Mul", ["X", "Y"], "out", broadcast=1)
        workspace.FeedBlob("X", X)
        workspace.FeedBlob("Y", Y)
        workspace.RunOperatorOnce(op)
        out = workspace.FetchBlob("out")
        np.testing.assert_array_almost_equal(out, X * Y)
        self.assertDeviceChecks(dc, op, [X, Y], [0])
        self.assertGradientChecks(gc, op, [X, Y], 1, [0])

        # broadcasting intermediate dimensions
        X = np.random.rand(2, 3, 4, 5).astype(np.float32)
        Y = np.random.rand(3, 4).astype(np.float32)
        op = core.CreateOperator("Mul", ["X", "Y"], "out", broadcast=1, axis=1)
        workspace.FeedBlob("X", X)
        workspace.FeedBlob("Y", Y)
        workspace.RunOperatorOnce(op)
        out = workspace.FetchBlob("out")
        np.testing.assert_array_almost_equal(out, X * Y[:, :, np.newaxis])
        self.assertGradientChecks(gc, op, [X, Y], 1, [0])
        self.assertDeviceChecks(dc, op, [X, Y], [0])

        # broadcasting the first dimension
        X = np.random.rand(2, 3, 4, 5).astype(np.float32)
        Y = np.random.rand(2).astype(np.float32)
        op = core.CreateOperator("Mul", ["X", "Y"], "out", broadcast=1, axis=0)
        workspace.FeedBlob("X", X)
        workspace.FeedBlob("Y", Y)
        workspace.RunOperatorOnce(op)
        out = workspace.FetchBlob("out")
        np.testing.assert_array_almost_equal(
            out, X * Y[:, np.newaxis, np.newaxis, np.newaxis])
        self.assertGradientChecks(gc, op, [X, Y], 1, [0])
        self.assertDeviceChecks(dc, op, [X, Y], [0])

        # broadcasting with single elem dimensions at both ends
        X = np.random.rand(2, 3, 4, 5).astype(np.float32)
        Y = np.random.rand(1, 4, 1).astype(np.float32)
        op = core.CreateOperator("Mul", ["X", "Y"], "out", broadcast=1, axis=1)
        workspace.FeedBlob("X", X)
        workspace.FeedBlob("Y", Y)
        workspace.RunOperatorOnce(op)
        out = workspace.FetchBlob("out")
        np.testing.assert_array_almost_equal(out, X * Y)
        self.assertDeviceChecks(dc, op, [X, Y], [0])
        self.assertGradientChecks(gc, op, [X, Y], 1, [0])

    @given(**hu.gcs)
    def test_broadcast_Sub(self, gc, dc):
        # Set broadcast and no axis, i.e. broadcasting last dimensions.
        X = np.random.rand(2, 3, 4, 5).astype(np.float32)
        Y = np.random.rand(4, 5).astype(np.float32)
        op = core.CreateOperator("Sub", ["X", "Y"], "out", broadcast=1)
        workspace.FeedBlob("X", X)
        workspace.FeedBlob("Y", Y)
        workspace.RunOperatorOnce(op)
        out = workspace.FetchBlob("out")
        np.testing.assert_array_almost_equal(out, X - Y)
        self.assertDeviceChecks(dc, op, [X, Y], [0])
        self.assertGradientChecks(gc, op, [X, Y], 1, [0])

        # broadcasting intermediate dimensions
        X = np.random.rand(2, 3, 4, 5).astype(np.float32)
        Y = np.random.rand(3, 4).astype(np.float32)
        op = core.CreateOperator("Sub", ["X", "Y"], "out", broadcast=1, axis=1)
        workspace.FeedBlob("X", X)
        workspace.FeedBlob("Y", Y)
        workspace.RunOperatorOnce(op)
        out = workspace.FetchBlob("out")
        np.testing.assert_array_almost_equal(out, X - Y[:, :, np.newaxis])
        self.assertGradientChecks(gc, op, [X, Y], 1, [0])
        self.assertDeviceChecks(dc, op, [X, Y], [0])

        # broadcasting the first dimension
        X = np.random.rand(2, 3, 4, 5).astype(np.float32)
        Y = np.random.rand(2).astype(np.float32)
        op = core.CreateOperator("Sub", ["X", "Y"], "out", broadcast=1, axis=0)
        workspace.FeedBlob("X", X)
        workspace.FeedBlob("Y", Y)
        workspace.RunOperatorOnce(op)
        out = workspace.FetchBlob("out")
        np.testing.assert_array_almost_equal(
            out, X - Y[:, np.newaxis, np.newaxis, np.newaxis])
        self.assertGradientChecks(gc, op, [X, Y], 1, [0])
        self.assertDeviceChecks(dc, op, [X, Y], [0])

        # broadcasting with single elem dimensions at both ends
        X = np.random.rand(2, 3, 4, 5).astype(np.float32)
        Y = np.random.rand(1, 4, 1).astype(np.float32)
        op = core.CreateOperator("Sub", ["X", "Y"], "out", broadcast=1, axis=1)
        workspace.FeedBlob("X", X)
        workspace.FeedBlob("Y", Y)
        workspace.RunOperatorOnce(op)
        out = workspace.FetchBlob("out")
        np.testing.assert_array_almost_equal(out, X - Y)
        self.assertDeviceChecks(dc, op, [X, Y], [0])
        self.assertGradientChecks(gc, op, [X, Y], 1, [0])

    @serial.given(**hu.gcs)
    def test_broadcast_powt(self, gc, dc):
        np.random.seed(101)

        #operator
        def powt_op(X, Y):
            return [np.power(X, Y)]

        #two gradients Y*X^(Y-1) and X^Y * ln(X)
        def powt_grad(g_out, outputs, fwd_inputs):
            [X, Y] = fwd_inputs
            Z = outputs[0]
            return ([Y * np.power(X, Y - 1), Z * np.log(X)] * g_out)

        #1. Set broadcast and no axis, i.e. broadcasting last dimensions.
        X = np.random.rand(2, 3, 4, 5).astype(np.float32) + 1.0
        Y = np.random.rand(4, 5).astype(np.float32) + 2.0

        #two gradients Y*X^(Y-1) and X^Y * ln(X)
        #latter gradient is sumed over 1 and 0 dims to account for broadcast
        def powt_grad_broadcast(g_out, outputs, fwd_inputs):
            [GX, GY] = powt_grad(g_out, outputs, fwd_inputs)
            return ([GX, np.sum(np.sum(GY, 1), 0)])

        op = core.CreateOperator("Pow", ["X", "Y"], "Z", broadcast=1)
        self.assertReferenceChecks(device_option=gc,
                                   op=op,
                                   inputs=[X, Y],
                                   reference=powt_op,
                                   output_to_grad="Z",
                                   grad_reference=powt_grad_broadcast)

        #2. broadcasting intermediate dimensions
        X = np.random.rand(2, 3, 4, 5).astype(np.float32) + 1.0
        Y = np.random.rand(3, 4).astype(np.float32) + 2.0

        #pow op with the latter array increased by one dim
        def powt_op_axis1(X, Y):
            return powt_op(X, Y[:, :, np.newaxis])

        #two gradients Y*X^(Y-1) and X^Y * ln(X)
        #latter gradient is sumed over 3 and 0 dims to account for broadcast
        def powt_grad_axis1(g_out, outputs, fwd_inputs):
            [X, Y] = fwd_inputs
            [GX, GY] = powt_grad(g_out, outputs, [X, Y[:, :, np.newaxis]])
            return ([GX, np.sum(np.sum(GY, 3), 0)])

        op = core.CreateOperator("Pow", ["X", "Y"], "Z", broadcast=1, axis=1)
        self.assertReferenceChecks(device_option=gc,
                                   op=op,
                                   inputs=[X, Y],
                                   reference=powt_op_axis1,
                                   output_to_grad="Z",
                                   grad_reference=powt_grad_axis1)

        #3. broadcasting the first dimension
        X = np.random.rand(2, 3, 4, 5).astype(np.float32) + 1.0
        Y = np.random.rand(2).astype(np.float32) + 2.0

        #pow op with the latter array increased by one dim
        def powt_op_axis0(X, Y):
            return powt_op(X, Y[:, np.newaxis, np.newaxis, np.newaxis])

        #two gradients Y*X^(Y-1) and X^Y * ln(X)
        #latter gradient is sumed over 3, 2 and 1 dims to account for broadcast
        def powt_grad_axis0(g_out, outputs, fwd_inputs):
            [X, Y] = fwd_inputs
            [GX, GY] = powt_grad(g_out,
                                 outputs,
                                 [X, Y[:, np.newaxis, np.newaxis, np.newaxis]])
            return ([GX, np.sum(np.sum(np.sum(GY, 3), 2), 1)])

        op = core.CreateOperator("Pow", ["X", "Y"], "Z", broadcast=1, axis=0)
        self.assertReferenceChecks(device_option=gc,
                                   op=op,
                                   inputs=[X, Y],
                                   reference=powt_op_axis0,
                                   output_to_grad="Z",
                                   grad_reference=powt_grad_axis0)

        #4. broadcasting with single elem dimensions at both ends
        X = np.random.rand(2, 3, 4, 5).astype(np.float32) + 1.0
        Y = np.random.rand(1, 4, 1).astype(np.float32) + 2.0

        #pow op with the latter array increased by one dim
        def powt_op_mixed(X, Y):
            return powt_op(X, Y[np.newaxis, :, :, :])

        #two gradients Y*X^(Y-1) and X^Y * ln(X)
        #latter gradient is sumed over 0 and 1 dims to account for broadcast
        def powt_grad_mixed(g_out, outputs, fwd_inputs):
            [X, Y] = fwd_inputs
            [GX, GY] = powt_grad(g_out, outputs, [X, Y[np.newaxis, :, :, :]])
            return ([GX, np.reshape(np.sum(np.sum(np.sum(GY, 3), 1), 0),
                                    (1, 4, 1))])

        op = core.CreateOperator("Pow", ["X", "Y"], "Z", broadcast=1, axis=1)
        self.assertReferenceChecks(device_option=gc,
                                   op=op,
                                   inputs=[X, Y],
                                   reference=powt_op_mixed,
                                   output_to_grad="Z",
                                   grad_reference=powt_grad_mixed)

    @given(**hu.gcs)
    def test_broadcast_scalar(self, gc, dc):
        # broadcasting constant
        X = np.random.rand(2, 3, 4, 5).astype(np.float32)
        Y = np.random.rand(1).astype(np.float32)
        op = core.CreateOperator("Add", ["X", "Y"], "out", broadcast=1)
        workspace.FeedBlob("X", X)
        workspace.FeedBlob("Y", Y)
        workspace.RunOperatorOnce(op)
        out = workspace.FetchBlob("out")
        np.testing.assert_array_almost_equal(
            out, X + Y)
        self.assertDeviceChecks(dc, op, [X, Y], [0])

        # broadcasting scalar
        X = np.random.rand(1).astype(np.float32)
        Y = np.random.rand(1).astype(np.float32).reshape([])
        op = core.CreateOperator("Add", ["X", "Y"], "out", broadcast=1)
        workspace.FeedBlob("X", X)
        workspace.FeedBlob("Y", Y)
        workspace.RunOperatorOnce(op)
        out = workspace.FetchBlob("out")
        np.testing.assert_array_almost_equal(
            out, X + Y)
        self.assertDeviceChecks(dc, op, [X, Y], [0])

    @given(**hu.gcs)
    def test_semantic_broadcast(self, gc, dc):
        # NCHW as default
        X = np.random.rand(2, 3, 4, 5).astype(np.float32)
        Y = np.random.rand(3).astype(np.float32)
        op = core.CreateOperator(
            "Add", ["X", "Y"], "out", broadcast=1, axis_str="C")
        workspace.FeedBlob("X", X)
        workspace.FeedBlob("Y", Y)
        workspace.RunOperatorOnce(op)
        out = workspace.FetchBlob("out")
        np.testing.assert_array_almost_equal(
            out, X + Y[:, np.newaxis, np.newaxis])
        self.assertDeviceChecks(dc, op, [X, Y], [0])

        # NHWC
        X = np.random.rand(2, 3, 4, 5).astype(np.float32)
        Y = np.random.rand(5).astype(np.float32)
        op = core.CreateOperator(
            "Add", ["X", "Y"], "out", broadcast=1, axis_str="C", order="NHWC")
        workspace.FeedBlob("X", X)
        workspace.FeedBlob("Y", Y)
        workspace.RunOperatorOnce(op)
        out = workspace.FetchBlob("out")
        np.testing.assert_array_almost_equal(out, X + Y)
        self.assertDeviceChecks(dc, op, [X, Y], [0])

    @given(**hu.gcs)
    def test_sum_reduce_empty_blob(self, gc, dc):
        net = core.Net('test')

        with core.DeviceScope(gc):
            net.GivenTensorFill([], ["X"], values=[], shape=[2, 0, 5])
            net.GivenTensorFill([], ["Y"], values=[], shape=[2, 0])
            net.SumReduceLike(["X", "Y"], "out", axis=0)
            workspace.RunNetOnce(net)

    @given(**hu.gcs)
    def test_sum_reduce(self, gc, dc):
        # Set broadcast and no axis, i.e. broadcasting last dimensions.
        X = np.random.rand(2, 3, 4, 5).astype(np.float32)
        Y = np.random.rand(4, 5).astype(np.float32)
        op = core.CreateOperator(
            "SumReduceLike", ["X", "Y"], "out", broadcast=1)
        workspace.FeedBlob("X", X)
        workspace.FeedBlob("Y", Y)
        workspace.RunOperatorOnce(op)
        out = workspace.FetchBlob("out")
        res = np.sum(X, axis=0)
        res = np.sum(res, axis=0)
        np.testing.assert_array_almost_equal(out, res)
        self.assertDeviceChecks(dc, op, [X, Y], [0])

        # Set broadcast and no axis, i.e. broadcasting last dimensions.
        X = np.random.rand(2, 3, 4, 5).astype(np.float32)
        Y = np.random.rand(2, 3).astype(np.float32)
        op = core.CreateOperator(
            "SumReduceLike", ["X", "Y"], "out", broadcast=1, axis=0)
        workspace.FeedBlob("X", X)
        workspace.FeedBlob("Y", Y)
        workspace.RunOperatorOnce(op)
        out = workspace.FetchBlob("out")
        res = np.sum(X, axis=3)
        res = np.sum(res, axis=2)
        np.testing.assert_array_almost_equal(out, res, decimal=3)
        self.assertDeviceChecks(dc, op, [X, Y], [0])

        # broadcasting intermediate dimensions
        X = np.random.rand(2, 3, 4, 5).astype(np.float32)
        Y = np.random.rand(3, 4).astype(np.float32)
        op = core.CreateOperator(
            "SumReduceLike", ["X", "Y"], "out", broadcast=1, axis=1)
        workspace.FeedBlob("X", X)
        workspace.FeedBlob("Y", Y)
        workspace.RunOperatorOnce(op)
        out = workspace.FetchBlob("out")
        res = np.sum(X, axis=0)
        res = np.sum(res, axis=2)
        np.testing.assert_array_almost_equal(out, res)
        self.assertDeviceChecks(dc, op, [X, Y], [0])

        # broadcasting intermediate dimensions
        X = np.random.rand(2, 3, 4, 500).astype(np.float64)
        Y = np.random.rand(1).astype(np.float64)
        op = core.CreateOperator(
            "SumReduceLike", ["X", "Y"], "out", broadcast=1)
        workspace.FeedBlob("X", X)
        workspace.FeedBlob("Y", Y)
        workspace.RunOperatorOnce(op)
        out = workspace.FetchBlob("out")
        res = np.array(np.sum(X))
        np.testing.assert_array_almost_equal(out, res, decimal=0)

        # broadcasting with single elem dimensions at both ends
        X = np.random.rand(2, 3, 4, 5).astype(np.float32)
        Y = np.random.rand(1, 3, 4, 1).astype(np.float32)
        op = core.CreateOperator(
            "SumReduceLike", ["X", "Y"], "out", broadcast=1)
        workspace.FeedBlob("X", X)
        workspace.FeedBlob("Y", Y)
        workspace.RunOperatorOnce(op)
        out = workspace.FetchBlob("out")
        res = np.sum(X, axis=0)
        res = np.sum(res, axis=2).reshape(Y.shape)
        np.testing.assert_array_almost_equal(out, res)
        self.assertDeviceChecks(dc, op, [X, Y], [0])

        # fp64 is not supported with the CUDA op
        dc_cpu_only = [d for d in dc if d.device_type != caffe2_pb2.CUDA]
        self.assertDeviceChecks(dc_cpu_only, op, [X, Y], [0])

    @unittest.skipIf(not workspace.has_gpu_support, "No gpu support")
    @given(**hu.gcs_gpu_only)
    def test_sum_reduce_fp16(self, gc, dc):
        # Set broadcast and no axis, i.e. broadcasting last dimensions.
        X = np.random.rand(2, 3, 4, 5).astype(np.float16)
        Y = np.random.rand(4, 5).astype(np.float16)
        op = core.CreateOperator(
            "SumReduceLike", ["X", "Y"], "out", broadcast=1, device_option=gc)

        def ref_op(X, Y):
            res = np.sum(X, axis=0)
            res = np.sum(res, axis=0)
            return [res]

        self.assertReferenceChecks(
            device_option=gc,
            op=op,
            inputs=[X, Y],
            reference=ref_op,
            threshold=1e-3)

        # Set broadcast and no axis, i.e. broadcasting last dimensions.
        X = np.random.rand(2, 3, 4, 5).astype(np.float16)
        Y = np.random.rand(2, 3).astype(np.float16)
        op = core.CreateOperator(
            "SumReduceLike", ["X", "Y"], "out", broadcast=1, axis=0)

        def ref_op(X, Y):
            res = np.sum(X, axis=3)
            res = np.sum(res, axis=2)
            return [res]

        self.assertReferenceChecks(
            device_option=gc,
            op=op,
            inputs=[X, Y],
            reference=ref_op,
            threshold=1e-3)

        # broadcasting intermediate dimensions
        X = np.random.rand(2, 3, 4, 5).astype(np.float16)
        Y = np.random.rand(3, 4).astype(np.float16)
        op = core.CreateOperator(
            "SumReduceLike", ["X", "Y"], "out", broadcast=1, axis=1)

        def ref_op(X, Y):
            res = np.sum(X, axis=0)
            res = np.sum(res, axis=2)
            return [res]

        self.assertReferenceChecks(
            device_option=gc,
            op=op,
            inputs=[X, Y],
            reference=ref_op,
            threshold=1e-3)

        # broadcasting with single elem dimensions at both ends
        X = np.random.rand(2, 3, 4, 5).astype(np.float16)
        Y = np.random.rand(1, 3, 4, 1).astype(np.float16)
        op = core.CreateOperator(
            "SumReduceLike", ["X", "Y"], "out", broadcast=1)

        def ref_op(X, Y):
            res = np.sum(X, axis=0)
            res = np.sum(res, axis=2)
            return [res.reshape(Y.shape)]

        self.assertReferenceChecks(
            device_option=gc,
            op=op,
            inputs=[X, Y],
            reference=ref_op,
            threshold=1e-3)

if __name__ == "__main__":
    unittest.main()

[(19, 'hypothesis.given', 'given', ([], {}), False, 'from hypothesis import given\n'), (70, 'hypothesis.given', 'given', ([], {}), False, 'from hypothesis import given\n'), (121, 'hypothesis.given', 'given', ([], {}), False, 'from hypothesis import given\n'), (172, 'caffe2.python.serialized_test.serialized_test_util.given', 'serial.given', ([], {}), True, 'import caffe2.python.serialized_test.serialized_test_util as serial\n'), (276, 'hypothesis.given', 'given', ([], {}), False, 'from hypothesis import given\n'), (302, 'hypothesis.given', 'given', ([], {}), False, 'from hypothesis import given\n'), (329, 'hypothesis.given', 'given', ([], {}), False, 'from hypothesis import given\n'), (339, 'hypothesis.given', 'given', ([], {}), False, 'from hypothesis import given\n'), (413, 'unittest.skipIf', 'unittest.skipIf', (['(not workspace.has_gpu_support)', '"""No gpu support"""'], {}), False, 'import unittest\n'), (414, 'hypothesis.given', 'given', ([], {}), False, 'from hypothesis import given\n'), (489, 'unittest.main', 'unittest.main', ([], {}), False, 'import unittest\n'), (24, 'caffe2.python.core.CreateOperator', 'core.CreateOperator', (['"""Add"""', "['X', 'Y']", '"""out"""'], {'broadcast': '(1)'}), False, 'from caffe2.python import core, workspace\n'), (25, 'caffe2.python.workspace.FeedBlob', 'workspace.FeedBlob', (['"""X"""', 'X'], {}), False, 'from caffe2.python import core, workspace\n'), (26, 'caffe2.python.workspace.FeedBlob', 'workspace.FeedBlob', (['"""Y"""', 'Y'], {}), False, 'from caffe2.python import core, workspace\n'), (27, 'caffe2.python.workspace.RunOperatorOnce', 'workspace.RunOperatorOnce', (['op'], {}), False, 'from caffe2.python import core, workspace\n'), (28, 'caffe2.python.workspace.FetchBlob', 'workspace.FetchBlob', (['"""out"""'], {}), False, 'from caffe2.python import core, workspace\n'), (29, 'numpy.testing.assert_array_almost_equal', 'np.testing.assert_array_almost_equal', (['out', '(X + Y)'], {}), True, 'import numpy as np\n'), (36, 'caffe2.python.core.CreateOperator', 'core.CreateOperator', (['"""Add"""', "['X', 'Y']", '"""out"""'], {'broadcast': '(1)', 'axis': '(1)'}), False, 'from caffe2.python import core, workspace\n'), (37, 'caffe2.python.workspace.FeedBlob', 'workspace.FeedBlob', (['"""X"""', 'X'], {}), False, 'from caffe2.python import core, workspace\n'), (38, 'caffe2.python.workspace.FeedBlob', 'workspace.FeedBlob', (['"""Y"""', 'Y'], {}), False, 'from caffe2.python import core, workspace\n'), (39, 'caffe2.python.workspace.RunOperatorOnce', 'workspace.RunOperatorOnce', (['op'], {}), False, 'from caffe2.python import core, workspace\n'), (40, 'caffe2.python.workspace.FetchBlob', 'workspace.FetchBlob', (['"""out"""'], {}), False, 'from caffe2.python import core, workspace\n'), (41, 'numpy.testing.assert_array_almost_equal', 'np.testing.assert_array_almost_equal', (['out', '(X + Y[:, :, (np.newaxis)])'], {}), True, 'import numpy as np\n'), (48, 'caffe2.python.core.CreateOperator', 'core.CreateOperator', (['"""Add"""', "['X', 'Y']", '"""out"""'], {'broadcast': '(1)', 'axis': '(0)'}), False, 'from caffe2.python import core, workspace\n'), (49, 'caffe2.python.workspace.FeedBlob', 'workspace.FeedBlob', (['"""X"""', 'X'], {}), False, 'from caffe2.python import core, workspace\n'), (50, 'caffe2.python.workspace.FeedBlob', 'workspace.FeedBlob', (['"""Y"""', 'Y'], {}), False, 'from caffe2.python import core, workspace\n'), (51, 'caffe2.python.workspace.RunOperatorOnce', 'workspace.RunOperatorOnce', (['op'], {}), False, 'from caffe2.python import core, workspace\n'), (52, 'caffe2.python.workspace.FetchBlob', 'workspace.FetchBlob', (['"""out"""'], {}), False, 'from caffe2.python import core, workspace\n'), (53, 'numpy.testing.assert_array_almost_equal', 'np.testing.assert_array_almost_equal', (['out', '(X + Y[:, (np.newaxis), (np.newaxis), (np.newaxis)])'], {}), True, 'import numpy as np\n'), (61, 'caffe2.python.core.CreateOperator', 'core.CreateOperator', (['"""Add"""', "['X', 'Y']", '"""out"""'], {'broadcast': '(1)', 'axis': '(1)'}), False, 'from caffe2.python import core, workspace\n'), (62, 'caffe2.python.workspace.FeedBlob', 'workspace.FeedBlob', (['"""X"""', 'X'], {}), False, 'from caffe2.python import core, workspace\n'), (63, 'caffe2.python.workspace.FeedBlob', 'workspace.FeedBlob', (['"""Y"""', 'Y'], {}), False, 'from caffe2.python import core, workspace\n'), (64, 'caffe2.python.workspace.RunOperatorOnce', 'workspace.RunOperatorOnce', (['op'], {}), False, 'from caffe2.python import core, workspace\n'), (65, 'caffe2.python.workspace.FetchBlob', 'workspace.FetchBlob', (['"""out"""'], {}), False, 'from caffe2.python import core, workspace\n'), (66, 'numpy.testing.assert_array_almost_equal', 'np.testing.assert_array_almost_equal', (['out', '(X + Y)'], {}), True, 'import numpy as np\n'), (75, 'caffe2.python.core.CreateOperator', 'core.CreateOperator', (['"""Mul"""', "['X', 'Y']", '"""out"""'], {'broadcast': '(1)'}), False, 'from caffe2.python import core, workspace\n'), (76, 'caffe2.python.workspace.FeedBlob', 'workspace.FeedBlob', (['"""X"""', 'X'], {}), False, 'from caffe2.python import core, workspace\n'), (77, 'caffe2.python.workspace.FeedBlob', 'workspace.FeedBlob', (['"""Y"""', 'Y'], {}), False, 'from caffe2.python import core, workspace\n'), (78, 'caffe2.python.workspace.RunOperatorOnce', 'workspace.RunOperatorOnce', (['op'], {}), False, 'from caffe2.python import core, workspace\n'), (79, 'caffe2.python.workspace.FetchBlob', 'workspace.FetchBlob', (['"""out"""'], {}), False, 'from caffe2.python import core, workspace\n'), (80, 'numpy.testing.assert_array_almost_equal', 'np.testing.assert_array_almost_equal', (['out', '(X * Y)'], {}), True, 'import numpy as np\n'), (87, 'caffe2.python.core.CreateOperator', 'core.CreateOperator', (['"""Mul"""', "['X', 'Y']", '"""out"""'], {'broadcast': '(1)', 'axis': '(1)'}), False, 'from caffe2.python import core, workspace\n'), (88, 'caffe2.python.workspace.FeedBlob', 'workspace.FeedBlob', (['"""X"""', 'X'], {}), False, 'from caffe2.python import core, workspace\n'), (89, 'caffe2.python.workspace.FeedBlob', 'workspace.FeedBlob', (['"""Y"""', 'Y'], {}), False, 'from caffe2.python import core, workspace\n'), (90, 'caffe2.python.workspace.RunOperatorOnce', 'workspace.RunOperatorOnce', (['op'], {}), False, 'from caffe2.python import core, workspace\n'), (91, 'caffe2.python.workspace.FetchBlob', 'workspace.FetchBlob', (['"""out"""'], {}), False, 'from caffe2.python import core, workspace\n'), (92, 'numpy.testing.assert_array_almost_equal', 'np.testing.assert_array_almost_equal', (['out', '(X * Y[:, :, (np.newaxis)])'], {}), True, 'import numpy as np\n'), (99, 'caffe2.python.core.CreateOperator', 'core.CreateOperator', (['"""Mul"""', "['X', 'Y']", '"""out"""'], {'broadcast': '(1)', 'axis': '(0)'}), False, 'from caffe2.python import core, workspace\n'), (100, 'caffe2.python.workspace.FeedBlob', 'workspace.FeedBlob', (['"""X"""', 'X'], {}), False, 'from caffe2.python import core, workspace\n'), (101, 'caffe2.python.workspace.FeedBlob', 'workspace.FeedBlob', (['"""Y"""', 'Y'], {}), False, 'from caffe2.python import core, workspace\n'), (102, 'caffe2.python.workspace.RunOperatorOnce', 'workspace.RunOperatorOnce', (['op'], {}), False, 'from caffe2.python import core, workspace\n'), (103, 'caffe2.python.workspace.FetchBlob', 'workspace.FetchBlob', (['"""out"""'], {}), False, 'from caffe2.python import core, workspace\n'), (104, 'numpy.testing.assert_array_almost_equal', 'np.testing.assert_array_almost_equal', (['out', '(X * Y[:, (np.newaxis), (np.newaxis), (np.newaxis)])'], {}), True, 'import numpy as np\n'), (112, 'caffe2.python.core.CreateOperator', 'core.CreateOperator', (['"""Mul"""', "['X', 'Y']", '"""out"""'], {'broadcast': '(1)', 'axis': '(1)'}), False, 'from caffe2.python import core, workspace\n'), (113, 'caffe2.python.workspace.FeedBlob', 'workspace.FeedBlob', (['"""X"""', 'X'], {}), False, 'from caffe2.python import core, workspace\n'), (114, 'caffe2.python.workspace.FeedBlob', 'workspace.FeedBlob', (['"""Y"""', 'Y'], {}), False, 'from caffe2.python import core, workspace\n'), (115, 'caffe2.python.workspace.RunOperatorOnce', 'workspace.RunOperatorOnce', (['op'], {}), False, 'from caffe2.python import core, workspace\n'), (116, 'caffe2.python.workspace.FetchBlob', 'workspace.FetchBlob', (['"""out"""'], {}), False, 'from caffe2.python import core, workspace\n'), (117, 'numpy.testing.assert_array_almost_equal', 'np.testing.assert_array_almost_equal', (['out', '(X * Y)'], {}), True, 'import numpy as np\n'), (126, 'caffe2.python.core.CreateOperator', 'core.CreateOperator', (['"""Sub"""', "['X', 'Y']", '"""out"""'], {'broadcast': '(1)'}), False, 'from caffe2.python import core, workspace\n'), (127, 'caffe2.python.workspace.FeedBlob', 'workspace.FeedBlob', (['"""X"""', 'X'], {}), False, 'from caffe2.python import core, workspace\n'), (128, 'caffe2.python.workspace.FeedBlob', 'workspace.FeedBlob', (['"""Y"""', 'Y'], {}), False, 'from caffe2.python import core, workspace\n'), (129, 'caffe2.python.workspace.RunOperatorOnce', 'workspace.RunOperatorOnce', (['op'], {}), False, 'from caffe2.python import core, workspace\n'), (130, 'caffe2.python.workspace.FetchBlob', 'workspace.FetchBlob', (['"""out"""'], {}), False, 'from caffe2.python import core, workspace\n'), (131, 'numpy.testing.assert_array_almost_equal', 'np.testing.assert_array_almost_equal', (['out', '(X - Y)'], {}), True, 'import numpy as np\n'), (138, 'caffe2.python.core.CreateOperator', 'core.CreateOperator', (['"""Sub"""', "['X', 'Y']", '"""out"""'], {'broadcast': '(1)', 'axis': '(1)'}), False, 'from caffe2.python import core, workspace\n'), (139, 'caffe2.python.workspace.FeedBlob', 'workspace.FeedBlob', (['"""X"""', 'X'], {}), False, 'from caffe2.python import core, workspace\n'), (140, 'caffe2.python.workspace.FeedBlob', 'workspace.FeedBlob', (['"""Y"""', 'Y'], {}), False, 'from caffe2.python import core, workspace\n'), (141, 'caffe2.python.workspace.RunOperatorOnce', 'workspace.RunOperatorOnce', (['op'], {}), False, 'from caffe2.python import core, workspace\n'), (142, 'caffe2.python.workspace.FetchBlob', 'workspace.FetchBlob', (['"""out"""'], {}), False, 'from caffe2.python import core, workspace\n'), (143, 'numpy.testing.assert_array_almost_equal', 'np.testing.assert_array_almost_equal', (['out', '(X - Y[:, :, (np.newaxis)])'], {}), True, 'import numpy as np\n'), (150, 'caffe2.python.core.CreateOperator', 'core.CreateOperator', (['"""Sub"""', "['X', 'Y']", '"""out"""'], {'broadcast': '(1)', 'axis': '(0)'}), False, 'from caffe2.python import core, workspace\n'), (151, 'caffe2.python.workspace.FeedBlob', 'workspace.FeedBlob', (['"""X"""', 'X'], {}), False, 'from caffe2.python import core, workspace\n'), (152, 'caffe2.python.workspace.FeedBlob', 'workspace.FeedBlob', (['"""Y"""', 'Y'], {}), False, 'from caffe2.python import core, workspace\n'), (153, 'caffe2.python.workspace.RunOperatorOnce', 'workspace.RunOperatorOnce', (['op'], {}), False, 'from caffe2.python import core, workspace\n'), (154, 'caffe2.python.workspace.FetchBlob', 'workspace.FetchBlob', (['"""out"""'], {}), False, 'from caffe2.python import core, workspace\n'), (155, 'numpy.testing.assert_array_almost_equal', 'np.testing.assert_array_almost_equal', (['out', '(X - Y[:, (np.newaxis), (np.newaxis), (np.newaxis)])'], {}), True, 'import numpy as np\n'), (163, 'caffe2.python.core.CreateOperator', 'core.CreateOperator', (['"""Sub"""', "['X', 'Y']", '"""out"""'], {'broadcast': '(1)', 'axis': '(1)'}), False, 'from caffe2.python import core, workspace\n'), (164, 'caffe2.python.workspace.FeedBlob', 'workspace.FeedBlob', (['"""X"""', 'X'], {}), False, 'from caffe2.python import core, workspace\n'), (165, 'caffe2.python.workspace.FeedBlob', 'workspace.FeedBlob', (['"""Y"""', 'Y'], {}), False, 'from caffe2.python import core, workspace\n'), (166, 'caffe2.python.workspace.RunOperatorOnce', 'workspace.RunOperatorOnce', (['op'], {}), False, 'from caffe2.python import core, workspace\n'), (167, 'caffe2.python.workspace.FetchBlob', 'workspace.FetchBlob', (['"""out"""'], {}), False, 'from caffe2.python import core, workspace\n'), (168, 'numpy.testing.assert_array_almost_equal', 'np.testing.assert_array_almost_equal', (['out', '(X - Y)'], {}), True, 'import numpy as np\n'), (174, 'numpy.random.seed', 'np.random.seed', (['(101)'], {}), True, 'import numpy as np\n'), (196, 'caffe2.python.core.CreateOperator', 'core.CreateOperator', (['"""Pow"""', "['X', 'Y']", '"""Z"""'], {'broadcast': '(1)'}), False, 'from caffe2.python import core, workspace\n'), (219, 'caffe2.python.core.CreateOperator', 'core.CreateOperator', (['"""Pow"""', "['X', 'Y']", '"""Z"""'], {'broadcast': '(1)', 'axis': '(1)'}), False, 'from caffe2.python import core, workspace\n'), (244, 'caffe2.python.core.CreateOperator', 'core.CreateOperator', (['"""Pow"""', "['X', 'Y']", '"""Z"""'], {'broadcast': '(1)', 'axis': '(0)'}), False, 'from caffe2.python import core, workspace\n'), (268, 'caffe2.python.core.CreateOperator', 'core.CreateOperator', (['"""Pow"""', "['X', 'Y']", '"""Z"""'], {'broadcast': '(1)', 'axis': '(1)'}), False, 'from caffe2.python import core, workspace\n'), (281, 'caffe2.python.core.CreateOperator', 'core.CreateOperator', (['"""Add"""', "['X', 'Y']", '"""out"""'], {'broadcast': '(1)'}), False, 'from caffe2.python import core, workspace\n'), (282, 'caffe2.python.workspace.FeedBlob', 'workspace.FeedBlob', (['"""X"""', 'X'], {}), False, 'from caffe2.python import core, workspace\n'), (283, 'caffe2.python.workspace.FeedBlob', 'workspace.FeedBlob', (['"""Y"""', 'Y'], {}), False, 'from caffe2.python import core, workspace\n'), (284, 'caffe2.python.workspace.RunOperatorOnce', 'workspace.RunOperatorOnce', (['op'], {}), False, 'from caffe2.python import core, workspace\n'), (285, 'caffe2.python.workspace.FetchBlob', 'workspace.FetchBlob', (['"""out"""'], {}), False, 'from caffe2.python import core, workspace\n'), (286, 'numpy.testing.assert_array_almost_equal', 'np.testing.assert_array_almost_equal', (['out', '(X + Y)'], {}), True, 'import numpy as np\n'), (293, 'caffe2.python.core.CreateOperator', 'core.CreateOperator', (['"""Add"""', "['X', 'Y']", '"""out"""'], {'broadcast': '(1)'}), False, 'from caffe2.python import core, workspace\n'), (294, 'caffe2.python.workspace.FeedBlob', 'workspace.FeedBlob', (['"""X"""', 'X'], {}), False, 'from caffe2.python import core, workspace\n'), (295, 'caffe2.python.workspace.FeedBlob', 'workspace.FeedBlob', (['"""Y"""', 'Y'], {}), False, 'from caffe2.python import core, workspace\n'), (296, 'caffe2.python.workspace.RunOperatorOnce', 'workspace.RunOperatorOnce', (['op'], {}), False, 'from caffe2.python import core, workspace\n'), (297, 'caffe2.python.workspace.FetchBlob', 'workspace.FetchBlob', (['"""out"""'], {}), False, 'from caffe2.python import core, workspace\n'), (298, 'numpy.testing.assert_array_almost_equal', 'np.testing.assert_array_almost_equal', (['out', '(X + Y)'], {}), True, 'import numpy as np\n'), (307, 'caffe2.python.core.CreateOperator', 'core.CreateOperator', (['"""Add"""', "['X', 'Y']", '"""out"""'], {'broadcast': '(1)', 'axis_str': '"""C"""'}), False, 'from caffe2.python import core, workspace\n'), (309, 'caffe2.python.workspace.FeedBlob', 'workspace.FeedBlob', (['"""X"""', 'X'], {}), False, 'from caffe2.python import core, workspace\n'), (310, 'caffe2.python.workspace.FeedBlob', 'workspace.FeedBlob', (['"""Y"""', 'Y'], {}), False, 'from caffe2.python import core, workspace\n'), (311, 'caffe2.python.workspace.RunOperatorOnce', 'workspace.RunOperatorOnce', (['op'], {}), False, 'from caffe2.python import core, workspace\n'), (312, 'caffe2.python.workspace.FetchBlob', 'workspace.FetchBlob', (['"""out"""'], {}), False, 'from caffe2.python import core, workspace\n'), (313, 'numpy.testing.assert_array_almost_equal', 'np.testing.assert_array_almost_equal', (['out', '(X + Y[:, (np.newaxis), (np.newaxis)])'], {}), True, 'import numpy as np\n'), (320, 'caffe2.python.core.CreateOperator', 'core.CreateOperator', (['"""Add"""', "['X', 'Y']", '"""out"""'], {'broadcast': '(1)', 'axis_str': '"""C"""', 'order': '"""NHWC"""'}), False, 'from caffe2.python import core, workspace\n'), (322, 'caffe2.python.workspace.FeedBlob', 'workspace.FeedBlob', (['"""X"""', 'X'], {}), False, 'from caffe2.python import core, workspace\n'), (323, 'caffe2.python.workspace.FeedBlob', 'workspace.FeedBlob', (['"""Y"""', 'Y'], {}), False, 'from caffe2.python import core, workspace\n'), (324, 'caffe2.python.workspace.RunOperatorOnce', 'workspace.RunOperatorOnce', (['op'], {}), False, 'from caffe2.python import core, workspace\n'), (325, 'caffe2.python.workspace.FetchBlob', 'workspace.FetchBlob', (['"""out"""'], {}), False, 'from caffe2.python import core, workspace\n'), (326, 'numpy.testing.assert_array_almost_equal', 'np.testing.assert_array_almost_equal', (['out', '(X + Y)'], {}), True, 'import numpy as np\n'), (331, 'caffe2.python.core.Net', 'core.Net', (['"""test"""'], {}), False, 'from caffe2.python import core, workspace\n'), (344, 'caffe2.python.core.CreateOperator', 'core.CreateOperator', (['"""SumReduceLike"""', "['X', 'Y']", '"""out"""'], {'broadcast': '(1)'}), False, 'from caffe2.python import core, workspace\n'), (346, 'caffe2.python.workspace.FeedBlob', 'workspace.FeedBlob', (['"""X"""', 'X'], {}), False, 'from caffe2.python import core, workspace\n'), (347, 'caffe2.python.workspace.FeedBlob', 'workspace.FeedBlob', (['"""Y"""', 'Y'], {}), False, 'from caffe2.python import core, workspace\n'), (348, 'caffe2.python.workspace.RunOperatorOnce', 'workspace.RunOperatorOnce', (['op'], {}), False, 'from caffe2.python import core, workspace\n'), (349, 'caffe2.python.workspace.FetchBlob', 'workspace.FetchBlob', (['"""out"""'], {}), False, 'from caffe2.python import core, workspace\n'), (350, 'numpy.sum', 'np.sum', (['X'], {'axis': '(0)'}), True, 'import numpy as np\n'), (351, 'numpy.sum', 'np.sum', (['res'], {'axis': '(0)'}), True, 'import numpy as np\n'), (352, 'numpy.testing.assert_array_almost_equal', 'np.testing.assert_array_almost_equal', (['out', 'res'], {}), True, 'import numpy as np\n'), (358, 'caffe2.python.core.CreateOperator', 'core.CreateOperator', (['"""SumReduceLike"""', "['X', 'Y']", '"""out"""'], {'broadcast': '(1)', 'axis': '(0)'}), False, 'from caffe2.python import core, workspace\n'), (360, 'caffe2.python.workspace.FeedBlob', 'workspace.FeedBlob', (['"""X"""', 'X'], {}), False, 'from caffe2.python import core, workspace\n'), (361, 'caffe2.python.workspace.FeedBlob', 'workspace.FeedBlob', (['"""Y"""', 'Y'], {}), False, 'from caffe2.python import core, workspace\n'), (362, 'caffe2.python.workspace.RunOperatorOnce', 'workspace.RunOperatorOnce', (['op'], {}), False, 'from caffe2.python import core, workspace\n'), (363, 'caffe2.python.workspace.FetchBlob', 'workspace.FetchBlob', (['"""out"""'], {}), False, 'from caffe2.python import core, workspace\n'), (364, 'numpy.sum', 'np.sum', (['X'], {'axis': '(3)'}), True, 'import numpy as np\n'), (365, 'numpy.sum', 'np.sum', (['res'], {'axis': '(2)'}), True, 'import numpy as np\n'), (366, 'numpy.testing.assert_array_almost_equal', 'np.testing.assert_array_almost_equal', (['out', 'res'], {'decimal': '(3)'}), True, 'import numpy as np\n'), (372, 'caffe2.python.core.CreateOperator', 'core.CreateOperator', (['"""SumReduceLike"""', "['X', 'Y']", '"""out"""'], {'broadcast': '(1)', 'axis': '(1)'}), False, 'from caffe2.python import core, workspace\n'), (374, 'caffe2.python.workspace.FeedBlob', 'workspace.FeedBlob', (['"""X"""', 'X'], {}), False, 'from caffe2.python import core, workspace\n'), (375, 'caffe2.python.workspace.FeedBlob', 'workspace.FeedBlob', (['"""Y"""', 'Y'], {}), False, 'from caffe2.python import core, workspace\n'), (376, 'caffe2.python.workspace.RunOperatorOnce', 'workspace.RunOperatorOnce', (['op'], {}), False, 'from caffe2.python import core, workspace\n'), (377, 'caffe2.python.workspace.FetchBlob', 'workspace.FetchBlob', (['"""out"""'], {}), False, 'from caffe2.python import core, workspace\n'), (378, 'numpy.sum', 'np.sum', (['X'], {'axis': '(0)'}), True, 'import numpy as np\n'), (379, 'numpy.sum', 'np.sum', (['res'], {'axis': '(2)'}), True, 'import numpy as np\n'), (380, 'numpy.testing.assert_array_almost_equal', 'np.testing.assert_array_almost_equal', (['out', 'res'], {}), True, 'import numpy as np\n'), (386, 'caffe2.python.core.CreateOperator', 'core.CreateOperator', (['"""SumReduceLike"""', "['X', 'Y']", '"""out"""'], {'broadcast': '(1)'}), False, 'from caffe2.python import core, workspace\n'), (388, 'caffe2.python.workspace.FeedBlob', 'workspace.FeedBlob', (['"""X"""', 'X'], {}), False, 'from caffe2.python import core, workspace\n'), (389, 'caffe2.python.workspace.FeedBlob', 'workspace.FeedBlob', (['"""Y"""', 'Y'], {}), False, 'from caffe2.python import core, workspace\n'), (390, 'caffe2.python.workspace.RunOperatorOnce', 'workspace.RunOperatorOnce', (['op'], {}), False, 'from caffe2.python import core, workspace\n'), (391, 'caffe2.python.workspace.FetchBlob', 'workspace.FetchBlob', (['"""out"""'], {}), False, 'from caffe2.python import core, workspace\n'), (393, 'numpy.testing.assert_array_almost_equal', 'np.testing.assert_array_almost_equal', (['out', 'res'], {'decimal': '(0)'}), True, 'import numpy as np\n'), (398, 'caffe2.python.core.CreateOperator', 'core.CreateOperator', (['"""SumReduceLike"""', "['X', 'Y']", '"""out"""'], {'broadcast': '(1)'}), False, 'from caffe2.python import core, workspace\n'), (400, 'caffe2.python.workspace.FeedBlob', 'workspace.FeedBlob', (['"""X"""', 'X'], {}), False, 'from caffe2.python import core, workspace\n'), (401, 'caffe2.python.workspace.FeedBlob', 'workspace.FeedBlob', (['"""Y"""', 'Y'], {}), False, 'from caffe2.python import core, workspace\n'), (402, 'caffe2.python.workspace.RunOperatorOnce', 'workspace.RunOperatorOnce', (['op'], {}), False, 'from caffe2.python import core, workspace\n'), (403, 'caffe2.python.workspace.FetchBlob', 'workspace.FetchBlob', (['"""out"""'], {}), False, 'from caffe2.python import core, workspace\n'), (404, 'numpy.sum', 'np.sum', (['X'], {'axis': '(0)'}), True, 'import numpy as np\n'), (406, 'numpy.testing.assert_array_almost_equal', 'np.testing.assert_array_almost_equal', (['out', 'res'], {}), True, 'import numpy as np\n'), (419, 'caffe2.python.core.CreateOperator', 'core.CreateOperator', (['"""SumReduceLike"""', "['X', 'Y']", '"""out"""'], {'broadcast': '(1)', 'device_option': 'gc'}), False, 'from caffe2.python import core, workspace\n'), (437, 'caffe2.python.core.CreateOperator', 'core.CreateOperator', (['"""SumReduceLike"""', "['X', 'Y']", '"""out"""'], {'broadcast': '(1)', 'axis': '(0)'}), False, 'from caffe2.python import core, workspace\n'), (455, 'caffe2.python.core.CreateOperator', 'core.CreateOperator', (['"""SumReduceLike"""', "['X', 'Y']", '"""out"""'], {'broadcast': '(1)', 'axis': '(1)'}), False, 'from caffe2.python import core, workspace\n'), (473, 'caffe2.python.core.CreateOperator', 'core.CreateOperator', (['"""SumReduceLike"""', "['X', 'Y']", '"""out"""'], {'broadcast': '(1)'}), False, 'from caffe2.python import core, workspace\n'), (333, 'caffe2.python.core.DeviceScope', 'core.DeviceScope', (['gc'], {}), False, 'from caffe2.python import core, workspace\n'), (337, 'caffe2.python.workspace.RunNetOnce', 'workspace.RunNetOnce', (['net'], {}), False, 'from caffe2.python import core, workspace\n'), (392, 'numpy.sum', 'np.sum', (['X'], {}), True, 'import numpy as np\n'), (423, 'numpy.sum', 'np.sum', (['X'], {'axis': '(0)'}), True, 'import numpy as np\n'), (424, 'numpy.sum', 'np.sum', (['res'], {'axis': '(0)'}), True, 'import numpy as np\n'), (441, 'numpy.sum', 'np.sum', (['X'], {'axis': '(3)'}), True, 'import numpy as np\n'), (442, 'numpy.sum', 'np.sum', (['res'], {'axis': '(2)'}), True, 'import numpy as np\n'), (459, 'numpy.sum', 'np.sum', (['X'], {'axis': '(0)'}), True, 'import numpy as np\n'), (460, 'numpy.sum', 'np.sum', (['res'], {'axis': '(2)'}), True, 'import numpy as np\n'), (477, 'numpy.sum', 'np.sum', (['X'], {'axis': '(0)'}), True, 'import numpy as np\n'), (478, 'numpy.sum', 'np.sum', (['res'], {'axis': '(2)'}), True, 'import numpy as np\n'), (22, 'numpy.random.rand', 'np.random.rand', (['(2)', '(3)', '(4)', '(5)'], {}), True, 'import numpy as np\n'), (23, 'numpy.random.rand', 'np.random.rand', (['(4)', '(5)'], {}), True, 'import numpy as np\n'), (34, 'numpy.random.rand', 'np.random.rand', (['(2)', '(3)', '(4)', '(5)'], {}), True, 'import numpy as np\n'), (35, 'numpy.random.rand', 'np.random.rand', (['(3)', '(4)'], {}), True, 'import numpy as np\n'), (46, 'numpy.random.rand', 'np.random.rand', (['(2)', '(3)', '(4)', '(5)'], {}), True, 'import numpy as np\n'), (47, 'numpy.random.rand', 'np.random.rand', (['(2)'], {}), True, 'import numpy as np\n'), (59, 'numpy.random.rand', 'np.random.rand', (['(2)', '(3)', '(4)', '(5)'], {}), True, 'import numpy as np\n'), (60, 'numpy.random.rand', 'np.random.rand', (['(1)', '(4)', '(1)'], {}), True, 'import numpy as np\n'), (73, 'numpy.random.rand', 'np.random.rand', (['(2)', '(3)', '(4)', '(5)'], {}), True, 'import numpy as np\n'), (74, 'numpy.random.rand', 'np.random.rand', (['(4)', '(5)'], {}), True, 'import numpy as np\n'), (85, 'numpy.random.rand', 'np.random.rand', (['(2)', '(3)', '(4)', '(5)'], {}), True, 'import numpy as np\n'), (86, 'numpy.random.rand', 'np.random.rand', (['(3)', '(4)'], {}), True, 'import numpy as np\n'), (97, 'numpy.random.rand', 'np.random.rand', (['(2)', '(3)', '(4)', '(5)'], {}), True, 'import numpy as np\n'), (98, 'numpy.random.rand', 'np.random.rand', (['(2)'], {}), True, 'import numpy as np\n'), (110, 'numpy.random.rand', 'np.random.rand', (['(2)', '(3)', '(4)', '(5)'], {}), True, 'import numpy as np\n'), (111, 'numpy.random.rand', 'np.random.rand', (['(1)', '(4)', '(1)'], {}), True, 'import numpy as np\n'), (124, 'numpy.random.rand', 'np.random.rand', (['(2)', '(3)', '(4)', '(5)'], {}), True, 'import numpy as np\n'), (125, 'numpy.random.rand', 'np.random.rand', (['(4)', '(5)'], {}), True, 'import numpy as np\n'), (136, 'numpy.random.rand', 'np.random.rand', (['(2)', '(3)', '(4)', '(5)'], {}), True, 'import numpy as np\n'), (137, 'numpy.random.rand', 'np.random.rand', (['(3)', '(4)'], {}), True, 'import numpy as np\n'), (148, 'numpy.random.rand', 'np.random.rand', (['(2)', '(3)', '(4)', '(5)'], {}), True, 'import numpy as np\n'), (149, 'numpy.random.rand', 'np.random.rand', (['(2)'], {}), True, 'import numpy as np\n'), (161, 'numpy.random.rand', 'np.random.rand', (['(2)', '(3)', '(4)', '(5)'], {}), True, 'import numpy as np\n'), (162, 'numpy.random.rand', 'np.random.rand', (['(1)', '(4)', '(1)'], {}), True, 'import numpy as np\n'), (178, 'numpy.power', 'np.power', (['X', 'Y'], {}), True, 'import numpy as np\n'), (279, 'numpy.random.rand', 'np.random.rand', (['(2)', '(3)', '(4)', '(5)'], {}), True, 'import numpy as np\n'), (280, 'numpy.random.rand', 'np.random.rand', (['(1)'], {}), True, 'import numpy as np\n'), (291, 'numpy.random.rand', 'np.random.rand', (['(1)'], {}), True, 'import numpy as np\n'), (305, 'numpy.random.rand', 'np.random.rand', (['(2)', '(3)', '(4)', '(5)'], {}), True, 'import numpy as np\n'), (306, 'numpy.random.rand', 'np.random.rand', (['(3)'], {}), True, 'import numpy as np\n'), (318, 'numpy.random.rand', 'np.random.rand', (['(2)', '(3)', '(4)', '(5)'], {}), True, 'import numpy as np\n'), (319, 'numpy.random.rand', 'np.random.rand', (['(5)'], {}), True, 'import numpy as np\n'), (342, 'numpy.random.rand', 'np.random.rand', (['(2)', '(3)', '(4)', '(5)'], {}), True, 'import numpy as np\n'), (343, 'numpy.random.rand', 'np.random.rand', (['(4)', '(5)'], {}), True, 'import numpy as np\n'), (356, 'numpy.random.rand', 'np.random.rand', (['(2)', '(3)', '(4)', '(5)'], {}), True, 'import numpy as np\n'), (357, 'numpy.random.rand', 'np.random.rand', (['(2)', '(3)'], {}), True, 'import numpy as np\n'), (370, 'numpy.random.rand', 'np.random.rand', (['(2)', '(3)', '(4)', '(5)'], {}), True, 'import numpy as np\n'), (371, 'numpy.random.rand', 'np.random.rand', (['(3)', '(4)'], {}), True, 'import numpy as np\n'), (384, 'numpy.random.rand', 'np.random.rand', (['(2)', '(3)', '(4)', '(500)'], {}), True, 'import numpy as np\n'), (385, 'numpy.random.rand', 'np.random.rand', (['(1)'], {}), True, 'import numpy as np\n'), (396, 'numpy.random.rand', 'np.random.rand', (['(2)', '(3)', '(4)', '(5)'], {}), True, 'import numpy as np\n'), (397, 'numpy.random.rand', 'np.random.rand', (['(1)', '(3)', '(4)', '(1)'], {}), True, 'import numpy as np\n'), (405, 'numpy.sum', 'np.sum', (['res'], {'axis': '(2)'}), True, 'import numpy as np\n'), (417, 'numpy.random.rand', 'np.random.rand', (['(2)', '(3)', '(4)', '(5)'], {}), True, 'import numpy as np\n'), (418, 'numpy.random.rand', 'np.random.rand', (['(4)', '(5)'], {}), True, 'import numpy as np\n'), (435, 'numpy.random.rand', 'np.random.rand', (['(2)', '(3)', '(4)', '(5)'], {}), True, 'import numpy as np\n'), (436, 'numpy.random.rand', 'np.random.rand', (['(2)', '(3)'], {}), True, 'import numpy as np\n'), (453, 'numpy.random.rand', 'np.random.rand', (['(2)', '(3)', '(4)', '(5)'], {}), True, 'import numpy as np\n'), (454, 'numpy.random.rand', 'np.random.rand', (['(3)', '(4)'], {}), True, 'import numpy as np\n'), (471, 'numpy.random.rand', 'np.random.rand', (['(2)', '(3)', '(4)', '(5)'], {}), True, 'import numpy as np\n'), (472, 'numpy.random.rand', 'np.random.rand', (['(1)', '(3)', '(4)', '(1)'], {}), True, 'import numpy as np\n'), (187, 'numpy.random.rand', 'np.random.rand', (['(2)', '(3)', '(4)', '(5)'], {}), True, 'import numpy as np\n'), (188, 'numpy.random.rand', 'np.random.rand', (['(4)', '(5)'], {}), True, 'import numpy as np\n'), (194, 'numpy.sum', 'np.sum', (['GY', '(1)'], {}), True, 'import numpy as np\n'), (205, 'numpy.random.rand', 'np.random.rand', (['(2)', '(3)', '(4)', '(5)'], {}), True, 'import numpy as np\n'), (206, 'numpy.random.rand', 'np.random.rand', (['(3)', '(4)'], {}), True, 'import numpy as np\n'), (217, 'numpy.sum', 'np.sum', (['GY', '(3)'], {}), True, 'import numpy as np\n'), (228, 'numpy.random.rand', 'np.random.rand', (['(2)', '(3)', '(4)', '(5)'], {}), True, 'import numpy as np\n'), (229, 'numpy.random.rand', 'np.random.rand', (['(2)'], {}), True, 'import numpy as np\n'), (253, 'numpy.random.rand', 'np.random.rand', (['(2)', '(3)', '(4)', '(5)'], {}), True, 'import numpy as np\n'), (254, 'numpy.random.rand', 'np.random.rand', (['(1)', '(4)', '(1)'], {}), True, 'import numpy as np\n'), (184, 'numpy.power', 'np.power', (['X', '(Y - 1)'], {}), True, 'import numpy as np\n'), (184, 'numpy.log', 'np.log', (['X'], {}), True, 'import numpy as np\n'), (242, 'numpy.sum', 'np.sum', (['GY', '(3)'], {}), True, 'import numpy as np\n'), (292, 'numpy.random.rand', 'np.random.rand', (['(1)'], {}), True, 'import numpy as np\n'), (265, 'numpy.sum', 'np.sum', (['GY', '(3)'], {}), True, 'import numpy as np\n')]