{"action":"created","comment":{"url":"https://api.github.com/repos/Theano/Theano/pulls/comments/27450419","id":27450419,"diff_hunk":"@@ -2591,6 +2595,139 @@ def local_adv_sub1_adv_inc_sub1(node):\n     return [T.cast(y, node.outputs[0].dtype)]\n \n \n+@register_specialize\n+@register_stabilize\n+@register_canonicalize\n+@gof.local_optimizer([IncSubtensor,\n+                      AdvancedIncSubtensor,\n+                      AdvancedIncSubtensor1])\n+def local_useless_incsubtensor_alloc(node):\n+    \"\"\"\n+    Replaces an [Advanced]IncSubtensor[1], whose increment is an `alloc` of\n+    a fully or partially broadcastable variable, by one that skips the\n+    intermediate `alloc` where possible.\n+    \"\"\"\n+    if isinstance(node.op, (IncSubtensor,\n+                            AdvancedIncSubtensor,\n+                            AdvancedIncSubtensor1)):\n+        x = node.inputs[0]\n+        y = node.inputs[1]\n+        i = node.inputs[2:]\n+\n+        if y.owner is not None and isinstance(y.owner.op, T.Alloc):\n+            # `z` is the input of the Alloc op, i.e. T.alloc(z, <shape>)\n+            z = y.owner.inputs[0]\n+\n+            # The following check is to prevent removal of shape errors.\n+            try:\n+                same_shape = node.fgraph.shape_feature.same_shape\n+\n+                # Get the subtensor of `x` indexed by `i` in order to compare\n+                # shapes later.\n+                if isinstance(node.op, IncSubtensor):\n+                    xi = Subtensor(node.op.idx_list)(x, *i)\n+                elif isinstance(node.op, AdvancedIncSubtensor):\n+                    xi = advanced_subtensor(x, *i)\n+                elif isinstance(node.op, AdvancedIncSubtensor1):\n+                    xi = advanced_subtensor1(x, *i)\n+                else:\n+                    raise Exception('Should never happen!')\n+\n+                # Add `xi` to the `fgraph`. This is important for shape\n+                # inference later because the variable must be part of the\n+                # function graph in order to call `same_shape` on it.\n+                reason = 'local_useless_incsubtensor_alloc'\n+                node.fgraph.__import_r__([xi], '%s: add `xi`' % reason)\n+\n+                # `xi` may have more dimensions than `y` since the subtensor\n+                # ops do automatic broadcasting of the increment internally.\n+                # Thus, we need to make the leading implicitly broadcasted\n+                # dimensions explicit for shape comparison later.\n+                if xi.ndim > y.ndim:\n+                    y = T.shape_padleft(y, xi.ndim - y.ndim)\n+                    node.fgraph.__import_r__([y], '%s: add `y`' % reason)\n+\n+                # Build `z_shape` and `z_broad` explicitly to include extra\n+                # implicit dimensions.\n+                z_shape = ((1,) * (max(xi.ndim, y.ndim) - z.ndim) +\n+                           tuple(z.shape))\n+                z_broad = ((True,) * (max(xi.ndim, y.ndim) - z.ndim) +\n+                           z.broadcastable)\n+\n+                cond = [# The shapes of `y` and `xi` must either agree or `y`\n+                        # may also have shape equal to 1 which may be treated\n+                        # as a broadcastable dimension by the subtensor op.\n+                        T.or_(T.eq(y.shape[k], xi.shape[k]),\n+                              T.eq(y.shape[k], 1))\n+                        # If the increment is broadcastable in dimension `k`,\n+                        # we need to check whether the shapes of `xi` and `y`\n+                        # are the same.\n+                        if z_broad[k]\n+                        # Else, we need to check whether the shapes of `xi` and\n+                        # `z` are the same in dimension `k`.\n+                        else T.eq(xi.shape[k], z_shape[k])\n+                        # Loop over all dimensions.\n+                        for k in xrange(xi.ndim)\n+                        # If we can infer statically that the shape of `xi` and\n+                        # `y` are the same in dimension `k` we do not need to\n+                        # check it at run time.\n+                        if not same_shape(xi, y, dim_x=k, dim_y=k)]\n+            except AttributeError:\n+                # The shape feature may not be available in some mode, but we\n+                # need it for this optimization, so don't continue.\n+                return False\n+\n+            if len(cond) > 0:\n+                msg = '`x[i]` and `y` do not have the same shape.'\n+                z = Assert(msg)(z, *cond)\n+\n+            return [node.op(x, z, *i)]\n+\n+\n+#################\n+# Bit-wise opts #\n+#################\n+\n+@register_canonicalize\n+@register_specialize\n+@register_stabilize\n+@gof.local_optimizer([T.Elemwise])\n+def local_useless_OR(node):\n+    \"\"\"\n+    Remove useless OR op.\n+    \"\"\"\n+    if (isinstance(node.op, T.Elemwise) and\n+        isinstance(node.op.scalar_op, scalar.basic.OR)):\n+        assert len(node.inputs) == 2\n+        for i in node.inputs:\n+            try:\n+                if get_scalar_constant_value(i) != 0:\n+                    return [T.as_tensor_variable(1)]\n+            except NotScalarConstantError:\n+                pass\n+    return False\n+\n+\n+@register_canonicalize\n+@register_specialize\n+@register_stabilize\n+@gof.local_optimizer([T.Elemwise])\n+def local_useless_AND(node):","path":"theano/tensor/opt.py","position":135,"original_position":135,"commit_id":"3162e02cb61db0c9ffbbc3e3d4160294270863db","original_commit_id":"3162e02cb61db0c9ffbbc3e3d4160294270863db","user":{"login":"nouiz","id":180987,"avatar_url":"https://avatars.githubusercontent.com/u/180987?v=3","gravatar_id":"","url":"https://api.github.com/users/nouiz","html_url":"https://github.com/nouiz","followers_url":"https://api.github.com/users/nouiz/followers","following_url":"https://api.github.com/users/nouiz/following{/other_user}","gists_url":"https://api.github.com/users/nouiz/gists{/gist_id}","starred_url":"https://api.github.com/users/nouiz/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/nouiz/subscriptions","organizations_url":"https://api.github.com/users/nouiz/orgs","repos_url":"https://api.github.com/users/nouiz/repos","events_url":"https://api.github.com/users/nouiz/events{/privacy}","received_events_url":"https://api.github.com/users/nouiz/received_events","type":"User","site_admin":false},"body":"Idem for this opt. I would remove it.","created_at":"2015-03-31T03:18:22Z","updated_at":"2015-03-31T03:18:22Z","html_url":"https://github.com/Theano/Theano/pull/2521#discussion_r27450419","pull_request_url":"https://api.github.com/repos/Theano/Theano/pulls/2521","_links":{"self":{"href":"https://api.github.com/repos/Theano/Theano/pulls/comments/27450419"},"html":{"href":"https://github.com/Theano/Theano/pull/2521#discussion_r27450419"},"pull_request":{"href":"https://api.github.com/repos/Theano/Theano/pulls/2521"}}},"pull_request":{"url":"https://api.github.com/repos/Theano/Theano/pulls/2521","id":29775930,"html_url":"https://github.com/Theano/Theano/pull/2521","diff_url":"https://github.com/Theano/Theano/pull/2521.diff","patch_url":"https://github.com/Theano/Theano/pull/2521.patch","issue_url":"https://api.github.com/repos/Theano/Theano/issues/2521","number":2521,"state":"open","locked":false,"title":"[WIP] New optimization: useless incsubtensor alloc","user":{"login":"sisp","id":2206639,"avatar_url":"https://avatars.githubusercontent.com/u/2206639?v=3","gravatar_id":"","url":"https://api.github.com/users/sisp","html_url":"https://github.com/sisp","followers_url":"https://api.github.com/users/sisp/followers","following_url":"https://api.github.com/users/sisp/following{/other_user}","gists_url":"https://api.github.com/users/sisp/gists{/gist_id}","starred_url":"https://api.github.com/users/sisp/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/sisp/subscriptions","organizations_url":"https://api.github.com/users/sisp/orgs","repos_url":"https://api.github.com/users/sisp/repos","events_url":"https://api.github.com/users/sisp/events{/privacy}","received_events_url":"https://api.github.com/users/sisp/received_events","type":"User","site_admin":false},"body":"I found a missing optimization when looking at the following graph:\r\n```\r\nW = T.vector('W')\r\ni = T.vector('i', dtype='int64')\r\nt = T.scalar('t')\r\nz = T.sqr(t - W[i].sum())\r\ng = theano.grad(z, W)\r\nf = theano.function([W, i, t], g)\r\ntheano.printing.pydotprint(f, 'graph.png', format='png')\r\n```\r\n![theano](https://cloud.githubusercontent.com/assets/2206639/6320145/0e34a248-bad7-11e4-8d8e-2fbbac0e0633.png)\r\nIn the picture, \"Alloc id=8\" is unnecessary because the broadcastable scalar resulting from the fused elementwise ops is simply repeated, but `IncSubtensor` and `AdvancedIncSubtensor1` can broadcast a scalar increment automatically. I added a new optimization that fixes this case.\r\n\r\nComments?","created_at":"2015-02-22T20:15:51Z","updated_at":"2015-03-31T03:18:22Z","closed_at":null,"merged_at":null,"merge_commit_sha":"1502212dc4fe1d7b13df333262766fe2952b7ea0","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/Theano/Theano/pulls/2521/commits","review_comments_url":"https://api.github.com/repos/Theano/Theano/pulls/2521/comments","review_comment_url":"https://api.github.com/repos/Theano/Theano/pulls/comments{/number}","comments_url":"https://api.github.com/repos/Theano/Theano/issues/2521/comments","statuses_url":"https://api.github.com/repos/Theano/Theano/statuses/3162e02cb61db0c9ffbbc3e3d4160294270863db","head":{"label":"sisp:local_useless_incsubtensor_alloc","ref":"local_useless_incsubtensor_alloc","sha":"3162e02cb61db0c9ffbbc3e3d4160294270863db","user":{"login":"sisp","id":2206639,"avatar_url":"https://avatars.githubusercontent.com/u/2206639?v=3","gravatar_id":"","url":"https://api.github.com/users/sisp","html_url":"https://github.com/sisp","followers_url":"https://api.github.com/users/sisp/followers","following_url":"https://api.github.com/users/sisp/following{/other_user}","gists_url":"https://api.github.com/users/sisp/gists{/gist_id}","starred_url":"https://api.github.com/users/sisp/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/sisp/subscriptions","organizations_url":"https://api.github.com/users/sisp/orgs","repos_url":"https://api.github.com/users/sisp/repos","events_url":"https://api.github.com/users/sisp/events{/privacy}","received_events_url":"https://api.github.com/users/sisp/received_events","type":"User","site_admin":false},"repo":{"id":25789060,"name":"Theano","full_name":"sisp/Theano","owner":{"login":"sisp","id":2206639,"avatar_url":"https://avatars.githubusercontent.com/u/2206639?v=3","gravatar_id":"","url":"https://api.github.com/users/sisp","html_url":"https://github.com/sisp","followers_url":"https://api.github.com/users/sisp/followers","following_url":"https://api.github.com/users/sisp/following{/other_user}","gists_url":"https://api.github.com/users/sisp/gists{/gist_id}","starred_url":"https://api.github.com/users/sisp/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/sisp/subscriptions","organizations_url":"https://api.github.com/users/sisp/orgs","repos_url":"https://api.github.com/users/sisp/repos","events_url":"https://api.github.com/users/sisp/events{/privacy}","received_events_url":"https://api.github.com/users/sisp/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/sisp/Theano","description":"Optimizing GPU-meta-programming code generating array oriented optimizing math compiler in Python","fork":true,"url":"https://api.github.com/repos/sisp/Theano","forks_url":"https://api.github.com/repos/sisp/Theano/forks","keys_url":"https://api.github.com/repos/sisp/Theano/keys{/key_id}","collaborators_url":"https://api.github.com/repos/sisp/Theano/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/sisp/Theano/teams","hooks_url":"https://api.github.com/repos/sisp/Theano/hooks","issue_events_url":"https://api.github.com/repos/sisp/Theano/issues/events{/number}","events_url":"https://api.github.com/repos/sisp/Theano/events","assignees_url":"https://api.github.com/repos/sisp/Theano/assignees{/user}","branches_url":"https://api.github.com/repos/sisp/Theano/branches{/branch}","tags_url":"https://api.github.com/repos/sisp/Theano/tags","blobs_url":"https://api.github.com/repos/sisp/Theano/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/sisp/Theano/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/sisp/Theano/git/refs{/sha}","trees_url":"https://api.github.com/repos/sisp/Theano/git/trees{/sha}","statuses_url":"https://api.github.com/repos/sisp/Theano/statuses/{sha}","languages_url":"https://api.github.com/repos/sisp/Theano/languages","stargazers_url":"https://api.github.com/repos/sisp/Theano/stargazers","contributors_url":"https://api.github.com/repos/sisp/Theano/contributors","subscribers_url":"https://api.github.com/repos/sisp/Theano/subscribers","subscription_url":"https://api.github.com/repos/sisp/Theano/subscription","commits_url":"https://api.github.com/repos/sisp/Theano/commits{/sha}","git_commits_url":"https://api.github.com/repos/sisp/Theano/git/commits{/sha}","comments_url":"https://api.github.com/repos/sisp/Theano/comments{/number}","issue_comment_url":"https://api.github.com/repos/sisp/Theano/issues/comments{/number}","contents_url":"https://api.github.com/repos/sisp/Theano/contents/{+path}","compare_url":"https://api.github.com/repos/sisp/Theano/compare/{base}...{head}","merges_url":"https://api.github.com/repos/sisp/Theano/merges","archive_url":"https://api.github.com/repos/sisp/Theano/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/sisp/Theano/downloads","issues_url":"https://api.github.com/repos/sisp/Theano/issues{/number}","pulls_url":"https://api.github.com/repos/sisp/Theano/pulls{/number}","milestones_url":"https://api.github.com/repos/sisp/Theano/milestones{/number}","notifications_url":"https://api.github.com/repos/sisp/Theano/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/sisp/Theano/labels{/name}","releases_url":"https://api.github.com/repos/sisp/Theano/releases{/id}","created_at":"2014-10-26T20:13:50Z","updated_at":"2015-03-13T09:21:07Z","pushed_at":"2015-03-13T09:21:06Z","git_url":"git://github.com/sisp/Theano.git","ssh_url":"git@github.com:sisp/Theano.git","clone_url":"https://github.com/sisp/Theano.git","svn_url":"https://github.com/sisp/Theano","homepage":"http://www.deeplearning.net/software/theano","size":26933,"stargazers_count":0,"watchers_count":0,"language":"Python","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"Theano:master","ref":"master","sha":"470218392aa1cba459811428865ea896c6db49f6","user":{"login":"Theano","id":970517,"avatar_url":"https://avatars.githubusercontent.com/u/970517?v=3","gravatar_id":"","url":"https://api.github.com/users/Theano","html_url":"https://github.com/Theano","followers_url":"https://api.github.com/users/Theano/followers","following_url":"https://api.github.com/users/Theano/following{/other_user}","gists_url":"https://api.github.com/users/Theano/gists{/gist_id}","starred_url":"https://api.github.com/users/Theano/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Theano/subscriptions","organizations_url":"https://api.github.com/users/Theano/orgs","repos_url":"https://api.github.com/users/Theano/repos","events_url":"https://api.github.com/users/Theano/events{/privacy}","received_events_url":"https://api.github.com/users/Theano/received_events","type":"Organization","site_admin":false},"repo":{"id":2183193,"name":"Theano","full_name":"Theano/Theano","owner":{"login":"Theano","id":970517,"avatar_url":"https://avatars.githubusercontent.com/u/970517?v=3","gravatar_id":"","url":"https://api.github.com/users/Theano","html_url":"https://github.com/Theano","followers_url":"https://api.github.com/users/Theano/followers","following_url":"https://api.github.com/users/Theano/following{/other_user}","gists_url":"https://api.github.com/users/Theano/gists{/gist_id}","starred_url":"https://api.github.com/users/Theano/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Theano/subscriptions","organizations_url":"https://api.github.com/users/Theano/orgs","repos_url":"https://api.github.com/users/Theano/repos","events_url":"https://api.github.com/users/Theano/events{/privacy}","received_events_url":"https://api.github.com/users/Theano/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/Theano/Theano","description":"Theano is a Python library that allows you to define, optimize, and evaluate mathematical expressions involving multi-dimensional arrays efficiently. It can use GPUs and perform efficient symbolic differentiation.","fork":false,"url":"https://api.github.com/repos/Theano/Theano","forks_url":"https://api.github.com/repos/Theano/Theano/forks","keys_url":"https://api.github.com/repos/Theano/Theano/keys{/key_id}","collaborators_url":"https://api.github.com/repos/Theano/Theano/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/Theano/Theano/teams","hooks_url":"https://api.github.com/repos/Theano/Theano/hooks","issue_events_url":"https://api.github.com/repos/Theano/Theano/issues/events{/number}","events_url":"https://api.github.com/repos/Theano/Theano/events","assignees_url":"https://api.github.com/repos/Theano/Theano/assignees{/user}","branches_url":"https://api.github.com/repos/Theano/Theano/branches{/branch}","tags_url":"https://api.github.com/repos/Theano/Theano/tags","blobs_url":"https://api.github.com/repos/Theano/Theano/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/Theano/Theano/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/Theano/Theano/git/refs{/sha}","trees_url":"https://api.github.com/repos/Theano/Theano/git/trees{/sha}","statuses_url":"https://api.github.com/repos/Theano/Theano/statuses/{sha}","languages_url":"https://api.github.com/repos/Theano/Theano/languages","stargazers_url":"https://api.github.com/repos/Theano/Theano/stargazers","contributors_url":"https://api.github.com/repos/Theano/Theano/contributors","subscribers_url":"https://api.github.com/repos/Theano/Theano/subscribers","subscription_url":"https://api.github.com/repos/Theano/Theano/subscription","commits_url":"https://api.github.com/repos/Theano/Theano/commits{/sha}","git_commits_url":"https://api.github.com/repos/Theano/Theano/git/commits{/sha}","comments_url":"https://api.github.com/repos/Theano/Theano/comments{/number}","issue_comment_url":"https://api.github.com/repos/Theano/Theano/issues/comments{/number}","contents_url":"https://api.github.com/repos/Theano/Theano/contents/{+path}","compare_url":"https://api.github.com/repos/Theano/Theano/compare/{base}...{head}","merges_url":"https://api.github.com/repos/Theano/Theano/merges","archive_url":"https://api.github.com/repos/Theano/Theano/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/Theano/Theano/downloads","issues_url":"https://api.github.com/repos/Theano/Theano/issues{/number}","pulls_url":"https://api.github.com/repos/Theano/Theano/pulls{/number}","milestones_url":"https://api.github.com/repos/Theano/Theano/milestones{/number}","notifications_url":"https://api.github.com/repos/Theano/Theano/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/Theano/Theano/labels{/name}","releases_url":"https://api.github.com/repos/Theano/Theano/releases{/id}","created_at":"2011-08-10T03:48:06Z","updated_at":"2015-03-30T23:10:34Z","pushed_at":"2015-03-31T03:12:09Z","git_url":"git://github.com/Theano/Theano.git","ssh_url":"git@github.com:Theano/Theano.git","clone_url":"https://github.com/Theano/Theano.git","svn_url":"https://github.com/Theano/Theano","homepage":"http://www.deeplearning.net/software/theano","size":41547,"stargazers_count":1325,"watchers_count":1325,"language":"Python","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":487,"mirror_url":null,"open_issues_count":333,"forks":487,"open_issues":333,"watchers":1325,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/Theano/Theano/pulls/2521"},"html":{"href":"https://github.com/Theano/Theano/pull/2521"},"issue":{"href":"https://api.github.com/repos/Theano/Theano/issues/2521"},"comments":{"href":"https://api.github.com/repos/Theano/Theano/issues/2521/comments"},"review_comments":{"href":"https://api.github.com/repos/Theano/Theano/pulls/2521/comments"},"review_comment":{"href":"https://api.github.com/repos/Theano/Theano/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/Theano/Theano/pulls/2521/commits"},"statuses":{"href":"https://api.github.com/repos/Theano/Theano/statuses/3162e02cb61db0c9ffbbc3e3d4160294270863db"}}}}