{"action":"created","comment":{"url":"https://api.github.com/repos/apache/incubator-mxnet/pulls/comments/173573792","pull_request_review_id":102796084,"id":173573792,"diff_hunk":"@@ -153,6 +157,214 @@ class RNNOp : public Operator {\n   RNNParam param_;\n };  // class RNNOp\n \n+template<typename DType>\n+class RNNOp<cpu, DType> : public Operator {\n+ public:\n+  explicit RNNOp(RNNParam param) {\n+    this->param_ = param;\n+    // RNN Mode\n+    param_.lstm_q_ = false;\n+    switch (param_.mode) {\n+      case rnn_enum::kLstm:\n+        param_.lstm_q_ = true;\n+        break;\n+      default:\n+        LOG(FATAL) << \"only LSTM is implmented on CPU\";\n+    }\n+  }\n+\n+  virtual void Forward(const OpContext &ctx,\n+                       const std::vector<TBlob> &in_data,\n+                       const std::vector<OpReqType> &req,\n+                       const std::vector<TBlob> &out_data,\n+                       const std::vector<TBlob> &aux_args) {\n+    // Layout TNC\n+    CHECK(!ctx.is_train) << \"only inference mode is available\"\n+      \"for cpu at the moment.\";\n+    size_t in_expected = param_.lstm_q_ ? 4 : 3;\n+    size_t out_expected = param_.lstm_q_ ? 3 : 2;\n+\n+    if (!param_.state_outputs)\n+      LOG(FATAL) << \"no state outputs is currently not supported for cpu.\";\n+\n+    CHECK_EQ(req[rnn_enum::kOut], kWriteTo);\n+    CHECK_EQ(in_data.size(), in_expected);\n+    CHECK_EQ(out_data.size(), out_expected);\n+\n+    mshadow::Stream<cpu> *s = ctx.get_stream<cpu>();\n+    // get input + output tensors\n+    // w layout i2h_w, h2h_w, i2h_b, h2h_b\n+    Tensor<cpu, 3, DType> x =\n+        in_data[rnn_enum::kData].get<cpu, 3, DType>(s);  // TNC\n+    Tensor<cpu, 1, DType> w = in_data[rnn_enum::kParams].get<cpu, 1, DType>(s);\n+    Tensor<cpu, 3, DType> hx =\n+        in_data[rnn_enum::kState].get<cpu, 3, DType>(s);  // LNC\n+    Tensor<cpu, 3, DType> y =\n+        out_data[rnn_enum::kOut].get<cpu, 3, DType>(s);  // TNC\n+    int64_t seq_len = x.shape_[0];\n+    int64_t num_layers = hx.shape_[0];\n+    int64_t batch_size = x.shape_[1];\n+    int64_t h_channel = hx.shape_[2];\n+    int64_t in_channel = x.shape_[2];\n+    Tensor<cpu, 2, DType> x_flatten = in_data[rnn_enum::kData]\n+      .get_with_shape<cpu, 2, DType>(\n+          mshadow::Shape2(seq_len * batch_size, in_channel), s);  // (T*N)C\n+    Tensor<cpu, 2, DType> y_flatten = out_data[rnn_enum::kOut]\n+      .get_with_shape<cpu, 2, DType>(\n+          mshadow::Shape2(\n+              y.shape_[0] * y.shape_[1], y.shape_[2]), s);  // (T*N)C\n+\n+    CHECK(x.CheckContiguous());\n+    CHECK(w.CheckContiguous());\n+    CHECK(hx.CheckContiguous());\n+    CHECK(y.CheckContiguous());\n+\n+    if (param_.lstm_q_) {\n+      const size_t kNumMat = 4;\n+      int64_t fused_h_ch = kNumMat * h_channel;\n+      int64_t h_size = batch_size * fused_h_ch;\n+      int64_t num_dir = 1 + param_.bidirectional;\n+      int64_t h2h_w_size = h_channel * fused_h_ch;\n+\n+      Tensor<cpu, 3, DType> cx =\n+          in_data[rnn_enum::kStateCell].get<cpu, 3, DType>(s);\n+      CHECK_EQ(cx.CheckContiguous(), true);\n+\n+      Tensor<cpu, 3, DType> cy =\n+          out_data[rnn_enum::kStateCellOut].get<cpu, 3, DType>(s);\n+      Tensor<cpu, 3, DType> hy =\n+          out_data[rnn_enum::kStateOut].get<cpu, 3, DType>(s);\n+      CHECK_EQ(cy.CheckContiguous(), true);\n+      CHECK_EQ(hy.CheckContiguous(), true);\n+\n+      DType* workspace_addr =\n+      static_cast<DType *>(ctx.requested[rnn_enum::kTempSpace]\n+          .get_host_space_internal(sizeof(DType) *\n+                                  (seq_len * h_size + h_size\n+                                  + y.shape_[0] * y.shape_[1] * y.shape_[2])));\n+      Tensor<cpu, 3, DType> i2h_y(\n+          workspace_addr, mshadow::Shape3(seq_len, batch_size, fused_h_ch));\n+      Tensor<cpu, 2, DType> i2h_y_flatten(\n+          workspace_addr, mshadow::Shape2(seq_len * batch_size, fused_h_ch));\n+      Tensor<cpu, 2, DType> h2h_y(workspace_addr\n+          + seq_len * h_size, mshadow::Shape2(batch_size, fused_h_ch));\n+      Tensor<cpu, 3, DType> y_tmp(workspace_addr\n+          + (seq_len + 1) * h_size, y.shape_);\n+      Tensor<cpu, 2, DType> y_flatten_tmp(workspace_addr\n+          + (seq_len + 1) * h_size, y_flatten.shape_);\n+      CHECK_EQ(i2h_y.CheckContiguous(), true);\n+      CHECK_EQ(h2h_y.CheckContiguous(), true);\n+      CHECK_EQ(y_tmp.CheckContiguous(), true);\n+\n+      for (int64_t layer = 0; layer < num_layers; layer++) {\n+        int reverse_dir = 0;\n+        int out_tmp = 0;\n+        if (param_.bidirectional && layer % 2)\n+          reverse_dir = 1;\n+        if (layer / num_dir % 2 == 0)\n+          out_tmp = 1;\n+        mshadow::Shape<2> i2h_w_shape = mshadow::Shape2(fused_h_ch,\n+            (layer < num_dir) ? in_channel : num_dir * h_channel);\n+        mshadow::Shape<2> h2h_w_shape = mshadow::Shape2(fused_h_ch, h_channel);\n+        int64_t start = layer < num_dir ?\n+            (layer * (in_channel * fused_h_ch + h2h_w_size)) :  // input layer\n+              (num_dir * (in_channel * fused_h_ch + h2h_w_size)\n+              + (layer - num_dir) * (h2h_w_size * num_dir + h2h_w_size));\n+        Tensor<cpu, 2, DType> i2h_w(w.Slice(start, start + (layer < num_dir ?\n+              (in_channel * fused_h_ch) : num_dir * h2h_w_size)).dptr_,\n+              i2h_w_shape);\n+        start += layer < num_dir ?\n+            in_channel * fused_h_ch : h2h_w_size * num_dir;\n+        Tensor<cpu, 2, DType> h2h_w(w.Slice(start, start + h2h_w_size).dptr_,\n+            h2h_w_shape);\n+        start = num_dir * (in_channel * fused_h_ch + h2h_w_size)\n+            + (num_layers - num_dir) * (h2h_w_size * (num_dir + 1))\n+              + layer * fused_h_ch * 2;\n+        Tensor<cpu, 1, DType> i2h_b = w.Slice(start, start + fused_h_ch);\n+        start += fused_h_ch;\n+        Tensor<cpu, 1, DType> h2h_b = w.Slice(start, start + fused_h_ch);\n+        if (out_tmp) {\n+          linalg_gemm(layer < num_dir ? x_flatten:y_flatten, i2h_w,\n+              i2h_y_flatten, false, true, s);\n+        } else {\n+          linalg_gemm(layer < num_dir ? x_flatten:y_flatten_tmp, i2h_w,\n+              i2h_y_flatten, false, true, s);\n+        }\n+        i2h_y_flatten += repmat(i2h_b, seq_len * batch_size);\n+        for (int64_t t = 0; t < seq_len; t++) {\n+          int64_t timestep = t;\n+          if (reverse_dir)\n+            timestep = seq_len - 1 - t;\n+          linalg_gemm(t == 0 ? hx[layer]:hy[layer], h2h_w, h2h_y,\n+              false, true, s);\n+          h2h_y += repmat(h2h_b, batch_size);\n+          // fused element-wise ops\n+          LSTMFusedElementWiseCPUOps(i2h_y[timestep], cx[layer], h2h_y,\n+              y[timestep], out_tmp ? y_tmp[timestep]: y[timestep],\n+                hy[layer], cy[layer], batch_size, h_channel, t,\n+                reverse_dir, out_tmp && (layer == num_layers - 1));\n+        }\n+      }\n+    } else {\n+      LOG(FATAL) << \"only LSTM is available for cpu at the moment.\";\n+    }\n+  }\n+\n+  virtual void Backward(const OpContext &ctx,\n+                        const std::vector<TBlob> &out_grad,\n+                        const std::vector<TBlob> &in_data,\n+      const std::vector<TBlob> &out_data,\n+                        const std::vector<OpReqType> &req,\n+                        const std::vector<TBlob> &in_grad,\n+                        const std::vector<TBlob> &aux_args) {\n+    LOG(FATAL) << \"LSTM backward is not available for cpu at the moment.\";\n+  }\n+\n+ private:\n+  RNNParam param_;\n+\n+  virtual void LSTMFusedElementWiseCPUOps(const Tensor<cpu, 2, DType> &i2h_y,\n+                                          const Tensor<cpu, 2, DType> &cx,\n+                                          const Tensor<cpu, 2, DType> &h2h_y,\n+                                          const Tensor<cpu, 2, DType> &y,\n+                                          // holding intermediate layer output\n+                                          const Tensor<cpu, 2, DType> &tmp,\n+                                          const Tensor<cpu, 2, DType> &hy,\n+                                          const Tensor<cpu, 2, DType> &cy,\n+                                          const int64_t batch_size,\n+                                          const int64_t h_channel,\n+                                          const int64_t t,\n+                                          const int reverse_dir,\n+                                          const int copy_tmp2y) {\n+    int64_t ji;\n+    #pragma omp parallel for private(ji)\n+    for (ji = 0; ji < batch_size * h_channel; ji++) {\n+      int64_t j = ji / h_channel;  // batch dim\n+      int64_t i = ji % h_channel;\n+      int64_t f = i + h_channel;\n+      int64_t c = i + h_channel * 2;\n+      int64_t o = i + h_channel * 3;\n+      h2h_y[j][i] += i2h_y[j][i];","path":"src/operator/rnn-inl.h","position":203,"original_position":203,"commit_id":"f41d8efbd4d3f6adac89f62b166a8b919d82e233","original_commit_id":"9de6bf63e6fdda5e088928b98c213521dd29dd3a","user":{"login":"reminisce","id":4978794,"avatar_url":"https://avatars1.githubusercontent.com/u/4978794?v=4","gravatar_id":"","url":"https://api.github.com/users/reminisce","html_url":"https://github.com/reminisce","followers_url":"https://api.github.com/users/reminisce/followers","following_url":"https://api.github.com/users/reminisce/following{/other_user}","gists_url":"https://api.github.com/users/reminisce/gists{/gist_id}","starred_url":"https://api.github.com/users/reminisce/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/reminisce/subscriptions","organizations_url":"https://api.github.com/users/reminisce/orgs","repos_url":"https://api.github.com/users/reminisce/repos","events_url":"https://api.github.com/users/reminisce/events{/privacy}","received_events_url":"https://api.github.com/users/reminisce/received_events","type":"User","site_admin":false},"body":"I don't have a strong opinion on this. If you could use `dptr_`, that's the best for performance because it saves function calls and temp tensor object creation, but it could introduce the issue of code readability and defeat the purpose of OO.\r\n\r\nI think the rule of thumb here is try to avoid temp tensor creation and destruction while keep the code readable. So  it's okay to use `operator[]` for a 1D Tensor since it only return values and cache the temp tensor created by calling `operator[]` for a 2D tensor.","created_at":"2018-03-09T21:33:30Z","updated_at":"2018-03-09T21:33:30Z","html_url":"https://github.com/apache/incubator-mxnet/pull/9977#discussion_r173573792","pull_request_url":"https://api.github.com/repos/apache/incubator-mxnet/pulls/9977","author_association":"CONTRIBUTOR","_links":{"self":{"href":"https://api.github.com/repos/apache/incubator-mxnet/pulls/comments/173573792"},"html":{"href":"https://github.com/apache/incubator-mxnet/pull/9977#discussion_r173573792"},"pull_request":{"href":"https://api.github.com/repos/apache/incubator-mxnet/pulls/9977"}},"in_reply_to_id":173385217},"pull_request":{"url":"https://api.github.com/repos/apache/incubator-mxnet/pulls/9977","id":172645613,"html_url":"https://github.com/apache/incubator-mxnet/pull/9977","diff_url":"https://github.com/apache/incubator-mxnet/pull/9977.diff","patch_url":"https://github.com/apache/incubator-mxnet/pull/9977.patch","issue_url":"https://api.github.com/repos/apache/incubator-mxnet/issues/9977","number":9977,"state":"open","locked":false,"title":"Cpu lstm inference","user":{"login":"Jerryzcn","id":4907789,"avatar_url":"https://avatars0.githubusercontent.com/u/4907789?v=4","gravatar_id":"","url":"https://api.github.com/users/Jerryzcn","html_url":"https://github.com/Jerryzcn","followers_url":"https://api.github.com/users/Jerryzcn/followers","following_url":"https://api.github.com/users/Jerryzcn/following{/other_user}","gists_url":"https://api.github.com/users/Jerryzcn/gists{/gist_id}","starred_url":"https://api.github.com/users/Jerryzcn/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Jerryzcn/subscriptions","organizations_url":"https://api.github.com/users/Jerryzcn/orgs","repos_url":"https://api.github.com/users/Jerryzcn/repos","events_url":"https://api.github.com/users/Jerryzcn/events{/privacy}","received_events_url":"https://api.github.com/users/Jerryzcn/received_events","type":"User","site_admin":false},"body":"## Description ##\r\n(Brief description on what this PR is about)\r\nCPU LSTM inference kernel. \r\nThis is around 9.5x faster than gluon LSTM cell.\r\n\r\nVerified on speech recognition task, as well as on unittest.\r\n\r\n## Checklist ##\r\n### Essentials ###\r\n- [x] Passed code style checking (`make lint`)\r\n- [x] Changes are complete (i.e. I finished coding on this PR)\r\n- [x] All changes have test coverage:\r\n- Unit tests are added for small changes to verify correctness (e.g. adding a new operator)\r\n- Nightly tests are added for complicated/long-running ones (e.g. changing distributed kvstore)\r\n- Build tests will be added for build configuration changes (e.g. adding a new build option with NCCL)\r\n- [x] Code is well-documented: \r\n- For user-facing API changes, API doc string has been updated. \r\n- For new C++ functions in header files, their functionalities and arguments are documented. \r\n- For new examples, README.md is added to explain the what the example does, the source of the dataset, expected performance on test set and reference to the original paper if applicable\r\n- [x] To the my best knowledge, examples are either not affected by this change, or have been fixed to be compatible with this change\r\n\r\n## Comments ##\r\n- If this change is a backward incompatible change, why must this change be made.\r\n- Interesting edge cases to note here\r\n","created_at":"2018-03-03T02:37:32Z","updated_at":"2018-03-09T21:33:30Z","closed_at":null,"merged_at":null,"merge_commit_sha":"0bab5dd0befe816a12ac5a7507c12480e0c9cc77","assignee":{"login":"szha","id":2626883,"avatar_url":"https://avatars2.githubusercontent.com/u/2626883?v=4","gravatar_id":"","url":"https://api.github.com/users/szha","html_url":"https://github.com/szha","followers_url":"https://api.github.com/users/szha/followers","following_url":"https://api.github.com/users/szha/following{/other_user}","gists_url":"https://api.github.com/users/szha/gists{/gist_id}","starred_url":"https://api.github.com/users/szha/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/szha/subscriptions","organizations_url":"https://api.github.com/users/szha/orgs","repos_url":"https://api.github.com/users/szha/repos","events_url":"https://api.github.com/users/szha/events{/privacy}","received_events_url":"https://api.github.com/users/szha/received_events","type":"User","site_admin":false},"assignees":[{"login":"szha","id":2626883,"avatar_url":"https://avatars2.githubusercontent.com/u/2626883?v=4","gravatar_id":"","url":"https://api.github.com/users/szha","html_url":"https://github.com/szha","followers_url":"https://api.github.com/users/szha/followers","following_url":"https://api.github.com/users/szha/following{/other_user}","gists_url":"https://api.github.com/users/szha/gists{/gist_id}","starred_url":"https://api.github.com/users/szha/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/szha/subscriptions","organizations_url":"https://api.github.com/users/szha/orgs","repos_url":"https://api.github.com/users/szha/repos","events_url":"https://api.github.com/users/szha/events{/privacy}","received_events_url":"https://api.github.com/users/szha/received_events","type":"User","site_admin":false}],"requested_reviewers":[{"login":"cjolivier01","id":11234557,"avatar_url":"https://avatars1.githubusercontent.com/u/11234557?v=4","gravatar_id":"","url":"https://api.github.com/users/cjolivier01","html_url":"https://github.com/cjolivier01","followers_url":"https://api.github.com/users/cjolivier01/followers","following_url":"https://api.github.com/users/cjolivier01/following{/other_user}","gists_url":"https://api.github.com/users/cjolivier01/gists{/gist_id}","starred_url":"https://api.github.com/users/cjolivier01/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/cjolivier01/subscriptions","organizations_url":"https://api.github.com/users/cjolivier01/orgs","repos_url":"https://api.github.com/users/cjolivier01/repos","events_url":"https://api.github.com/users/cjolivier01/events{/privacy}","received_events_url":"https://api.github.com/users/cjolivier01/received_events","type":"User","site_admin":false}],"requested_teams":[],"labels":[],"milestone":null,"commits_url":"https://api.github.com/repos/apache/incubator-mxnet/pulls/9977/commits","review_comments_url":"https://api.github.com/repos/apache/incubator-mxnet/pulls/9977/comments","review_comment_url":"https://api.github.com/repos/apache/incubator-mxnet/pulls/comments{/number}","comments_url":"https://api.github.com/repos/apache/incubator-mxnet/issues/9977/comments","statuses_url":"https://api.github.com/repos/apache/incubator-mxnet/statuses/f41d8efbd4d3f6adac89f62b166a8b919d82e233","head":{"label":"Jerryzcn:cpu-lstm","ref":"cpu-lstm","sha":"f41d8efbd4d3f6adac89f62b166a8b919d82e233","user":{"login":"Jerryzcn","id":4907789,"avatar_url":"https://avatars0.githubusercontent.com/u/4907789?v=4","gravatar_id":"","url":"https://api.github.com/users/Jerryzcn","html_url":"https://github.com/Jerryzcn","followers_url":"https://api.github.com/users/Jerryzcn/followers","following_url":"https://api.github.com/users/Jerryzcn/following{/other_user}","gists_url":"https://api.github.com/users/Jerryzcn/gists{/gist_id}","starred_url":"https://api.github.com/users/Jerryzcn/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Jerryzcn/subscriptions","organizations_url":"https://api.github.com/users/Jerryzcn/orgs","repos_url":"https://api.github.com/users/Jerryzcn/repos","events_url":"https://api.github.com/users/Jerryzcn/events{/privacy}","received_events_url":"https://api.github.com/users/Jerryzcn/received_events","type":"User","site_admin":false},"repo":{"id":87584895,"name":"mxnet","full_name":"Jerryzcn/mxnet","owner":{"login":"Jerryzcn","id":4907789,"avatar_url":"https://avatars0.githubusercontent.com/u/4907789?v=4","gravatar_id":"","url":"https://api.github.com/users/Jerryzcn","html_url":"https://github.com/Jerryzcn","followers_url":"https://api.github.com/users/Jerryzcn/followers","following_url":"https://api.github.com/users/Jerryzcn/following{/other_user}","gists_url":"https://api.github.com/users/Jerryzcn/gists{/gist_id}","starred_url":"https://api.github.com/users/Jerryzcn/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Jerryzcn/subscriptions","organizations_url":"https://api.github.com/users/Jerryzcn/orgs","repos_url":"https://api.github.com/users/Jerryzcn/repos","events_url":"https://api.github.com/users/Jerryzcn/events{/privacy}","received_events_url":"https://api.github.com/users/Jerryzcn/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/Jerryzcn/mxnet","description":"Lightweight, Portable, Flexible Distributed/Mobile Deep Learning with Dynamic, Mutation-aware Dataflow Dep Scheduler; for Python, R, Julia, Scala, Go, Javascript and more","fork":true,"url":"https://api.github.com/repos/Jerryzcn/mxnet","forks_url":"https://api.github.com/repos/Jerryzcn/mxnet/forks","keys_url":"https://api.github.com/repos/Jerryzcn/mxnet/keys{/key_id}","collaborators_url":"https://api.github.com/repos/Jerryzcn/mxnet/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/Jerryzcn/mxnet/teams","hooks_url":"https://api.github.com/repos/Jerryzcn/mxnet/hooks","issue_events_url":"https://api.github.com/repos/Jerryzcn/mxnet/issues/events{/number}","events_url":"https://api.github.com/repos/Jerryzcn/mxnet/events","assignees_url":"https://api.github.com/repos/Jerryzcn/mxnet/assignees{/user}","branches_url":"https://api.github.com/repos/Jerryzcn/mxnet/branches{/branch}","tags_url":"https://api.github.com/repos/Jerryzcn/mxnet/tags","blobs_url":"https://api.github.com/repos/Jerryzcn/mxnet/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/Jerryzcn/mxnet/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/Jerryzcn/mxnet/git/refs{/sha}","trees_url":"https://api.github.com/repos/Jerryzcn/mxnet/git/trees{/sha}","statuses_url":"https://api.github.com/repos/Jerryzcn/mxnet/statuses/{sha}","languages_url":"https://api.github.com/repos/Jerryzcn/mxnet/languages","stargazers_url":"https://api.github.com/repos/Jerryzcn/mxnet/stargazers","contributors_url":"https://api.github.com/repos/Jerryzcn/mxnet/contributors","subscribers_url":"https://api.github.com/repos/Jerryzcn/mxnet/subscribers","subscription_url":"https://api.github.com/repos/Jerryzcn/mxnet/subscription","commits_url":"https://api.github.com/repos/Jerryzcn/mxnet/commits{/sha}","git_commits_url":"https://api.github.com/repos/Jerryzcn/mxnet/git/commits{/sha}","comments_url":"https://api.github.com/repos/Jerryzcn/mxnet/comments{/number}","issue_comment_url":"https://api.github.com/repos/Jerryzcn/mxnet/issues/comments{/number}","contents_url":"https://api.github.com/repos/Jerryzcn/mxnet/contents/{+path}","compare_url":"https://api.github.com/repos/Jerryzcn/mxnet/compare/{base}...{head}","merges_url":"https://api.github.com/repos/Jerryzcn/mxnet/merges","archive_url":"https://api.github.com/repos/Jerryzcn/mxnet/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/Jerryzcn/mxnet/downloads","issues_url":"https://api.github.com/repos/Jerryzcn/mxnet/issues{/number}","pulls_url":"https://api.github.com/repos/Jerryzcn/mxnet/pulls{/number}","milestones_url":"https://api.github.com/repos/Jerryzcn/mxnet/milestones{/number}","notifications_url":"https://api.github.com/repos/Jerryzcn/mxnet/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/Jerryzcn/mxnet/labels{/name}","releases_url":"https://api.github.com/repos/Jerryzcn/mxnet/releases{/id}","deployments_url":"https://api.github.com/repos/Jerryzcn/mxnet/deployments","created_at":"2017-04-07T20:35:50Z","updated_at":"2018-02-08T01:55:25Z","pushed_at":"2018-03-09T09:12:37Z","git_url":"git://github.com/Jerryzcn/mxnet.git","ssh_url":"git@github.com:Jerryzcn/mxnet.git","clone_url":"https://github.com/Jerryzcn/mxnet.git","svn_url":"https://github.com/Jerryzcn/mxnet","homepage":"http://mxnet.io","size":33021,"stargazers_count":0,"watchers_count":0,"language":"Python","has_issues":false,"has_projects":true,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":0,"mirror_url":null,"archived":false,"open_issues_count":0,"license":{"key":"apache-2.0","name":"Apache License 2.0","spdx_id":"Apache-2.0","url":"https://api.github.com/licenses/apache-2.0"},"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"apache:master","ref":"master","sha":"62b9d48c87736ef1c398a2658953aee017ab9fc2","user":{"login":"apache","id":47359,"avatar_url":"https://avatars0.githubusercontent.com/u/47359?v=4","gravatar_id":"","url":"https://api.github.com/users/apache","html_url":"https://github.com/apache","followers_url":"https://api.github.com/users/apache/followers","following_url":"https://api.github.com/users/apache/following{/other_user}","gists_url":"https://api.github.com/users/apache/gists{/gist_id}","starred_url":"https://api.github.com/users/apache/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/apache/subscriptions","organizations_url":"https://api.github.com/users/apache/orgs","repos_url":"https://api.github.com/users/apache/repos","events_url":"https://api.github.com/users/apache/events{/privacy}","received_events_url":"https://api.github.com/users/apache/received_events","type":"Organization","site_admin":false},"repo":{"id":34864402,"name":"incubator-mxnet","full_name":"apache/incubator-mxnet","owner":{"login":"apache","id":47359,"avatar_url":"https://avatars0.githubusercontent.com/u/47359?v=4","gravatar_id":"","url":"https://api.github.com/users/apache","html_url":"https://github.com/apache","followers_url":"https://api.github.com/users/apache/followers","following_url":"https://api.github.com/users/apache/following{/other_user}","gists_url":"https://api.github.com/users/apache/gists{/gist_id}","starred_url":"https://api.github.com/users/apache/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/apache/subscriptions","organizations_url":"https://api.github.com/users/apache/orgs","repos_url":"https://api.github.com/users/apache/repos","events_url":"https://api.github.com/users/apache/events{/privacy}","received_events_url":"https://api.github.com/users/apache/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/apache/incubator-mxnet","description":"Lightweight, Portable, Flexible Distributed/Mobile Deep Learning with Dynamic, Mutation-aware Dataflow Dep Scheduler; for Python, R, Julia, Scala, Go, Javascript and more","fork":false,"url":"https://api.github.com/repos/apache/incubator-mxnet","forks_url":"https://api.github.com/repos/apache/incubator-mxnet/forks","keys_url":"https://api.github.com/repos/apache/incubator-mxnet/keys{/key_id}","collaborators_url":"https://api.github.com/repos/apache/incubator-mxnet/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/apache/incubator-mxnet/teams","hooks_url":"https://api.github.com/repos/apache/incubator-mxnet/hooks","issue_events_url":"https://api.github.com/repos/apache/incubator-mxnet/issues/events{/number}","events_url":"https://api.github.com/repos/apache/incubator-mxnet/events","assignees_url":"https://api.github.com/repos/apache/incubator-mxnet/assignees{/user}","branches_url":"https://api.github.com/repos/apache/incubator-mxnet/branches{/branch}","tags_url":"https://api.github.com/repos/apache/incubator-mxnet/tags","blobs_url":"https://api.github.com/repos/apache/incubator-mxnet/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/apache/incubator-mxnet/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/apache/incubator-mxnet/git/refs{/sha}","trees_url":"https://api.github.com/repos/apache/incubator-mxnet/git/trees{/sha}","statuses_url":"https://api.github.com/repos/apache/incubator-mxnet/statuses/{sha}","languages_url":"https://api.github.com/repos/apache/incubator-mxnet/languages","stargazers_url":"https://api.github.com/repos/apache/incubator-mxnet/stargazers","contributors_url":"https://api.github.com/repos/apache/incubator-mxnet/contributors","subscribers_url":"https://api.github.com/repos/apache/incubator-mxnet/subscribers","subscription_url":"https://api.github.com/repos/apache/incubator-mxnet/subscription","commits_url":"https://api.github.com/repos/apache/incubator-mxnet/commits{/sha}","git_commits_url":"https://api.github.com/repos/apache/incubator-mxnet/git/commits{/sha}","comments_url":"https://api.github.com/repos/apache/incubator-mxnet/comments{/number}","issue_comment_url":"https://api.github.com/repos/apache/incubator-mxnet/issues/comments{/number}","contents_url":"https://api.github.com/repos/apache/incubator-mxnet/contents/{+path}","compare_url":"https://api.github.com/repos/apache/incubator-mxnet/compare/{base}...{head}","merges_url":"https://api.github.com/repos/apache/incubator-mxnet/merges","archive_url":"https://api.github.com/repos/apache/incubator-mxnet/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/apache/incubator-mxnet/downloads","issues_url":"https://api.github.com/repos/apache/incubator-mxnet/issues{/number}","pulls_url":"https://api.github.com/repos/apache/incubator-mxnet/pulls{/number}","milestones_url":"https://api.github.com/repos/apache/incubator-mxnet/milestones{/number}","notifications_url":"https://api.github.com/repos/apache/incubator-mxnet/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/apache/incubator-mxnet/labels{/name}","releases_url":"https://api.github.com/repos/apache/incubator-mxnet/releases{/id}","deployments_url":"https://api.github.com/repos/apache/incubator-mxnet/deployments","created_at":"2015-04-30T16:21:15Z","updated_at":"2018-03-09T20:06:58Z","pushed_at":"2018-03-09T20:26:23Z","git_url":"git://github.com/apache/incubator-mxnet.git","ssh_url":"git@github.com:apache/incubator-mxnet.git","clone_url":"https://github.com/apache/incubator-mxnet.git","svn_url":"https://github.com/apache/incubator-mxnet","homepage":"http://mxnet.io","size":33815,"stargazers_count":13306,"watchers_count":13306,"language":"Python","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":4903,"mirror_url":null,"archived":false,"open_issues_count":835,"license":{"key":"apache-2.0","name":"Apache License 2.0","spdx_id":"Apache-2.0","url":"https://api.github.com/licenses/apache-2.0"},"forks":4903,"open_issues":835,"watchers":13306,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/apache/incubator-mxnet/pulls/9977"},"html":{"href":"https://github.com/apache/incubator-mxnet/pull/9977"},"issue":{"href":"https://api.github.com/repos/apache/incubator-mxnet/issues/9977"},"comments":{"href":"https://api.github.com/repos/apache/incubator-mxnet/issues/9977/comments"},"review_comments":{"href":"https://api.github.com/repos/apache/incubator-mxnet/pulls/9977/comments"},"review_comment":{"href":"https://api.github.com/repos/apache/incubator-mxnet/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/apache/incubator-mxnet/pulls/9977/commits"},"statuses":{"href":"https://api.github.com/repos/apache/incubator-mxnet/statuses/f41d8efbd4d3f6adac89f62b166a8b919d82e233"}},"author_association":"CONTRIBUTOR"}}
{"actor":{"display_login":"reminisce"}}