{"action":"created","comment":{"url":"https://api.github.com/repos/uber/horovod/pulls/comments/244257938","pull_request_review_id":188214172,"id":244257938,"node_id":"MDI0OlB1bGxSZXF1ZXN0UmV2aWV3Q29tbWVudDI0NDI1NzkzOA==","diff_hunk":"@@ -0,0 +1,287 @@\n+# Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.\n+#\n+# Permission is hereby granted, free of charge, to any person obtaining a copy of this\n+# software and associated documentation files (the \"Software\"), to deal in the Software\n+# without restriction, including without limitation the rights to use, copy, modify,\n+# merge, publish, distribute, sublicense, and/or sell copies of the Software, and to\n+# permit persons to whom the Software is furnished to do so.\n+#\n+# THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n+# INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A\n+# PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n+# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\n+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n+# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n+\n+import argparse, time, logging, os\n+import numpy as np\n+import mxnet as mx\n+import math\n+from mxnet import gluon, nd\n+from mxnet import autograd as ag\n+from mxnet.lr_scheduler import MultiFactorScheduler\n+from mxnet.io import DataBatch, DataIter\n+from mxnet.util import makedirs\n+from mxnet.gluon.model_zoo.vision import get_model\n+\n+import horovod.mxnet as hvd\n+\n+# Initialize Horovod\n+hvd.init()\n+\n+# CLI\n+parser = argparse.ArgumentParser(description='Train a model for image classification.')\n+parser.add_argument('--benchmark', type=int, default='0',\n+                    help='if 0 then feed the network with synthetic data.')\n+parser.add_argument('--data-nthreads', type=int, default=4,\n+                    help='number of threads for data decoding')\n+parser.add_argument('--rec-train', type=str, default='',\n+                    help='the training data')\n+parser.add_argument('--rec-train-idx', type=str, default='',\n+                    help='the index of training data')\n+parser.add_argument('--rec-val', type=str, default='',\n+                    help='the validation data')\n+parser.add_argument('--rec-val-idx', type=str, default='',\n+                    help='the index of validation data')\n+parser.add_argument('--batch-size', type=int, default=128,\n+                    help='training batch size per device (CPU/GPU).')\n+parser.add_argument('--dtype', type=str, default='float32',\n+                    help='data type for training, default is float32')\n+parser.add_argument('--gpus', type=str, default='0',\n+                    help='number of gpus to use.')\n+parser.add_argument('--num-epochs', type=int, default=90,\n+                    help='number of training epochs.')\n+parser.add_argument('--lr', type=float, default=0.1,\n+                    help='learning rate, default is 0.1.')\n+parser.add_argument('--momentum', type=float, default=0.9,\n+                    help='momentum value for optimizer, default is 0.9.')\n+parser.add_argument('--wd', type=float, default=0.0001,\n+                    help='weight decay rate, default is 0.0001.')\n+parser.add_argument('--lr-decay', type=float, default=0.1,\n+                    help='decay rate of learning rate, default is 0.1.')\n+parser.add_argument('--lr-decay-epoch', type=str, default='40,60',\n+                    help='epoches at which learning rate decays, default is 40,60.')\n+parser.add_argument('--warmup-lr', type=float, default=0.001,\n+                    help='starting warmup learning rate, default is 0.001')\n+parser.add_argument('--warmup-epochs', type=int, default=5,\n+                    help='number of warmup epochs, default is 5.')\n+parser.add_argument('--model', type=str, required=True,\n+                    help='type of model to use. see vision_model for options.')\n+parser.add_argument('--use-pretrained', action='store_true',\n+                    help='enable using pretrained model from gluon.')\n+parser.add_argument('--save-frequency', type=int, default=0,\n+                    help='frequency of model saving.')\n+args = parser.parse_args()\n+\n+logging.basicConfig(level=logging.INFO)\n+logging.info(args)\n+\n+save_frequency = args.save_frequency\n+batch_size = args.batch_size\n+classes = 1000\n+num_training_samples = 1281167\n+\n+data_nthreads = args.data_nthreads\n+context = mx.cpu() if args.gpus is None or args.gpus == \"\" else mx.gpu(hvd.local_rank())\n+num_workers = hvd.size()\n+batch_size = args.batch_size\n+kwargs = {'ctx': context, 'pretrained': args.use_pretrained, 'classes': classes}\n+\n+epoch_size = int(math.ceil(int(num_training_samples // num_workers)/batch_size))\n+\n+# Adjust learning rate\n+lr_decay = args.lr_decay\n+lr_decay_epoch = [int(i) for i in args.lr_decay_epoch.split(',')]\n+steps = [epoch_size * x for x in lr_decay_epoch]\n+lr_scheduler = MultiFactorScheduler(step=steps, factor=lr_decay, base_lr=args.lr, warmup_steps=(args.warmup_epochs * epoch_size), warmup_begin_lr=args.warmup_lr)\n+\n+# Two functions for reading data from record file or raw images\n+# For more details about data loading in MXNet, please refer to\n+# https://mxnet.incubator.apache.org/tutorials/basic/data.html?highlight=imagerecorditer\n+def get_data_rec(rec_train, rec_train_idx, rec_val, rec_val_idx, batch_size, data_nthreads):\n+    rec_train = os.path.expanduser(rec_train)\n+    rec_train_idx = os.path.expanduser(rec_train_idx)\n+    rec_val = os.path.expanduser(rec_val)\n+    rec_val_idx = os.path.expanduser(rec_val_idx)\n+    jitter_param = 0.4\n+    lighting_param = 0.1\n+    mean_rgb = [123.68, 116.779, 103.939]\n+    std_rgb = [58.393, 57.12, 57.375]\n+\n+    def batch_fn(batch, ctx):\n+        data = gluon.utils.split_and_load(batch.data[0], ctx_list=ctx, batch_axis=0)\n+        label = gluon.utils.split_and_load(batch.label[0], ctx_list=ctx, batch_axis=0)\n+        return data, label\n+\n+    train_data = mx.io.ImageRecordIter(\n+        path_imgrec         = rec_train,\n+        path_imgidx         = rec_train_idx,\n+        preprocess_threads  = data_nthreads,\n+        shuffle             = True,\n+        batch_size          = batch_size,\n+        label_width         = 1,\n+        data_shape          = (3, 224, 224),\n+        mean_r              = mean_rgb[0],\n+        mean_g              = mean_rgb[1],\n+        mean_b              = mean_rgb[2],\n+        rand_mirror         = True,\n+        rand_crop           = False,\n+        random_resized_crop = True,\n+        max_aspect_ratio    = 4. / 3.,\n+        min_aspect_ratio    = 3. / 4.,\n+        max_random_area     = 1,\n+        min_random_area     = 0.08,\n+        verbose             = False,\n+        brightness          = jitter_param,\n+        saturation          = jitter_param,\n+        contrast            = jitter_param,\n+        pca_noise           = lighting_param,\n+        num_parts           = hvd.size(),\n+        part_index          = hvd.rank()\n+    )\n+    # kept each node to use full val data to make it easy to monitor results\n+    val_data = mx.io.ImageRecordIter(\n+        path_imgrec         = rec_val,\n+        path_imgidx         = rec_val_idx,\n+        preprocess_threads  = data_nthreads,\n+        shuffle             = False,\n+        batch_size          = batch_size,\n+        resize              = 256,\n+        label_width         = 1,\n+        rand_crop           = False,\n+        rand_mirror         = False,\n+        data_shape          = (3, 224, 224),\n+        mean_r              = mean_rgb[0],\n+        mean_g              = mean_rgb[1],\n+        mean_b              = mean_rgb[2]\n+    )\n+\n+    return train_data, val_data, batch_fn\n+\n+# Create data iterator for synthetic data\n+class SyntheticDataIter(DataIter):\n+    def __init__(self, num_classes, data_shape, max_iter, dtype):\n+        self.batch_size = data_shape[0]\n+        self.cur_iter = 0\n+        self.max_iter = max_iter\n+        self.dtype = dtype\n+        label = np.random.randint(0, num_classes, [self.batch_size,])\n+        data = np.random.uniform(-1, 1, data_shape)\n+        self.data = mx.nd.array(data, dtype=self.dtype, ctx=mx.Context('cpu_pinned', hvd.local_rank()))\n+        self.label = mx.nd.array(label, dtype=self.dtype, ctx=mx.Context('cpu_pinned', hvd.local_rank()))\n+    def __iter__(self):\n+        return self\n+    @property","path":"examples/mxnet_imagenet_resnet50.py","position":174,"original_position":174,"commit_id":"0bcef707b5dd59bbc4f1a9ffaca6876630bf1bb1","original_commit_id":"0bcef707b5dd59bbc4f1a9ffaca6876630bf1bb1","user":{"login":"alsrgv","id":16640218,"node_id":"MDQ6VXNlcjE2NjQwMjE4","avatar_url":"https://avatars2.githubusercontent.com/u/16640218?v=4","gravatar_id":"","url":"https://api.github.com/users/alsrgv","html_url":"https://github.com/alsrgv","followers_url":"https://api.github.com/users/alsrgv/followers","following_url":"https://api.github.com/users/alsrgv/following{/other_user}","gists_url":"https://api.github.com/users/alsrgv/gists{/gist_id}","starred_url":"https://api.github.com/users/alsrgv/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/alsrgv/subscriptions","organizations_url":"https://api.github.com/users/alsrgv/orgs","repos_url":"https://api.github.com/users/alsrgv/repos","events_url":"https://api.github.com/users/alsrgv/events{/privacy}","received_events_url":"https://api.github.com/users/alsrgv/received_events","type":"User","site_admin":false},"body":"Style: can you format according to PEP-8?  There should be a space between member declarations, two spaces around classes, etc.","created_at":"2018-12-28T03:45:06Z","updated_at":"2018-12-28T03:58:58Z","html_url":"https://github.com/uber/horovod/pull/542#discussion_r244257938","pull_request_url":"https://api.github.com/repos/uber/horovod/pulls/542","author_association":"COLLABORATOR","_links":{"self":{"href":"https://api.github.com/repos/uber/horovod/pulls/comments/244257938"},"html":{"href":"https://github.com/uber/horovod/pull/542#discussion_r244257938"},"pull_request":{"href":"https://api.github.com/repos/uber/horovod/pulls/542"}}},"pull_request":{"url":"https://api.github.com/repos/uber/horovod/pulls/542","id":220874740,"node_id":"MDExOlB1bGxSZXF1ZXN0MjIwODc0NzQw","html_url":"https://github.com/uber/horovod/pull/542","diff_url":"https://github.com/uber/horovod/pull/542.diff","patch_url":"https://github.com/uber/horovod/pull/542.patch","issue_url":"https://api.github.com/repos/uber/horovod/issues/542","number":542,"state":"open","locked":false,"title":"Horovod support for MXNet framework","user":{"login":"ctcyang","id":2542420,"node_id":"MDQ6VXNlcjI1NDI0MjA=","avatar_url":"https://avatars3.githubusercontent.com/u/2542420?v=4","gravatar_id":"","url":"https://api.github.com/users/ctcyang","html_url":"https://github.com/ctcyang","followers_url":"https://api.github.com/users/ctcyang/followers","following_url":"https://api.github.com/users/ctcyang/following{/other_user}","gists_url":"https://api.github.com/users/ctcyang/gists{/gist_id}","starred_url":"https://api.github.com/users/ctcyang/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ctcyang/subscriptions","organizations_url":"https://api.github.com/users/ctcyang/orgs","repos_url":"https://api.github.com/users/ctcyang/repos","events_url":"https://api.github.com/users/ctcyang/events{/privacy}","received_events_url":"https://api.github.com/users/ctcyang/received_events","type":"User","site_admin":false},"body":"This is a PR for adding Horovod support to do distributed training with the MXNet deep learning framework. The core Allreduce and Broadcast functionality passes unit tests. @yuxihu and @apeforest are currently training ResNet-50 end-to-end, so that should tell us if this setup converges or not.\r\n\r\nOur performance results are here showing throughput (scaling efficiency) with and without hierarchical allreduce (HA) on ResNet-50 with float32:\r\n```\r\n# gpus | Without HA |   With HA\r\n---------------------------------\r\n   8   |  3072  (NA)|  3078  (NA)\r\n  16   |  6027 (98%)|  5859 (95%)\r\n  32   | 12030 (98%)| 11675 (95%)\r\n  64   | 22346 (83%)| 23166 (94%)\r\n 128   | 40938 (84%)| 45972 (93%)\r\n 256   | 64998 (66%)| 89858 (91%)\r\n```\r\n\r\nWe have completed and merged the PR to make necessary changes on the MXNet for Horovod support. You can see the PR here: https://github.com/apache/incubator-mxnet/pull/12666\r\n\r\n[Design document](https://cwiki.apache.org/confluence/display/MXNET/Horovod-MXNet+Integration) \r\n[Installation instructions](https://github.com/ctcyang/incubator-mxnet/tree/horovod_feature/example/image-classification/scripts)","created_at":"2018-10-06T09:06:36Z","updated_at":"2018-12-28T03:58:58Z","closed_at":null,"merged_at":null,"merge_commit_sha":"ef06239edb1a95cb7c2e1c00c7c3b2da686ee61c","assignee":null,"assignees":[],"requested_reviewers":[],"requested_teams":[],"labels":[],"milestone":null,"commits_url":"https://api.github.com/repos/uber/horovod/pulls/542/commits","review_comments_url":"https://api.github.com/repos/uber/horovod/pulls/542/comments","review_comment_url":"https://api.github.com/repos/uber/horovod/pulls/comments{/number}","comments_url":"https://api.github.com/repos/uber/horovod/issues/542/comments","statuses_url":"https://api.github.com/repos/uber/horovod/statuses/0bcef707b5dd59bbc4f1a9ffaca6876630bf1bb1","head":{"label":"ctcyang:mxnet_feature_fp16","ref":"mxnet_feature_fp16","sha":"0bcef707b5dd59bbc4f1a9ffaca6876630bf1bb1","user":{"login":"ctcyang","id":2542420,"node_id":"MDQ6VXNlcjI1NDI0MjA=","avatar_url":"https://avatars3.githubusercontent.com/u/2542420?v=4","gravatar_id":"","url":"https://api.github.com/users/ctcyang","html_url":"https://github.com/ctcyang","followers_url":"https://api.github.com/users/ctcyang/followers","following_url":"https://api.github.com/users/ctcyang/following{/other_user}","gists_url":"https://api.github.com/users/ctcyang/gists{/gist_id}","starred_url":"https://api.github.com/users/ctcyang/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ctcyang/subscriptions","organizations_url":"https://api.github.com/users/ctcyang/orgs","repos_url":"https://api.github.com/users/ctcyang/repos","events_url":"https://api.github.com/users/ctcyang/events{/privacy}","received_events_url":"https://api.github.com/users/ctcyang/received_events","type":"User","site_admin":false},"repo":{"id":140943649,"node_id":"MDEwOlJlcG9zaXRvcnkxNDA5NDM2NDk=","name":"horovod","full_name":"ctcyang/horovod","private":false,"owner":{"login":"ctcyang","id":2542420,"node_id":"MDQ6VXNlcjI1NDI0MjA=","avatar_url":"https://avatars3.githubusercontent.com/u/2542420?v=4","gravatar_id":"","url":"https://api.github.com/users/ctcyang","html_url":"https://github.com/ctcyang","followers_url":"https://api.github.com/users/ctcyang/followers","following_url":"https://api.github.com/users/ctcyang/following{/other_user}","gists_url":"https://api.github.com/users/ctcyang/gists{/gist_id}","starred_url":"https://api.github.com/users/ctcyang/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ctcyang/subscriptions","organizations_url":"https://api.github.com/users/ctcyang/orgs","repos_url":"https://api.github.com/users/ctcyang/repos","events_url":"https://api.github.com/users/ctcyang/events{/privacy}","received_events_url":"https://api.github.com/users/ctcyang/received_events","type":"User","site_admin":false},"html_url":"https://github.com/ctcyang/horovod","description":"Distributed training framework for TensorFlow, Keras, and PyTorch.","fork":true,"url":"https://api.github.com/repos/ctcyang/horovod","forks_url":"https://api.github.com/repos/ctcyang/horovod/forks","keys_url":"https://api.github.com/repos/ctcyang/horovod/keys{/key_id}","collaborators_url":"https://api.github.com/repos/ctcyang/horovod/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/ctcyang/horovod/teams","hooks_url":"https://api.github.com/repos/ctcyang/horovod/hooks","issue_events_url":"https://api.github.com/repos/ctcyang/horovod/issues/events{/number}","events_url":"https://api.github.com/repos/ctcyang/horovod/events","assignees_url":"https://api.github.com/repos/ctcyang/horovod/assignees{/user}","branches_url":"https://api.github.com/repos/ctcyang/horovod/branches{/branch}","tags_url":"https://api.github.com/repos/ctcyang/horovod/tags","blobs_url":"https://api.github.com/repos/ctcyang/horovod/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/ctcyang/horovod/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/ctcyang/horovod/git/refs{/sha}","trees_url":"https://api.github.com/repos/ctcyang/horovod/git/trees{/sha}","statuses_url":"https://api.github.com/repos/ctcyang/horovod/statuses/{sha}","languages_url":"https://api.github.com/repos/ctcyang/horovod/languages","stargazers_url":"https://api.github.com/repos/ctcyang/horovod/stargazers","contributors_url":"https://api.github.com/repos/ctcyang/horovod/contributors","subscribers_url":"https://api.github.com/repos/ctcyang/horovod/subscribers","subscription_url":"https://api.github.com/repos/ctcyang/horovod/subscription","commits_url":"https://api.github.com/repos/ctcyang/horovod/commits{/sha}","git_commits_url":"https://api.github.com/repos/ctcyang/horovod/git/commits{/sha}","comments_url":"https://api.github.com/repos/ctcyang/horovod/comments{/number}","issue_comment_url":"https://api.github.com/repos/ctcyang/horovod/issues/comments{/number}","contents_url":"https://api.github.com/repos/ctcyang/horovod/contents/{+path}","compare_url":"https://api.github.com/repos/ctcyang/horovod/compare/{base}...{head}","merges_url":"https://api.github.com/repos/ctcyang/horovod/merges","archive_url":"https://api.github.com/repos/ctcyang/horovod/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/ctcyang/horovod/downloads","issues_url":"https://api.github.com/repos/ctcyang/horovod/issues{/number}","pulls_url":"https://api.github.com/repos/ctcyang/horovod/pulls{/number}","milestones_url":"https://api.github.com/repos/ctcyang/horovod/milestones{/number}","notifications_url":"https://api.github.com/repos/ctcyang/horovod/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/ctcyang/horovod/labels{/name}","releases_url":"https://api.github.com/repos/ctcyang/horovod/releases{/id}","deployments_url":"https://api.github.com/repos/ctcyang/horovod/deployments","created_at":"2018-07-14T12:16:47Z","updated_at":"2018-12-28T03:08:03Z","pushed_at":"2018-12-28T03:09:40Z","git_url":"git://github.com/ctcyang/horovod.git","ssh_url":"git@github.com:ctcyang/horovod.git","clone_url":"https://github.com/ctcyang/horovod.git","svn_url":"https://github.com/ctcyang/horovod","homepage":"","size":1098,"stargazers_count":2,"watchers_count":2,"language":"C++","has_issues":false,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"archived":false,"open_issues_count":1,"license":{"key":"other","name":"Other","spdx_id":"NOASSERTION","url":null,"node_id":"MDc6TGljZW5zZTA="},"forks":0,"open_issues":1,"watchers":2,"default_branch":"master"}},"base":{"label":"uber:master","ref":"master","sha":"8142b63302f98e1892cf636fa50fd25014802530","user":{"login":"uber","id":538264,"node_id":"MDEyOk9yZ2FuaXphdGlvbjUzODI2NA==","avatar_url":"https://avatars3.githubusercontent.com/u/538264?v=4","gravatar_id":"","url":"https://api.github.com/users/uber","html_url":"https://github.com/uber","followers_url":"https://api.github.com/users/uber/followers","following_url":"https://api.github.com/users/uber/following{/other_user}","gists_url":"https://api.github.com/users/uber/gists{/gist_id}","starred_url":"https://api.github.com/users/uber/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/uber/subscriptions","organizations_url":"https://api.github.com/users/uber/orgs","repos_url":"https://api.github.com/users/uber/repos","events_url":"https://api.github.com/users/uber/events{/privacy}","received_events_url":"https://api.github.com/users/uber/received_events","type":"Organization","site_admin":false},"repo":{"id":99846383,"node_id":"MDEwOlJlcG9zaXRvcnk5OTg0NjM4Mw==","name":"horovod","full_name":"uber/horovod","private":false,"owner":{"login":"uber","id":538264,"node_id":"MDEyOk9yZ2FuaXphdGlvbjUzODI2NA==","avatar_url":"https://avatars3.githubusercontent.com/u/538264?v=4","gravatar_id":"","url":"https://api.github.com/users/uber","html_url":"https://github.com/uber","followers_url":"https://api.github.com/users/uber/followers","following_url":"https://api.github.com/users/uber/following{/other_user}","gists_url":"https://api.github.com/users/uber/gists{/gist_id}","starred_url":"https://api.github.com/users/uber/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/uber/subscriptions","organizations_url":"https://api.github.com/users/uber/orgs","repos_url":"https://api.github.com/users/uber/repos","events_url":"https://api.github.com/users/uber/events{/privacy}","received_events_url":"https://api.github.com/users/uber/received_events","type":"Organization","site_admin":false},"html_url":"https://github.com/uber/horovod","description":"Distributed training framework for TensorFlow, Keras, and PyTorch.","fork":false,"url":"https://api.github.com/repos/uber/horovod","forks_url":"https://api.github.com/repos/uber/horovod/forks","keys_url":"https://api.github.com/repos/uber/horovod/keys{/key_id}","collaborators_url":"https://api.github.com/repos/uber/horovod/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/uber/horovod/teams","hooks_url":"https://api.github.com/repos/uber/horovod/hooks","issue_events_url":"https://api.github.com/repos/uber/horovod/issues/events{/number}","events_url":"https://api.github.com/repos/uber/horovod/events","assignees_url":"https://api.github.com/repos/uber/horovod/assignees{/user}","branches_url":"https://api.github.com/repos/uber/horovod/branches{/branch}","tags_url":"https://api.github.com/repos/uber/horovod/tags","blobs_url":"https://api.github.com/repos/uber/horovod/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/uber/horovod/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/uber/horovod/git/refs{/sha}","trees_url":"https://api.github.com/repos/uber/horovod/git/trees{/sha}","statuses_url":"https://api.github.com/repos/uber/horovod/statuses/{sha}","languages_url":"https://api.github.com/repos/uber/horovod/languages","stargazers_url":"https://api.github.com/repos/uber/horovod/stargazers","contributors_url":"https://api.github.com/repos/uber/horovod/contributors","subscribers_url":"https://api.github.com/repos/uber/horovod/subscribers","subscription_url":"https://api.github.com/repos/uber/horovod/subscription","commits_url":"https://api.github.com/repos/uber/horovod/commits{/sha}","git_commits_url":"https://api.github.com/repos/uber/horovod/git/commits{/sha}","comments_url":"https://api.github.com/repos/uber/horovod/comments{/number}","issue_comment_url":"https://api.github.com/repos/uber/horovod/issues/comments{/number}","contents_url":"https://api.github.com/repos/uber/horovod/contents/{+path}","compare_url":"https://api.github.com/repos/uber/horovod/compare/{base}...{head}","merges_url":"https://api.github.com/repos/uber/horovod/merges","archive_url":"https://api.github.com/repos/uber/horovod/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/uber/horovod/downloads","issues_url":"https://api.github.com/repos/uber/horovod/issues{/number}","pulls_url":"https://api.github.com/repos/uber/horovod/pulls{/number}","milestones_url":"https://api.github.com/repos/uber/horovod/milestones{/number}","notifications_url":"https://api.github.com/repos/uber/horovod/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/uber/horovod/labels{/name}","releases_url":"https://api.github.com/repos/uber/horovod/releases{/id}","deployments_url":"https://api.github.com/repos/uber/horovod/deployments","created_at":"2017-08-09T19:39:59Z","updated_at":"2018-12-28T02:27:34Z","pushed_at":"2018-12-28T03:09:41Z","git_url":"git://github.com/uber/horovod.git","ssh_url":"git@github.com:uber/horovod.git","clone_url":"https://github.com/uber/horovod.git","svn_url":"https://github.com/uber/horovod","homepage":"https://eng.uber.com/horovod/","size":992,"stargazers_count":4805,"watchers_count":4805,"language":"C++","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":664,"mirror_url":null,"archived":false,"open_issues_count":205,"license":{"key":"other","name":"Other","spdx_id":"NOASSERTION","url":null,"node_id":"MDc6TGljZW5zZTA="},"forks":664,"open_issues":205,"watchers":4805,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/uber/horovod/pulls/542"},"html":{"href":"https://github.com/uber/horovod/pull/542"},"issue":{"href":"https://api.github.com/repos/uber/horovod/issues/542"},"comments":{"href":"https://api.github.com/repos/uber/horovod/issues/542/comments"},"review_comments":{"href":"https://api.github.com/repos/uber/horovod/pulls/542/comments"},"review_comment":{"href":"https://api.github.com/repos/uber/horovod/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/uber/horovod/pulls/542/commits"},"statuses":{"href":"https://api.github.com/repos/uber/horovod/statuses/0bcef707b5dd59bbc4f1a9ffaca6876630bf1bb1"}},"author_association":"NONE"}}
{"actor":{"display_login":"alsrgv"}}