{"action":"created","comment":{"url":"https://api.github.com/repos/dmlc/mxnet/pulls/comments/91585603","pull_request_review_id":12080524,"id":91585603,"diff_hunk":"@@ -1711,3 +1713,436 @@ JNIEXPORT jint JNICALL Java_ml_dmlc_mxnet_LibInfo_mxRtcFree\n   int ret = MXRtcFree(handle);\n   return ret;\n }\n+\n+JNIEnv *globalEnv;\n+std::unordered_map<std::string, jobject> globalOpPropMap;\n+std::unordered_map<std::string, jobject> globalOpMap;\n+\n+JNIEXPORT jint JNICALL Java_ml_dmlc_mxnet_LibInfo_mxCustomOpRegister\n+  (JNIEnv *env, jobject obj, jstring jregName, jobject jopProp) {\n+\n+  globalEnv = env;\n+\n+  const char *regName = globalEnv->GetStringUTFChars(jregName, 0);\n+  std::string key(regName);\n+  globalOpPropMap.insert({ key, globalEnv->NewGlobalRef(jopProp) });\n+\n+  auto creatorLambda = [](const char *opType, const int numKwargs,\n+    const char  **keys, const char **values, CustomOpPropInfo *ret) {\n+    bool success = true;\n+\n+    // set CustomOpProp.kwargs\n+    std::string opPropKey(opType);\n+    if (globalOpPropMap.find(opPropKey) == globalOpPropMap.end()) {\n+      std::cout << \"CustomOpProp: \" << opPropKey << \" not found\" << std::endl;\n+      success = false;\n+    } else {\n+      jclass opPropClass = globalEnv->GetObjectClass(globalOpPropMap.at(opPropKey));\n+      jmethodID midInit = globalEnv->GetMethodID(opPropClass, \"init\", \"([Ljava/lang/String;[Ljava/lang/String;)V\");\n+      if (NULL == midInit) {\n+        std::cout << \"could not find CustomOpProp method init.\";\n+        success = false;\n+      } else {\n+        // call init\n+        jclass strCls = globalEnv->FindClass(\"Ljava/lang/String;\");\n+        jobjectArray keysArr = globalEnv->NewObjectArray(numKwargs, strCls, NULL);\n+        jobjectArray valuesArr = globalEnv->NewObjectArray(numKwargs, strCls, NULL);\n+        for(int i=0; i<numKwargs; ++i) {\n+          jstring keyStr = globalEnv->NewStringUTF(keys[i]);\n+          jstring valueStr = globalEnv->NewStringUTF(values[i]);\n+          globalEnv->SetObjectArrayElement(keysArr, i, keyStr);\n+          globalEnv->SetObjectArrayElement(valuesArr, i, valueStr);\n+          globalEnv->DeleteLocalRef(keyStr);\n+          globalEnv->DeleteLocalRef(valueStr);\n+        }\n+        globalEnv->CallVoidMethod(globalOpPropMap.at(opPropKey), midInit, keysArr, valuesArr);\n+      }\n+    }\n+\n+    // list_arguments callback\n+    auto opPropListArgument = [](char ***args, void *state) {\n+      bool success = true;\n+      std::string key((char *)state);\n+      if (globalOpPropMap.find(key) == globalOpPropMap.end()) {\n+        std::cout << \"CustomOpProp: \" << key << \" not found\" << std::endl;\n+        success = false;\n+      } else {\n+        jclass opPropClass = globalEnv->GetObjectClass(globalOpPropMap.at(key));\n+        jmethodID midListArguments = globalEnv->GetMethodID(opPropClass, \"listArguments\", \"()[Ljava/lang/String;\");\n+        if (NULL == midListArguments) {\n+          std::cout << \"could not find opProp method listArguments.\";\n+          success = false;\n+        } else {\n+          jobjectArray jargs = (jobjectArray)(globalEnv->CallObjectMethod(globalOpPropMap.at(key), midListArguments));\n+          int len = globalEnv->GetArrayLength(jargs);\n+          (*args) = new char *[len+1];\n+          for (int i = 0; i < len; ++i) {\n+            jstring jarg = reinterpret_cast<jstring>(globalEnv->GetObjectArrayElement(jargs, i));\n+            const char *arg = globalEnv->GetStringUTFChars(jarg, 0);\n+            (*args)[i] = const_cast<char *>(arg);\n+            globalEnv->DeleteLocalRef(jarg);\n+          }\n+          (*args)[len] = NULL;\n+        }\n+      }\n+      return success;\n+    };\n+\n+    // list_outputs callback\n+    auto opPropListOutputs = [](char ***outputs, void *state) {\n+      bool success = true;\n+      std::string key((char *)state);\n+      if (globalOpPropMap.find(key) == globalOpPropMap.end()) {\n+        std::cout << \"CustomOpProp: \" << key << \" not found\" << std::endl;\n+        success = false;\n+      } else {\n+        jclass opPropClass = globalEnv->GetObjectClass(globalOpPropMap.at(key));\n+        jmethodID midListOutputs = globalEnv->GetMethodID(opPropClass, \"listOutputs\", \"()[Ljava/lang/String;\");\n+        if (NULL == midListOutputs) {\n+          std::cout << \"could not find opProp method listOutputs.\";\n+          success = false;\n+        } else {\n+          jobjectArray joutputs = (jobjectArray)(globalEnv->CallObjectMethod(globalOpPropMap.at(key), midListOutputs));\n+          int len = globalEnv->GetArrayLength(joutputs);\n+          (*outputs) = new char *[len + 1];\n+          for (int i = 0; i < len; ++i) {\n+            jstring joutput = reinterpret_cast<jstring>(globalEnv->GetObjectArrayElement(joutputs, i));\n+            const char *output = globalEnv->GetStringUTFChars(joutput, 0);\n+            (*outputs)[i] = const_cast<char *>(output);\n+            globalEnv->DeleteLocalRef(joutput);\n+          }\n+          (*outputs)[len] = NULL;\n+        }\n+      }\n+      return success;\n+    };\n+\n+    // list_auxiliary_states callback\n+    auto opPropListAuxStates = [](char ***auxs, void *state) {\n+      bool success = true;\n+      std::string key((char *)state);\n+      if (globalOpPropMap.find(key) == globalOpPropMap.end()) {\n+        std::cout << \"CustomOpProp: \" << key << \" not found\" << std::endl;\n+        success = false;\n+      } else {\n+        jclass opPropClass = globalEnv->GetObjectClass(globalOpPropMap.at(key));\n+        jmethodID midListAuxStates = globalEnv->GetMethodID(opPropClass, \"listAuxiliaryStates\", \"()[Ljava/lang/String;\");\n+        if (NULL == midListAuxStates) {\n+          std::cout << \"could not find opProp method listAuxiliaryStates.\";\n+          success = false;\n+        } else {\n+          auto obj = globalEnv->CallObjectMethod(globalOpPropMap.at(key), midListAuxStates);\n+          if (obj != NULL) {\n+            jobjectArray jauxs = (jobjectArray)obj;\n+            int len = globalEnv->GetArrayLength(jauxs);\n+            (*auxs) = new char *[len+1];\n+            for (int i = 0; i < len; ++i) {\n+              jstring jaux = reinterpret_cast<jstring>(globalEnv->GetObjectArrayElement(jauxs, i));\n+              const char *aux = globalEnv->GetStringUTFChars(jaux, 0);\n+              (*auxs)[i] = const_cast<char *>(aux);\n+              globalEnv->DeleteLocalRef(jaux);\n+            }\n+            (*auxs)[len] = NULL;\n+          } else { \n+            (*auxs) = new char *[1];\n+            (*auxs)[0] = NULL;\n+          }\n+        }\n+      }\n+      return success;\n+    };\n+\n+    // declare_backward_dependency callback\n+    auto opPropDeclareBkDep = [](const int *outGrad, const int *inData,\n+      const int *outData, int *numDeps, int **rdeps, void *state) {\n+      bool success = true;\n+      std::string key((char *)state);\n+      if (globalOpPropMap.find(key) == globalOpPropMap.end()) {\n+        std::cout << \"CustomOpProp: \" << key << \" not found\" << std::endl;\n+        success = false;\n+      } else {\n+        jclass opPropClass = globalEnv->GetObjectClass(globalOpPropMap.at(key));\n+        jmethodID midDeclareBkDep = globalEnv->GetMethodID(opPropClass, \"declareBackwardDependency\", \"([I[I[I)[I\");\n+        if (NULL == midDeclareBkDep) {\n+          std::cout << \"could not find opProp method declareBackwardDependency.\";\n+          success = false;\n+        } else {\n+          jmethodID midListOutputs = globalEnv->GetMethodID(opPropClass, \"listOutputs\", \"()[Ljava/lang/String;\");\n+          jobjectArray joutputs = (jobjectArray)(globalEnv->CallObjectMethod(globalOpPropMap.at(key), midListOutputs));\n+          int outLen = globalEnv->GetArrayLength(joutputs);\n+          jmethodID midListArguments = globalEnv->GetMethodID(opPropClass, \"listArguments\", \"()[Ljava/lang/String;\");\n+          jobjectArray jargs = (jobjectArray)(globalEnv->CallObjectMethod(globalOpPropMap.at(key), midListArguments));\n+          int intLen = globalEnv->GetArrayLength(jargs);\n+\n+          jintArray outGradArr = globalEnv->NewIntArray(outLen);\n+          globalEnv->SetIntArrayRegion(outGradArr, (jsize)0, (jsize)outLen, outGrad);\n+          jintArray inDataArr = globalEnv->NewIntArray(intLen);\n+          globalEnv->SetIntArrayRegion(inDataArr, (jsize)0, (jsize)intLen, inData);\n+          jintArray outDataArr = globalEnv->NewIntArray(outLen);\n+          globalEnv->SetIntArrayRegion(outDataArr, (jsize)0, (jsize)outLen, outData);\n+\n+          auto obj = globalEnv->CallObjectMethod(globalOpPropMap.at(key), midDeclareBkDep,\n+                                                 outGradArr,\n+                                                 inDataArr,\n+                                                 outDataArr);\n+          jintArray jrdeps = (jintArray)obj;\n+          jint *rdepsArr = globalEnv->GetIntArrayElements(jrdeps, NULL);\n+\n+          (*numDeps) = globalEnv->GetArrayLength(jrdeps);\n+          (* rdeps) = new int[(* numDeps)];\n+          for (int i=0; i<(*numDeps); ++i) {\n+            (* rdeps)[i] = rdepsArr[i];\n+          }\n+\n+          globalEnv->DeleteLocalRef(outGradArr);\n+          globalEnv->DeleteLocalRef(inDataArr);\n+          globalEnv->DeleteLocalRef(outDataArr);\n+          globalEnv->ReleaseIntArrayElements(jrdeps, rdepsArr, 0);\n+        }\n+      }\n+      return success;\n+    };\n+\n+    // infer_shape callback\n+    auto opPropInferShape = [](int numInput, int *ndims,\n+      unsigned **shapes, void *state) {\n+      bool success = true;\n+      std::string key((char *)state);\n+      if (globalOpPropMap.find(key) == globalOpPropMap.end()) {\n+        std::cout << \"CustomOpProp: \" << key << \" not found\" << std::endl;\n+        success = false;\n+      } else {\n+        jclass opPropClass = globalEnv->GetObjectClass(globalOpPropMap.at(key));\n+        jmethodID midInferShape = globalEnv->GetMethodID(opPropClass, \"inferShapeEntry\", \"(I[[I)[[I\");\n+        if (NULL == midInferShape) {\n+          std::cout << \"could not find opProp method inferShapeEntry.\";\n+          success = false;\n+        } else {\n+          jmethodID midListArguments = globalEnv->GetMethodID(opPropClass, \"listArguments\", \"()[Ljava/lang/String;\");\n+          jobjectArray jargs = (jobjectArray)(globalEnv->CallObjectMethod(globalOpPropMap.at(key), midListArguments));\n+          int intLen = globalEnv->GetArrayLength(jargs);\n+          jintArray *ts = new jintArray[intLen];\n+          auto tmp = globalEnv->NewIntArray(1);\n+          jclass arrayClass = globalEnv->GetObjectClass(tmp);\n+          globalEnv->DeleteLocalRef(tmp);\n+          jobjectArray tensorShapes = globalEnv->NewObjectArray(intLen, arrayClass, NULL);\n+          for (int i=0; i<intLen; ++i) {\n+            ts[i] = globalEnv->NewIntArray(ndims[i]);\n+            globalEnv->SetIntArrayRegion(ts[i], (jsize)0, (jsize)ndims[i], (int *)(shapes[i]));\n+            globalEnv->SetObjectArrayElement(tensorShapes, i, (jobject)(ts[i]));\n+          }\n+          jobjectArray ret = (jobjectArray)(globalEnv->CallObjectMethod(globalOpPropMap.at(key), midInferShape,\n+                                                                        numInput,\n+                                                                        tensorShapes));\n+          for (int i=0; i<numInput; ++i) {\n+            jintArray jarr = reinterpret_cast<jintArray>(globalEnv->GetObjectArrayElement(ret, i));\n+            int len = globalEnv->GetArrayLength(jarr);\n+            jint *arr = globalEnv->GetIntArrayElements(jarr, NULL);\n+            ndims[i] = len;\n+            shapes[i] = new unsigned[len];\n+            for (int j=0; j<len; ++j) shapes[i][j] = (unsigned)(arr[j]);\n+            globalEnv->DeleteLocalRef(jarr);\n+          }\n+          for (int i=0; i<intLen; ++i) {\n+            globalEnv->DeleteLocalRef(ts[i]);\n+          }\n+          delete[] ts;\n+        }\n+      }\n+      return success;\n+    };\n+\n+    // create_operator callback\n+    auto opPropCreateOp = [](const char *ctx, int numInputs,\n+      unsigned **shapes, int *ndims, int *dtypes, CustomOpInfo *ret, void *state) {\n+      bool success = true;\n+      std::string key((char *)state);\n+      if (globalOpPropMap.find(key) == globalOpPropMap.end()) {\n+        std::cout << \"CustomOpProp: \" << key << \" not found\" << std::endl;\n+        success = false;\n+      } else {\n+        jclass opPropClass = globalEnv->GetObjectClass(globalOpPropMap.at(key));\n+        jmethodID midCreateOp = globalEnv->GetMethodID(opPropClass, \"createOperator\", \"(Ljava/lang/String;[[I[I)Lml/dmlc/mxnet/CustomOp;\");\n+        if (NULL == midCreateOp) {\n+          std::cout << \"could not find opProp method createOperator.\";\n+          success = false;\n+        } else {\n+          jstring jctx = globalEnv->NewStringUTF(ctx);\n+          jintArray *ts = new jintArray[numInputs];\n+          auto tmp = globalEnv->NewIntArray(1);\n+          jclass arrayClass = globalEnv->GetObjectClass(tmp);\n+          globalEnv->DeleteLocalRef(tmp);\n+          jobjectArray inputShapes = globalEnv->NewObjectArray(numInputs, arrayClass, NULL);\n+          for (int i=0; i<numInputs; ++i) {\n+            ts[i] = globalEnv->NewIntArray(ndims[i]);\n+            globalEnv->SetIntArrayRegion(ts[i], (jsize)0, (jsize)ndims[i], (int *)(shapes[i]));\n+            globalEnv->SetObjectArrayElement(inputShapes, i, (jobject)(ts[i]));\n+          }\n+          jintArray jdtypes = globalEnv->NewIntArray(numInputs);\n+          globalEnv->SetIntArrayRegion(jdtypes, (jsize)0, (jsize)numInputs, dtypes);\n+          // get operator\n+          jobject jOp = globalEnv->CallObjectMethod(globalOpPropMap.at(key), midCreateOp,\n+\t\t                                    jctx,\n+\t\t                                    inputShapes,\n+\t\t                                    jdtypes);\n+          globalEnv->DeleteLocalRef(jctx);\n+          for (int i=0; i<numInputs; ++i) {\n+            globalEnv->DeleteLocalRef(ts[i]);\n+          }\n+          delete[] ts;\n+\n+          globalOpMap.insert({ key, globalEnv->NewGlobalRef(jOp) });\n+\n+          // forward callback\n+          auto forwardEntry = [](int size, void **ptrs, int *tags,\n+            const int *reqs, const bool isTrain, void *state) {\n+            std::string key((char *)state);\n+            bool success = true;\n+            if (globalOpMap.find(key) == globalOpMap.end()) {\n+              std::cout << \"op: \" << key << \" not found\" << std::endl;\n+              success = false;\n+            } else {\n+              _jvm->AttachCurrentThread((void **)&globalEnv, NULL);\n+              jclass opClass =  globalEnv->GetObjectClass(globalOpMap.at(key));\n+              jmethodID midForward = globalEnv->GetMethodID(opClass, \"forwardEntry\", \"(I[J[I[IZ)I\");\n+              if (NULL == midForward) {\n+                std::cout << \"could not find op method forwardEntry.\";\n+                success = false;\n+              } else {\n+                jintArray tagsArr = globalEnv->NewIntArray(size);\n+                globalEnv->SetIntArrayRegion(tagsArr, (jsize)0, (jsize)size, tags);\n+                int reqSize = 0;\n+                for (int i=0; i<size; ++i) {\n+                  if (tags[i] == 1) reqSize ++;\n+                }\n+                jintArray reqsArr = globalEnv->NewIntArray(reqSize);\n+                globalEnv->SetIntArrayRegion(reqsArr, (jsize)0, (jsize)reqSize, reqs);\n+                jlongArray ptrsArr = globalEnv->NewLongArray(size);\n+                globalEnv->SetLongArrayRegion(ptrsArr, (jsize)0, (jsize)size, reinterpret_cast<jlong*>(ptrs));\n+                jint result = globalEnv->CallIntMethod(globalOpMap.at(key), midForward,\n+                                                       size,\n+                                                       ptrsArr,\n+                                                       tagsArr,\n+                                                       reqsArr,\n+                                                       *(const_cast<bool*>(&isTrain)));\n+                if ((int)result == 0) success = false;\n+                globalEnv->DeleteLocalRef(tagsArr);\n+                globalEnv->DeleteLocalRef(reqsArr);\n+                globalEnv->DeleteLocalRef(ptrsArr);\n+              }\n+              _jvm->DetachCurrentThread();\n+            }\n+            return success;\n+          };\n+\n+          // backward callback\n+          auto backwardEntry = [](int size, void **ptrs, int *tags,\n+            const int *reqs, const bool isTrain, void *state) {\n+            std::string key((char *)state);\n+            bool success = true;\n+            // std::cout << \"bkk\" << std::endl;\n+            if (globalOpMap.find(key) == globalOpMap.end()) {\n+              std::cout << \"op: \" << key << \" not found\" << std::endl;\n+              success = false;\n+            } else {\n+              _jvm->AttachCurrentThread((void **)&globalEnv, NULL);\n+              jclass opClass = globalEnv->GetObjectClass(globalOpMap.at(key));\n+              jmethodID midBackward = globalEnv->GetMethodID(opClass, \"backwardEntry\", \"(I[J[I[IZ)I\");\n+              if (NULL == midBackward) {\n+                std::cout << \"could not find op method backwardEntry.\";\n+                success = false;\n+              } else {\n+                jintArray tagsArr = globalEnv->NewIntArray(size);\n+                globalEnv->SetIntArrayRegion(tagsArr, (jsize)0, (jsize)size, tags);\n+\n+                int reqSize = 0;\n+                for (int i=0; i<size; ++i) {\n+                  if (tags[i] == 2) reqSize ++;\n+                }\n+                jintArray reqsArr = globalEnv->NewIntArray(reqSize);\n+                globalEnv->SetIntArrayRegion(reqsArr, (jsize)0, (jsize)reqSize, reqs);\n+                jlongArray ptrsArr = globalEnv->NewLongArray(size);\n+                globalEnv->SetLongArrayRegion(ptrsArr, (jsize)0, (jsize)size, reinterpret_cast<jlong*>(ptrs));\n+                jint result = globalEnv->CallIntMethod(globalOpMap.at(key), midBackward,\n+                                                       size,\n+                                                       ptrsArr,\n+                                                       tagsArr,\n+                                                       reqsArr,\n+                                                       *(const_cast<bool*>(&isTrain)));\n+                if ((int)result == 0) success = false;\n+                globalEnv->DeleteLocalRef(tagsArr);\n+                globalEnv->DeleteLocalRef(reqsArr);\n+                globalEnv->DeleteLocalRef(ptrsArr);\n+              }\n+              _jvm->DetachCurrentThread();\n+            }\n+            return success;\n+          };\n+\n+          // del callback\n+          auto delEntry = [](void *state) {\n+            std::string key((char *)state);\n+            bool success = true;\n+            // if (globalOpMap.find(key) == globalOpMap.end()) {","path":"scala-package/native/src/main/native/ml_dmlc_mxnet_native_c_api.cc","position":384,"original_position":383,"commit_id":"703867700e929c1a8ac623c15a4830eff0615191","original_commit_id":"88d05e1750a1300293d78c8c595987c8d3e037ac","user":{"login":"javelinjs","id":631860,"avatar_url":"https://avatars.githubusercontent.com/u/631860?v=3","gravatar_id":"","url":"https://api.github.com/users/javelinjs","html_url":"https://github.com/javelinjs","followers_url":"https://api.github.com/users/javelinjs/followers","following_url":"https://api.github.com/users/javelinjs/following{/other_user}","gists_url":"https://api.github.com/users/javelinjs/gists{/gist_id}","starred_url":"https://api.github.com/users/javelinjs/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/javelinjs/subscriptions","organizations_url":"https://api.github.com/users/javelinjs/orgs","repos_url":"https://api.github.com/users/javelinjs/repos","events_url":"https://api.github.com/users/javelinjs/events{/privacy}","received_events_url":"https://api.github.com/users/javelinjs/received_events","type":"User","site_admin":false},"body":"I'm not quite sure what happens here. ping @piiswrong","created_at":"2016-12-08T19:14:34Z","updated_at":"2016-12-08T19:19:12Z","html_url":"https://github.com/dmlc/mxnet/pull/4118#discussion_r91585603","pull_request_url":"https://api.github.com/repos/dmlc/mxnet/pulls/4118","_links":{"self":{"href":"https://api.github.com/repos/dmlc/mxnet/pulls/comments/91585603"},"html":{"href":"https://github.com/dmlc/mxnet/pull/4118#discussion_r91585603"},"pull_request":{"href":"https://api.github.com/repos/dmlc/mxnet/pulls/4118"}}},"pull_request":{"url":"https://api.github.com/repos/dmlc/mxnet/pulls/4118","id":96685881,"html_url":"https://github.com/dmlc/mxnet/pull/4118","diff_url":"https://github.com/dmlc/mxnet/pull/4118.diff","patch_url":"https://github.com/dmlc/mxnet/pull/4118.patch","issue_url":"https://api.github.com/repos/dmlc/mxnet/issues/4118","number":4118,"state":"open","locked":false,"title":"[Scala] add CustomOp support","user":{"login":"Ldpe2G","id":2424744,"avatar_url":"https://avatars.githubusercontent.com/u/2424744?v=3","gravatar_id":"","url":"https://api.github.com/users/Ldpe2G","html_url":"https://github.com/Ldpe2G","followers_url":"https://api.github.com/users/Ldpe2G/followers","following_url":"https://api.github.com/users/Ldpe2G/following{/other_user}","gists_url":"https://api.github.com/users/Ldpe2G/gists{/gist_id}","starred_url":"https://api.github.com/users/Ldpe2G/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Ldpe2G/subscriptions","organizations_url":"https://api.github.com/users/Ldpe2G/orgs","repos_url":"https://api.github.com/users/Ldpe2G/repos","events_url":"https://api.github.com/users/Ldpe2G/events{/privacy}","received_events_url":"https://api.github.com/users/Ldpe2G/received_events","type":"User","site_admin":false},"body":"follows: https://github.com/dmlc/mxnet/blob/master/python/mxnet/operator.py\r\n@javelinjs Could you help to review the code?\r\nOr anyone else help to review this code will be appreciated.\r\nI am not sure whether I am implementating it right, for me this is the reasonable way I can come up with.","created_at":"2016-12-06T09:13:37Z","updated_at":"2016-12-08T19:19:12Z","closed_at":null,"merged_at":null,"merge_commit_sha":"53d5b69697f7b6bad2ac5989ff95f4e068f7354d","assignee":null,"assignees":[],"milestone":null,"commits_url":"https://api.github.com/repos/dmlc/mxnet/pulls/4118/commits","review_comments_url":"https://api.github.com/repos/dmlc/mxnet/pulls/4118/comments","review_comment_url":"https://api.github.com/repos/dmlc/mxnet/pulls/comments{/number}","comments_url":"https://api.github.com/repos/dmlc/mxnet/issues/4118/comments","statuses_url":"https://api.github.com/repos/dmlc/mxnet/statuses/703867700e929c1a8ac623c15a4830eff0615191","head":{"label":"Ldpe2G:develop","ref":"develop","sha":"703867700e929c1a8ac623c15a4830eff0615191","user":{"login":"Ldpe2G","id":2424744,"avatar_url":"https://avatars.githubusercontent.com/u/2424744?v=3","gravatar_id":"","url":"https://api.github.com/users/Ldpe2G","html_url":"https://github.com/Ldpe2G","followers_url":"https://api.github.com/users/Ldpe2G/followers","following_url":"https://api.github.com/users/Ldpe2G/following{/other_user}","gists_url":"https://api.github.com/users/Ldpe2G/gists{/gist_id}","starred_url":"https://api.github.com/users/Ldpe2G/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Ldpe2G/subscriptions","organizations_url":"https://api.github.com/users/Ldpe2G/orgs","repos_url":"https://api.github.com/users/Ldpe2G/repos","events_url":"https://api.github.com/users/Ldpe2G/events{/privacy}","received_events_url":"https://api.github.com/users/Ldpe2G/received_events","type":"User","site_admin":false},"repo":{"id":58503781,"name":"mxnet","full_name":"Ldpe2G/mxnet","owner":{"login":"Ldpe2G","id":2424744,"avatar_url":"https://avatars.githubusercontent.com/u/2424744?v=3","gravatar_id":"","url":"https://api.github.com/users/Ldpe2G","html_url":"https://github.com/Ldpe2G","followers_url":"https://api.github.com/users/Ldpe2G/followers","following_url":"https://api.github.com/users/Ldpe2G/following{/other_user}","gists_url":"https://api.github.com/users/Ldpe2G/gists{/gist_id}","starred_url":"https://api.github.com/users/Ldpe2G/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Ldpe2G/subscriptions","organizations_url":"https://api.github.com/users/Ldpe2G/orgs","repos_url":"https://api.github.com/users/Ldpe2G/repos","events_url":"https://api.github.com/users/Ldpe2G/events{/privacy}","received_events_url":"https://api.github.com/users/Ldpe2G/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/Ldpe2G/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/Ldpe2G/mxnet","forks_url":"https://api.github.com/repos/Ldpe2G/mxnet/forks","keys_url":"https://api.github.com/repos/Ldpe2G/mxnet/keys{/key_id}","collaborators_url":"https://api.github.com/repos/Ldpe2G/mxnet/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/Ldpe2G/mxnet/teams","hooks_url":"https://api.github.com/repos/Ldpe2G/mxnet/hooks","issue_events_url":"https://api.github.com/repos/Ldpe2G/mxnet/issues/events{/number}","events_url":"https://api.github.com/repos/Ldpe2G/mxnet/events","assignees_url":"https://api.github.com/repos/Ldpe2G/mxnet/assignees{/user}","branches_url":"https://api.github.com/repos/Ldpe2G/mxnet/branches{/branch}","tags_url":"https://api.github.com/repos/Ldpe2G/mxnet/tags","blobs_url":"https://api.github.com/repos/Ldpe2G/mxnet/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/Ldpe2G/mxnet/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/Ldpe2G/mxnet/git/refs{/sha}","trees_url":"https://api.github.com/repos/Ldpe2G/mxnet/git/trees{/sha}","statuses_url":"https://api.github.com/repos/Ldpe2G/mxnet/statuses/{sha}","languages_url":"https://api.github.com/repos/Ldpe2G/mxnet/languages","stargazers_url":"https://api.github.com/repos/Ldpe2G/mxnet/stargazers","contributors_url":"https://api.github.com/repos/Ldpe2G/mxnet/contributors","subscribers_url":"https://api.github.com/repos/Ldpe2G/mxnet/subscribers","subscription_url":"https://api.github.com/repos/Ldpe2G/mxnet/subscription","commits_url":"https://api.github.com/repos/Ldpe2G/mxnet/commits{/sha}","git_commits_url":"https://api.github.com/repos/Ldpe2G/mxnet/git/commits{/sha}","comments_url":"https://api.github.com/repos/Ldpe2G/mxnet/comments{/number}","issue_comment_url":"https://api.github.com/repos/Ldpe2G/mxnet/issues/comments{/number}","contents_url":"https://api.github.com/repos/Ldpe2G/mxnet/contents/{+path}","compare_url":"https://api.github.com/repos/Ldpe2G/mxnet/compare/{base}...{head}","merges_url":"https://api.github.com/repos/Ldpe2G/mxnet/merges","archive_url":"https://api.github.com/repos/Ldpe2G/mxnet/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/Ldpe2G/mxnet/downloads","issues_url":"https://api.github.com/repos/Ldpe2G/mxnet/issues{/number}","pulls_url":"https://api.github.com/repos/Ldpe2G/mxnet/pulls{/number}","milestones_url":"https://api.github.com/repos/Ldpe2G/mxnet/milestones{/number}","notifications_url":"https://api.github.com/repos/Ldpe2G/mxnet/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/Ldpe2G/mxnet/labels{/name}","releases_url":"https://api.github.com/repos/Ldpe2G/mxnet/releases{/id}","deployments_url":"https://api.github.com/repos/Ldpe2G/mxnet/deployments","created_at":"2016-05-11T01:09:36Z","updated_at":"2016-12-05T01:06:15Z","pushed_at":"2016-12-08T05:12:41Z","git_url":"git://github.com/Ldpe2G/mxnet.git","ssh_url":"git@github.com:Ldpe2G/mxnet.git","clone_url":"https://github.com/Ldpe2G/mxnet.git","svn_url":"https://github.com/Ldpe2G/mxnet","homepage":"http://mxnet.rtfd.org","size":12262,"stargazers_count":1,"watchers_count":1,"language":"C++","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":1,"default_branch":"develop"}},"base":{"label":"dmlc:master","ref":"master","sha":"a457228b0f74992cab04a61a18bcf6b366e24342","user":{"login":"dmlc","id":11508361,"avatar_url":"https://avatars.githubusercontent.com/u/11508361?v=3","gravatar_id":"","url":"https://api.github.com/users/dmlc","html_url":"https://github.com/dmlc","followers_url":"https://api.github.com/users/dmlc/followers","following_url":"https://api.github.com/users/dmlc/following{/other_user}","gists_url":"https://api.github.com/users/dmlc/gists{/gist_id}","starred_url":"https://api.github.com/users/dmlc/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dmlc/subscriptions","organizations_url":"https://api.github.com/users/dmlc/orgs","repos_url":"https://api.github.com/users/dmlc/repos","events_url":"https://api.github.com/users/dmlc/events{/privacy}","received_events_url":"https://api.github.com/users/dmlc/received_events","type":"Organization","site_admin":false},"repo":{"id":34864402,"name":"mxnet","full_name":"dmlc/mxnet","owner":{"login":"dmlc","id":11508361,"avatar_url":"https://avatars.githubusercontent.com/u/11508361?v=3","gravatar_id":"","url":"https://api.github.com/users/dmlc","html_url":"https://github.com/dmlc","followers_url":"https://api.github.com/users/dmlc/followers","following_url":"https://api.github.com/users/dmlc/following{/other_user}","gists_url":"https://api.github.com/users/dmlc/gists{/gist_id}","starred_url":"https://api.github.com/users/dmlc/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dmlc/subscriptions","organizations_url":"https://api.github.com/users/dmlc/orgs","repos_url":"https://api.github.com/users/dmlc/repos","events_url":"https://api.github.com/users/dmlc/events{/privacy}","received_events_url":"https://api.github.com/users/dmlc/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/dmlc/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/dmlc/mxnet","forks_url":"https://api.github.com/repos/dmlc/mxnet/forks","keys_url":"https://api.github.com/repos/dmlc/mxnet/keys{/key_id}","collaborators_url":"https://api.github.com/repos/dmlc/mxnet/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/dmlc/mxnet/teams","hooks_url":"https://api.github.com/repos/dmlc/mxnet/hooks","issue_events_url":"https://api.github.com/repos/dmlc/mxnet/issues/events{/number}","events_url":"https://api.github.com/repos/dmlc/mxnet/events","assignees_url":"https://api.github.com/repos/dmlc/mxnet/assignees{/user}","branches_url":"https://api.github.com/repos/dmlc/mxnet/branches{/branch}","tags_url":"https://api.github.com/repos/dmlc/mxnet/tags","blobs_url":"https://api.github.com/repos/dmlc/mxnet/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/dmlc/mxnet/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/dmlc/mxnet/git/refs{/sha}","trees_url":"https://api.github.com/repos/dmlc/mxnet/git/trees{/sha}","statuses_url":"https://api.github.com/repos/dmlc/mxnet/statuses/{sha}","languages_url":"https://api.github.com/repos/dmlc/mxnet/languages","stargazers_url":"https://api.github.com/repos/dmlc/mxnet/stargazers","contributors_url":"https://api.github.com/repos/dmlc/mxnet/contributors","subscribers_url":"https://api.github.com/repos/dmlc/mxnet/subscribers","subscription_url":"https://api.github.com/repos/dmlc/mxnet/subscription","commits_url":"https://api.github.com/repos/dmlc/mxnet/commits{/sha}","git_commits_url":"https://api.github.com/repos/dmlc/mxnet/git/commits{/sha}","comments_url":"https://api.github.com/repos/dmlc/mxnet/comments{/number}","issue_comment_url":"https://api.github.com/repos/dmlc/mxnet/issues/comments{/number}","contents_url":"https://api.github.com/repos/dmlc/mxnet/contents/{+path}","compare_url":"https://api.github.com/repos/dmlc/mxnet/compare/{base}...{head}","merges_url":"https://api.github.com/repos/dmlc/mxnet/merges","archive_url":"https://api.github.com/repos/dmlc/mxnet/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/dmlc/mxnet/downloads","issues_url":"https://api.github.com/repos/dmlc/mxnet/issues{/number}","pulls_url":"https://api.github.com/repos/dmlc/mxnet/pulls{/number}","milestones_url":"https://api.github.com/repos/dmlc/mxnet/milestones{/number}","notifications_url":"https://api.github.com/repos/dmlc/mxnet/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/dmlc/mxnet/labels{/name}","releases_url":"https://api.github.com/repos/dmlc/mxnet/releases{/id}","deployments_url":"https://api.github.com/repos/dmlc/mxnet/deployments","created_at":"2015-04-30T16:21:15Z","updated_at":"2016-12-08T15:54:07Z","pushed_at":"2016-12-08T15:41:22Z","git_url":"git://github.com/dmlc/mxnet.git","ssh_url":"git@github.com:dmlc/mxnet.git","clone_url":"https://github.com/dmlc/mxnet.git","svn_url":"https://github.com/dmlc/mxnet","homepage":"http://mxnet.io","size":21510,"stargazers_count":6939,"watchers_count":6939,"language":"C++","has_issues":true,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":2545,"mirror_url":null,"open_issues_count":911,"forks":2545,"open_issues":911,"watchers":6939,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/dmlc/mxnet/pulls/4118"},"html":{"href":"https://github.com/dmlc/mxnet/pull/4118"},"issue":{"href":"https://api.github.com/repos/dmlc/mxnet/issues/4118"},"comments":{"href":"https://api.github.com/repos/dmlc/mxnet/issues/4118/comments"},"review_comments":{"href":"https://api.github.com/repos/dmlc/mxnet/pulls/4118/comments"},"review_comment":{"href":"https://api.github.com/repos/dmlc/mxnet/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/dmlc/mxnet/pulls/4118/commits"},"statuses":{"href":"https://api.github.com/repos/dmlc/mxnet/statuses/703867700e929c1a8ac623c15a4830eff0615191"}}}}
{"actor":{"display_login":"javelinjs"}}