[
  {
    "path": ".gitignore",
    "content": "legacy/*\n.DS_Store\ndebug/*\n*.DS_Store\n*.json\n*.mat\nsrc/.vscode/*\npreds/*\n*.h5\n*.pth\n*.checkpoint\n# Byte-compiled / optimized / DLL files\n__pycache__/\n*.py[cod]\n*$py.class\n\n# C extensions\n*.so\n\n# Distribution / packaging\n.Python\nenv/\nbuild/\ndevelop-eggs/\ndist/\ndownloads/\neggs/\n.eggs/\nlib64/\nparts/\nsdist/\nvar/\nwheels/\n*.egg-info/\n.installed.cfg\n*.egg\n\n# PyInstaller\n#  Usually these files are written by a python script from a template\n#  before PyInstaller builds the exe, so as to inject date/other infos into it.\n*.manifest\n*.spec\n\n# Installer logs\npip-log.txt\npip-delete-this-directory.txt\n\n# Unit test / coverage reports\nhtmlcov/\n.tox/\n.coverage\n.coverage.*\n.cache\nnosetests.xml\ncoverage.xml\n*.cover\n.hypothesis/\n\n# Translations\n*.mo\n*.pot\n\n# Django stuff:\n*.log\nlocal_settings.py\n\n# Flask stuff:\ninstance/\n.webassets-cache\n\n# Scrapy stuff:\n.scrapy\n\n# Sphinx documentation\ndocs/_build/\n\n# PyBuilder\ntarget/\n\n# Jupyter Notebook\n.ipynb_checkpoints\n\n# pyenv\n.python-version\n\n# celery beat schedule file\ncelerybeat-schedule\n\n# SageMath parsed files\n*.sage.py\n\n# dotenv\n.env\n\n# virtualenv\n.venv\nvenv/\nENV/\n\n# Spyder project settings\n.spyderproject\n.spyproject\n\n# Rope project settings\n.ropeproject\n\n# mkdocs documentation\n/site\n\n# mypy\n.mypy_cache/\n"
  },
  {
    "path": ".travis.yml",
    "content": "group: travis_latest\ndist: xenial  # ubuntu-16.04\nlanguage: python\ncache: pip\npython:\n  - 3.6\n  - 3.7\ninstall:\n  - pip install flake8\n  - pip install -r requirements.txt\nbefore_script:\n  # stop the build if there are Python syntax errors or undefined names\n  - flake8 . --count --select=E9,F63,F72,F82 --show-source --statistics\n  # exit-zero treats all errors as warnings.  The GitHub editor is 127 chars wide\n  - flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics\nscript:\n  - true  # add other tests here\nnotifications:\n  on_success: change\n  on_failure: change  # `always` will be the setting once code changes slow down\n"
  },
  {
    "path": "LICENSE",
    "content": "MIT License\n\nCopyright (c) 2019 Xingyi Zhou\nAll rights reserved.\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n\n"
  },
  {
    "path": "NOTICE",
    "content": "Portions of this software are derived from tf-faster-rcnn.\n\n==============================================================================\ntf-faster-rcnn licence\n==============================================================================\n\nMIT License\n\nCopyright (c) 2017 Xinlei Chen\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n\n\nPortions of this software are derived from human-pose-estimation.pytorch.\n\n==============================================================================\nhuman-pose-estimation.pytorch licence\n==============================================================================\n    MIT License\n\n    Copyright (c) Microsoft Corporation. All rights reserved.\n\n    Permission is hereby granted, free of charge, to any person obtaining a copy\n    of this software and associated documentation files (the \"Software\"), to deal\n    in the Software without restriction, including without limitation the rights\n    to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n    copies of the Software, and to permit persons to whom the Software is\n    furnished to do so, subject to the following conditions:\n\n    The above copyright notice and this permission notice shall be included in all\n    copies or substantial portions of the Software.\n\n    THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n    AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n    OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n    SOFTWARE\n    \nPortions of this software are derived from CornerNet.\n\n==============================================================================\nCornerNet licence\n==============================================================================\n\nBSD 3-Clause License\n\nCopyright (c) 2018, University of Michigan\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n* Redistributions of source code must retain the above copyright notice, this\n  list of conditions and the following disclaimer.\n\n* Redistributions in binary form must reproduce the above copyright notice,\n  this list of conditions and the following disclaimer in the documentation\n  and/or other materials provided with the distribution.\n\n* Neither the name of the copyright holder nor the names of its\n  contributors may be used to endorse or promote products derived from\n  this software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\nDISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE\nFOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\nDAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\nSERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\nCAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\nOR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n\n\nPortions of this software are derived from DCNv2.\n\n==============================================================================\nDCNv2 licence\n==============================================================================\n\nBSD 3-Clause License\n\nCopyright (c) 2019, Charles Shang\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n1. Redistributions of source code must retain the above copyright notice, this\n   list of conditions and the following disclaimer.\n\n2. Redistributions in binary form must reproduce the above copyright notice,\n   this list of conditions and the following disclaimer in the documentation\n   and/or other materials provided with the distribution.\n\n3. Neither the name of the copyright holder nor the names of its\n   contributors may be used to endorse or promote products derived from\n   this software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\nDISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE\nFOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\nDAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\nSERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\nCAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\nOR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\nOF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n==============================================================================\nDLA licence\n==============================================================================\n\nBSD 3-Clause License\n\nCopyright (c) 2018, Fisher Yu\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n* Redistributions of source code must retain the above copyright notice, this\n  list of conditions and the following disclaimer.\n\n* Redistributions in binary form must reproduce the above copyright notice,\n  this list of conditions and the following disclaimer in the documentation\n  and/or other materials provided with the distribution.\n\n* Neither the name of the copyright holder nor the names of its\n  contributors may be used to endorse or promote products derived from\n  this software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\nDISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE\nFOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\nDAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\nSERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\nCAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\nOR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\nOF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
  },
  {
    "path": "README.md",
    "content": "# Objects as Points\nObject detection, 3D detection, and pose estimation using center point detection:\n![](readme/fig2.png)\n> [**Objects as Points**](http://arxiv.org/abs/1904.07850),            \n> Xingyi Zhou, Dequan Wang, Philipp Kr&auml;henb&uuml;hl,        \n> *arXiv technical report ([arXiv 1904.07850](http://arxiv.org/abs/1904.07850))*         \n\n\nContact: [zhouxy2017@gmail.com](mailto:zhouxy2017@gmail.com). Any questions or discussions are welcomed! \n\n## Updates\n\n - (June, 2020) We released a state-of-the-art Lidar-based 3D detection and tracking framework [CenterPoint](https://github.com/tianweiy/CenterPoint).\n - (April, 2020) We released a state-of-the-art (multi-category-/ pose-/ 3d-) tracking extension [CenterTrack](https://github.com/xingyizhou/CenterTrack).\n\n## Abstract \n\nDetection identifies objects as axis-aligned boxes in an image. Most successful object detectors enumerate a nearly exhaustive list of potential object locations and classify each. This is wasteful, inefficient, and requires additional post-processing. In this paper, we take a different approach. We model an object as a single point -- the center point of its bounding box. Our detector uses keypoint estimation to find center points and regresses to all other object properties, such as size, 3D location, orientation, and even pose. Our center point based approach, CenterNet, is end-to-end differentiable, simpler, faster, and more accurate than corresponding bounding box based detectors. CenterNet achieves the best speed-accuracy trade-off on the MS COCO dataset, with 28.1% AP at 142 FPS, 37.4% AP at 52 FPS, and 45.1% AP with multi-scale testing at 1.4 FPS. We use the same approach to estimate 3D bounding box in the KITTI benchmark and human pose on the COCO keypoint dataset. Our method performs competitively with sophisticated multi-stage methods and runs in real-time.\n\n## Highlights\n\n- **Simple:** One-sentence method summary: use keypoint detection technic to detect the bounding box center point and regress to all other object properties like bounding box size, 3d information, and pose.\n\n- **Versatile:** The same framework works for object detection, 3d bounding box estimation, and multi-person pose estimation with minor modification.\n\n- **Fast:** The whole process in a single network feedforward. No NMS post processing is needed. Our DLA-34 model runs at *52* FPS with *37.4* COCO AP.\n\n- **Strong**: Our best single model achieves *45.1*AP on COCO test-dev.\n\n- **Easy to use:** We provide user friendly testing API and webcam demos.\n\n## Main results\n\n### Object Detection on COCO validation\n\n| Backbone     |  AP / FPS | Flip AP / FPS|  Multi-scale AP / FPS |\n|--------------|-----------|--------------|-----------------------|\n|Hourglass-104 | 40.3 / 14 | 42.2 / 7.8   | 45.1 / 1.4            |\n|DLA-34        | 37.4 / 52 | 39.2 / 28    | 41.7 / 4              |\n|ResNet-101    | 34.6 / 45 | 36.2 / 25    | 39.3 / 4              |\n|ResNet-18     | 28.1 / 142| 30.0 / 71    | 33.2 / 12             |\n\n### Keypoint detection on COCO validation\n\n| Backbone     |  AP       |  FPS         |\n|--------------|-----------|--------------|\n|Hourglass-104 | 64.0      |    6.6       |\n|DLA-34        | 58.9      |    23        |\n\n### 3D bounding box detection on KITTI validation\n\n|Backbone|FPS|AP-E|AP-M|AP-H|AOS-E|AOS-M|AOS-H|BEV-E|BEV-M|BEV-H| \n|--------|---|----|----|----|-----|-----|-----|-----|-----|-----|\n|DLA-34  |32 |96.9|87.8|79.2|93.9 |84.3 |75.7 |34.0 |30.5 |26.8 |\n\n\nAll models and details are available in our [Model zoo](readme/MODEL_ZOO.md).\n\n## Installation\n\nPlease refer to [INSTALL.md](readme/INSTALL.md) for installation instructions.\n\n## Use CenterNet\n\nWe support demo for image/ image folder, video, and webcam. \n\nFirst, download the models (By default, [ctdet_coco_dla_2x](https://drive.google.com/file/d/18Q3fzzAsha_3Qid6mn4jcIFPeOGUaj1d) for detection and \n[multi_pose_dla_3x](https://drive.google.com/file/d/1mC2PAQT_RuHi_9ZMZgkt4rg7BSY2_Lkd) for human pose estimation) \nfrom the [Model zoo](readme/MODEL_ZOO.md) and put them in `CenterNet_ROOT/models/`.\n\nFor object detection on images/ video, run:\n\n~~~\npython demo.py ctdet --demo /path/to/image/or/folder/or/video --load_model ../models/ctdet_coco_dla_2x.pth\n~~~\nWe provide example images in `CenterNet_ROOT/images/` (from [Detectron](https://github.com/facebookresearch/Detectron/tree/master/demo)). If set up correctly, the output should look like\n\n<p align=\"center\"> <img src='readme/det1.png' align=\"center\" height=\"230px\"> <img src='readme/det2.png' align=\"center\" height=\"230px\"> </p>\n\nFor webcam demo, run     \n\n~~~\npython demo.py ctdet --demo webcam --load_model ../models/ctdet_coco_dla_2x.pth\n~~~\n\nSimilarly, for human pose estimation, run:\n\n~~~\npython demo.py multi_pose --demo /path/to/image/or/folder/or/video/or/webcam --load_model ../models/multi_pose_dla_3x.pth\n~~~\nThe result for the example images should look like:\n\n<p align=\"center\">  <img src='readme/pose1.png' align=\"center\" height=\"200px\"> <img src='readme/pose2.png' align=\"center\" height=\"200px\"> <img src='readme/pose3.png' align=\"center\" height=\"200px\">  </p>\n\nYou can add `--debug 2` to visualize the heatmap outputs.\nYou can add `--flip_test` for flip test.\n\nTo use this CenterNet in your own project, you can \n\n~~~\nimport sys\nCENTERNET_PATH = /path/to/CenterNet/src/lib/\nsys.path.insert(0, CENTERNET_PATH)\n\nfrom detectors.detector_factory import detector_factory\nfrom opts import opts\n\nMODEL_PATH = /path/to/model\nTASK = 'ctdet' # or 'multi_pose' for human pose estimation\nopt = opts().init('{} --load_model {}'.format(TASK, MODEL_PATH).split(' '))\ndetector = detector_factory[opt.task](opt)\n\nimg = image/or/path/to/your/image/\nret = detector.run(img)['results']\n~~~\n`ret` will be a python dict: `{category_id : [[x1, y1, x2, y2, score], ...], }`\n\n## Benchmark Evaluation and Training\n\nAfter [installation](readme/INSTALL.md), follow the instructions in [DATA.md](readme/DATA.md) to setup the datasets. Then check [GETTING_STARTED.md](readme/GETTING_STARTED.md) to reproduce the results in the paper.\nWe provide scripts for all the experiments in the [experiments](experiments) folder.\n\n## Develop\n\nIf you are interested in training CenterNet in a new dataset, use CenterNet in a new task, or use a new network architecture for CenterNet, please refer to [DEVELOP.md](readme/DEVELOP.md). Also feel free to send us emails for discussions or suggestions.\n\n## Third-party resources\n\n- CenterNet + embedding learning based tracking: [FairMOT](https://github.com/ifzhang/FairMOT) from [Yifu Zhang](https://github.com/ifzhang).\n- Detectron2 based implementation: [CenterNet-better](https://github.com/FateScript/CenterNet-better) from [Feng Wang](https://github.com/FateScript).\n- Keras Implementation: [keras-centernet](https://github.com/see--/keras-centernet) from [see--](https://github.com/see--) and [keras-CenterNet](https://github.com/xuannianz/keras-CenterNet) from [xuannianz](https://github.com/xuannianz).\n- MXnet implementation: [mxnet-centernet](https://github.com/Guanghan/mxnet-centernet) from [Guanghan Ning](https://github.com/Guanghan).\n- Stronger human open estimation models: [centerpose](https://github.com/tensorboy/centerpose) from [tensorboy](https://github.com/tensorboy).\n- TensorRT extension with ONNX models: [TensorRT-CenterNet](https://github.com/CaoWGG/TensorRT-CenterNet) from [Wengang Cao](https://github.com/CaoWGG).\n- CenterNet + DeepSORT tracking implementation: [centerNet-deep-sort](https://github.com/kimyoon-young/centerNet-deep-sort) from [kimyoon-young](https://github.com/kimyoon-young).\n- Blogs on training CenterNet on custom datasets (in Chinese): [ships](https://blog.csdn.net/weixin_42634342/article/details/97756458) from [Rhett Chen](https://blog.csdn.net/weixin_42634342) and [faces](https://blog.csdn.net/weixin_41765699/article/details/100118353) from [linbior](https://me.csdn.net/weixin_41765699).\n\n\n## License\n\nCenterNet itself is released under the MIT License (refer to the LICENSE file for details).\nPortions of the code are borrowed from [human-pose-estimation.pytorch](https://github.com/Microsoft/human-pose-estimation.pytorch) (image transform, resnet), [CornerNet](https://github.com/princeton-vl/CornerNet) (hourglassnet, loss functions), [dla](https://github.com/ucbdrive/dla) (DLA network), [DCNv2](https://github.com/CharlesShang/DCNv2)(deformable convolutions), [tf-faster-rcnn](https://github.com/endernewton/tf-faster-rcnn)(Pascal VOC evaluation) and [kitti_eval](https://github.com/prclibo/kitti_eval) (KITTI dataset evaluation). Please refer to the original License of these projects (See [NOTICE](NOTICE)).\n\n## Citation\n\nIf you find this project useful for your research, please use the following BibTeX entry.\n\n    @inproceedings{zhou2019objects,\n      title={Objects as Points},\n      author={Zhou, Xingyi and Wang, Dequan and Kr{\\\"a}henb{\\\"u}hl, Philipp},\n      booktitle={arXiv preprint arXiv:1904.07850},\n      year={2019}\n    }\n"
  },
  {
    "path": "data/.gitignore",
    "content": "*\n!.gitignore\n"
  },
  {
    "path": "exp/.gitignore",
    "content": "*\n!.gitignore\n"
  },
  {
    "path": "experiments/ctdet_coco_dla_1x.sh",
    "content": "cd src\n# train\npython main.py ctdet --exp_id coco_dla_1x --batch_size 128 --master_batch 9 --lr 5e-4 --gpus 0,1,2,3,4,5,6,7 --num_workers 16\n# test\npython test.py ctdet --exp_id coco_dla_1x --keep_res --resume\n# flip test\npython test.py ctdet --exp_id coco_dla_1x --keep_res --resume --flip_test \n# multi scale test\npython test.py ctdet --exp_id coco_dla_1x --keep_res --resume --flip_test --test_scales 0.5,0.75,1,1.25,1.5\ncd ..\n"
  },
  {
    "path": "experiments/ctdet_coco_dla_2x.sh",
    "content": "cd src\n# train\npython main.py ctdet --exp_id coco_dla_2x --batch_size 128 --master_batch 9 --lr 5e-4 --gpus 0,1,2,3,4,5,6,7 --num_workers 16 --num_epochs 230 lr_step 180,210\n# or use the following command if your have coco_s2_dla_1x trained\n# python main.py ctdet --exp_id coco_dla_2x --batch_size 128 --master_batch 9 --lr 5e-4 --gpus 0,1,2,3,4,5,6,7 --num_workers 16 --load_model ../exp/ctdet/coco_dla_1x/model_90.pth --resume\n# test\npython test.py ctdet --exp_id coco_dla_2x --keep_res --resume\n# flip test\npython test.py ctdet --exp_id coco_dla_2x --keep_res --resume --flip_test\n# multi scale test\npython test.py ctdet --exp_id coco_dla_2x --keep_res --resume --flip_test --test_scales 0.5,0.75,1,1.25,1.5\ncd ..\n"
  },
  {
    "path": "experiments/ctdet_coco_hg.sh",
    "content": "cd src\n# train\npython main.py ctdet --exp_id coco_hg --arch hourglass --batch_size 24 --master_batch 4 --lr 2.5e-4 --load_model ../models/ExtremeNet_500000.pth --gpus 0,1,2,3,4\n# test\npython test.py ctdet --exp_id coco_hg --arch hourglass --keep_res --resume\n# flip test\npython test.py ctdet --exp_id coco_hg --arch hourglass --keep_res --resume --flip_test \n# multi scale test\npython test.py ctdet --exp_id coco_hg --arch hourglass --keep_res --resume --flip_test --test_scales 0.5,0.75,1,1.25,1.5\ncd .."
  },
  {
    "path": "experiments/ctdet_coco_resdcn101.sh",
    "content": "cd src\n# train\npython main.py ctdet --exp_id coco_resdcn101 --arch resdcn_101 --batch_size 96 --master_batch 5 --lr 3.75e-4 --gpus 0,1,2,3,4,5,6,7 --num_workers 16\n# test\npython test.py ctdet --exp_id coco_resdcn101 --keep_res --resume\n# flip test\npython test.py ctdet --exp_id coco_resdcn101 --keep_res --resume --flip_test \n# multi scale test\npython test.py ctdet --exp_id coco_resdcn101 --keep_res --resume --flip_test --test_scales 0.5,0.75,1,1.25,1.5\ncd ..\n"
  },
  {
    "path": "experiments/ctdet_coco_resdcn18.sh",
    "content": "cd src\n# train\npython main.py ctdet --exp_id coco_resdcn18 --arch resdcn_18 --batch_size 114 --master_batch 18 --lr 5e-4 --gpus 0,1,2,3 --num_workers 16\n# test\npython test.py ctdet --exp_id coco_resdcn18 --arch resdcn_18 --keep_res --resume\n# flip test\npython test.py ctdet --exp_id coco_resdcn18 --arch resdcn_18 --keep_res --resume --flip_test \n# multi scale test\npython test.py ctdet --exp_id coco_resdcn18 --arch resdcn_18 --keep_res --resume --flip_test --test_scales 0.5,0.75,1,1.25,1.5\ncd ..\n"
  },
  {
    "path": "experiments/ctdet_pascal_dla_384.sh",
    "content": "cd src\n# train\npython main.py ctdet --exp_id pascal_dla_384 --dataset pascal --num_epochs 70 --lr_step 45,60\n# test\npython test.py ctdet --exp_id pascal_dla_384 --dataset pascal --resume\n# flip test\npython test.py ctdet --exp_id pascal_dla_384 --dataset pascal --resume --flip_test\ncd ..\n"
  },
  {
    "path": "experiments/ctdet_pascal_dla_512.sh",
    "content": "cd src\n# train\npython main.py ctdet --exp_id pascal_dla_512 --dataset pascal --input_res 512 --num_epochs 70 --lr_step 45,60 --gpus 0,1\n# test\npython test.py ctdet --exp_id pascal_dla_512 --dataset pascal --input_res 512 --resume\n# flip test\npython test.py ctdet --exp_id pascal_dla_512 --dataset pascal --input_res 512 --resume --flip_test\ncd ..\n"
  },
  {
    "path": "experiments/ctdet_pascal_resdcn101_384.sh",
    "content": "cd src\n# train\npython main.py ctdet --exp_id pascal_resdcn101_384 --arch resdcn_101 --dataset pascal --num_epochs 70 --lr_step 45,60 --gpus 0,1\n# test\npython test.py ctdet --exp_id pascal_resdcn101_384 --arch resdcn_101 --dataset pascal --resume\n# flip test\npython test.py ctdet --exp_id pascal_resdcn101_384 --arch resdcn_101 --dataset pascal --resume --flip_test\ncd ..\n"
  },
  {
    "path": "experiments/ctdet_pascal_resdcn101_512.sh",
    "content": "cd src\n# train\npython main.py ctdet --exp_id pascal_resdcn101_512 --arch resdcn_101 --dataset pascal --input_res 512 --num_epochs 70 --lr_step 45,60 --gpus 0,1,2,3\n# test\npython test.py ctdet --exp_id pascal_resdcn101_512 --arch resdcn_101 --dataset pascal --input_res 512 --resume\n# flip test\npython test.py ctdet --exp_id pascal_resdcn101_512 --arch resdcn_101 --dataset pascal --input_res 512 --resume --flip_test\ncd ..\n"
  },
  {
    "path": "experiments/ctdet_pascal_resdcn18_384.sh",
    "content": "cd src\n# train\npython main.py ctdet --exp_id pascal_resdcn18_384 --arch resdcn_18 --dataset pascal --num_epochs 70 --lr_step 45,60\n# test\npython test.py ctdet --exp_id pascal_resdcn18_384 --arch resdcn_18 --dataset pascal --resume\n# flip test\npython test.py ctdet --exp_id pascal_resdcn18_384 --arch resdcn_18 --dataset pascal --resume --flip_test\ncd ..\n"
  },
  {
    "path": "experiments/ctdet_pascal_resdcn18_512.sh",
    "content": "cd src\n# train\npython main.py ctdet --exp_id pascal_resdcn18_512 --arch resdcn_18 --dataset pascal --input_res 512 --num_epochs 70 --lr_step 45,60\n# test\npython test.py ctdet --exp_id pascal_resdcn18_512 --arch resdcn_18 --dataset pascal --input_res 512 --resume\n# flip test\npython test.py ctdet --exp_id pascal_resdcn18_512 --arch resdcn_18 --dataset pascal --input_res 512 --resume --flip_test\ncd ..\n"
  },
  {
    "path": "experiments/ddd_3dop.sh",
    "content": "cd src\n# train\npython main.py ddd --exp_id 3dop --dataset kitti --kitti_split 3dop --batch_size 16 --master_batch 7 --num_epochs 70 --lr_step 45,60 --gpus 0,1\n# test\npython test.py ddd --exp_id 3dop --dataset kitti --kitti_split 3dop --resume\ncd ..\n"
  },
  {
    "path": "experiments/ddd_sub.sh",
    "content": "cd src\n# train\npython main.py ddd --exp_id sub --dataset kitti --kitti_split subcnn --batch_size 16 --master_batch 7 --num_epochs 70 --lr_step 45,60 --gpus 0,1\n# test\npython test.py ddd --exp_id sub --dataset kitti --kitti_split subcnn --resume\ncd ..\n"
  },
  {
    "path": "experiments/exdet_coco_dla.sh",
    "content": "cd src\n# train\npython main.py exdet --exp_id coco_dla --batch_size 64 --master_batch 1 --lr 2.5e-4 --gpus 0,1,2,3,4,5,6,7 --num_workers 8\n# test\npython test.py exdet --exp_id coco_dla --keep_res --resume\n# flip test\npython test.py exdet --exp_id coco_dla --keep_res --resume --flip_test \n# multi scale test\npython test.py exdet --exp_id coco_dla --keep_res --resume --flip_test --test_scales 0.5,0.75,1,1.25,1.5\ncd ..\n"
  },
  {
    "path": "experiments/exdet_coco_hg.sh",
    "content": "cd src\n# train\npython main.py exdet --exp_id coco_hg --arch hourglass --batch_size 24 --master_batch 4 --lr 2.5e-4 --gpus 0,1,2,3,4\n# test\npython test.py exdet --exp_id coco_hg --arch hourglass --keep_res --resume\n# flip test\npython test.py exdet --exp_id coco_hg --arch hourglass --keep_res --resume --flip_test \n# multi scale test\npython test.py exdet --exp_id coco_hg --arch hourglass --keep_res --resume --flip_test --test_scales 0.5,0.75,1,1.25,1.5\ncd ..\n"
  },
  {
    "path": "experiments/multi_pose_dla_1x.sh",
    "content": "cd src\n# train\npython main.py multi_pose --exp_id dla_1x --dataset coco_hp --batch_size 128 --master_batch 9 --lr 5e-4 --load_model ../models/ctdet_coco_dla_2x.pth --gpus 0,1,2,3,4,5,6,7 --num_workers 16\n# test\npython test.py multi_pose --exp_id dla_1x --dataset coco_hp --keep_res --resume\n# flip test\npython test.py multi_pose --exp_id dla_1x --dataset coco_hp --keep_res --resume --flip_test\ncd ..\n"
  },
  {
    "path": "experiments/multi_pose_dla_3x.sh",
    "content": "cd src\n# train\npython main.py multi_pose --exp_id dla_3x --dataset coco_hp --batch_size 128 --master_batch 9 --lr 5e-4 --load_model ../models/ctdet_coco_dla_2x.pth --gpus 0,1,2,3,4,5,6,7 --num_workers 16 --num_epochs 320 lr_step 270,300\n# or use the following command if your have dla_1x trained\n# python main.py multi_pose --exp_id dla_3x --dataset coco_hp --batch_size 128 --master_batch 9 --lr 5e-4 --gpus 0,1,2,3,4,5,6,7 --num_workers 16 --load_model ../exp/multi_pose/dla_1x/model_90.pth --resume\n# test\npython test.py multi_pose --exp_id dla_3x --dataset coco_hp --keep_res --resume\n# flip test\npython test.py multi_pose --exp_id dla_3x --dataset coco_hp --keep_res --resume --flip_test\ncd ..\n"
  },
  {
    "path": "experiments/multi_pose_hg_1x.sh",
    "content": "cd src\n# train\npython main.py multi_pose --exp_id hg_1x --dataset coco_hp --arch hourglass --batch_size 24 --master_batch 4 --lr 2.5e-4 --load_model ../models/ctdet_coco_hg.pth --gpus 0,1,2,3,4 --num_epochs 50 --lr_step 40\n# test\npython test.py multi_pose --exp_id hg_1x --dataset coco_hp --arch hourglass --keep_res --resume\n# flip test\npython test.py multi_pose --exp_id hg_1x --dataset coco_hp --arch hourglass --keep_res --resume --flip_test\ncd ..\n"
  },
  {
    "path": "experiments/multi_pose_hg_3x.sh",
    "content": "cd src\n# train\npython main.py multi_pose --exp_id hg_3x --dataset coco_hp --arch hourglass --batch_size 24 --master_batch 4 --lr 2.5e-4 -load_model ../models/ctdet_coco_hg.pth --gpus 0,1,2,3,4 --num_epochs 150 --lr_step 130\n# or use the following command if your have dla_1x trained\n# python main.py multi_pose --exp_id hg_3x --dataset coco_hp  --arch hourglass --batch_size 24 --master_batch 4 --lr 2.5e-4 --gpus 0,1,2,3,4 --num_epochs 150 --lr_step 130 --load_model ../exp/multi_pose/hg_1x/model_40.pth --resume\n# test\npython test.py multi_pose --exp_id hg_3x --dataset coco_hp --arch hourglass --keep_res --resume\n# flip test\npython test.py multi_pose --exp_id hg_3x --dataset coco_hp --arch hourglass --keep_res --resume --flip_test\ncd ..\n"
  },
  {
    "path": "images/NOTICE",
    "content": "The demo images are licensed as United States government work:\nhttps://www.usa.gov/government-works\n\nThe image files were obtained on Jan 13, 2018 from the following\nURLs.\n\n16004479832_a748d55f21_k.jpg\nhttps://www.flickr.com/photos/archivesnews/16004479832\n\n18124840932_e42b3e377c_k.jpg\nhttps://www.flickr.com/photos/usnavy/18124840932\n\n33887522274_eebd074106_k.jpg\nhttps://www.flickr.com/photos/usaid_pakistan/33887522274\n\n15673749081_767a7fa63a_k.jpg\nhttps://www.flickr.com/photos/usnavy/15673749081\n\n34501842524_3c858b3080_k.jpg\nhttps://www.flickr.com/photos/departmentofenergy/34501842524\n\n24274813513_0cfd2ce6d0_k.jpg\nhttps://www.flickr.com/photos/dhsgov/24274813513\n\n19064748793_bb942deea1_k.jpg\nhttps://www.flickr.com/photos/statephotos/19064748793\n\n33823288584_1d21cf0a26_k.jpg\nhttps://www.flickr.com/photos/cbpphotos/33823288584\n\n17790319373_bd19b24cfc_k.jpg\nhttps://www.flickr.com/photos/secdef/17790319373\n"
  },
  {
    "path": "models/.gitignore",
    "content": "*\n!.gitignore\n"
  },
  {
    "path": "readme/DATA.md",
    "content": "# Dataset preparation\n\nIf you want to reproduce the results in the paper for benchmark evaluation and training, you will need to setup dataset.\n\n\n### COCO\n- Download the images (2017 Train, 2017 Val, 2017 Test) from [coco website](http://cocodataset.org/#download).\n- Download annotation files (2017 train/val and test image info) from [coco website](http://cocodataset.org/#download). \n- Place the data (or create symlinks) to make the data folder like:\n\n  ~~~\n  ${CenterNet_ROOT}\n  |-- data\n  `-- |-- coco\n      `-- |-- annotations\n          |   |-- instances_train2017.json\n          |   |-- instances_val2017.json\n          |   |-- person_keypoints_train2017.json\n          |   |-- person_keypoints_val2017.json\n          |   |-- image_info_test-dev2017.json\n          |---|-- train2017\n          |---|-- val2017\n          `---|-- test2017\n  ~~~\n\n- [Optional] If you want to train ExtremeNet, generate extreme point annotation from segmentation:\n    \n    ~~~\n    cd $CenterNet_ROOT/tools/\n    python gen_coco_extreme_points.py\n    ~~~\n  It generates `instances_extreme_train2017.json` and `instances_extreme_val2017.json` in `data/coco/annotations/`. \n\n### Pascal VOC\n\n- Run\n\n    ~~~\n    cd $CenterNet_ROOT/tools/\n    bash get_pascal_voc.sh\n    ~~~\n- The above script includes:\n    - Download, unzip, and move Pascal VOC images from the [VOC website](http://host.robots.ox.ac.uk/pascal/VOC/). \n    - [Download](https://storage.googleapis.com/coco-dataset/external/PASCAL_VOC.zip) Pascal VOC annotation in COCO format (from [Detectron](https://github.com/facebookresearch/Detectron/tree/master/detectron/datasets/data)). \n    - Combine train/val 2007/2012 annotation files into a single json. \n\n\n- Move the created `voc` folder to `data` (or create symlinks) to make the data folder like:\n\n  ~~~\n  ${CenterNet_ROOT}\n  |-- data\n  `-- |-- voc\n      `-- |-- annotations\n          |   |-- pascal_trainval0712.json\n          |   |-- pascal_test2017.json\n          |-- images\n          |   |-- 000001.jpg\n          |   ......\n          `-- VOCdevkit\n  \n  ~~~\n  The `VOCdevkit` folder is needed to run the evaluation script from [faster rcnn](https://github.com/rbgirshick/py-faster-rcnn/blob/master/tools/reval.py).\n\n### KITTI\n\n- Download [images](http://www.cvlibs.net/download.php?file=data_object_image_2.zip), [annotations](http://www.cvlibs.net/download.php?file=data_object_label_2.zip), and [calibrations](http://www.cvlibs.net/download.php?file=data_object_calib.zip) from [KITTI website](http://www.cvlibs.net/datasets/kitti/eval_object.php?obj_benchmark=3d) and unzip.\n\n- Download the train-val split of [3DOP](https://xiaozhichen.github.io/files/mv3d/imagesets.tar.gz) and [SubCNN](https://github.com/tanshen/SubCNN/tree/master/fast-rcnn/data/KITTI) and place the data as below\n\n  ~~~\n  ${CenterNet_ROOT}\n  |-- data\n  `-- |-- kitti\n      `-- |-- training\n          |   |-- image_2\n          |   |-- label_2\n          |   |-- calib\n          |-- ImageSets_3dop\n          |   |-- test.txt\n          |   |-- train.txt\n          |   |-- val.txt\n          |   |-- trainval.txt\n          `-- ImageSets_subcnn\n              |-- test.txt\n              |-- train.txt\n              |-- val.txt\n              |-- trainval.txt\n  ~~~\n\n- Run `python convert_kitti_to_coco.py` in `tools` to convert the annotation into COCO format. You can set `DEBUG=True` in `line 5` to visualize the annotation.\n\n- Link image folder\n\n  ~~~\n  cd ${CenterNet_ROOT}/data/kitti/\n  mkdir images\n  ln -s training/image_2 images/trainval\n  ~~~\n\n- The data structure should look like:\n\n  ~~~\n  ${CenterNet_ROOT}\n  |-- data\n  `-- |-- kitti\n      `-- |-- annotations\n          |   |-- kitti_3dop_train.json\n          |   |-- kitti_3dop_val.json\n          |   |-- kitti_subcnn_train.json\n          |   |-- kitti_subcnn_val.json\n          `-- images\n              |-- trainval\n              |-- test\n  ~~~\n"
  },
  {
    "path": "readme/DEVELOP.md",
    "content": "# Develop\n\nThis document provides tutorials to develop CenterNet. `lib/src/opts` lists a few more options that the current version supports.\n\n## New dataset\nBasically there are three steps:\n\n- Convert the dataset annotation to [COCO format](http://cocodataset.org/#format-data). Please refer to [src/tools/convert_kitti_to_coco.py](../src/tools/convert_kitti_to_coco.py) for an example to convert kitti format to coco format.\n- Create a dataset intilization file in `src/lib/datasets/dataset`. In most cases you can just copy `src/lib/datasets/dataset/coco.py` to your dataset name and change the category information, and annotation path.\n- Import your dataset at `src/lib/datasets/dataset_factory`.\n\n## New task\n\nYou will need to add files to `src/lib/datasets/sample/`, `src/lib/datasets/trains/`, and `src/lib/datasets/detectors/`, which specify the data generation during training, the training targets, and the testing, respectively.\n\n## New architecture\n\n- Add your model file to `src/lib/models/networks/`. The model should accept a dict `heads` of `{name: channels}`, which specify the name of each network output and its number of channels. Make sure your model returns a list (for multiple stages. Single stage model should return a list containing a single element.). The element of the list is a dict contraining the same keys with `heads`.\n- Add your model in `model_factory` of `src/lib/models/model.py`.\n"
  },
  {
    "path": "readme/GETTING_STARTED.md",
    "content": "# Getting Started\n\nThis document provides tutorials to train and evaluate CenterNet. Before getting started, make sure you have finished [installation](INSTALL.md) and [dataset setup](DATA.md).\n\n## Benchmark evaluation\n\nFirst, download the models you want to evaluate from our [model zoo](MODEL_ZOO.md) and put them in `CenterNet_ROOT/models/`. \n\n### COCO\n\nTo evaluate COCO object detection with DLA\nrun\n\n~~~\npython test.py ctdet --exp_id coco_dla --keep_res --load_model ../models/ctdet_coco_dla_2x.pth\n~~~\n\nThis will give an AP of `37.4` if setup correctly. `--keep_res` is for keep the original image resolution. Without `--keep_res` it will resize the images to `512 x 512`. You can add `--flip_test` and `--flip_test --test_scales 0.5,0.75,1,1.25,1.5` to the above commend, for flip test and multi_scale test, respectively. The expected APs are `39.2` and `41.7`, respectively.\n\nTo test with hourglass net, run\n\n~~~\npython test.py ctdet --exp_id coco_hg --arch hourglass --fix_res --load_model ../models/ctdet_coco_hg.pth\n~~~\n\nSimilarly, to evaluate human pose estimation, run the following command for dla\n\n~~~\npython test.py multi_pose --exp_id dla --keep_res --load_model ../models/multi_pose_dla_3x.pth --flip_test\n~~~\n\nand the following for hourglass\n\n~~~\npython test.py multi_pose --exp_id hg --arch hourglass --keep_res --load_model ../models/multi_pose_dla_3x.pth --flip_test\n~~~\n\nThe expected results can be found in the model zoo.\n\n### Pascal\n\nTo evaluate object detection on Pascal VOC (test2007), run\n\n~~~\npython test.py ctdet --exp_id dla --dataset pascal --load_model ../models/ctdet_pascal_dla.pth --flip_test\n~~~\n\nNote that we fix the resolution during testing.\nAnd you can change to other network architectures and resolutions by specifying `--arch` and `--input_res 512`.\n\n### KITTI\n\nTo evaluate the kitti dataset, first compile the evaluation tool (from [here](https://github.com/prclibo/kitti_eval)):\n\n~~~\ncd CenterNet_ROOT/src/tools/kitti_eval\ng++ -o evaluate_object_3d_offline evaluate_object_3d_offline.cpp -O3\n~~~\n\nThen run the evaluation with pretrained model:\n\n~~~\npython test.py ddd --exp_id 3dop --dataset kitti --kitti_split 3dop --load_model ../models/ddd_3dop.pth\n~~~\n\nto evaluate the 3DOP split. For the subcnn split, change `--kitti_split` to `subcnn` and load the corresponding models.\nNote that test time augmentation is not trivially applicable for 3D orientation.\n\n## Training\n\nWe have packed all the training scripts in the [experiments](../experiments) folder.\nThe experiment names are correspond to the model name in the [model zoo](MODEL_ZOO.md).\nThe number of GPUs for each experiments can be found in the scripts and the model zoo.\nIn the case that you don't have 8 GPUs, you can follow the [linear learning rate rule](https://arxiv.org/abs/1706.02677) to scale the learning rate as batch size.\nFor example, to train COCO object detection with dla on 2 GPUs, run\n\n~~~\npython main.py ctdet --exp_id coco_dla --batch_size 32 --master_batch 15 --lr 1.25e-4  --gpus 0,1\n~~~\n\nThe default learning rate is `1.25e-4` for batch size `32` (on 2 GPUs).\nBy default, pytorch evenly splits the total batch size to each GPUs.\n`--master_batch` allows using different batchsize for the master GPU, which usually costs more memory than other GPUs.\nIf it encounters GPU memory out, using slightly less batch size (e.g., `112` of `128`) with the same learning is fine.\n\nIf the training is terminated before finishing, you can use the same commond with `--resume` to resume training. It will found the lastest model with the same `exp_id`.\n\nOur HourglassNet model is finetuned from the pretrained [ExtremeNet model](https://drive.google.com/file/d/1JMbHgN4uLkP9MAyJU5EeHrgxwe101hwO) (from the [ExtremeNet repo](https://github.com/xingyizhou/ExtremeNet)).\nYou will need to download the model, run `python convert_hourglass_weight.py` to convert the model format, and load the model for training (see the [script](../experiments/ctdet_coco_hg.sh)).\n"
  },
  {
    "path": "readme/INSTALL.md",
    "content": "# Installation\n\n\nThe code was tested on Ubuntu 16.04, with [Anaconda](https://www.anaconda.com/download) Python 3.6 and [PyTorch]((http://pytorch.org/)) v0.4.1. NVIDIA GPUs are needed for both training and testing.\nAfter install Anaconda:\n\n0. [Optional but recommended] create a new conda environment. \n\n    ~~~\n    conda create --name CenterNet python=3.6\n    ~~~\n    And activate the environment.\n    \n    ~~~\n    conda activate CenterNet\n    ~~~\n\n1. Install pytorch0.4.1:\n\n    ~~~\n    conda install pytorch=0.4.1 torchvision -c pytorch\n    ~~~\n    \n    And disable cudnn batch normalization(Due to [this issue](https://github.com/xingyizhou/pytorch-pose-hg-3d/issues/16)).\n    \n     ~~~\n    # PYTORCH=/path/to/pytorch # usually ~/anaconda3/envs/CenterNet/lib/python3.6/site-packages/\n    # for pytorch v0.4.0\n    sed -i \"1194s/torch\\.backends\\.cudnn\\.enabled/False/g\" ${PYTORCH}/torch/nn/functional.py\n    # for pytorch v0.4.1\n    sed -i \"1254s/torch\\.backends\\.cudnn\\.enabled/False/g\" ${PYTORCH}/torch/nn/functional.py\n     ~~~\n     \n     For other pytorch version, you can manually open `torch/nn/functional.py` and find the line with `torch.batch_norm` and replace the `torch.backends.cudnn.enabled` with `False`. We observed slight worse training results without doing so. \n     \n2. Install [COCOAPI](https://github.com/cocodataset/cocoapi):\n\n    ~~~\n    # COCOAPI=/path/to/clone/cocoapi\n    git clone https://github.com/cocodataset/cocoapi.git $COCOAPI\n    cd $COCOAPI/PythonAPI\n    make\n    python setup.py install --user\n    ~~~\n\n3. Clone this repo:\n\n    ~~~\n    CenterNet_ROOT=/path/to/clone/CenterNet\n    git clone https://github.com/xingyizhou/CenterNet $CenterNet_ROOT\n    ~~~\n\n\n4. Install the requirements\n\n    ~~~\n    pip install -r requirements.txt\n    ~~~\n    \n    \n5. Compile deformable convolutional (from [DCNv2](https://github.com/CharlesShang/DCNv2/tree/pytorch_0.4)).\n\n    ~~~\n    cd $CenterNet_ROOT/src/lib/models/networks/DCNv2\n    ./make.sh\n    ~~~\n6. [Optional, only required if you are using extremenet or multi-scale testing] Compile NMS if your want to use multi-scale testing or test ExtremeNet.\n\n    ~~~\n    cd $CenterNet_ROOT/src/lib/external\n    make\n    ~~~\n\n7. Download pertained models for [detection]() or [pose estimation]() and move them to `$CenterNet_ROOT/models/`. More models can be found in [Model zoo](MODEL_ZOO.md).\n"
  },
  {
    "path": "readme/MODEL_ZOO.md",
    "content": "# MODEL ZOO\n\n### Common settings and notes\n\n- The experiments are run with pytorch 0.4.1, CUDA 9.0, and CUDNN 7.1.\n- Training times are measured on our servers with 8 TITAN V GPUs (12 GB Memeory).\n- Testing times are measured on our local machine with TITAN Xp GPU. \n- The models can be downloaded directly from [Google drive](https://drive.google.com/drive/folders/1S3NnppRgXea_IG4WeyquJcnOB3I6G-LX).\n\n## Object Detection\n\n\n### COCO\n\n| Model                    | GPUs |Train time(h)| Test time (ms) |   AP               |  Download | \n|--------------------------|------|-------------|----------------|--------------------|-----------|\n|[ctdet\\_coco\\_hg](../experiments/ctdet_coco_hg.sh)       |   5  |109          | 71 / 129 / 674 | 40.3 / 42.2 / 45.1 | [model](https://drive.google.com/file/d/13F904yXltGIqa_K3g3-FLleaNX0n7c9O) |\n|[ctdet\\_coco\\_dla\\_1x](../experiments/ctdet_coco_dla_1x.sh)  |   8  | 57          |  19 / 36 / 248 | 36.3 / 38.2 / 40.7 | [model](https://drive.google.com/file/d/1xqFsdA3DANMq1MfnXG8n7nQPe4AfXTHv) |\n|[ctdet\\_coco\\_dla\\_2x](../experiments/ctdet_coco_dla_2x.sh)  |   8  | 92          |  19 / 36 / 248 | 37.4 / 39.2 / 41.7 | [model](https://drive.google.com/file/d/18Q3fzzAsha_3Qid6mn4jcIFPeOGUaj1d) |\n|[ctdet\\_coco\\_resdcn101](../experiments/ctdet_coco_resdcn101.sh)|   8  | 65          |  22 / 40 / 259 | 34.6 / 36.2 / 39.3 | [model](https://drive.google.com/file/d/1tKkSyzC3iWmM6XTYNJrC4XLCIToDmnHz) |\n|[ctdet\\_coco\\_resdcn18](../experiments/ctdet_coco_resdcn18.sh) |   4  | 28          |  7 / 14 / 81   | 28.1 / 30.0 / 33.2 | [model](https://drive.google.com/file/d/1RtFps3kQAyLjQyzCao7pPDclOBQ64Vyp) |\n|[exdet\\_coco\\_hg](../experiments/exdet_coco_hg.sh)       |   5  |215          | 134 / 246/1340 | 35.8 / 39.8 / 42.4 | [model](https://drive.google.com/file/d/1gf9bVWs9htzOaQiAF_mqaa2SCFTvwNvh) |\n|[exdet\\_coco\\_dla](../experiments/exdet_coco_dla.sh)      |   8  |133          | 51 / 90 / 481  | 33.0 / 36.5 / 38.5 | [model](https://drive.google.com/file/d/1RtFps3kQAyLjQyzCao7pPDclOBQ64Vyp) |\n\n#### Notes\n\n- All models are trained on COCO train 2017 and evaluated on val 2017. \n- We show test time and AP with no augmentation / flip augmentation / multi scale (0.5, 0.75, 1, 1.25, 1.5) augmentation. \n- Results on COCO test-dev can be found in the paper or add `--trainval` for `test.py`. \n- exdet is our re-implementation of [ExtremeNet](https://github.com/xingyizhou/ExtremeNet). The testing does not include edge aggregation.\n- For dla and resnets, `1x` means the training schedule that train 140 epochs with learning rate dropped 10 times at the 90 and 120 epoch (following [SimpleBaseline](https://github.com/Microsoft/human-pose-estimation.pytorch)). `2x` means train 230 epochs with learning rate dropped 10 times at the 180 and 210 epoch. The training schedules are **not** carefully investigated.\n- The hourglass trained schedule follows [ExtremeNet](https://github.com/xingyizhou/ExtremeNet): trains 50 epochs (approximately 250000 iterations in batch size 24) and drops learning rate at the 40 epoch.\n- Testing time include network forwarding time, decoding time, and nms time (for ExtremeNet).\n- We observed up to 0.4 AP performance jitter due to randomness in training. \n\n### Pascal VOC\n\n| Model                           |GPUs| Train time (h)| Test time (ms) | mAP  | Download  |\n|---------------------------------|----|---------------|----------------|------|-----------|\n|[ctdet\\_pascal\\_dla\\_384](../experiments/ctdet_pascal_dla_384.sh)      | 1  |15             | 20             | 79.3 | [model](https://drive.google.com/file/d/19J7WoUZKYiSEU7vrhZInz5C2m0-9zmC1) |\n|[ctdet\\_pascal\\_dla\\_512](../experiments/ctdet_pascal_dla_512.sh)      | 2  |15             | 30             | 80.7 | [model](https://drive.google.com/file/d/1Iqqr_VLtG8T3tUzy-EuMaeuCtFuv6pEU) |\n|[ctdet\\_pascal\\_resdcn18\\_384](../experiments/ctdet_pascal_resdcn18_384.sh) | 1  |3              | 7              | 72.6 | [model](https://drive.google.com/file/d/1mpeslWUt0aJqx99_-UcCzJ7GBcD6sCA-) |\n|[ctdet\\_pascal\\_resdcn18\\_512](../experiments/ctdet_pascal_resdcn18_512.sh) | 1  |5              | 10             | 75.7 | [model](https://drive.google.com/file/d/1ILnmGrJQiDK2Ib-D7TzBs2fq5bfju-Bd) |\n|[ctdet\\_pascal\\_resdcn101\\_384](../experiments/ctdet_pascal_resdcn101_384.sh)| 2  |7              | 22             | 77.1 | [model](https://drive.google.com/file/d/1-Qy4zMhzmBk9fMF0u2s5zNI0Uj9latsk) |\n|[ctdet\\_pascal\\_resdcn101\\_512](../experiments/ctdet_pascal_resdcn101_512.sh)| 4  |7              | 33             | 78.7 | [model](https://drive.google.com/file/d/1TiJkPaofzUaEMLi5wr9TIIUY8G2VewCQ) |\n\n#### Notes\n- All models are trained on trainval 07+12 and tested on test 2007.\n- Flip test is used by default.\n- Training schedule: train for 70 epochs with learning rate dropped 10 times at the 45 and 60 epoch.\n- We observed up to 1 mAP performance jitter due to randomness in training.\n\n## Human pose estimation\n\n### COCO\n\n| Model                    | GPUs |Train time(h)| Test time (ms) |   AP        |  Download | \n|--------------------------|------|-------------|----------------|-------------|-----------|\n|[multi\\_pose\\_hg_1x](../experiments/multi_pose_hg_1x.sh)    |   5  |62           | 151            | 58.7        | [model](https://drive.google.com/file/d/1neg1zfVjRTS45FCdk5hgIV-TxJ0McAew) |\n|[multi\\_pose\\_hg_3x](../experiments/multi_pose_hg_3x.sh)    |   5  |188          | 151            | 64.0        | [model](https://drive.google.com/file/d/17-YS11iguOQKwPPHUg8LzakLzrgKSLfA) |\n|[multi\\_pose\\_dla_1x](../experiments/multi_pose_dla_1x.sh)   |   8  |30           | 44             | 54.7        | [model](https://drive.google.com/file/d/1WKqVdkIew43SxLTSxi81a-_f4Q9v2Fx5) |\n|[multi\\_pose\\_dla_3x](../experiments/multi_pose_dla_3x.sh)   |   8  |70           | 44             | 58.9        | [model](https://drive.google.com/file/d/1mC2PAQT_RuHi_9ZMZgkt4rg7BSY2_Lkd) |\n\n#### Notes\n- All models are trained on keypoint train 2017 images which contains at least one human with keypoint annotations (64115 images).\n- The evaluation is done on COCO keypoint val 2017 (5000 images).\n- Flip test is used by default.\n- The models are fine-tuned from the corresponding center point detection models.\n- Dla training schedule: `1x`: train for 140 epochs with learning rate dropped 10 times at the 90 and 120 epoch.`3x`: train for 320 epochs with learning rate dropped 10 times at the 270 and 300 epoch.\n- Hourglass training schedule: `1x`: train for 50 epochs with learning rate dropped 10 times at the 40 epoch.`3x`: train for 150 epochs with learning rate dropped 10 times at the 130 epoch.\n\n## 3D bounding box detection\n\n#### Notes\n- The 3dop split is from [3DOP](https://papers.nips.cc/paper/5644-3d-object-proposals-for-accurate-object-class-detection) and the suborn split is from [SubCNN](https://github.com/tanshen/SubCNN).\n- No augmentation is used in testing.\n- The models are trained for 70 epochs with learning rate dropped at the 45 and 60 epoch.\n\n### KITTI 3DOP split\n\n|Model       |GPUs|Train time|Test time|AP-E|AP-M|AP-H|AOS-E|AOS-M|AOS-H|BEV-E|BEV-M|BEV-H| Download |\n|------------|----|----------|---------|----|----|----|-----|-----|-----|-----|-----|-----|----------|\n|[ddd_3dop](../experiments/ddd_3dop.sh)|2   | 7h       |  31ms   |96.9|87.8|79.2|93.9 |84.3 |75.7 |34.0 |30.5 |26.8 | [model](https://drive.google.com/file/d/1LrAzVJqlZECVuyr_NJI_4xd88mA1fL5b)|\n\n### KITTI SubCNN split\n\n|Model       |GPUs|Train time|Test time|AP-E|AP-M|AP-H|AOS-E|AOS-M|AOS-H|BEV-E|BEV-M|BEV-H| Download |\n|------------|----|----------|---------|----|----|----|-----|-----|-----|-----|-----|-----|----------|\n|[ddd_sub](../experiments/ddd_sub.sh) |2   | 7h       |  31ms   |89.6|79.8|70.3|85.7 |75.2 |65.9 |34.9 |27.7 |26.4 | [model](https://drive.google.com/file/d/1ZUsUqrM_yTjxaJuDBxm0WTKXj1snVuvP)|"
  },
  {
    "path": "requirements.txt",
    "content": "opencv-python\nCython\nnumba\nprogress\nmatplotlib\neasydict\nscipy\n"
  },
  {
    "path": "src/_init_paths.py",
    "content": "import os.path as osp\nimport sys\n\ndef add_path(path):\n    if path not in sys.path:\n        sys.path.insert(0, path)\n\nthis_dir = osp.dirname(__file__)\n\n# Add lib to PYTHONPATH\nlib_path = osp.join(this_dir, 'lib')\nadd_path(lib_path)\n"
  },
  {
    "path": "src/demo.py",
    "content": "from __future__ import absolute_import\nfrom __future__ import division\nfrom __future__ import print_function\n\nimport _init_paths\n\nimport os\nimport cv2\n\nfrom opts import opts\nfrom detectors.detector_factory import detector_factory\n\nimage_ext = ['jpg', 'jpeg', 'png', 'webp']\nvideo_ext = ['mp4', 'mov', 'avi', 'mkv']\ntime_stats = ['tot', 'load', 'pre', 'net', 'dec', 'post', 'merge']\n\ndef demo(opt):\n  os.environ['CUDA_VISIBLE_DEVICES'] = opt.gpus_str\n  opt.debug = max(opt.debug, 1)\n  Detector = detector_factory[opt.task]\n  detector = Detector(opt)\n\n  if opt.demo == 'webcam' or \\\n    opt.demo[opt.demo.rfind('.') + 1:].lower() in video_ext:\n    cam = cv2.VideoCapture(0 if opt.demo == 'webcam' else opt.demo)\n    detector.pause = False\n    while True:\n        _, img = cam.read()\n        cv2.imshow('input', img)\n        ret = detector.run(img)\n        time_str = ''\n        for stat in time_stats:\n          time_str = time_str + '{} {:.3f}s |'.format(stat, ret[stat])\n        print(time_str)\n        if cv2.waitKey(1) == 27:\n            return  # esc to quit\n  else:\n    if os.path.isdir(opt.demo):\n      image_names = []\n      ls = os.listdir(opt.demo)\n      for file_name in sorted(ls):\n          ext = file_name[file_name.rfind('.') + 1:].lower()\n          if ext in image_ext:\n              image_names.append(os.path.join(opt.demo, file_name))\n    else:\n      image_names = [opt.demo]\n    \n    for (image_name) in image_names:\n      ret = detector.run(image_name)\n      time_str = ''\n      for stat in time_stats:\n        time_str = time_str + '{} {:.3f}s |'.format(stat, ret[stat])\n      print(time_str)\nif __name__ == '__main__':\n  opt = opts().init()\n  demo(opt)\n"
  },
  {
    "path": "src/lib/datasets/dataset/coco.py",
    "content": "from __future__ import absolute_import\nfrom __future__ import division\nfrom __future__ import print_function\n\nimport pycocotools.coco as coco\nfrom pycocotools.cocoeval import COCOeval\nimport numpy as np\nimport json\nimport os\n\nimport torch.utils.data as data\n\nclass COCO(data.Dataset):\n  num_classes = 80\n  default_resolution = [512, 512]\n  mean = np.array([0.40789654, 0.44719302, 0.47026115],\n                   dtype=np.float32).reshape(1, 1, 3)\n  std  = np.array([0.28863828, 0.27408164, 0.27809835],\n                   dtype=np.float32).reshape(1, 1, 3)\n\n  def __init__(self, opt, split):\n    super(COCO, self).__init__()\n    self.data_dir = os.path.join(opt.data_dir, 'coco')\n    self.img_dir = os.path.join(self.data_dir, '{}2017'.format(split))\n    if split == 'test':\n      self.annot_path = os.path.join(\n          self.data_dir, 'annotations', \n          'image_info_test-dev2017.json').format(split)\n    else:\n      if opt.task == 'exdet':\n        self.annot_path = os.path.join(\n          self.data_dir, 'annotations', \n          'instances_extreme_{}2017.json').format(split)\n      else:\n        self.annot_path = os.path.join(\n          self.data_dir, 'annotations', \n          'instances_{}2017.json').format(split)\n    self.max_objs = 128\n    self.class_name = [\n      '__background__', 'person', 'bicycle', 'car', 'motorcycle', 'airplane',\n      'bus', 'train', 'truck', 'boat', 'traffic light', 'fire hydrant',\n      'stop sign', 'parking meter', 'bench', 'bird', 'cat', 'dog', 'horse',\n      'sheep', 'cow', 'elephant', 'bear', 'zebra', 'giraffe', 'backpack',\n      'umbrella', 'handbag', 'tie', 'suitcase', 'frisbee', 'skis',\n      'snowboard', 'sports ball', 'kite', 'baseball bat', 'baseball glove',\n      'skateboard', 'surfboard', 'tennis racket', 'bottle', 'wine glass',\n      'cup', 'fork', 'knife', 'spoon', 'bowl', 'banana', 'apple', 'sandwich',\n      'orange', 'broccoli', 'carrot', 'hot dog', 'pizza', 'donut', 'cake',\n      'chair', 'couch', 'potted plant', 'bed', 'dining table', 'toilet', 'tv',\n      'laptop', 'mouse', 'remote', 'keyboard', 'cell phone', 'microwave',\n      'oven', 'toaster', 'sink', 'refrigerator', 'book', 'clock', 'vase',\n      'scissors', 'teddy bear', 'hair drier', 'toothbrush']\n    self._valid_ids = [\n      1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, \n      14, 15, 16, 17, 18, 19, 20, 21, 22, 23, \n      24, 25, 27, 28, 31, 32, 33, 34, 35, 36, \n      37, 38, 39, 40, 41, 42, 43, 44, 46, 47, \n      48, 49, 50, 51, 52, 53, 54, 55, 56, 57, \n      58, 59, 60, 61, 62, 63, 64, 65, 67, 70, \n      72, 73, 74, 75, 76, 77, 78, 79, 80, 81, \n      82, 84, 85, 86, 87, 88, 89, 90]\n    self.cat_ids = {v: i for i, v in enumerate(self._valid_ids)}\n    self.voc_color = [(v // 32 * 64 + 64, (v // 8) % 4 * 64, v % 8 * 32) \\\n                      for v in range(1, self.num_classes + 1)]\n    self._data_rng = np.random.RandomState(123)\n    self._eig_val = np.array([0.2141788, 0.01817699, 0.00341571],\n                             dtype=np.float32)\n    self._eig_vec = np.array([\n        [-0.58752847, -0.69563484, 0.41340352],\n        [-0.5832747, 0.00994535, -0.81221408],\n        [-0.56089297, 0.71832671, 0.41158938]\n    ], dtype=np.float32)\n    # self.mean = np.array([0.485, 0.456, 0.406], np.float32).reshape(1, 1, 3)\n    # self.std = np.array([0.229, 0.224, 0.225], np.float32).reshape(1, 1, 3)\n\n    self.split = split\n    self.opt = opt\n\n    print('==> initializing coco 2017 {} data.'.format(split))\n    self.coco = coco.COCO(self.annot_path)\n    self.images = self.coco.getImgIds()\n    self.num_samples = len(self.images)\n\n    print('Loaded {} {} samples'.format(split, self.num_samples))\n\n  def _to_float(self, x):\n    return float(\"{:.2f}\".format(x))\n\n  def convert_eval_format(self, all_bboxes):\n    # import pdb; pdb.set_trace()\n    detections = []\n    for image_id in all_bboxes:\n      for cls_ind in all_bboxes[image_id]:\n        category_id = self._valid_ids[cls_ind - 1]\n        for bbox in all_bboxes[image_id][cls_ind]:\n          bbox[2] -= bbox[0]\n          bbox[3] -= bbox[1]\n          score = bbox[4]\n          bbox_out  = list(map(self._to_float, bbox[0:4]))\n\n          detection = {\n              \"image_id\": int(image_id),\n              \"category_id\": int(category_id),\n              \"bbox\": bbox_out,\n              \"score\": float(\"{:.2f}\".format(score))\n          }\n          if len(bbox) > 5:\n              extreme_points = list(map(self._to_float, bbox[5:13]))\n              detection[\"extreme_points\"] = extreme_points\n          detections.append(detection)\n    return detections\n\n  def __len__(self):\n    return self.num_samples\n\n  def save_results(self, results, save_dir):\n    json.dump(self.convert_eval_format(results), \n                open('{}/results.json'.format(save_dir), 'w'))\n  \n  def run_eval(self, results, save_dir):\n    # result_json = os.path.join(save_dir, \"results.json\")\n    # detections  = self.convert_eval_format(results)\n    # json.dump(detections, open(result_json, \"w\"))\n    self.save_results(results, save_dir)\n    coco_dets = self.coco.loadRes('{}/results.json'.format(save_dir))\n    coco_eval = COCOeval(self.coco, coco_dets, \"bbox\")\n    coco_eval.evaluate()\n    coco_eval.accumulate()\n    coco_eval.summarize()\n"
  },
  {
    "path": "src/lib/datasets/dataset/coco_hp.py",
    "content": "from __future__ import absolute_import\nfrom __future__ import division\nfrom __future__ import print_function\n\nimport pycocotools.coco as coco\nfrom pycocotools.cocoeval import COCOeval\nimport numpy as np\nimport json\nimport os\n\nimport torch.utils.data as data\n\nclass COCOHP(data.Dataset):\n  num_classes = 1\n  num_joints = 17\n  default_resolution = [512, 512]\n  mean = np.array([0.40789654, 0.44719302, 0.47026115],\n                   dtype=np.float32).reshape(1, 1, 3)\n  std  = np.array([0.28863828, 0.27408164, 0.27809835],\n                   dtype=np.float32).reshape(1, 1, 3)\n  flip_idx = [[1, 2], [3, 4], [5, 6], [7, 8], [9, 10], \n              [11, 12], [13, 14], [15, 16]]\n  def __init__(self, opt, split):\n    super(COCOHP, self).__init__()\n    self.edges = [[0, 1], [0, 2], [1, 3], [2, 4], \n                  [4, 6], [3, 5], [5, 6], \n                  [5, 7], [7, 9], [6, 8], [8, 10], \n                  [6, 12], [5, 11], [11, 12], \n                  [12, 14], [14, 16], [11, 13], [13, 15]]\n    \n    self.acc_idxs = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]\n    self.data_dir = os.path.join(opt.data_dir, 'coco')\n    self.img_dir = os.path.join(self.data_dir, '{}2017'.format(split))\n    if split == 'test':\n      self.annot_path = os.path.join(\n          self.data_dir, 'annotations', \n          'image_info_test-dev2017.json').format(split)\n    else:\n      self.annot_path = os.path.join(\n        self.data_dir, 'annotations', \n        'person_keypoints_{}2017.json').format(split)\n    self.max_objs = 32\n    self._data_rng = np.random.RandomState(123)\n    self._eig_val = np.array([0.2141788, 0.01817699, 0.00341571],\n                             dtype=np.float32)\n    self._eig_vec = np.array([\n        [-0.58752847, -0.69563484, 0.41340352],\n        [-0.5832747, 0.00994535, -0.81221408],\n        [-0.56089297, 0.71832671, 0.41158938]\n    ], dtype=np.float32)\n    self.split = split\n    self.opt = opt\n\n    print('==> initializing coco 2017 {} data.'.format(split))\n    self.coco = coco.COCO(self.annot_path)\n    image_ids = self.coco.getImgIds()\n\n    if split == 'train':\n      self.images = []\n      for img_id in image_ids:\n        idxs = self.coco.getAnnIds(imgIds=[img_id])\n        if len(idxs) > 0:\n          self.images.append(img_id)\n    else:\n      self.images = image_ids\n    self.num_samples = len(self.images)\n    print('Loaded {} {} samples'.format(split, self.num_samples))\n\n  def _to_float(self, x):\n    return float(\"{:.2f}\".format(x))\n\n  def convert_eval_format(self, all_bboxes):\n    # import pdb; pdb.set_trace()\n    detections = []\n    for image_id in all_bboxes:\n      for cls_ind in all_bboxes[image_id]:\n        category_id = 1\n        for dets in all_bboxes[image_id][cls_ind]:\n          bbox = dets[:4]\n          bbox[2] -= bbox[0]\n          bbox[3] -= bbox[1]\n          score = dets[4]\n          bbox_out  = list(map(self._to_float, bbox))\n          keypoints = np.concatenate([\n            np.array(dets[5:39], dtype=np.float32).reshape(-1, 2), \n            np.ones((17, 1), dtype=np.float32)], axis=1).reshape(51).tolist()\n          keypoints  = list(map(self._to_float, keypoints))\n\n          detection = {\n              \"image_id\": int(image_id),\n              \"category_id\": int(category_id),\n              \"bbox\": bbox_out,\n              \"score\": float(\"{:.2f}\".format(score)),\n              \"keypoints\": keypoints\n          }\n          detections.append(detection)\n    return detections\n\n  def __len__(self):\n    return self.num_samples\n\n  def save_results(self, results, save_dir):\n    json.dump(self.convert_eval_format(results), \n              open('{}/results.json'.format(save_dir), 'w'))\n\n\n  def run_eval(self, results, save_dir):\n    # result_json = os.path.join(opt.save_dir, \"results.json\")\n    # detections  = convert_eval_format(all_boxes)\n    # json.dump(detections, open(result_json, \"w\"))\n    self.save_results(results, save_dir)\n    coco_dets = self.coco.loadRes('{}/results.json'.format(save_dir))\n    coco_eval = COCOeval(self.coco, coco_dets, \"keypoints\")\n    coco_eval.evaluate()\n    coco_eval.accumulate()\n    coco_eval.summarize()\n    coco_eval = COCOeval(self.coco, coco_dets, \"bbox\")\n    coco_eval.evaluate()\n    coco_eval.accumulate()\n    coco_eval.summarize()"
  },
  {
    "path": "src/lib/datasets/dataset/kitti.py",
    "content": "from __future__ import absolute_import\nfrom __future__ import division\nfrom __future__ import print_function\n\nimport torch.utils.data as data\nimport pycocotools.coco as coco\nimport numpy as np\nimport torch\nimport json\nimport cv2\nimport os\nimport math\n\nimport torch.utils.data as data\n\n\nclass KITTI(data.Dataset):\n  num_classes = 3\n  default_resolution = [384, 1280]\n  mean = np.array([0.485, 0.456, 0.406], np.float32).reshape(1, 1, 3)\n  std = np.array([0.229, 0.224, 0.225], np.float32).reshape(1, 1, 3)\n\n  def __init__(self, opt, split):\n    super(KITTI, self).__init__()\n    self.data_dir = os.path.join(opt.data_dir, 'kitti')\n    self.img_dir = os.path.join(self.data_dir, 'images', 'trainval')\n    if opt.trainval:\n      split = 'trainval' if split == 'train' else 'test'\n      self.img_dir = os.path.join(self.data_dir, 'images', split)\n      self.annot_path = os.path.join(\n        self.data_dir, 'annotations', 'kitti_{}.json').format(split)\n    else:\n      self.annot_path = os.path.join(self.data_dir, \n        'annotations', 'kitti_{}_{}.json').format(opt.kitti_split, split)\n    self.max_objs = 50\n    self.class_name = [\n      '__background__', 'Pedestrian', 'Car', 'Cyclist']\n    self.cat_ids = {1:0, 2:1, 3:2, 4:-3, 5:-3, 6:-2, 7:-99, 8:-99, 9:-1}\n    \n    self._data_rng = np.random.RandomState(123)\n    self._eig_val = np.array([0.2141788, 0.01817699, 0.00341571],\n                             dtype=np.float32)\n    self._eig_vec = np.array([\n        [-0.58752847, -0.69563484, 0.41340352],\n        [-0.5832747, 0.00994535, -0.81221408],\n        [-0.56089297, 0.71832671, 0.41158938]\n    ], dtype=np.float32)\n    self.split = split\n    self.opt = opt\n    self.alpha_in_degree = False\n\n    print('==> initializing kitti {}, {} data.'.format(opt.kitti_split, split))\n    self.coco = coco.COCO(self.annot_path)\n    self.images = self.coco.getImgIds()\n    self.num_samples = len(self.images)\n\n    print('Loaded {} {} samples'.format(split, self.num_samples))\n\n  def __len__(self):\n    return self.num_samples\n\n  def _to_float(self, x):\n    return float(\"{:.2f}\".format(x))\n\n  def convert_eval_format(self, all_bboxes):\n    pass\n\n  def save_results(self, results, save_dir):\n    results_dir = os.path.join(save_dir, 'results')\n    if not os.path.exists(results_dir):\n      os.mkdir(results_dir)\n    for img_id in results.keys():\n      out_path = os.path.join(results_dir, '{:06d}.txt'.format(img_id))\n      f = open(out_path, 'w')\n      for cls_ind in results[img_id]:\n        for j in range(len(results[img_id][cls_ind])):\n          class_name = self.class_name[cls_ind]\n          f.write('{} 0.0 0'.format(class_name))\n          for i in range(len(results[img_id][cls_ind][j])):\n            f.write(' {:.2f}'.format(results[img_id][cls_ind][j][i]))\n          f.write('\\n')\n      f.close()\n\n  def run_eval(self, results, save_dir):\n    self.save_results(results, save_dir)\n    os.system('./tools/kitti_eval/evaluate_object_3d_offline ' + \\\n              '../data/kitti/training/label_val ' + \\\n              '{}/results/'.format(save_dir))\n    \n"
  },
  {
    "path": "src/lib/datasets/dataset/pascal.py",
    "content": "from __future__ import absolute_import\nfrom __future__ import division\nfrom __future__ import print_function\n\nimport pycocotools.coco as coco\nimport numpy as np\nimport torch\nimport json\nimport os\n\nimport torch.utils.data as data\n\nclass PascalVOC(data.Dataset):\n  num_classes = 20\n  default_resolution = [384, 384]\n  mean = np.array([0.485, 0.456, 0.406],\n                   dtype=np.float32).reshape(1, 1, 3)\n  std  = np.array([0.229, 0.224, 0.225],\n                   dtype=np.float32).reshape(1, 1, 3)\n  \n  def __init__(self, opt, split):\n    super(PascalVOC, self).__init__()\n    self.data_dir = os.path.join(opt.data_dir, 'voc')\n    self.img_dir = os.path.join(self.data_dir, 'images')\n    _ann_name = {'train': 'trainval0712', 'val': 'test2007'}\n    self.annot_path = os.path.join(\n      self.data_dir, 'annotations', \n      'pascal_{}.json').format(_ann_name[split])\n    self.max_objs = 50\n    self.class_name = ['__background__', \"aeroplane\", \"bicycle\", \"bird\", \"boat\",\n     \"bottle\", \"bus\", \"car\", \"cat\", \"chair\", \"cow\", \"diningtable\", \"dog\", \n     \"horse\", \"motorbike\", \"person\", \"pottedplant\", \"sheep\", \"sofa\", \n     \"train\", \"tvmonitor\"]\n    self._valid_ids = np.arange(1, 21, dtype=np.int32)\n    self.cat_ids = {v: i for i, v in enumerate(self._valid_ids)}\n    self._data_rng = np.random.RandomState(123)\n    self._eig_val = np.array([0.2141788, 0.01817699, 0.00341571],\n                             dtype=np.float32)\n    self._eig_vec = np.array([\n        [-0.58752847, -0.69563484, 0.41340352],\n        [-0.5832747, 0.00994535, -0.81221408],\n        [-0.56089297, 0.71832671, 0.41158938]\n    ], dtype=np.float32)\n    self.split = split\n    self.opt = opt\n\n    print('==> initializing pascal {} data.'.format(_ann_name[split]))\n    self.coco = coco.COCO(self.annot_path)\n    self.images = sorted(self.coco.getImgIds())\n    self.num_samples = len(self.images)\n\n    print('Loaded {} {} samples'.format(split, self.num_samples))\n\n  def _to_float(self, x):\n    return float(\"{:.2f}\".format(x))\n\n  def convert_eval_format(self, all_bboxes):\n    detections = [[[] for __ in range(self.num_samples)] \\\n                  for _ in range(self.num_classes + 1)]\n    for i in range(self.num_samples):\n      img_id = self.images[i]\n      for j in range(1, self.num_classes + 1):\n        if isinstance(all_bboxes[img_id][j], np.ndarray):\n          detections[j][i] = all_bboxes[img_id][j].tolist()\n        else:\n          detections[j][i] = all_bboxes[img_id][j]\n    return detections\n\n  def __len__(self):\n    return self.num_samples\n\n  def save_results(self, results, save_dir):\n    json.dump(self.convert_eval_format(results), \n              open('{}/results.json'.format(save_dir), 'w'))\n\n  def run_eval(self, results, save_dir):\n    # result_json = os.path.join(save_dir, \"results.json\")\n    # detections  = self.convert_eval_format(results)\n    # json.dump(detections, open(result_json, \"w\"))\n    self.save_results(results, save_dir)\n    os.system('python tools/reval.py ' + \\\n              '{}/results.json'.format(save_dir))\n"
  },
  {
    "path": "src/lib/datasets/dataset_factory.py",
    "content": "from __future__ import absolute_import\nfrom __future__ import division\nfrom __future__ import print_function\n\nfrom .sample.ddd import DddDataset\nfrom .sample.exdet import EXDetDataset\nfrom .sample.ctdet import CTDetDataset\nfrom .sample.multi_pose import MultiPoseDataset\n\nfrom .dataset.coco import COCO\nfrom .dataset.pascal import PascalVOC\nfrom .dataset.kitti import KITTI\nfrom .dataset.coco_hp import COCOHP\n\n\ndataset_factory = {\n  'coco': COCO,\n  'pascal': PascalVOC,\n  'kitti': KITTI,\n  'coco_hp': COCOHP\n}\n\n_sample_factory = {\n  'exdet': EXDetDataset,\n  'ctdet': CTDetDataset,\n  'ddd': DddDataset,\n  'multi_pose': MultiPoseDataset\n}\n\n\ndef get_dataset(dataset, task):\n  class Dataset(dataset_factory[dataset], _sample_factory[task]):\n    pass\n  return Dataset\n  \n"
  },
  {
    "path": "src/lib/datasets/sample/ctdet.py",
    "content": "from __future__ import absolute_import\nfrom __future__ import division\nfrom __future__ import print_function\n\nimport torch.utils.data as data\nimport numpy as np\nimport torch\nimport json\nimport cv2\nimport os\nfrom utils.image import flip, color_aug\nfrom utils.image import get_affine_transform, affine_transform\nfrom utils.image import gaussian_radius, draw_umich_gaussian, draw_msra_gaussian\nfrom utils.image import draw_dense_reg\nimport math\n\nclass CTDetDataset(data.Dataset):\n  def _coco_box_to_bbox(self, box):\n    bbox = np.array([box[0], box[1], box[0] + box[2], box[1] + box[3]],\n                    dtype=np.float32)\n    return bbox\n\n  def _get_border(self, border, size):\n    i = 1\n    while size - border // i <= border // i:\n        i *= 2\n    return border // i\n\n  def __getitem__(self, index):\n    img_id = self.images[index]\n    file_name = self.coco.loadImgs(ids=[img_id])[0]['file_name']\n    img_path = os.path.join(self.img_dir, file_name)\n    ann_ids = self.coco.getAnnIds(imgIds=[img_id])\n    anns = self.coco.loadAnns(ids=ann_ids)\n    num_objs = min(len(anns), self.max_objs)\n\n    img = cv2.imread(img_path)\n\n    height, width = img.shape[0], img.shape[1]\n    c = np.array([img.shape[1] / 2., img.shape[0] / 2.], dtype=np.float32)\n    if self.opt.keep_res:\n      input_h = (height | self.opt.pad) + 1\n      input_w = (width | self.opt.pad) + 1\n      s = np.array([input_w, input_h], dtype=np.float32)\n    else:\n      s = max(img.shape[0], img.shape[1]) * 1.0\n      input_h, input_w = self.opt.input_h, self.opt.input_w\n    \n    flipped = False\n    if self.split == 'train':\n      if not self.opt.not_rand_crop:\n        s = s * np.random.choice(np.arange(0.6, 1.4, 0.1))\n        w_border = self._get_border(128, img.shape[1])\n        h_border = self._get_border(128, img.shape[0])\n        c[0] = np.random.randint(low=w_border, high=img.shape[1] - w_border)\n        c[1] = np.random.randint(low=h_border, high=img.shape[0] - h_border)\n      else:\n        sf = self.opt.scale\n        cf = self.opt.shift\n        c[0] += s * np.clip(np.random.randn()*cf, -2*cf, 2*cf)\n        c[1] += s * np.clip(np.random.randn()*cf, -2*cf, 2*cf)\n        s = s * np.clip(np.random.randn()*sf + 1, 1 - sf, 1 + sf)\n      \n      if np.random.random() < self.opt.flip:\n        flipped = True\n        img = img[:, ::-1, :]\n        c[0] =  width - c[0] - 1\n        \n\n    trans_input = get_affine_transform(\n      c, s, 0, [input_w, input_h])\n    inp = cv2.warpAffine(img, trans_input, \n                         (input_w, input_h),\n                         flags=cv2.INTER_LINEAR)\n    inp = (inp.astype(np.float32) / 255.)\n    if self.split == 'train' and not self.opt.no_color_aug:\n      color_aug(self._data_rng, inp, self._eig_val, self._eig_vec)\n    inp = (inp - self.mean) / self.std\n    inp = inp.transpose(2, 0, 1)\n\n    output_h = input_h // self.opt.down_ratio\n    output_w = input_w // self.opt.down_ratio\n    num_classes = self.num_classes\n    trans_output = get_affine_transform(c, s, 0, [output_w, output_h])\n\n    hm = np.zeros((num_classes, output_h, output_w), dtype=np.float32)\n    wh = np.zeros((self.max_objs, 2), dtype=np.float32)\n    dense_wh = np.zeros((2, output_h, output_w), dtype=np.float32)\n    reg = np.zeros((self.max_objs, 2), dtype=np.float32)\n    ind = np.zeros((self.max_objs), dtype=np.int64)\n    reg_mask = np.zeros((self.max_objs), dtype=np.uint8)\n    cat_spec_wh = np.zeros((self.max_objs, num_classes * 2), dtype=np.float32)\n    cat_spec_mask = np.zeros((self.max_objs, num_classes * 2), dtype=np.uint8)\n    \n    draw_gaussian = draw_msra_gaussian if self.opt.mse_loss else \\\n                    draw_umich_gaussian\n\n    gt_det = []\n    for k in range(num_objs):\n      ann = anns[k]\n      bbox = self._coco_box_to_bbox(ann['bbox'])\n      cls_id = int(self.cat_ids[ann['category_id']])\n      if flipped:\n        bbox[[0, 2]] = width - bbox[[2, 0]] - 1\n      bbox[:2] = affine_transform(bbox[:2], trans_output)\n      bbox[2:] = affine_transform(bbox[2:], trans_output)\n      bbox[[0, 2]] = np.clip(bbox[[0, 2]], 0, output_w - 1)\n      bbox[[1, 3]] = np.clip(bbox[[1, 3]], 0, output_h - 1)\n      h, w = bbox[3] - bbox[1], bbox[2] - bbox[0]\n      if h > 0 and w > 0:\n        radius = gaussian_radius((math.ceil(h), math.ceil(w)))\n        radius = max(0, int(radius))\n        radius = self.opt.hm_gauss if self.opt.mse_loss else radius\n        ct = np.array(\n          [(bbox[0] + bbox[2]) / 2, (bbox[1] + bbox[3]) / 2], dtype=np.float32)\n        ct_int = ct.astype(np.int32)\n        draw_gaussian(hm[cls_id], ct_int, radius)\n        wh[k] = 1. * w, 1. * h\n        ind[k] = ct_int[1] * output_w + ct_int[0]\n        reg[k] = ct - ct_int\n        reg_mask[k] = 1\n        cat_spec_wh[k, cls_id * 2: cls_id * 2 + 2] = wh[k]\n        cat_spec_mask[k, cls_id * 2: cls_id * 2 + 2] = 1\n        if self.opt.dense_wh:\n          draw_dense_reg(dense_wh, hm.max(axis=0), ct_int, wh[k], radius)\n        gt_det.append([ct[0] - w / 2, ct[1] - h / 2, \n                       ct[0] + w / 2, ct[1] + h / 2, 1, cls_id])\n    \n    ret = {'input': inp, 'hm': hm, 'reg_mask': reg_mask, 'ind': ind, 'wh': wh}\n    if self.opt.dense_wh:\n      hm_a = hm.max(axis=0, keepdims=True)\n      dense_wh_mask = np.concatenate([hm_a, hm_a], axis=0)\n      ret.update({'dense_wh': dense_wh, 'dense_wh_mask': dense_wh_mask})\n      del ret['wh']\n    elif self.opt.cat_spec_wh:\n      ret.update({'cat_spec_wh': cat_spec_wh, 'cat_spec_mask': cat_spec_mask})\n      del ret['wh']\n    if self.opt.reg_offset:\n      ret.update({'reg': reg})\n    if self.opt.debug > 0 or not self.split == 'train':\n      gt_det = np.array(gt_det, dtype=np.float32) if len(gt_det) > 0 else \\\n               np.zeros((1, 6), dtype=np.float32)\n      meta = {'c': c, 's': s, 'gt_det': gt_det, 'img_id': img_id}\n      ret['meta'] = meta\n    return ret"
  },
  {
    "path": "src/lib/datasets/sample/ddd.py",
    "content": "from __future__ import absolute_import\nfrom __future__ import division\nfrom __future__ import print_function\n\nimport torch.utils.data as data\nimport pycocotools.coco as coco\nimport numpy as np\nimport torch\nimport json\nimport cv2\nimport os\nimport math\nfrom utils.image import flip, color_aug\nfrom utils.image import get_affine_transform, affine_transform\nfrom utils.image import gaussian_radius, draw_umich_gaussian, draw_msra_gaussian\nimport pycocotools.coco as coco\n\nclass DddDataset(data.Dataset):\n  def _coco_box_to_bbox(self, box):\n    bbox = np.array([box[0], box[1], box[0] + box[2], box[1] + box[3]],\n                    dtype=np.float32)\n    return bbox\n\n  def _convert_alpha(self, alpha):\n    return math.radians(alpha + 45) if self.alpha_in_degree else alpha\n\n  def __getitem__(self, index):\n    img_id = self.images[index]\n    img_info = self.coco.loadImgs(ids=[img_id])[0]\n    img_path = os.path.join(self.img_dir, img_info['file_name'])\n    img = cv2.imread(img_path)\n    if 'calib' in img_info:\n      calib = np.array(img_info['calib'], dtype=np.float32)\n    else:\n      calib = self.calib\n\n    height, width = img.shape[0], img.shape[1]\n    c = np.array([img.shape[1] / 2., img.shape[0] / 2.])\n    if self.opt.keep_res:\n      s = np.array([self.opt.input_w, self.opt.input_h], dtype=np.int32)\n    else:\n      s = np.array([width, height], dtype=np.int32)\n    \n    aug = False\n    if self.split == 'train' and np.random.random() < self.opt.aug_ddd:\n      aug = True\n      sf = self.opt.scale\n      cf = self.opt.shift\n      s = s * np.clip(np.random.randn()*sf + 1, 1 - sf, 1 + sf)\n      c[0] += img.shape[1] * np.clip(np.random.randn()*cf, -2*cf, 2*cf)\n      c[1] += img.shape[0] * np.clip(np.random.randn()*cf, -2*cf, 2*cf)\n\n    trans_input = get_affine_transform(\n      c, s, 0, [self.opt.input_w, self.opt.input_h])\n    inp = cv2.warpAffine(img, trans_input, \n                         (self.opt.input_w, self.opt.input_h),\n                         flags=cv2.INTER_LINEAR)\n    inp = (inp.astype(np.float32) / 255.)\n    # if self.split == 'train' and not self.opt.no_color_aug:\n    #   color_aug(self._data_rng, inp, self._eig_val, self._eig_vec)\n    inp = (inp - self.mean) / self.std\n    inp = inp.transpose(2, 0, 1)\n\n    num_classes = self.opt.num_classes\n    trans_output = get_affine_transform(\n      c, s, 0, [self.opt.output_w, self.opt.output_h])\n\n    hm = np.zeros(\n      (num_classes, self.opt.output_h, self.opt.output_w), dtype=np.float32)\n    wh = np.zeros((self.max_objs, 2), dtype=np.float32)\n    reg = np.zeros((self.max_objs, 2), dtype=np.float32)\n    dep = np.zeros((self.max_objs, 1), dtype=np.float32)\n    rotbin = np.zeros((self.max_objs, 2), dtype=np.int64)\n    rotres = np.zeros((self.max_objs, 2), dtype=np.float32)\n    dim = np.zeros((self.max_objs, 3), dtype=np.float32)\n    ind = np.zeros((self.max_objs), dtype=np.int64)\n    reg_mask = np.zeros((self.max_objs), dtype=np.uint8)\n    rot_mask = np.zeros((self.max_objs), dtype=np.uint8)\n\n    ann_ids = self.coco.getAnnIds(imgIds=[img_id])\n    anns = self.coco.loadAnns(ids=ann_ids)\n    num_objs = min(len(anns), self.max_objs)\n    draw_gaussian = draw_msra_gaussian if self.opt.mse_loss else \\\n                    draw_umich_gaussian\n    gt_det = []\n    for k in range(num_objs):\n      ann = anns[k]\n      bbox = self._coco_box_to_bbox(ann['bbox'])\n      cls_id = int(self.cat_ids[ann['category_id']])\n      if cls_id <= -99:\n        continue\n      # if flipped:\n      #   bbox[[0, 2]] = width - bbox[[2, 0]] - 1\n      bbox[:2] = affine_transform(bbox[:2], trans_output)\n      bbox[2:] = affine_transform(bbox[2:], trans_output)\n      bbox[[0, 2]] = np.clip(bbox[[0, 2]], 0, self.opt.output_w - 1)\n      bbox[[1, 3]] = np.clip(bbox[[1, 3]], 0, self.opt.output_h - 1)\n      h, w = bbox[3] - bbox[1], bbox[2] - bbox[0]\n      if h > 0 and w > 0:\n        radius = gaussian_radius((h, w))\n        radius = max(0, int(radius))\n        ct = np.array(\n          [(bbox[0] + bbox[2]) / 2, (bbox[1] + bbox[3]) / 2], dtype=np.float32)\n        ct_int = ct.astype(np.int32)\n        if cls_id < 0:\n          ignore_id = [_ for _ in range(num_classes)] \\\n                      if cls_id == - 1 else  [- cls_id - 2]\n          if self.opt.rect_mask:\n            hm[ignore_id, int(bbox[1]): int(bbox[3]) + 1, \n              int(bbox[0]): int(bbox[2]) + 1] = 0.9999\n          else:\n            for cc in ignore_id:\n              draw_gaussian(hm[cc], ct, radius)\n            hm[ignore_id, ct_int[1], ct_int[0]] = 0.9999\n          continue\n        draw_gaussian(hm[cls_id], ct, radius)\n\n        wh[k] = 1. * w, 1. * h\n        gt_det.append([ct[0], ct[1], 1] + \\\n                      self._alpha_to_8(self._convert_alpha(ann['alpha'])) + \\\n                      [ann['depth']] + (np.array(ann['dim']) / 1).tolist() + [cls_id])\n        if self.opt.reg_bbox:\n          gt_det[-1] = gt_det[-1][:-1] + [w, h] + [gt_det[-1][-1]]\n        # if (not self.opt.car_only) or cls_id == 1: # Only estimate ADD for cars !!!\n        if 1:\n          alpha = self._convert_alpha(ann['alpha'])\n          # print('img_id cls_id alpha rot_y', img_path, cls_id, alpha, ann['rotation_y'])\n          if alpha < np.pi / 6. or alpha > 5 * np.pi / 6.:\n            rotbin[k, 0] = 1\n            rotres[k, 0] = alpha - (-0.5 * np.pi)    \n          if alpha > -np.pi / 6. or alpha < -5 * np.pi / 6.:\n            rotbin[k, 1] = 1\n            rotres[k, 1] = alpha - (0.5 * np.pi)\n          dep[k] = ann['depth']\n          dim[k] = ann['dim']\n          # print('        cat dim', cls_id, dim[k])\n          ind[k] = ct_int[1] * self.opt.output_w + ct_int[0]\n          reg[k] = ct - ct_int\n          reg_mask[k] = 1 if not aug else 0\n          rot_mask[k] = 1\n    # print('gt_det', gt_det)\n    # print('')\n    ret = {'input': inp, 'hm': hm, 'dep': dep, 'dim': dim, 'ind': ind, \n           'rotbin': rotbin, 'rotres': rotres, 'reg_mask': reg_mask,\n           'rot_mask': rot_mask}\n    if self.opt.reg_bbox:\n      ret.update({'wh': wh})\n    if self.opt.reg_offset:\n      ret.update({'reg': reg})\n    if self.opt.debug > 0 or not ('train' in self.split):\n      gt_det = np.array(gt_det, dtype=np.float32) if len(gt_det) > 0 else \\\n               np.zeros((1, 18), dtype=np.float32)\n      meta = {'c': c, 's': s, 'gt_det': gt_det, 'calib': calib,\n              'image_path': img_path, 'img_id': img_id}\n      ret['meta'] = meta\n    \n    return ret\n\n  def _alpha_to_8(self, alpha):\n    # return [alpha, 0, 0, 0, 0, 0, 0, 0]\n    ret = [0, 0, 0, 1, 0, 0, 0, 1]\n    if alpha < np.pi / 6. or alpha > 5 * np.pi / 6.:\n      r = alpha - (-0.5 * np.pi)\n      ret[1] = 1\n      ret[2], ret[3] = np.sin(r), np.cos(r)\n    if alpha > -np.pi / 6. or alpha < -5 * np.pi / 6.:\n      r = alpha - (0.5 * np.pi)\n      ret[5] = 1\n      ret[6], ret[7] = np.sin(r), np.cos(r)\n    return ret\n"
  },
  {
    "path": "src/lib/datasets/sample/exdet.py",
    "content": "from __future__ import absolute_import\nfrom __future__ import division\nfrom __future__ import print_function\n\nimport torch.utils.data as data\nimport pycocotools.coco as coco\nimport numpy as np\nimport torch\nimport json\nimport cv2\nimport os\nfrom utils.image import flip, color_aug\nfrom utils.image import get_affine_transform, affine_transform\nfrom utils.image import gaussian_radius, draw_umich_gaussian, draw_msra_gaussian\nimport pycocotools.coco as coco\nimport math\n\nclass EXDetDataset(data.Dataset):\n  def _coco_box_to_bbox(self, box):\n    bbox = np.array([box[0], box[1], box[0] + box[2], box[1] + box[3]],\n                    dtype=np.float32)\n    return bbox\n\n  def _get_border(self, border, size):\n    i = 1\n    while size - border // i <= border // i:\n        i *= 2\n    return border // i\n\n  def __getitem__(self, index):\n    img_id = self.images[index]\n    img_info = self.coco.loadImgs(ids=[img_id])[0]\n    img_path = os.path.join(self.img_dir, img_info['file_name'])\n    img = cv2.imread(img_path)\n\n    height, width = img.shape[0], img.shape[1]\n    c = np.array([img.shape[1] / 2., img.shape[0] / 2.])\n    s = max(img.shape[0], img.shape[1]) * 1.0\n    \n    flipped = False\n    if self.split == 'train':\n      if not self.opt.not_rand_crop:\n        s = s * np.random.choice(np.arange(0.6, 1.4, 0.1))\n        w_border = self._get_border(128, img.shape[1])\n        h_border = self._get_border(128, img.shape[0])\n        c[0] = np.random.randint(low=w_border, high=img.shape[1] - w_border)\n        c[1] = np.random.randint(low=h_border, high=img.shape[0] - h_border)\n      else:\n        sf = self.opt.scale\n        cf = self.opt.shift\n        s = s * np.clip(np.random.randn()*sf + 1, 1 - sf, 1 + sf)\n        c[0] += img.shape[1] * np.clip(np.random.randn()*cf, -2*cf, 2*cf)\n        c[1] += img.shape[0] * np.clip(np.random.randn()*cf, -2*cf, 2*cf)\n      if np.random.random() < self.opt.flip:\n        flipped = True\n        img = img[:, ::-1, :]\n\n    trans_input = get_affine_transform(\n      c, s, 0, [self.opt.input_res, self.opt.input_res])\n    inp = cv2.warpAffine(img, trans_input, \n                         (self.opt.input_res, self.opt.input_res),\n                         flags=cv2.INTER_LINEAR)\n    inp = (inp.astype(np.float32) / 255.)\n    if self.split == 'train' and not self.opt.no_color_aug:\n      color_aug(self._data_rng, inp, self._eig_val, self._eig_vec)\n    inp = (inp - self.mean) / self.std\n    inp = inp.transpose(2, 0, 1)\n\n    output_res = self.opt.output_res\n    num_classes = self.opt.num_classes\n    trans_output = get_affine_transform(c, s, 0, [output_res, output_res])\n    num_hm = 1 if self.opt.agnostic_ex else num_classes\n\n    hm_t = np.zeros((num_hm, output_res, output_res), dtype=np.float32)\n    hm_l = np.zeros((num_hm, output_res, output_res), dtype=np.float32)\n    hm_b = np.zeros((num_hm, output_res, output_res), dtype=np.float32)\n    hm_r = np.zeros((num_hm, output_res, output_res), dtype=np.float32)\n    hm_c = np.zeros((num_classes, output_res, output_res), dtype=np.float32)\n    reg_t = np.zeros((self.max_objs, 2), dtype=np.float32)\n    reg_l = np.zeros((self.max_objs, 2), dtype=np.float32)\n    reg_b = np.zeros((self.max_objs, 2), dtype=np.float32)\n    reg_r = np.zeros((self.max_objs, 2), dtype=np.float32)\n    ind_t = np.zeros((self.max_objs), dtype=np.int64)\n    ind_l = np.zeros((self.max_objs), dtype=np.int64)\n    ind_b = np.zeros((self.max_objs), dtype=np.int64)\n    ind_r = np.zeros((self.max_objs), dtype=np.int64)\n    reg_mask = np.zeros((self.max_objs), dtype=np.uint8)\n    \n    ann_ids = self.coco.getAnnIds(imgIds=[img_id])\n    anns = self.coco.loadAnns(ids=ann_ids)\n    num_objs = min(len(anns), self.max_objs)\n    draw_gaussian = draw_msra_gaussian if self.opt.mse_loss else \\\n                    draw_umich_gaussian\n\n    for k in range(num_objs):\n      ann = anns[k]\n      # bbox = self._coco_box_to_bbox(ann['bbox'])\n      # tlbr\n      pts = np.array(ann['extreme_points'], dtype=np.float32).reshape(4, 2)\n      # cls_id = int(self.cat_ids[ann['category_id']] - 1) # bug\n      cls_id = int(self.cat_ids[ann['category_id']])\n      hm_id = 0 if self.opt.agnostic_ex else cls_id\n      if flipped:\n        pts[:, 0] = width - pts[:, 0] - 1\n        pts[1], pts[3] = pts[3].copy(), pts[1].copy()\n      for j in range(4):\n        pts[j] = affine_transform(pts[j], trans_output)\n      pts = np.clip(pts, 0, self.opt.output_res - 1)\n      h, w = pts[2, 1] - pts[0, 1], pts[3, 0] - pts[1, 0]\n      if h > 0 and w > 0:\n        radius = gaussian_radius((math.ceil(h), math.ceil(w)))\n        radius = max(0, int(radius))\n        pt_int = pts.astype(np.int32)\n        draw_gaussian(hm_t[hm_id], pt_int[0], radius)\n        draw_gaussian(hm_l[hm_id], pt_int[1], radius)\n        draw_gaussian(hm_b[hm_id], pt_int[2], radius)\n        draw_gaussian(hm_r[hm_id], pt_int[3], radius)\n        reg_t[k] = pts[0] - pt_int[0]\n        reg_l[k] = pts[1] - pt_int[1]\n        reg_b[k] = pts[2] - pt_int[2]\n        reg_r[k] = pts[3] - pt_int[3]\n        ind_t[k] = pt_int[0, 1] * output_res + pt_int[0, 0]\n        ind_l[k] = pt_int[1, 1] * output_res + pt_int[1, 0]\n        ind_b[k] = pt_int[2, 1] * output_res + pt_int[2, 0]\n        ind_r[k] = pt_int[3, 1] * output_res + pt_int[3, 0]\n\n        ct = [int((pts[3, 0] + pts[1, 0]) / 2), int((pts[0, 1] + pts[2, 1]) / 2)]\n        draw_gaussian(hm_c[cls_id], ct, radius)\n        reg_mask[k] = 1\n    ret = {'input': inp, 'hm_t': hm_t, 'hm_l': hm_l, 'hm_b': hm_b, \n            'hm_r': hm_r, 'hm_c': hm_c}\n    if self.opt.reg_offset:\n      ret.update({'reg_mask': reg_mask,\n        'reg_t': reg_t, 'reg_l': reg_l, 'reg_b': reg_b, 'reg_r': reg_r,\n        'ind_t': ind_t, 'ind_l': ind_l, 'ind_b': ind_b, 'ind_r': ind_r})\n    \n    return ret"
  },
  {
    "path": "src/lib/datasets/sample/multi_pose.py",
    "content": "from __future__ import absolute_import\nfrom __future__ import division\nfrom __future__ import print_function\n\nimport torch.utils.data as data\nimport numpy as np\nimport torch\nimport json\nimport cv2\nimport os\nfrom utils.image import flip, color_aug\nfrom utils.image import get_affine_transform, affine_transform\nfrom utils.image import gaussian_radius, draw_umich_gaussian, draw_msra_gaussian\nfrom utils.image import draw_dense_reg\nimport math\n\nclass MultiPoseDataset(data.Dataset):\n  def _coco_box_to_bbox(self, box):\n    bbox = np.array([box[0], box[1], box[0] + box[2], box[1] + box[3]],\n                    dtype=np.float32)\n    return bbox\n\n  def _get_border(self, border, size):\n    i = 1\n    while size - border // i <= border // i:\n        i *= 2\n    return border // i\n\n  def __getitem__(self, index):\n    img_id = self.images[index]\n    file_name = self.coco.loadImgs(ids=[img_id])[0]['file_name']\n    img_path = os.path.join(self.img_dir, file_name)\n    ann_ids = self.coco.getAnnIds(imgIds=[img_id])\n    anns = self.coco.loadAnns(ids=ann_ids)\n    num_objs = min(len(anns), self.max_objs)\n\n    img = cv2.imread(img_path)\n\n    height, width = img.shape[0], img.shape[1]\n    c = np.array([img.shape[1] / 2., img.shape[0] / 2.], dtype=np.float32)\n    s = max(img.shape[0], img.shape[1]) * 1.0\n    rot = 0\n\n    flipped = False\n    if self.split == 'train':\n      if not self.opt.not_rand_crop:\n        s = s * np.random.choice(np.arange(0.6, 1.4, 0.1))\n        w_border = self._get_border(128, img.shape[1])\n        h_border = self._get_border(128, img.shape[0])\n        c[0] = np.random.randint(low=w_border, high=img.shape[1] - w_border)\n        c[1] = np.random.randint(low=h_border, high=img.shape[0] - h_border)\n      else:\n        sf = self.opt.scale\n        cf = self.opt.shift\n        c[0] += s * np.clip(np.random.randn()*cf, -2*cf, 2*cf)\n        c[1] += s * np.clip(np.random.randn()*cf, -2*cf, 2*cf)\n        s = s * np.clip(np.random.randn()*sf + 1, 1 - sf, 1 + sf)\n      if np.random.random() < self.opt.aug_rot:\n        rf = self.opt.rotate\n        rot = np.clip(np.random.randn()*rf, -rf*2, rf*2)\n\n      if np.random.random() < self.opt.flip:\n        flipped = True\n        img = img[:, ::-1, :]\n        c[0] =  width - c[0] - 1\n        \n\n    trans_input = get_affine_transform(\n      c, s, rot, [self.opt.input_res, self.opt.input_res])\n    inp = cv2.warpAffine(img, trans_input, \n                         (self.opt.input_res, self.opt.input_res),\n                         flags=cv2.INTER_LINEAR)\n    inp = (inp.astype(np.float32) / 255.)\n    if self.split == 'train' and not self.opt.no_color_aug:\n      color_aug(self._data_rng, inp, self._eig_val, self._eig_vec)\n    inp = (inp - self.mean) / self.std\n    inp = inp.transpose(2, 0, 1)\n\n    output_res = self.opt.output_res\n    num_joints = self.num_joints\n    trans_output_rot = get_affine_transform(c, s, rot, [output_res, output_res])\n    trans_output = get_affine_transform(c, s, 0, [output_res, output_res])\n\n    hm = np.zeros((self.num_classes, output_res, output_res), dtype=np.float32)\n    hm_hp = np.zeros((num_joints, output_res, output_res), dtype=np.float32)\n    dense_kps = np.zeros((num_joints, 2, output_res, output_res), \n                          dtype=np.float32)\n    dense_kps_mask = np.zeros((num_joints, output_res, output_res), \n                               dtype=np.float32)\n    wh = np.zeros((self.max_objs, 2), dtype=np.float32)\n    kps = np.zeros((self.max_objs, num_joints * 2), dtype=np.float32)\n    reg = np.zeros((self.max_objs, 2), dtype=np.float32)\n    ind = np.zeros((self.max_objs), dtype=np.int64)\n    reg_mask = np.zeros((self.max_objs), dtype=np.uint8)\n    kps_mask = np.zeros((self.max_objs, self.num_joints * 2), dtype=np.uint8)\n    hp_offset = np.zeros((self.max_objs * num_joints, 2), dtype=np.float32)\n    hp_ind = np.zeros((self.max_objs * num_joints), dtype=np.int64)\n    hp_mask = np.zeros((self.max_objs * num_joints), dtype=np.int64)\n\n    draw_gaussian = draw_msra_gaussian if self.opt.mse_loss else \\\n                    draw_umich_gaussian\n\n    gt_det = []\n    for k in range(num_objs):\n      ann = anns[k]\n      bbox = self._coco_box_to_bbox(ann['bbox'])\n      cls_id = int(ann['category_id']) - 1\n      pts = np.array(ann['keypoints'], np.float32).reshape(num_joints, 3)\n      if flipped:\n        bbox[[0, 2]] = width - bbox[[2, 0]] - 1\n        pts[:, 0] = width - pts[:, 0] - 1\n        for e in self.flip_idx:\n          pts[e[0]], pts[e[1]] = pts[e[1]].copy(), pts[e[0]].copy()\n      bbox[:2] = affine_transform(bbox[:2], trans_output)\n      bbox[2:] = affine_transform(bbox[2:], trans_output)\n      bbox = np.clip(bbox, 0, output_res - 1)\n      h, w = bbox[3] - bbox[1], bbox[2] - bbox[0]\n      if (h > 0 and w > 0) or (rot != 0):\n        radius = gaussian_radius((math.ceil(h), math.ceil(w)))\n        radius = self.opt.hm_gauss if self.opt.mse_loss else max(0, int(radius)) \n        ct = np.array(\n          [(bbox[0] + bbox[2]) / 2, (bbox[1] + bbox[3]) / 2], dtype=np.float32)\n        ct_int = ct.astype(np.int32)\n        wh[k] = 1. * w, 1. * h\n        ind[k] = ct_int[1] * output_res + ct_int[0]\n        reg[k] = ct - ct_int\n        reg_mask[k] = 1\n        num_kpts = pts[:, 2].sum()\n        if num_kpts == 0:\n          hm[cls_id, ct_int[1], ct_int[0]] = 0.9999\n          reg_mask[k] = 0\n\n        hp_radius = gaussian_radius((math.ceil(h), math.ceil(w)))\n        hp_radius = self.opt.hm_gauss \\\n                    if self.opt.mse_loss else max(0, int(hp_radius)) \n        for j in range(num_joints):\n          if pts[j, 2] > 0:\n            pts[j, :2] = affine_transform(pts[j, :2], trans_output_rot)\n            if pts[j, 0] >= 0 and pts[j, 0] < output_res and \\\n               pts[j, 1] >= 0 and pts[j, 1] < output_res:\n              kps[k, j * 2: j * 2 + 2] = pts[j, :2] - ct_int\n              kps_mask[k, j * 2: j * 2 + 2] = 1\n              pt_int = pts[j, :2].astype(np.int32)\n              hp_offset[k * num_joints + j] = pts[j, :2] - pt_int\n              hp_ind[k * num_joints + j] = pt_int[1] * output_res + pt_int[0]\n              hp_mask[k * num_joints + j] = 1\n              if self.opt.dense_hp:\n                # must be before draw center hm gaussian\n                draw_dense_reg(dense_kps[j], hm[cls_id], ct_int, \n                               pts[j, :2] - ct_int, radius, is_offset=True)\n                draw_gaussian(dense_kps_mask[j], ct_int, radius)\n              draw_gaussian(hm_hp[j], pt_int, hp_radius)\n        draw_gaussian(hm[cls_id], ct_int, radius)\n        gt_det.append([ct[0] - w / 2, ct[1] - h / 2, \n                       ct[0] + w / 2, ct[1] + h / 2, 1] + \n                       pts[:, :2].reshape(num_joints * 2).tolist() + [cls_id])\n    if rot != 0:\n      hm = hm * 0 + 0.9999\n      reg_mask *= 0\n      kps_mask *= 0\n    ret = {'input': inp, 'hm': hm, 'reg_mask': reg_mask, 'ind': ind, 'wh': wh,\n           'hps': kps, 'hps_mask': kps_mask}\n    if self.opt.dense_hp:\n      dense_kps = dense_kps.reshape(num_joints * 2, output_res, output_res)\n      dense_kps_mask = dense_kps_mask.reshape(\n        num_joints, 1, output_res, output_res)\n      dense_kps_mask = np.concatenate([dense_kps_mask, dense_kps_mask], axis=1)\n      dense_kps_mask = dense_kps_mask.reshape(\n        num_joints * 2, output_res, output_res)\n      ret.update({'dense_hps': dense_kps, 'dense_hps_mask': dense_kps_mask})\n      del ret['hps'], ret['hps_mask']\n    if self.opt.reg_offset:\n      ret.update({'reg': reg})\n    if self.opt.hm_hp:\n      ret.update({'hm_hp': hm_hp})\n    if self.opt.reg_hp_offset:\n      ret.update({'hp_offset': hp_offset, 'hp_ind': hp_ind, 'hp_mask': hp_mask})\n    if self.opt.debug > 0 or not self.split == 'train':\n      gt_det = np.array(gt_det, dtype=np.float32) if len(gt_det) > 0 else \\\n               np.zeros((1, 40), dtype=np.float32)\n      meta = {'c': c, 's': s, 'gt_det': gt_det, 'img_id': img_id}\n      ret['meta'] = meta\n    return ret\n"
  },
  {
    "path": "src/lib/detectors/base_detector.py",
    "content": "from __future__ import absolute_import\nfrom __future__ import division\nfrom __future__ import print_function\n\nimport cv2\nimport numpy as np\nfrom progress.bar import Bar\nimport time\nimport torch\n\nfrom models.model import create_model, load_model\nfrom utils.image import get_affine_transform\nfrom utils.debugger import Debugger\n\n\nclass BaseDetector(object):\n  def __init__(self, opt):\n    if opt.gpus[0] >= 0:\n      opt.device = torch.device('cuda')\n    else:\n      opt.device = torch.device('cpu')\n    \n    print('Creating model...')\n    self.model = create_model(opt.arch, opt.heads, opt.head_conv)\n    self.model = load_model(self.model, opt.load_model)\n    self.model = self.model.to(opt.device)\n    self.model.eval()\n\n    self.mean = np.array(opt.mean, dtype=np.float32).reshape(1, 1, 3)\n    self.std = np.array(opt.std, dtype=np.float32).reshape(1, 1, 3)\n    self.max_per_image = 100\n    self.num_classes = opt.num_classes\n    self.scales = opt.test_scales\n    self.opt = opt\n    self.pause = True\n\n  def pre_process(self, image, scale, meta=None):\n    height, width = image.shape[0:2]\n    new_height = int(height * scale)\n    new_width  = int(width * scale)\n    if self.opt.fix_res:\n      inp_height, inp_width = self.opt.input_h, self.opt.input_w\n      c = np.array([new_width / 2., new_height / 2.], dtype=np.float32)\n      s = max(height, width) * 1.0\n    else:\n      inp_height = (new_height | self.opt.pad) + 1\n      inp_width = (new_width | self.opt.pad) + 1\n      c = np.array([new_width // 2, new_height // 2], dtype=np.float32)\n      s = np.array([inp_width, inp_height], dtype=np.float32)\n\n    trans_input = get_affine_transform(c, s, 0, [inp_width, inp_height])\n    resized_image = cv2.resize(image, (new_width, new_height))\n    inp_image = cv2.warpAffine(\n      resized_image, trans_input, (inp_width, inp_height),\n      flags=cv2.INTER_LINEAR)\n    inp_image = ((inp_image / 255. - self.mean) / self.std).astype(np.float32)\n\n    images = inp_image.transpose(2, 0, 1).reshape(1, 3, inp_height, inp_width)\n    if self.opt.flip_test:\n      images = np.concatenate((images, images[:, :, :, ::-1]), axis=0)\n    images = torch.from_numpy(images)\n    meta = {'c': c, 's': s, \n            'out_height': inp_height // self.opt.down_ratio, \n            'out_width': inp_width // self.opt.down_ratio}\n    return images, meta\n\n  def process(self, images, return_time=False):\n    raise NotImplementedError\n\n  def post_process(self, dets, meta, scale=1):\n    raise NotImplementedError\n\n  def merge_outputs(self, detections):\n    raise NotImplementedError\n\n  def debug(self, debugger, images, dets, output, scale=1):\n    raise NotImplementedError\n\n  def show_results(self, debugger, image, results):\n   raise NotImplementedError\n\n  def run(self, image_or_path_or_tensor, meta=None):\n    load_time, pre_time, net_time, dec_time, post_time = 0, 0, 0, 0, 0\n    merge_time, tot_time = 0, 0\n    debugger = Debugger(dataset=self.opt.dataset, ipynb=(self.opt.debug==3),\n                        theme=self.opt.debugger_theme)\n    start_time = time.time()\n    pre_processed = False\n    if isinstance(image_or_path_or_tensor, np.ndarray):\n      image = image_or_path_or_tensor\n    elif type(image_or_path_or_tensor) == type (''): \n      image = cv2.imread(image_or_path_or_tensor)\n    else:\n      image = image_or_path_or_tensor['image'][0].numpy()\n      pre_processed_images = image_or_path_or_tensor\n      pre_processed = True\n    \n    loaded_time = time.time()\n    load_time += (loaded_time - start_time)\n    \n    detections = []\n    for scale in self.scales:\n      scale_start_time = time.time()\n      if not pre_processed:\n        images, meta = self.pre_process(image, scale, meta)\n      else:\n        # import pdb; pdb.set_trace()\n        images = pre_processed_images['images'][scale][0]\n        meta = pre_processed_images['meta'][scale]\n        meta = {k: v.numpy()[0] for k, v in meta.items()}\n      images = images.to(self.opt.device)\n      torch.cuda.synchronize()\n      pre_process_time = time.time()\n      pre_time += pre_process_time - scale_start_time\n      \n      output, dets, forward_time = self.process(images, return_time=True)\n\n      torch.cuda.synchronize()\n      net_time += forward_time - pre_process_time\n      decode_time = time.time()\n      dec_time += decode_time - forward_time\n      \n      if self.opt.debug >= 2:\n        self.debug(debugger, images, dets, output, scale)\n      \n      dets = self.post_process(dets, meta, scale)\n      torch.cuda.synchronize()\n      post_process_time = time.time()\n      post_time += post_process_time - decode_time\n\n      detections.append(dets)\n    \n    results = self.merge_outputs(detections)\n    torch.cuda.synchronize()\n    end_time = time.time()\n    merge_time += end_time - post_process_time\n    tot_time += end_time - start_time\n\n    if self.opt.debug >= 1:\n      self.show_results(debugger, image, results)\n    \n    return {'results': results, 'tot': tot_time, 'load': load_time,\n            'pre': pre_time, 'net': net_time, 'dec': dec_time,\n            'post': post_time, 'merge': merge_time}"
  },
  {
    "path": "src/lib/detectors/ctdet.py",
    "content": "from __future__ import absolute_import\nfrom __future__ import division\nfrom __future__ import print_function\n\nimport cv2\nimport numpy as np\nfrom progress.bar import Bar\nimport time\nimport torch\n\ntry:\n  from external.nms import soft_nms\nexcept:\n  print('NMS not imported! If you need it,'\n        ' do \\n cd $CenterNet_ROOT/src/lib/external \\n make')\nfrom models.decode import ctdet_decode\nfrom models.utils import flip_tensor\nfrom utils.image import get_affine_transform\nfrom utils.post_process import ctdet_post_process\nfrom utils.debugger import Debugger\n\nfrom .base_detector import BaseDetector\n\nclass CtdetDetector(BaseDetector):\n  def __init__(self, opt):\n    super(CtdetDetector, self).__init__(opt)\n  \n  def process(self, images, return_time=False):\n    with torch.no_grad():\n      output = self.model(images)[-1]\n      hm = output['hm'].sigmoid_()\n      wh = output['wh']\n      reg = output['reg'] if self.opt.reg_offset else None\n      if self.opt.flip_test:\n        hm = (hm[0:1] + flip_tensor(hm[1:2])) / 2\n        wh = (wh[0:1] + flip_tensor(wh[1:2])) / 2\n        reg = reg[0:1] if reg is not None else None\n      torch.cuda.synchronize()\n      forward_time = time.time()\n      dets = ctdet_decode(hm, wh, reg=reg, cat_spec_wh=self.opt.cat_spec_wh, K=self.opt.K)\n      \n    if return_time:\n      return output, dets, forward_time\n    else:\n      return output, dets\n\n  def post_process(self, dets, meta, scale=1):\n    dets = dets.detach().cpu().numpy()\n    dets = dets.reshape(1, -1, dets.shape[2])\n    dets = ctdet_post_process(\n        dets.copy(), [meta['c']], [meta['s']],\n        meta['out_height'], meta['out_width'], self.opt.num_classes)\n    for j in range(1, self.num_classes + 1):\n      dets[0][j] = np.array(dets[0][j], dtype=np.float32).reshape(-1, 5)\n      dets[0][j][:, :4] /= scale\n    return dets[0]\n\n  def merge_outputs(self, detections):\n    results = {}\n    for j in range(1, self.num_classes + 1):\n      results[j] = np.concatenate(\n        [detection[j] for detection in detections], axis=0).astype(np.float32)\n      if len(self.scales) > 1 or self.opt.nms:\n         soft_nms(results[j], Nt=0.5, method=2)\n    scores = np.hstack(\n      [results[j][:, 4] for j in range(1, self.num_classes + 1)])\n    if len(scores) > self.max_per_image:\n      kth = len(scores) - self.max_per_image\n      thresh = np.partition(scores, kth)[kth]\n      for j in range(1, self.num_classes + 1):\n        keep_inds = (results[j][:, 4] >= thresh)\n        results[j] = results[j][keep_inds]\n    return results\n\n  def debug(self, debugger, images, dets, output, scale=1):\n    detection = dets.detach().cpu().numpy().copy()\n    detection[:, :, :4] *= self.opt.down_ratio\n    for i in range(1):\n      img = images[i].detach().cpu().numpy().transpose(1, 2, 0)\n      img = ((img * self.std + self.mean) * 255).astype(np.uint8)\n      pred = debugger.gen_colormap(output['hm'][i].detach().cpu().numpy())\n      debugger.add_blend_img(img, pred, 'pred_hm_{:.1f}'.format(scale))\n      debugger.add_img(img, img_id='out_pred_{:.1f}'.format(scale))\n      for k in range(len(dets[i])):\n        if detection[i, k, 4] > self.opt.center_thresh:\n          debugger.add_coco_bbox(detection[i, k, :4], detection[i, k, -1],\n                                 detection[i, k, 4], \n                                 img_id='out_pred_{:.1f}'.format(scale))\n\n  def show_results(self, debugger, image, results):\n    debugger.add_img(image, img_id='ctdet')\n    for j in range(1, self.num_classes + 1):\n      for bbox in results[j]:\n        if bbox[4] > self.opt.vis_thresh:\n          debugger.add_coco_bbox(bbox[:4], j - 1, bbox[4], img_id='ctdet')\n    debugger.show_all_imgs(pause=self.pause)\n"
  },
  {
    "path": "src/lib/detectors/ddd.py",
    "content": "from __future__ import absolute_import\nfrom __future__ import division\nfrom __future__ import print_function\n\nimport cv2\nimport numpy as np\nfrom progress.bar import Bar\nimport time\nimport torch\n\n\nfrom models.decode import ddd_decode\nfrom models.utils import flip_tensor\nfrom utils.image import get_affine_transform\nfrom utils.post_process import ddd_post_process\nfrom utils.debugger import Debugger\nfrom utils.ddd_utils import compute_box_3d, project_to_image, alpha2rot_y\nfrom utils.ddd_utils import draw_box_3d, unproject_2d_to_3d\n\nfrom .base_detector import BaseDetector\n\nclass DddDetector(BaseDetector):\n  def __init__(self, opt):\n    super(DddDetector, self).__init__(opt)\n    self.calib = np.array([[707.0493, 0, 604.0814, 45.75831],\n                           [0, 707.0493, 180.5066, -0.3454157],\n                           [0, 0, 1., 0.004981016]], dtype=np.float32)\n\n\n  def pre_process(self, image, scale, calib=None):\n    height, width = image.shape[0:2]\n    \n    inp_height, inp_width = self.opt.input_h, self.opt.input_w\n    c = np.array([width / 2, height / 2], dtype=np.float32)\n    if self.opt.keep_res:\n      s = np.array([inp_width, inp_height], dtype=np.int32)\n    else:\n      s = np.array([width, height], dtype=np.int32)\n\n    trans_input = get_affine_transform(c, s, 0, [inp_width, inp_height])\n    resized_image = image #cv2.resize(image, (width, height))\n    inp_image = cv2.warpAffine(\n      resized_image, trans_input, (inp_width, inp_height),\n      flags=cv2.INTER_LINEAR)\n    inp_image = (inp_image.astype(np.float32) / 255.)\n    inp_image = (inp_image - self.mean) / self.std\n    images = inp_image.transpose(2, 0, 1)[np.newaxis, ...]\n    calib = np.array(calib, dtype=np.float32) if calib is not None \\\n            else self.calib\n    images = torch.from_numpy(images)\n    meta = {'c': c, 's': s, \n            'out_height': inp_height // self.opt.down_ratio, \n            'out_width': inp_width // self.opt.down_ratio,\n            'calib': calib}\n    return images, meta\n  \n  def process(self, images, return_time=False):\n    with torch.no_grad():\n      torch.cuda.synchronize()\n      output = self.model(images)[-1]\n      output['hm'] = output['hm'].sigmoid_()\n      output['dep'] = 1. / (output['dep'].sigmoid() + 1e-6) - 1.\n      wh = output['wh'] if self.opt.reg_bbox else None\n      reg = output['reg'] if self.opt.reg_offset else None\n      torch.cuda.synchronize()\n      forward_time = time.time()\n      \n      dets = ddd_decode(output['hm'], output['rot'], output['dep'],\n                          output['dim'], wh=wh, reg=reg, K=self.opt.K)\n    if return_time:\n      return output, dets, forward_time\n    else:\n      return output, dets\n\n  def post_process(self, dets, meta, scale=1):\n    dets = dets.detach().cpu().numpy()\n    detections = ddd_post_process(\n      dets.copy(), [meta['c']], [meta['s']], [meta['calib']], self.opt)\n    self.this_calib = meta['calib']\n    return detections[0]\n\n  def merge_outputs(self, detections):\n    results = detections[0]\n    for j in range(1, self.num_classes + 1):\n      if len(results[j] > 0):\n        keep_inds = (results[j][:, -1] > self.opt.peak_thresh)\n        results[j] = results[j][keep_inds]\n    return results\n\n  def debug(self, debugger, images, dets, output, scale=1):\n    dets = dets.detach().cpu().numpy()\n    img = images[0].detach().cpu().numpy().transpose(1, 2, 0)\n    img = ((img * self.std + self.mean) * 255).astype(np.uint8)\n    pred = debugger.gen_colormap(output['hm'][0].detach().cpu().numpy())\n    debugger.add_blend_img(img, pred, 'pred_hm')\n    debugger.add_ct_detection(\n      img, dets[0], show_box=self.opt.reg_bbox, \n      center_thresh=self.opt.vis_thresh, img_id='det_pred')\n  \n  def show_results(self, debugger, image, results):\n    debugger.add_3d_detection(\n      image, results, self.this_calib,\n      center_thresh=self.opt.vis_thresh, img_id='add_pred')\n    debugger.add_bird_view(\n      results, center_thresh=self.opt.vis_thresh, img_id='bird_pred')\n    debugger.show_all_imgs(pause=self.pause)"
  },
  {
    "path": "src/lib/detectors/detector_factory.py",
    "content": "from __future__ import absolute_import\nfrom __future__ import division\nfrom __future__ import print_function\n\nfrom .exdet import ExdetDetector\nfrom .ddd import DddDetector\nfrom .ctdet import CtdetDetector\nfrom .multi_pose import MultiPoseDetector\n\ndetector_factory = {\n  'exdet': ExdetDetector, \n  'ddd': DddDetector,\n  'ctdet': CtdetDetector,\n  'multi_pose': MultiPoseDetector, \n}\n"
  },
  {
    "path": "src/lib/detectors/exdet.py",
    "content": "from __future__ import absolute_import\nfrom __future__ import division\nfrom __future__ import print_function\n\nimport _init_paths\n\nimport os\n\nimport cv2\nimport numpy as np\nfrom progress.bar import Bar\nimport time\nimport torch\n\nfrom models.decode import exct_decode, agnex_ct_decode\nfrom models.utils import flip_tensor\nfrom utils.image import get_affine_transform, transform_preds\nfrom utils.post_process import ctdet_post_process\nfrom utils.debugger import Debugger\n\nfrom .base_detector import BaseDetector\n\nclass ExdetDetector(BaseDetector):\n  def __init__(self, opt):\n    super(ExdetDetector, self).__init__(opt)\n    self.decode = agnex_ct_decode if opt.agnostic_ex else exct_decode\n\n  def process(self, images, return_time=False):\n    with torch.no_grad():\n      torch.cuda.synchronize()\n      output = self.model(images)[-1]\n      t_heat = output['hm_t'].sigmoid_()\n      l_heat = output['hm_l'].sigmoid_()\n      b_heat = output['hm_b'].sigmoid_()\n      r_heat = output['hm_r'].sigmoid_()\n      c_heat = output['hm_c'].sigmoid_()\n      torch.cuda.synchronize()\n      forward_time = time.time()\n      if self.opt.reg_offset:\n        dets = self.decode(t_heat, l_heat, b_heat, r_heat, c_heat, \n                      output['reg_t'], output['reg_l'],\n                      output['reg_b'], output['reg_r'], \n                      K=self.opt.K,\n                      scores_thresh=self.opt.scores_thresh,\n                      center_thresh=self.opt.center_thresh,\n                      aggr_weight=self.opt.aggr_weight)\n      else:\n        dets = self.decode(t_heat, l_heat, b_heat, r_heat, c_heat, K=self.opt.K,\n                      scores_thresh=self.opt.scores_thresh,\n                      center_thresh=self.opt.center_thresh,\n                      aggr_weight=self.opt.aggr_weight)\n    if return_time:\n      return output, dets, forward_time\n    else:\n      return output, dets\n\n  def debug(self, debugger, images, dets, output, scale=1):\n    detection = dets.detach().cpu().numpy().copy()\n    detection[:, :, :4] *= self.opt.down_ratio\n    for i in range(1):\n      inp_height, inp_width = images.shape[2], images.shape[3]\n      pred_hm = np.zeros((inp_height, inp_width, 3), dtype=np.uint8)\n      img = images[i].detach().cpu().numpy().transpose(1, 2, 0)\n      img = ((img * self.std + self.mean) * 255).astype(np.uint8)\n      parts = ['t', 'l', 'b', 'r', 'c']\n      for p in parts:\n        tag = 'hm_{}'.format(p)\n        pred = debugger.gen_colormap(\n          output[tag][i].detach().cpu().numpy(), (inp_height, inp_width))\n        if p != 'c':\n          pred_hm = np.maximum(pred_hm, pred)\n        else:\n          debugger.add_blend_img(\n            img, pred, 'pred_{}_{:.1f}'.format(p, scale))\n      debugger.add_blend_img(img, pred_hm, 'pred_{:.1f}'.format(scale))\n      debugger.add_img(img, img_id='out_{:.1f}'.format(scale))\n      for k in range(len(detection[i])):\n        # print('detection', detection[i, k, 4], detection[i, k])\n        if detection[i, k, 4] > 0.01:\n          # print('detection', detection[i, k, 4], detection[i, k])\n          debugger.add_coco_bbox(detection[i, k, :4], detection[i, k, -1],\n                                 detection[i, k, 4], \n                                 img_id='out_{:.1f}'.format(scale))\n\n  def post_process(self, dets, meta, scale=1):\n    out_width, out_height = meta['out_width'], meta['out_height']\n    dets = dets.detach().cpu().numpy().reshape(2, -1, 14)\n    dets[1, :, [0, 2]] = out_width - dets[1, :, [2, 0]]\n    dets = dets.reshape(1, -1, 14)\n    dets[0, :, 0:2] = transform_preds(\n      dets[0, :, 0:2], meta['c'], meta['s'], (out_width, out_height))\n    dets[0, :, 2:4] = transform_preds(\n      dets[0, :, 2:4], meta['c'], meta['s'], (out_width, out_height))\n    dets[:, :, 0:4] /= scale\n    return dets[0]\n\n  def merge_outputs(self, detections):\n    detections = np.concatenate(\n        [detection for detection in detections], axis=0).astype(np.float32)\n    classes = detections[..., -1]\n    keep_inds = (detections[:, 4] > 0)\n    detections = detections[keep_inds]\n    classes = classes[keep_inds]\n\n    results = {}\n    for j in range(self.num_classes):\n      keep_inds = (classes == j)\n      results[j + 1] = detections[keep_inds][:, 0:7].astype(np.float32)\n      soft_nms(results[j + 1], Nt=0.5, method=2)\n      results[j + 1] = results[j + 1][:, 0:5]\n\n    scores = np.hstack([\n      results[j][:, -1] \n      for j in range(1, self.num_classes + 1)\n    ])\n    if len(scores) > self.max_per_image:\n      kth = len(scores) - self.max_per_image\n      thresh = np.partition(scores, kth)[kth]\n      for j in range(1, self.num_classes + 1):\n        keep_inds = (results[j][:, -1] >= thresh)\n        results[j] = results[j][keep_inds]\n    return results\n\n\n  def show_results(self, debugger, image, results):\n    debugger.add_img(image, img_id='exdet')\n    for j in range(1, self.num_classes + 1):\n      for bbox in results[j]:\n        if bbox[4] > self.opt.vis_thresh:\n          debugger.add_coco_bbox(bbox[:4], j - 1, bbox[4], img_id='exdet')\n    debugger.show_all_imgs(pause=self.pause)\n"
  },
  {
    "path": "src/lib/detectors/multi_pose.py",
    "content": "from __future__ import absolute_import\nfrom __future__ import division\nfrom __future__ import print_function\n\nimport cv2\nimport numpy as np\nfrom progress.bar import Bar\nimport time\nimport torch\n\ntry:\n  from external.nms import soft_nms_39\nexcept:\n  print('NMS not imported! If you need it,'\n        ' do \\n cd $CenterNet_ROOT/src/lib/external \\n make')\nfrom models.decode import multi_pose_decode\nfrom models.utils import flip_tensor, flip_lr_off, flip_lr\nfrom utils.image import get_affine_transform\nfrom utils.post_process import multi_pose_post_process\nfrom utils.debugger import Debugger\n\nfrom .base_detector import BaseDetector\n\nclass MultiPoseDetector(BaseDetector):\n  def __init__(self, opt):\n    super(MultiPoseDetector, self).__init__(opt)\n    self.flip_idx = opt.flip_idx\n\n  def process(self, images, return_time=False):\n    with torch.no_grad():\n      torch.cuda.synchronize()\n      output = self.model(images)[-1]\n      output['hm'] = output['hm'].sigmoid_()\n      if self.opt.hm_hp and not self.opt.mse_loss:\n        output['hm_hp'] = output['hm_hp'].sigmoid_()\n\n      reg = output['reg'] if self.opt.reg_offset else None\n      hm_hp = output['hm_hp'] if self.opt.hm_hp else None\n      hp_offset = output['hp_offset'] if self.opt.reg_hp_offset else None\n      torch.cuda.synchronize()\n      forward_time = time.time()\n      \n      if self.opt.flip_test:\n        output['hm'] = (output['hm'][0:1] + flip_tensor(output['hm'][1:2])) / 2\n        output['wh'] = (output['wh'][0:1] + flip_tensor(output['wh'][1:2])) / 2\n        output['hps'] = (output['hps'][0:1] + \n          flip_lr_off(output['hps'][1:2], self.flip_idx)) / 2\n        hm_hp = (hm_hp[0:1] + flip_lr(hm_hp[1:2], self.flip_idx)) / 2 \\\n                if hm_hp is not None else None\n        reg = reg[0:1] if reg is not None else None\n        hp_offset = hp_offset[0:1] if hp_offset is not None else None\n      \n      dets = multi_pose_decode(\n        output['hm'], output['wh'], output['hps'],\n        reg=reg, hm_hp=hm_hp, hp_offset=hp_offset, K=self.opt.K)\n\n    if return_time:\n      return output, dets, forward_time\n    else:\n      return output, dets\n\n  def post_process(self, dets, meta, scale=1):\n    dets = dets.detach().cpu().numpy().reshape(1, -1, dets.shape[2])\n    dets = multi_pose_post_process(\n      dets.copy(), [meta['c']], [meta['s']],\n      meta['out_height'], meta['out_width'])\n    for j in range(1, self.num_classes + 1):\n      dets[0][j] = np.array(dets[0][j], dtype=np.float32).reshape(-1, 39)\n      # import pdb; pdb.set_trace()\n      dets[0][j][:, :4] /= scale\n      dets[0][j][:, 5:] /= scale\n    return dets[0]\n\n  def merge_outputs(self, detections):\n    results = {}\n    results[1] = np.concatenate(\n        [detection[1] for detection in detections], axis=0).astype(np.float32)\n    if self.opt.nms or len(self.opt.test_scales) > 1:\n      soft_nms_39(results[1], Nt=0.5, method=2)\n    results[1] = results[1].tolist()\n    return results\n\n  def debug(self, debugger, images, dets, output, scale=1):\n    dets = dets.detach().cpu().numpy().copy()\n    dets[:, :, :4] *= self.opt.down_ratio\n    dets[:, :, 5:39] *= self.opt.down_ratio\n    img = images[0].detach().cpu().numpy().transpose(1, 2, 0)\n    img = np.clip(((\n      img * self.std + self.mean) * 255.), 0, 255).astype(np.uint8)\n    pred = debugger.gen_colormap(output['hm'][0].detach().cpu().numpy())\n    debugger.add_blend_img(img, pred, 'pred_hm')\n    if self.opt.hm_hp:\n      pred = debugger.gen_colormap_hp(\n        output['hm_hp'][0].detach().cpu().numpy())\n      debugger.add_blend_img(img, pred, 'pred_hmhp')\n  \n  def show_results(self, debugger, image, results):\n    debugger.add_img(image, img_id='multi_pose')\n    for bbox in results[1]:\n      if bbox[4] > self.opt.vis_thresh:\n        debugger.add_coco_bbox(bbox[:4], 0, bbox[4], img_id='multi_pose')\n        debugger.add_coco_hp(bbox[5:39], img_id='multi_pose')\n    debugger.show_all_imgs(pause=self.pause)"
  },
  {
    "path": "src/lib/external/.gitignore",
    "content": "bbox.c\nbbox.cpython-35m-x86_64-linux-gnu.so\nbbox.cpython-36m-x86_64-linux-gnu.so\n\nnms.c\nnms.cpython-35m-x86_64-linux-gnu.so\nnms.cpython-36m-x86_64-linux-gnu.so\n"
  },
  {
    "path": "src/lib/external/Makefile",
    "content": "all:\n\tpython setup.py build_ext --inplace\n\trm -rf build\n"
  },
  {
    "path": "src/lib/external/__init__.py",
    "content": ""
  },
  {
    "path": "src/lib/external/nms.pyx",
    "content": "# --------------------------------------------------------\n# Fast R-CNN\n# Copyright (c) 2015 Microsoft\n# Licensed under The MIT License [see LICENSE for details]\n# Written by Ross Girshick\n# --------------------------------------------------------\n\n# ----------------------------------------------------------\n# Soft-NMS: Improving Object Detection With One Line of Code\n# Copyright (c) University of Maryland, College Park\n# Licensed under The MIT License [see LICENSE for details]\n# Written by Navaneeth Bodla and Bharat Singh\n# ----------------------------------------------------------\n\nimport numpy as np\ncimport numpy as np\n\ncdef inline np.float32_t max(np.float32_t a, np.float32_t b):\n    return a if a >= b else b\n\ncdef inline np.float32_t min(np.float32_t a, np.float32_t b):\n    return a if a <= b else b\n\ndef nms(np.ndarray[np.float32_t, ndim=2] dets, np.float thresh):\n    cdef np.ndarray[np.float32_t, ndim=1] x1 = dets[:, 0]\n    cdef np.ndarray[np.float32_t, ndim=1] y1 = dets[:, 1]\n    cdef np.ndarray[np.float32_t, ndim=1] x2 = dets[:, 2]\n    cdef np.ndarray[np.float32_t, ndim=1] y2 = dets[:, 3]\n    cdef np.ndarray[np.float32_t, ndim=1] scores = dets[:, 4]\n\n    cdef np.ndarray[np.float32_t, ndim=1] areas = (x2 - x1 + 1) * (y2 - y1 + 1)\n    cdef np.ndarray[np.int_t, ndim=1] order = scores.argsort()[::-1]\n\n    cdef int ndets = dets.shape[0]\n    cdef np.ndarray[np.int_t, ndim=1] suppressed = \\\n            np.zeros((ndets), dtype=np.int)\n\n    # nominal indices\n    cdef int _i, _j\n    # sorted indices\n    cdef int i, j\n    # temp variables for box i's (the box currently under consideration)\n    cdef np.float32_t ix1, iy1, ix2, iy2, iarea\n    # variables for computing overlap with box j (lower scoring box)\n    cdef np.float32_t xx1, yy1, xx2, yy2\n    cdef np.float32_t w, h\n    cdef np.float32_t inter, ovr\n\n    keep = []\n    for _i in range(ndets):\n        i = order[_i]\n        if suppressed[i] == 1:\n            continue\n        keep.append(i)\n        ix1 = x1[i]\n        iy1 = y1[i]\n        ix2 = x2[i]\n        iy2 = y2[i]\n        iarea = areas[i]\n        for _j in range(_i + 1, ndets):\n            j = order[_j]\n            if suppressed[j] == 1:\n                continue\n            xx1 = max(ix1, x1[j])\n            yy1 = max(iy1, y1[j])\n            xx2 = min(ix2, x2[j])\n            yy2 = min(iy2, y2[j])\n            w = max(0.0, xx2 - xx1 + 1)\n            h = max(0.0, yy2 - yy1 + 1)\n            inter = w * h\n            ovr = inter / (iarea + areas[j] - inter)\n            if ovr >= thresh:\n                suppressed[j] = 1\n\n    return keep\n\ndef soft_nms(np.ndarray[float, ndim=2] boxes, float sigma=0.5, float Nt=0.3, float threshold=0.001, unsigned int method=0):\n    cdef unsigned int N = boxes.shape[0]\n    cdef float iw, ih, box_area\n    cdef float ua\n    cdef int pos = 0\n    cdef float maxscore = 0\n    cdef int maxpos = 0\n    cdef float x1,x2,y1,y2,tx1,tx2,ty1,ty2,ts,area,weight,ov\n\n    for i in range(N):\n        maxscore = boxes[i, 4]\n        maxpos = i\n\n        tx1 = boxes[i,0]\n        ty1 = boxes[i,1]\n        tx2 = boxes[i,2]\n        ty2 = boxes[i,3]\n        ts = boxes[i,4]\n\n        pos = i + 1\n        # get max box\n        while pos < N:\n            if maxscore < boxes[pos, 4]:\n                maxscore = boxes[pos, 4]\n                maxpos = pos\n            pos = pos + 1\n\n        # add max box as a detection \n        boxes[i,0] = boxes[maxpos,0]\n        boxes[i,1] = boxes[maxpos,1]\n        boxes[i,2] = boxes[maxpos,2]\n        boxes[i,3] = boxes[maxpos,3]\n        boxes[i,4] = boxes[maxpos,4]\n\n        # swap ith box with position of max box\n        boxes[maxpos,0] = tx1\n        boxes[maxpos,1] = ty1\n        boxes[maxpos,2] = tx2\n        boxes[maxpos,3] = ty2\n        boxes[maxpos,4] = ts\n\n        tx1 = boxes[i,0]\n        ty1 = boxes[i,1]\n        tx2 = boxes[i,2]\n        ty2 = boxes[i,3]\n        ts = boxes[i,4]\n\n        pos = i + 1\n        # NMS iterations, note that N changes if detection boxes fall below threshold\n        while pos < N:\n            x1 = boxes[pos, 0]\n            y1 = boxes[pos, 1]\n            x2 = boxes[pos, 2]\n            y2 = boxes[pos, 3]\n            s = boxes[pos, 4]\n\n            area = (x2 - x1 + 1) * (y2 - y1 + 1)\n            iw = (min(tx2, x2) - max(tx1, x1) + 1)\n            if iw > 0:\n                ih = (min(ty2, y2) - max(ty1, y1) + 1)\n                if ih > 0:\n                    ua = float((tx2 - tx1 + 1) * (ty2 - ty1 + 1) + area - iw * ih)\n                    ov = iw * ih / ua #iou between max box and detection box\n\n                    if method == 1: # linear\n                        if ov > Nt: \n                            weight = 1 - ov\n                        else:\n                            weight = 1\n                    elif method == 2: # gaussian\n                        weight = np.exp(-(ov * ov)/sigma)\n                    else: # original NMS\n                        if ov > Nt: \n                            weight = 0\n                        else:\n                            weight = 1\n\n                    boxes[pos, 4] = weight*boxes[pos, 4]\n                                \n                    # if box score falls below threshold, discard the box by swapping with last box\n                    # update N\n                    if boxes[pos, 4] < threshold:\n                        boxes[pos,0] = boxes[N-1, 0]\n                        boxes[pos,1] = boxes[N-1, 1]\n                        boxes[pos,2] = boxes[N-1, 2]\n                        boxes[pos,3] = boxes[N-1, 3]\n                        boxes[pos,4] = boxes[N-1, 4]\n                        N = N - 1\n                        pos = pos - 1\n\n            pos = pos + 1\n\n    keep = [i for i in range(N)]\n    return keep\n\ndef soft_nms_39(np.ndarray[float, ndim=2] boxes, float sigma=0.5, float Nt=0.3, float threshold=0.001, unsigned int method=0):\n    cdef unsigned int N = boxes.shape[0]\n    cdef float iw, ih, box_area\n    cdef float ua\n    cdef int pos = 0\n    cdef float maxscore = 0\n    cdef int maxpos = 0\n    cdef float x1,x2,y1,y2,tx1,tx2,ty1,ty2,ts,area,weight,ov\n    cdef float tmp\n\n    for i in range(N):\n        maxscore = boxes[i, 4]\n        maxpos = i\n\n        tx1 = boxes[i,0]\n        ty1 = boxes[i,1]\n        tx2 = boxes[i,2]\n        ty2 = boxes[i,3]\n        ts = boxes[i,4]\n\n        pos = i + 1\n        # get max box\n        while pos < N:\n            if maxscore < boxes[pos, 4]:\n                maxscore = boxes[pos, 4]\n                maxpos = pos\n            pos = pos + 1\n\n        # add max box as a detection \n        boxes[i,0] = boxes[maxpos,0]\n        boxes[i,1] = boxes[maxpos,1]\n        boxes[i,2] = boxes[maxpos,2]\n        boxes[i,3] = boxes[maxpos,3]\n        boxes[i,4] = boxes[maxpos,4]\n\n        # swap ith box with position of max box\n        boxes[maxpos,0] = tx1\n        boxes[maxpos,1] = ty1\n        boxes[maxpos,2] = tx2\n        boxes[maxpos,3] = ty2\n        boxes[maxpos,4] = ts\n\n        for j in range(5, 39):\n            tmp = boxes[i, j]\n            boxes[i, j] = boxes[maxpos, j]\n            boxes[maxpos, j] = tmp\n\n        tx1 = boxes[i,0]\n        ty1 = boxes[i,1]\n        tx2 = boxes[i,2]\n        ty2 = boxes[i,3]\n        ts = boxes[i,4]\n\n        pos = i + 1\n        # NMS iterations, note that N changes if detection boxes fall below threshold\n        while pos < N:\n            x1 = boxes[pos, 0]\n            y1 = boxes[pos, 1]\n            x2 = boxes[pos, 2]\n            y2 = boxes[pos, 3]\n            s = boxes[pos, 4]\n\n            area = (x2 - x1 + 1) * (y2 - y1 + 1)\n            iw = (min(tx2, x2) - max(tx1, x1) + 1)\n            if iw > 0:\n                ih = (min(ty2, y2) - max(ty1, y1) + 1)\n                if ih > 0:\n                    ua = float((tx2 - tx1 + 1) * (ty2 - ty1 + 1) + area - iw * ih)\n                    ov = iw * ih / ua #iou between max box and detection box\n\n                    if method == 1: # linear\n                        if ov > Nt: \n                            weight = 1 - ov\n                        else:\n                            weight = 1\n                    elif method == 2: # gaussian\n                        weight = np.exp(-(ov * ov)/sigma)\n                    else: # original NMS\n                        if ov > Nt: \n                            weight = 0\n                        else:\n                            weight = 1\n\n                    boxes[pos, 4] = weight*boxes[pos, 4]\n                                \n                    # if box score falls below threshold, discard the box by swapping with last box\n                    # update N\n                    if boxes[pos, 4] < threshold:\n                        boxes[pos,0] = boxes[N-1, 0]\n                        boxes[pos,1] = boxes[N-1, 1]\n                        boxes[pos,2] = boxes[N-1, 2]\n                        boxes[pos,3] = boxes[N-1, 3]\n                        boxes[pos,4] = boxes[N-1, 4]\n                        for j in range(5, 39):\n                            tmp = boxes[pos, j]\n                            boxes[pos, j] = boxes[N - 1, j]\n                            boxes[N - 1, j] = tmp\n                        N = N - 1\n                        pos = pos - 1\n\n            pos = pos + 1\n\n    keep = [i for i in range(N)]\n    return keep\n\ndef soft_nms_merge(np.ndarray[float, ndim=2] boxes, float sigma=0.5, float Nt=0.3, float threshold=0.001, unsigned int method=0, float weight_exp=6):\n    cdef unsigned int N = boxes.shape[0]\n    cdef float iw, ih, box_area\n    cdef float ua\n    cdef int pos = 0\n    cdef float maxscore = 0\n    cdef int maxpos = 0\n    cdef float x1,x2,y1,y2,tx1,tx2,ty1,ty2,ts,area,weight,ov\n    cdef float mx1,mx2,my1,my2,mts,mbs,mw\n\n    for i in range(N):\n        maxscore = boxes[i, 4]\n        maxpos = i\n\n        tx1 = boxes[i,0]\n        ty1 = boxes[i,1]\n        tx2 = boxes[i,2]\n        ty2 = boxes[i,3]\n        ts = boxes[i,4]\n\n        pos = i + 1\n        # get max box\n        while pos < N:\n            if maxscore < boxes[pos, 4]:\n                maxscore = boxes[pos, 4]\n                maxpos = pos\n            pos = pos + 1\n\n        # add max box as a detection \n        boxes[i,0] = boxes[maxpos,0]\n        boxes[i,1] = boxes[maxpos,1]\n        boxes[i,2] = boxes[maxpos,2]\n        boxes[i,3] = boxes[maxpos,3]\n        boxes[i,4] = boxes[maxpos,4]\n\n        mx1 = boxes[i, 0] * boxes[i, 5]\n        my1 = boxes[i, 1] * boxes[i, 5]\n        mx2 = boxes[i, 2] * boxes[i, 6]\n        my2 = boxes[i, 3] * boxes[i, 6]\n        mts = boxes[i, 5]\n        mbs = boxes[i, 6]\n\n        # swap ith box with position of max box\n        boxes[maxpos,0] = tx1\n        boxes[maxpos,1] = ty1\n        boxes[maxpos,2] = tx2\n        boxes[maxpos,3] = ty2\n        boxes[maxpos,4] = ts\n\n        tx1 = boxes[i,0]\n        ty1 = boxes[i,1]\n        tx2 = boxes[i,2]\n        ty2 = boxes[i,3]\n        ts = boxes[i,4]\n\n        pos = i + 1\n        # NMS iterations, note that N changes if detection boxes fall below threshold\n        while pos < N:\n            x1 = boxes[pos, 0]\n            y1 = boxes[pos, 1]\n            x2 = boxes[pos, 2]\n            y2 = boxes[pos, 3]\n            s = boxes[pos, 4]\n\n            area = (x2 - x1 + 1) * (y2 - y1 + 1)\n            iw = (min(tx2, x2) - max(tx1, x1) + 1)\n            if iw > 0:\n                ih = (min(ty2, y2) - max(ty1, y1) + 1)\n                if ih > 0:\n                    ua = float((tx2 - tx1 + 1) * (ty2 - ty1 + 1) + area - iw * ih)\n                    ov = iw * ih / ua #iou between max box and detection box\n\n                    if method == 1: # linear\n                        if ov > Nt: \n                            weight = 1 - ov\n                        else:\n                            weight = 1\n                    elif method == 2: # gaussian\n                        weight = np.exp(-(ov * ov)/sigma)\n                    else: # original NMS\n                        if ov > Nt: \n                            weight = 0\n                        else:\n                            weight = 1\n\n                    mw  = (1 - weight) ** weight_exp\n                    mx1 = mx1 + boxes[pos, 0] * boxes[pos, 5] * mw\n                    my1 = my1 + boxes[pos, 1] * boxes[pos, 5] * mw\n                    mx2 = mx2 + boxes[pos, 2] * boxes[pos, 6] * mw\n                    my2 = my2 + boxes[pos, 3] * boxes[pos, 6] * mw\n                    mts = mts + boxes[pos, 5] * mw\n                    mbs = mbs + boxes[pos, 6] * mw\n\n                    boxes[pos, 4] = weight*boxes[pos, 4]\n                                \n                    # if box score falls below threshold, discard the box by swapping with last box\n                    # update N\n                    if boxes[pos, 4] < threshold:\n                        boxes[pos,0] = boxes[N-1, 0]\n                        boxes[pos,1] = boxes[N-1, 1]\n                        boxes[pos,2] = boxes[N-1, 2]\n                        boxes[pos,3] = boxes[N-1, 3]\n                        boxes[pos,4] = boxes[N-1, 4]\n                        N = N - 1\n                        pos = pos - 1\n\n            pos = pos + 1\n\n        boxes[i, 0] = mx1 / mts\n        boxes[i, 1] = my1 / mts\n        boxes[i, 2] = mx2 / mbs\n        boxes[i, 3] = my2 / mbs\n\n    keep = [i for i in range(N)]\n    return keep\n"
  },
  {
    "path": "src/lib/external/setup.py",
    "content": "import numpy\nfrom distutils.core import setup\nfrom distutils.extension import Extension\nfrom Cython.Build import cythonize\n\nextensions = [\n    Extension(\n        \"nms\", \n        [\"nms.pyx\"],\n        extra_compile_args=[\"-Wno-cpp\", \"-Wno-unused-function\"]\n    )\n]\n\nsetup(\n    name=\"coco\",\n    ext_modules=cythonize(extensions),\n    include_dirs=[numpy.get_include()]\n)\n"
  },
  {
    "path": "src/lib/logger.py",
    "content": "from __future__ import absolute_import\nfrom __future__ import division\nfrom __future__ import print_function\n\n# Code referenced from https://gist.github.com/gyglim/1f8dfb1b5c82627ae3efcfbbadb9f514\nimport os\nimport time\nimport sys\nimport torch\nUSE_TENSORBOARD = True\ntry:\n  import tensorboardX\n  print('Using tensorboardX')\nexcept:\n  USE_TENSORBOARD = False\n\nclass Logger(object):\n  def __init__(self, opt):\n    \"\"\"Create a summary writer logging to log_dir.\"\"\"\n    if not os.path.exists(opt.save_dir):\n      os.makedirs(opt.save_dir)\n    if not os.path.exists(opt.debug_dir):\n      os.makedirs(opt.debug_dir)\n   \n    time_str = time.strftime('%Y-%m-%d-%H-%M')\n\n    args = dict((name, getattr(opt, name)) for name in dir(opt)\n                if not name.startswith('_'))\n    file_name = os.path.join(opt.save_dir, 'opt.txt')\n    with open(file_name, 'wt') as opt_file:\n      opt_file.write('==> torch version: {}\\n'.format(torch.__version__))\n      opt_file.write('==> cudnn version: {}\\n'.format(\n        torch.backends.cudnn.version()))\n      opt_file.write('==> Cmd:\\n')\n      opt_file.write(str(sys.argv))\n      opt_file.write('\\n==> Opt:\\n')\n      for k, v in sorted(args.items()):\n        opt_file.write('  %s: %s\\n' % (str(k), str(v)))\n          \n    log_dir = opt.save_dir + '/logs_{}'.format(time_str)\n    if USE_TENSORBOARD:\n      self.writer = tensorboardX.SummaryWriter(log_dir=log_dir)\n    else:\n      if not os.path.exists(os.path.dirname(log_dir)):\n        os.mkdir(os.path.dirname(log_dir))\n      if not os.path.exists(log_dir):\n        os.mkdir(log_dir)\n    self.log = open(log_dir + '/log.txt', 'w')\n    try:\n      os.system('cp {}/opt.txt {}/'.format(opt.save_dir, log_dir))\n    except:\n      pass\n    self.start_line = True\n\n  def write(self, txt):\n    if self.start_line:\n      time_str = time.strftime('%Y-%m-%d-%H-%M')\n      self.log.write('{}: {}'.format(time_str, txt))\n    else:\n      self.log.write(txt)  \n    self.start_line = False\n    if '\\n' in txt:\n      self.start_line = True\n      self.log.flush()\n  \n  def close(self):\n    self.log.close()\n  \n  def scalar_summary(self, tag, value, step):\n    \"\"\"Log a scalar variable.\"\"\"\n    if USE_TENSORBOARD:\n      self.writer.add_scalar(tag, value, step)\n"
  },
  {
    "path": "src/lib/models/data_parallel.py",
    "content": "import torch\nfrom torch.nn.modules import Module\nfrom torch.nn.parallel.scatter_gather import gather\nfrom torch.nn.parallel.replicate import replicate\nfrom torch.nn.parallel.parallel_apply import parallel_apply\n\n\nfrom .scatter_gather import scatter_kwargs\n\nclass _DataParallel(Module):\n    r\"\"\"Implements data parallelism at the module level.\n\n    This container parallelizes the application of the given module by\n    splitting the input across the specified devices by chunking in the batch\n    dimension. In the forward pass, the module is replicated on each device,\n    and each replica handles a portion of the input. During the backwards\n    pass, gradients from each replica are summed into the original module.\n\n    The batch size should be larger than the number of GPUs used. It should\n    also be an integer multiple of the number of GPUs so that each chunk is the\n    same size (so that each GPU processes the same number of samples).\n\n    See also: :ref:`cuda-nn-dataparallel-instead`\n\n    Arbitrary positional and keyword inputs are allowed to be passed into\n    DataParallel EXCEPT Tensors. All variables will be scattered on dim\n    specified (default 0). Primitive types will be broadcasted, but all\n    other types will be a shallow copy and can be corrupted if written to in\n    the model's forward pass.\n\n    Args:\n        module: module to be parallelized\n        device_ids: CUDA devices (default: all devices)\n        output_device: device location of output (default: device_ids[0])\n\n    Example::\n\n        >>> net = torch.nn.DataParallel(model, device_ids=[0, 1, 2])\n        >>> output = net(input_var)\n    \"\"\"\n\n    # TODO: update notes/cuda.rst when this class handles 8+ GPUs well\n\n    def __init__(self, module, device_ids=None, output_device=None, dim=0, chunk_sizes=None):\n        super(_DataParallel, self).__init__()\n\n        if not torch.cuda.is_available():\n            self.module = module\n            self.device_ids = []\n            return\n\n        if device_ids is None:\n            device_ids = list(range(torch.cuda.device_count()))\n        if output_device is None:\n            output_device = device_ids[0]\n        self.dim = dim\n        self.module = module\n        self.device_ids = device_ids\n        self.chunk_sizes = chunk_sizes\n        self.output_device = output_device\n        if len(self.device_ids) == 1:\n            self.module.cuda(device_ids[0])\n\n    def forward(self, *inputs, **kwargs):\n        if not self.device_ids:\n            return self.module(*inputs, **kwargs)\n        inputs, kwargs = self.scatter(inputs, kwargs, self.device_ids, self.chunk_sizes)\n        if len(self.device_ids) == 1:\n            return self.module(*inputs[0], **kwargs[0])\n        replicas = self.replicate(self.module, self.device_ids[:len(inputs)])\n        outputs = self.parallel_apply(replicas, inputs, kwargs)\n        return self.gather(outputs, self.output_device)\n\n    def replicate(self, module, device_ids):\n        return replicate(module, device_ids)\n\n    def scatter(self, inputs, kwargs, device_ids, chunk_sizes):\n        return scatter_kwargs(inputs, kwargs, device_ids, dim=self.dim, chunk_sizes=self.chunk_sizes)\n\n    def parallel_apply(self, replicas, inputs, kwargs):\n        return parallel_apply(replicas, inputs, kwargs, self.device_ids[:len(replicas)])\n\n    def gather(self, outputs, output_device):\n        return gather(outputs, output_device, dim=self.dim)\n\n\ndef data_parallel(module, inputs, device_ids=None, output_device=None, dim=0, module_kwargs=None):\n    r\"\"\"Evaluates module(input) in parallel across the GPUs given in device_ids.\n\n    This is the functional version of the DataParallel module.\n\n    Args:\n        module: the module to evaluate in parallel\n        inputs: inputs to the module\n        device_ids: GPU ids on which to replicate module\n        output_device: GPU location of the output  Use -1 to indicate the CPU.\n            (default: device_ids[0])\n    Returns:\n        a Variable containing the result of module(input) located on\n        output_device\n    \"\"\"\n    if not isinstance(inputs, tuple):\n        inputs = (inputs,)\n\n    if device_ids is None:\n        device_ids = list(range(torch.cuda.device_count()))\n\n    if output_device is None:\n        output_device = device_ids[0]\n\n    inputs, module_kwargs = scatter_kwargs(inputs, module_kwargs, device_ids, dim)\n    if len(device_ids) == 1:\n        return module(*inputs[0], **module_kwargs[0])\n    used_device_ids = device_ids[:len(inputs)]\n    replicas = replicate(module, used_device_ids)\n    outputs = parallel_apply(replicas, inputs, module_kwargs, used_device_ids)\n    return gather(outputs, output_device, dim)\n\ndef DataParallel(module, device_ids=None, output_device=None, dim=0, chunk_sizes=None):\n    if chunk_sizes is None:\n        return torch.nn.DataParallel(module, device_ids, output_device, dim)\n    standard_size = True\n    for i in range(1, len(chunk_sizes)):\n        if chunk_sizes[i] != chunk_sizes[0]:\n            standard_size = False\n    if standard_size:\n        return torch.nn.DataParallel(module, device_ids, output_device, dim)\n    return _DataParallel(module, device_ids, output_device, dim, chunk_sizes)"
  },
  {
    "path": "src/lib/models/decode.py",
    "content": "from __future__ import absolute_import\nfrom __future__ import division\nfrom __future__ import print_function\n\nimport torch\nimport torch.nn as nn\nfrom .utils import _gather_feat, _transpose_and_gather_feat\n\ndef _nms(heat, kernel=3):\n    pad = (kernel - 1) // 2\n\n    hmax = nn.functional.max_pool2d(\n        heat, (kernel, kernel), stride=1, padding=pad)\n    keep = (hmax == heat).float()\n    return heat * keep\n\ndef _left_aggregate(heat):\n    '''\n        heat: batchsize x channels x h x w\n    '''\n    shape = heat.shape \n    heat = heat.reshape(-1, heat.shape[3])\n    heat = heat.transpose(1, 0).contiguous()\n    ret = heat.clone()\n    for i in range(1, heat.shape[0]):\n        inds = (heat[i] >= heat[i - 1])\n        ret[i] += ret[i - 1] * inds.float()\n    return (ret - heat).transpose(1, 0).reshape(shape) \n\ndef _right_aggregate(heat):\n    '''\n        heat: batchsize x channels x h x w\n    '''\n    shape = heat.shape \n    heat = heat.reshape(-1, heat.shape[3])\n    heat = heat.transpose(1, 0).contiguous()\n    ret = heat.clone()\n    for i in range(heat.shape[0] - 2, -1, -1):\n        inds = (heat[i] >= heat[i +1])\n        ret[i] += ret[i + 1] * inds.float()\n    return (ret - heat).transpose(1, 0).reshape(shape) \n\ndef _top_aggregate(heat):\n    '''\n        heat: batchsize x channels x h x w\n    '''\n    heat = heat.transpose(3, 2) \n    shape = heat.shape\n    heat = heat.reshape(-1, heat.shape[3])\n    heat = heat.transpose(1, 0).contiguous()\n    ret = heat.clone()\n    for i in range(1, heat.shape[0]):\n        inds = (heat[i] >= heat[i - 1])\n        ret[i] += ret[i - 1] * inds.float()\n    return (ret - heat).transpose(1, 0).reshape(shape).transpose(3, 2)\n\ndef _bottom_aggregate(heat):\n    '''\n        heat: batchsize x channels x h x w\n    '''\n    heat = heat.transpose(3, 2) \n    shape = heat.shape\n    heat = heat.reshape(-1, heat.shape[3])\n    heat = heat.transpose(1, 0).contiguous()\n    ret = heat.clone()\n    for i in range(heat.shape[0] - 2, -1, -1):\n        inds = (heat[i] >= heat[i + 1])\n        ret[i] += ret[i + 1] * inds.float()\n    return (ret - heat).transpose(1, 0).reshape(shape).transpose(3, 2)\n\ndef _h_aggregate(heat, aggr_weight=0.1):\n    return aggr_weight * _left_aggregate(heat) + \\\n           aggr_weight * _right_aggregate(heat) + heat\n\ndef _v_aggregate(heat, aggr_weight=0.1):\n    return aggr_weight * _top_aggregate(heat) + \\\n           aggr_weight * _bottom_aggregate(heat) + heat\n\n'''\n# Slow for large number of categories\ndef _topk(scores, K=40):\n    batch, cat, height, width = scores.size()\n    topk_scores, topk_inds = torch.topk(scores.view(batch, -1), K)\n\n    topk_clses = (topk_inds / (height * width)).int()\n\n    topk_inds = topk_inds % (height * width)\n    topk_ys   = (topk_inds / width).int().float()\n    topk_xs   = (topk_inds % width).int().float()\n    return topk_scores, topk_inds, topk_clses, topk_ys, topk_xs\n'''\ndef _topk_channel(scores, K=40):\n      batch, cat, height, width = scores.size()\n      \n      topk_scores, topk_inds = torch.topk(scores.view(batch, cat, -1), K)\n\n      topk_inds = topk_inds % (height * width)\n      topk_ys   = (topk_inds / width).int().float()\n      topk_xs   = (topk_inds % width).int().float()\n\n      return topk_scores, topk_inds, topk_ys, topk_xs\n\ndef _topk(scores, K=40):\n    batch, cat, height, width = scores.size()\n      \n    topk_scores, topk_inds = torch.topk(scores.view(batch, cat, -1), K)\n\n    topk_inds = topk_inds % (height * width)\n    topk_ys   = (topk_inds / width).int().float()\n    topk_xs   = (topk_inds % width).int().float()\n      \n    topk_score, topk_ind = torch.topk(topk_scores.view(batch, -1), K)\n    topk_clses = (topk_ind / K).int()\n    topk_inds = _gather_feat(\n        topk_inds.view(batch, -1, 1), topk_ind).view(batch, K)\n    topk_ys = _gather_feat(topk_ys.view(batch, -1, 1), topk_ind).view(batch, K)\n    topk_xs = _gather_feat(topk_xs.view(batch, -1, 1), topk_ind).view(batch, K)\n\n    return topk_score, topk_inds, topk_clses, topk_ys, topk_xs\n\n\ndef agnex_ct_decode(\n    t_heat, l_heat, b_heat, r_heat, ct_heat, \n    t_regr=None, l_regr=None, b_regr=None, r_regr=None, \n    K=40, scores_thresh=0.1, center_thresh=0.1, aggr_weight=0.0, num_dets=1000\n):\n    batch, cat, height, width = t_heat.size()\n\n    '''\n    t_heat  = torch.sigmoid(t_heat)\n    l_heat  = torch.sigmoid(l_heat)\n    b_heat  = torch.sigmoid(b_heat)\n    r_heat  = torch.sigmoid(r_heat)\n    ct_heat = torch.sigmoid(ct_heat)\n    '''\n    if aggr_weight > 0: \n      t_heat = _h_aggregate(t_heat, aggr_weight=aggr_weight)\n      l_heat = _v_aggregate(l_heat, aggr_weight=aggr_weight)\n      b_heat = _h_aggregate(b_heat, aggr_weight=aggr_weight)\n      r_heat = _v_aggregate(r_heat, aggr_weight=aggr_weight)\n      \n    # perform nms on heatmaps\n    t_heat = _nms(t_heat)\n    l_heat = _nms(l_heat)\n    b_heat = _nms(b_heat)\n    r_heat = _nms(r_heat)\n      \n      \n    t_heat[t_heat > 1] = 1\n    l_heat[l_heat > 1] = 1\n    b_heat[b_heat > 1] = 1\n    r_heat[r_heat > 1] = 1\n\n    t_scores, t_inds, _, t_ys, t_xs = _topk(t_heat, K=K)\n    l_scores, l_inds, _, l_ys, l_xs = _topk(l_heat, K=K)\n    b_scores, b_inds, _, b_ys, b_xs = _topk(b_heat, K=K)\n    r_scores, r_inds, _, r_ys, r_xs = _topk(r_heat, K=K)\n      \n    ct_heat_agn, ct_clses = torch.max(ct_heat, dim=1, keepdim=True)\n      \n    # import pdb; pdb.set_trace()\n\n    t_ys = t_ys.view(batch, K, 1, 1, 1).expand(batch, K, K, K, K)\n    t_xs = t_xs.view(batch, K, 1, 1, 1).expand(batch, K, K, K, K)\n    l_ys = l_ys.view(batch, 1, K, 1, 1).expand(batch, K, K, K, K)\n    l_xs = l_xs.view(batch, 1, K, 1, 1).expand(batch, K, K, K, K)\n    b_ys = b_ys.view(batch, 1, 1, K, 1).expand(batch, K, K, K, K)\n    b_xs = b_xs.view(batch, 1, 1, K, 1).expand(batch, K, K, K, K)\n    r_ys = r_ys.view(batch, 1, 1, 1, K).expand(batch, K, K, K, K)\n    r_xs = r_xs.view(batch, 1, 1, 1, K).expand(batch, K, K, K, K)\n\n    box_ct_xs = ((l_xs + r_xs + 0.5) / 2).long()\n    box_ct_ys = ((t_ys + b_ys + 0.5) / 2).long()\n\n    ct_inds     = box_ct_ys * width + box_ct_xs\n    ct_inds     = ct_inds.view(batch, -1)\n    ct_heat_agn = ct_heat_agn.view(batch, -1, 1)\n    ct_clses    = ct_clses.view(batch, -1, 1)\n    ct_scores   = _gather_feat(ct_heat_agn, ct_inds)\n    clses       = _gather_feat(ct_clses, ct_inds)\n\n    t_scores = t_scores.view(batch, K, 1, 1, 1).expand(batch, K, K, K, K)\n    l_scores = l_scores.view(batch, 1, K, 1, 1).expand(batch, K, K, K, K)\n    b_scores = b_scores.view(batch, 1, 1, K, 1).expand(batch, K, K, K, K)\n    r_scores = r_scores.view(batch, 1, 1, 1, K).expand(batch, K, K, K, K)\n    ct_scores = ct_scores.view(batch, K, K, K, K)\n    scores    = (t_scores + l_scores + b_scores + r_scores + 2 * ct_scores) / 6\n\n    # reject boxes based on classes\n    top_inds  = (t_ys > l_ys) + (t_ys > b_ys) + (t_ys > r_ys)\n    top_inds = (top_inds > 0)\n    left_inds  = (l_xs > t_xs) + (l_xs > b_xs) + (l_xs > r_xs)\n    left_inds = (left_inds > 0)\n    bottom_inds  = (b_ys < t_ys) + (b_ys < l_ys) + (b_ys < r_ys)\n    bottom_inds = (bottom_inds > 0)\n    right_inds  = (r_xs < t_xs) + (r_xs < l_xs) + (r_xs < b_xs)\n    right_inds = (right_inds > 0)\n\n    sc_inds = (t_scores < scores_thresh) + (l_scores < scores_thresh) + \\\n              (b_scores < scores_thresh) + (r_scores < scores_thresh) + \\\n              (ct_scores < center_thresh)\n    sc_inds = (sc_inds > 0)\n\n    scores = scores - sc_inds.float()\n    scores = scores - top_inds.float()\n    scores = scores - left_inds.float()\n    scores = scores - bottom_inds.float()\n    scores = scores - right_inds.float()\n\n    scores = scores.view(batch, -1)\n    scores, inds = torch.topk(scores, num_dets)\n    scores = scores.unsqueeze(2)\n\n    if t_regr is not None and l_regr is not None \\\n      and b_regr is not None and r_regr is not None:\n        t_regr = _transpose_and_gather_feat(t_regr, t_inds)\n        t_regr = t_regr.view(batch, K, 1, 1, 1, 2)\n        l_regr = _transpose_and_gather_feat(l_regr, l_inds)\n        l_regr = l_regr.view(batch, 1, K, 1, 1, 2)\n        b_regr = _transpose_and_gather_feat(b_regr, b_inds)\n        b_regr = b_regr.view(batch, 1, 1, K, 1, 2)\n        r_regr = _transpose_and_gather_feat(r_regr, r_inds)\n        r_regr = r_regr.view(batch, 1, 1, 1, K, 2)\n\n        t_xs = t_xs + t_regr[..., 0]\n        t_ys = t_ys + t_regr[..., 1]\n        l_xs = l_xs + l_regr[..., 0]\n        l_ys = l_ys + l_regr[..., 1]\n        b_xs = b_xs + b_regr[..., 0]\n        b_ys = b_ys + b_regr[..., 1]\n        r_xs = r_xs + r_regr[..., 0]\n        r_ys = r_ys + r_regr[..., 1]\n    else:\n        t_xs = t_xs + 0.5\n        t_ys = t_ys + 0.5\n        l_xs = l_xs + 0.5\n        l_ys = l_ys + 0.5\n        b_xs = b_xs + 0.5\n        b_ys = b_ys + 0.5\n        r_xs = r_xs + 0.5\n        r_ys = r_ys + 0.5\n      \n    bboxes = torch.stack((l_xs, t_ys, r_xs, b_ys), dim=5)\n    bboxes = bboxes.view(batch, -1, 4)\n    bboxes = _gather_feat(bboxes, inds)\n\n    clses  = clses.contiguous().view(batch, -1, 1)\n    clses  = _gather_feat(clses, inds).float()\n\n    t_xs = t_xs.contiguous().view(batch, -1, 1)\n    t_xs = _gather_feat(t_xs, inds).float()\n    t_ys = t_ys.contiguous().view(batch, -1, 1)\n    t_ys = _gather_feat(t_ys, inds).float()\n    l_xs = l_xs.contiguous().view(batch, -1, 1)\n    l_xs = _gather_feat(l_xs, inds).float()\n    l_ys = l_ys.contiguous().view(batch, -1, 1)\n    l_ys = _gather_feat(l_ys, inds).float()\n    b_xs = b_xs.contiguous().view(batch, -1, 1)\n    b_xs = _gather_feat(b_xs, inds).float()\n    b_ys = b_ys.contiguous().view(batch, -1, 1)\n    b_ys = _gather_feat(b_ys, inds).float()\n    r_xs = r_xs.contiguous().view(batch, -1, 1)\n    r_xs = _gather_feat(r_xs, inds).float()\n    r_ys = r_ys.contiguous().view(batch, -1, 1)\n    r_ys = _gather_feat(r_ys, inds).float()\n\n\n    detections = torch.cat([bboxes, scores, t_xs, t_ys, l_xs, l_ys, \n                            b_xs, b_ys, r_xs, r_ys, clses], dim=2)\n\n    return detections\n\ndef exct_decode(\n    t_heat, l_heat, b_heat, r_heat, ct_heat, \n    t_regr=None, l_regr=None, b_regr=None, r_regr=None, \n    K=40, scores_thresh=0.1, center_thresh=0.1, aggr_weight=0.0, num_dets=1000\n):\n    batch, cat, height, width = t_heat.size()\n    '''\n    t_heat  = torch.sigmoid(t_heat)\n    l_heat  = torch.sigmoid(l_heat)\n    b_heat  = torch.sigmoid(b_heat)\n    r_heat  = torch.sigmoid(r_heat)\n    ct_heat = torch.sigmoid(ct_heat)\n    '''\n\n    if aggr_weight > 0:   \n      t_heat = _h_aggregate(t_heat, aggr_weight=aggr_weight)\n      l_heat = _v_aggregate(l_heat, aggr_weight=aggr_weight)\n      b_heat = _h_aggregate(b_heat, aggr_weight=aggr_weight)\n      r_heat = _v_aggregate(r_heat, aggr_weight=aggr_weight)\n      \n    # perform nms on heatmaps\n    t_heat = _nms(t_heat)\n    l_heat = _nms(l_heat)\n    b_heat = _nms(b_heat)\n    r_heat = _nms(r_heat)\n      \n    t_heat[t_heat > 1] = 1\n    l_heat[l_heat > 1] = 1\n    b_heat[b_heat > 1] = 1\n    r_heat[r_heat > 1] = 1\n\n    t_scores, t_inds, t_clses, t_ys, t_xs = _topk(t_heat, K=K)\n    l_scores, l_inds, l_clses, l_ys, l_xs = _topk(l_heat, K=K)\n    b_scores, b_inds, b_clses, b_ys, b_xs = _topk(b_heat, K=K)\n    r_scores, r_inds, r_clses, r_ys, r_xs = _topk(r_heat, K=K)\n\n    t_ys = t_ys.view(batch, K, 1, 1, 1).expand(batch, K, K, K, K)\n    t_xs = t_xs.view(batch, K, 1, 1, 1).expand(batch, K, K, K, K)\n    l_ys = l_ys.view(batch, 1, K, 1, 1).expand(batch, K, K, K, K)\n    l_xs = l_xs.view(batch, 1, K, 1, 1).expand(batch, K, K, K, K)\n    b_ys = b_ys.view(batch, 1, 1, K, 1).expand(batch, K, K, K, K)\n    b_xs = b_xs.view(batch, 1, 1, K, 1).expand(batch, K, K, K, K)\n    r_ys = r_ys.view(batch, 1, 1, 1, K).expand(batch, K, K, K, K)\n    r_xs = r_xs.view(batch, 1, 1, 1, K).expand(batch, K, K, K, K)\n\n    t_clses = t_clses.view(batch, K, 1, 1, 1).expand(batch, K, K, K, K)\n    l_clses = l_clses.view(batch, 1, K, 1, 1).expand(batch, K, K, K, K)\n    b_clses = b_clses.view(batch, 1, 1, K, 1).expand(batch, K, K, K, K)\n    r_clses = r_clses.view(batch, 1, 1, 1, K).expand(batch, K, K, K, K)\n    box_ct_xs = ((l_xs + r_xs + 0.5) / 2).long()\n    box_ct_ys = ((t_ys + b_ys + 0.5) / 2).long()\n    ct_inds = t_clses.long() * (height * width) + box_ct_ys * width + box_ct_xs\n    ct_inds = ct_inds.view(batch, -1)\n    ct_heat = ct_heat.view(batch, -1, 1)\n    ct_scores = _gather_feat(ct_heat, ct_inds)\n\n    t_scores = t_scores.view(batch, K, 1, 1, 1).expand(batch, K, K, K, K)\n    l_scores = l_scores.view(batch, 1, K, 1, 1).expand(batch, K, K, K, K)\n    b_scores = b_scores.view(batch, 1, 1, K, 1).expand(batch, K, K, K, K)\n    r_scores = r_scores.view(batch, 1, 1, 1, K).expand(batch, K, K, K, K)\n    ct_scores = ct_scores.view(batch, K, K, K, K)\n    scores    = (t_scores + l_scores + b_scores + r_scores + 2 * ct_scores) / 6\n\n    # reject boxes based on classes\n    cls_inds = (t_clses != l_clses) + (t_clses != b_clses) + \\\n               (t_clses != r_clses)\n    cls_inds = (cls_inds > 0)\n\n    top_inds  = (t_ys > l_ys) + (t_ys > b_ys) + (t_ys > r_ys)\n    top_inds = (top_inds > 0)\n    left_inds  = (l_xs > t_xs) + (l_xs > b_xs) + (l_xs > r_xs)\n    left_inds = (left_inds > 0)\n    bottom_inds  = (b_ys < t_ys) + (b_ys < l_ys) + (b_ys < r_ys)\n    bottom_inds = (bottom_inds > 0)\n    right_inds  = (r_xs < t_xs) + (r_xs < l_xs) + (r_xs < b_xs)\n    right_inds = (right_inds > 0)\n\n    sc_inds = (t_scores < scores_thresh) + (l_scores < scores_thresh) + \\\n              (b_scores < scores_thresh) + (r_scores < scores_thresh) + \\\n              (ct_scores < center_thresh)\n    sc_inds = (sc_inds > 0)\n\n    scores = scores - sc_inds.float()\n    scores = scores - cls_inds.float()\n    scores = scores - top_inds.float()\n    scores = scores - left_inds.float()\n    scores = scores - bottom_inds.float()\n    scores = scores - right_inds.float()\n\n    scores = scores.view(batch, -1)\n    scores, inds = torch.topk(scores, num_dets)\n    scores = scores.unsqueeze(2)\n\n    if t_regr is not None and l_regr is not None \\\n      and b_regr is not None and r_regr is not None:\n        t_regr = _transpose_and_gather_feat(t_regr, t_inds)\n        t_regr = t_regr.view(batch, K, 1, 1, 1, 2)\n        l_regr = _transpose_and_gather_feat(l_regr, l_inds)\n        l_regr = l_regr.view(batch, 1, K, 1, 1, 2)\n        b_regr = _transpose_and_gather_feat(b_regr, b_inds)\n        b_regr = b_regr.view(batch, 1, 1, K, 1, 2)\n        r_regr = _transpose_and_gather_feat(r_regr, r_inds)\n        r_regr = r_regr.view(batch, 1, 1, 1, K, 2)\n\n        t_xs = t_xs + t_regr[..., 0]\n        t_ys = t_ys + t_regr[..., 1]\n        l_xs = l_xs + l_regr[..., 0]\n        l_ys = l_ys + l_regr[..., 1]\n        b_xs = b_xs + b_regr[..., 0]\n        b_ys = b_ys + b_regr[..., 1]\n        r_xs = r_xs + r_regr[..., 0]\n        r_ys = r_ys + r_regr[..., 1]\n    else:\n        t_xs = t_xs + 0.5\n        t_ys = t_ys + 0.5\n        l_xs = l_xs + 0.5\n        l_ys = l_ys + 0.5\n        b_xs = b_xs + 0.5\n        b_ys = b_ys + 0.5\n        r_xs = r_xs + 0.5\n        r_ys = r_ys + 0.5\n      \n    bboxes = torch.stack((l_xs, t_ys, r_xs, b_ys), dim=5)\n    bboxes = bboxes.view(batch, -1, 4)\n    bboxes = _gather_feat(bboxes, inds)\n\n    clses  = t_clses.contiguous().view(batch, -1, 1)\n    clses  = _gather_feat(clses, inds).float()\n\n    t_xs = t_xs.contiguous().view(batch, -1, 1)\n    t_xs = _gather_feat(t_xs, inds).float()\n    t_ys = t_ys.contiguous().view(batch, -1, 1)\n    t_ys = _gather_feat(t_ys, inds).float()\n    l_xs = l_xs.contiguous().view(batch, -1, 1)\n    l_xs = _gather_feat(l_xs, inds).float()\n    l_ys = l_ys.contiguous().view(batch, -1, 1)\n    l_ys = _gather_feat(l_ys, inds).float()\n    b_xs = b_xs.contiguous().view(batch, -1, 1)\n    b_xs = _gather_feat(b_xs, inds).float()\n    b_ys = b_ys.contiguous().view(batch, -1, 1)\n    b_ys = _gather_feat(b_ys, inds).float()\n    r_xs = r_xs.contiguous().view(batch, -1, 1)\n    r_xs = _gather_feat(r_xs, inds).float()\n    r_ys = r_ys.contiguous().view(batch, -1, 1)\n    r_ys = _gather_feat(r_ys, inds).float()\n\n\n    detections = torch.cat([bboxes, scores, t_xs, t_ys, l_xs, l_ys, \n                            b_xs, b_ys, r_xs, r_ys, clses], dim=2)\n\n\n    return detections\n\ndef ddd_decode(heat, rot, depth, dim, wh=None, reg=None, K=40):\n    batch, cat, height, width = heat.size()\n    # heat = torch.sigmoid(heat)\n    # perform nms on heatmaps\n    heat = _nms(heat)\n      \n    scores, inds, clses, ys, xs = _topk(heat, K=K)\n    if reg is not None:\n      reg = _transpose_and_gather_feat(reg, inds)\n      reg = reg.view(batch, K, 2)\n      xs = xs.view(batch, K, 1) + reg[:, :, 0:1]\n      ys = ys.view(batch, K, 1) + reg[:, :, 1:2]\n    else:\n      xs = xs.view(batch, K, 1) + 0.5\n      ys = ys.view(batch, K, 1) + 0.5\n      \n    rot = _transpose_and_gather_feat(rot, inds)\n    rot = rot.view(batch, K, 8)\n    depth = _transpose_and_gather_feat(depth, inds)\n    depth = depth.view(batch, K, 1)\n    dim = _transpose_and_gather_feat(dim, inds)\n    dim = dim.view(batch, K, 3)\n    clses  = clses.view(batch, K, 1).float()\n    scores = scores.view(batch, K, 1)\n    xs = xs.view(batch, K, 1)\n    ys = ys.view(batch, K, 1)\n      \n    if wh is not None:\n        wh = _transpose_and_gather_feat(wh, inds)\n        wh = wh.view(batch, K, 2)\n        detections = torch.cat(\n            [xs, ys, scores, rot, depth, dim, wh, clses], dim=2)\n    else:\n        detections = torch.cat(\n            [xs, ys, scores, rot, depth, dim, clses], dim=2)\n      \n    return detections\n\ndef ctdet_decode(heat, wh, reg=None, cat_spec_wh=False, K=100):\n    batch, cat, height, width = heat.size()\n\n    # heat = torch.sigmoid(heat)\n    # perform nms on heatmaps\n    heat = _nms(heat)\n      \n    scores, inds, clses, ys, xs = _topk(heat, K=K)\n    if reg is not None:\n      reg = _transpose_and_gather_feat(reg, inds)\n      reg = reg.view(batch, K, 2)\n      xs = xs.view(batch, K, 1) + reg[:, :, 0:1]\n      ys = ys.view(batch, K, 1) + reg[:, :, 1:2]\n    else:\n      xs = xs.view(batch, K, 1) + 0.5\n      ys = ys.view(batch, K, 1) + 0.5\n    wh = _transpose_and_gather_feat(wh, inds)\n    if cat_spec_wh:\n      wh = wh.view(batch, K, cat, 2)\n      clses_ind = clses.view(batch, K, 1, 1).expand(batch, K, 1, 2).long()\n      wh = wh.gather(2, clses_ind).view(batch, K, 2)\n    else:\n      wh = wh.view(batch, K, 2)\n    clses  = clses.view(batch, K, 1).float()\n    scores = scores.view(batch, K, 1)\n    bboxes = torch.cat([xs - wh[..., 0:1] / 2, \n                        ys - wh[..., 1:2] / 2,\n                        xs + wh[..., 0:1] / 2, \n                        ys + wh[..., 1:2] / 2], dim=2)\n    detections = torch.cat([bboxes, scores, clses], dim=2)\n      \n    return detections\n\ndef multi_pose_decode(\n    heat, wh, kps, reg=None, hm_hp=None, hp_offset=None, K=100):\n  batch, cat, height, width = heat.size()\n  num_joints = kps.shape[1] // 2\n  # heat = torch.sigmoid(heat)\n  # perform nms on heatmaps\n  heat = _nms(heat)\n  scores, inds, clses, ys, xs = _topk(heat, K=K)\n\n  kps = _transpose_and_gather_feat(kps, inds)\n  kps = kps.view(batch, K, num_joints * 2)\n  kps[..., ::2] += xs.view(batch, K, 1).expand(batch, K, num_joints)\n  kps[..., 1::2] += ys.view(batch, K, 1).expand(batch, K, num_joints)\n  if reg is not None:\n    reg = _transpose_and_gather_feat(reg, inds)\n    reg = reg.view(batch, K, 2)\n    xs = xs.view(batch, K, 1) + reg[:, :, 0:1]\n    ys = ys.view(batch, K, 1) + reg[:, :, 1:2]\n  else:\n    xs = xs.view(batch, K, 1) + 0.5\n    ys = ys.view(batch, K, 1) + 0.5\n  wh = _transpose_and_gather_feat(wh, inds)\n  wh = wh.view(batch, K, 2)\n  clses  = clses.view(batch, K, 1).float()\n  scores = scores.view(batch, K, 1)\n\n  bboxes = torch.cat([xs - wh[..., 0:1] / 2, \n                      ys - wh[..., 1:2] / 2,\n                      xs + wh[..., 0:1] / 2, \n                      ys + wh[..., 1:2] / 2], dim=2)\n  if hm_hp is not None:\n      hm_hp = _nms(hm_hp)\n      thresh = 0.1\n      kps = kps.view(batch, K, num_joints, 2).permute(\n          0, 2, 1, 3).contiguous() # b x J x K x 2\n      reg_kps = kps.unsqueeze(3).expand(batch, num_joints, K, K, 2)\n      hm_score, hm_inds, hm_ys, hm_xs = _topk_channel(hm_hp, K=K) # b x J x K\n      if hp_offset is not None:\n          hp_offset = _transpose_and_gather_feat(\n              hp_offset, hm_inds.view(batch, -1))\n          hp_offset = hp_offset.view(batch, num_joints, K, 2)\n          hm_xs = hm_xs + hp_offset[:, :, :, 0]\n          hm_ys = hm_ys + hp_offset[:, :, :, 1]\n      else:\n          hm_xs = hm_xs + 0.5\n          hm_ys = hm_ys + 0.5\n        \n      mask = (hm_score > thresh).float()\n      hm_score = (1 - mask) * -1 + mask * hm_score\n      hm_ys = (1 - mask) * (-10000) + mask * hm_ys\n      hm_xs = (1 - mask) * (-10000) + mask * hm_xs\n      hm_kps = torch.stack([hm_xs, hm_ys], dim=-1).unsqueeze(\n          2).expand(batch, num_joints, K, K, 2)\n      dist = (((reg_kps - hm_kps) ** 2).sum(dim=4) ** 0.5)\n      min_dist, min_ind = dist.min(dim=3) # b x J x K\n      hm_score = hm_score.gather(2, min_ind).unsqueeze(-1) # b x J x K x 1\n      min_dist = min_dist.unsqueeze(-1)\n      min_ind = min_ind.view(batch, num_joints, K, 1, 1).expand(\n          batch, num_joints, K, 1, 2)\n      hm_kps = hm_kps.gather(3, min_ind)\n      hm_kps = hm_kps.view(batch, num_joints, K, 2)\n      l = bboxes[:, :, 0].view(batch, 1, K, 1).expand(batch, num_joints, K, 1)\n      t = bboxes[:, :, 1].view(batch, 1, K, 1).expand(batch, num_joints, K, 1)\n      r = bboxes[:, :, 2].view(batch, 1, K, 1).expand(batch, num_joints, K, 1)\n      b = bboxes[:, :, 3].view(batch, 1, K, 1).expand(batch, num_joints, K, 1)\n      mask = (hm_kps[..., 0:1] < l) + (hm_kps[..., 0:1] > r) + \\\n             (hm_kps[..., 1:2] < t) + (hm_kps[..., 1:2] > b) + \\\n             (hm_score < thresh) + (min_dist > (torch.max(b - t, r - l) * 0.3))\n      mask = (mask > 0).float().expand(batch, num_joints, K, 2)\n      kps = (1 - mask) * hm_kps + mask * kps\n      kps = kps.permute(0, 2, 1, 3).contiguous().view(\n          batch, K, num_joints * 2)\n  detections = torch.cat([bboxes, scores, kps, clses], dim=2)\n    \n  return detections"
  },
  {
    "path": "src/lib/models/losses.py",
    "content": "# ------------------------------------------------------------------------------\n# Portions of this code are from\n# CornerNet (https://github.com/princeton-vl/CornerNet)\n# Copyright (c) 2018, University of Michigan\n# Licensed under the BSD 3-Clause License\n# ------------------------------------------------------------------------------\nfrom __future__ import absolute_import\nfrom __future__ import division\nfrom __future__ import print_function\n\nimport torch\nimport torch.nn as nn\nfrom .utils import _transpose_and_gather_feat\nimport torch.nn.functional as F\n\n\ndef _slow_neg_loss(pred, gt):\n  '''focal loss from CornerNet'''\n  pos_inds = gt.eq(1)\n  neg_inds = gt.lt(1)\n\n  neg_weights = torch.pow(1 - gt[neg_inds], 4)\n\n  loss = 0\n  pos_pred = pred[pos_inds]\n  neg_pred = pred[neg_inds]\n\n  pos_loss = torch.log(pos_pred) * torch.pow(1 - pos_pred, 2)\n  neg_loss = torch.log(1 - neg_pred) * torch.pow(neg_pred, 2) * neg_weights\n\n  num_pos  = pos_inds.float().sum()\n  pos_loss = pos_loss.sum()\n  neg_loss = neg_loss.sum()\n\n  if pos_pred.nelement() == 0:\n    loss = loss - neg_loss\n  else:\n    loss = loss - (pos_loss + neg_loss) / num_pos\n  return loss\n\n\ndef _neg_loss(pred, gt):\n  ''' Modified focal loss. Exactly the same as CornerNet.\n      Runs faster and costs a little bit more memory\n    Arguments:\n      pred (batch x c x h x w)\n      gt_regr (batch x c x h x w)\n  '''\n  pos_inds = gt.eq(1).float()\n  neg_inds = gt.lt(1).float()\n\n  neg_weights = torch.pow(1 - gt, 4)\n\n  loss = 0\n\n  pos_loss = torch.log(pred) * torch.pow(1 - pred, 2) * pos_inds\n  neg_loss = torch.log(1 - pred) * torch.pow(pred, 2) * neg_weights * neg_inds\n\n  num_pos  = pos_inds.float().sum()\n  pos_loss = pos_loss.sum()\n  neg_loss = neg_loss.sum()\n\n  if num_pos == 0:\n    loss = loss - neg_loss\n  else:\n    loss = loss - (pos_loss + neg_loss) / num_pos\n  return loss\n\ndef _not_faster_neg_loss(pred, gt):\n    pos_inds = gt.eq(1).float()\n    neg_inds = gt.lt(1).float()    \n    num_pos  = pos_inds.float().sum()\n    neg_weights = torch.pow(1 - gt, 4)\n\n    loss = 0\n    trans_pred = pred * neg_inds + (1 - pred) * pos_inds\n    weight = neg_weights * neg_inds + pos_inds\n    all_loss = torch.log(1 - trans_pred) * torch.pow(trans_pred, 2) * weight\n    all_loss = all_loss.sum()\n\n    if num_pos > 0:\n        all_loss /= num_pos\n    loss -=  all_loss\n    return loss\n\ndef _slow_reg_loss(regr, gt_regr, mask):\n    num  = mask.float().sum()\n    mask = mask.unsqueeze(2).expand_as(gt_regr)\n\n    regr    = regr[mask]\n    gt_regr = gt_regr[mask]\n    \n    regr_loss = nn.functional.smooth_l1_loss(regr, gt_regr, size_average=False)\n    regr_loss = regr_loss / (num + 1e-4)\n    return regr_loss\n\ndef _reg_loss(regr, gt_regr, mask):\n  ''' L1 regression loss\n    Arguments:\n      regr (batch x max_objects x dim)\n      gt_regr (batch x max_objects x dim)\n      mask (batch x max_objects)\n  '''\n  num = mask.float().sum()\n  mask = mask.unsqueeze(2).expand_as(gt_regr).float()\n\n  regr = regr * mask\n  gt_regr = gt_regr * mask\n    \n  regr_loss = nn.functional.smooth_l1_loss(regr, gt_regr, size_average=False)\n  regr_loss = regr_loss / (num + 1e-4)\n  return regr_loss\n\nclass FocalLoss(nn.Module):\n  '''nn.Module warpper for focal loss'''\n  def __init__(self):\n    super(FocalLoss, self).__init__()\n    self.neg_loss = _neg_loss\n\n  def forward(self, out, target):\n    return self.neg_loss(out, target)\n\nclass RegLoss(nn.Module):\n  '''Regression loss for an output tensor\n    Arguments:\n      output (batch x dim x h x w)\n      mask (batch x max_objects)\n      ind (batch x max_objects)\n      target (batch x max_objects x dim)\n  '''\n  def __init__(self):\n    super(RegLoss, self).__init__()\n  \n  def forward(self, output, mask, ind, target):\n    pred = _transpose_and_gather_feat(output, ind)\n    loss = _reg_loss(pred, target, mask)\n    return loss\n\nclass RegL1Loss(nn.Module):\n  def __init__(self):\n    super(RegL1Loss, self).__init__()\n  \n  def forward(self, output, mask, ind, target):\n    pred = _transpose_and_gather_feat(output, ind)\n    mask = mask.unsqueeze(2).expand_as(pred).float()\n    # loss = F.l1_loss(pred * mask, target * mask, reduction='elementwise_mean')\n    loss = F.l1_loss(pred * mask, target * mask, size_average=False)\n    loss = loss / (mask.sum() + 1e-4)\n    return loss\n\nclass NormRegL1Loss(nn.Module):\n  def __init__(self):\n    super(NormRegL1Loss, self).__init__()\n  \n  def forward(self, output, mask, ind, target):\n    pred = _transpose_and_gather_feat(output, ind)\n    mask = mask.unsqueeze(2).expand_as(pred).float()\n    # loss = F.l1_loss(pred * mask, target * mask, reduction='elementwise_mean')\n    pred = pred / (target + 1e-4)\n    target = target * 0 + 1\n    loss = F.l1_loss(pred * mask, target * mask, size_average=False)\n    loss = loss / (mask.sum() + 1e-4)\n    return loss\n\nclass RegWeightedL1Loss(nn.Module):\n  def __init__(self):\n    super(RegWeightedL1Loss, self).__init__()\n  \n  def forward(self, output, mask, ind, target):\n    pred = _transpose_and_gather_feat(output, ind)\n    mask = mask.float()\n    # loss = F.l1_loss(pred * mask, target * mask, reduction='elementwise_mean')\n    loss = F.l1_loss(pred * mask, target * mask, size_average=False)\n    loss = loss / (mask.sum() + 1e-4)\n    return loss\n\nclass L1Loss(nn.Module):\n  def __init__(self):\n    super(L1Loss, self).__init__()\n  \n  def forward(self, output, mask, ind, target):\n    pred = _transpose_and_gather_feat(output, ind)\n    mask = mask.unsqueeze(2).expand_as(pred).float()\n    loss = F.l1_loss(pred * mask, target * mask, reduction='elementwise_mean')\n    return loss\n\nclass BinRotLoss(nn.Module):\n  def __init__(self):\n    super(BinRotLoss, self).__init__()\n  \n  def forward(self, output, mask, ind, rotbin, rotres):\n    pred = _transpose_and_gather_feat(output, ind)\n    loss = compute_rot_loss(pred, rotbin, rotres, mask)\n    return loss\n\ndef compute_res_loss(output, target):\n    return F.smooth_l1_loss(output, target, reduction='elementwise_mean')\n\n# TODO: weight\ndef compute_bin_loss(output, target, mask):\n    mask = mask.expand_as(output)\n    output = output * mask.float()\n    return F.cross_entropy(output, target, reduction='elementwise_mean')\n\ndef compute_rot_loss(output, target_bin, target_res, mask):\n    # output: (B, 128, 8) [bin1_cls[0], bin1_cls[1], bin1_sin, bin1_cos, \n    #                 bin2_cls[0], bin2_cls[1], bin2_sin, bin2_cos]\n    # target_bin: (B, 128, 2) [bin1_cls, bin2_cls]\n    # target_res: (B, 128, 2) [bin1_res, bin2_res]\n    # mask: (B, 128, 1)\n    # import pdb; pdb.set_trace()\n    output = output.view(-1, 8)\n    target_bin = target_bin.view(-1, 2)\n    target_res = target_res.view(-1, 2)\n    mask = mask.view(-1, 1)\n    loss_bin1 = compute_bin_loss(output[:, 0:2], target_bin[:, 0], mask)\n    loss_bin2 = compute_bin_loss(output[:, 4:6], target_bin[:, 1], mask)\n    loss_res = torch.zeros_like(loss_bin1)\n    if target_bin[:, 0].nonzero().shape[0] > 0:\n        idx1 = target_bin[:, 0].nonzero()[:, 0]\n        valid_output1 = torch.index_select(output, 0, idx1.long())\n        valid_target_res1 = torch.index_select(target_res, 0, idx1.long())\n        loss_sin1 = compute_res_loss(\n          valid_output1[:, 2], torch.sin(valid_target_res1[:, 0]))\n        loss_cos1 = compute_res_loss(\n          valid_output1[:, 3], torch.cos(valid_target_res1[:, 0]))\n        loss_res += loss_sin1 + loss_cos1\n    if target_bin[:, 1].nonzero().shape[0] > 0:\n        idx2 = target_bin[:, 1].nonzero()[:, 0]\n        valid_output2 = torch.index_select(output, 0, idx2.long())\n        valid_target_res2 = torch.index_select(target_res, 0, idx2.long())\n        loss_sin2 = compute_res_loss(\n          valid_output2[:, 6], torch.sin(valid_target_res2[:, 1]))\n        loss_cos2 = compute_res_loss(\n          valid_output2[:, 7], torch.cos(valid_target_res2[:, 1]))\n        loss_res += loss_sin2 + loss_cos2\n    return loss_bin1 + loss_bin2 + loss_res\n"
  },
  {
    "path": "src/lib/models/model.py",
    "content": "from __future__ import absolute_import\nfrom __future__ import division\nfrom __future__ import print_function\n\nimport torchvision.models as models\nimport torch\nimport torch.nn as nn\nimport os\n\nfrom .networks.msra_resnet import get_pose_net\nfrom .networks.dlav0 import get_pose_net as get_dlav0\nfrom .networks.pose_dla_dcn import get_pose_net as get_dla_dcn\nfrom .networks.resnet_dcn import get_pose_net as get_pose_net_dcn\nfrom .networks.large_hourglass import get_large_hourglass_net\n\n_model_factory = {\n  'res': get_pose_net, # default Resnet with deconv\n  'dlav0': get_dlav0, # default DLAup\n  'dla': get_dla_dcn,\n  'resdcn': get_pose_net_dcn,\n  'hourglass': get_large_hourglass_net,\n}\n\ndef create_model(arch, heads, head_conv):\n  num_layers = int(arch[arch.find('_') + 1:]) if '_' in arch else 0\n  arch = arch[:arch.find('_')] if '_' in arch else arch\n  get_model = _model_factory[arch]\n  model = get_model(num_layers=num_layers, heads=heads, head_conv=head_conv)\n  return model\n\ndef load_model(model, model_path, optimizer=None, resume=False, \n               lr=None, lr_step=None):\n  start_epoch = 0\n  checkpoint = torch.load(model_path, map_location=lambda storage, loc: storage)\n  print('loaded {}, epoch {}'.format(model_path, checkpoint['epoch']))\n  state_dict_ = checkpoint['state_dict']\n  state_dict = {}\n  \n  # convert data_parallal to model\n  for k in state_dict_:\n    if k.startswith('module') and not k.startswith('module_list'):\n      state_dict[k[7:]] = state_dict_[k]\n    else:\n      state_dict[k] = state_dict_[k]\n  model_state_dict = model.state_dict()\n\n  # check loaded parameters and created model parameters\n  msg = 'If you see this, your model does not fully load the ' + \\\n        'pre-trained weight. Please make sure ' + \\\n        'you have correctly specified --arch xxx ' + \\\n        'or set the correct --num_classes for your own dataset.'\n  for k in state_dict:\n    if k in model_state_dict:\n      if state_dict[k].shape != model_state_dict[k].shape:\n        print('Skip loading parameter {}, required shape{}, '\\\n              'loaded shape{}. {}'.format(\n          k, model_state_dict[k].shape, state_dict[k].shape, msg))\n        state_dict[k] = model_state_dict[k]\n    else:\n      print('Drop parameter {}.'.format(k) + msg)\n  for k in model_state_dict:\n    if not (k in state_dict):\n      print('No param {}.'.format(k) + msg)\n      state_dict[k] = model_state_dict[k]\n  model.load_state_dict(state_dict, strict=False)\n\n  # resume optimizer parameters\n  if optimizer is not None and resume:\n    if 'optimizer' in checkpoint:\n      optimizer.load_state_dict(checkpoint['optimizer'])\n      start_epoch = checkpoint['epoch']\n      start_lr = lr\n      for step in lr_step:\n        if start_epoch >= step:\n          start_lr *= 0.1\n      for param_group in optimizer.param_groups:\n        param_group['lr'] = start_lr\n      print('Resumed optimizer with start lr', start_lr)\n    else:\n      print('No optimizer parameters in checkpoint.')\n  if optimizer is not None:\n    return model, optimizer, start_epoch\n  else:\n    return model\n\ndef save_model(path, epoch, model, optimizer=None):\n  if isinstance(model, torch.nn.DataParallel):\n    state_dict = model.module.state_dict()\n  else:\n    state_dict = model.state_dict()\n  data = {'epoch': epoch,\n          'state_dict': state_dict}\n  if not (optimizer is None):\n    data['optimizer'] = optimizer.state_dict()\n  torch.save(data, path)\n\n"
  },
  {
    "path": "src/lib/models/networks/DCNv2/.gitignore",
    "content": ".vscode\n.idea\n*.so\n*.o\n*pyc\n_ext"
  },
  {
    "path": "src/lib/models/networks/DCNv2/LICENSE",
    "content": "BSD 3-Clause License\n\nCopyright (c) 2019, Charles Shang\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n1. Redistributions of source code must retain the above copyright notice, this\n   list of conditions and the following disclaimer.\n\n2. Redistributions in binary form must reproduce the above copyright notice,\n   this list of conditions and the following disclaimer in the documentation\n   and/or other materials provided with the distribution.\n\n3. Neither the name of the copyright holder nor the names of its\n   contributors may be used to endorse or promote products derived from\n   this software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\nDISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE\nFOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\nDAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\nSERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\nCAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\nOR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\nOF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n"
  },
  {
    "path": "src/lib/models/networks/DCNv2/README.md",
    "content": "## Deformable Convolutional Networks V2 with Pytorch\n\n### Build\n```bash\n    ./make.sh         # build\n    python test.py    # run examples and gradient check \n```\n\n### An Example\n- deformable conv\n```python\n    from dcn_v2 import DCN\n    input = torch.randn(2, 64, 128, 128).cuda()\n    # wrap all things (offset and mask) in DCN\n    dcn = DCN(64, 64, kernel_size=(3,3), stride=1, padding=1, deformable_groups=2).cuda()\n    output = dcn(input)\n    print(output.shape)\n```\n- deformable roi pooling\n```python\n    from dcn_v2 import DCNPooling\n    input = torch.randn(2, 32, 64, 64).cuda()\n    batch_inds = torch.randint(2, (20, 1)).cuda().float()\n    x = torch.randint(256, (20, 1)).cuda().float()\n    y = torch.randint(256, (20, 1)).cuda().float()\n    w = torch.randint(64, (20, 1)).cuda().float()\n    h = torch.randint(64, (20, 1)).cuda().float()\n    rois = torch.cat((batch_inds, x, y, x + w, y + h), dim=1)\n\n    # mdformable pooling (V2)\n    # wrap all things (offset and mask) in DCNPooling\n    dpooling = DCNPooling(spatial_scale=1.0 / 4,\n                         pooled_size=7,\n                         output_dim=32,\n                         no_trans=False,\n                         group_size=1,\n                         trans_std=0.1).cuda()\n\n    dout = dpooling(input, rois)\n```\n\n### Known Issues:\n\n- [x] Gradient check w.r.t offset (solved)\n- [ ] Backward is not reentrant (minor)\n\nThis is an adaption of the official [Deformable-ConvNets](https://github.com/msracver/Deformable-ConvNets/tree/master/DCNv2_op).\n\n<s>I have ran the gradient check for many times with DOUBLE type. Every tensor **except offset** passes.\nHowever, when I set the offset to 0.5, it passes. I'm still wondering what cause this problem. Is it because some\nnon-differential points? </s>\n\nUpdate: all gradient check passes with double precision. \n\nAnother issue is that it raises `RuntimeError: Backward is not reentrant`. However, the error is very small (`<1e-7` for \nfloat `<1e-15` for double), \nso it may not be a serious problem (?)\n\nPlease post an issue or PR if you have any comments.\n    "
  },
  {
    "path": "src/lib/models/networks/DCNv2/__init__.py",
    "content": ""
  },
  {
    "path": "src/lib/models/networks/DCNv2/build.py",
    "content": "import os\nimport torch\nfrom torch.utils.ffi import create_extension\n\n\nsources = ['src/dcn_v2.c']\nheaders = ['src/dcn_v2.h']\ndefines = []\nwith_cuda = False\n\nextra_objects = []\nif torch.cuda.is_available():\n    print('Including CUDA code.')\n    sources += ['src/dcn_v2_cuda.c']\n    headers += ['src/dcn_v2_cuda.h']\n    defines += [('WITH_CUDA', None)]\n    extra_objects += ['src/cuda/dcn_v2_im2col_cuda.cu.o']\n    extra_objects += ['src/cuda/dcn_v2_psroi_pooling_cuda.cu.o']\n    with_cuda = True\nelse:\n    raise ValueError('CUDA is not available')\n\nextra_compile_args = ['-fopenmp', '-std=c99']\n\nthis_file = os.path.dirname(os.path.realpath(__file__))\nprint(this_file)\nsources = [os.path.join(this_file, fname) for fname in sources]\nheaders = [os.path.join(this_file, fname) for fname in headers]\nextra_objects = [os.path.join(this_file, fname) for fname in extra_objects]\n\nffi = create_extension(\n    '_ext.dcn_v2',\n    headers=headers,\n    sources=sources,\n    define_macros=defines,\n    relative_to=__file__,\n    with_cuda=with_cuda,\n    extra_objects=extra_objects,\n    extra_compile_args=extra_compile_args\n)\n\nif __name__ == '__main__':\n    ffi.build()\n"
  },
  {
    "path": "src/lib/models/networks/DCNv2/build_double.py",
    "content": "import os\nimport torch\nfrom torch.utils.ffi import create_extension\n\n\nsources = ['src/dcn_v2_double.c']\nheaders = ['src/dcn_v2_double.h']\ndefines = []\nwith_cuda = False\n\nextra_objects = []\nif torch.cuda.is_available():\n    print('Including CUDA code.')\n    sources += ['src/dcn_v2_cuda_double.c']\n    headers += ['src/dcn_v2_cuda_double.h']\n    defines += [('WITH_CUDA', None)]\n    extra_objects += ['src/cuda/dcn_v2_im2col_cuda_double.cu.o']\n    extra_objects += ['src/cuda/dcn_v2_psroi_pooling_cuda_double.cu.o']\n    with_cuda = True\nelse:\n    raise ValueError('CUDA is not available')\n\nextra_compile_args = ['-fopenmp', '-std=c99']\n\nthis_file = os.path.dirname(os.path.realpath(__file__))\nprint(this_file)\nsources = [os.path.join(this_file, fname) for fname in sources]\nheaders = [os.path.join(this_file, fname) for fname in headers]\nextra_objects = [os.path.join(this_file, fname) for fname in extra_objects]\n\nffi = create_extension(\n    '_ext.dcn_v2_double',\n    headers=headers,\n    sources=sources,\n    define_macros=defines,\n    relative_to=__file__,\n    with_cuda=with_cuda,\n    extra_objects=extra_objects,\n    extra_compile_args=extra_compile_args\n)\n\nif __name__ == '__main__':\n    ffi.build()\n"
  },
  {
    "path": "src/lib/models/networks/DCNv2/dcn_v2.py",
    "content": "#!/usr/bin/env python\nfrom __future__ import absolute_import\nfrom __future__ import print_function\nfrom __future__ import division\n\nimport torch\nimport math\nfrom torch import nn\nfrom torch.nn.modules.utils import _pair\n\nfrom .dcn_v2_func import DCNv2Function\nfrom .dcn_v2_func import DCNv2PoolingFunction\n\nclass DCNv2(nn.Module):\n\n    def __init__(self, in_channels, out_channels,\n                 kernel_size, stride, padding, dilation=1, deformable_groups=1):\n        super(DCNv2, self).__init__()\n        self.in_channels = in_channels\n        self.out_channels = out_channels\n        self.kernel_size = _pair(kernel_size)\n        self.stride = stride\n        self.padding = padding\n        self.dilation = dilation\n        self.deformable_groups = deformable_groups\n\n        self.weight = nn.Parameter(torch.Tensor(out_channels, in_channels, *self.kernel_size))\n        self.bias = nn.Parameter(torch.Tensor(out_channels))\n        self.reset_parameters()\n\n    def reset_parameters(self):\n        n = self.in_channels\n        for k in self.kernel_size:\n            n *= k\n        stdv = 1. / math.sqrt(n)\n        self.weight.data.uniform_(-stdv, stdv)\n        self.bias.data.zero_()\n\n    def forward(self, input, offset, mask):\n        func = DCNv2Function(self.stride, self.padding, self.dilation, self.deformable_groups)\n        return func(input, offset, mask, self.weight, self.bias)\n\n\nclass DCN(DCNv2):\n\n    def __init__(self, in_channels, out_channels,\n                 kernel_size, stride, padding,\n                 dilation=1, deformable_groups=1):\n        super(DCN, self).__init__(in_channels, out_channels,\n                                  kernel_size, stride, padding, dilation, deformable_groups)\n\n        self.conv_offset_mask = nn.Conv2d(self.in_channels,\n                                          self.deformable_groups * 3 * self.kernel_size[0] * self.kernel_size[1],\n                                          kernel_size=self.kernel_size,\n                                          stride=(self.stride, self.stride),\n                                          padding=(self.padding, self.padding),\n                                          bias=True)\n        self.init_offset()\n\n    def init_offset(self):\n        self.conv_offset_mask.weight.data.zero_()\n        self.conv_offset_mask.bias.data.zero_()\n\n    def forward(self, input):\n        out = self.conv_offset_mask(input)\n        o1, o2, mask = torch.chunk(out, 3, dim=1)\n        offset = torch.cat((o1, o2), dim=1)\n        mask = torch.sigmoid(mask)\n        func = DCNv2Function(self.stride, self.padding, self.dilation, self.deformable_groups)\n        return func(input, offset, mask, self.weight, self.bias)\n\n\nclass DCNv2Pooling(nn.Module):\n\n    def __init__(self,\n                 spatial_scale,\n                 pooled_size,\n                 output_dim,\n                 no_trans,\n                 group_size=1,\n                 part_size=None,\n                 sample_per_part=4,\n                 trans_std=.0):\n        super(DCNv2Pooling, self).__init__()\n        self.spatial_scale = spatial_scale\n        self.pooled_size = pooled_size\n        self.output_dim = output_dim\n        self.no_trans = no_trans\n        self.group_size = group_size\n        self.part_size = pooled_size if part_size is None else part_size\n        self.sample_per_part = sample_per_part\n        self.trans_std = trans_std\n        self.func = DCNv2PoolingFunction(self.spatial_scale,\n                             self.pooled_size,\n                             self.output_dim,\n                             self.no_trans,\n                             self.group_size,\n                             self.part_size,\n                             self.sample_per_part,\n                             self.trans_std)\n\n    def forward(self, data, rois, offset):\n\n        if self.no_trans:\n            offset = data.new()\n        return self.func(data, rois, offset)\n\nclass DCNPooling(DCNv2Pooling):\n\n    def __init__(self,\n                 spatial_scale,\n                 pooled_size,\n                 output_dim,\n                 no_trans,\n                 group_size=1,\n                 part_size=None,\n                 sample_per_part=4,\n                 trans_std=.0,\n                 deform_fc_dim=1024):\n        super(DCNPooling, self).__init__(spatial_scale,\n                                         pooled_size,\n                                         output_dim,\n                                         no_trans,\n                                         group_size,\n                                         part_size,\n                                         sample_per_part,\n                                         trans_std)\n\n        self.deform_fc_dim = deform_fc_dim\n\n        if not no_trans:\n            self.func_offset = DCNv2PoolingFunction(self.spatial_scale,\n                                                    self.pooled_size,\n                                                    self.output_dim,\n                                                    True,\n                                                    self.group_size,\n                                                    self.part_size,\n                                                    self.sample_per_part,\n                                                    self.trans_std)\n            self.offset_fc = nn.Sequential(\n                nn.Linear(self.pooled_size * self.pooled_size * self.output_dim, self.deform_fc_dim),\n                nn.ReLU(inplace=True),\n                nn.Linear(self.deform_fc_dim, self.deform_fc_dim),\n                nn.ReLU(inplace=True),\n                nn.Linear(self.deform_fc_dim, self.pooled_size * self.pooled_size * 2)\n            )\n            self.offset_fc[4].weight.data.zero_()\n            self.offset_fc[4].bias.data.zero_()\n            self.mask_fc = nn.Sequential(\n                nn.Linear(self.pooled_size * self.pooled_size * self.output_dim, self.deform_fc_dim),\n                nn.ReLU(inplace=True),\n                nn.Linear(self.deform_fc_dim, self.pooled_size * self.pooled_size * 1),\n                nn.Sigmoid()\n            )\n            self.mask_fc[2].weight.data.zero_()\n            self.mask_fc[2].bias.data.zero_()\n\n    def forward(self, data, rois):\n        if self.no_trans:\n            offset = data.new()\n        else:\n            n = rois.shape[0]\n            offset = data.new()\n            x = self.func_offset(data, rois, offset)\n            offset = self.offset_fc(x.view(n, -1))\n            offset = offset.view(n, 2, self.pooled_size, self.pooled_size)\n            mask = self.mask_fc(x.view(n, -1))\n            mask = mask.view(n, 1, self.pooled_size, self.pooled_size)\n            feat = self.func(data, rois, offset) * mask\n            return feat\n        return self.func(data, rois, offset)\n"
  },
  {
    "path": "src/lib/models/networks/DCNv2/dcn_v2_func.py",
    "content": "#!/usr/bin/env python\nfrom __future__ import absolute_import\nfrom __future__ import print_function\nfrom __future__ import division\n\nimport torch\nfrom torch.autograd import Function\n\nfrom ._ext import dcn_v2 as _backend\n# from _ext import dcn_v2_double as _backend\n\n\nclass DCNv2Function(Function):\n\n    def __init__(self, stride, padding, dilation=1, deformable_groups=1):\n        super(DCNv2Function, self).__init__()\n        self.stride = stride\n        self.padding = padding\n        self.dilation = dilation\n        self.deformable_groups = deformable_groups\n\n    def forward(self, input, offset, mask, weight, bias):\n        if not input.is_cuda:\n            raise NotImplementedError\n        if weight.requires_grad or mask.requires_grad or offset.requires_grad or input.requires_grad:\n            self.save_for_backward(input, offset, mask, weight, bias)\n        output = input.new(*self._infer_shape(input, weight))\n        self._bufs = [input.new(), input.new()]\n        _backend.dcn_v2_cuda_forward(input, weight,\n                                     bias, self._bufs[0],\n                                     offset, mask,\n                                     output, self._bufs[1],\n                                     weight.shape[2], weight.shape[3],\n                                     self.stride, self.stride,\n                                     self.padding, self.padding,\n                                     self.dilation, self.dilation,\n                                     self.deformable_groups)\n        return output\n\n    def backward(self, grad_output):\n        if not grad_output.is_cuda:\n            raise NotImplementedError\n        input, offset, mask, weight, bias = self.saved_tensors\n        grad_input = input.new(*input.size()).zero_()\n        grad_offset = offset.new(*offset.size()).zero_()\n        grad_mask = mask.new(*mask.size()).zero_()\n        grad_weight = weight.new(*weight.size()).zero_()\n        grad_bias = bias.new(*bias.size()).zero_()\n        _backend.dcn_v2_cuda_backward(input, weight,\n                                      bias, self._bufs[0],\n                                      offset, mask,\n                                      self._bufs[1],\n                                      grad_input, grad_weight,\n                                      grad_bias, grad_offset,\n                                      grad_mask, grad_output,\n                                      weight.shape[2], weight.shape[3],\n                                      self.stride, self.stride,\n                                      self.padding, self.padding,\n                                      self.dilation, self.dilation,\n                                      self.deformable_groups)\n\n        return grad_input, grad_offset, grad_mask, grad_weight, grad_bias\n\n    def _infer_shape(self, input, weight):\n        n = input.size(0)\n        channels_out = weight.size(0)\n        height, width = input.shape[2:4]\n        kernel_h, kernel_w = weight.shape[2:4]\n        height_out = (height + 2 * self.padding -\n                      (self.dilation * (kernel_h - 1) + 1)) // self.stride + 1\n        width_out = (width + 2 * self.padding - (self.dilation *\n                                                 (kernel_w - 1) + 1)) // self.stride + 1\n        return (n, channels_out, height_out, width_out)\n\n\nclass DCNv2PoolingFunction(Function):\n\n    def __init__(self,\n                 spatial_scale,\n                 pooled_size,\n                 output_dim,\n                 no_trans,\n                 group_size=1,\n                 part_size=None,\n                 sample_per_part=4,\n                 trans_std=.0):\n        super(DCNv2PoolingFunction, self).__init__()\n        self.spatial_scale = spatial_scale\n        self.pooled_size = pooled_size\n        self.output_dim = output_dim\n        self.no_trans = no_trans\n        self.group_size = group_size\n        self.part_size = pooled_size if part_size is None else part_size\n        self.sample_per_part = sample_per_part\n        self.trans_std = trans_std\n\n        assert self.trans_std >= 0.0 and self.trans_std <= 1.0\n\n    def forward(self, data, rois, offset):\n        if not data.is_cuda:\n            raise NotImplementedError\n\n        output = data.new(*self._infer_shape(data, rois))\n        output_count = data.new(*self._infer_shape(data, rois))\n        _backend.dcn_v2_psroi_pooling_cuda_forward(data, rois, offset,\n                                                   output, output_count,\n                                                   self.no_trans, self.spatial_scale,\n                                                   self.output_dim, self.group_size,\n                                                   self.pooled_size, self.part_size,\n                                                   self.sample_per_part, self.trans_std)\n\n        if data.requires_grad or rois.requires_grad or offset.requires_grad:\n            self.save_for_backward(data, rois, offset, output_count)\n\n        return output\n\n    def backward(self, grad_output):\n        if not grad_output.is_cuda:\n            raise NotImplementedError\n\n        data, rois, offset, output_count = self.saved_tensors\n        grad_input = data.new(*data.size()).zero_()\n        grad_offset = offset.new(*offset.size()).zero_()\n\n        _backend.dcn_v2_psroi_pooling_cuda_backward(grad_output,\n                                                    data,\n                                                    rois,\n                                                    offset,\n                                                    output_count,\n                                                    grad_input,\n                                                    grad_offset,\n                                                    self.no_trans,\n                                                    self.spatial_scale,\n                                                    self.output_dim,\n                                                    self.group_size,\n                                                    self.pooled_size,\n                                                    self.part_size,\n                                                    self.sample_per_part,\n                                                    self.trans_std)\n        return grad_input, None, grad_offset\n\n    def _infer_shape(self, data, rois):\n        # _, c, h, w = data.shape[:4]\n        c = data.shape[1]\n        n = rois.shape[0]\n        return (n, self.output_dim, self.pooled_size, self.pooled_size)\n"
  },
  {
    "path": "src/lib/models/networks/DCNv2/make.sh",
    "content": "#!/usr/bin/env bash\ncd src/cuda\n\n# compile dcn\nnvcc -c -o dcn_v2_im2col_cuda.cu.o dcn_v2_im2col_cuda.cu -x cu -Xcompiler -fPIC\nnvcc -c -o dcn_v2_im2col_cuda_double.cu.o dcn_v2_im2col_cuda_double.cu -x cu -Xcompiler -fPIC\n\n# compile dcn-roi-pooling\nnvcc -c -o dcn_v2_psroi_pooling_cuda.cu.o dcn_v2_psroi_pooling_cuda.cu -x cu -Xcompiler -fPIC\nnvcc -c -o dcn_v2_psroi_pooling_cuda_double.cu.o dcn_v2_psroi_pooling_cuda_double.cu -x cu -Xcompiler -fPIC\n\ncd -\npython build.py\npython build_double.py\n"
  },
  {
    "path": "src/lib/models/networks/DCNv2/src/cuda/dcn_v2_im2col_cuda.cu",
    "content": "#include \"dcn_v2_im2col_cuda.h\"\n#include <cstdio>\n#include <algorithm>\n#include <cstring>\n\n#define CUDA_KERNEL_LOOP(i, n)                          \\\n  for (int i = blockIdx.x * blockDim.x + threadIdx.x;   \\\n      i < (n);                                          \\\n      i += blockDim.x * gridDim.x)\n\nconst int CUDA_NUM_THREADS = 1024;\ninline int GET_BLOCKS(const int N)\n{\n  return (N + CUDA_NUM_THREADS - 1) / CUDA_NUM_THREADS;\n}\n\n\n__device__ float dmcn_im2col_bilinear(const float *bottom_data, const int data_width,\n                                      const int height, const int width, float h, float w)\n{\n  int h_low = floor(h);\n  int w_low = floor(w);\n  int h_high = h_low + 1;\n  int w_high = w_low + 1;\n\n  float lh = h - h_low;\n  float lw = w - w_low;\n  float hh = 1 - lh, hw = 1 - lw;\n\n  float v1 = 0;\n  if (h_low >= 0 && w_low >= 0)\n    v1 = bottom_data[h_low * data_width + w_low];\n  float v2 = 0;\n  if (h_low >= 0 && w_high <= width - 1)\n    v2 = bottom_data[h_low * data_width + w_high];\n  float v3 = 0;\n  if (h_high <= height - 1 && w_low >= 0)\n    v3 = bottom_data[h_high * data_width + w_low];\n  float v4 = 0;\n  if (h_high <= height - 1 && w_high <= width - 1)\n    v4 = bottom_data[h_high * data_width + w_high];\n\n  float w1 = hh * hw, w2 = hh * lw, w3 = lh * hw, w4 = lh * lw;\n\n  float val = (w1 * v1 + w2 * v2 + w3 * v3 + w4 * v4);\n  return val;\n}\n\n__device__ float dmcn_get_gradient_weight(float argmax_h, float argmax_w,\n                                          const int h, const int w, const int height, const int width)\n{\n  if (argmax_h <= -1 || argmax_h >= height || argmax_w <= -1 || argmax_w >= width)\n  {\n    //empty\n    return 0;\n  }\n\n  int argmax_h_low = floor(argmax_h);\n  int argmax_w_low = floor(argmax_w);\n  int argmax_h_high = argmax_h_low + 1;\n  int argmax_w_high = argmax_w_low + 1;\n\n  float weight = 0;\n  if (h == argmax_h_low && w == argmax_w_low)\n    weight = (h + 1 - argmax_h) * (w + 1 - argmax_w);\n  if (h == argmax_h_low && w == argmax_w_high)\n    weight = (h + 1 - argmax_h) * (argmax_w + 1 - w);\n  if (h == argmax_h_high && w == argmax_w_low)\n    weight = (argmax_h + 1 - h) * (w + 1 - argmax_w);\n  if (h == argmax_h_high && w == argmax_w_high)\n    weight = (argmax_h + 1 - h) * (argmax_w + 1 - w);\n  return weight;\n}\n\n__device__ float dmcn_get_coordinate_weight(float argmax_h, float argmax_w,\n                                            const int height, const int width, const float *im_data,\n                                            const int data_width, const int bp_dir)\n{\n  if (argmax_h <= -1 || argmax_h >= height || argmax_w <= -1 || argmax_w >= width)\n  {\n    //empty\n    return 0;\n  }\n\n  int argmax_h_low = floor(argmax_h);\n  int argmax_w_low = floor(argmax_w);\n  int argmax_h_high = argmax_h_low + 1;\n  int argmax_w_high = argmax_w_low + 1;\n\n  float weight = 0;\n\n  if (bp_dir == 0)\n  {\n    if (argmax_h_low >= 0 && argmax_w_low >= 0)\n      weight += -1 * (argmax_w_low + 1 - argmax_w) * im_data[argmax_h_low * data_width + argmax_w_low];\n    if (argmax_h_low >= 0 && argmax_w_high <= width - 1)\n      weight += -1 * (argmax_w - argmax_w_low) * im_data[argmax_h_low * data_width + argmax_w_high];\n    if (argmax_h_high <= height - 1 && argmax_w_low >= 0)\n      weight += (argmax_w_low + 1 - argmax_w) * im_data[argmax_h_high * data_width + argmax_w_low];\n    if (argmax_h_high <= height - 1 && argmax_w_high <= width - 1)\n      weight += (argmax_w - argmax_w_low) * im_data[argmax_h_high * data_width + argmax_w_high];\n  }\n  else if (bp_dir == 1)\n  {\n    if (argmax_h_low >= 0 && argmax_w_low >= 0)\n      weight += -1 * (argmax_h_low + 1 - argmax_h) * im_data[argmax_h_low * data_width + argmax_w_low];\n    if (argmax_h_low >= 0 && argmax_w_high <= width - 1)\n      weight += (argmax_h_low + 1 - argmax_h) * im_data[argmax_h_low * data_width + argmax_w_high];\n    if (argmax_h_high <= height - 1 && argmax_w_low >= 0)\n      weight += -1 * (argmax_h - argmax_h_low) * im_data[argmax_h_high * data_width + argmax_w_low];\n    if (argmax_h_high <= height - 1 && argmax_w_high <= width - 1)\n      weight += (argmax_h - argmax_h_low) * im_data[argmax_h_high * data_width + argmax_w_high];\n  }\n\n  return weight;\n}\n\n__global__ void modulated_deformable_im2col_gpu_kernel(const int n,\n                                                       const float *data_im, const float *data_offset, const float *data_mask,\n                                                       const int height, const int width, const int kernel_h, const int kernel_w,\n                                                       const int pad_h, const int pad_w,\n                                                       const int stride_h, const int stride_w,\n                                                       const int dilation_h, const int dilation_w,\n                                                       const int channel_per_deformable_group,\n                                                       const int batch_size, const int num_channels, const int deformable_group,\n                                                       const int height_col, const int width_col,\n                                                       float *data_col)\n{\n  CUDA_KERNEL_LOOP(index, n)\n  {\n    // index index of output matrix\n    const int w_col = index % width_col;\n    const int h_col = (index / width_col) % height_col;\n    const int b_col = (index / width_col / height_col) % batch_size;\n    const int c_im = (index / width_col / height_col) / batch_size;\n    const int c_col = c_im * kernel_h * kernel_w;\n\n    // compute deformable group index\n    const int deformable_group_index = c_im / channel_per_deformable_group;\n\n    const int h_in = h_col * stride_h - pad_h;\n    const int w_in = w_col * stride_w - pad_w;\n\n    float *data_col_ptr = data_col + ((c_col * batch_size + b_col) * height_col + h_col) * width_col + w_col;\n    //const float* data_im_ptr = data_im + ((b_col * num_channels + c_im) * height + h_in) * width + w_in;\n    const float *data_im_ptr = data_im + (b_col * num_channels + c_im) * height * width;\n    const float *data_offset_ptr = data_offset + (b_col * deformable_group + deformable_group_index) * 2 * kernel_h * kernel_w * height_col * width_col;\n\n    const float *data_mask_ptr = data_mask + (b_col * deformable_group + deformable_group_index) * kernel_h * kernel_w * height_col * width_col;\n\n    for (int i = 0; i < kernel_h; ++i)\n    {\n      for (int j = 0; j < kernel_w; ++j)\n      {\n        const int data_offset_h_ptr = ((2 * (i * kernel_w + j)) * height_col + h_col) * width_col + w_col;\n        const int data_offset_w_ptr = ((2 * (i * kernel_w + j) + 1) * height_col + h_col) * width_col + w_col;\n        const int data_mask_hw_ptr = ((i * kernel_w + j) * height_col + h_col) * width_col + w_col;\n        const float offset_h = data_offset_ptr[data_offset_h_ptr];\n        const float offset_w = data_offset_ptr[data_offset_w_ptr];\n        const float mask = data_mask_ptr[data_mask_hw_ptr];\n        float val = static_cast<float>(0);\n        const float h_im = h_in + i * dilation_h + offset_h;\n        const float w_im = w_in + j * dilation_w + offset_w;\n        //if (h_im >= 0 && w_im >= 0 && h_im < height && w_im < width) {\n        if (h_im > -1 && w_im > -1 && h_im < height && w_im < width)\n        {\n          //const float map_h = i * dilation_h + offset_h;\n          //const float map_w = j * dilation_w + offset_w;\n          //const int cur_height = height - h_in;\n          //const int cur_width = width - w_in;\n          //val = dmcn_im2col_bilinear(data_im_ptr, width, cur_height, cur_width, map_h, map_w);\n          val = dmcn_im2col_bilinear(data_im_ptr, width, height, width, h_im, w_im);\n        }\n        *data_col_ptr = val * mask;\n        data_col_ptr += batch_size * height_col * width_col;\n        //data_col_ptr += height_col * width_col;\n      }\n    }\n  }\n}\n\n__global__ void modulated_deformable_col2im_gpu_kernel(const int n,\n                                                       const float *data_col, const float *data_offset, const float *data_mask,\n                                                       const int channels, const int height, const int width,\n                                                       const int kernel_h, const int kernel_w,\n                                                       const int pad_h, const int pad_w,\n                                                       const int stride_h, const int stride_w,\n                                                       const int dilation_h, const int dilation_w,\n                                                       const int channel_per_deformable_group,\n                                                       const int batch_size, const int deformable_group,\n                                                       const int height_col, const int width_col,\n                                                       float *grad_im)\n{\n  CUDA_KERNEL_LOOP(index, n)\n  {\n    const int j = (index / width_col / height_col / batch_size) % kernel_w;\n    const int i = (index / width_col / height_col / batch_size / kernel_w) % kernel_h;\n    const int c = index / width_col / height_col / batch_size / kernel_w / kernel_h;\n    // compute the start and end of the output\n\n    const int deformable_group_index = c / channel_per_deformable_group;\n\n    int w_out = index % width_col;\n    int h_out = (index / width_col) % height_col;\n    int b = (index / width_col / height_col) % batch_size;\n    int w_in = w_out * stride_w - pad_w;\n    int h_in = h_out * stride_h - pad_h;\n\n    const float *data_offset_ptr = data_offset + (b * deformable_group + deformable_group_index) * 2 * kernel_h * kernel_w * height_col * width_col;\n    const float *data_mask_ptr = data_mask + (b * deformable_group + deformable_group_index) * kernel_h * kernel_w * height_col * width_col;\n    const int data_offset_h_ptr = ((2 * (i * kernel_w + j)) * height_col + h_out) * width_col + w_out;\n    const int data_offset_w_ptr = ((2 * (i * kernel_w + j) + 1) * height_col + h_out) * width_col + w_out;\n    const int data_mask_hw_ptr = ((i * kernel_w + j) * height_col + h_out) * width_col + w_out;\n    const float offset_h = data_offset_ptr[data_offset_h_ptr];\n    const float offset_w = data_offset_ptr[data_offset_w_ptr];\n    const float mask = data_mask_ptr[data_mask_hw_ptr];\n    const float cur_inv_h_data = h_in + i * dilation_h + offset_h;\n    const float cur_inv_w_data = w_in + j * dilation_w + offset_w;\n\n    const float cur_top_grad = data_col[index] * mask;\n    const int cur_h = (int)cur_inv_h_data;\n    const int cur_w = (int)cur_inv_w_data;\n    for (int dy = -2; dy <= 2; dy++)\n    {\n      for (int dx = -2; dx <= 2; dx++)\n      {\n        if (cur_h + dy >= 0 && cur_h + dy < height &&\n            cur_w + dx >= 0 && cur_w + dx < width &&\n            abs(cur_inv_h_data - (cur_h + dy)) < 1 &&\n            abs(cur_inv_w_data - (cur_w + dx)) < 1)\n        {\n          int cur_bottom_grad_pos = ((b * channels + c) * height + cur_h + dy) * width + cur_w + dx;\n          float weight = dmcn_get_gradient_weight(cur_inv_h_data, cur_inv_w_data, cur_h + dy, cur_w + dx, height, width);\n          atomicAdd(grad_im + cur_bottom_grad_pos, weight * cur_top_grad);\n        }\n      }\n    }\n  }\n}\n\n__global__ void modulated_deformable_col2im_coord_gpu_kernel(const int n,\n                                                             const float *data_col, const float *data_im,\n                                                             const float *data_offset, const float *data_mask,\n                                                             const int channels, const int height, const int width,\n                                                             const int kernel_h, const int kernel_w,\n                                                             const int pad_h, const int pad_w,\n                                                             const int stride_h, const int stride_w,\n                                                             const int dilation_h, const int dilation_w,\n                                                             const int channel_per_deformable_group,\n                                                             const int batch_size, const int offset_channels, const int deformable_group,\n                                                             const int height_col, const int width_col,\n                                                             float *grad_offset, float *grad_mask)\n{\n  CUDA_KERNEL_LOOP(index, n)\n  {\n    float val = 0, mval = 0;\n    int w = index % width_col;\n    int h = (index / width_col) % height_col;\n    int c = (index / width_col / height_col) % offset_channels;\n    int b = (index / width_col / height_col) / offset_channels;\n    // compute the start and end of the output\n\n    const int deformable_group_index = c / (2 * kernel_h * kernel_w);\n    const int col_step = kernel_h * kernel_w;\n    int cnt = 0;\n    const float *data_col_ptr = data_col + deformable_group_index * channel_per_deformable_group * batch_size * width_col * height_col;\n    const float *data_im_ptr = data_im + (b * deformable_group + deformable_group_index) * channel_per_deformable_group / kernel_h / kernel_w * height * width;\n    const float *data_offset_ptr = data_offset + (b * deformable_group + deformable_group_index) * 2 * kernel_h * kernel_w * height_col * width_col;\n    const float *data_mask_ptr = data_mask + (b * deformable_group + deformable_group_index) * kernel_h * kernel_w * height_col * width_col;\n\n    const int offset_c = c - deformable_group_index * 2 * kernel_h * kernel_w;\n\n    for (int col_c = (offset_c / 2); col_c < channel_per_deformable_group; col_c += col_step)\n    {\n      const int col_pos = (((col_c * batch_size + b) * height_col) + h) * width_col + w;\n      const int bp_dir = offset_c % 2;\n\n      int j = (col_pos / width_col / height_col / batch_size) % kernel_w;\n      int i = (col_pos / width_col / height_col / batch_size / kernel_w) % kernel_h;\n      int w_out = col_pos % width_col;\n      int h_out = (col_pos / width_col) % height_col;\n      int w_in = w_out * stride_w - pad_w;\n      int h_in = h_out * stride_h - pad_h;\n      const int data_offset_h_ptr = (((2 * (i * kernel_w + j)) * height_col + h_out) * width_col + w_out);\n      const int data_offset_w_ptr = (((2 * (i * kernel_w + j) + 1) * height_col + h_out) * width_col + w_out);\n      const int data_mask_hw_ptr = (((i * kernel_w + j) * height_col + h_out) * width_col + w_out);\n      const float offset_h = data_offset_ptr[data_offset_h_ptr];\n      const float offset_w = data_offset_ptr[data_offset_w_ptr];\n      const float mask = data_mask_ptr[data_mask_hw_ptr];\n      float inv_h = h_in + i * dilation_h + offset_h;\n      float inv_w = w_in + j * dilation_w + offset_w;\n      if (inv_h <= -1 || inv_w <= -1 || inv_h >= height || inv_w >= width)\n      {\n        inv_h = inv_w = -2;\n      }\n      else\n      {\n        mval += data_col_ptr[col_pos] * dmcn_im2col_bilinear(data_im_ptr + cnt * height * width, width, height, width, inv_h, inv_w);\n      }\n      const float weight = dmcn_get_coordinate_weight(\n          inv_h, inv_w,\n          height, width, data_im_ptr + cnt * height * width, width, bp_dir);\n      val += weight * data_col_ptr[col_pos] * mask;\n      cnt += 1;\n    }\n    // KERNEL_ASSIGN(grad_offset[index], offset_req, val);\n    grad_offset[index] = val;\n    if (offset_c % 2 == 0)\n      // KERNEL_ASSIGN(grad_mask[(((b * deformable_group + deformable_group_index) * kernel_h * kernel_w + offset_c / 2) * height_col + h) * width_col + w], mask_req, mval);\n      grad_mask[(((b * deformable_group + deformable_group_index) * kernel_h * kernel_w + offset_c / 2) * height_col + h) * width_col + w] = mval;\n  }\n}\n\nvoid modulated_deformable_im2col_cuda(cudaStream_t stream,\n  const float* data_im, const float* data_offset, const float* data_mask,\n  const int batch_size, const int channels, const int height_im, const int width_im, \n  const int height_col, const int width_col, const int kernel_h, const int kenerl_w,\n  const int pad_h, const int pad_w, const int stride_h, const int stride_w, \n  const int dilation_h, const int dilation_w,\n  const int deformable_group, float* data_col) {\n  // num_axes should be smaller than block size\n  const int channel_per_deformable_group = channels / deformable_group;\n  const int num_kernels = channels * batch_size * height_col * width_col;\n  modulated_deformable_im2col_gpu_kernel\n      <<<GET_BLOCKS(num_kernels), CUDA_NUM_THREADS,\n          0, stream>>>(\n      num_kernels, data_im, data_offset, data_mask, height_im, width_im, kernel_h, kenerl_w,\n      pad_h, pad_w, stride_h, stride_w, dilation_h, dilation_w, channel_per_deformable_group,\n      batch_size, channels, deformable_group, height_col, width_col, data_col);\n  \n  cudaError_t err = cudaGetLastError();\n  if (err != cudaSuccess)\n  {\n    printf(\"error in modulated_deformable_im2col_cuda: %s\\n\", cudaGetErrorString(err));\n  }\n\n}\n\nvoid modulated_deformable_col2im_cuda(cudaStream_t stream,\n  const float* data_col, const float* data_offset, const float* data_mask,\n  const int batch_size, const int channels, const int height_im, const int width_im, \n  const int height_col, const int width_col, const int kernel_h, const int kernel_w,\n  const int pad_h, const int pad_w, const int stride_h, const int stride_w, \n  const int dilation_h, const int dilation_w, \n  const int deformable_group, float* grad_im){\n\n  const int channel_per_deformable_group = channels / deformable_group;\n  const int num_kernels = channels * kernel_h * kernel_w * batch_size * height_col * width_col;\n  modulated_deformable_col2im_gpu_kernel\n      <<<GET_BLOCKS(num_kernels), CUDA_NUM_THREADS,\n          0, stream>>>(\n        num_kernels, data_col, data_offset, data_mask, channels, height_im, width_im,\n        kernel_h, kernel_w, pad_h, pad_h, stride_h, stride_w,\n        dilation_h, dilation_w, channel_per_deformable_group,\n        batch_size, deformable_group, height_col, width_col, grad_im);\n  cudaError_t err = cudaGetLastError();\n  if (err != cudaSuccess)\n  {\n    printf(\"error in modulated_deformable_col2im_cuda: %s\\n\", cudaGetErrorString(err));\n  }\n\n}\n\nvoid modulated_deformable_col2im_coord_cuda(cudaStream_t stream,\n  const float* data_col, const float* data_im, const float* data_offset, const float* data_mask,\n  const int batch_size, const int channels, const int height_im, const int width_im, \n  const int height_col, const int width_col, const int kernel_h, const int kernel_w,\n  const int pad_h, const int pad_w, const int stride_h, const int stride_w, \n  const int dilation_h, const int dilation_w, \n  const int deformable_group,\n  float* grad_offset, float* grad_mask) {\n  const int num_kernels = batch_size * height_col * width_col * 2 * kernel_h * kernel_w * deformable_group;\n  const int channel_per_deformable_group = channels * kernel_h * kernel_w / deformable_group;\n  modulated_deformable_col2im_coord_gpu_kernel\n      <<<GET_BLOCKS(num_kernels), CUDA_NUM_THREADS,\n        0, stream>>>(\n        num_kernels, data_col, data_im, data_offset, data_mask, channels, height_im, width_im,\n        kernel_h, kernel_w, pad_h, pad_w, stride_h, stride_w,\n        dilation_h, dilation_w, channel_per_deformable_group,\n        batch_size, 2 * kernel_h * kernel_w * deformable_group, deformable_group, height_col, width_col, \n        grad_offset, grad_mask);\n  cudaError_t err = cudaGetLastError();\n  if (err != cudaSuccess)\n  {\n    printf(\"error in modulated_deformable_col2im_coord_cuda: %s\\n\", cudaGetErrorString(err));\n  }\n}"
  },
  {
    "path": "src/lib/models/networks/DCNv2/src/cuda/dcn_v2_im2col_cuda.h",
    "content": "/*!\n ******************* BEGIN Caffe Copyright Notice and Disclaimer ****************\n *\n * COPYRIGHT\n *\n * All contributions by the University of California:\n * Copyright (c) 2014-2017 The Regents of the University of California (Regents)\n * All rights reserved.\n *\n * All other contributions:\n * Copyright (c) 2014-2017, the respective contributors\n * All rights reserved.\n *\n * Caffe uses a shared copyright model: each contributor holds copyright over\n * their contributions to Caffe. The project versioning records all such\n * contribution and copyright details. If a contributor wants to further mark\n * their specific copyright on a particular contribution, they should indicate\n * their copyright solely in the commit message of the change when it is\n * committed.\n *\n * LICENSE\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are met:\n *\n * 1. Redistributions of source code must retain the above copyright notice, this\n * list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright notice,\n * this list of conditions and the following disclaimer in the documentation\n * and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR\n * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\n * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\n * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n *\n * CONTRIBUTION AGREEMENT\n *\n * By contributing to the BVLC/caffe repository through pull-request, comment,\n * or otherwise, the contributor releases their content to the\n * license and copyright terms herein.\n *\n ***************** END Caffe Copyright Notice and Disclaimer ********************\n *\n * Copyright (c) 2018 Microsoft\n * Licensed under The MIT License [see LICENSE for details]\n * \\file modulated_deformable_im2col.h\n * \\brief Function definitions of converting an image to\n * column matrix based on kernel, padding, dilation, and offset.\n * These functions are mainly used in deformable convolution operators.\n * \\ref: https://arxiv.org/abs/1811.11168\n * \\author Yuwen Xiong, Haozhi Qi, Jifeng Dai, Xizhou Zhu, Han Hu\n */\n\n/***************** Adapted by Charles Shang *********************/\n\n#ifndef DCN_V2_IM2COL_CUDA\n#define DCN_V2_IM2COL_CUDA\n\n#ifdef __cplusplus\nextern \"C\"\n{\n#endif\n\n  void modulated_deformable_im2col_cuda(cudaStream_t stream,\n                                        const float *data_im, const float *data_offset, const float *data_mask,\n                                        const int batch_size, const int channels, const int height_im, const int width_im,\n                                        const int height_col, const int width_col, const int kernel_h, const int kenerl_w,\n                                        const int pad_h, const int pad_w, const int stride_h, const int stride_w,\n                                        const int dilation_h, const int dilation_w,\n                                        const int deformable_group, float *data_col);\n\n  void modulated_deformable_col2im_cuda(cudaStream_t stream,\n                                        const float *data_col, const float *data_offset, const float *data_mask,\n                                        const int batch_size, const int channels, const int height_im, const int width_im,\n                                        const int height_col, const int width_col, const int kernel_h, const int kenerl_w,\n                                        const int pad_h, const int pad_w, const int stride_h, const int stride_w,\n                                        const int dilation_h, const int dilation_w,\n                                        const int deformable_group, float *grad_im);\n\n  void modulated_deformable_col2im_coord_cuda(cudaStream_t stream,\n                                         const float *data_col, const float *data_im, const float *data_offset, const float *data_mask,\n                                         const int batch_size, const int channels, const int height_im, const int width_im,\n                                         const int height_col, const int width_col, const int kernel_h, const int kenerl_w,\n                                         const int pad_h, const int pad_w, const int stride_h, const int stride_w,\n                                         const int dilation_h, const int dilation_w,\n                                         const int deformable_group,\n                                         float *grad_offset, float *grad_mask);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif"
  },
  {
    "path": "src/lib/models/networks/DCNv2/src/cuda/dcn_v2_im2col_cuda_double.cu",
    "content": "#include \"dcn_v2_im2col_cuda_double.h\"\n#include <cstdio>\n#include <algorithm>\n#include <cstring>\n\n#define CUDA_KERNEL_LOOP(i, n)                        \\\n  for (int i = blockIdx.x * blockDim.x + threadIdx.x; \\\n       i < (n);                                       \\\n       i += blockDim.x * gridDim.x)\n\nconst int CUDA_NUM_THREADS = 512;\ninline int GET_BLOCKS(const int N)\n{\n  return (N + CUDA_NUM_THREADS - 1) / CUDA_NUM_THREADS;\n}\n\n#if !defined(__CUDA_ARCH__) || __CUDA_ARCH__ >= 600\n#else\n__device__ double atomicAdd(double* address, double val)\n{\n    unsigned long long int* address_as_ull = (unsigned long long int*)address;\n    unsigned long long int old = *address_as_ull, assumed;\n    do {\n        assumed = old;\n        old = atomicCAS(address_as_ull, assumed,\n                __double_as_longlong(val + __longlong_as_double(assumed)));\n    } while (assumed != old);\n    return __longlong_as_double(old);\n}\n#endif\n\n__device__ double dmcn_im2col_bilinear(const double *bottom_data, const int data_width,\n                                       const int height, const int width, double h, double w)\n{\n  int h_low = floor(h);\n  int w_low = floor(w);\n  int h_high = h_low + 1;\n  int w_high = w_low + 1;\n\n  double lh = h - h_low;\n  double lw = w - w_low;\n  double hh = 1 - lh, hw = 1 - lw;\n\n  double v1 = 0;\n  if (h_low >= 0 && w_low >= 0)\n    v1 = bottom_data[h_low * data_width + w_low];\n  double v2 = 0;\n  if (h_low >= 0 && w_high <= width - 1)\n    v2 = bottom_data[h_low * data_width + w_high];\n  double v3 = 0;\n  if (h_high <= height - 1 && w_low >= 0)\n    v3 = bottom_data[h_high * data_width + w_low];\n  double v4 = 0;\n  if (h_high <= height - 1 && w_high <= width - 1)\n    v4 = bottom_data[h_high * data_width + w_high];\n\n  double w1 = hh * hw, w2 = hh * lw, w3 = lh * hw, w4 = lh * lw;\n\n  double val = (w1 * v1 + w2 * v2 + w3 * v3 + w4 * v4);\n  return val;\n}\n\n__device__ double dmcn_get_gradient_weight(double argmax_h, double argmax_w,\n                                           const int h, const int w, const int height, const int width)\n{\n  if (argmax_h <= -1 || argmax_h >= height || argmax_w <= -1 || argmax_w >= width)\n  {\n    //empty\n    return 0;\n  }\n\n  int argmax_h_low = floor(argmax_h);\n  int argmax_w_low = floor(argmax_w);\n  int argmax_h_high = argmax_h_low + 1;\n  int argmax_w_high = argmax_w_low + 1;\n\n  double weight = 0;\n  if (h == argmax_h_low && w == argmax_w_low)\n    weight = (h + 1 - argmax_h) * (w + 1 - argmax_w);\n  if (h == argmax_h_low && w == argmax_w_high)\n    weight = (h + 1 - argmax_h) * (argmax_w + 1 - w);\n  if (h == argmax_h_high && w == argmax_w_low)\n    weight = (argmax_h + 1 - h) * (w + 1 - argmax_w);\n  if (h == argmax_h_high && w == argmax_w_high)\n    weight = (argmax_h + 1 - h) * (argmax_w + 1 - w);\n  return weight;\n}\n\n__device__ double dmcn_get_coordinate_weight(double argmax_h, double argmax_w,\n                                             const int height, const int width, const double *im_data,\n                                             const int data_width, const int bp_dir)\n{\n  if (argmax_h <= -1 || argmax_h >= height || argmax_w <= -1 || argmax_w >= width)\n  {\n    //empty\n    return 0;\n  }\n\n  int argmax_h_low = floor(argmax_h);\n  int argmax_w_low = floor(argmax_w);\n  int argmax_h_high = argmax_h_low + 1;\n  int argmax_w_high = argmax_w_low + 1;\n\n  double weight = 0;\n\n  if (bp_dir == 0)\n  {\n    if (argmax_h_low >= 0 && argmax_w_low >= 0)\n      weight += -1 * (argmax_w_low + 1 - argmax_w) * im_data[argmax_h_low * data_width + argmax_w_low];\n    if (argmax_h_low >= 0 && argmax_w_high <= width - 1)\n      weight += -1 * (argmax_w - argmax_w_low) * im_data[argmax_h_low * data_width + argmax_w_high];\n    if (argmax_h_high <= height - 1 && argmax_w_low >= 0)\n      weight += (argmax_w_low + 1 - argmax_w) * im_data[argmax_h_high * data_width + argmax_w_low];\n    if (argmax_h_high <= height - 1 && argmax_w_high <= width - 1)\n      weight += (argmax_w - argmax_w_low) * im_data[argmax_h_high * data_width + argmax_w_high];\n  }\n  else if (bp_dir == 1)\n  {\n    if (argmax_h_low >= 0 && argmax_w_low >= 0)\n      weight += -1 * (argmax_h_low + 1 - argmax_h) * im_data[argmax_h_low * data_width + argmax_w_low];\n    if (argmax_h_low >= 0 && argmax_w_high <= width - 1)\n      weight += (argmax_h_low + 1 - argmax_h) * im_data[argmax_h_low * data_width + argmax_w_high];\n    if (argmax_h_high <= height - 1 && argmax_w_low >= 0)\n      weight += -1 * (argmax_h - argmax_h_low) * im_data[argmax_h_high * data_width + argmax_w_low];\n    if (argmax_h_high <= height - 1 && argmax_w_high <= width - 1)\n      weight += (argmax_h - argmax_h_low) * im_data[argmax_h_high * data_width + argmax_w_high];\n  }\n\n  return weight;\n}\n\n__global__ void modulated_deformable_im2col_gpu_kernel(const int n,\n                                                       const double *data_im, const double *data_offset, const double *data_mask,\n                                                       const int height, const int width, const int kernel_h, const int kernel_w,\n                                                       const int pad_h, const int pad_w,\n                                                       const int stride_h, const int stride_w,\n                                                       const int dilation_h, const int dilation_w,\n                                                       const int channel_per_deformable_group,\n                                                       const int batch_size, const int num_channels, const int deformable_group,\n                                                       const int height_col, const int width_col,\n                                                       double *data_col)\n{\n  CUDA_KERNEL_LOOP(index, n)\n  {\n    // index index of output matrix\n    const int w_col = index % width_col;\n    const int h_col = (index / width_col) % height_col;\n    const int b_col = (index / width_col / height_col) % batch_size;\n    const int c_im = (index / width_col / height_col) / batch_size;\n    const int c_col = c_im * kernel_h * kernel_w;\n\n    // compute deformable group index\n    const int deformable_group_index = c_im / channel_per_deformable_group;\n\n    const int h_in = h_col * stride_h - pad_h;\n    const int w_in = w_col * stride_w - pad_w;\n\n    double *data_col_ptr = data_col + ((c_col * batch_size + b_col) * height_col + h_col) * width_col + w_col;\n    //const double* data_im_ptr = data_im + ((b_col * num_channels + c_im) * height + h_in) * width + w_in;\n    const double *data_im_ptr = data_im + (b_col * num_channels + c_im) * height * width;\n    const double *data_offset_ptr = data_offset + (b_col * deformable_group + deformable_group_index) * 2 * kernel_h * kernel_w * height_col * width_col;\n\n    const double *data_mask_ptr = data_mask + (b_col * deformable_group + deformable_group_index) * kernel_h * kernel_w * height_col * width_col;\n\n    for (int i = 0; i < kernel_h; ++i)\n    {\n      for (int j = 0; j < kernel_w; ++j)\n      {\n        const int data_offset_h_ptr = ((2 * (i * kernel_w + j)) * height_col + h_col) * width_col + w_col;\n        const int data_offset_w_ptr = ((2 * (i * kernel_w + j) + 1) * height_col + h_col) * width_col + w_col;\n        const int data_mask_hw_ptr = ((i * kernel_w + j) * height_col + h_col) * width_col + w_col;\n        const double offset_h = data_offset_ptr[data_offset_h_ptr];\n        const double offset_w = data_offset_ptr[data_offset_w_ptr];\n        const double mask = data_mask_ptr[data_mask_hw_ptr];\n        double val = static_cast<double>(0);\n        const double h_im = h_in + i * dilation_h + offset_h;\n        const double w_im = w_in + j * dilation_w + offset_w;\n        //if (h_im >= 0 && w_im >= 0 && h_im < height && w_im < width) {\n        if (h_im > -1 && w_im > -1 && h_im < height && w_im < width)\n        {\n          //const double map_h = i * dilation_h + offset_h;\n          //const double map_w = j * dilation_w + offset_w;\n          //const int cur_height = height - h_in;\n          //const int cur_width = width - w_in;\n          //val = dmcn_im2col_bilinear(data_im_ptr, width, cur_height, cur_width, map_h, map_w);\n          val = dmcn_im2col_bilinear(data_im_ptr, width, height, width, h_im, w_im);\n        }\n        *data_col_ptr = val * mask;\n        data_col_ptr += batch_size * height_col * width_col;\n        //data_col_ptr += height_col * width_col;\n      }\n    }\n  }\n}\n\n__global__ void modulated_deformable_col2im_gpu_kernel(const int n,\n                                                       const double *data_col, const double *data_offset, const double *data_mask,\n                                                       const int channels, const int height, const int width,\n                                                       const int kernel_h, const int kernel_w,\n                                                       const int pad_h, const int pad_w,\n                                                       const int stride_h, const int stride_w,\n                                                       const int dilation_h, const int dilation_w,\n                                                       const int channel_per_deformable_group,\n                                                       const int batch_size, const int deformable_group,\n                                                       const int height_col, const int width_col,\n                                                       double *grad_im)\n{\n  CUDA_KERNEL_LOOP(index, n)\n  {\n    const int j = (index / width_col / height_col / batch_size) % kernel_w;\n    const int i = (index / width_col / height_col / batch_size / kernel_w) % kernel_h;\n    const int c = index / width_col / height_col / batch_size / kernel_w / kernel_h;\n    // compute the start and end of the output\n\n    const int deformable_group_index = c / channel_per_deformable_group;\n\n    int w_out = index % width_col;\n    int h_out = (index / width_col) % height_col;\n    int b = (index / width_col / height_col) % batch_size;\n    int w_in = w_out * stride_w - pad_w;\n    int h_in = h_out * stride_h - pad_h;\n\n    const double *data_offset_ptr = data_offset + (b * deformable_group + deformable_group_index) * 2 * kernel_h * kernel_w * height_col * width_col;\n    const double *data_mask_ptr = data_mask + (b * deformable_group + deformable_group_index) * kernel_h * kernel_w * height_col * width_col;\n    const int data_offset_h_ptr = ((2 * (i * kernel_w + j)) * height_col + h_out) * width_col + w_out;\n    const int data_offset_w_ptr = ((2 * (i * kernel_w + j) + 1) * height_col + h_out) * width_col + w_out;\n    const int data_mask_hw_ptr = ((i * kernel_w + j) * height_col + h_out) * width_col + w_out;\n    const double offset_h = data_offset_ptr[data_offset_h_ptr];\n    const double offset_w = data_offset_ptr[data_offset_w_ptr];\n    const double mask = data_mask_ptr[data_mask_hw_ptr];\n    const double cur_inv_h_data = h_in + i * dilation_h + offset_h;\n    const double cur_inv_w_data = w_in + j * dilation_w + offset_w;\n\n    const double cur_top_grad = data_col[index] * mask;\n    const int cur_h = (int)cur_inv_h_data;\n    const int cur_w = (int)cur_inv_w_data;\n    for (int dy = -2; dy <= 2; dy++)\n    {\n      for (int dx = -2; dx <= 2; dx++)\n      {\n        if (cur_h + dy >= 0 && cur_h + dy < height &&\n            cur_w + dx >= 0 && cur_w + dx < width &&\n            abs(cur_inv_h_data - (cur_h + dy)) < 1 &&\n            abs(cur_inv_w_data - (cur_w + dx)) < 1)\n        {\n          int cur_bottom_grad_pos = ((b * channels + c) * height + cur_h + dy) * width + cur_w + dx;\n          double weight = dmcn_get_gradient_weight(cur_inv_h_data, cur_inv_w_data, cur_h + dy, cur_w + dx, height, width);\n          atomicAdd(grad_im + cur_bottom_grad_pos, weight * cur_top_grad);\n        }\n      }\n    }\n  }\n}\n\n__global__ void modulated_deformable_col2im_coord_gpu_kernel(const int n,\n                                                             const double *data_col, const double *data_im,\n                                                             const double *data_offset, const double *data_mask,\n                                                             const int channels, const int height, const int width,\n                                                             const int kernel_h, const int kernel_w,\n                                                             const int pad_h, const int pad_w,\n                                                             const int stride_h, const int stride_w,\n                                                             const int dilation_h, const int dilation_w,\n                                                             const int channel_per_deformable_group,\n                                                             const int batch_size, const int offset_channels, const int deformable_group,\n                                                             const int height_col, const int width_col,\n                                                             double *grad_offset, double *grad_mask)\n{\n  CUDA_KERNEL_LOOP(index, n)\n  {\n    double val = 0, mval = 0;\n    int w = index % width_col;\n    int h = (index / width_col) % height_col;\n    int c = (index / width_col / height_col) % offset_channels;\n    int b = (index / width_col / height_col) / offset_channels;\n    // compute the start and end of the output\n\n    const int deformable_group_index = c / (2 * kernel_h * kernel_w);\n    const int col_step = kernel_h * kernel_w;\n    int cnt = 0;\n    const double *data_col_ptr = data_col + deformable_group_index * channel_per_deformable_group * batch_size * width_col * height_col;\n    const double *data_im_ptr = data_im + (b * deformable_group + deformable_group_index) * channel_per_deformable_group / kernel_h / kernel_w * height * width;\n    const double *data_offset_ptr = data_offset + (b * deformable_group + deformable_group_index) * 2 * kernel_h * kernel_w * height_col * width_col;\n    const double *data_mask_ptr = data_mask + (b * deformable_group + deformable_group_index) * kernel_h * kernel_w * height_col * width_col;\n\n    const int offset_c = c - deformable_group_index * 2 * kernel_h * kernel_w;\n\n    for (int col_c = (offset_c / 2); col_c < channel_per_deformable_group; col_c += col_step)\n    {\n      const int col_pos = (((col_c * batch_size + b) * height_col) + h) * width_col + w;\n      const int bp_dir = offset_c % 2;\n\n      int j = (col_pos / width_col / height_col / batch_size) % kernel_w;\n      int i = (col_pos / width_col / height_col / batch_size / kernel_w) % kernel_h;\n      int w_out = col_pos % width_col;\n      int h_out = (col_pos / width_col) % height_col;\n      int w_in = w_out * stride_w - pad_w;\n      int h_in = h_out * stride_h - pad_h;\n      const int data_offset_h_ptr = (((2 * (i * kernel_w + j)) * height_col + h_out) * width_col + w_out);\n      const int data_offset_w_ptr = (((2 * (i * kernel_w + j) + 1) * height_col + h_out) * width_col + w_out);\n      const int data_mask_hw_ptr = (((i * kernel_w + j) * height_col + h_out) * width_col + w_out);\n      const double offset_h = data_offset_ptr[data_offset_h_ptr];\n      const double offset_w = data_offset_ptr[data_offset_w_ptr];\n      const double mask = data_mask_ptr[data_mask_hw_ptr];\n      double inv_h = h_in + i * dilation_h + offset_h;\n      double inv_w = w_in + j * dilation_w + offset_w;\n      if (inv_h <= -1 || inv_w <= -1 || inv_h >= height || inv_w >= width)\n      {\n        inv_h = inv_w = -2;\n      }\n      else\n      {\n        mval += data_col_ptr[col_pos] * dmcn_im2col_bilinear(data_im_ptr + cnt * height * width, width, height, width, inv_h, inv_w);\n      }\n      const double weight = dmcn_get_coordinate_weight(\n          inv_h, inv_w,\n          height, width, data_im_ptr + cnt * height * width, width, bp_dir);\n      val += weight * data_col_ptr[col_pos] * mask;\n      cnt += 1;\n    }\n    // KERNEL_ASSIGN(grad_offset[index], offset_req, val);\n    grad_offset[index] = val;\n    if (offset_c % 2 == 0)\n      // KERNEL_ASSIGN(grad_mask[(((b * deformable_group + deformable_group_index) * kernel_h * kernel_w + offset_c / 2) * height_col + h) * width_col + w], mask_req, mval);\n      grad_mask[(((b * deformable_group + deformable_group_index) * kernel_h * kernel_w + offset_c / 2) * height_col + h) * width_col + w] = mval;\n  }\n}\n\nvoid modulated_deformable_im2col_cuda(cudaStream_t stream,\n                                      const double *data_im, const double *data_offset, const double *data_mask,\n                                      const int batch_size, const int channels, const int height_im, const int width_im,\n                                      const int height_col, const int width_col, const int kernel_h, const int kenerl_w,\n                                      const int pad_h, const int pad_w, const int stride_h, const int stride_w,\n                                      const int dilation_h, const int dilation_w,\n                                      const int deformable_group, double *data_col)\n{\n  // num_axes should be smaller than block size\n  const int channel_per_deformable_group = channels / deformable_group;\n  const int num_kernels = channels * batch_size * height_col * width_col;\n  modulated_deformable_im2col_gpu_kernel<<<GET_BLOCKS(num_kernels), CUDA_NUM_THREADS,\n                                           0, stream>>>(\n      num_kernels, data_im, data_offset, data_mask, height_im, width_im, kernel_h, kenerl_w,\n      pad_h, pad_w, stride_h, stride_w, dilation_h, dilation_w, channel_per_deformable_group,\n      batch_size, channels, deformable_group, height_col, width_col, data_col);\n\n  cudaError_t err = cudaGetLastError();\n  if (err != cudaSuccess)\n  {\n    printf(\"error in modulated_deformable_im2col_cuda: %s\\n\", cudaGetErrorString(err));\n  }\n}\n\nvoid modulated_deformable_col2im_cuda(cudaStream_t stream,\n                                      const double *data_col, const double *data_offset, const double *data_mask,\n                                      const int batch_size, const int channels, const int height_im, const int width_im,\n                                      const int height_col, const int width_col, const int kernel_h, const int kernel_w,\n                                      const int pad_h, const int pad_w, const int stride_h, const int stride_w,\n                                      const int dilation_h, const int dilation_w,\n                                      const int deformable_group, double *grad_im)\n{\n\n  const int channel_per_deformable_group = channels / deformable_group;\n  const int num_kernels = channels * kernel_h * kernel_w * batch_size * height_col * width_col;\n  modulated_deformable_col2im_gpu_kernel<<<GET_BLOCKS(num_kernels), CUDA_NUM_THREADS,\n                                           0, stream>>>(\n      num_kernels, data_col, data_offset, data_mask, channels, height_im, width_im,\n      kernel_h, kernel_w, pad_h, pad_h, stride_h, stride_w,\n      dilation_h, dilation_w, channel_per_deformable_group,\n      batch_size, deformable_group, height_col, width_col, grad_im);\n  cudaError_t err = cudaGetLastError();\n  if (err != cudaSuccess)\n  {\n    printf(\"error in modulated_deformable_col2im_cuda: %s\\n\", cudaGetErrorString(err));\n  }\n}\n\nvoid modulated_deformable_col2im_coord_cuda(cudaStream_t stream,\n                                            const double *data_col, const double *data_im, const double *data_offset, const double *data_mask,\n                                            const int batch_size, const int channels, const int height_im, const int width_im,\n                                            const int height_col, const int width_col, const int kernel_h, const int kernel_w,\n                                            const int pad_h, const int pad_w, const int stride_h, const int stride_w,\n                                            const int dilation_h, const int dilation_w,\n                                            const int deformable_group,\n                                            double *grad_offset, double *grad_mask)\n{\n  const int num_kernels = batch_size * height_col * width_col * 2 * kernel_h * kernel_w * deformable_group;\n  const int channel_per_deformable_group = channels * kernel_h * kernel_w / deformable_group;\n  modulated_deformable_col2im_coord_gpu_kernel<<<GET_BLOCKS(num_kernels), CUDA_NUM_THREADS,\n                                                 0, stream>>>(\n      num_kernels, data_col, data_im, data_offset, data_mask, channels, height_im, width_im,\n      kernel_h, kernel_w, pad_h, pad_w, stride_h, stride_w,\n      dilation_h, dilation_w, channel_per_deformable_group,\n      batch_size, 2 * kernel_h * kernel_w * deformable_group, deformable_group, height_col, width_col,\n      grad_offset, grad_mask);\n  cudaError_t err = cudaGetLastError();\n  if (err != cudaSuccess)\n  {\n    printf(\"error in modulated_deformable_col2im_coord_cuda: %s\\n\", cudaGetErrorString(err));\n  }\n}"
  },
  {
    "path": "src/lib/models/networks/DCNv2/src/cuda/dcn_v2_im2col_cuda_double.h",
    "content": "/*!\n ******************* BEGIN Caffe Copyright Notice and Disclaimer ****************\n *\n * COPYRIGHT\n *\n * All contributions by the University of California:\n * Copyright (c) 2014-2017 The Regents of the University of California (Regents)\n * All rights reserved.\n *\n * All other contributions:\n * Copyright (c) 2014-2017, the respective contributors\n * All rights reserved.\n *\n * Caffe uses a shared copyright model: each contributor holds copyright over\n * their contributions to Caffe. The project versioning records all such\n * contribution and copyright details. If a contributor wants to further mark\n * their specific copyright on a particular contribution, they should indicate\n * their copyright solely in the commit message of the change when it is\n * committed.\n *\n * LICENSE\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are met:\n *\n * 1. Redistributions of source code must retain the above copyright notice, this\n * list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright notice,\n * this list of conditions and the following disclaimer in the documentation\n * and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR\n * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\n * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\n * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n *\n * CONTRIBUTION AGREEMENT\n *\n * By contributing to the BVLC/caffe repository through pull-request, comment,\n * or otherwise, the contributor releases their content to the\n * license and copyright terms herein.\n *\n ***************** END Caffe Copyright Notice and Disclaimer ********************\n *\n * Copyright (c) 2018 Microsoft\n * Licensed under The MIT License [see LICENSE for details]\n * \\file modulated_deformable_im2col.h\n * \\brief Function definitions of converting an image to\n * column matrix based on kernel, padding, dilation, and offset.\n * These functions are mainly used in deformable convolution operators.\n * \\ref: https://arxiv.org/abs/1811.11168\n * \\author Yuwen Xiong, Haozhi Qi, Jifeng Dai, Xizhou Zhu, Han Hu\n */\n\n/***************** Adapted by Charles Shang *********************/\n\n#ifndef DCN_V2_IM2COL_CUDA_DOUBLE\n#define DCN_V2_IM2COL_CUDA_DOUBLE\n\n#ifdef __cplusplus\nextern \"C\"\n{\n#endif\n\n  void modulated_deformable_im2col_cuda(cudaStream_t stream,\n                                        const double *data_im, const double *data_offset, const double *data_mask,\n                                        const int batch_size, const int channels, const int height_im, const int width_im,\n                                        const int height_col, const int width_col, const int kernel_h, const int kenerl_w,\n                                        const int pad_h, const int pad_w, const int stride_h, const int stride_w,\n                                        const int dilation_h, const int dilation_w,\n                                        const int deformable_group, double *data_col);\n\n  void modulated_deformable_col2im_cuda(cudaStream_t stream,\n                                        const double *data_col, const double *data_offset, const double *data_mask,\n                                        const int batch_size, const int channels, const int height_im, const int width_im,\n                                        const int height_col, const int width_col, const int kernel_h, const int kenerl_w,\n                                        const int pad_h, const int pad_w, const int stride_h, const int stride_w,\n                                        const int dilation_h, const int dilation_w,\n                                        const int deformable_group, double *grad_im);\n\n  void modulated_deformable_col2im_coord_cuda(cudaStream_t stream,\n                                         const double *data_col, const double *data_im, const double *data_offset, const double *data_mask,\n                                         const int batch_size, const int channels, const int height_im, const int width_im,\n                                         const int height_col, const int width_col, const int kernel_h, const int kenerl_w,\n                                         const int pad_h, const int pad_w, const int stride_h, const int stride_w,\n                                         const int dilation_h, const int dilation_w,\n                                         const int deformable_group,\n                                         double *grad_offset, double *grad_mask);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif"
  },
  {
    "path": "src/lib/models/networks/DCNv2/src/cuda/dcn_v2_psroi_pooling_cuda.cu",
    "content": "/*!\n * Copyright (c) 2017 Microsoft\n * Licensed under The MIT License [see LICENSE for details]\n * \\file deformable_psroi_pooling.cu\n * \\brief\n * \\author Yi Li, Guodong Zhang, Jifeng Dai\n*/\n/***************** Adapted by Charles Shang *********************/\n#include \"dcn_v2_psroi_pooling_cuda.h\"\n#include <cstdio>\n#include <algorithm>\n#include <cstring>\n\n#define CUDA_KERNEL_LOOP(i, n)                        \\\n  for (int i = blockIdx.x * blockDim.x + threadIdx.x; \\\n       i < (n);                                       \\\n       i += blockDim.x * gridDim.x)\n\nconst int CUDA_NUM_THREADS = 1024;\ninline int GET_BLOCKS(const int N)\n{\n  return (N + CUDA_NUM_THREADS - 1) / CUDA_NUM_THREADS;\n}\n\n__device__ float bilinear_interp(\n    const float *data,\n    const float x,\n    const float y,\n    const int width,\n    const int height)\n{\n  int x1 = floor(x);\n  int x2 = ceil(x);\n  int y1 = floor(y);\n  int y2 = ceil(y);\n  float dist_x = (float)(x - x1);\n  float dist_y = (float)(y - y1);\n  float value11 = data[y1 * width + x1];\n  float value12 = data[y2 * width + x1];\n  float value21 = data[y1 * width + x2];\n  float value22 = data[y2 * width + x2];\n  float value = (1 - dist_x) * (1 - dist_y) * value11 + (1 - dist_x) * dist_y * value12 + dist_x * (1 - dist_y) * value21 + dist_x * dist_y * value22;\n  return value;\n}\n\n__global__ void DeformablePSROIPoolForwardKernel(\n    const int count,\n    const float *bottom_data,\n    const float spatial_scale,\n    const int channels,\n    const int height, const int width,\n    const int pooled_height, const int pooled_width,\n    const float *bottom_rois, const float *bottom_trans,\n    const int no_trans,\n    const float trans_std,\n    const int sample_per_part,\n    const int output_dim,\n    const int group_size,\n    const int part_size,\n    const int num_classes,\n    const int channels_each_class,\n    float *top_data,\n    float *top_count)\n{\n  CUDA_KERNEL_LOOP(index, count)\n  {\n    // The output is in order (n, ctop, ph, pw)\n    int pw = index % pooled_width;\n    int ph = (index / pooled_width) % pooled_height;\n    int ctop = (index / pooled_width / pooled_height) % output_dim;\n    int n = index / pooled_width / pooled_height / output_dim;\n\n    // [start, end) interval for spatial sampling\n    const float *offset_bottom_rois = bottom_rois + n * 5;\n    int roi_batch_ind = offset_bottom_rois[0];\n    float roi_start_w = (float)(round(offset_bottom_rois[1])) * spatial_scale - 0.5;\n    float roi_start_h = (float)(round(offset_bottom_rois[2])) * spatial_scale - 0.5;\n    float roi_end_w = (float)(round(offset_bottom_rois[3]) + 1.) * spatial_scale - 0.5;\n    float roi_end_h = (float)(round(offset_bottom_rois[4]) + 1.) * spatial_scale - 0.5;\n\n    // Force too small ROIs to be 1x1\n    float roi_width = max(roi_end_w - roi_start_w, 0.1); //avoid 0\n    float roi_height = max(roi_end_h - roi_start_h, 0.1);\n\n    // Compute w and h at bottom\n    float bin_size_h = roi_height / (float)(pooled_height);\n    float bin_size_w = roi_width / (float)(pooled_width);\n\n    float sub_bin_size_h = bin_size_h / (float)(sample_per_part);\n    float sub_bin_size_w = bin_size_w / (float)(sample_per_part);\n\n    int part_h = floor((float)(ph) / pooled_height * part_size);\n    int part_w = floor((float)(pw) / pooled_width * part_size);\n    int class_id = ctop / channels_each_class;\n    float trans_x = no_trans ? (float)(0) : bottom_trans[(((n * num_classes + class_id) * 2) * part_size + part_h) * part_size + part_w] * trans_std;\n    float trans_y = no_trans ? (float)(0) : bottom_trans[(((n * num_classes + class_id) * 2 + 1) * part_size + part_h) * part_size + part_w] * trans_std;\n\n    float wstart = (float)(pw)*bin_size_w + roi_start_w;\n    wstart += trans_x * roi_width;\n    float hstart = (float)(ph)*bin_size_h + roi_start_h;\n    hstart += trans_y * roi_height;\n\n    float sum = 0;\n    int count = 0;\n    int gw = floor((float)(pw)*group_size / pooled_width);\n    int gh = floor((float)(ph)*group_size / pooled_height);\n    gw = min(max(gw, 0), group_size - 1);\n    gh = min(max(gh, 0), group_size - 1);\n\n    const float *offset_bottom_data = bottom_data + (roi_batch_ind * channels) * height * width;\n    for (int ih = 0; ih < sample_per_part; ih++)\n    {\n      for (int iw = 0; iw < sample_per_part; iw++)\n      {\n        float w = wstart + iw * sub_bin_size_w;\n        float h = hstart + ih * sub_bin_size_h;\n        // bilinear interpolation\n        if (w < -0.5 || w > width - 0.5 || h < -0.5 || h > height - 0.5)\n        {\n          continue;\n        }\n        w = min(max(w, 0.), width - 1.);\n        h = min(max(h, 0.), height - 1.);\n        int c = (ctop * group_size + gh) * group_size + gw;\n        float val = bilinear_interp(offset_bottom_data + c * height * width, w, h, width, height);\n        sum += val;\n        count++;\n      }\n    }\n    top_data[index] = count == 0 ? (float)(0) : sum / count;\n    top_count[index] = count;\n  }\n}\n\n__global__ void DeformablePSROIPoolBackwardAccKernel(\n    const int count,\n    const float *top_diff,\n    const float *top_count,\n    const int num_rois,\n    const float spatial_scale,\n    const int channels,\n    const int height, const int width,\n    const int pooled_height, const int pooled_width,\n    const int output_dim,\n    float *bottom_data_diff, float *bottom_trans_diff,\n    const float *bottom_data,\n    const float *bottom_rois,\n    const float *bottom_trans,\n    const int no_trans,\n    const float trans_std,\n    const int sample_per_part,\n    const int group_size,\n    const int part_size,\n    const int num_classes,\n    const int channels_each_class)\n{\n  CUDA_KERNEL_LOOP(index, count)\n  {\n    // The output is in order (n, ctop, ph, pw)\n    int pw = index % pooled_width;\n    int ph = (index / pooled_width) % pooled_height;\n    int ctop = (index / pooled_width / pooled_height) % output_dim;\n    int n = index / pooled_width / pooled_height / output_dim;\n\n    // [start, end) interval for spatial sampling\n    const float *offset_bottom_rois = bottom_rois + n * 5;\n    int roi_batch_ind = offset_bottom_rois[0];\n    float roi_start_w = (float)(round(offset_bottom_rois[1])) * spatial_scale - 0.5;\n    float roi_start_h = (float)(round(offset_bottom_rois[2])) * spatial_scale - 0.5;\n    float roi_end_w = (float)(round(offset_bottom_rois[3]) + 1.) * spatial_scale - 0.5;\n    float roi_end_h = (float)(round(offset_bottom_rois[4]) + 1.) * spatial_scale - 0.5;\n\n    // Force too small ROIs to be 1x1\n    float roi_width = max(roi_end_w - roi_start_w, 0.1); //avoid 0\n    float roi_height = max(roi_end_h - roi_start_h, 0.1);\n\n    // Compute w and h at bottom\n    float bin_size_h = roi_height / (float)(pooled_height);\n    float bin_size_w = roi_width / (float)(pooled_width);\n\n    float sub_bin_size_h = bin_size_h / (float)(sample_per_part);\n    float sub_bin_size_w = bin_size_w / (float)(sample_per_part);\n\n    int part_h = floor((float)(ph) / pooled_height * part_size);\n    int part_w = floor((float)(pw) / pooled_width * part_size);\n    int class_id = ctop / channels_each_class;\n    float trans_x = no_trans ? (float)(0) : bottom_trans[(((n * num_classes + class_id) * 2) * part_size + part_h) * part_size + part_w] * trans_std;\n    float trans_y = no_trans ? (float)(0) : bottom_trans[(((n * num_classes + class_id) * 2 + 1) * part_size + part_h) * part_size + part_w] * trans_std;\n\n    float wstart = (float)(pw)*bin_size_w + roi_start_w;\n    wstart += trans_x * roi_width;\n    float hstart = (float)(ph)*bin_size_h + roi_start_h;\n    hstart += trans_y * roi_height;\n\n    if (top_count[index] <= 0)\n    {\n      continue;\n    }\n    float diff_val = top_diff[index] / top_count[index];\n    const float *offset_bottom_data = bottom_data + roi_batch_ind * channels * height * width;\n    float *offset_bottom_data_diff = bottom_data_diff + roi_batch_ind * channels * height * width;\n    int gw = floor((float)(pw)*group_size / pooled_width);\n    int gh = floor((float)(ph)*group_size / pooled_height);\n    gw = min(max(gw, 0), group_size - 1);\n    gh = min(max(gh, 0), group_size - 1);\n\n    for (int ih = 0; ih < sample_per_part; ih++)\n    {\n      for (int iw = 0; iw < sample_per_part; iw++)\n      {\n        float w = wstart + iw * sub_bin_size_w;\n        float h = hstart + ih * sub_bin_size_h;\n        // bilinear interpolation\n        if (w < -0.5 || w > width - 0.5 || h < -0.5 || h > height - 0.5)\n        {\n          continue;\n        }\n        w = min(max(w, 0.), width - 1.);\n        h = min(max(h, 0.), height - 1.);\n        int c = (ctop * group_size + gh) * group_size + gw;\n        // backward on feature\n        int x0 = floor(w);\n        int x1 = ceil(w);\n        int y0 = floor(h);\n        int y1 = ceil(h);\n        float dist_x = w - x0, dist_y = h - y0;\n        float q00 = (1 - dist_x) * (1 - dist_y);\n        float q01 = (1 - dist_x) * dist_y;\n        float q10 = dist_x * (1 - dist_y);\n        float q11 = dist_x * dist_y;\n        int bottom_index_base = c * height * width;\n        atomicAdd(offset_bottom_data_diff + bottom_index_base + y0 * width + x0, q00 * diff_val);\n        atomicAdd(offset_bottom_data_diff + bottom_index_base + y1 * width + x0, q01 * diff_val);\n        atomicAdd(offset_bottom_data_diff + bottom_index_base + y0 * width + x1, q10 * diff_val);\n        atomicAdd(offset_bottom_data_diff + bottom_index_base + y1 * width + x1, q11 * diff_val);\n\n        if (no_trans)\n        {\n          continue;\n        }\n        float U00 = offset_bottom_data[bottom_index_base + y0 * width + x0];\n        float U01 = offset_bottom_data[bottom_index_base + y1 * width + x0];\n        float U10 = offset_bottom_data[bottom_index_base + y0 * width + x1];\n        float U11 = offset_bottom_data[bottom_index_base + y1 * width + x1];\n        float diff_x = (U11 * dist_y + U10 * (1 - dist_y) - U01 * dist_y - U00 * (1 - dist_y)) * trans_std * diff_val;\n        diff_x *= roi_width;\n        float diff_y = (U11 * dist_x + U01 * (1 - dist_x) - U10 * dist_x - U00 * (1 - dist_x)) * trans_std * diff_val;\n        diff_y *= roi_height;\n\n        atomicAdd(bottom_trans_diff + (((n * num_classes + class_id) * 2) * part_size + part_h) * part_size + part_w, diff_x);\n        atomicAdd(bottom_trans_diff + (((n * num_classes + class_id) * 2 + 1) * part_size + part_h) * part_size + part_w, diff_y);\n      }\n    }\n  }\n}\n\nvoid DeformablePSROIPoolForward(cudaStream_t stream,\n                                const float *data,\n                                const float *bbox,\n                                const float *trans,\n                                float *out,\n                                float *top_count,\n                                const int batch,\n                                const int channels,\n                                const int height,\n                                const int width,\n                                const int num_bbox,\n                                const int channels_trans,\n                                const int no_trans,\n                                const float spatial_scale,\n                                const int output_dim,\n                                const int group_size,\n                                const int pooled_size,\n                                const int part_size,\n                                const int sample_per_part,\n                                const float trans_std)\n{\n\n  const float *bottom_data = data;\n  const float *bottom_rois = bbox;\n  const float *bottom_trans = no_trans ? NULL : trans;\n  float *top_data = out;\n  float *top_count_data = top_count;\n\n  const int pooled_height = pooled_size;\n  const int pooled_width = pooled_size;\n  const int count = num_bbox * output_dim * pooled_height * pooled_width;\n  const int num_classes = no_trans ? 1 : channels_trans / 2;\n  const int channels_each_class = no_trans ? output_dim : output_dim / num_classes;\n\n  DeformablePSROIPoolForwardKernel<<<GET_BLOCKS(count), CUDA_NUM_THREADS, 0, stream>>>(\n      count, bottom_data, spatial_scale, channels, height, width, pooled_height, pooled_width,\n      bottom_rois, bottom_trans, no_trans, trans_std, sample_per_part, output_dim,\n      group_size, part_size, num_classes, channels_each_class, top_data, top_count_data);\n\n  cudaError_t err = cudaGetLastError();\n  if (err != cudaSuccess)\n  {\n    printf(\"error in DeformablePSROIPoolForward: %s\\n\", cudaGetErrorString(err));\n  }\n}\n\nvoid DeformablePSROIPoolBackwardAcc(cudaStream_t stream,\n                                    const float *out_grad,\n                                    const float *data,\n                                    const float *bbox,\n                                    const float *trans,\n                                    const float *top_count,\n                                    float *in_grad,\n                                    float *trans_grad,\n                                    const int batch,\n                                    const int channels,\n                                    const int height,\n                                    const int width,\n                                    const int num_bbox,\n                                    const int channels_trans,\n                                    const int no_trans,\n                                    const float spatial_scale,\n                                    const int output_dim,\n                                    const int group_size,\n                                    const int pooled_size,\n                                    const int part_size,\n                                    const int sample_per_part,\n                                    const float trans_std)\n{\n  // LOG(INFO) << \"DeformablePSROIPoolBackward\";\n  const float *top_diff = out_grad;\n  const float *bottom_data = data;\n  const float *bottom_rois = bbox;\n  const float *bottom_trans = no_trans ? NULL : trans;\n  float *bottom_data_diff = in_grad;\n  float *bottom_trans_diff = no_trans ? NULL : trans_grad;\n  const float *top_count_data = top_count;\n\n  const int num_rois = num_bbox;\n  const int pooled_height = pooled_size;\n  const int pooled_width = pooled_size;\n  const int count = num_bbox * output_dim * pooled_height * pooled_width;\n  const int num_classes = no_trans ? 1 : channels_trans / 2;\n  const int channels_each_class = no_trans ? output_dim : output_dim / num_classes;\n\n  DeformablePSROIPoolBackwardAccKernel<<<GET_BLOCKS(count), CUDA_NUM_THREADS, 0, stream>>>(\n      count, top_diff, top_count_data, num_rois, spatial_scale, channels, height, width,\n      pooled_height, pooled_width, output_dim, bottom_data_diff, bottom_trans_diff,\n      bottom_data, bottom_rois, bottom_trans, no_trans, trans_std, sample_per_part,\n      group_size, part_size, num_classes, channels_each_class);\n\n  cudaError_t err = cudaGetLastError();\n  if (err != cudaSuccess)\n  {\n    printf(\"error in DeformablePSROIPoolForward: %s\\n\", cudaGetErrorString(err));\n  }\n}"
  },
  {
    "path": "src/lib/models/networks/DCNv2/src/cuda/dcn_v2_psroi_pooling_cuda.h",
    "content": "/*!\n * Copyright (c) 2017 Microsoft\n * Licensed under The MIT License [see LICENSE for details]\n * \\file deformable_psroi_pooling.cu\n * \\brief\n * \\author Yi Li, Guodong Zhang, Jifeng Dai\n*/\n/***************** Adapted by Charles Shang *********************/\n\n#ifndef DCN_V2_PSROI_POOLING_CUDA\n#define DCN_V2_PSROI_POOLING_CUDA\n\n#ifdef __cplusplus\nextern \"C\"\n{\n#endif\n\n    void DeformablePSROIPoolForward(cudaStream_t stream,\n                                    const float *data,\n                                    const float *bbox,\n                                    const float *trans,\n                                    float *out,\n                                    float *top_count,\n                                    const int batch,\n                                    const int channels,\n                                    const int height,\n                                    const int width,\n                                    const int num_bbox,\n                                    const int channels_trans,\n                                    const int no_trans,\n                                    const float spatial_scale,\n                                    const int output_dim,\n                                    const int group_size,\n                                    const int pooled_size,\n                                    const int part_size,\n                                    const int sample_per_part,\n                                    const float trans_std);\n\n    void DeformablePSROIPoolBackwardAcc(cudaStream_t stream,\n                                        const float *out_grad,\n                                        const float *data,\n                                        const float *bbox,\n                                        const float *trans,\n                                        const float *top_count,\n                                        float *in_grad,\n                                        float *trans_grad,\n                                        const int batch,\n                                        const int channels,\n                                        const int height,\n                                        const int width,\n                                        const int num_bbox,\n                                        const int channels_trans,\n                                        const int no_trans,\n                                        const float spatial_scale,\n                                        const int output_dim,\n                                        const int group_size,\n                                        const int pooled_size,\n                                        const int part_size,\n                                        const int sample_per_part,\n                                        const float trans_std);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif"
  },
  {
    "path": "src/lib/models/networks/DCNv2/src/cuda/dcn_v2_psroi_pooling_cuda_double.cu",
    "content": "/*!\n * Copyright (c) 2017 Microsoft\n * Licensed under The MIT License [see LICENSE for details]\n * \\file deformable_psroi_pooling.cu\n * \\brief\n * \\author Yi Li, Guodong Zhang, Jifeng Dai\n*/\n/***************** Adapted by Charles Shang *********************/\n#include \"dcn_v2_psroi_pooling_cuda_double.h\"\n#include <cstdio>\n#include <algorithm>\n#include <cstring>\n\n#define CUDA_KERNEL_LOOP(i, n)                        \\\n  for (int i = blockIdx.x * blockDim.x + threadIdx.x; \\\n       i < (n);                                       \\\n       i += blockDim.x * gridDim.x)\n\nconst int CUDA_NUM_THREADS = 1024;\ninline int GET_BLOCKS(const int N)\n{\n  return (N + CUDA_NUM_THREADS - 1) / CUDA_NUM_THREADS;\n}\n\n#if !defined(__CUDA_ARCH__) || __CUDA_ARCH__ >= 600\n#else\n__device__ double atomicAdd(double* address, double val)\n{\n    unsigned long long int* address_as_ull = (unsigned long long int*)address;\n    unsigned long long int old = *address_as_ull, assumed;\n    do {\n        assumed = old;\n        old = atomicCAS(address_as_ull, assumed,\n                __double_as_longlong(val + __longlong_as_double(assumed)));\n    } while (assumed != old);\n    return __longlong_as_double(old);\n}\n#endif\n\n__device__ double bilinear_interp(\n    const double *data,\n    const double x,\n    const double y,\n    const int width,\n    const int height)\n{\n  int x1 = floor(x);\n  int x2 = ceil(x);\n  int y1 = floor(y);\n  int y2 = ceil(y);\n  double dist_x = (double)(x - x1);\n  double dist_y = (double)(y - y1);\n  double value11 = data[y1 * width + x1];\n  double value12 = data[y2 * width + x1];\n  double value21 = data[y1 * width + x2];\n  double value22 = data[y2 * width + x2];\n  double value = (1 - dist_x) * (1 - dist_y) * value11 + (1 - dist_x) * dist_y * value12 + dist_x * (1 - dist_y) * value21 + dist_x * dist_y * value22;\n  return value;\n}\n\n__global__ void DeformablePSROIPoolForwardKernel(\n    const int count,\n    const double *bottom_data,\n    const double spatial_scale,\n    const int channels,\n    const int height, const int width,\n    const int pooled_height, const int pooled_width,\n    const double *bottom_rois, const double *bottom_trans,\n    const int no_trans,\n    const double trans_std,\n    const int sample_per_part,\n    const int output_dim,\n    const int group_size,\n    const int part_size,\n    const int num_classes,\n    const int channels_each_class,\n    double *top_data,\n    double *top_count)\n{\n  CUDA_KERNEL_LOOP(index, count)\n  {\n    // The output is in order (n, ctop, ph, pw)\n    int pw = index % pooled_width;\n    int ph = (index / pooled_width) % pooled_height;\n    int ctop = (index / pooled_width / pooled_height) % output_dim;\n    int n = index / pooled_width / pooled_height / output_dim;\n\n    // [start, end) interval for spatial sampling\n    const double *offset_bottom_rois = bottom_rois + n * 5;\n    int roi_batch_ind = offset_bottom_rois[0];\n    double roi_start_w = (double)(round(offset_bottom_rois[1])) * spatial_scale - 0.5;\n    double roi_start_h = (double)(round(offset_bottom_rois[2])) * spatial_scale - 0.5;\n    double roi_end_w = (double)(round(offset_bottom_rois[3]) + 1.) * spatial_scale - 0.5;\n    double roi_end_h = (double)(round(offset_bottom_rois[4]) + 1.) * spatial_scale - 0.5;\n\n    // Force too small ROIs to be 1x1\n    double roi_width = max(roi_end_w - roi_start_w, 0.1); //avoid 0\n    double roi_height = max(roi_end_h - roi_start_h, 0.1);\n\n    // Compute w and h at bottom\n    double bin_size_h = roi_height / (double)(pooled_height);\n    double bin_size_w = roi_width / (double)(pooled_width);\n\n    double sub_bin_size_h = bin_size_h / (double)(sample_per_part);\n    double sub_bin_size_w = bin_size_w / (double)(sample_per_part);\n\n    int part_h = floor((double)(ph) / pooled_height * part_size);\n    int part_w = floor((double)(pw) / pooled_width * part_size);\n    int class_id = ctop / channels_each_class;\n    double trans_x = no_trans ? (double)(0) : bottom_trans[(((n * num_classes + class_id) * 2) * part_size + part_h) * part_size + part_w] * trans_std;\n    double trans_y = no_trans ? (double)(0) : bottom_trans[(((n * num_classes + class_id) * 2 + 1) * part_size + part_h) * part_size + part_w] * trans_std;\n\n    double wstart = (double)(pw)*bin_size_w + roi_start_w;\n    wstart += trans_x * roi_width;\n    double hstart = (double)(ph)*bin_size_h + roi_start_h;\n    hstart += trans_y * roi_height;\n\n    double sum = 0;\n    int count = 0;\n    int gw = floor((double)(pw)*group_size / pooled_width);\n    int gh = floor((double)(ph)*group_size / pooled_height);\n    gw = min(max(gw, 0), group_size - 1);\n    gh = min(max(gh, 0), group_size - 1);\n\n    const double *offset_bottom_data = bottom_data + (roi_batch_ind * channels) * height * width;\n    for (int ih = 0; ih < sample_per_part; ih++)\n    {\n      for (int iw = 0; iw < sample_per_part; iw++)\n      {\n        double w = wstart + iw * sub_bin_size_w;\n        double h = hstart + ih * sub_bin_size_h;\n        // bilinear interpolation\n        if (w < -0.5 || w > width - 0.5 || h < -0.5 || h > height - 0.5)\n        {\n          continue;\n        }\n        w = min(max(w, 0.), width - 1.);\n        h = min(max(h, 0.), height - 1.);\n        int c = (ctop * group_size + gh) * group_size + gw;\n        double val = bilinear_interp(offset_bottom_data + c * height * width, w, h, width, height);\n        sum += val;\n        count++;\n      }\n    }\n    top_data[index] = count == 0 ? (double)(0) : sum / count;\n    top_count[index] = count;\n  }\n}\n\n__global__ void DeformablePSROIPoolBackwardAccKernel(\n    const int count,\n    const double *top_diff,\n    const double *top_count,\n    const int num_rois,\n    const double spatial_scale,\n    const int channels,\n    const int height, const int width,\n    const int pooled_height, const int pooled_width,\n    const int output_dim,\n    double *bottom_data_diff, double *bottom_trans_diff,\n    const double *bottom_data,\n    const double *bottom_rois,\n    const double *bottom_trans,\n    const int no_trans,\n    const double trans_std,\n    const int sample_per_part,\n    const int group_size,\n    const int part_size,\n    const int num_classes,\n    const int channels_each_class)\n{\n  CUDA_KERNEL_LOOP(index, count)\n  {\n    // The output is in order (n, ctop, ph, pw)\n    int pw = index % pooled_width;\n    int ph = (index / pooled_width) % pooled_height;\n    int ctop = (index / pooled_width / pooled_height) % output_dim;\n    int n = index / pooled_width / pooled_height / output_dim;\n\n    // [start, end) interval for spatial sampling\n    const double *offset_bottom_rois = bottom_rois + n * 5;\n    int roi_batch_ind = offset_bottom_rois[0];\n    double roi_start_w = (double)(round(offset_bottom_rois[1])) * spatial_scale - 0.5;\n    double roi_start_h = (double)(round(offset_bottom_rois[2])) * spatial_scale - 0.5;\n    double roi_end_w = (double)(round(offset_bottom_rois[3]) + 1.) * spatial_scale - 0.5;\n    double roi_end_h = (double)(round(offset_bottom_rois[4]) + 1.) * spatial_scale - 0.5;\n\n    // Force too small ROIs to be 1x1\n    double roi_width = max(roi_end_w - roi_start_w, 0.1); //avoid 0\n    double roi_height = max(roi_end_h - roi_start_h, 0.1);\n\n    // Compute w and h at bottom\n    double bin_size_h = roi_height / (double)(pooled_height);\n    double bin_size_w = roi_width / (double)(pooled_width);\n\n    double sub_bin_size_h = bin_size_h / (double)(sample_per_part);\n    double sub_bin_size_w = bin_size_w / (double)(sample_per_part);\n\n    int part_h = floor((double)(ph) / pooled_height * part_size);\n    int part_w = floor((double)(pw) / pooled_width * part_size);\n    int class_id = ctop / channels_each_class;\n    double trans_x = no_trans ? (double)(0) : bottom_trans[(((n * num_classes + class_id) * 2) * part_size + part_h) * part_size + part_w] * trans_std;\n    double trans_y = no_trans ? (double)(0) : bottom_trans[(((n * num_classes + class_id) * 2 + 1) * part_size + part_h) * part_size + part_w] * trans_std;\n\n    double wstart = (double)(pw)*bin_size_w + roi_start_w;\n    wstart += trans_x * roi_width;\n    double hstart = (double)(ph)*bin_size_h + roi_start_h;\n    hstart += trans_y * roi_height;\n\n    if (top_count[index] <= 0)\n    {\n      continue;\n    }\n    double diff_val = top_diff[index] / top_count[index];\n    const double *offset_bottom_data = bottom_data + roi_batch_ind * channels * height * width;\n    double *offset_bottom_data_diff = bottom_data_diff + roi_batch_ind * channels * height * width;\n    int gw = floor((double)(pw)*group_size / pooled_width);\n    int gh = floor((double)(ph)*group_size / pooled_height);\n    gw = min(max(gw, 0), group_size - 1);\n    gh = min(max(gh, 0), group_size - 1);\n\n    for (int ih = 0; ih < sample_per_part; ih++)\n    {\n      for (int iw = 0; iw < sample_per_part; iw++)\n      {\n        double w = wstart + iw * sub_bin_size_w;\n        double h = hstart + ih * sub_bin_size_h;\n        // bilinear interpolation\n        if (w < -0.5 || w > width - 0.5 || h < -0.5 || h > height - 0.5)\n        {\n          continue;\n        }\n        w = min(max(w, 0.), width - 1.);\n        h = min(max(h, 0.), height - 1.);\n        int c = (ctop * group_size + gh) * group_size + gw;\n        // backward on feature\n        int x0 = floor(w);\n        int x1 = ceil(w);\n        int y0 = floor(h);\n        int y1 = ceil(h);\n        double dist_x = w - x0, dist_y = h - y0;\n        double q00 = (1 - dist_x) * (1 - dist_y);\n        double q01 = (1 - dist_x) * dist_y;\n        double q10 = dist_x * (1 - dist_y);\n        double q11 = dist_x * dist_y;\n        int bottom_index_base = c * height * width;\n        atomicAdd(offset_bottom_data_diff + bottom_index_base + y0 * width + x0, q00 * diff_val);\n        atomicAdd(offset_bottom_data_diff + bottom_index_base + y1 * width + x0, q01 * diff_val);\n        atomicAdd(offset_bottom_data_diff + bottom_index_base + y0 * width + x1, q10 * diff_val);\n        atomicAdd(offset_bottom_data_diff + bottom_index_base + y1 * width + x1, q11 * diff_val);\n\n        if (no_trans)\n        {\n          continue;\n        }\n        double U00 = offset_bottom_data[bottom_index_base + y0 * width + x0];\n        double U01 = offset_bottom_data[bottom_index_base + y1 * width + x0];\n        double U10 = offset_bottom_data[bottom_index_base + y0 * width + x1];\n        double U11 = offset_bottom_data[bottom_index_base + y1 * width + x1];\n        double diff_x = (U11 * dist_y + U10 * (1 - dist_y) - U01 * dist_y - U00 * (1 - dist_y)) * trans_std * diff_val;\n        diff_x *= roi_width;\n        double diff_y = (U11 * dist_x + U01 * (1 - dist_x) - U10 * dist_x - U00 * (1 - dist_x)) * trans_std * diff_val;\n        diff_y *= roi_height;\n\n        atomicAdd(bottom_trans_diff + (((n * num_classes + class_id) * 2) * part_size + part_h) * part_size + part_w, diff_x);\n        atomicAdd(bottom_trans_diff + (((n * num_classes + class_id) * 2 + 1) * part_size + part_h) * part_size + part_w, diff_y);\n      }\n    }\n  }\n}\n\nvoid DeformablePSROIPoolForward(cudaStream_t stream,\n                                const double *data,\n                                const double *bbox,\n                                const double *trans,\n                                double *out,\n                                double *top_count,\n                                const int batch,\n                                const int channels,\n                                const int height,\n                                const int width,\n                                const int num_bbox,\n                                const int channels_trans,\n                                const int no_trans,\n                                const double spatial_scale,\n                                const int output_dim,\n                                const int group_size,\n                                const int pooled_size,\n                                const int part_size,\n                                const int sample_per_part,\n                                const double trans_std)\n{\n\n  const double *bottom_data = data;\n  const double *bottom_rois = bbox;\n  const double *bottom_trans = no_trans ? NULL : trans;\n  double *top_data = out;\n  double *top_count_data = top_count;\n\n  const int pooled_height = pooled_size;\n  const int pooled_width = pooled_size;\n  const int count = num_bbox * output_dim * pooled_height * pooled_width;\n  const int num_classes = no_trans ? 1 : channels_trans / 2;\n  const int channels_each_class = no_trans ? output_dim : output_dim / num_classes;\n\n  DeformablePSROIPoolForwardKernel<<<GET_BLOCKS(count), CUDA_NUM_THREADS, 0, stream>>>(\n      count, bottom_data, spatial_scale, channels, height, width, pooled_height, pooled_width,\n      bottom_rois, bottom_trans, no_trans, trans_std, sample_per_part, output_dim,\n      group_size, part_size, num_classes, channels_each_class, top_data, top_count_data);\n\n  cudaError_t err = cudaGetLastError();\n  if (err != cudaSuccess)\n  {\n    printf(\"error in DeformablePSROIPoolForward: %s\\n\", cudaGetErrorString(err));\n  }\n}\n\nvoid DeformablePSROIPoolBackwardAcc(cudaStream_t stream,\n                                    const double *out_grad,\n                                    const double *data,\n                                    const double *bbox,\n                                    const double *trans,\n                                    const double *top_count,\n                                    double *in_grad,\n                                    double *trans_grad,\n                                    const int batch,\n                                    const int channels,\n                                    const int height,\n                                    const int width,\n                                    const int num_bbox,\n                                    const int channels_trans,\n                                    const int no_trans,\n                                    const double spatial_scale,\n                                    const int output_dim,\n                                    const int group_size,\n                                    const int pooled_size,\n                                    const int part_size,\n                                    const int sample_per_part,\n                                    const double trans_std)\n{\n  // LOG(INFO) << \"DeformablePSROIPoolBackward\";\n  const double *top_diff = out_grad;\n  const double *bottom_data = data;\n  const double *bottom_rois = bbox;\n  const double *bottom_trans = no_trans ? NULL : trans;\n  double *bottom_data_diff = in_grad;\n  double *bottom_trans_diff = no_trans ? NULL : trans_grad;\n  const double *top_count_data = top_count;\n\n  const int num_rois = num_bbox;\n  const int pooled_height = pooled_size;\n  const int pooled_width = pooled_size;\n  const int count = num_bbox * output_dim * pooled_height * pooled_width;\n  const int num_classes = no_trans ? 1 : channels_trans / 2;\n  const int channels_each_class = no_trans ? output_dim : output_dim / num_classes;\n\n  DeformablePSROIPoolBackwardAccKernel<<<GET_BLOCKS(count), CUDA_NUM_THREADS, 0, stream>>>(\n      count, top_diff, top_count_data, num_rois, spatial_scale, channels, height, width,\n      pooled_height, pooled_width, output_dim, bottom_data_diff, bottom_trans_diff,\n      bottom_data, bottom_rois, bottom_trans, no_trans, trans_std, sample_per_part,\n      group_size, part_size, num_classes, channels_each_class);\n\n  cudaError_t err = cudaGetLastError();\n  if (err != cudaSuccess)\n  {\n    printf(\"error in DeformablePSROIPoolForward: %s\\n\", cudaGetErrorString(err));\n  }\n}"
  },
  {
    "path": "src/lib/models/networks/DCNv2/src/cuda/dcn_v2_psroi_pooling_cuda_double.h",
    "content": "/*!\n * Copyright (c) 2017 Microsoft\n * Licensed under The MIT License [see LICENSE for details]\n * \\file deformable_psroi_pooling.cu\n * \\brief\n * \\author Yi Li, Guodong Zhang, Jifeng Dai\n*/\n/***************** Adapted by Charles Shang *********************/\n\n#ifndef DCN_V2_PSROI_POOLING_CUDA_DOUBLE\n#define DCN_V2_PSROI_POOLING_CUDA_DOUBLE\n\n#ifdef __cplusplus\nextern \"C\"\n{\n#endif\n\n    void DeformablePSROIPoolForward(cudaStream_t stream,\n                                    const double *data,\n                                    const double *bbox,\n                                    const double *trans,\n                                    double *out,\n                                    double *top_count,\n                                    const int batch,\n                                    const int channels,\n                                    const int height,\n                                    const int width,\n                                    const int num_bbox,\n                                    const int channels_trans,\n                                    const int no_trans,\n                                    const double spatial_scale,\n                                    const int output_dim,\n                                    const int group_size,\n                                    const int pooled_size,\n                                    const int part_size,\n                                    const int sample_per_part,\n                                    const double trans_std);\n\n    void DeformablePSROIPoolBackwardAcc(cudaStream_t stream,\n                                        const double *out_grad,\n                                        const double *data,\n                                        const double *bbox,\n                                        const double *trans,\n                                        const double *top_count,\n                                        double *in_grad,\n                                        double *trans_grad,\n                                        const int batch,\n                                        const int channels,\n                                        const int height,\n                                        const int width,\n                                        const int num_bbox,\n                                        const int channels_trans,\n                                        const int no_trans,\n                                        const double spatial_scale,\n                                        const int output_dim,\n                                        const int group_size,\n                                        const int pooled_size,\n                                        const int part_size,\n                                        const int sample_per_part,\n                                        const double trans_std);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif"
  },
  {
    "path": "src/lib/models/networks/DCNv2/src/dcn_v2.c",
    "content": "#include <TH/TH.h>\n#include <stdio.h>\n#include <math.h>\n\nvoid dcn_v2_forward(THFloatTensor *input, THFloatTensor *weight,\n                        THFloatTensor *bias, THFloatTensor *ones,\n                        THFloatTensor *offset, THFloatTensor *mask,\n                        THFloatTensor *output, THFloatTensor *columns,\n                        const int pad_h, const int pad_w,\n                        const int stride_h, const int stride_w,\n                        const int dilation_h, const int dilation_w,\n                        const int deformable_group)\n{\n    printf(\"only implemented in GPU\");\n}\n    void dcn_v2_backward(THFloatTensor *input, THFloatTensor *weight,\n                         THFloatTensor *bias, THFloatTensor *ones,\n                         THFloatTensor *offset, THFloatTensor *mask,\n                         THFloatTensor *output, THFloatTensor *columns,\n                         THFloatTensor *grad_input, THFloatTensor *grad_weight,\n                         THFloatTensor *grad_bias, THFloatTensor *grad_offset,\n                         THFloatTensor *grad_mask, THFloatTensor *grad_output,\n                         int kernel_h, int kernel_w,\n                         int stride_h, int stride_w,\n                         int pad_h, int pad_w,\n                         int dilation_h, int dilation_w,\n                         int deformable_group)\n{\n    printf(\"only implemented in GPU\");\n}"
  },
  {
    "path": "src/lib/models/networks/DCNv2/src/dcn_v2.h",
    "content": "void dcn_v2_forward(THFloatTensor *input, THFloatTensor *weight,\n                        THFloatTensor *bias, THFloatTensor *ones,\n                        THFloatTensor *offset, THFloatTensor *mask,\n                        THFloatTensor *output, THFloatTensor *columns,\n                        const int pad_h, const int pad_w,\n                        const int stride_h, const int stride_w,\n                        const int dilation_h, const int dilation_w,\n                        const int deformable_group);\nvoid dcn_v2_backward(THFloatTensor *input, THFloatTensor *weight,\n                        THFloatTensor *bias, THFloatTensor *ones,\n                        THFloatTensor *offset, THFloatTensor *mask,\n                        THFloatTensor *output, THFloatTensor *columns,\n                        THFloatTensor *grad_input, THFloatTensor *grad_weight,\n                        THFloatTensor *grad_bias, THFloatTensor *grad_offset,\n                        THFloatTensor *grad_mask, THFloatTensor *grad_output,\n                        int kernel_h, int kernel_w,\n                        int stride_h, int stride_w,\n                        int pad_h, int pad_w,\n                        int dilation_h, int dilation_w,\n                        int deformable_group);"
  },
  {
    "path": "src/lib/models/networks/DCNv2/src/dcn_v2_cuda.c",
    "content": "#include <THC/THC.h>\n#include \"cuda/dcn_v2_im2col_cuda.h\"\n#include \"cuda/dcn_v2_psroi_pooling_cuda.h\"\n\nextern THCState *state;\n\n// author: Charles Shang\n// https://github.com/torch/cunn/blob/master/lib/THCUNN/generic/SpatialConvolutionMM.cu\n\nvoid dcn_v2_cuda_forward(THCudaTensor *input, THCudaTensor *weight,\n                         THCudaTensor *bias, THCudaTensor *ones,\n                         THCudaTensor *offset, THCudaTensor *mask,\n                         THCudaTensor *output, THCudaTensor *columns,\n                         int kernel_h, int kernel_w,\n                         const int stride_h, const int stride_w,\n                         const int pad_h, const int pad_w,\n                         const int dilation_h, const int dilation_w,\n                         const int deformable_group)\n{\n    THCAssertSameGPU(THCudaTensor_checkGPU(state, 8, input, weight, bias, ones, offset, mask, output, columns));\n    THArgCheck(THCudaTensor_isContiguous(state, input), 1, \"input tensor has to be contiguous\");\n    THArgCheck(THCudaTensor_isContiguous(state, weight), 2, \"weight tensor has to be contiguous\");\n    \n    const int batch = THCudaTensor_size(state, input, 0);\n    const int channels = THCudaTensor_size(state, input, 1);\n    const int height = THCudaTensor_size(state, input, 2);\n    const int width = THCudaTensor_size(state, input, 3);\n\n    const int channels_out = THCudaTensor_size(state, weight, 0);\n    const int channels_kernel = THCudaTensor_size(state, weight, 1);\n    const int kernel_h_ = THCudaTensor_size(state, weight, 2);\n    const int kernel_w_ = THCudaTensor_size(state, weight, 3);\n    if (kernel_h_ != kernel_h || kernel_w_ != kernel_w)\n        THError(\"Input shape and kernel shape wont match: (%d x %d vs %d x %d).\", \n        kernel_h_, kernel_w, kernel_h_, kernel_w_);\n    if (channels != channels_kernel)\n        THError(\"Input shape and kernel channels wont match: (%d vs %d).\", \n        channels, channels_kernel);\n\n    const int height_out = (height + 2 * pad_h - (dilation_h * (kernel_h - 1) + 1)) / stride_h + 1;\n    const int width_out = (width + 2 * pad_w - (dilation_w * (kernel_w - 1) + 1)) / stride_w + 1;\n\n    if (THCudaTensor_nDimension(state, ones) != 2 ||\n        THCudaTensor_size(state, ones, 0) * THCudaTensor_size(state, ones, 1) < height_out * width_out)\n    {\n        // Resize plane and fill with ones...\n        THCudaTensor_resize2d(state, ones, height_out, width_out);\n        THCudaTensor_fill(state, ones, 1);\n    }\n\n    // resize output\n    THCudaTensor_resize4d(state, output, batch, channels_out, height_out, width_out);\n    // resize temporary columns\n    THCudaTensor_resize2d(state, columns, channels * kernel_h * kernel_w, 1 * height_out * width_out);\n\n    THCudaTensor *input_n = THCudaTensor_new(state);\n    THCudaTensor *offset_n = THCudaTensor_new(state);\n    THCudaTensor *mask_n = THCudaTensor_new(state);\n    THCudaTensor *output_n = THCudaTensor_new(state);\n\n    for (int b = 0; b < batch; b++)\n    {\n        THCudaTensor_select(state, input_n, input, 0, b);\n        THCudaTensor_select(state, offset_n, offset, 0, b);\n        THCudaTensor_select(state, mask_n, mask, 0, b);\n        THCudaTensor_select(state, output_n, output, 0, b);\n\n        // Do Bias first:\n        // M,N,K are dims of matrix A and B\n        // (see http://docs.nvidia.com/cuda/cublas/#cublas-lt-t-gt-gemm)\n        // (N x 1) (1 x M)\n        long m_ = channels_out;\n        long n_ = height_out * width_out;\n        long k_ = 1;\n        THCudaBlas_Sgemm(state, 't', 'n', n_, m_, k_, 1.0f,\n                         THCudaTensor_data(state, ones), k_,\n                         THCudaTensor_data(state, bias), k_, 0.0f,\n                         THCudaTensor_data(state, output_n), n_);\n\n        modulated_deformable_im2col_cuda(THCState_getCurrentStream(state),\n                                         THCudaTensor_data(state, input_n), THCudaTensor_data(state, offset_n),\n                                         THCudaTensor_data(state, mask_n),\n                                         1, channels, height, width,\n                                         height_out, width_out, kernel_h, kernel_w,\n                                         pad_h, pad_w, stride_h, stride_w, dilation_h, dilation_w,\n                                         deformable_group, THCudaTensor_data(state, columns));\n\n        //(k * m)  x  (m * n)\n        // Y = WC\n        long m = channels_out;\n        long n = height_out * width_out;\n        long k = channels * kernel_h * kernel_w;\n        THCudaBlas_Sgemm(state, 'n', 'n', n, m, k, 1.0f,\n                         THCudaTensor_data(state, columns), n,\n                         THCudaTensor_data(state, weight), k, 1.0f,\n                         THCudaTensor_data(state, output_n), n);\n    }\n    THCudaTensor_free(state, input_n);\n    THCudaTensor_free(state, offset_n);\n    THCudaTensor_free(state, mask_n);\n    THCudaTensor_free(state, output_n);\n}\n\nvoid dcn_v2_cuda_backward(THCudaTensor *input, THCudaTensor *weight,\n                          THCudaTensor *bias, THCudaTensor *ones,\n                          THCudaTensor *offset, THCudaTensor *mask,\n                          THCudaTensor *columns,\n                          THCudaTensor *grad_input, THCudaTensor *grad_weight,\n                          THCudaTensor *grad_bias, THCudaTensor *grad_offset,\n                          THCudaTensor *grad_mask, THCudaTensor *grad_output,\n                          int kernel_h, int kernel_w,\n                          int stride_h, int stride_w,\n                          int pad_h, int pad_w,\n                          int dilation_h, int dilation_w,\n                          int deformable_group)\n{\n    THCAssertSameGPU(THCudaTensor_checkGPU(state, 13, input, weight, bias, ones, offset, mask, columns,\n                                           grad_input, grad_weight, grad_bias, grad_offset, grad_mask, grad_output));\n    THArgCheck(THCudaTensor_isContiguous(state, input), 1, \"input tensor has to be contiguous\");\n    THArgCheck(THCudaTensor_isContiguous(state, weight), 2, \"weight tensor has to be contiguous\");\n\n    const int batch = THCudaTensor_size(state, input, 0);\n    const int channels = THCudaTensor_size(state, input, 1);\n    const int height = THCudaTensor_size(state, input, 2);\n    const int width = THCudaTensor_size(state, input, 3);\n\n    const int channels_out = THCudaTensor_size(state, weight, 0);\n    const int channels_kernel = THCudaTensor_size(state, weight, 1);\n    const int kernel_h_ = THCudaTensor_size(state, weight, 2);\n    const int kernel_w_ = THCudaTensor_size(state, weight, 3);\n    if (kernel_h_ != kernel_h || kernel_w_ != kernel_w)\n        THError(\"Input shape and kernel shape wont match: (%d x %d vs %d x %d).\", \n        kernel_h_, kernel_w, kernel_h_, kernel_w_);\n    if (channels != channels_kernel)\n        THError(\"Input shape and kernel channels wont match: (%d vs %d).\", \n        channels, channels_kernel);\n\n    const int height_out = (height + 2 * pad_h - (dilation_h * (kernel_h - 1) + 1)) / stride_h + 1;\n    const int width_out = (width + 2 * pad_w - (dilation_w * (kernel_w - 1) + 1)) / stride_w + 1;\n\n    if (THCudaTensor_nDimension(state, ones) != 2 ||\n        THCudaTensor_size(state, ones, 0) * THCudaTensor_size(state, ones, 1) < height_out * width_out)\n    {\n        // Resize plane and fill with ones...\n        THCudaTensor_resize2d(state, ones, height_out, width_out);\n        THCudaTensor_fill(state, ones, 1.0f);\n    }\n\n    THCudaTensor_resize4d(state, grad_input, batch, channels, height, width);\n    THCudaTensor_resize2d(state, columns, channels * kernel_h * kernel_w, height_out * width_out);\n\n    THCudaTensor *input_n = THCudaTensor_new(state);\n    THCudaTensor *offset_n = THCudaTensor_new(state);\n    THCudaTensor *mask_n = THCudaTensor_new(state);\n\n    THCudaTensor *grad_output_n = THCudaTensor_new(state);\n    THCudaTensor *grad_input_n = THCudaTensor_new(state);\n    THCudaTensor *grad_offset_n = THCudaTensor_new(state);\n    THCudaTensor *grad_mask_n = THCudaTensor_new(state);\n\n    for (int b = 0; b < batch; b++)\n    {\n        THCudaTensor_select(state, input_n, input, 0, b);\n        THCudaTensor_select(state, offset_n, offset, 0, b);\n        THCudaTensor_select(state, mask_n, mask, 0, b);\n        THCudaTensor_select(state, grad_output_n, grad_output, 0, b);\n        THCudaTensor_select(state, grad_input_n, grad_input, 0, b);\n        THCudaTensor_select(state, grad_offset_n, grad_offset, 0, b);\n        THCudaTensor_select(state, grad_mask_n, grad_mask, 0, b);\n\n        long m = channels * kernel_h * kernel_w;\n        long n = height_out * width_out;\n        long k = channels_out;\n\n        THCudaBlas_Sgemm(state, 'n', 't', n, m, k, 1.0f,\n                         THCudaTensor_data(state, grad_output_n), n,\n                         THCudaTensor_data(state, weight), m, 0.0f,\n                         THCudaTensor_data(state, columns), n);\n\n        // gradient w.r.t. input coordinate data\n        modulated_deformable_col2im_coord_cuda(THCState_getCurrentStream(state),\n                                               THCudaTensor_data(state, columns),\n                                               THCudaTensor_data(state, input_n),\n                                               THCudaTensor_data(state, offset_n),\n                                               THCudaTensor_data(state, mask_n),\n                                               1, channels, height, width,\n                                               height_out, width_out, kernel_h, kernel_w,\n                                               pad_h, pad_w, stride_h, stride_w,\n                                               dilation_h, dilation_w, deformable_group,\n                                               THCudaTensor_data(state, grad_offset_n),\n                                               THCudaTensor_data(state, grad_mask_n));\n        // gradient w.r.t. input data\n        modulated_deformable_col2im_cuda(THCState_getCurrentStream(state),\n                                         THCudaTensor_data(state, columns),\n                                         THCudaTensor_data(state, offset_n),\n                                         THCudaTensor_data(state, mask_n),\n                                         1, channels, height, width,\n                                         height_out, width_out, kernel_h, kernel_w,\n                                         pad_h, pad_w, stride_h, stride_w,\n                                         dilation_h, dilation_w, deformable_group,\n                                         THCudaTensor_data(state, grad_input_n));\n\n        // gradient w.r.t. weight, dWeight should accumulate across the batch and group\n        modulated_deformable_im2col_cuda(THCState_getCurrentStream(state),\n                                         THCudaTensor_data(state, input_n),\n                                         THCudaTensor_data(state, offset_n),\n                                         THCudaTensor_data(state, mask_n),\n                                         1, channels, height, width,\n                                         height_out, width_out, kernel_h, kernel_w,\n                                         pad_h, pad_w, stride_h, stride_w,\n                                         dilation_h, dilation_w, deformable_group,\n                                         THCudaTensor_data(state, columns));\n        long m_ = channels_out;\n        long n_ = channels * kernel_h * kernel_w;\n        long k_ = height_out * width_out;\n\n        THCudaBlas_Sgemm(state, 't', 'n', n_, m_, k_, 1.0f,\n                         THCudaTensor_data(state, columns), k_,\n                         THCudaTensor_data(state, grad_output_n), k_, 1.0f,\n                         THCudaTensor_data(state, grad_weight), n_);\n\n        // gradient w.r.t. bias\n        // long m_ = channels_out;\n        // long k__ = height_out * width_out;\n        THCudaBlas_Sgemv(state,\n                         't',\n                         k_, m_, 1.0f,\n                         THCudaTensor_data(state, grad_output_n), k_,\n                         THCudaTensor_data(state, ones), 1, 1.0f,\n                         THCudaTensor_data(state, grad_bias), 1);\n    }\n\n    THCudaTensor_free(state, input_n);\n    THCudaTensor_free(state, offset_n);\n    THCudaTensor_free(state, mask_n);\n\n    THCudaTensor_free(state, grad_output_n);\n    THCudaTensor_free(state, grad_input_n);\n    THCudaTensor_free(state, grad_offset_n);\n    THCudaTensor_free(state, grad_mask_n);\n}\n\nvoid dcn_v2_psroi_pooling_cuda_forward(THCudaTensor * input, THCudaTensor * bbox,\n                                       THCudaTensor * trans, \n                                       THCudaTensor * out, THCudaTensor * top_count,\n                                       const int no_trans,\n                                       const float spatial_scale,\n                                       const int output_dim,\n                                       const int group_size,\n                                       const int pooled_size,\n                                       const int part_size,\n                                       const int sample_per_part,\n                                       const float trans_std)\n{\n    THArgCheck(THCudaTensor_isContiguous(state, input), 1, \"input tensor has to be contiguous\");\n    THCAssertSameGPU(THCudaTensor_checkGPU(state, 5, input, bbox, trans, out, top_count));\n\n    const int batch = THCudaTensor_size(state, input, 0);\n    const int channels = THCudaTensor_size(state, input, 1);\n    const int height = THCudaTensor_size(state, input, 2);\n    const int width = THCudaTensor_size(state, input, 3);\n    const int channels_trans = no_trans? 2 : THCudaTensor_size(state, trans, 1);\n\n    const int num_bbox = THCudaTensor_size(state, bbox, 0);\n    if (num_bbox != THCudaTensor_size(state, out, 0))\n        THError(\"Output shape and bbox number wont match: (%d vs %d).\", \n                THCudaTensor_size(state, out, 0), num_bbox);\n\n    DeformablePSROIPoolForward(THCState_getCurrentStream(state),\n                               THCudaTensor_data(state, input),\n                               THCudaTensor_data(state, bbox),\n                               THCudaTensor_data(state, trans),\n                               THCudaTensor_data(state, out),\n                               THCudaTensor_data(state, top_count),\n                               batch, channels, height, width,\n                               num_bbox, \n                               channels_trans, \n                               no_trans, \n                               spatial_scale,\n                               output_dim, \n                               group_size, \n                               pooled_size, \n                               part_size,\n                               sample_per_part, \n                               trans_std);\n}\n\nvoid dcn_v2_psroi_pooling_cuda_backward(THCudaTensor * out_grad, \n                                        THCudaTensor * input, THCudaTensor * bbox,\n                                        THCudaTensor * trans, THCudaTensor * top_count,\n                                        THCudaTensor * input_grad, THCudaTensor * trans_grad,\n                                        const int no_trans,\n                                        const float spatial_scale,\n                                        const int output_dim,\n                                        const int group_size,\n                                        const int pooled_size,\n                                        const int part_size,\n                                        const int sample_per_part,\n                                        const float trans_std)\n{\n    THArgCheck(THCudaTensor_isContiguous(state, out_grad), 0, \"out_grad tensor has to be contiguous\");\n    THArgCheck(THCudaTensor_isContiguous(state, input), 1, \"input tensor has to be contiguous\");\n    THCAssertSameGPU(THCudaTensor_checkGPU(state, 7, input, bbox, trans, out_grad, top_count,\n                    input_grad, trans_grad));\n\n    const int batch = THCudaTensor_size(state, input, 0);\n    const int channels = THCudaTensor_size(state, input, 1);\n    const int height = THCudaTensor_size(state, input, 2);\n    const int width = THCudaTensor_size(state, input, 3);\n    const int channels_trans = no_trans? 2 : THCudaTensor_size(state, trans, 1);\n\n    const int num_bbox = THCudaTensor_size(state, bbox, 0);\n    if (num_bbox != THCudaTensor_size(state, out_grad, 0))\n        THError(\"Output shape and bbox number wont match: (%d vs %d).\", \n                THCudaTensor_size(state, out_grad, 0), num_bbox);\n\n    DeformablePSROIPoolBackwardAcc(THCState_getCurrentStream(state),\n                                   THCudaTensor_data(state, out_grad),\n                                   THCudaTensor_data(state, input),\n                                   THCudaTensor_data(state, bbox),\n                                   THCudaTensor_data(state, trans),\n                                   THCudaTensor_data(state, top_count),\n                                   THCudaTensor_data(state, input_grad),\n                                   THCudaTensor_data(state, trans_grad),\n                                   batch, channels, height, width, num_bbox,\n                                   channels_trans, \n                                   no_trans, \n                                   spatial_scale, \n                                   output_dim,\n                                   group_size, \n                                   pooled_size, \n                                   part_size,\n                                   sample_per_part, \n                                   trans_std);\n}"
  },
  {
    "path": "src/lib/models/networks/DCNv2/src/dcn_v2_cuda.h",
    "content": "// #ifndef DCN_V2_CUDA\n// #define DCN_V2_CUDA\n\n// #ifdef __cplusplus\n// extern \"C\"\n// {\n// #endif\n\nvoid dcn_v2_cuda_forward(THCudaTensor *input, THCudaTensor *weight,\n                         THCudaTensor *bias, THCudaTensor *ones,\n                         THCudaTensor *offset, THCudaTensor *mask,\n                         THCudaTensor *output, THCudaTensor *columns,\n                         int kernel_h, int kernel_w,\n                         const int stride_h, const int stride_w,\n                         const int pad_h, const int pad_w,\n                         const int dilation_h, const int dilation_w,\n                         const int deformable_group);\nvoid dcn_v2_cuda_backward(THCudaTensor *input, THCudaTensor *weight,\n                          THCudaTensor *bias, THCudaTensor *ones,\n                          THCudaTensor *offset, THCudaTensor *mask,\n                          THCudaTensor *columns,\n                          THCudaTensor *grad_input, THCudaTensor *grad_weight,\n                          THCudaTensor *grad_bias, THCudaTensor *grad_offset,\n                          THCudaTensor *grad_mask, THCudaTensor *grad_output,\n                          int kernel_h, int kernel_w,\n                          int stride_h, int stride_w,\n                          int pad_h, int pad_w,\n                          int dilation_h, int dilation_w,\n                          int deformable_group);\n\nvoid dcn_v2_psroi_pooling_cuda_forward(THCudaTensor * input, THCudaTensor * bbox,\n                                       THCudaTensor * trans, \n                                       THCudaTensor * out, THCudaTensor * top_count,\n                                       const int no_trans,\n                                       const float spatial_scale,\n                                       const int output_dim,\n                                       const int group_size,\n                                       const int pooled_size,\n                                       const int part_size,\n                                       const int sample_per_part,\n                                       const float trans_std);\n\nvoid dcn_v2_psroi_pooling_cuda_backward(THCudaTensor * out_grad, \n                                        THCudaTensor * input, THCudaTensor * bbox,\n                                        THCudaTensor * trans, THCudaTensor * top_count,\n                                        THCudaTensor * input_grad, THCudaTensor * trans_grad,\n                                        const int no_trans,\n                                        const float spatial_scale,\n                                        const int output_dim,\n                                        const int group_size,\n                                        const int pooled_size,\n                                        const int part_size,\n                                        const int sample_per_part,\n                                        const float trans_std);\n\n// #ifdef __cplusplus\n// }\n// #endif\n\n// #endif"
  },
  {
    "path": "src/lib/models/networks/DCNv2/src/dcn_v2_cuda_double.c",
    "content": "#include <THC/THC.h>\n#include \"cuda/dcn_v2_im2col_cuda_double.h\"\n#include \"cuda/dcn_v2_psroi_pooling_cuda_double.h\"\n\nextern THCState *state;\n\n// author: Charles Shang\n// https://github.com/torch/cunn/blob/master/lib/THCUNN/generic/SpatialConvolutionMM.cu\n\nvoid dcn_v2_cuda_forward(THCudaDoubleTensor *input, THCudaDoubleTensor *weight,\n                         THCudaDoubleTensor *bias, THCudaDoubleTensor *ones,\n                         THCudaDoubleTensor *offset, THCudaDoubleTensor *mask,\n                         THCudaDoubleTensor *output, THCudaDoubleTensor *columns,\n                         int kernel_h, int kernel_w,\n                         const int stride_h, const int stride_w,\n                         const int pad_h, const int pad_w,\n                         const int dilation_h, const int dilation_w,\n                         const int deformable_group)\n{\n    THCAssertSameGPU(THCudaDoubleTensor_checkGPU(state, 8, input, weight, bias, ones, offset, mask, output, columns));\n    THArgCheck(THCudaDoubleTensor_isContiguous(state, input), 1, \"input tensor has to be contiguous\");\n    THArgCheck(THCudaDoubleTensor_isContiguous(state, weight), 2, \"weight tensor has to be contiguous\");\n\n    input = THCudaDoubleTensor_newContiguous(state, input);\n    offset = THCudaDoubleTensor_newContiguous(state, offset);\n    mask = THCudaDoubleTensor_newContiguous(state, mask);\n    weight = THCudaDoubleTensor_newContiguous(state, weight);\n\n    const int batch = THCudaDoubleTensor_size(state, input, 0);\n    const int channels = THCudaDoubleTensor_size(state, input, 1);\n    const int height = THCudaDoubleTensor_size(state, input, 2);\n    const int width = THCudaDoubleTensor_size(state, input, 3);\n\n    const int channels_out = THCudaDoubleTensor_size(state, weight, 0);\n    const int channels_kernel = THCudaDoubleTensor_size(state, weight, 1);\n    const int kernel_h_ = THCudaDoubleTensor_size(state, weight, 2);\n    const int kernel_w_ = THCudaDoubleTensor_size(state, weight, 3);\n    if (kernel_h_ != kernel_h || kernel_w_ != kernel_w)\n        THError(\"Input shape and kernel shape wont match: (%d x %d vs %d x %d).\",\n                kernel_h_, kernel_w, kernel_h_, kernel_w_);\n    if (channels != channels_kernel)\n        THError(\"Input shape and kernel channels wont match: (%d vs %d).\",\n                channels, channels_kernel);\n\n    const int height_out = (height + 2 * pad_h - (dilation_h * (kernel_h - 1) + 1)) / stride_h + 1;\n    const int width_out = (width + 2 * pad_w - (dilation_w * (kernel_w - 1) + 1)) / stride_w + 1;\n\n    if (THCudaDoubleTensor_nDimension(state, ones) != 2 ||\n        THCudaDoubleTensor_size(state, ones, 0) * THCudaDoubleTensor_size(state, ones, 1) < height_out * width_out)\n    {\n        // Resize plane and fill with ones...\n        THCudaDoubleTensor_resize2d(state, ones, height_out, width_out);\n        THCudaDoubleTensor_fill(state, ones, 1);\n    }\n\n    // resize output\n    THCudaDoubleTensor_resize4d(state, output, batch, channels_out, height_out, width_out);\n    // resize temporary columns\n    THCudaDoubleTensor_resize2d(state, columns, channels * kernel_h * kernel_w, 1 * height_out * width_out);\n\n    THCudaDoubleTensor *input_n = THCudaDoubleTensor_new(state);\n    THCudaDoubleTensor *offset_n = THCudaDoubleTensor_new(state);\n    THCudaDoubleTensor *mask_n = THCudaDoubleTensor_new(state);\n    THCudaDoubleTensor *output_n = THCudaDoubleTensor_new(state);\n\n    for (int b = 0; b < batch; b++)\n    {\n        THCudaDoubleTensor_select(state, input_n, input, 0, b);\n        THCudaDoubleTensor_select(state, offset_n, offset, 0, b);\n        THCudaDoubleTensor_select(state, mask_n, mask, 0, b);\n        THCudaDoubleTensor_select(state, output_n, output, 0, b);\n\n        // Do Bias first:\n        // M,N,K are dims of matrix A and B\n        // (see http://docs.nvidia.com/cuda/cublas/#cublas-lt-t-gt-gemm)\n        // (N x 1) (1 x M)\n        long m_ = channels_out;\n        long n_ = height_out * width_out;\n        long k_ = 1;\n        THCudaBlas_Dgemm(state, 't', 'n', n_, m_, k_, 1.0,\n                         THCudaDoubleTensor_data(state, ones), k_,\n                         THCudaDoubleTensor_data(state, bias), k_, 0.0,\n                         THCudaDoubleTensor_data(state, output_n), n_);\n\n        modulated_deformable_im2col_cuda(THCState_getCurrentStream(state),\n                                         THCudaDoubleTensor_data(state, input_n), THCudaDoubleTensor_data(state, offset_n),\n                                         THCudaDoubleTensor_data(state, mask_n),\n                                         1, channels, height, width,\n                                         height_out, width_out, kernel_h, kernel_w,\n                                         pad_h, pad_w, stride_h, stride_w, dilation_h, dilation_w,\n                                         deformable_group, THCudaDoubleTensor_data(state, columns));\n\n        //(k * m)  x  (m * n)\n        // Y = WC\n        long m = channels_out;\n        long n = height_out * width_out;\n        long k = channels * kernel_h * kernel_w;\n        THCudaBlas_Dgemm(state, 'n', 'n', n, m, k, 1.0f,\n                         THCudaDoubleTensor_data(state, columns), n,\n                         THCudaDoubleTensor_data(state, weight), k, 1.0f,\n                         THCudaDoubleTensor_data(state, output_n), n);\n    }\n    THCudaDoubleTensor_free(state, input_n);\n    THCudaDoubleTensor_free(state, offset_n);\n    THCudaDoubleTensor_free(state, mask_n);\n    THCudaDoubleTensor_free(state, output_n);\n\n    THCudaDoubleTensor_free(state, input);\n    THCudaDoubleTensor_free(state, offset);\n    THCudaDoubleTensor_free(state, mask);\n    THCudaDoubleTensor_free(state, weight);\n}\n\nvoid dcn_v2_cuda_backward(THCudaDoubleTensor *input, THCudaDoubleTensor *weight,\n                          THCudaDoubleTensor *bias, THCudaDoubleTensor *ones,\n                          THCudaDoubleTensor *offset, THCudaDoubleTensor *mask,\n                          THCudaDoubleTensor *columns,\n                          THCudaDoubleTensor *grad_input, THCudaDoubleTensor *grad_weight,\n                          THCudaDoubleTensor *grad_bias, THCudaDoubleTensor *grad_offset,\n                          THCudaDoubleTensor *grad_mask, THCudaDoubleTensor *grad_output,\n                          int kernel_h, int kernel_w,\n                          int stride_h, int stride_w,\n                          int pad_h, int pad_w,\n                          int dilation_h, int dilation_w,\n                          int deformable_group)\n{\n    THCAssertSameGPU(THCudaDoubleTensor_checkGPU(state, 13, input, weight, bias, ones, offset, mask, columns,\n                                                 grad_input, grad_weight, grad_bias, grad_offset, grad_mask, grad_output));\n    THArgCheck(THCudaDoubleTensor_isContiguous(state, input), 1, \"input tensor has to be contiguous\");\n    THArgCheck(THCudaDoubleTensor_isContiguous(state, weight), 2, \"weight tensor has to be contiguous\");\n\n    input = THCudaDoubleTensor_newContiguous(state, input);\n    offset = THCudaDoubleTensor_newContiguous(state, offset);\n    mask = THCudaDoubleTensor_newContiguous(state, mask);\n    weight = THCudaDoubleTensor_newContiguous(state, weight);\n    grad_output = THCudaDoubleTensor_newContiguous(state, grad_output);\n\n    const int batch = THCudaDoubleTensor_size(state, input, 0);\n    const int channels = THCudaDoubleTensor_size(state, input, 1);\n    const int height = THCudaDoubleTensor_size(state, input, 2);\n    const int width = THCudaDoubleTensor_size(state, input, 3);\n\n    const int channels_out = THCudaDoubleTensor_size(state, weight, 0);\n    const int channels_kernel = THCudaDoubleTensor_size(state, weight, 1);\n    const int kernel_h_ = THCudaDoubleTensor_size(state, weight, 2);\n    const int kernel_w_ = THCudaDoubleTensor_size(state, weight, 3);\n    if (kernel_h_ != kernel_h || kernel_w_ != kernel_w)\n        THError(\"Input shape and kernel shape wont match: (%d x %d vs %d x %d).\",\n                kernel_h_, kernel_w, kernel_h_, kernel_w_);\n    if (channels != channels_kernel)\n        THError(\"Input shape and kernel channels wont match: (%d vs %d).\",\n                channels, channels_kernel);\n\n    const int height_out = (height + 2 * pad_h - (dilation_h * (kernel_h - 1) + 1)) / stride_h + 1;\n    const int width_out = (width + 2 * pad_w - (dilation_w * (kernel_w - 1) + 1)) / stride_w + 1;\n\n    if (THCudaDoubleTensor_nDimension(state, ones) != 2 ||\n        THCudaDoubleTensor_size(state, ones, 0) * THCudaDoubleTensor_size(state, ones, 1) < height_out * width_out)\n    {\n        // Resize plane and fill with ones...\n        THCudaDoubleTensor_resize2d(state, ones, height_out, width_out);\n        THCudaDoubleTensor_fill(state, ones, 1);\n    }\n\n    // THCudaDoubleTensor_resize4d(state, grad_input, batch, channels, height, width);\n    THCudaDoubleTensor_resize2d(state, columns, channels * kernel_h * kernel_w, height_out * width_out);\n\n    THCudaDoubleTensor *input_n = THCudaDoubleTensor_new(state);\n    THCudaDoubleTensor *offset_n = THCudaDoubleTensor_new(state);\n    THCudaDoubleTensor *mask_n = THCudaDoubleTensor_new(state);\n\n    THCudaDoubleTensor *grad_output_n = THCudaDoubleTensor_new(state);\n    THCudaDoubleTensor *grad_input_n = THCudaDoubleTensor_new(state);\n    THCudaDoubleTensor *grad_offset_n = THCudaDoubleTensor_new(state);\n    THCudaDoubleTensor *grad_mask_n = THCudaDoubleTensor_new(state);\n\n    for (int b = 0; b < batch; b++)\n    {\n        THCudaDoubleTensor_select(state, input_n, input, 0, b);\n        THCudaDoubleTensor_select(state, offset_n, offset, 0, b);\n        THCudaDoubleTensor_select(state, mask_n, mask, 0, b);\n        THCudaDoubleTensor_select(state, grad_output_n, grad_output, 0, b);\n        THCudaDoubleTensor_select(state, grad_input_n, grad_input, 0, b);\n        THCudaDoubleTensor_select(state, grad_offset_n, grad_offset, 0, b);\n        THCudaDoubleTensor_select(state, grad_mask_n, grad_mask, 0, b);\n\n        long m = channels * kernel_h * kernel_w;\n        long n = height_out * width_out;\n        long k = channels_out;\n\n        THCudaBlas_Dgemm(state, 'n', 't', n, m, k, 1.0,\n                         THCudaDoubleTensor_data(state, grad_output_n), n,\n                         THCudaDoubleTensor_data(state, weight), m, 0.0,\n                         THCudaDoubleTensor_data(state, columns), n);\n\n        // gradient w.r.t. input offset and mask data\n        modulated_deformable_col2im_coord_cuda(THCState_getCurrentStream(state),\n                                               THCudaDoubleTensor_data(state, columns),\n                                               THCudaDoubleTensor_data(state, input_n),\n                                               THCudaDoubleTensor_data(state, offset_n),\n                                               THCudaDoubleTensor_data(state, mask_n),\n                                               1, channels, height, width,\n                                               height_out, width_out, kernel_h, kernel_w,\n                                               pad_h, pad_w, stride_h, stride_w,\n                                               dilation_h, dilation_w, deformable_group,\n                                               THCudaDoubleTensor_data(state, grad_offset_n),\n                                               THCudaDoubleTensor_data(state, grad_mask_n));\n        // gradient w.r.t. input data\n        modulated_deformable_col2im_cuda(THCState_getCurrentStream(state),\n                                         THCudaDoubleTensor_data(state, columns),\n                                         THCudaDoubleTensor_data(state, offset_n),\n                                         THCudaDoubleTensor_data(state, mask_n),\n                                         1, channels, height, width,\n                                         height_out, width_out, kernel_h, kernel_w,\n                                         pad_h, pad_w, stride_h, stride_w,\n                                         dilation_h, dilation_w, deformable_group,\n                                         THCudaDoubleTensor_data(state, grad_input_n));\n\n        // gradient w.r.t. weight, dWeight should accumulate across the batch and group\n        modulated_deformable_im2col_cuda(THCState_getCurrentStream(state),\n                                         THCudaDoubleTensor_data(state, input_n),\n                                         THCudaDoubleTensor_data(state, offset_n),\n                                         THCudaDoubleTensor_data(state, mask_n),\n                                         1, channels, height, width,\n                                         height_out, width_out, kernel_h, kernel_w,\n                                         pad_h, pad_w, stride_h, stride_w,\n                                         dilation_h, dilation_w, deformable_group,\n                                         THCudaDoubleTensor_data(state, columns));\n        long m_ = channels_out;\n        long n_ = channels * kernel_h * kernel_w;\n        long k_ = height_out * width_out;\n\n        THCudaBlas_Dgemm(state, 't', 'n', n_, m_, k_, 1.0,\n                         THCudaDoubleTensor_data(state, columns), k_,\n                         THCudaDoubleTensor_data(state, grad_output_n), k_, 1.0,\n                         THCudaDoubleTensor_data(state, grad_weight), n_);\n\n        // gradient w.r.t. bias\n        // long m_ = channels_out;\n        // long k__ = height_out * width_out;\n        THCudaBlas_Dgemv(state,\n                         't',\n                         k_, m_, 1.0,\n                         THCudaDoubleTensor_data(state, grad_output_n), k_,\n                         THCudaDoubleTensor_data(state, ones), 1, 1.0,\n                         THCudaDoubleTensor_data(state, grad_bias), 1);\n    }\n\n    THCudaDoubleTensor_free(state, input_n);\n    THCudaDoubleTensor_free(state, offset_n);\n    THCudaDoubleTensor_free(state, mask_n);\n\n    THCudaDoubleTensor_free(state, grad_output_n);\n    THCudaDoubleTensor_free(state, grad_input_n);\n    THCudaDoubleTensor_free(state, grad_offset_n);\n    THCudaDoubleTensor_free(state, grad_mask_n);\n\n    THCudaDoubleTensor_free(state, input);\n    THCudaDoubleTensor_free(state, offset);\n    THCudaDoubleTensor_free(state, mask);\n    THCudaDoubleTensor_free(state, weight);\n    THCudaDoubleTensor_free(state, grad_output);\n}\n\n\nvoid dcn_v2_psroi_pooling_cuda_forward(THCudaDoubleTensor * input, THCudaDoubleTensor * bbox,\n                                       THCudaDoubleTensor * trans, \n                                       THCudaDoubleTensor * out, THCudaDoubleTensor * top_count,\n                                       const int no_trans,\n                                       const double spatial_scale,\n                                       const int output_dim,\n                                       const int group_size,\n                                       const int pooled_size,\n                                       const int part_size,\n                                       const int sample_per_part,\n                                       const double trans_std)\n{\n    THArgCheck(THCudaDoubleTensor_isContiguous(state, input), 1, \"input tensor has to be contiguous\");\n    THCAssertSameGPU(THCudaDoubleTensor_checkGPU(state, 5, input, bbox, trans, out, top_count));\n\n    const int batch = THCudaDoubleTensor_size(state, input, 0);\n    const int channels = THCudaDoubleTensor_size(state, input, 1);\n    const int height = THCudaDoubleTensor_size(state, input, 2);\n    const int width = THCudaDoubleTensor_size(state, input, 3);\n    const int channels_trans = no_trans? 2 : THCudaDoubleTensor_size(state, trans, 1);\n\n    const int num_bbox = THCudaDoubleTensor_size(state, bbox, 0);\n    if (num_bbox != THCudaDoubleTensor_size(state, out, 0))\n        THError(\"Output shape and bbox number wont match: (%d vs %d).\", \n                THCudaDoubleTensor_size(state, out, 0), num_bbox);\n\n    DeformablePSROIPoolForward(THCState_getCurrentStream(state),\n                               THCudaDoubleTensor_data(state, input),\n                               THCudaDoubleTensor_data(state, bbox),\n                               THCudaDoubleTensor_data(state, trans),\n                               THCudaDoubleTensor_data(state, out),\n                               THCudaDoubleTensor_data(state, top_count),\n                               batch, channels, height, width,\n                               num_bbox, \n                               channels_trans, \n                               no_trans, \n                               spatial_scale,\n                               output_dim, \n                               group_size, \n                               pooled_size, \n                               part_size,\n                               sample_per_part, \n                               trans_std);\n}\n\nvoid dcn_v2_psroi_pooling_cuda_backward(THCudaDoubleTensor * out_grad, \n                                        THCudaDoubleTensor * input, THCudaDoubleTensor * bbox,\n                                        THCudaDoubleTensor * trans, THCudaDoubleTensor * top_count,\n                                        THCudaDoubleTensor * input_grad, THCudaDoubleTensor * trans_grad,\n                                        const int no_trans,\n                                        const double spatial_scale,\n                                        const int output_dim,\n                                        const int group_size,\n                                        const int pooled_size,\n                                        const int part_size,\n                                        const int sample_per_part,\n                                        const double trans_std)\n{\n    THArgCheck(THCudaDoubleTensor_isContiguous(state, out_grad), 0, \"out_grad tensor has to be contiguous\");\n    THArgCheck(THCudaDoubleTensor_isContiguous(state, input), 1, \"input tensor has to be contiguous\");\n    THCAssertSameGPU(THCudaDoubleTensor_checkGPU(state, 7, input, bbox, trans, out_grad, top_count,\n                    input_grad, trans_grad));\n\n    const int batch = THCudaDoubleTensor_size(state, input, 0);\n    const int channels = THCudaDoubleTensor_size(state, input, 1);\n    const int height = THCudaDoubleTensor_size(state, input, 2);\n    const int width = THCudaDoubleTensor_size(state, input, 3);\n    const int channels_trans = no_trans? 2 : THCudaDoubleTensor_size(state, trans, 1);\n\n    const int num_bbox = THCudaDoubleTensor_size(state, bbox, 0);\n    if (num_bbox != THCudaDoubleTensor_size(state, out_grad, 0))\n        THError(\"Output shape and bbox number wont match: (%d vs %d).\", \n                THCudaDoubleTensor_size(state, out_grad, 0), num_bbox);\n\n    DeformablePSROIPoolBackwardAcc(THCState_getCurrentStream(state),\n                                   THCudaDoubleTensor_data(state, out_grad),\n                                   THCudaDoubleTensor_data(state, input),\n                                   THCudaDoubleTensor_data(state, bbox),\n                                   THCudaDoubleTensor_data(state, trans),\n                                   THCudaDoubleTensor_data(state, top_count),\n                                   THCudaDoubleTensor_data(state, input_grad),\n                                   THCudaDoubleTensor_data(state, trans_grad),\n                                   batch, channels, height, width, num_bbox,\n                                   channels_trans, \n                                   no_trans, \n                                   spatial_scale, \n                                   output_dim,\n                                   group_size, \n                                   pooled_size, \n                                   part_size,\n                                   sample_per_part, \n                                   trans_std);\n}"
  },
  {
    "path": "src/lib/models/networks/DCNv2/src/dcn_v2_cuda_double.h",
    "content": "// #ifndef DCN_V2_CUDA\n// #define DCN_V2_CUDA\n\n// #ifdef __cplusplus\n// extern \"C\"\n// {\n// #endif\n\nvoid dcn_v2_cuda_forward(THCudaDoubleTensor *input, THCudaDoubleTensor *weight,\n                         THCudaDoubleTensor *bias, THCudaDoubleTensor *ones,\n                         THCudaDoubleTensor *offset, THCudaDoubleTensor *mask,\n                         THCudaDoubleTensor *output, THCudaDoubleTensor *columns,\n                         int kernel_h, int kernel_w,\n                         const int stride_h, const int stride_w,\n                         const int pad_h, const int pad_w,\n                         const int dilation_h, const int dilation_w,\n                         const int deformable_group);\nvoid dcn_v2_cuda_backward(THCudaDoubleTensor *input, THCudaDoubleTensor *weight,\n                          THCudaDoubleTensor *bias, THCudaDoubleTensor *ones,\n                          THCudaDoubleTensor *offset, THCudaDoubleTensor *mask,\n                          THCudaDoubleTensor *columns,\n                          THCudaDoubleTensor *grad_input, THCudaDoubleTensor *grad_weight,\n                          THCudaDoubleTensor *grad_bias, THCudaDoubleTensor *grad_offset,\n                          THCudaDoubleTensor *grad_mask, THCudaDoubleTensor *grad_output,\n                          int kernel_h, int kernel_w,\n                          int stride_h, int stride_w,\n                          int pad_h, int pad_w,\n                          int dilation_h, int dilation_w,\n                          int deformable_group);\n\nvoid dcn_v2_psroi_pooling_cuda_forward(THCudaDoubleTensor * input, THCudaDoubleTensor * bbox,\n                                       THCudaDoubleTensor * trans, \n                                       THCudaDoubleTensor * out, THCudaDoubleTensor * top_count,\n                                       const int no_trans,\n                                       const double spatial_scale,\n                                       const int output_dim,\n                                       const int group_size,\n                                       const int pooled_size,\n                                       const int part_size,\n                                       const int sample_per_part,\n                                       const double trans_std);\n\nvoid dcn_v2_psroi_pooling_cuda_backward(THCudaDoubleTensor * out_grad, \n                                        THCudaDoubleTensor * input, THCudaDoubleTensor * bbox,\n                                        THCudaDoubleTensor * trans, THCudaDoubleTensor * top_count,\n                                        THCudaDoubleTensor * input_grad, THCudaDoubleTensor * trans_grad,\n                                        const int no_trans,\n                                        const double spatial_scale,\n                                        const int output_dim,\n                                        const int group_size,\n                                        const int pooled_size,\n                                        const int part_size,\n                                        const int sample_per_part,\n                                        const double trans_std);\n\n\n// #ifdef __cplusplus\n// }\n// #endif\n\n// #endif"
  },
  {
    "path": "src/lib/models/networks/DCNv2/src/dcn_v2_double.c",
    "content": "#include <TH/TH.h>\n#include <stdio.h>\n#include <math.h>\n\nvoid dcn_v2_forward(THDoubleTensor *input, THDoubleTensor *weight,\n                    THDoubleTensor *bias, THDoubleTensor *ones,\n                    THDoubleTensor *offset, THDoubleTensor *mask,\n                    THDoubleTensor *output, THDoubleTensor *columns,\n                    const int pad_h, const int pad_w,\n                    const int stride_h, const int stride_w,\n                    const int dilation_h, const int dilation_w,\n                    const int deformable_group)\n{\n    printf(\"only implemented in GPU\");\n}\nvoid dcn_v2_backward(THDoubleTensor *input, THDoubleTensor *weight,\n                     THDoubleTensor *bias, THDoubleTensor *ones,\n                     THDoubleTensor *offset, THDoubleTensor *mask,\n                     THDoubleTensor *output, THDoubleTensor *columns,\n                     THDoubleTensor *grad_input, THDoubleTensor *grad_weight,\n                     THDoubleTensor *grad_bias, THDoubleTensor *grad_offset,\n                     THDoubleTensor *grad_mask, THDoubleTensor *grad_output,\n                     int kernel_h, int kernel_w,\n                     int stride_h, int stride_w,\n                     int pad_h, int pad_w,\n                     int dilation_h, int dilation_w,\n                     int deformable_group)\n{\n    printf(\"only implemented in GPU\");\n}"
  },
  {
    "path": "src/lib/models/networks/DCNv2/src/dcn_v2_double.h",
    "content": "void dcn_v2_forward(THDoubleTensor *input, THDoubleTensor *weight,\n                    THDoubleTensor *bias, THDoubleTensor *ones,\n                    THDoubleTensor *offset, THDoubleTensor *mask,\n                    THDoubleTensor *output, THDoubleTensor *columns,\n                    const int pad_h, const int pad_w,\n                    const int stride_h, const int stride_w,\n                    const int dilation_h, const int dilation_w,\n                    const int deformable_group);\nvoid dcn_v2_backward(THDoubleTensor *input, THDoubleTensor *weight,\n                     THDoubleTensor *bias, THDoubleTensor *ones,\n                     THDoubleTensor *offset, THDoubleTensor *mask,\n                     THDoubleTensor *output, THDoubleTensor *columns,\n                     THDoubleTensor *grad_input, THDoubleTensor *grad_weight,\n                     THDoubleTensor *grad_bias, THDoubleTensor *grad_offset,\n                     THDoubleTensor *grad_mask, THDoubleTensor *grad_output,\n                     int kernel_h, int kernel_w,\n                     int stride_h, int stride_w,\n                     int pad_h, int pad_w,\n                     int dilation_h, int dilation_w,\n                     int deformable_group);"
  },
  {
    "path": "src/lib/models/networks/DCNv2/test.py",
    "content": "#!/usr/bin/env python\nfrom __future__ import absolute_import\nfrom __future__ import print_function\nfrom __future__ import division\n\nimport time\nimport torch\nimport torch.nn as nn\nfrom torch.autograd import gradcheck\n\nfrom dcn_v2 import DCNv2\nfrom dcn_v2_func import DCNv2Function\nfrom dcn_v2 import DCNv2Pooling\nfrom dcn_v2_func import DCNv2PoolingFunction\n\ndeformable_groups = 1\nN, inC, inH, inW = 2, 2, 4, 4\noutC = 2\nkH, kW = 3, 3\n\ndef conv_identify(weight, bias):\n    weight.data.zero_()\n    bias.data.zero_()\n    o, i, h, w = weight.shape\n    y = h//2\n    x = w//2\n    for p in range(i):\n        for q in range(o):\n            if p == q:\n                weight.data[q, p, y, x] = 1.0\n\ndef check_zero_offset():\n    conv_offset = nn.Conv2d(inC, deformable_groups * 2 * kH * kW,\n        kernel_size=(kH, kW),\n        stride=(1, 1),\n        padding=(1, 1),\n        bias=True).cuda()\n\n    conv_mask = nn.Conv2d(inC, deformable_groups * 1 * kH * kW,\n        kernel_size=(kH, kW),\n        stride=(1, 1),\n        padding=(1, 1),\n        bias=True).cuda()\n\n    dcn_v2 = DCNv2(inC, outC, (kH, kW),\n                   stride=1, padding=1, dilation=1,\n                   deformable_groups=deformable_groups).cuda()\n\n    conv_offset.weight.data.zero_()\n    conv_offset.bias.data.zero_()\n    conv_mask.weight.data.zero_()\n    conv_mask.bias.data.zero_()\n    conv_identify(dcn_v2.weight, dcn_v2.bias)\n\n    input = torch.randn(N, inC, inH, inW).cuda()\n    offset = conv_offset(input)\n    mask = conv_mask(input)\n    mask = torch.sigmoid(mask)\n    output = dcn_v2(input, offset, mask)\n    output *= 2\n    d = (input - output).abs().max()\n    if d < 1e-10:\n        print('Zero offset passed')\n    else:\n        print('Zero offset failed')\n\ndef check_gradient_dconv_double():\n\n    input = torch.randn(N, inC, inH, inW, dtype=torch.float64).cuda()\n    input.requires_grad = True\n\n    offset = torch.randn(N, deformable_groups * 2 * kW * kH, inH, inW, dtype=torch.float64).cuda()\n    # offset.data.zero_()\n    # offset.data -= 0.00001\n    offset.requires_grad = True\n\n    mask = torch.rand(N, deformable_groups * 1 * kW * kH, inH, inW, dtype=torch.float64).cuda()\n    # mask.data.zero_()\n    mask.requires_grad = True\n    mask = torch.sigmoid(mask)\n\n    weight = torch.randn(outC, inC, kH, kW, dtype=torch.float64).cuda()\n    weight.requires_grad = True\n\n    bias = torch.rand(outC, dtype=torch.float64).cuda()\n    bias.requires_grad = True\n\n    func = DCNv2Function(stride=1, padding=1, dilation=1, deformable_groups=deformable_groups)\n\n    print(gradcheck(func, (input, offset, mask, weight, bias), eps=1e-6, atol=1e-5, rtol=1e-3))\n\ndef check_gradient_dconv():\n\n    input = torch.randn(N, inC, inH, inW).cuda()\n    input.requires_grad = True\n\n    offset = torch.randn(N, deformable_groups * 2 * kW * kH, inH, inW).cuda()\n    # offset.data.zero_()\n    # offset.data -= 0.5\n    offset.requires_grad = True\n\n    mask = torch.rand(N, deformable_groups * 1 * kW * kH, inH, inW).cuda()\n    # mask.data.zero_()\n    mask.requires_grad = True\n    mask = torch.sigmoid(mask)\n\n    weight = torch.randn(outC, inC, kH, kW).cuda()\n    weight.requires_grad = True\n\n    bias = torch.rand(outC).cuda()\n    bias.requires_grad = True\n\n    func = DCNv2Function(stride=1, padding=1, dilation=1, deformable_groups=deformable_groups)\n\n    print(gradcheck(func, (input, offset, mask, weight, bias), eps=1e-3, atol=1e-3, rtol=1e-2))\n\ndef check_pooling_zero_offset():\n    from dcn_v2 import DCNv2Pooling\n    input = torch.randn(2, 16, 64, 64).cuda().zero_()\n    input[0, :, 16:26, 16:26] = 1.\n    input[1, :, 10:20, 20:30] = 2.\n    rois = torch.tensor([\n        [0, 65, 65, 103, 103],\n        [1, 81, 41, 119, 79],\n    ]).cuda().float()\n    pooling = DCNv2Pooling(spatial_scale=1.0 / 4,\n                           pooled_size=7,\n                           output_dim=16,\n                           no_trans=True,\n                           group_size=1,\n                           trans_std=0.1).cuda()\n\n    out = pooling(input, rois, input.new())\n    s = ', '.join(['%f' % out[i, :, :, :].mean().item() for i in range(rois.shape[0])])\n    print(s)\n\n    dpooling = DCNv2Pooling(spatial_scale=1.0 / 4,\n                            pooled_size=7,\n                            output_dim=16,\n                            no_trans=False,\n                            group_size=1,\n                            trans_std=0.1).cuda()\n    offset = torch.randn(20, 2, 7, 7).cuda().zero_()\n    dout = dpooling(input, rois, offset)\n    s = ', '.join(['%f' % dout[i, :, :, :].mean().item() for i in range(rois.shape[0])])\n    print(s)\n\ndef check_gradient_dpooling():\n    input = torch.randn(2, 3, 5, 5).cuda() * 0.01\n    N = 4\n    batch_inds = torch.randint(2, (N, 1)).cuda().float()\n    x = torch.rand((N, 1)).cuda().float() * 15\n    y = torch.rand((N, 1)).cuda().float() * 15\n    w = torch.rand((N, 1)).cuda().float() * 10\n    h = torch.rand((N, 1)).cuda().float() * 10\n    rois = torch.cat((batch_inds, x, y, x + w, y + h), dim=1)\n    offset = torch.randn(N, 2, 3, 3).cuda()\n    dpooling = DCNv2Pooling(spatial_scale=1.0 / 4,\n                            pooled_size=3,\n                            output_dim=3,\n                            no_trans=False,\n                            group_size=1,\n                            trans_std=0.0).cuda()\n    input.requires_grad = True\n    offset.requires_grad = True\n    print('check_gradient_dpooling', gradcheck(dpooling, (input, rois, offset), eps=1e-4))\n\n\ndef example_dconv():\n    from dcn_v2 import DCN\n    input = torch.randn(2, 64, 128, 128).cuda()\n    # wrap all things (offset and mask) in DCN\n    dcn = DCN(64, 64, kernel_size=(3,3), stride=1, padding=1, deformable_groups=2).cuda()\n    output = dcn(input)\n    targert = output.new(*output.size())\n    targert.data.uniform_(-0.01, 0.01)\n    error = (targert - output).mean()\n    error.backward()\n    print(output.shape)\n\ndef example_dpooling():\n    from dcn_v2 import DCNv2Pooling\n    input = torch.randn(2, 32, 64, 64).cuda()\n    batch_inds = torch.randint(2, (20, 1)).cuda().float()\n    x = torch.randint(256, (20, 1)).cuda().float()\n    y = torch.randint(256, (20, 1)).cuda().float()\n    w = torch.randint(64, (20, 1)).cuda().float()\n    h = torch.randint(64, (20, 1)).cuda().float()\n    rois = torch.cat((batch_inds, x, y, x + w, y + h), dim=1)\n    offset = torch.randn(20, 2, 7, 7).cuda()\n    input.requires_grad = True\n    offset.requires_grad = True\n\n    # normal roi_align\n    pooling = DCNv2Pooling(spatial_scale=1.0 / 4,\n                           pooled_size=7,\n                           output_dim=32,\n                           no_trans=True,\n                           group_size=1,\n                           trans_std=0.1).cuda()\n\n    # deformable pooling\n    dpooling = DCNv2Pooling(spatial_scale=1.0 / 4,\n                            pooled_size=7,\n                            output_dim=32,\n                            no_trans=False,\n                            group_size=1,\n                            trans_std=0.1).cuda()\n\n    out = pooling(input, rois, offset)\n    dout = dpooling(input, rois, offset)\n    print(out.shape)\n    print(dout.shape)\n\n    target_out = out.new(*out.size())\n    target_out.data.uniform_(-0.01, 0.01)\n    target_dout = dout.new(*dout.size())\n    target_dout.data.uniform_(-0.01, 0.01)\n    e = (target_out - out).mean()\n    e.backward()\n    e = (target_dout - dout).mean()\n    e.backward()\n\ndef example_mdpooling():\n    from dcn_v2 import DCNPooling\n    input = torch.randn(2, 32, 64, 64).cuda()\n    input.requires_grad = True\n    batch_inds = torch.randint(2, (20, 1)).cuda().float()\n    x = torch.randint(256, (20, 1)).cuda().float()\n    y = torch.randint(256, (20, 1)).cuda().float()\n    w = torch.randint(64, (20, 1)).cuda().float()\n    h = torch.randint(64, (20, 1)).cuda().float()\n    rois = torch.cat((batch_inds, x, y, x + w, y + h), dim=1)\n\n    # mdformable pooling (V2)\n    dpooling = DCNPooling(spatial_scale=1.0 / 4,\n                         pooled_size=7,\n                         output_dim=32,\n                         no_trans=False,\n                         group_size=1,\n                         trans_std=0.1).cuda()\n\n    dout = dpooling(input, rois)\n    target = dout.new(*dout.size())\n    target.data.uniform_(-0.1, 0.1)\n    error = (target - dout).mean()\n    error.backward()\n    print(dout.shape)\n\nif __name__ == '__main__':\n\n    example_dconv()\n    example_dpooling()\n    example_mdpooling()\n\n    check_pooling_zero_offset()\n    # zero offset check\n    if inC == outC:\n        check_zero_offset()\n\n    check_gradient_dpooling()\n\n    # # gradient check\n    # try:\n    #     check_gradient_double()\n    # except TypeError:\n    #     print('''****** You can swith to double precision in dcn_v2_func.py by (un)commenting these two lines:\n    #              ****** from _ext import dcn_v2 as _backend\n    #              ****** from _ext import dcn_v2_double as _backend''')\n    #     print('****** Your tensor may not be **double** type')\n    #     print('****** Switching to **float** type')\n    #\n    #     check_gradient()\n    # finally:\n    #     print('****** Note: backward is not reentrant error may not be a serious problem, '\n    #           '****** since the max error is less than 1e-7\\n'\n    #           '****** Still looking for what trigger this problem')"
  },
  {
    "path": "src/lib/models/networks/dlav0.py",
    "content": "#!/usr/bin/env python\n# -*- coding: utf-8 -*-\nfrom __future__ import absolute_import\nfrom __future__ import division\nfrom __future__ import print_function\n\nimport math\nfrom os.path import join\n\nimport torch\nfrom torch import nn\nimport torch.utils.model_zoo as model_zoo\n\nimport numpy as np\n\nBatchNorm = nn.BatchNorm2d\n\ndef get_model_url(data='imagenet', name='dla34', hash='ba72cf86'):\n    return join('http://dl.yf.io/dla/models', data, '{}-{}.pth'.format(name, hash))\n\n\ndef conv3x3(in_planes, out_planes, stride=1):\n    \"3x3 convolution with padding\"\n    return nn.Conv2d(in_planes, out_planes, kernel_size=3, stride=stride,\n                     padding=1, bias=False)\n\n\nclass BasicBlock(nn.Module):\n    def __init__(self, inplanes, planes, stride=1, dilation=1):\n        super(BasicBlock, self).__init__()\n        self.conv1 = nn.Conv2d(inplanes, planes, kernel_size=3,\n                               stride=stride, padding=dilation,\n                               bias=False, dilation=dilation)\n        self.bn1 = BatchNorm(planes)\n        self.relu = nn.ReLU(inplace=True)\n        self.conv2 = nn.Conv2d(planes, planes, kernel_size=3,\n                               stride=1, padding=dilation,\n                               bias=False, dilation=dilation)\n        self.bn2 = BatchNorm(planes)\n        self.stride = stride\n\n    def forward(self, x, residual=None):\n        if residual is None:\n            residual = x\n\n        out = self.conv1(x)\n        out = self.bn1(out)\n        out = self.relu(out)\n\n        out = self.conv2(out)\n        out = self.bn2(out)\n\n        out += residual\n        out = self.relu(out)\n\n        return out\n\n\nclass Bottleneck(nn.Module):\n    expansion = 2\n\n    def __init__(self, inplanes, planes, stride=1, dilation=1):\n        super(Bottleneck, self).__init__()\n        expansion = Bottleneck.expansion\n        bottle_planes = planes // expansion\n        self.conv1 = nn.Conv2d(inplanes, bottle_planes,\n                               kernel_size=1, bias=False)\n        self.bn1 = BatchNorm(bottle_planes)\n        self.conv2 = nn.Conv2d(bottle_planes, bottle_planes, kernel_size=3,\n                               stride=stride, padding=dilation,\n                               bias=False, dilation=dilation)\n        self.bn2 = BatchNorm(bottle_planes)\n        self.conv3 = nn.Conv2d(bottle_planes, planes,\n                               kernel_size=1, bias=False)\n        self.bn3 = BatchNorm(planes)\n        self.relu = nn.ReLU(inplace=True)\n        self.stride = stride\n\n    def forward(self, x, residual=None):\n        if residual is None:\n            residual = x\n\n        out = self.conv1(x)\n        out = self.bn1(out)\n        out = self.relu(out)\n\n        out = self.conv2(out)\n        out = self.bn2(out)\n        out = self.relu(out)\n\n        out = self.conv3(out)\n        out = self.bn3(out)\n\n        out += residual\n        out = self.relu(out)\n\n        return out\n\n\nclass BottleneckX(nn.Module):\n    expansion = 2\n    cardinality = 32\n\n    def __init__(self, inplanes, planes, stride=1, dilation=1):\n        super(BottleneckX, self).__init__()\n        cardinality = BottleneckX.cardinality\n        # dim = int(math.floor(planes * (BottleneckV5.expansion / 64.0)))\n        # bottle_planes = dim * cardinality\n        bottle_planes = planes * cardinality // 32\n        self.conv1 = nn.Conv2d(inplanes, bottle_planes,\n                               kernel_size=1, bias=False)\n        self.bn1 = BatchNorm(bottle_planes)\n        self.conv2 = nn.Conv2d(bottle_planes, bottle_planes, kernel_size=3,\n                               stride=stride, padding=dilation, bias=False,\n                               dilation=dilation, groups=cardinality)\n        self.bn2 = BatchNorm(bottle_planes)\n        self.conv3 = nn.Conv2d(bottle_planes, planes,\n                               kernel_size=1, bias=False)\n        self.bn3 = BatchNorm(planes)\n        self.relu = nn.ReLU(inplace=True)\n        self.stride = stride\n\n    def forward(self, x, residual=None):\n        if residual is None:\n            residual = x\n\n        out = self.conv1(x)\n        out = self.bn1(out)\n        out = self.relu(out)\n\n        out = self.conv2(out)\n        out = self.bn2(out)\n        out = self.relu(out)\n\n        out = self.conv3(out)\n        out = self.bn3(out)\n\n        out += residual\n        out = self.relu(out)\n\n        return out\n\n\nclass Root(nn.Module):\n    def __init__(self, in_channels, out_channels, kernel_size, residual):\n        super(Root, self).__init__()\n        self.conv = nn.Conv2d(\n            in_channels, out_channels, 1,\n            stride=1, bias=False, padding=(kernel_size - 1) // 2)\n        self.bn = BatchNorm(out_channels)\n        self.relu = nn.ReLU(inplace=True)\n        self.residual = residual\n\n    def forward(self, *x):\n        children = x\n        x = self.conv(torch.cat(x, 1))\n        x = self.bn(x)\n        if self.residual:\n            x += children[0]\n        x = self.relu(x)\n\n        return x\n\n\nclass Tree(nn.Module):\n    def __init__(self, levels, block, in_channels, out_channels, stride=1,\n                 level_root=False, root_dim=0, root_kernel_size=1,\n                 dilation=1, root_residual=False):\n        super(Tree, self).__init__()\n        if root_dim == 0:\n            root_dim = 2 * out_channels\n        if level_root:\n            root_dim += in_channels\n        if levels == 1:\n            self.tree1 = block(in_channels, out_channels, stride,\n                               dilation=dilation)\n            self.tree2 = block(out_channels, out_channels, 1,\n                               dilation=dilation)\n        else:\n            self.tree1 = Tree(levels - 1, block, in_channels, out_channels,\n                              stride, root_dim=0,\n                              root_kernel_size=root_kernel_size,\n                              dilation=dilation, root_residual=root_residual)\n            self.tree2 = Tree(levels - 1, block, out_channels, out_channels,\n                              root_dim=root_dim + out_channels,\n                              root_kernel_size=root_kernel_size,\n                              dilation=dilation, root_residual=root_residual)\n        if levels == 1:\n            self.root = Root(root_dim, out_channels, root_kernel_size,\n                             root_residual)\n        self.level_root = level_root\n        self.root_dim = root_dim\n        self.downsample = None\n        self.project = None\n        self.levels = levels\n        if stride > 1:\n            self.downsample = nn.MaxPool2d(stride, stride=stride)\n        if in_channels != out_channels:\n            self.project = nn.Sequential(\n                nn.Conv2d(in_channels, out_channels,\n                          kernel_size=1, stride=1, bias=False),\n                BatchNorm(out_channels)\n            )\n\n    def forward(self, x, residual=None, children=None):\n        children = [] if children is None else children\n        bottom = self.downsample(x) if self.downsample else x\n        residual = self.project(bottom) if self.project else bottom\n        if self.level_root:\n            children.append(bottom)\n        x1 = self.tree1(x, residual)\n        if self.levels == 1:\n            x2 = self.tree2(x1)\n            x = self.root(x2, x1, *children)\n        else:\n            children.append(x1)\n            x = self.tree2(x1, children=children)\n        return x\n\n\nclass DLA(nn.Module):\n    def __init__(self, levels, channels, num_classes=1000,\n                 block=BasicBlock, residual_root=False, return_levels=False,\n                 pool_size=7, linear_root=False):\n        super(DLA, self).__init__()\n        self.channels = channels\n        self.return_levels = return_levels\n        self.num_classes = num_classes\n        self.base_layer = nn.Sequential(\n            nn.Conv2d(3, channels[0], kernel_size=7, stride=1,\n                      padding=3, bias=False),\n            BatchNorm(channels[0]),\n            nn.ReLU(inplace=True))\n        self.level0 = self._make_conv_level(\n            channels[0], channels[0], levels[0])\n        self.level1 = self._make_conv_level(\n            channels[0], channels[1], levels[1], stride=2)\n        self.level2 = Tree(levels[2], block, channels[1], channels[2], 2,\n                           level_root=False,\n                           root_residual=residual_root)\n        self.level3 = Tree(levels[3], block, channels[2], channels[3], 2,\n                           level_root=True, root_residual=residual_root)\n        self.level4 = Tree(levels[4], block, channels[3], channels[4], 2,\n                           level_root=True, root_residual=residual_root)\n        self.level5 = Tree(levels[5], block, channels[4], channels[5], 2,\n                           level_root=True, root_residual=residual_root)\n\n        self.avgpool = nn.AvgPool2d(pool_size)\n        self.fc = nn.Conv2d(channels[-1], num_classes, kernel_size=1,\n                            stride=1, padding=0, bias=True)\n\n        for m in self.modules():\n            if isinstance(m, nn.Conv2d):\n                n = m.kernel_size[0] * m.kernel_size[1] * m.out_channels\n                m.weight.data.normal_(0, math.sqrt(2. / n))\n            elif isinstance(m, BatchNorm):\n                m.weight.data.fill_(1)\n                m.bias.data.zero_()\n\n    def _make_level(self, block, inplanes, planes, blocks, stride=1):\n        downsample = None\n        if stride != 1 or inplanes != planes:\n            downsample = nn.Sequential(\n                nn.MaxPool2d(stride, stride=stride),\n                nn.Conv2d(inplanes, planes,\n                          kernel_size=1, stride=1, bias=False),\n                BatchNorm(planes),\n            )\n\n        layers = []\n        layers.append(block(inplanes, planes, stride, downsample=downsample))\n        for i in range(1, blocks):\n            layers.append(block(inplanes, planes))\n\n        return nn.Sequential(*layers)\n\n    def _make_conv_level(self, inplanes, planes, convs, stride=1, dilation=1):\n        modules = []\n        for i in range(convs):\n            modules.extend([\n                nn.Conv2d(inplanes, planes, kernel_size=3,\n                          stride=stride if i == 0 else 1,\n                          padding=dilation, bias=False, dilation=dilation),\n                BatchNorm(planes),\n                nn.ReLU(inplace=True)])\n            inplanes = planes\n        return nn.Sequential(*modules)\n\n    def forward(self, x):\n        y = []\n        x = self.base_layer(x)\n        for i in range(6):\n            x = getattr(self, 'level{}'.format(i))(x)\n            y.append(x)\n        if self.return_levels:\n            return y\n        else:\n            x = self.avgpool(x)\n            x = self.fc(x)\n            x = x.view(x.size(0), -1)\n\n            return x\n\n    def load_pretrained_model(self,  data='imagenet', name='dla34', hash='ba72cf86'):\n        fc = self.fc\n        if name.endswith('.pth'):\n            model_weights = torch.load(data + name)\n        else:\n            model_url = get_model_url(data, name, hash)\n            model_weights = model_zoo.load_url(model_url)\n        num_classes = len(model_weights[list(model_weights.keys())[-1]])\n        self.fc = nn.Conv2d(\n            self.channels[-1], num_classes,\n            kernel_size=1, stride=1, padding=0, bias=True)\n        self.load_state_dict(model_weights)\n        self.fc = fc\n\n\ndef dla34(pretrained, **kwargs):  # DLA-34\n    model = DLA([1, 1, 1, 2, 2, 1],\n                [16, 32, 64, 128, 256, 512],\n                block=BasicBlock, **kwargs)\n    if pretrained:\n        model.load_pretrained_model(data='imagenet', name='dla34', hash='ba72cf86')\n    return model\n\n\ndef dla46_c(pretrained=None, **kwargs):  # DLA-46-C\n    Bottleneck.expansion = 2\n    model = DLA([1, 1, 1, 2, 2, 1],\n                [16, 32, 64, 64, 128, 256],\n                block=Bottleneck, **kwargs)\n    if pretrained is not None:\n        model.load_pretrained_model(pretrained, 'dla46_c')\n    return model\n\n\ndef dla46x_c(pretrained=None, **kwargs):  # DLA-X-46-C\n    BottleneckX.expansion = 2\n    model = DLA([1, 1, 1, 2, 2, 1],\n                [16, 32, 64, 64, 128, 256],\n                block=BottleneckX, **kwargs)\n    if pretrained is not None:\n        model.load_pretrained_model(pretrained, 'dla46x_c')\n    return model\n\n\ndef dla60x_c(pretrained, **kwargs):  # DLA-X-60-C\n    BottleneckX.expansion = 2\n    model = DLA([1, 1, 1, 2, 3, 1],\n                [16, 32, 64, 64, 128, 256],\n                block=BottleneckX, **kwargs)\n    if pretrained:\n        model.load_pretrained_model(data='imagenet', name='dla60x_c', hash='b870c45c')\n    return model\n\n\ndef dla60(pretrained=None, **kwargs):  # DLA-60\n    Bottleneck.expansion = 2\n    model = DLA([1, 1, 1, 2, 3, 1],\n                [16, 32, 128, 256, 512, 1024],\n                block=Bottleneck, **kwargs)\n    if pretrained is not None:\n        model.load_pretrained_model(pretrained, 'dla60')\n    return model\n\n\ndef dla60x(pretrained=None, **kwargs):  # DLA-X-60\n    BottleneckX.expansion = 2\n    model = DLA([1, 1, 1, 2, 3, 1],\n                [16, 32, 128, 256, 512, 1024],\n                block=BottleneckX, **kwargs)\n    if pretrained is not None:\n        model.load_pretrained_model(pretrained, 'dla60x')\n    return model\n\n\ndef dla102(pretrained=None, **kwargs):  # DLA-102\n    Bottleneck.expansion = 2\n    model = DLA([1, 1, 1, 3, 4, 1], [16, 32, 128, 256, 512, 1024],\n                block=Bottleneck, residual_root=True, **kwargs)\n    if pretrained is not None:\n        model.load_pretrained_model(pretrained, 'dla102')\n    return model\n\n\ndef dla102x(pretrained=None, **kwargs):  # DLA-X-102\n    BottleneckX.expansion = 2\n    model = DLA([1, 1, 1, 3, 4, 1], [16, 32, 128, 256, 512, 1024],\n                block=BottleneckX, residual_root=True, **kwargs)\n    if pretrained is not None:\n        model.load_pretrained_model(pretrained, 'dla102x')\n    return model\n\n\ndef dla102x2(pretrained=None, **kwargs):  # DLA-X-102 64\n    BottleneckX.cardinality = 64\n    model = DLA([1, 1, 1, 3, 4, 1], [16, 32, 128, 256, 512, 1024],\n                block=BottleneckX, residual_root=True, **kwargs)\n    if pretrained is not None:\n        model.load_pretrained_model(pretrained, 'dla102x2')\n    return model\n\n\ndef dla169(pretrained=None, **kwargs):  # DLA-169\n    Bottleneck.expansion = 2\n    model = DLA([1, 1, 2, 3, 5, 1], [16, 32, 128, 256, 512, 1024],\n                block=Bottleneck, residual_root=True, **kwargs)\n    if pretrained is not None:\n        model.load_pretrained_model(pretrained, 'dla169')\n    return model\n\n\ndef set_bn(bn):\n    global BatchNorm\n    BatchNorm = bn\n    dla.BatchNorm = bn\n\n\nclass Identity(nn.Module):\n    def __init__(self):\n        super(Identity, self).__init__()\n\n    def forward(self, x):\n        return x\n\n\ndef fill_up_weights(up):\n    w = up.weight.data\n    f = math.ceil(w.size(2) / 2)\n    c = (2 * f - 1 - f % 2) / (2. * f)\n    for i in range(w.size(2)):\n        for j in range(w.size(3)):\n            w[0, 0, i, j] = \\\n                (1 - math.fabs(i / f - c)) * (1 - math.fabs(j / f - c))\n    for c in range(1, w.size(0)):\n        w[c, 0, :, :] = w[0, 0, :, :]\n\n\nclass IDAUp(nn.Module):\n    def __init__(self, node_kernel, out_dim, channels, up_factors):\n        super(IDAUp, self).__init__()\n        self.channels = channels\n        self.out_dim = out_dim\n        for i, c in enumerate(channels):\n            if c == out_dim:\n                proj = Identity()\n            else:\n                proj = nn.Sequential(\n                    nn.Conv2d(c, out_dim,\n                              kernel_size=1, stride=1, bias=False),\n                    BatchNorm(out_dim),\n                    nn.ReLU(inplace=True))\n            f = int(up_factors[i])\n            if f == 1:\n                up = Identity()\n            else:\n                up = nn.ConvTranspose2d(\n                    out_dim, out_dim, f * 2, stride=f, padding=f // 2,\n                    output_padding=0, groups=out_dim, bias=False)\n                fill_up_weights(up)\n            setattr(self, 'proj_' + str(i), proj)\n            setattr(self, 'up_' + str(i), up)\n\n        for i in range(1, len(channels)):\n            node = nn.Sequential(\n                nn.Conv2d(out_dim * 2, out_dim,\n                          kernel_size=node_kernel, stride=1,\n                          padding=node_kernel // 2, bias=False),\n                BatchNorm(out_dim),\n                nn.ReLU(inplace=True))\n            setattr(self, 'node_' + str(i), node)\n\n        for m in self.modules():\n            if isinstance(m, nn.Conv2d):\n                n = m.kernel_size[0] * m.kernel_size[1] * m.out_channels\n                m.weight.data.normal_(0, math.sqrt(2. / n))\n            elif isinstance(m, BatchNorm):\n                m.weight.data.fill_(1)\n                m.bias.data.zero_()\n\n    def forward(self, layers):\n        assert len(self.channels) == len(layers), \\\n            '{} vs {} layers'.format(len(self.channels), len(layers))\n        layers = list(layers)\n        for i, l in enumerate(layers):\n            upsample = getattr(self, 'up_' + str(i))\n            project = getattr(self, 'proj_' + str(i))\n            layers[i] = upsample(project(l))\n        x = layers[0]\n        y = []\n        for i in range(1, len(layers)):\n            node = getattr(self, 'node_' + str(i))\n            x = node(torch.cat([x, layers[i]], 1))\n            y.append(x)\n        return x, y\n\n\nclass DLAUp(nn.Module):\n    def __init__(self, channels, scales=(1, 2, 4, 8, 16), in_channels=None):\n        super(DLAUp, self).__init__()\n        if in_channels is None:\n            in_channels = channels\n        self.channels = channels\n        channels = list(channels)\n        scales = np.array(scales, dtype=int)\n        for i in range(len(channels) - 1):\n            j = -i - 2\n            setattr(self, 'ida_{}'.format(i),\n                    IDAUp(3, channels[j], in_channels[j:],\n                          scales[j:] // scales[j]))\n            scales[j + 1:] = scales[j]\n            in_channels[j + 1:] = [channels[j] for _ in channels[j + 1:]]\n\n    def forward(self, layers):\n        layers = list(layers)\n        assert len(layers) > 1\n        for i in range(len(layers) - 1):\n            ida = getattr(self, 'ida_{}'.format(i))\n            x, y = ida(layers[-i - 2:])\n            layers[-i - 1:] = y\n        return x\n\ndef fill_fc_weights(layers):\n    for m in layers.modules():\n        if isinstance(m, nn.Conv2d):\n            nn.init.normal_(m.weight, std=0.001)\n            # torch.nn.init.kaiming_normal_(m.weight.data, nonlinearity='relu')\n            # torch.nn.init.xavier_normal_(m.weight.data)\n            if m.bias is not None:\n                nn.init.constant_(m.bias, 0)\n\nclass DLASeg(nn.Module):\n    def __init__(self, base_name, heads,\n                 pretrained=True, down_ratio=4, head_conv=256):\n        super(DLASeg, self).__init__()\n        assert down_ratio in [2, 4, 8, 16]\n        self.heads = heads\n        self.first_level = int(np.log2(down_ratio))\n        self.base = globals()[base_name](\n          pretrained=pretrained, return_levels=True)\n        channels = self.base.channels\n        scales = [2 ** i for i in range(len(channels[self.first_level:]))]\n        self.dla_up = DLAUp(channels[self.first_level:], scales=scales)\n        '''\n        self.fc = nn.Sequential(\n            nn.Conv2d(channels[self.first_level], classes, kernel_size=1,\n                      stride=1, padding=0, bias=True)\n        )\n        '''\n\n        for head in self.heads:\n            classes = self.heads[head]\n            if head_conv > 0:\n                fc = nn.Sequential(\n                  nn.Conv2d(channels[self.first_level], head_conv,\n                    kernel_size=3, padding=1, bias=True),\n                  nn.ReLU(inplace=True),\n                  nn.Conv2d(head_conv, classes, \n                    kernel_size=1, stride=1, \n                    padding=0, bias=True))\n                if 'hm' in head:\n                    fc[-1].bias.data.fill_(-2.19)\n                else:\n                    fill_fc_weights(fc)\n            else:\n                fc = nn.Conv2d(channels[self.first_level], classes, \n                  kernel_size=1, stride=1, \n                  padding=0, bias=True)\n                if 'hm' in head:\n                    fc.bias.data.fill_(-2.19)\n                else:\n                    fill_fc_weights(fc)\n            self.__setattr__(head, fc)\n\n        '''\n        up_factor = 2 ** self.first_level\n        if up_factor > 1:\n            up = nn.ConvTranspose2d(classes, classes, up_factor * 2,\n                                    stride=up_factor, padding=up_factor // 2,\n                                    output_padding=0, groups=classes,\n                                    bias=False)\n            fill_up_weights(up)\n            up.weight.requires_grad = False\n        else:\n            up = Identity()\n        self.up = up\n        self.softmax = nn.LogSoftmax(dim=1)\n        \n\n        for m in self.fc.modules():\n            if isinstance(m, nn.Conv2d):\n                n = m.kernel_size[0] * m.kernel_size[1] * m.out_channels\n                m.weight.data.normal_(0, math.sqrt(2. / n))\n            elif isinstance(m, BatchNorm):\n                m.weight.data.fill_(1)\n                m.bias.data.zero_()\n        '''\n\n    def forward(self, x):\n        x = self.base(x)\n        x = self.dla_up(x[self.first_level:])\n        # x = self.fc(x)\n        # y = self.softmax(self.up(x))\n        ret = {}\n        for head in self.heads:\n            ret[head] = self.__getattr__(head)(x)\n        return [ret]\n\n    '''\n    def optim_parameters(self, memo=None):\n        for param in self.base.parameters():\n            yield param\n        for param in self.dla_up.parameters():\n            yield param\n        for param in self.fc.parameters():\n            yield param\n    '''\n'''\ndef dla34up(classes, pretrained_base=None, **kwargs):\n    model = DLASeg('dla34', classes, pretrained_base=pretrained_base, **kwargs)\n    return model\n\n\ndef dla60up(classes, pretrained_base=None, **kwargs):\n    model = DLASeg('dla60', classes, pretrained_base=pretrained_base, **kwargs)\n    return model\n\n\ndef dla102up(classes, pretrained_base=None, **kwargs):\n    model = DLASeg('dla102', classes,\n                   pretrained_base=pretrained_base, **kwargs)\n    return model\n\n\ndef dla169up(classes, pretrained_base=None, **kwargs):\n    model = DLASeg('dla169', classes,\n                   pretrained_base=pretrained_base, **kwargs)\n    return model\n'''\n\ndef get_pose_net(num_layers, heads, head_conv=256, down_ratio=4):\n  model = DLASeg('dla{}'.format(num_layers), heads,\n                 pretrained=True,\n                 down_ratio=down_ratio,\n                 head_conv=head_conv)\n  return model\n"
  },
  {
    "path": "src/lib/models/networks/large_hourglass.py",
    "content": "# ------------------------------------------------------------------------------\n# This code is base on \n# CornerNet (https://github.com/princeton-vl/CornerNet)\n# Copyright (c) 2018, University of Michigan\n# Licensed under the BSD 3-Clause License\n# ------------------------------------------------------------------------------\n\n\nfrom __future__ import absolute_import\nfrom __future__ import division\nfrom __future__ import print_function\n\nimport numpy as np\nimport torch\nimport torch.nn as nn\n\nclass convolution(nn.Module):\n    def __init__(self, k, inp_dim, out_dim, stride=1, with_bn=True):\n        super(convolution, self).__init__()\n\n        pad = (k - 1) // 2\n        self.conv = nn.Conv2d(inp_dim, out_dim, (k, k), padding=(pad, pad), stride=(stride, stride), bias=not with_bn)\n        self.bn   = nn.BatchNorm2d(out_dim) if with_bn else nn.Sequential()\n        self.relu = nn.ReLU(inplace=True)\n\n    def forward(self, x):\n        conv = self.conv(x)\n        bn   = self.bn(conv)\n        relu = self.relu(bn)\n        return relu\n\nclass fully_connected(nn.Module):\n    def __init__(self, inp_dim, out_dim, with_bn=True):\n        super(fully_connected, self).__init__()\n        self.with_bn = with_bn\n\n        self.linear = nn.Linear(inp_dim, out_dim)\n        if self.with_bn:\n            self.bn = nn.BatchNorm1d(out_dim)\n        self.relu   = nn.ReLU(inplace=True)\n\n    def forward(self, x):\n        linear = self.linear(x)\n        bn     = self.bn(linear) if self.with_bn else linear\n        relu   = self.relu(bn)\n        return relu\n\nclass residual(nn.Module):\n    def __init__(self, k, inp_dim, out_dim, stride=1, with_bn=True):\n        super(residual, self).__init__()\n\n        self.conv1 = nn.Conv2d(inp_dim, out_dim, (3, 3), padding=(1, 1), stride=(stride, stride), bias=False)\n        self.bn1   = nn.BatchNorm2d(out_dim)\n        self.relu1 = nn.ReLU(inplace=True)\n\n        self.conv2 = nn.Conv2d(out_dim, out_dim, (3, 3), padding=(1, 1), bias=False)\n        self.bn2   = nn.BatchNorm2d(out_dim)\n        \n        self.skip  = nn.Sequential(\n            nn.Conv2d(inp_dim, out_dim, (1, 1), stride=(stride, stride), bias=False),\n            nn.BatchNorm2d(out_dim)\n        ) if stride != 1 or inp_dim != out_dim else nn.Sequential()\n        self.relu  = nn.ReLU(inplace=True)\n\n    def forward(self, x):\n        conv1 = self.conv1(x)\n        bn1   = self.bn1(conv1)\n        relu1 = self.relu1(bn1)\n\n        conv2 = self.conv2(relu1)\n        bn2   = self.bn2(conv2)\n\n        skip  = self.skip(x)\n        return self.relu(bn2 + skip)\n\ndef make_layer(k, inp_dim, out_dim, modules, layer=convolution, **kwargs):\n    layers = [layer(k, inp_dim, out_dim, **kwargs)]\n    for _ in range(1, modules):\n        layers.append(layer(k, out_dim, out_dim, **kwargs))\n    return nn.Sequential(*layers)\n\ndef make_layer_revr(k, inp_dim, out_dim, modules, layer=convolution, **kwargs):\n    layers = []\n    for _ in range(modules - 1):\n        layers.append(layer(k, inp_dim, inp_dim, **kwargs))\n    layers.append(layer(k, inp_dim, out_dim, **kwargs))\n    return nn.Sequential(*layers)\n\nclass MergeUp(nn.Module):\n    def forward(self, up1, up2):\n        return up1 + up2\n\ndef make_merge_layer(dim):\n    return MergeUp()\n\n# def make_pool_layer(dim):\n#     return nn.MaxPool2d(kernel_size=2, stride=2)\n\ndef make_pool_layer(dim):\n    return nn.Sequential()\n\ndef make_unpool_layer(dim):\n    return nn.Upsample(scale_factor=2)\n\ndef make_kp_layer(cnv_dim, curr_dim, out_dim):\n    return nn.Sequential(\n        convolution(3, cnv_dim, curr_dim, with_bn=False),\n        nn.Conv2d(curr_dim, out_dim, (1, 1))\n    )\n\ndef make_inter_layer(dim):\n    return residual(3, dim, dim)\n\ndef make_cnv_layer(inp_dim, out_dim):\n    return convolution(3, inp_dim, out_dim)\n\nclass kp_module(nn.Module):\n    def __init__(\n        self, n, dims, modules, layer=residual,\n        make_up_layer=make_layer, make_low_layer=make_layer,\n        make_hg_layer=make_layer, make_hg_layer_revr=make_layer_revr,\n        make_pool_layer=make_pool_layer, make_unpool_layer=make_unpool_layer,\n        make_merge_layer=make_merge_layer, **kwargs\n    ):\n        super(kp_module, self).__init__()\n\n        self.n   = n\n\n        curr_mod = modules[0]\n        next_mod = modules[1]\n\n        curr_dim = dims[0]\n        next_dim = dims[1]\n\n        self.up1  = make_up_layer(\n            3, curr_dim, curr_dim, curr_mod, \n            layer=layer, **kwargs\n        )  \n        self.max1 = make_pool_layer(curr_dim)\n        self.low1 = make_hg_layer(\n            3, curr_dim, next_dim, curr_mod,\n            layer=layer, **kwargs\n        )\n        self.low2 = kp_module(\n            n - 1, dims[1:], modules[1:], layer=layer, \n            make_up_layer=make_up_layer, \n            make_low_layer=make_low_layer,\n            make_hg_layer=make_hg_layer,\n            make_hg_layer_revr=make_hg_layer_revr,\n            make_pool_layer=make_pool_layer,\n            make_unpool_layer=make_unpool_layer,\n            make_merge_layer=make_merge_layer,\n            **kwargs\n        ) if self.n > 1 else \\\n        make_low_layer(\n            3, next_dim, next_dim, next_mod,\n            layer=layer, **kwargs\n        )\n        self.low3 = make_hg_layer_revr(\n            3, next_dim, curr_dim, curr_mod,\n            layer=layer, **kwargs\n        )\n        self.up2  = make_unpool_layer(curr_dim)\n\n        self.merge = make_merge_layer(curr_dim)\n\n    def forward(self, x):\n        up1  = self.up1(x)\n        max1 = self.max1(x)\n        low1 = self.low1(max1)\n        low2 = self.low2(low1)\n        low3 = self.low3(low2)\n        up2  = self.up2(low3)\n        return self.merge(up1, up2)\n\nclass exkp(nn.Module):\n    def __init__(\n        self, n, nstack, dims, modules, heads, pre=None, cnv_dim=256, \n        make_tl_layer=None, make_br_layer=None,\n        make_cnv_layer=make_cnv_layer, make_heat_layer=make_kp_layer,\n        make_tag_layer=make_kp_layer, make_regr_layer=make_kp_layer,\n        make_up_layer=make_layer, make_low_layer=make_layer, \n        make_hg_layer=make_layer, make_hg_layer_revr=make_layer_revr,\n        make_pool_layer=make_pool_layer, make_unpool_layer=make_unpool_layer,\n        make_merge_layer=make_merge_layer, make_inter_layer=make_inter_layer, \n        kp_layer=residual\n    ):\n        super(exkp, self).__init__()\n\n        self.nstack    = nstack\n        self.heads     = heads\n\n        curr_dim = dims[0]\n\n        self.pre = nn.Sequential(\n            convolution(7, 3, 128, stride=2),\n            residual(3, 128, 256, stride=2)\n        ) if pre is None else pre\n\n        self.kps  = nn.ModuleList([\n            kp_module(\n                n, dims, modules, layer=kp_layer,\n                make_up_layer=make_up_layer,\n                make_low_layer=make_low_layer,\n                make_hg_layer=make_hg_layer,\n                make_hg_layer_revr=make_hg_layer_revr,\n                make_pool_layer=make_pool_layer,\n                make_unpool_layer=make_unpool_layer,\n                make_merge_layer=make_merge_layer\n            ) for _ in range(nstack)\n        ])\n        self.cnvs = nn.ModuleList([\n            make_cnv_layer(curr_dim, cnv_dim) for _ in range(nstack)\n        ])\n\n        self.inters = nn.ModuleList([\n            make_inter_layer(curr_dim) for _ in range(nstack - 1)\n        ])\n\n        self.inters_ = nn.ModuleList([\n            nn.Sequential(\n                nn.Conv2d(curr_dim, curr_dim, (1, 1), bias=False),\n                nn.BatchNorm2d(curr_dim)\n            ) for _ in range(nstack - 1)\n        ])\n        self.cnvs_   = nn.ModuleList([\n            nn.Sequential(\n                nn.Conv2d(cnv_dim, curr_dim, (1, 1), bias=False),\n                nn.BatchNorm2d(curr_dim)\n            ) for _ in range(nstack - 1)\n        ])\n\n        ## keypoint heatmaps\n        for head in heads.keys():\n            if 'hm' in head:\n                module =  nn.ModuleList([\n                    make_heat_layer(\n                        cnv_dim, curr_dim, heads[head]) for _ in range(nstack)\n                ])\n                self.__setattr__(head, module)\n                for heat in self.__getattr__(head):\n                    heat[-1].bias.data.fill_(-2.19)\n            else:\n                module = nn.ModuleList([\n                    make_regr_layer(\n                        cnv_dim, curr_dim, heads[head]) for _ in range(nstack)\n                ])\n                self.__setattr__(head, module)\n\n\n        self.relu = nn.ReLU(inplace=True)\n\n    def forward(self, image):\n        # print('image shape', image.shape)\n        inter = self.pre(image)\n        outs  = []\n\n        for ind in range(self.nstack):\n            kp_, cnv_  = self.kps[ind], self.cnvs[ind]\n            kp  = kp_(inter)\n            cnv = cnv_(kp)\n\n            out = {}\n            for head in self.heads:\n                layer = self.__getattr__(head)[ind]\n                y = layer(cnv)\n                out[head] = y\n            \n            outs.append(out)\n            if ind < self.nstack - 1:\n                inter = self.inters_[ind](inter) + self.cnvs_[ind](cnv)\n                inter = self.relu(inter)\n                inter = self.inters[ind](inter)\n        return outs\n\n\ndef make_hg_layer(kernel, dim0, dim1, mod, layer=convolution, **kwargs):\n    layers  = [layer(kernel, dim0, dim1, stride=2)]\n    layers += [layer(kernel, dim1, dim1) for _ in range(mod - 1)]\n    return nn.Sequential(*layers)\n\n\nclass HourglassNet(exkp):\n    def __init__(self, heads, num_stacks=2):\n        n       = 5\n        dims    = [256, 256, 384, 384, 384, 512]\n        modules = [2, 2, 2, 2, 2, 4]\n\n        super(HourglassNet, self).__init__(\n            n, num_stacks, dims, modules, heads,\n            make_tl_layer=None,\n            make_br_layer=None,\n            make_pool_layer=make_pool_layer,\n            make_hg_layer=make_hg_layer,\n            kp_layer=residual, cnv_dim=256\n        )\n\ndef get_large_hourglass_net(num_layers, heads, head_conv):\n  model = HourglassNet(heads, 2)\n  return model\n"
  },
  {
    "path": "src/lib/models/networks/msra_resnet.py",
    "content": "# ------------------------------------------------------------------------------\n# Copyright (c) Microsoft\n# Licensed under the MIT License.\n# Written by Bin Xiao (Bin.Xiao@microsoft.com)\n# Modified by Xingyi Zhou\n# ------------------------------------------------------------------------------\n\nfrom __future__ import absolute_import\nfrom __future__ import division\nfrom __future__ import print_function\n\nimport os\n\nimport torch\nimport torch.nn as nn\nimport torch.utils.model_zoo as model_zoo\n\nBN_MOMENTUM = 0.1\n\nmodel_urls = {\n    'resnet18': 'https://download.pytorch.org/models/resnet18-5c106cde.pth',\n    'resnet34': 'https://download.pytorch.org/models/resnet34-333f7ec4.pth',\n    'resnet50': 'https://download.pytorch.org/models/resnet50-19c8e357.pth',\n    'resnet101': 'https://download.pytorch.org/models/resnet101-5d3b4d8f.pth',\n    'resnet152': 'https://download.pytorch.org/models/resnet152-b121ed2d.pth',\n}\n\ndef conv3x3(in_planes, out_planes, stride=1):\n    \"\"\"3x3 convolution with padding\"\"\"\n    return nn.Conv2d(in_planes, out_planes, kernel_size=3, stride=stride,\n                     padding=1, bias=False)\n\n\nclass BasicBlock(nn.Module):\n    expansion = 1\n\n    def __init__(self, inplanes, planes, stride=1, downsample=None):\n        super(BasicBlock, self).__init__()\n        self.conv1 = conv3x3(inplanes, planes, stride)\n        self.bn1 = nn.BatchNorm2d(planes, momentum=BN_MOMENTUM)\n        self.relu = nn.ReLU(inplace=True)\n        self.conv2 = conv3x3(planes, planes)\n        self.bn2 = nn.BatchNorm2d(planes, momentum=BN_MOMENTUM)\n        self.downsample = downsample\n        self.stride = stride\n\n    def forward(self, x):\n        residual = x\n\n        out = self.conv1(x)\n        out = self.bn1(out)\n        out = self.relu(out)\n\n        out = self.conv2(out)\n        out = self.bn2(out)\n\n        if self.downsample is not None:\n            residual = self.downsample(x)\n\n        out += residual\n        out = self.relu(out)\n\n        return out\n\n\nclass Bottleneck(nn.Module):\n    expansion = 4\n\n    def __init__(self, inplanes, planes, stride=1, downsample=None):\n        super(Bottleneck, self).__init__()\n        self.conv1 = nn.Conv2d(inplanes, planes, kernel_size=1, bias=False)\n        self.bn1 = nn.BatchNorm2d(planes, momentum=BN_MOMENTUM)\n        self.conv2 = nn.Conv2d(planes, planes, kernel_size=3, stride=stride,\n                               padding=1, bias=False)\n        self.bn2 = nn.BatchNorm2d(planes, momentum=BN_MOMENTUM)\n        self.conv3 = nn.Conv2d(planes, planes * self.expansion, kernel_size=1,\n                               bias=False)\n        self.bn3 = nn.BatchNorm2d(planes * self.expansion,\n                                  momentum=BN_MOMENTUM)\n        self.relu = nn.ReLU(inplace=True)\n        self.downsample = downsample\n        self.stride = stride\n\n    def forward(self, x):\n        residual = x\n\n        out = self.conv1(x)\n        out = self.bn1(out)\n        out = self.relu(out)\n\n        out = self.conv2(out)\n        out = self.bn2(out)\n        out = self.relu(out)\n\n        out = self.conv3(out)\n        out = self.bn3(out)\n\n        if self.downsample is not None:\n            residual = self.downsample(x)\n\n        out += residual\n        out = self.relu(out)\n\n        return out\n\n\nclass PoseResNet(nn.Module):\n\n    def __init__(self, block, layers, heads, head_conv, **kwargs):\n        self.inplanes = 64\n        self.deconv_with_bias = False\n        self.heads = heads\n\n        super(PoseResNet, self).__init__()\n        self.conv1 = nn.Conv2d(3, 64, kernel_size=7, stride=2, padding=3,\n                               bias=False)\n        self.bn1 = nn.BatchNorm2d(64, momentum=BN_MOMENTUM)\n        self.relu = nn.ReLU(inplace=True)\n        self.maxpool = nn.MaxPool2d(kernel_size=3, stride=2, padding=1)\n        self.layer1 = self._make_layer(block, 64, layers[0])\n        self.layer2 = self._make_layer(block, 128, layers[1], stride=2)\n        self.layer3 = self._make_layer(block, 256, layers[2], stride=2)\n        self.layer4 = self._make_layer(block, 512, layers[3], stride=2)\n\n        # used for deconv layers\n        self.deconv_layers = self._make_deconv_layer(\n            3,\n            [256, 256, 256],\n            [4, 4, 4],\n        )\n        # self.final_layer = []\n\n        for head in sorted(self.heads):\n          num_output = self.heads[head]\n          if head_conv > 0:\n            fc = nn.Sequential(\n                nn.Conv2d(256, head_conv,\n                  kernel_size=3, padding=1, bias=True),\n                nn.ReLU(inplace=True),\n                nn.Conv2d(head_conv, num_output, \n                  kernel_size=1, stride=1, padding=0))\n          else:\n            fc = nn.Conv2d(\n              in_channels=256,\n              out_channels=num_output,\n              kernel_size=1,\n              stride=1,\n              padding=0\n          )\n          self.__setattr__(head, fc)\n\n        # self.final_layer = nn.ModuleList(self.final_layer)\n\n    def _make_layer(self, block, planes, blocks, stride=1):\n        downsample = None\n        if stride != 1 or self.inplanes != planes * block.expansion:\n            downsample = nn.Sequential(\n                nn.Conv2d(self.inplanes, planes * block.expansion,\n                          kernel_size=1, stride=stride, bias=False),\n                nn.BatchNorm2d(planes * block.expansion, momentum=BN_MOMENTUM),\n            )\n\n        layers = []\n        layers.append(block(self.inplanes, planes, stride, downsample))\n        self.inplanes = planes * block.expansion\n        for i in range(1, blocks):\n            layers.append(block(self.inplanes, planes))\n\n        return nn.Sequential(*layers)\n\n    def _get_deconv_cfg(self, deconv_kernel, index):\n        if deconv_kernel == 4:\n            padding = 1\n            output_padding = 0\n        elif deconv_kernel == 3:\n            padding = 1\n            output_padding = 1\n        elif deconv_kernel == 2:\n            padding = 0\n            output_padding = 0\n\n        return deconv_kernel, padding, output_padding\n\n    def _make_deconv_layer(self, num_layers, num_filters, num_kernels):\n        assert num_layers == len(num_filters), \\\n            'ERROR: num_deconv_layers is different len(num_deconv_filters)'\n        assert num_layers == len(num_kernels), \\\n            'ERROR: num_deconv_layers is different len(num_deconv_filters)'\n\n        layers = []\n        for i in range(num_layers):\n            kernel, padding, output_padding = \\\n                self._get_deconv_cfg(num_kernels[i], i)\n\n            planes = num_filters[i]\n            layers.append(\n                nn.ConvTranspose2d(\n                    in_channels=self.inplanes,\n                    out_channels=planes,\n                    kernel_size=kernel,\n                    stride=2,\n                    padding=padding,\n                    output_padding=output_padding,\n                    bias=self.deconv_with_bias))\n            layers.append(nn.BatchNorm2d(planes, momentum=BN_MOMENTUM))\n            layers.append(nn.ReLU(inplace=True))\n            self.inplanes = planes\n\n        return nn.Sequential(*layers)\n\n    def forward(self, x):\n        x = self.conv1(x)\n        x = self.bn1(x)\n        x = self.relu(x)\n        x = self.maxpool(x)\n\n        x = self.layer1(x)\n        x = self.layer2(x)\n        x = self.layer3(x)\n        x = self.layer4(x)\n\n        x = self.deconv_layers(x)\n        ret = {}\n        for head in self.heads:\n            ret[head] = self.__getattr__(head)(x)\n        return [ret]\n\n    def init_weights(self, num_layers, pretrained=True):\n        if pretrained:\n            # print('=> init resnet deconv weights from normal distribution')\n            for _, m in self.deconv_layers.named_modules():\n                if isinstance(m, nn.ConvTranspose2d):\n                    # print('=> init {}.weight as normal(0, 0.001)'.format(name))\n                    # print('=> init {}.bias as 0'.format(name))\n                    nn.init.normal_(m.weight, std=0.001)\n                    if self.deconv_with_bias:\n                        nn.init.constant_(m.bias, 0)\n                elif isinstance(m, nn.BatchNorm2d):\n                    # print('=> init {}.weight as 1'.format(name))\n                    # print('=> init {}.bias as 0'.format(name))\n                    nn.init.constant_(m.weight, 1)\n                    nn.init.constant_(m.bias, 0)\n            # print('=> init final conv weights from normal distribution')\n            for head in self.heads:\n              final_layer = self.__getattr__(head)\n              for i, m in enumerate(final_layer.modules()):\n                  if isinstance(m, nn.Conv2d):\n                      # nn.init.kaiming_normal_(m.weight, mode='fan_out', nonlinearity='relu')\n                      # print('=> init {}.weight as normal(0, 0.001)'.format(name))\n                      # print('=> init {}.bias as 0'.format(name))\n                      if m.weight.shape[0] == self.heads[head]:\n                          if 'hm' in head:\n                              nn.init.constant_(m.bias, -2.19)\n                          else:\n                              nn.init.normal_(m.weight, std=0.001)\n                              nn.init.constant_(m.bias, 0)\n            #pretrained_state_dict = torch.load(pretrained)\n            url = model_urls['resnet{}'.format(num_layers)]\n            pretrained_state_dict = model_zoo.load_url(url)\n            print('=> loading pretrained model {}'.format(url))\n            self.load_state_dict(pretrained_state_dict, strict=False)\n        else:\n            print('=> imagenet pretrained model dose not exist')\n            print('=> please download it first')\n            raise ValueError('imagenet pretrained model does not exist')\n\n\nresnet_spec = {18: (BasicBlock, [2, 2, 2, 2]),\n               34: (BasicBlock, [3, 4, 6, 3]),\n               50: (Bottleneck, [3, 4, 6, 3]),\n               101: (Bottleneck, [3, 4, 23, 3]),\n               152: (Bottleneck, [3, 8, 36, 3])}\n\n\ndef get_pose_net(num_layers, heads, head_conv):\n  block_class, layers = resnet_spec[num_layers]\n\n  model = PoseResNet(block_class, layers, heads, head_conv=head_conv)\n  model.init_weights(num_layers, pretrained=True)\n  return model\n"
  },
  {
    "path": "src/lib/models/networks/pose_dla_dcn.py",
    "content": "from __future__ import absolute_import\nfrom __future__ import division\nfrom __future__ import print_function\n\nimport os\nimport math\nimport logging\nimport numpy as np\nfrom os.path import join\n\nimport torch\nfrom torch import nn\nimport torch.nn.functional as F\nimport torch.utils.model_zoo as model_zoo\n\nfrom .DCNv2.dcn_v2 import DCN\n\nBN_MOMENTUM = 0.1\nlogger = logging.getLogger(__name__)\n\ndef get_model_url(data='imagenet', name='dla34', hash='ba72cf86'):\n    return join('http://dl.yf.io/dla/models', data, '{}-{}.pth'.format(name, hash))\n\n\ndef conv3x3(in_planes, out_planes, stride=1):\n    \"3x3 convolution with padding\"\n    return nn.Conv2d(in_planes, out_planes, kernel_size=3, stride=stride,\n                     padding=1, bias=False)\n\n\nclass BasicBlock(nn.Module):\n    def __init__(self, inplanes, planes, stride=1, dilation=1):\n        super(BasicBlock, self).__init__()\n        self.conv1 = nn.Conv2d(inplanes, planes, kernel_size=3,\n                               stride=stride, padding=dilation,\n                               bias=False, dilation=dilation)\n        self.bn1 = nn.BatchNorm2d(planes, momentum=BN_MOMENTUM)\n        self.relu = nn.ReLU(inplace=True)\n        self.conv2 = nn.Conv2d(planes, planes, kernel_size=3,\n                               stride=1, padding=dilation,\n                               bias=False, dilation=dilation)\n        self.bn2 = nn.BatchNorm2d(planes, momentum=BN_MOMENTUM)\n        self.stride = stride\n\n    def forward(self, x, residual=None):\n        if residual is None:\n            residual = x\n\n        out = self.conv1(x)\n        out = self.bn1(out)\n        out = self.relu(out)\n\n        out = self.conv2(out)\n        out = self.bn2(out)\n\n        out += residual\n        out = self.relu(out)\n\n        return out\n\n\nclass Bottleneck(nn.Module):\n    expansion = 2\n\n    def __init__(self, inplanes, planes, stride=1, dilation=1):\n        super(Bottleneck, self).__init__()\n        expansion = Bottleneck.expansion\n        bottle_planes = planes // expansion\n        self.conv1 = nn.Conv2d(inplanes, bottle_planes,\n                               kernel_size=1, bias=False)\n        self.bn1 = nn.BatchNorm2d(bottle_planes, momentum=BN_MOMENTUM)\n        self.conv2 = nn.Conv2d(bottle_planes, bottle_planes, kernel_size=3,\n                               stride=stride, padding=dilation,\n                               bias=False, dilation=dilation)\n        self.bn2 = nn.BatchNorm2d(bottle_planes, momentum=BN_MOMENTUM)\n        self.conv3 = nn.Conv2d(bottle_planes, planes,\n                               kernel_size=1, bias=False)\n        self.bn3 = nn.BatchNorm2d(planes, momentum=BN_MOMENTUM)\n        self.relu = nn.ReLU(inplace=True)\n        self.stride = stride\n\n    def forward(self, x, residual=None):\n        if residual is None:\n            residual = x\n\n        out = self.conv1(x)\n        out = self.bn1(out)\n        out = self.relu(out)\n\n        out = self.conv2(out)\n        out = self.bn2(out)\n        out = self.relu(out)\n\n        out = self.conv3(out)\n        out = self.bn3(out)\n\n        out += residual\n        out = self.relu(out)\n\n        return out\n\n\nclass BottleneckX(nn.Module):\n    expansion = 2\n    cardinality = 32\n\n    def __init__(self, inplanes, planes, stride=1, dilation=1):\n        super(BottleneckX, self).__init__()\n        cardinality = BottleneckX.cardinality\n        # dim = int(math.floor(planes * (BottleneckV5.expansion / 64.0)))\n        # bottle_planes = dim * cardinality\n        bottle_planes = planes * cardinality // 32\n        self.conv1 = nn.Conv2d(inplanes, bottle_planes,\n                               kernel_size=1, bias=False)\n        self.bn1 = nn.BatchNorm2d(bottle_planes, momentum=BN_MOMENTUM)\n        self.conv2 = nn.Conv2d(bottle_planes, bottle_planes, kernel_size=3,\n                               stride=stride, padding=dilation, bias=False,\n                               dilation=dilation, groups=cardinality)\n        self.bn2 = nn.BatchNorm2d(bottle_planes, momentum=BN_MOMENTUM)\n        self.conv3 = nn.Conv2d(bottle_planes, planes,\n                               kernel_size=1, bias=False)\n        self.bn3 = nn.BatchNorm2d(planes, momentum=BN_MOMENTUM)\n        self.relu = nn.ReLU(inplace=True)\n        self.stride = stride\n\n    def forward(self, x, residual=None):\n        if residual is None:\n            residual = x\n\n        out = self.conv1(x)\n        out = self.bn1(out)\n        out = self.relu(out)\n\n        out = self.conv2(out)\n        out = self.bn2(out)\n        out = self.relu(out)\n\n        out = self.conv3(out)\n        out = self.bn3(out)\n\n        out += residual\n        out = self.relu(out)\n\n        return out\n\n\nclass Root(nn.Module):\n    def __init__(self, in_channels, out_channels, kernel_size, residual):\n        super(Root, self).__init__()\n        self.conv = nn.Conv2d(\n            in_channels, out_channels, 1,\n            stride=1, bias=False, padding=(kernel_size - 1) // 2)\n        self.bn = nn.BatchNorm2d(out_channels, momentum=BN_MOMENTUM)\n        self.relu = nn.ReLU(inplace=True)\n        self.residual = residual\n\n    def forward(self, *x):\n        children = x\n        x = self.conv(torch.cat(x, 1))\n        x = self.bn(x)\n        if self.residual:\n            x += children[0]\n        x = self.relu(x)\n\n        return x\n\n\nclass Tree(nn.Module):\n    def __init__(self, levels, block, in_channels, out_channels, stride=1,\n                 level_root=False, root_dim=0, root_kernel_size=1,\n                 dilation=1, root_residual=False):\n        super(Tree, self).__init__()\n        if root_dim == 0:\n            root_dim = 2 * out_channels\n        if level_root:\n            root_dim += in_channels\n        if levels == 1:\n            self.tree1 = block(in_channels, out_channels, stride,\n                               dilation=dilation)\n            self.tree2 = block(out_channels, out_channels, 1,\n                               dilation=dilation)\n        else:\n            self.tree1 = Tree(levels - 1, block, in_channels, out_channels,\n                              stride, root_dim=0,\n                              root_kernel_size=root_kernel_size,\n                              dilation=dilation, root_residual=root_residual)\n            self.tree2 = Tree(levels - 1, block, out_channels, out_channels,\n                              root_dim=root_dim + out_channels,\n                              root_kernel_size=root_kernel_size,\n                              dilation=dilation, root_residual=root_residual)\n        if levels == 1:\n            self.root = Root(root_dim, out_channels, root_kernel_size,\n                             root_residual)\n        self.level_root = level_root\n        self.root_dim = root_dim\n        self.downsample = None\n        self.project = None\n        self.levels = levels\n        if stride > 1:\n            self.downsample = nn.MaxPool2d(stride, stride=stride)\n        if in_channels != out_channels:\n            self.project = nn.Sequential(\n                nn.Conv2d(in_channels, out_channels,\n                          kernel_size=1, stride=1, bias=False),\n                nn.BatchNorm2d(out_channels, momentum=BN_MOMENTUM)\n            )\n\n    def forward(self, x, residual=None, children=None):\n        children = [] if children is None else children\n        bottom = self.downsample(x) if self.downsample else x\n        residual = self.project(bottom) if self.project else bottom\n        if self.level_root:\n            children.append(bottom)\n        x1 = self.tree1(x, residual)\n        if self.levels == 1:\n            x2 = self.tree2(x1)\n            x = self.root(x2, x1, *children)\n        else:\n            children.append(x1)\n            x = self.tree2(x1, children=children)\n        return x\n\n\nclass DLA(nn.Module):\n    def __init__(self, levels, channels, num_classes=1000,\n                 block=BasicBlock, residual_root=False, linear_root=False):\n        super(DLA, self).__init__()\n        self.channels = channels\n        self.num_classes = num_classes\n        self.base_layer = nn.Sequential(\n            nn.Conv2d(3, channels[0], kernel_size=7, stride=1,\n                      padding=3, bias=False),\n            nn.BatchNorm2d(channels[0], momentum=BN_MOMENTUM),\n            nn.ReLU(inplace=True))\n        self.level0 = self._make_conv_level(\n            channels[0], channels[0], levels[0])\n        self.level1 = self._make_conv_level(\n            channels[0], channels[1], levels[1], stride=2)\n        self.level2 = Tree(levels[2], block, channels[1], channels[2], 2,\n                           level_root=False,\n                           root_residual=residual_root)\n        self.level3 = Tree(levels[3], block, channels[2], channels[3], 2,\n                           level_root=True, root_residual=residual_root)\n        self.level4 = Tree(levels[4], block, channels[3], channels[4], 2,\n                           level_root=True, root_residual=residual_root)\n        self.level5 = Tree(levels[5], block, channels[4], channels[5], 2,\n                           level_root=True, root_residual=residual_root)\n\n        # for m in self.modules():\n        #     if isinstance(m, nn.Conv2d):\n        #         n = m.kernel_size[0] * m.kernel_size[1] * m.out_channels\n        #         m.weight.data.normal_(0, math.sqrt(2. / n))\n        #     elif isinstance(m, nn.BatchNorm2d):\n        #         m.weight.data.fill_(1)\n        #         m.bias.data.zero_()\n\n    def _make_level(self, block, inplanes, planes, blocks, stride=1):\n        downsample = None\n        if stride != 1 or inplanes != planes:\n            downsample = nn.Sequential(\n                nn.MaxPool2d(stride, stride=stride),\n                nn.Conv2d(inplanes, planes,\n                          kernel_size=1, stride=1, bias=False),\n                nn.BatchNorm2d(planes, momentum=BN_MOMENTUM),\n            )\n\n        layers = []\n        layers.append(block(inplanes, planes, stride, downsample=downsample))\n        for i in range(1, blocks):\n            layers.append(block(inplanes, planes))\n\n        return nn.Sequential(*layers)\n\n    def _make_conv_level(self, inplanes, planes, convs, stride=1, dilation=1):\n        modules = []\n        for i in range(convs):\n            modules.extend([\n                nn.Conv2d(inplanes, planes, kernel_size=3,\n                          stride=stride if i == 0 else 1,\n                          padding=dilation, bias=False, dilation=dilation),\n                nn.BatchNorm2d(planes, momentum=BN_MOMENTUM),\n                nn.ReLU(inplace=True)])\n            inplanes = planes\n        return nn.Sequential(*modules)\n\n    def forward(self, x):\n        y = []\n        x = self.base_layer(x)\n        for i in range(6):\n            x = getattr(self, 'level{}'.format(i))(x)\n            y.append(x)\n        return y\n\n    def load_pretrained_model(self, data='imagenet', name='dla34', hash='ba72cf86'):\n        # fc = self.fc\n        if name.endswith('.pth'):\n            model_weights = torch.load(data + name)\n        else:\n            model_url = get_model_url(data, name, hash)\n            model_weights = model_zoo.load_url(model_url)\n        num_classes = len(model_weights[list(model_weights.keys())[-1]])\n        self.fc = nn.Conv2d(\n            self.channels[-1], num_classes,\n            kernel_size=1, stride=1, padding=0, bias=True)\n        self.load_state_dict(model_weights)\n        # self.fc = fc\n\n\ndef dla34(pretrained=True, **kwargs):  # DLA-34\n    model = DLA([1, 1, 1, 2, 2, 1],\n                [16, 32, 64, 128, 256, 512],\n                block=BasicBlock, **kwargs)\n    if pretrained:\n        model.load_pretrained_model(data='imagenet', name='dla34', hash='ba72cf86')\n    return model\n\nclass Identity(nn.Module):\n\n    def __init__(self):\n        super(Identity, self).__init__()\n\n    def forward(self, x):\n        return x\n\n\ndef fill_fc_weights(layers):\n    for m in layers.modules():\n        if isinstance(m, nn.Conv2d):\n            if m.bias is not None:\n                nn.init.constant_(m.bias, 0)\n\n\ndef fill_up_weights(up):\n    w = up.weight.data\n    f = math.ceil(w.size(2) / 2)\n    c = (2 * f - 1 - f % 2) / (2. * f)\n    for i in range(w.size(2)):\n        for j in range(w.size(3)):\n            w[0, 0, i, j] = \\\n                (1 - math.fabs(i / f - c)) * (1 - math.fabs(j / f - c))\n    for c in range(1, w.size(0)):\n        w[c, 0, :, :] = w[0, 0, :, :]\n\n\nclass DeformConv(nn.Module):\n    def __init__(self, chi, cho):\n        super(DeformConv, self).__init__()\n        self.actf = nn.Sequential(\n            nn.BatchNorm2d(cho, momentum=BN_MOMENTUM),\n            nn.ReLU(inplace=True)\n        )\n        self.conv = DCN(chi, cho, kernel_size=(3,3), stride=1, padding=1, dilation=1, deformable_groups=1)\n\n    def forward(self, x):\n        x = self.conv(x)\n        x = self.actf(x)\n        return x\n\n\nclass IDAUp(nn.Module):\n\n    def __init__(self, o, channels, up_f):\n        super(IDAUp, self).__init__()\n        for i in range(1, len(channels)):\n            c = channels[i]\n            f = int(up_f[i])  \n            proj = DeformConv(c, o)\n            node = DeformConv(o, o)\n     \n            up = nn.ConvTranspose2d(o, o, f * 2, stride=f, \n                                    padding=f // 2, output_padding=0,\n                                    groups=o, bias=False)\n            fill_up_weights(up)\n\n            setattr(self, 'proj_' + str(i), proj)\n            setattr(self, 'up_' + str(i), up)\n            setattr(self, 'node_' + str(i), node)\n                 \n        \n    def forward(self, layers, startp, endp):\n        for i in range(startp + 1, endp):\n            upsample = getattr(self, 'up_' + str(i - startp))\n            project = getattr(self, 'proj_' + str(i - startp))\n            layers[i] = upsample(project(layers[i]))\n            node = getattr(self, 'node_' + str(i - startp))\n            layers[i] = node(layers[i] + layers[i - 1])\n\n\n\nclass DLAUp(nn.Module):\n    def __init__(self, startp, channels, scales, in_channels=None):\n        super(DLAUp, self).__init__()\n        self.startp = startp\n        if in_channels is None:\n            in_channels = channels\n        self.channels = channels\n        channels = list(channels)\n        scales = np.array(scales, dtype=int)\n        for i in range(len(channels) - 1):\n            j = -i - 2\n            setattr(self, 'ida_{}'.format(i),\n                    IDAUp(channels[j], in_channels[j:],\n                          scales[j:] // scales[j]))\n            scales[j + 1:] = scales[j]\n            in_channels[j + 1:] = [channels[j] for _ in channels[j + 1:]]\n\n    def forward(self, layers):\n        out = [layers[-1]] # start with 32\n        for i in range(len(layers) - self.startp - 1):\n            ida = getattr(self, 'ida_{}'.format(i))\n            ida(layers, len(layers) -i - 2, len(layers))\n            out.insert(0, layers[-1])\n        return out\n\n\nclass Interpolate(nn.Module):\n    def __init__(self, scale, mode):\n        super(Interpolate, self).__init__()\n        self.scale = scale\n        self.mode = mode\n        \n    def forward(self, x):\n        x = F.interpolate(x, scale_factor=self.scale, mode=self.mode, align_corners=False)\n        return x\n\n\nclass DLASeg(nn.Module):\n    def __init__(self, base_name, heads, pretrained, down_ratio, final_kernel,\n                 last_level, head_conv, out_channel=0):\n        super(DLASeg, self).__init__()\n        assert down_ratio in [2, 4, 8, 16]\n        self.first_level = int(np.log2(down_ratio))\n        self.last_level = last_level\n        self.base = globals()[base_name](pretrained=pretrained)\n        channels = self.base.channels\n        scales = [2 ** i for i in range(len(channels[self.first_level:]))]\n        self.dla_up = DLAUp(self.first_level, channels[self.first_level:], scales)\n\n        if out_channel == 0:\n            out_channel = channels[self.first_level]\n\n        self.ida_up = IDAUp(out_channel, channels[self.first_level:self.last_level], \n                            [2 ** i for i in range(self.last_level - self.first_level)])\n        \n        self.heads = heads\n        for head in self.heads:\n            classes = self.heads[head]\n            if head_conv > 0:\n              fc = nn.Sequential(\n                  nn.Conv2d(channels[self.first_level], head_conv,\n                    kernel_size=3, padding=1, bias=True),\n                  nn.ReLU(inplace=True),\n                  nn.Conv2d(head_conv, classes, \n                    kernel_size=final_kernel, stride=1, \n                    padding=final_kernel // 2, bias=True))\n              if 'hm' in head:\n                fc[-1].bias.data.fill_(-2.19)\n              else:\n                fill_fc_weights(fc)\n            else:\n              fc = nn.Conv2d(channels[self.first_level], classes, \n                  kernel_size=final_kernel, stride=1, \n                  padding=final_kernel // 2, bias=True)\n              if 'hm' in head:\n                fc.bias.data.fill_(-2.19)\n              else:\n                fill_fc_weights(fc)\n            self.__setattr__(head, fc)\n\n    def forward(self, x):\n        x = self.base(x)\n        x = self.dla_up(x)\n\n        y = []\n        for i in range(self.last_level - self.first_level):\n            y.append(x[i].clone())\n        self.ida_up(y, 0, len(y))\n\n        z = {}\n        for head in self.heads:\n            z[head] = self.__getattr__(head)(y[-1])\n        return [z]\n    \n\ndef get_pose_net(num_layers, heads, head_conv=256, down_ratio=4):\n  model = DLASeg('dla{}'.format(num_layers), heads,\n                 pretrained=True,\n                 down_ratio=down_ratio,\n                 final_kernel=1,\n                 last_level=5,\n                 head_conv=head_conv)\n  return model\n\n"
  },
  {
    "path": "src/lib/models/networks/resnet_dcn.py",
    "content": "# ------------------------------------------------------------------------------\n# Copyright (c) Microsoft\n# Licensed under the MIT License.\n# Written by Bin Xiao (Bin.Xiao@microsoft.com)\n# Modified by Dequan Wang and Xingyi Zhou\n# ------------------------------------------------------------------------------\n\nfrom __future__ import absolute_import\nfrom __future__ import division\nfrom __future__ import print_function\n\nimport os\nimport math\nimport logging\n\nimport torch\nimport torch.nn as nn\nfrom .DCNv2.dcn_v2 import DCN\nimport torch.utils.model_zoo as model_zoo\n\nBN_MOMENTUM = 0.1\nlogger = logging.getLogger(__name__)\n\nmodel_urls = {\n    'resnet18': 'https://download.pytorch.org/models/resnet18-5c106cde.pth',\n    'resnet34': 'https://download.pytorch.org/models/resnet34-333f7ec4.pth',\n    'resnet50': 'https://download.pytorch.org/models/resnet50-19c8e357.pth',\n    'resnet101': 'https://download.pytorch.org/models/resnet101-5d3b4d8f.pth',\n    'resnet152': 'https://download.pytorch.org/models/resnet152-b121ed2d.pth',\n}\n\ndef conv3x3(in_planes, out_planes, stride=1):\n    \"\"\"3x3 convolution with padding\"\"\"\n    return nn.Conv2d(in_planes, out_planes, kernel_size=3, stride=stride,\n                     padding=1, bias=False)\n\n\nclass BasicBlock(nn.Module):\n    expansion = 1\n\n    def __init__(self, inplanes, planes, stride=1, downsample=None):\n        super(BasicBlock, self).__init__()\n        self.conv1 = conv3x3(inplanes, planes, stride)\n        self.bn1 = nn.BatchNorm2d(planes, momentum=BN_MOMENTUM)\n        self.relu = nn.ReLU(inplace=True)\n        self.conv2 = conv3x3(planes, planes)\n        self.bn2 = nn.BatchNorm2d(planes, momentum=BN_MOMENTUM)\n        self.downsample = downsample\n        self.stride = stride\n\n    def forward(self, x):\n        residual = x\n\n        out = self.conv1(x)\n        out = self.bn1(out)\n        out = self.relu(out)\n\n        out = self.conv2(out)\n        out = self.bn2(out)\n\n        if self.downsample is not None:\n            residual = self.downsample(x)\n\n        out += residual\n        out = self.relu(out)\n\n        return out\n\n\nclass Bottleneck(nn.Module):\n    expansion = 4\n\n    def __init__(self, inplanes, planes, stride=1, downsample=None):\n        super(Bottleneck, self).__init__()\n        self.conv1 = nn.Conv2d(inplanes, planes, kernel_size=1, bias=False)\n        self.bn1 = nn.BatchNorm2d(planes, momentum=BN_MOMENTUM)\n        self.conv2 = nn.Conv2d(planes, planes, kernel_size=3, stride=stride,\n                               padding=1, bias=False)\n        self.bn2 = nn.BatchNorm2d(planes, momentum=BN_MOMENTUM)\n        self.conv3 = nn.Conv2d(planes, planes * self.expansion, kernel_size=1,\n                               bias=False)\n        self.bn3 = nn.BatchNorm2d(planes * self.expansion,\n                                  momentum=BN_MOMENTUM)\n        self.relu = nn.ReLU(inplace=True)\n        self.downsample = downsample\n        self.stride = stride\n\n    def forward(self, x):\n        residual = x\n\n        out = self.conv1(x)\n        out = self.bn1(out)\n        out = self.relu(out)\n\n        out = self.conv2(out)\n        out = self.bn2(out)\n        out = self.relu(out)\n\n        out = self.conv3(out)\n        out = self.bn3(out)\n\n        if self.downsample is not None:\n            residual = self.downsample(x)\n\n        out += residual\n        out = self.relu(out)\n\n        return out\n\ndef fill_up_weights(up):\n    w = up.weight.data\n    f = math.ceil(w.size(2) / 2)\n    c = (2 * f - 1 - f % 2) / (2. * f)\n    for i in range(w.size(2)):\n        for j in range(w.size(3)):\n            w[0, 0, i, j] = \\\n                (1 - math.fabs(i / f - c)) * (1 - math.fabs(j / f - c))\n    for c in range(1, w.size(0)):\n        w[c, 0, :, :] = w[0, 0, :, :] \n\ndef fill_fc_weights(layers):\n    for m in layers.modules():\n        if isinstance(m, nn.Conv2d):\n            nn.init.normal_(m.weight, std=0.001)\n            # torch.nn.init.kaiming_normal_(m.weight.data, nonlinearity='relu')\n            # torch.nn.init.xavier_normal_(m.weight.data)\n            if m.bias is not None:\n                nn.init.constant_(m.bias, 0)\n\nclass PoseResNet(nn.Module):\n\n    def __init__(self, block, layers, heads, head_conv):\n        self.inplanes = 64\n        self.heads = heads\n        self.deconv_with_bias = False\n\n        super(PoseResNet, self).__init__()\n        self.conv1 = nn.Conv2d(3, 64, kernel_size=7, stride=2, padding=3,\n                               bias=False)\n        self.bn1 = nn.BatchNorm2d(64, momentum=BN_MOMENTUM)\n        self.relu = nn.ReLU(inplace=True)\n        self.maxpool = nn.MaxPool2d(kernel_size=3, stride=2, padding=1)\n        self.layer1 = self._make_layer(block, 64, layers[0])\n        self.layer2 = self._make_layer(block, 128, layers[1], stride=2)\n        self.layer3 = self._make_layer(block, 256, layers[2], stride=2)\n        self.layer4 = self._make_layer(block, 512, layers[3], stride=2)\n\n        # used for deconv layers\n        self.deconv_layers = self._make_deconv_layer(\n            3,\n            [256, 128, 64],\n            [4, 4, 4],\n        )\n\n        for head in self.heads:\n            classes = self.heads[head]\n            if head_conv > 0:\n                fc = nn.Sequential(\n                  nn.Conv2d(64, head_conv,\n                    kernel_size=3, padding=1, bias=True),\n                  nn.ReLU(inplace=True),\n                  nn.Conv2d(head_conv, classes, \n                    kernel_size=1, stride=1, \n                    padding=0, bias=True))\n                if 'hm' in head:\n                    fc[-1].bias.data.fill_(-2.19)\n                else:\n                    fill_fc_weights(fc)\n            else:\n                fc = nn.Conv2d(64, classes, \n                  kernel_size=1, stride=1, \n                  padding=0, bias=True)\n                if 'hm' in head:\n                    fc.bias.data.fill_(-2.19)\n                else:\n                    fill_fc_weights(fc)\n            self.__setattr__(head, fc)\n\n    def _make_layer(self, block, planes, blocks, stride=1):\n        downsample = None\n        if stride != 1 or self.inplanes != planes * block.expansion:\n            downsample = nn.Sequential(\n                nn.Conv2d(self.inplanes, planes * block.expansion,\n                          kernel_size=1, stride=stride, bias=False),\n                nn.BatchNorm2d(planes * block.expansion, momentum=BN_MOMENTUM),\n            )\n\n        layers = []\n        layers.append(block(self.inplanes, planes, stride, downsample))\n        self.inplanes = planes * block.expansion\n        for i in range(1, blocks):\n            layers.append(block(self.inplanes, planes))\n\n        return nn.Sequential(*layers)\n\n    def _get_deconv_cfg(self, deconv_kernel, index):\n        if deconv_kernel == 4:\n            padding = 1\n            output_padding = 0\n        elif deconv_kernel == 3:\n            padding = 1\n            output_padding = 1\n        elif deconv_kernel == 2:\n            padding = 0\n            output_padding = 0\n\n        return deconv_kernel, padding, output_padding\n\n    def _make_deconv_layer(self, num_layers, num_filters, num_kernels):\n        assert num_layers == len(num_filters), \\\n            'ERROR: num_deconv_layers is different len(num_deconv_filters)'\n        assert num_layers == len(num_kernels), \\\n            'ERROR: num_deconv_layers is different len(num_deconv_filters)'\n\n        layers = []\n        for i in range(num_layers):\n            kernel, padding, output_padding = \\\n                self._get_deconv_cfg(num_kernels[i], i)\n\n            planes = num_filters[i]\n            fc = DCN(self.inplanes, planes, \n                    kernel_size=(3,3), stride=1,\n                    padding=1, dilation=1, deformable_groups=1)\n            # fc = nn.Conv2d(self.inplanes, planes,\n            #         kernel_size=3, stride=1, \n            #         padding=1, dilation=1, bias=False)\n            # fill_fc_weights(fc)\n            up = nn.ConvTranspose2d(\n                    in_channels=planes,\n                    out_channels=planes,\n                    kernel_size=kernel,\n                    stride=2,\n                    padding=padding,\n                    output_padding=output_padding,\n                    bias=self.deconv_with_bias)\n            fill_up_weights(up)\n\n            layers.append(fc)\n            layers.append(nn.BatchNorm2d(planes, momentum=BN_MOMENTUM))\n            layers.append(nn.ReLU(inplace=True))\n            layers.append(up)\n            layers.append(nn.BatchNorm2d(planes, momentum=BN_MOMENTUM))\n            layers.append(nn.ReLU(inplace=True))\n            self.inplanes = planes\n\n        return nn.Sequential(*layers)\n\n    def forward(self, x):\n        x = self.conv1(x)\n        x = self.bn1(x)\n        x = self.relu(x)\n        x = self.maxpool(x)\n\n        x = self.layer1(x)\n        x = self.layer2(x)\n        x = self.layer3(x)\n        x = self.layer4(x)\n\n        x = self.deconv_layers(x)\n        ret = {}\n        for head in self.heads:\n            ret[head] = self.__getattr__(head)(x)\n        return [ret]\n\n    def init_weights(self, num_layers):\n        if 1:\n            url = model_urls['resnet{}'.format(num_layers)]\n            pretrained_state_dict = model_zoo.load_url(url)\n            print('=> loading pretrained model {}'.format(url))\n            self.load_state_dict(pretrained_state_dict, strict=False)\n            print('=> init deconv weights from normal distribution')\n            for name, m in self.deconv_layers.named_modules():\n                if isinstance(m, nn.BatchNorm2d):\n                    nn.init.constant_(m.weight, 1)\n                    nn.init.constant_(m.bias, 0)\n\n\nresnet_spec = {18: (BasicBlock, [2, 2, 2, 2]),\n               34: (BasicBlock, [3, 4, 6, 3]),\n               50: (Bottleneck, [3, 4, 6, 3]),\n               101: (Bottleneck, [3, 4, 23, 3]),\n               152: (Bottleneck, [3, 8, 36, 3])}\n\n\ndef get_pose_net(num_layers, heads, head_conv=256):\n  block_class, layers = resnet_spec[num_layers]\n\n  model = PoseResNet(block_class, layers, heads, head_conv=head_conv)\n  model.init_weights(num_layers)\n  return model\n"
  },
  {
    "path": "src/lib/models/scatter_gather.py",
    "content": "import torch\nfrom torch.autograd import Variable\nfrom torch.nn.parallel._functions import Scatter, Gather\n\n\ndef scatter(inputs, target_gpus, dim=0, chunk_sizes=None):\n    r\"\"\"\n    Slices variables into approximately equal chunks and\n    distributes them across given GPUs. Duplicates\n    references to objects that are not variables. Does not\n    support Tensors.\n    \"\"\"\n    def scatter_map(obj):\n        if isinstance(obj, Variable):\n            return Scatter.apply(target_gpus, chunk_sizes, dim, obj)\n        assert not torch.is_tensor(obj), \"Tensors not supported in scatter.\"\n        if isinstance(obj, tuple):\n            return list(zip(*map(scatter_map, obj)))\n        if isinstance(obj, list):\n            return list(map(list, zip(*map(scatter_map, obj))))\n        if isinstance(obj, dict):\n            return list(map(type(obj), zip(*map(scatter_map, obj.items()))))\n        return [obj for targets in target_gpus]\n\n    return scatter_map(inputs)\n\n\ndef scatter_kwargs(inputs, kwargs, target_gpus, dim=0, chunk_sizes=None):\n    r\"\"\"Scatter with support for kwargs dictionary\"\"\"\n    inputs = scatter(inputs, target_gpus, dim, chunk_sizes) if inputs else []\n    kwargs = scatter(kwargs, target_gpus, dim, chunk_sizes) if kwargs else []\n    if len(inputs) < len(kwargs):\n        inputs.extend([() for _ in range(len(kwargs) - len(inputs))])\n    elif len(kwargs) < len(inputs):\n        kwargs.extend([{} for _ in range(len(inputs) - len(kwargs))])\n    inputs = tuple(inputs)\n    kwargs = tuple(kwargs)\n    return inputs, kwargs\n"
  },
  {
    "path": "src/lib/models/utils.py",
    "content": "from __future__ import absolute_import\nfrom __future__ import division\nfrom __future__ import print_function\n\nimport torch\nimport torch.nn as nn\n\ndef _sigmoid(x):\n  y = torch.clamp(x.sigmoid_(), min=1e-4, max=1-1e-4)\n  return y\n\ndef _gather_feat(feat, ind, mask=None):\n    dim  = feat.size(2)\n    ind  = ind.unsqueeze(2).expand(ind.size(0), ind.size(1), dim)\n    feat = feat.gather(1, ind)\n    if mask is not None:\n        mask = mask.unsqueeze(2).expand_as(feat)\n        feat = feat[mask]\n        feat = feat.view(-1, dim)\n    return feat\n\ndef _transpose_and_gather_feat(feat, ind):\n    feat = feat.permute(0, 2, 3, 1).contiguous()\n    feat = feat.view(feat.size(0), -1, feat.size(3))\n    feat = _gather_feat(feat, ind)\n    return feat\n\ndef flip_tensor(x):\n    return torch.flip(x, [3])\n    # tmp = x.detach().cpu().numpy()[..., ::-1].copy()\n    # return torch.from_numpy(tmp).to(x.device)\n\ndef flip_lr(x, flip_idx):\n  tmp = x.detach().cpu().numpy()[..., ::-1].copy()\n  shape = tmp.shape\n  for e in flip_idx:\n    tmp[:, e[0], ...], tmp[:, e[1], ...] = \\\n      tmp[:, e[1], ...].copy(), tmp[:, e[0], ...].copy()\n  return torch.from_numpy(tmp.reshape(shape)).to(x.device)\n\ndef flip_lr_off(x, flip_idx):\n  tmp = x.detach().cpu().numpy()[..., ::-1].copy()\n  shape = tmp.shape\n  tmp = tmp.reshape(tmp.shape[0], 17, 2, \n                    tmp.shape[2], tmp.shape[3])\n  tmp[:, :, 0, :, :] *= -1\n  for e in flip_idx:\n    tmp[:, e[0], ...], tmp[:, e[1], ...] = \\\n      tmp[:, e[1], ...].copy(), tmp[:, e[0], ...].copy()\n  return torch.from_numpy(tmp.reshape(shape)).to(x.device)"
  },
  {
    "path": "src/lib/opts.py",
    "content": "from __future__ import absolute_import\nfrom __future__ import division\nfrom __future__ import print_function\n\nimport argparse\nimport os\nimport sys\n\nclass opts(object):\n  def __init__(self):\n    self.parser = argparse.ArgumentParser()\n    # basic experiment setting\n    self.parser.add_argument('task', default='ctdet',\n                             help='ctdet | ddd | multi_pose | exdet')\n    self.parser.add_argument('--dataset', default='coco',\n                             help='coco | kitti | coco_hp | pascal')\n    self.parser.add_argument('--exp_id', default='default')\n    self.parser.add_argument('--test', action='store_true')\n    self.parser.add_argument('--debug', type=int, default=0,\n                             help='level of visualization.'\n                                  '1: only show the final detection results'\n                                  '2: show the network output features'\n                                  '3: use matplot to display' # useful when lunching training with ipython notebook\n                                  '4: save all visualizations to disk')\n    self.parser.add_argument('--demo', default='', \n                             help='path to image/ image folders/ video. '\n                                  'or \"webcam\"')\n    self.parser.add_argument('--load_model', default='',\n                             help='path to pretrained model')\n    self.parser.add_argument('--resume', action='store_true',\n                             help='resume an experiment. '\n                                  'Reloaded the optimizer parameter and '\n                                  'set load_model to model_last.pth '\n                                  'in the exp dir if load_model is empty.') \n\n    # system\n    self.parser.add_argument('--gpus', default='0', \n                             help='-1 for CPU, use comma for multiple gpus')\n    self.parser.add_argument('--num_workers', type=int, default=4,\n                             help='dataloader threads. 0 for single-thread.')\n    self.parser.add_argument('--not_cuda_benchmark', action='store_true',\n                             help='disable when the input size is not fixed.')\n    self.parser.add_argument('--seed', type=int, default=317, \n                             help='random seed') # from CornerNet\n\n    # log\n    self.parser.add_argument('--print_iter', type=int, default=0, \n                             help='disable progress bar and print to screen.')\n    self.parser.add_argument('--hide_data_time', action='store_true',\n                             help='not display time during training.')\n    self.parser.add_argument('--save_all', action='store_true',\n                             help='save model to disk every 5 epochs.')\n    self.parser.add_argument('--metric', default='loss', \n                             help='main metric to save best model')\n    self.parser.add_argument('--vis_thresh', type=float, default=0.3,\n                             help='visualization threshold.')\n    self.parser.add_argument('--debugger_theme', default='white', \n                             choices=['white', 'black'])\n    \n    # model\n    self.parser.add_argument('--arch', default='dla_34', \n                             help='model architecture. Currently tested'\n                                  'res_18 | res_101 | resdcn_18 | resdcn_101 |'\n                                  'dlav0_34 | dla_34 | hourglass')\n    self.parser.add_argument('--head_conv', type=int, default=-1,\n                             help='conv layer channels for output head'\n                                  '0 for no conv layer'\n                                  '-1 for default setting: '\n                                  '64 for resnets and 256 for dla.')\n    self.parser.add_argument('--down_ratio', type=int, default=4,\n                             help='output stride. Currently only supports 4.')\n\n    # input\n    self.parser.add_argument('--input_res', type=int, default=-1, \n                             help='input height and width. -1 for default from '\n                             'dataset. Will be overriden by input_h | input_w')\n    self.parser.add_argument('--input_h', type=int, default=-1, \n                             help='input height. -1 for default from dataset.')\n    self.parser.add_argument('--input_w', type=int, default=-1, \n                             help='input width. -1 for default from dataset.')\n    \n    # train\n    self.parser.add_argument('--lr', type=float, default=1.25e-4, \n                             help='learning rate for batch size 32.')\n    self.parser.add_argument('--lr_step', type=str, default='90,120',\n                             help='drop learning rate by 10.')\n    self.parser.add_argument('--num_epochs', type=int, default=140,\n                             help='total training epochs.')\n    self.parser.add_argument('--batch_size', type=int, default=32,\n                             help='batch size')\n    self.parser.add_argument('--master_batch_size', type=int, default=-1,\n                             help='batch size on the master gpu.')\n    self.parser.add_argument('--num_iters', type=int, default=-1,\n                             help='default: #samples / batch_size.')\n    self.parser.add_argument('--val_intervals', type=int, default=5,\n                             help='number of epochs to run validation.')\n    self.parser.add_argument('--trainval', action='store_true',\n                             help='include validation in training and '\n                                  'test on test set')\n\n    # test\n    self.parser.add_argument('--flip_test', action='store_true',\n                             help='flip data augmentation.')\n    self.parser.add_argument('--test_scales', type=str, default='1',\n                             help='multi scale test augmentation.')\n    self.parser.add_argument('--nms', action='store_true',\n                             help='run nms in testing.')\n    self.parser.add_argument('--K', type=int, default=100,\n                             help='max number of output objects.') \n    self.parser.add_argument('--not_prefetch_test', action='store_true',\n                             help='not use parallal data pre-processing.')\n    self.parser.add_argument('--fix_res', action='store_true',\n                             help='fix testing resolution or keep '\n                                  'the original resolution')\n    self.parser.add_argument('--keep_res', action='store_true',\n                             help='keep the original resolution'\n                                  ' during validation.')\n\n    # dataset\n    self.parser.add_argument('--not_rand_crop', action='store_true',\n                             help='not use the random crop data augmentation'\n                                  'from CornerNet.')\n    self.parser.add_argument('--shift', type=float, default=0.1,\n                             help='when not using random crop'\n                                  'apply shift augmentation.')\n    self.parser.add_argument('--scale', type=float, default=0.4,\n                             help='when not using random crop'\n                                  'apply scale augmentation.')\n    self.parser.add_argument('--rotate', type=float, default=0,\n                             help='when not using random crop'\n                                  'apply rotation augmentation.')\n    self.parser.add_argument('--flip', type = float, default=0.5,\n                             help='probability of applying flip augmentation.')\n    self.parser.add_argument('--no_color_aug', action='store_true',\n                             help='not use the color augmenation '\n                                  'from CornerNet')\n    # multi_pose\n    self.parser.add_argument('--aug_rot', type=float, default=0, \n                             help='probability of applying '\n                                  'rotation augmentation.')\n    # ddd\n    self.parser.add_argument('--aug_ddd', type=float, default=0.5,\n                             help='probability of applying crop augmentation.')\n    self.parser.add_argument('--rect_mask', action='store_true',\n                             help='for ignored object, apply mask on the '\n                                  'rectangular region or just center point.')\n    self.parser.add_argument('--kitti_split', default='3dop',\n                             help='different validation split for kitti: '\n                                  '3dop | subcnn')\n\n    # loss\n    self.parser.add_argument('--mse_loss', action='store_true',\n                             help='use mse loss or focal loss to train '\n                                  'keypoint heatmaps.')\n    # ctdet\n    self.parser.add_argument('--reg_loss', default='l1',\n                             help='regression loss: sl1 | l1 | l2')\n    self.parser.add_argument('--hm_weight', type=float, default=1,\n                             help='loss weight for keypoint heatmaps.')\n    self.parser.add_argument('--off_weight', type=float, default=1,\n                             help='loss weight for keypoint local offsets.')\n    self.parser.add_argument('--wh_weight', type=float, default=0.1,\n                             help='loss weight for bounding box size.')\n    # multi_pose\n    self.parser.add_argument('--hp_weight', type=float, default=1,\n                             help='loss weight for human pose offset.')\n    self.parser.add_argument('--hm_hp_weight', type=float, default=1,\n                             help='loss weight for human keypoint heatmap.')\n    # ddd\n    self.parser.add_argument('--dep_weight', type=float, default=1,\n                             help='loss weight for depth.')\n    self.parser.add_argument('--dim_weight', type=float, default=1,\n                             help='loss weight for 3d bounding box size.')\n    self.parser.add_argument('--rot_weight', type=float, default=1,\n                             help='loss weight for orientation.')\n    self.parser.add_argument('--peak_thresh', type=float, default=0.2)\n    \n    # task\n    # ctdet\n    self.parser.add_argument('--norm_wh', action='store_true',\n                             help='L1(\\hat(y) / y, 1) or L1(\\hat(y), y)')\n    self.parser.add_argument('--dense_wh', action='store_true',\n                             help='apply weighted regression near center or '\n                                  'just apply regression on center point.')\n    self.parser.add_argument('--cat_spec_wh', action='store_true',\n                             help='category specific bounding box size.')\n    self.parser.add_argument('--not_reg_offset', action='store_true',\n                             help='not regress local offset.')\n    # exdet\n    self.parser.add_argument('--agnostic_ex', action='store_true',\n                             help='use category agnostic extreme points.')\n    self.parser.add_argument('--scores_thresh', type=float, default=0.1,\n                             help='threshold for extreme point heatmap.')\n    self.parser.add_argument('--center_thresh', type=float, default=0.1,\n                             help='threshold for centermap.')\n    self.parser.add_argument('--aggr_weight', type=float, default=0.0,\n                             help='edge aggregation weight.')\n    # multi_pose\n    self.parser.add_argument('--dense_hp', action='store_true',\n                             help='apply weighted pose regression near center '\n                                  'or just apply regression on center point.')\n    self.parser.add_argument('--not_hm_hp', action='store_true',\n                             help='not estimate human joint heatmap, '\n                                  'directly use the joint offset from center.')\n    self.parser.add_argument('--not_reg_hp_offset', action='store_true',\n                             help='not regress local offset for '\n                                  'human joint heatmaps.')\n    self.parser.add_argument('--not_reg_bbox', action='store_true',\n                             help='not regression bounding box size.')\n    \n    # ground truth validation\n    self.parser.add_argument('--eval_oracle_hm', action='store_true', \n                             help='use ground center heatmap.')\n    self.parser.add_argument('--eval_oracle_wh', action='store_true', \n                             help='use ground truth bounding box size.')\n    self.parser.add_argument('--eval_oracle_offset', action='store_true', \n                             help='use ground truth local heatmap offset.')\n    self.parser.add_argument('--eval_oracle_kps', action='store_true', \n                             help='use ground truth human pose offset.')\n    self.parser.add_argument('--eval_oracle_hmhp', action='store_true', \n                             help='use ground truth human joint heatmaps.')\n    self.parser.add_argument('--eval_oracle_hp_offset', action='store_true', \n                             help='use ground truth human joint local offset.')\n    self.parser.add_argument('--eval_oracle_dep', action='store_true', \n                             help='use ground truth depth.')\n\n  def parse(self, args=''):\n    if args == '':\n      opt = self.parser.parse_args()\n    else:\n      opt = self.parser.parse_args(args)\n\n    opt.gpus_str = opt.gpus\n    opt.gpus = [int(gpu) for gpu in opt.gpus.split(',')]\n    opt.gpus = [i for i in range(len(opt.gpus))] if opt.gpus[0] >=0 else [-1]\n    opt.lr_step = [int(i) for i in opt.lr_step.split(',')]\n    opt.test_scales = [float(i) for i in opt.test_scales.split(',')]\n\n    opt.fix_res = not opt.keep_res\n    print('Fix size testing.' if opt.fix_res else 'Keep resolution testing.')\n    opt.reg_offset = not opt.not_reg_offset\n    opt.reg_bbox = not opt.not_reg_bbox\n    opt.hm_hp = not opt.not_hm_hp\n    opt.reg_hp_offset = (not opt.not_reg_hp_offset) and opt.hm_hp\n\n    if opt.head_conv == -1: # init default head_conv\n      opt.head_conv = 256 if 'dla' in opt.arch else 64\n    opt.pad = 127 if 'hourglass' in opt.arch else 31\n    opt.num_stacks = 2 if opt.arch == 'hourglass' else 1\n\n    if opt.trainval:\n      opt.val_intervals = 100000000\n\n    if opt.debug > 0:\n      opt.num_workers = 0\n      opt.batch_size = 1\n      opt.gpus = [opt.gpus[0]]\n      opt.master_batch_size = -1\n\n    if opt.master_batch_size == -1:\n      opt.master_batch_size = opt.batch_size // len(opt.gpus)\n    rest_batch_size = (opt.batch_size - opt.master_batch_size)\n    opt.chunk_sizes = [opt.master_batch_size]\n    for i in range(len(opt.gpus) - 1):\n      slave_chunk_size = rest_batch_size // (len(opt.gpus) - 1)\n      if i < rest_batch_size % (len(opt.gpus) - 1):\n        slave_chunk_size += 1\n      opt.chunk_sizes.append(slave_chunk_size)\n    print('training chunk_sizes:', opt.chunk_sizes)\n\n    opt.root_dir = os.path.join(os.path.dirname(__file__), '..', '..')\n    opt.data_dir = os.path.join(opt.root_dir, 'data')\n    opt.exp_dir = os.path.join(opt.root_dir, 'exp', opt.task)\n    opt.save_dir = os.path.join(opt.exp_dir, opt.exp_id)\n    opt.debug_dir = os.path.join(opt.save_dir, 'debug')\n    print('The output will be saved to ', opt.save_dir)\n    \n    if opt.resume and opt.load_model == '':\n      model_path = opt.save_dir[:-4] if opt.save_dir.endswith('TEST') \\\n                  else opt.save_dir\n      opt.load_model = os.path.join(model_path, 'model_last.pth')\n    return opt\n\n  def update_dataset_info_and_set_heads(self, opt, dataset):\n    input_h, input_w = dataset.default_resolution\n    opt.mean, opt.std = dataset.mean, dataset.std\n    opt.num_classes = dataset.num_classes\n\n    # input_h(w): opt.input_h overrides opt.input_res overrides dataset default\n    input_h = opt.input_res if opt.input_res > 0 else input_h\n    input_w = opt.input_res if opt.input_res > 0 else input_w\n    opt.input_h = opt.input_h if opt.input_h > 0 else input_h\n    opt.input_w = opt.input_w if opt.input_w > 0 else input_w\n    opt.output_h = opt.input_h // opt.down_ratio\n    opt.output_w = opt.input_w // opt.down_ratio\n    opt.input_res = max(opt.input_h, opt.input_w)\n    opt.output_res = max(opt.output_h, opt.output_w)\n    \n    if opt.task == 'exdet':\n      # assert opt.dataset in ['coco']\n      num_hm = 1 if opt.agnostic_ex else opt.num_classes\n      opt.heads = {'hm_t': num_hm, 'hm_l': num_hm, \n                   'hm_b': num_hm, 'hm_r': num_hm,\n                   'hm_c': opt.num_classes}\n      if opt.reg_offset:\n        opt.heads.update({'reg_t': 2, 'reg_l': 2, 'reg_b': 2, 'reg_r': 2})\n    elif opt.task == 'ddd':\n      # assert opt.dataset in ['gta', 'kitti', 'viper']\n      opt.heads = {'hm': opt.num_classes, 'dep': 1, 'rot': 8, 'dim': 3}\n      if opt.reg_bbox:\n        opt.heads.update(\n          {'wh': 2})\n      if opt.reg_offset:\n        opt.heads.update({'reg': 2})\n    elif opt.task == 'ctdet':\n      # assert opt.dataset in ['pascal', 'coco']\n      opt.heads = {'hm': opt.num_classes,\n                   'wh': 2 if not opt.cat_spec_wh else 2 * opt.num_classes}\n      if opt.reg_offset:\n        opt.heads.update({'reg': 2})\n    elif opt.task == 'multi_pose':\n      # assert opt.dataset in ['coco_hp']\n      opt.flip_idx = dataset.flip_idx\n      opt.heads = {'hm': opt.num_classes, 'wh': 2, 'hps': 34}\n      if opt.reg_offset:\n        opt.heads.update({'reg': 2})\n      if opt.hm_hp:\n        opt.heads.update({'hm_hp': 17})\n      if opt.reg_hp_offset:\n        opt.heads.update({'hp_offset': 2})\n    else:\n      assert 0, 'task not defined!'\n    print('heads', opt.heads)\n    return opt\n\n  def init(self, args=''):\n    default_dataset_info = {\n      'ctdet': {'default_resolution': [512, 512], 'num_classes': 80, \n                'mean': [0.408, 0.447, 0.470], 'std': [0.289, 0.274, 0.278],\n                'dataset': 'coco'},\n      'exdet': {'default_resolution': [512, 512], 'num_classes': 80, \n                'mean': [0.408, 0.447, 0.470], 'std': [0.289, 0.274, 0.278],\n                'dataset': 'coco'},\n      'multi_pose': {\n        'default_resolution': [512, 512], 'num_classes': 1, \n        'mean': [0.408, 0.447, 0.470], 'std': [0.289, 0.274, 0.278],\n        'dataset': 'coco_hp', 'num_joints': 17,\n        'flip_idx': [[1, 2], [3, 4], [5, 6], [7, 8], [9, 10], \n                     [11, 12], [13, 14], [15, 16]]},\n      'ddd': {'default_resolution': [384, 1280], 'num_classes': 3, \n                'mean': [0.485, 0.456, 0.406], 'std': [0.229, 0.224, 0.225],\n                'dataset': 'kitti'},\n    }\n    class Struct:\n      def __init__(self, entries):\n        for k, v in entries.items():\n          self.__setattr__(k, v)\n    opt = self.parse(args)\n    dataset = Struct(default_dataset_info[opt.task])\n    opt.dataset = dataset.dataset\n    opt = self.update_dataset_info_and_set_heads(opt, dataset)\n    return opt\n"
  },
  {
    "path": "src/lib/trains/base_trainer.py",
    "content": "from __future__ import absolute_import\nfrom __future__ import division\nfrom __future__ import print_function\n\nimport time\nimport torch\nfrom progress.bar import Bar\nfrom models.data_parallel import DataParallel\nfrom utils.utils import AverageMeter\n\n\nclass ModelWithLoss(torch.nn.Module):\n  def __init__(self, model, loss):\n    super(ModelWithLoss, self).__init__()\n    self.model = model\n    self.loss = loss\n  \n  def forward(self, batch):\n    outputs = self.model(batch['input'])\n    loss, loss_stats = self.loss(outputs, batch)\n    return outputs[-1], loss, loss_stats\n\nclass BaseTrainer(object):\n  def __init__(\n    self, opt, model, optimizer=None):\n    self.opt = opt\n    self.optimizer = optimizer\n    self.loss_stats, self.loss = self._get_losses(opt)\n    self.model_with_loss = ModelWithLoss(model, self.loss)\n\n  def set_device(self, gpus, chunk_sizes, device):\n    if len(gpus) > 1:\n      self.model_with_loss = DataParallel(\n        self.model_with_loss, device_ids=gpus, \n        chunk_sizes=chunk_sizes).to(device)\n    else:\n      self.model_with_loss = self.model_with_loss.to(device)\n    \n    for state in self.optimizer.state.values():\n      for k, v in state.items():\n        if isinstance(v, torch.Tensor):\n          state[k] = v.to(device=device, non_blocking=True)\n\n  def run_epoch(self, phase, epoch, data_loader):\n    model_with_loss = self.model_with_loss\n    if phase == 'train':\n      model_with_loss.train()\n    else:\n      if len(self.opt.gpus) > 1:\n        model_with_loss = self.model_with_loss.module\n      model_with_loss.eval()\n      torch.cuda.empty_cache()\n\n    opt = self.opt\n    results = {}\n    data_time, batch_time = AverageMeter(), AverageMeter()\n    avg_loss_stats = {l: AverageMeter() for l in self.loss_stats}\n    num_iters = len(data_loader) if opt.num_iters < 0 else opt.num_iters\n    bar = Bar('{}/{}'.format(opt.task, opt.exp_id), max=num_iters)\n    end = time.time()\n    for iter_id, batch in enumerate(data_loader):\n      if iter_id >= num_iters:\n        break\n      data_time.update(time.time() - end)\n\n      for k in batch:\n        if k != 'meta':\n          batch[k] = batch[k].to(device=opt.device, non_blocking=True)    \n      output, loss, loss_stats = model_with_loss(batch)\n      loss = loss.mean()\n      if phase == 'train':\n        self.optimizer.zero_grad()\n        loss.backward()\n        self.optimizer.step()\n      batch_time.update(time.time() - end)\n      end = time.time()\n\n      Bar.suffix = '{phase}: [{0}][{1}/{2}]|Tot: {total:} |ETA: {eta:} '.format(\n        epoch, iter_id, num_iters, phase=phase,\n        total=bar.elapsed_td, eta=bar.eta_td)\n      for l in avg_loss_stats:\n        avg_loss_stats[l].update(\n          loss_stats[l].mean().item(), batch['input'].size(0))\n        Bar.suffix = Bar.suffix + '|{} {:.4f} '.format(l, avg_loss_stats[l].avg)\n      if not opt.hide_data_time:\n        Bar.suffix = Bar.suffix + '|Data {dt.val:.3f}s({dt.avg:.3f}s) ' \\\n          '|Net {bt.avg:.3f}s'.format(dt=data_time, bt=batch_time)\n      if opt.print_iter > 0:\n        if iter_id % opt.print_iter == 0:\n          print('{}/{}| {}'.format(opt.task, opt.exp_id, Bar.suffix)) \n      else:\n        bar.next()\n      \n      if opt.debug > 0:\n        self.debug(batch, output, iter_id)\n      \n      if opt.test:\n        self.save_result(output, batch, results)\n      del output, loss, loss_stats\n    \n    bar.finish()\n    ret = {k: v.avg for k, v in avg_loss_stats.items()}\n    ret['time'] = bar.elapsed_td.total_seconds() / 60.\n    return ret, results\n  \n  def debug(self, batch, output, iter_id):\n    raise NotImplementedError\n\n  def save_result(self, output, batch, results):\n    raise NotImplementedError\n\n  def _get_losses(self, opt):\n    raise NotImplementedError\n  \n  def val(self, epoch, data_loader):\n    return self.run_epoch('val', epoch, data_loader)\n\n  def train(self, epoch, data_loader):\n    return self.run_epoch('train', epoch, data_loader)"
  },
  {
    "path": "src/lib/trains/ctdet.py",
    "content": "from __future__ import absolute_import\nfrom __future__ import division\nfrom __future__ import print_function\n\nimport torch\nimport numpy as np\n\nfrom models.losses import FocalLoss\nfrom models.losses import RegL1Loss, RegLoss, NormRegL1Loss, RegWeightedL1Loss\nfrom models.decode import ctdet_decode\nfrom models.utils import _sigmoid\nfrom utils.debugger import Debugger\nfrom utils.post_process import ctdet_post_process\nfrom utils.oracle_utils import gen_oracle_map\nfrom .base_trainer import BaseTrainer\n\nclass CtdetLoss(torch.nn.Module):\n  def __init__(self, opt):\n    super(CtdetLoss, self).__init__()\n    self.crit = torch.nn.MSELoss() if opt.mse_loss else FocalLoss()\n    self.crit_reg = RegL1Loss() if opt.reg_loss == 'l1' else \\\n              RegLoss() if opt.reg_loss == 'sl1' else None\n    self.crit_wh = torch.nn.L1Loss(reduction='sum') if opt.dense_wh else \\\n              NormRegL1Loss() if opt.norm_wh else \\\n              RegWeightedL1Loss() if opt.cat_spec_wh else self.crit_reg\n    self.opt = opt\n\n  def forward(self, outputs, batch):\n    opt = self.opt\n    hm_loss, wh_loss, off_loss = 0, 0, 0\n    for s in range(opt.num_stacks):\n      output = outputs[s]\n      if not opt.mse_loss:\n        output['hm'] = _sigmoid(output['hm'])\n\n      if opt.eval_oracle_hm:\n        output['hm'] = batch['hm']\n      if opt.eval_oracle_wh:\n        output['wh'] = torch.from_numpy(gen_oracle_map(\n          batch['wh'].detach().cpu().numpy(), \n          batch['ind'].detach().cpu().numpy(), \n          output['wh'].shape[3], output['wh'].shape[2])).to(opt.device)\n      if opt.eval_oracle_offset:\n        output['reg'] = torch.from_numpy(gen_oracle_map(\n          batch['reg'].detach().cpu().numpy(), \n          batch['ind'].detach().cpu().numpy(), \n          output['reg'].shape[3], output['reg'].shape[2])).to(opt.device)\n\n      hm_loss += self.crit(output['hm'], batch['hm']) / opt.num_stacks\n      if opt.wh_weight > 0:\n        if opt.dense_wh:\n          mask_weight = batch['dense_wh_mask'].sum() + 1e-4\n          wh_loss += (\n            self.crit_wh(output['wh'] * batch['dense_wh_mask'],\n            batch['dense_wh'] * batch['dense_wh_mask']) / \n            mask_weight) / opt.num_stacks\n        elif opt.cat_spec_wh:\n          wh_loss += self.crit_wh(\n            output['wh'], batch['cat_spec_mask'],\n            batch['ind'], batch['cat_spec_wh']) / opt.num_stacks\n        else:\n          wh_loss += self.crit_reg(\n            output['wh'], batch['reg_mask'],\n            batch['ind'], batch['wh']) / opt.num_stacks\n      \n      if opt.reg_offset and opt.off_weight > 0:\n        off_loss += self.crit_reg(output['reg'], batch['reg_mask'],\n                             batch['ind'], batch['reg']) / opt.num_stacks\n        \n    loss = opt.hm_weight * hm_loss + opt.wh_weight * wh_loss + \\\n           opt.off_weight * off_loss\n    loss_stats = {'loss': loss, 'hm_loss': hm_loss,\n                  'wh_loss': wh_loss, 'off_loss': off_loss}\n    return loss, loss_stats\n\nclass CtdetTrainer(BaseTrainer):\n  def __init__(self, opt, model, optimizer=None):\n    super(CtdetTrainer, self).__init__(opt, model, optimizer=optimizer)\n  \n  def _get_losses(self, opt):\n    loss_states = ['loss', 'hm_loss', 'wh_loss', 'off_loss']\n    loss = CtdetLoss(opt)\n    return loss_states, loss\n\n  def debug(self, batch, output, iter_id):\n    opt = self.opt\n    reg = output['reg'] if opt.reg_offset else None\n    dets = ctdet_decode(\n      output['hm'], output['wh'], reg=reg,\n      cat_spec_wh=opt.cat_spec_wh, K=opt.K)\n    dets = dets.detach().cpu().numpy().reshape(1, -1, dets.shape[2])\n    dets[:, :, :4] *= opt.down_ratio\n    dets_gt = batch['meta']['gt_det'].numpy().reshape(1, -1, dets.shape[2])\n    dets_gt[:, :, :4] *= opt.down_ratio\n    for i in range(1):\n      debugger = Debugger(\n        dataset=opt.dataset, ipynb=(opt.debug==3), theme=opt.debugger_theme)\n      img = batch['input'][i].detach().cpu().numpy().transpose(1, 2, 0)\n      img = np.clip(((\n        img * opt.std + opt.mean) * 255.), 0, 255).astype(np.uint8)\n      pred = debugger.gen_colormap(output['hm'][i].detach().cpu().numpy())\n      gt = debugger.gen_colormap(batch['hm'][i].detach().cpu().numpy())\n      debugger.add_blend_img(img, pred, 'pred_hm')\n      debugger.add_blend_img(img, gt, 'gt_hm')\n      debugger.add_img(img, img_id='out_pred')\n      for k in range(len(dets[i])):\n        if dets[i, k, 4] > opt.center_thresh:\n          debugger.add_coco_bbox(dets[i, k, :4], dets[i, k, -1],\n                                 dets[i, k, 4], img_id='out_pred')\n\n      debugger.add_img(img, img_id='out_gt')\n      for k in range(len(dets_gt[i])):\n        if dets_gt[i, k, 4] > opt.center_thresh:\n          debugger.add_coco_bbox(dets_gt[i, k, :4], dets_gt[i, k, -1],\n                                 dets_gt[i, k, 4], img_id='out_gt')\n\n      if opt.debug == 4:\n        debugger.save_all_imgs(opt.debug_dir, prefix='{}'.format(iter_id))\n      else:\n        debugger.show_all_imgs(pause=True)\n\n  def save_result(self, output, batch, results):\n    reg = output['reg'] if self.opt.reg_offset else None\n    dets = ctdet_decode(\n      output['hm'], output['wh'], reg=reg,\n      cat_spec_wh=self.opt.cat_spec_wh, K=self.opt.K)\n    dets = dets.detach().cpu().numpy().reshape(1, -1, dets.shape[2])\n    dets_out = ctdet_post_process(\n      dets.copy(), batch['meta']['c'].cpu().numpy(),\n      batch['meta']['s'].cpu().numpy(),\n      output['hm'].shape[2], output['hm'].shape[3], output['hm'].shape[1])\n    results[batch['meta']['img_id'].cpu().numpy()[0]] = dets_out[0]"
  },
  {
    "path": "src/lib/trains/ddd.py",
    "content": "from __future__ import absolute_import\nfrom __future__ import division\nfrom __future__ import print_function\n\nimport torch\nimport numpy as np\n\nfrom models.losses import FocalLoss, L1Loss, BinRotLoss\nfrom models.decode import ddd_decode\nfrom models.utils import _sigmoid\nfrom utils.debugger import Debugger\nfrom utils.post_process import ddd_post_process\nfrom utils.oracle_utils import gen_oracle_map\nfrom .base_trainer import BaseTrainer\n\nclass DddLoss(torch.nn.Module):\n  def __init__(self, opt):\n    super(DddLoss, self).__init__()\n    self.crit = torch.nn.MSELoss() if opt.mse_loss else FocalLoss()\n    self.crit_reg = L1Loss()\n    self.crit_rot = BinRotLoss()\n    self.opt = opt\n  \n  def forward(self, outputs, batch):\n    opt = self.opt\n\n    hm_loss, dep_loss, rot_loss, dim_loss = 0, 0, 0, 0\n    wh_loss, off_loss = 0, 0\n    for s in range(opt.num_stacks):\n      output = outputs[s]\n      output['hm'] = _sigmoid(output['hm'])\n      output['dep'] = 1. / (output['dep'].sigmoid() + 1e-6) - 1.\n      \n      if opt.eval_oracle_dep:\n        output['dep'] = torch.from_numpy(gen_oracle_map(\n          batch['dep'].detach().cpu().numpy(), \n          batch['ind'].detach().cpu().numpy(), \n          opt.output_w, opt.output_h)).to(opt.device)\n      \n      hm_loss += self.crit(output['hm'], batch['hm']) / opt.num_stacks\n      if opt.dep_weight > 0:\n        dep_loss += self.crit_reg(output['dep'], batch['reg_mask'],\n                                  batch['ind'], batch['dep']) / opt.num_stacks\n      if opt.dim_weight > 0:\n        dim_loss += self.crit_reg(output['dim'], batch['reg_mask'],\n                                  batch['ind'], batch['dim']) / opt.num_stacks\n      if opt.rot_weight > 0:\n        rot_loss += self.crit_rot(output['rot'], batch['rot_mask'],\n                                  batch['ind'], batch['rotbin'],\n                                  batch['rotres']) / opt.num_stacks\n      if opt.reg_bbox and opt.wh_weight > 0:\n        wh_loss += self.crit_reg(output['wh'], batch['rot_mask'],\n                                 batch['ind'], batch['wh']) / opt.num_stacks\n      if opt.reg_offset and opt.off_weight > 0:\n        off_loss += self.crit_reg(output['reg'], batch['rot_mask'],\n                                  batch['ind'], batch['reg']) / opt.num_stacks\n    loss = opt.hm_weight * hm_loss + opt.dep_weight * dep_loss + \\\n           opt.dim_weight * dim_loss + opt.rot_weight * rot_loss + \\\n           opt.wh_weight * wh_loss + opt.off_weight * off_loss\n\n    loss_stats = {'loss': loss, 'hm_loss': hm_loss, 'dep_loss': dep_loss, \n                  'dim_loss': dim_loss, 'rot_loss': rot_loss, \n                  'wh_loss': wh_loss, 'off_loss': off_loss}\n    return loss, loss_stats\n\nclass DddTrainer(BaseTrainer):\n  def __init__(self, opt, model, optimizer=None):\n    super(DddTrainer, self).__init__(opt, model, optimizer=optimizer)\n  \n  def _get_losses(self, opt):\n    loss_states = ['loss', 'hm_loss', 'dep_loss', 'dim_loss', 'rot_loss', \n                   'wh_loss', 'off_loss']\n    loss = DddLoss(opt)\n    return loss_states, loss\n\n  def debug(self, batch, output, iter_id):\n      opt = self.opt\n      wh = output['wh'] if opt.reg_bbox else None\n      reg = output['reg'] if opt.reg_offset else None\n      dets = ddd_decode(output['hm'], output['rot'], output['dep'],\n                          output['dim'], wh=wh, reg=reg, K=opt.K)\n\n      # x, y, score, r1-r8, depth, dim1-dim3, cls\n      dets = dets.detach().cpu().numpy().reshape(1, -1, dets.shape[2])\n      calib = batch['meta']['calib'].detach().numpy()\n      # x, y, score, rot, depth, dim1, dim2, dim3\n      # if opt.dataset == 'gta':\n      #   dets[:, 12:15] /= 3\n      dets_pred = ddd_post_process(\n        dets.copy(), batch['meta']['c'].detach().numpy(), \n        batch['meta']['s'].detach().numpy(), calib, opt)\n      dets_gt = ddd_post_process(\n        batch['meta']['gt_det'].detach().numpy().copy(),\n        batch['meta']['c'].detach().numpy(), \n        batch['meta']['s'].detach().numpy(), calib, opt)\n      #for i in range(input.size(0)):\n      for i in range(1):\n        debugger = Debugger(dataset=opt.dataset, ipynb=(opt.debug==3),\n                            theme=opt.debugger_theme)\n        img = batch['input'][i].detach().cpu().numpy().transpose(1, 2, 0)\n        img = ((img * self.opt.std + self.opt.mean) * 255.).astype(np.uint8)\n        pred = debugger.gen_colormap(\n          output['hm'][i].detach().cpu().numpy())\n        gt = debugger.gen_colormap(batch['hm'][i].detach().cpu().numpy())\n        debugger.add_blend_img(img, pred, 'hm_pred')\n        debugger.add_blend_img(img, gt, 'hm_gt')\n        # decode\n        debugger.add_ct_detection(\n          img, dets[i], show_box=opt.reg_bbox, center_thresh=opt.center_thresh, \n          img_id='det_pred')\n        debugger.add_ct_detection(\n          img, batch['meta']['gt_det'][i].cpu().numpy().copy(), \n          show_box=opt.reg_bbox, img_id='det_gt')\n        debugger.add_3d_detection(\n          batch['meta']['image_path'][i], dets_pred[i], calib[i],\n          center_thresh=opt.center_thresh, img_id='add_pred')\n        debugger.add_3d_detection(\n          batch['meta']['image_path'][i], dets_gt[i], calib[i],\n          center_thresh=opt.center_thresh, img_id='add_gt')\n        # debugger.add_bird_view(\n        #   dets_pred[i], center_thresh=opt.center_thresh, img_id='bird_pred')\n        # debugger.add_bird_view(dets_gt[i], img_id='bird_gt')\n        debugger.add_bird_views(\n          dets_pred[i], dets_gt[i], \n          center_thresh=opt.center_thresh, img_id='bird_pred_gt')\n        \n        # debugger.add_blend_img(img, pred, 'out', white=True)\n        debugger.compose_vis_add(\n          batch['meta']['image_path'][i], dets_pred[i], calib[i],\n          opt.center_thresh, pred, 'bird_pred_gt', img_id='out')\n        # debugger.add_img(img, img_id='out')\n        if opt.debug ==4:\n          debugger.save_all_imgs(opt.debug_dir, prefix='{}'.format(iter_id))\n        else:\n          debugger.show_all_imgs(pause=True)\n\n  def save_result(self, output, batch, results):\n    opt = self.opt\n    wh = output['wh'] if opt.reg_bbox else None\n    reg = output['reg'] if opt.reg_offset else None\n    dets = ddd_decode(output['hm'], output['rot'], output['dep'],\n                        output['dim'], wh=wh, reg=reg, K=opt.K)\n\n    # x, y, score, r1-r8, depth, dim1-dim3, cls\n    dets = dets.detach().cpu().numpy().reshape(1, -1, dets.shape[2])\n    calib = batch['meta']['calib'].detach().numpy()\n    # x, y, score, rot, depth, dim1, dim2, dim3\n    dets_pred = ddd_post_process(\n      dets.copy(), batch['meta']['c'].detach().numpy(), \n      batch['meta']['s'].detach().numpy(), calib, opt)\n    img_id = batch['meta']['img_id'].detach().numpy()[0]\n    results[img_id] = dets_pred[0]\n    for j in range(1, opt.num_classes + 1):\n      keep_inds = (results[img_id][j][:, -1] > opt.center_thresh)\n      results[img_id][j] = results[img_id][j][keep_inds]"
  },
  {
    "path": "src/lib/trains/exdet.py",
    "content": "from __future__ import absolute_import\nfrom __future__ import division\nfrom __future__ import print_function\n\nimport torch\nimport numpy as np\nimport cv2\nimport sys\nimport time\nfrom utils.debugger import Debugger\nfrom models.data_parallel import DataParallel\nfrom models.losses import FocalLoss, RegL1Loss\nfrom models.decode import agnex_ct_decode, exct_decode\nfrom models.utils import _sigmoid\nfrom .base_trainer import BaseTrainer\n\nclass ExdetLoss(torch.nn.Module):\n  def __init__(self, opt):\n    super(ExdetLoss, self).__init__()\n    self.crit = torch.nn.MSELoss() if opt.mse_loss else FocalLoss()\n    self.crit_reg = RegL1Loss()\n    self.opt = opt\n    self.parts = ['t', 'l', 'b', 'r', 'c']\n\n  def forward(self, outputs, batch):\n    opt = self.opt\n    hm_loss, reg_loss = 0, 0\n    for s in range(opt.num_stacks):\n      output = outputs[s]\n      for p in self.parts:\n        tag = 'hm_{}'.format(p)\n        output[tag] = _sigmoid(output[tag])\n        hm_loss += self.crit(output[tag], batch[tag]) / opt.num_stacks\n        if p != 'c' and opt.reg_offset and opt.off_weight > 0:\n          reg_loss += self.crit_reg(output['reg_{}'.format(p)], \n                                    batch['reg_mask'],\n                                    batch['ind_{}'.format(p)],\n                                    batch['reg_{}'.format(p)]) / opt.num_stacks\n    loss = opt.hm_weight * hm_loss + opt.off_weight * reg_loss\n    loss_stats = {'loss': loss, 'off_loss': reg_loss, 'hm_loss': hm_loss}\n    return loss, loss_stats\n\nclass ExdetTrainer(BaseTrainer):\n  def __init__(self, opt, model, optimizer=None):\n    super(ExdetTrainer, self).__init__(opt, model, optimizer=optimizer)\n    self.decode = agnex_ct_decode if opt.agnostic_ex else exct_decode\n\n  def _get_losses(self, opt):\n    loss_states = ['loss', 'hm_loss', 'off_loss']\n    loss = ExdetLoss(opt)\n    return loss_states, loss\n\n  def debug(self, batch, output, iter_id):\n    opt = self.opt\n    detections = self.decode(output['hm_t'], output['hm_l'], \n                             output['hm_b'], output['hm_r'], \n                             output['hm_c']).detach().cpu().numpy()\n    detections[:, :, :4] *= opt.input_res / opt.output_res\n    for i in range(1):\n      debugger = Debugger(\n        dataset=opt.dataset, ipynb=(opt.debug==3), theme=opt.debugger_theme)\n      pred_hm = np.zeros((opt.input_res, opt.input_res, 3), dtype=np.uint8)\n      gt_hm = np.zeros((opt.input_res, opt.input_res, 3), dtype=np.uint8)\n      img = batch['input'][i].detach().cpu().numpy().transpose(1, 2, 0)\n      img = ((img * self.opt.std + self.opt.mean) * 255.).astype(np.uint8)\n      for p in self.parts:\n        tag = 'hm_{}'.format(p)\n        pred = debugger.gen_colormap(output[tag][i].detach().cpu().numpy())\n        gt = debugger.gen_colormap(batch[tag][i].detach().cpu().numpy())\n        if p != 'c':\n          pred_hm = np.maximum(pred_hm, pred)\n          gt_hm = np.maximum(gt_hm, gt)\n        if p == 'c' or opt.debug > 2:\n          debugger.add_blend_img(img, pred, 'pred_{}'.format(p))\n          debugger.add_blend_img(img, gt, 'gt_{}'.format(p))\n      debugger.add_blend_img(img, pred_hm, 'pred')\n      debugger.add_blend_img(img, gt_hm, 'gt')\n      debugger.add_img(img, img_id='out')\n      for k in range(len(detections[i])):\n        if detections[i, k, 4] > 0.1:\n          debugger.add_coco_bbox(detections[i, k, :4], detections[i, k, -1],\n                                 detections[i, k, 4], img_id='out')\n      if opt.debug == 4:\n        debugger.save_all_imgs(opt.debug_dir, prefix='{}'.format(iter_id))\n      else:\n        debugger.show_all_imgs(pause=True)"
  },
  {
    "path": "src/lib/trains/multi_pose.py",
    "content": "from __future__ import absolute_import\nfrom __future__ import division\nfrom __future__ import print_function\n\nimport torch\nimport numpy as np\n\nfrom models.losses import FocalLoss, RegL1Loss, RegLoss, RegWeightedL1Loss\nfrom models.decode import multi_pose_decode\nfrom models.utils import _sigmoid, flip_tensor, flip_lr_off, flip_lr\nfrom utils.debugger import Debugger\nfrom utils.post_process import multi_pose_post_process\nfrom utils.oracle_utils import gen_oracle_map\nfrom .base_trainer import BaseTrainer\n\nclass MultiPoseLoss(torch.nn.Module):\n  def __init__(self, opt):\n    super(MultiPoseLoss, self).__init__()\n    self.crit = FocalLoss()\n    self.crit_hm_hp = torch.nn.MSELoss() if opt.mse_loss else FocalLoss()\n    self.crit_kp = RegWeightedL1Loss() if not opt.dense_hp else \\\n                   torch.nn.L1Loss(reduction='sum')\n    self.crit_reg = RegL1Loss() if opt.reg_loss == 'l1' else \\\n                    RegLoss() if opt.reg_loss == 'sl1' else None\n    self.opt = opt\n\n  def forward(self, outputs, batch):\n    opt = self.opt\n    hm_loss, wh_loss, off_loss = 0, 0, 0\n    hp_loss, off_loss, hm_hp_loss, hp_offset_loss = 0, 0, 0, 0\n    for s in range(opt.num_stacks):\n      output = outputs[s]\n      output['hm'] = _sigmoid(output['hm'])\n      if opt.hm_hp and not opt.mse_loss:\n        output['hm_hp'] = _sigmoid(output['hm_hp'])\n      \n      if opt.eval_oracle_hmhp:\n        output['hm_hp'] = batch['hm_hp']\n      if opt.eval_oracle_hm:\n        output['hm'] = batch['hm']\n      if opt.eval_oracle_kps:\n        if opt.dense_hp:\n          output['hps'] = batch['dense_hps']\n        else:\n          output['hps'] = torch.from_numpy(gen_oracle_map(\n            batch['hps'].detach().cpu().numpy(), \n            batch['ind'].detach().cpu().numpy(), \n            opt.output_res, opt.output_res)).to(opt.device)\n      if opt.eval_oracle_hp_offset:\n        output['hp_offset'] = torch.from_numpy(gen_oracle_map(\n          batch['hp_offset'].detach().cpu().numpy(), \n          batch['hp_ind'].detach().cpu().numpy(), \n          opt.output_res, opt.output_res)).to(opt.device)\n\n\n      hm_loss += self.crit(output['hm'], batch['hm']) / opt.num_stacks\n      if opt.dense_hp:\n        mask_weight = batch['dense_hps_mask'].sum() + 1e-4\n        hp_loss += (self.crit_kp(output['hps'] * batch['dense_hps_mask'], \n                                 batch['dense_hps'] * batch['dense_hps_mask']) / \n                                 mask_weight) / opt.num_stacks\n      else:\n        hp_loss += self.crit_kp(output['hps'], batch['hps_mask'], \n                                batch['ind'], batch['hps']) / opt.num_stacks\n      if opt.wh_weight > 0:\n        wh_loss += self.crit_reg(output['wh'], batch['reg_mask'],\n                                 batch['ind'], batch['wh']) / opt.num_stacks\n      if opt.reg_offset and opt.off_weight > 0:\n        off_loss += self.crit_reg(output['reg'], batch['reg_mask'],\n                                  batch['ind'], batch['reg']) / opt.num_stacks\n      if opt.reg_hp_offset and opt.off_weight > 0:\n        hp_offset_loss += self.crit_reg(\n          output['hp_offset'], batch['hp_mask'],\n          batch['hp_ind'], batch['hp_offset']) / opt.num_stacks\n      if opt.hm_hp and opt.hm_hp_weight > 0:\n        hm_hp_loss += self.crit_hm_hp(\n          output['hm_hp'], batch['hm_hp']) / opt.num_stacks\n    loss = opt.hm_weight * hm_loss + opt.wh_weight * wh_loss + \\\n           opt.off_weight * off_loss + opt.hp_weight * hp_loss + \\\n           opt.hm_hp_weight * hm_hp_loss + opt.off_weight * hp_offset_loss\n    \n    loss_stats = {'loss': loss, 'hm_loss': hm_loss, 'hp_loss': hp_loss, \n                  'hm_hp_loss': hm_hp_loss, 'hp_offset_loss': hp_offset_loss,\n                  'wh_loss': wh_loss, 'off_loss': off_loss}\n    return loss, loss_stats\n\nclass MultiPoseTrainer(BaseTrainer):\n  def __init__(self, opt, model, optimizer=None):\n    super(MultiPoseTrainer, self).__init__(opt, model, optimizer=optimizer)\n  \n  def _get_losses(self, opt):\n    loss_states = ['loss', 'hm_loss', 'hp_loss', 'hm_hp_loss', \n                   'hp_offset_loss', 'wh_loss', 'off_loss']\n    loss = MultiPoseLoss(opt)\n    return loss_states, loss\n\n  def debug(self, batch, output, iter_id):\n    opt = self.opt\n    reg = output['reg'] if opt.reg_offset else None\n    hm_hp = output['hm_hp'] if opt.hm_hp else None\n    hp_offset = output['hp_offset'] if opt.reg_hp_offset else None\n    dets = multi_pose_decode(\n      output['hm'], output['wh'], output['hps'], \n      reg=reg, hm_hp=hm_hp, hp_offset=hp_offset, K=opt.K)\n    dets = dets.detach().cpu().numpy().reshape(1, -1, dets.shape[2])\n\n    dets[:, :, :4] *= opt.input_res / opt.output_res\n    dets[:, :, 5:39] *= opt.input_res / opt.output_res\n    dets_gt = batch['meta']['gt_det'].numpy().reshape(1, -1, dets.shape[2])\n    dets_gt[:, :, :4] *= opt.input_res / opt.output_res\n    dets_gt[:, :, 5:39] *= opt.input_res / opt.output_res\n    for i in range(1):\n      debugger = Debugger(\n        dataset=opt.dataset, ipynb=(opt.debug==3), theme=opt.debugger_theme)\n      img = batch['input'][i].detach().cpu().numpy().transpose(1, 2, 0)\n      img = np.clip(((\n        img * opt.std + opt.mean) * 255.), 0, 255).astype(np.uint8)\n      pred = debugger.gen_colormap(output['hm'][i].detach().cpu().numpy())\n      gt = debugger.gen_colormap(batch['hm'][i].detach().cpu().numpy())\n      debugger.add_blend_img(img, pred, 'pred_hm')\n      debugger.add_blend_img(img, gt, 'gt_hm')\n\n      debugger.add_img(img, img_id='out_pred')\n      for k in range(len(dets[i])):\n        if dets[i, k, 4] > opt.center_thresh:\n          debugger.add_coco_bbox(dets[i, k, :4], dets[i, k, -1],\n                                 dets[i, k, 4], img_id='out_pred')\n          debugger.add_coco_hp(dets[i, k, 5:39], img_id='out_pred')\n\n      debugger.add_img(img, img_id='out_gt')\n      for k in range(len(dets_gt[i])):\n        if dets_gt[i, k, 4] > opt.center_thresh:\n          debugger.add_coco_bbox(dets_gt[i, k, :4], dets_gt[i, k, -1],\n                                 dets_gt[i, k, 4], img_id='out_gt')\n          debugger.add_coco_hp(dets_gt[i, k, 5:39], img_id='out_gt')\n\n      if opt.hm_hp:\n        pred = debugger.gen_colormap_hp(output['hm_hp'][i].detach().cpu().numpy())\n        gt = debugger.gen_colormap_hp(batch['hm_hp'][i].detach().cpu().numpy())\n        debugger.add_blend_img(img, pred, 'pred_hmhp')\n        debugger.add_blend_img(img, gt, 'gt_hmhp')\n\n      if opt.debug == 4:\n        debugger.save_all_imgs(opt.debug_dir, prefix='{}'.format(iter_id))\n      else:\n        debugger.show_all_imgs(pause=True)\n\n  def save_result(self, output, batch, results):\n    reg = output['reg'] if self.opt.reg_offset else None\n    hm_hp = output['hm_hp'] if self.opt.hm_hp else None\n    hp_offset = output['hp_offset'] if self.opt.reg_hp_offset else None\n    dets = multi_pose_decode(\n      output['hm'], output['wh'], output['hps'], \n      reg=reg, hm_hp=hm_hp, hp_offset=hp_offset, K=self.opt.K)\n    dets = dets.detach().cpu().numpy().reshape(1, -1, dets.shape[2])\n    \n    dets_out = multi_pose_post_process(\n      dets.copy(), batch['meta']['c'].cpu().numpy(),\n      batch['meta']['s'].cpu().numpy(),\n      output['hm'].shape[2], output['hm'].shape[3])\n    results[batch['meta']['img_id'].cpu().numpy()[0]] = dets_out[0]"
  },
  {
    "path": "src/lib/trains/train_factory.py",
    "content": "from __future__ import absolute_import\nfrom __future__ import division\nfrom __future__ import print_function\n\nfrom .ctdet import CtdetTrainer\nfrom .ddd import DddTrainer\nfrom .exdet import ExdetTrainer\nfrom .multi_pose import MultiPoseTrainer\n\ntrain_factory = {\n  'exdet': ExdetTrainer, \n  'ddd': DddTrainer,\n  'ctdet': CtdetTrainer,\n  'multi_pose': MultiPoseTrainer, \n}\n"
  },
  {
    "path": "src/lib/utils/__init__.py",
    "content": ""
  },
  {
    "path": "src/lib/utils/ddd_utils.py",
    "content": "from __future__ import absolute_import\nfrom __future__ import division\nfrom __future__ import print_function\n\nimport numpy as np\nimport cv2\n\ndef compute_box_3d(dim, location, rotation_y):\n  # dim: 3\n  # location: 3\n  # rotation_y: 1\n  # return: 8 x 3\n  c, s = np.cos(rotation_y), np.sin(rotation_y)\n  R = np.array([[c, 0, s], [0, 1, 0], [-s, 0, c]], dtype=np.float32)\n  l, w, h = dim[2], dim[1], dim[0]\n  x_corners = [l/2, l/2, -l/2, -l/2, l/2, l/2, -l/2, -l/2]\n  y_corners = [0,0,0,0,-h,-h,-h,-h]\n  z_corners = [w/2, -w/2, -w/2, w/2, w/2, -w/2, -w/2, w/2]\n\n  corners = np.array([x_corners, y_corners, z_corners], dtype=np.float32)\n  corners_3d = np.dot(R, corners) \n  corners_3d = corners_3d + np.array(location, dtype=np.float32).reshape(3, 1)\n  return corners_3d.transpose(1, 0)\n\ndef project_to_image(pts_3d, P):\n  # pts_3d: n x 3\n  # P: 3 x 4\n  # return: n x 2\n  pts_3d_homo = np.concatenate(\n    [pts_3d, np.ones((pts_3d.shape[0], 1), dtype=np.float32)], axis=1)\n  pts_2d = np.dot(P, pts_3d_homo.transpose(1, 0)).transpose(1, 0)\n  pts_2d = pts_2d[:, :2] / pts_2d[:, 2:]\n  # import pdb; pdb.set_trace()\n  return pts_2d\n\ndef compute_orientation_3d(dim, location, rotation_y):\n  # dim: 3\n  # location: 3\n  # rotation_y: 1\n  # return: 2 x 3\n  c, s = np.cos(rotation_y), np.sin(rotation_y)\n  R = np.array([[c, 0, s], [0, 1, 0], [-s, 0, c]], dtype=np.float32)\n  orientation_3d = np.array([[0, dim[2]], [0, 0], [0, 0]], dtype=np.float32)\n  orientation_3d = np.dot(R, orientation_3d)\n  orientation_3d = orientation_3d + \\\n                   np.array(location, dtype=np.float32).reshape(3, 1)\n  return orientation_3d.transpose(1, 0)\n\ndef draw_box_3d(image, corners, c=(0, 0, 255)):\n  face_idx = [[0,1,5,4],\n              [1,2,6, 5],\n              [2,3,7,6],\n              [3,0,4,7]]\n  for ind_f in range(3, -1, -1):\n    f = face_idx[ind_f]\n    for j in range(4):\n      cv2.line(image, (corners[f[j], 0], corners[f[j], 1]),\n               (corners[f[(j+1)%4], 0], corners[f[(j+1)%4], 1]), c, 2, lineType=cv2.LINE_AA)\n    if ind_f == 0:\n      cv2.line(image, (corners[f[0], 0], corners[f[0], 1]),\n               (corners[f[2], 0], corners[f[2], 1]), c, 1, lineType=cv2.LINE_AA)\n      cv2.line(image, (corners[f[1], 0], corners[f[1], 1]),\n               (corners[f[3], 0], corners[f[3], 1]), c, 1, lineType=cv2.LINE_AA)\n  return image\n\ndef unproject_2d_to_3d(pt_2d, depth, P):\n  # pts_2d: 2\n  # depth: 1\n  # P: 3 x 4\n  # return: 3\n  z = depth - P[2, 3]\n  x = (pt_2d[0] * depth - P[0, 3] - P[0, 2] * z) / P[0, 0]\n  y = (pt_2d[1] * depth - P[1, 3] - P[1, 2] * z) / P[1, 1]\n  pt_3d = np.array([x, y, z], dtype=np.float32)\n  return pt_3d\n\ndef alpha2rot_y(alpha, x, cx, fx):\n    \"\"\"\n    Get rotation_y by alpha + theta - 180\n    alpha : Observation angle of object, ranging [-pi..pi]\n    x : Object center x to the camera center (x-W/2), in pixels\n    rotation_y : Rotation ry around Y-axis in camera coordinates [-pi..pi]\n    \"\"\"\n    rot_y = alpha + np.arctan2(x - cx, fx)\n    if rot_y > np.pi:\n      rot_y -= 2 * np.pi\n    if rot_y < -np.pi:\n      rot_y += 2 * np.pi\n    return rot_y\n\ndef rot_y2alpha(rot_y, x, cx, fx):\n    \"\"\"\n    Get rotation_y by alpha + theta - 180\n    alpha : Observation angle of object, ranging [-pi..pi]\n    x : Object center x to the camera center (x-W/2), in pixels\n    rotation_y : Rotation ry around Y-axis in camera coordinates [-pi..pi]\n    \"\"\"\n    alpha = rot_y - np.arctan2(x - cx, fx)\n    if alpha > np.pi:\n      alpha -= 2 * np.pi\n    if alpha < -np.pi:\n      alpha += 2 * np.pi\n    return alpha\n\n\ndef ddd2locrot(center, alpha, dim, depth, calib):\n  # single image\n  locations = unproject_2d_to_3d(center, depth, calib)\n  locations[1] += dim[0] / 2\n  rotation_y = alpha2rot_y(alpha, center[0], calib[0, 2], calib[0, 0])\n  return locations, rotation_y\n\ndef project_3d_bbox(location, dim, rotation_y, calib):\n  box_3d = compute_box_3d(dim, location, rotation_y)\n  box_2d = project_to_image(box_3d, calib)\n  return box_2d\n\n\nif __name__ == '__main__':\n  calib = np.array(\n    [[7.070493000000e+02, 0.000000000000e+00, 6.040814000000e+02, 4.575831000000e+01],\n     [0.000000000000e+00, 7.070493000000e+02, 1.805066000000e+02, -3.454157000000e-01],\n     [0.000000000000e+00, 0.000000000000e+00, 1.000000000000e+00, 4.981016000000e-03]],\n    dtype=np.float32)\n  alpha = -0.20\n  tl = np.array([712.40, 143.00], dtype=np.float32)\n  br = np.array([810.73, 307.92], dtype=np.float32)\n  ct = (tl + br) / 2\n  rotation_y = 0.01\n  print('alpha2rot_y', alpha2rot_y(alpha, ct[0], calib[0, 2], calib[0, 0]))\n  print('rotation_y', rotation_y)"
  },
  {
    "path": "src/lib/utils/debugger.py",
    "content": "from __future__ import absolute_import\nfrom __future__ import division\nfrom __future__ import print_function\n\nimport numpy as np\nimport cv2\nfrom .ddd_utils import compute_box_3d, project_to_image, draw_box_3d\n\nclass Debugger(object):\n  def __init__(self, ipynb=False, theme='black', \n               num_classes=-1, dataset=None, down_ratio=4):\n    self.ipynb = ipynb\n    if not self.ipynb:\n      import matplotlib.pyplot as plt\n      self.plt = plt\n    self.imgs = {}\n    self.theme = theme\n    colors = [(color_list[_]).astype(np.uint8) \\\n            for _ in range(len(color_list))]\n    self.colors = np.array(colors, dtype=np.uint8).reshape(len(colors), 1, 1, 3)\n    if self.theme == 'white':\n      self.colors = self.colors.reshape(-1)[::-1].reshape(len(colors), 1, 1, 3)\n      self.colors = np.clip(self.colors, 0., 0.6 * 255).astype(np.uint8)\n    self.dim_scale = 1\n    if dataset == 'coco_hp':\n      self.names = ['p']\n      self.num_class = 1\n      self.num_joints = 17\n      self.edges = [[0, 1], [0, 2], [1, 3], [2, 4], \n                    [3, 5], [4, 6], [5, 6], \n                    [5, 7], [7, 9], [6, 8], [8, 10], \n                    [5, 11], [6, 12], [11, 12], \n                    [11, 13], [13, 15], [12, 14], [14, 16]]\n      self.ec = [(255, 0, 0), (0, 0, 255), (255, 0, 0), (0, 0, 255), \n                 (255, 0, 0), (0, 0, 255), (255, 0, 255),\n                 (255, 0, 0), (255, 0, 0), (0, 0, 255), (0, 0, 255),\n                 (255, 0, 0), (0, 0, 255), (255, 0, 255),\n                 (255, 0, 0), (255, 0, 0), (0, 0, 255), (0, 0, 255)]\n      self.colors_hp = [(255, 0, 255), (255, 0, 0), (0, 0, 255), \n        (255, 0, 0), (0, 0, 255), (255, 0, 0), (0, 0, 255),\n        (255, 0, 0), (0, 0, 255), (255, 0, 0), (0, 0, 255),\n        (255, 0, 0), (0, 0, 255), (255, 0, 0), (0, 0, 255),\n        (255, 0, 0), (0, 0, 255)]\n    elif num_classes == 80 or dataset == 'coco':\n      self.names = coco_class_name\n    elif num_classes == 20 or dataset == 'pascal':\n      self.names = pascal_class_name\n    elif dataset == 'gta':\n      self.names = gta_class_name\n      self.focal_length = 935.3074360871937\n      self.W = 1920\n      self.H = 1080\n      self.dim_scale = 3\n    elif dataset == 'viper':\n      self.names = gta_class_name\n      self.focal_length = 1158\n      self.W = 1920\n      self.H = 1080\n      self.dim_scale = 3\n    elif num_classes == 3 or dataset == 'kitti':\n      self.names = kitti_class_name\n      self.focal_length = 721.5377\n      self.W = 1242\n      self.H = 375\n    num_classes = len(self.names)\n    self.down_ratio=down_ratio\n    # for bird view\n    self.world_size = 64\n    self.out_size = 384\n\n  def add_img(self, img, img_id='default', revert_color=False):\n    if revert_color:\n      img = 255 - img\n    self.imgs[img_id] = img.copy()\n  \n  def add_mask(self, mask, bg, imgId = 'default', trans = 0.8):\n    self.imgs[imgId] = (mask.reshape(\n      mask.shape[0], mask.shape[1], 1) * 255 * trans + \\\n      bg * (1 - trans)).astype(np.uint8)\n  \n  def show_img(self, pause = False, imgId = 'default'):\n    cv2.imshow('{}'.format(imgId), self.imgs[imgId])\n    if pause:\n      cv2.waitKey()\n  \n  def add_blend_img(self, back, fore, img_id='blend', trans=0.7):\n    if self.theme == 'white':\n      fore = 255 - fore\n    if fore.shape[0] != back.shape[0] or fore.shape[0] != back.shape[1]:\n      fore = cv2.resize(fore, (back.shape[1], back.shape[0]))\n    if len(fore.shape) == 2:\n      fore = fore.reshape(fore.shape[0], fore.shape[1], 1)\n    self.imgs[img_id] = (back * (1. - trans) + fore * trans)\n    self.imgs[img_id][self.imgs[img_id] > 255] = 255\n    self.imgs[img_id][self.imgs[img_id] < 0] = 0\n    self.imgs[img_id] = self.imgs[img_id].astype(np.uint8).copy()\n\n  '''\n  # slow version\n  def gen_colormap(self, img, output_res=None):\n    # num_classes = len(self.colors)\n    img[img < 0] = 0\n    h, w = img.shape[1], img.shape[2]\n    if output_res is None:\n      output_res = (h * self.down_ratio, w * self.down_ratio)\n    color_map = np.zeros((output_res[0], output_res[1], 3), dtype=np.uint8)\n    for i in range(img.shape[0]):\n      resized = cv2.resize(img[i], (output_res[1], output_res[0]))\n      resized = resized.reshape(output_res[0], output_res[1], 1)\n      cl = self.colors[i] if not (self.theme == 'white') \\\n           else 255 - self.colors[i]\n      color_map = np.maximum(color_map, (resized * cl).astype(np.uint8))\n    return color_map\n    '''\n\n  \n  def gen_colormap(self, img, output_res=None):\n    img = img.copy()\n    c, h, w = img.shape[0], img.shape[1], img.shape[2]\n    if output_res is None:\n      output_res = (h * self.down_ratio, w * self.down_ratio)\n    img = img.transpose(1, 2, 0).reshape(h, w, c, 1).astype(np.float32)\n    colors = np.array(\n      self.colors, dtype=np.float32).reshape(-1, 3)[:c].reshape(1, 1, c, 3)\n    if self.theme == 'white':\n      colors = 255 - colors\n    color_map = (img * colors).max(axis=2).astype(np.uint8)\n    color_map = cv2.resize(color_map, (output_res[0], output_res[1]))\n    return color_map\n    \n  '''\n  # slow\n  def gen_colormap_hp(self, img, output_res=None):\n    # num_classes = len(self.colors)\n    # img[img < 0] = 0\n    h, w = img.shape[1], img.shape[2]\n    if output_res is None:\n      output_res = (h * self.down_ratio, w * self.down_ratio)\n    color_map = np.zeros((output_res[0], output_res[1], 3), dtype=np.uint8)\n    for i in range(img.shape[0]):\n      resized = cv2.resize(img[i], (output_res[1], output_res[0]))\n      resized = resized.reshape(output_res[0], output_res[1], 1)\n      cl =  self.colors_hp[i] if not (self.theme == 'white') else \\\n        (255 - np.array(self.colors_hp[i]))\n      color_map = np.maximum(color_map, (resized * cl).astype(np.uint8))\n    return color_map\n  '''\n  def gen_colormap_hp(self, img, output_res=None):\n    c, h, w = img.shape[0], img.shape[1], img.shape[2]\n    if output_res is None:\n      output_res = (h * self.down_ratio, w * self.down_ratio)\n    img = img.transpose(1, 2, 0).reshape(h, w, c, 1).astype(np.float32)\n    colors = np.array(\n      self.colors_hp, dtype=np.float32).reshape(-1, 3)[:c].reshape(1, 1, c, 3)\n    if self.theme == 'white':\n      colors = 255 - colors\n    color_map = (img * colors).max(axis=2).astype(np.uint8)\n    color_map = cv2.resize(color_map, (output_res[0], output_res[1]))\n    return color_map\n\n\n  def add_rect(self, rect1, rect2, c, conf=1, img_id='default'): \n    cv2.rectangle(\n      self.imgs[img_id], (rect1[0], rect1[1]), (rect2[0], rect2[1]), c, 2)\n    if conf < 1:\n      cv2.circle(self.imgs[img_id], (rect1[0], rect1[1]), int(10 * conf), c, 1)\n      cv2.circle(self.imgs[img_id], (rect2[0], rect2[1]), int(10 * conf), c, 1)\n      cv2.circle(self.imgs[img_id], (rect1[0], rect2[1]), int(10 * conf), c, 1)\n      cv2.circle(self.imgs[img_id], (rect2[0], rect1[1]), int(10 * conf), c, 1)\n\n  def add_coco_bbox(self, bbox, cat, conf=1, show_txt=True, img_id='default'): \n    bbox = np.array(bbox, dtype=np.int32)\n    # cat = (int(cat) + 1) % 80\n    cat = int(cat)\n    # print('cat', cat, self.names[cat])\n    c = self.colors[cat][0][0].tolist()\n    if self.theme == 'white':\n      c = (255 - np.array(c)).tolist()\n    txt = '{}{:.1f}'.format(self.names[cat], conf)\n    font = cv2.FONT_HERSHEY_SIMPLEX\n    cat_size = cv2.getTextSize(txt, font, 0.5, 2)[0]\n    cv2.rectangle(\n      self.imgs[img_id], (bbox[0], bbox[1]), (bbox[2], bbox[3]), c, 2)\n    if show_txt:\n      cv2.rectangle(self.imgs[img_id],\n                    (bbox[0], bbox[1] - cat_size[1] - 2),\n                    (bbox[0] + cat_size[0], bbox[1] - 2), c, -1)\n      cv2.putText(self.imgs[img_id], txt, (bbox[0], bbox[1] - 2), \n                  font, 0.5, (0, 0, 0), thickness=1, lineType=cv2.LINE_AA)\n\n  def add_coco_hp(self, points, img_id='default'): \n    points = np.array(points, dtype=np.int32).reshape(self.num_joints, 2)\n    for j in range(self.num_joints):\n      cv2.circle(self.imgs[img_id],\n                 (points[j, 0], points[j, 1]), 3, self.colors_hp[j], -1)\n    for j, e in enumerate(self.edges):\n      if points[e].min() > 0:\n        cv2.line(self.imgs[img_id], (points[e[0], 0], points[e[0], 1]),\n                      (points[e[1], 0], points[e[1], 1]), self.ec[j], 2,\n                      lineType=cv2.LINE_AA)\n\n  def add_points(self, points, img_id='default'):\n    num_classes = len(points)\n    # assert num_classes == len(self.colors)\n    for i in range(num_classes):\n      for j in range(len(points[i])):\n        c = self.colors[i, 0, 0]\n        cv2.circle(self.imgs[img_id], (points[i][j][0] * self.down_ratio, \n                                       points[i][j][1] * self.down_ratio),\n                   5, (255, 255, 255), -1)\n        cv2.circle(self.imgs[img_id], (points[i][j][0] * self.down_ratio,\n                                       points[i][j][1] * self.down_ratio),\n                   3, (int(c[0]), int(c[1]), int(c[2])), -1)\n\n  def show_all_imgs(self, pause=False, time=0):\n    if not self.ipynb:\n      for i, v in self.imgs.items():\n        cv2.imshow('{}'.format(i), v)\n      if cv2.waitKey(0 if pause else 1) == 27:\n        import sys\n        sys.exit(0)\n    else:\n      self.ax = None\n      nImgs = len(self.imgs)\n      fig=self.plt.figure(figsize=(nImgs * 10,10))\n      nCols = nImgs\n      nRows = nImgs // nCols\n      for i, (k, v) in enumerate(self.imgs.items()):\n        fig.add_subplot(1, nImgs, i + 1)\n        if len(v.shape) == 3:\n          self.plt.imshow(cv2.cvtColor(v, cv2.COLOR_BGR2RGB))\n        else:\n          self.plt.imshow(v)\n      self.plt.show()\n\n  def save_img(self, imgId='default', path='./cache/debug/'):\n    cv2.imwrite(path + '{}.png'.format(imgId), self.imgs[imgId])\n    \n  def save_all_imgs(self, path='./cache/debug/', prefix='', genID=False):\n    if genID:\n      try:\n        idx = int(np.loadtxt(path + '/id.txt'))\n      except:\n        idx = 0\n      prefix=idx\n      np.savetxt(path + '/id.txt', np.ones(1) * (idx + 1), fmt='%d')\n    for i, v in self.imgs.items():\n      cv2.imwrite(path + '/{}{}.png'.format(prefix, i), v)\n\n  def remove_side(self, img_id, img):\n    if not (img_id in self.imgs):\n      return\n    ws = img.sum(axis=2).sum(axis=0)\n    l = 0\n    while ws[l] == 0 and l < len(ws):\n      l+= 1\n    r = ws.shape[0] - 1\n    while ws[r] == 0 and r > 0:\n      r -= 1\n    hs = img.sum(axis=2).sum(axis=1)\n    t = 0\n    while hs[t] == 0 and t < len(hs):\n      t += 1\n    b = hs.shape[0] - 1\n    while hs[b] == 0 and b > 0:\n      b -= 1\n    self.imgs[img_id] = self.imgs[img_id][t:b+1, l:r+1].copy()\n\n  def project_3d_to_bird(self, pt):\n    pt[0] += self.world_size / 2\n    pt[1] = self.world_size - pt[1]\n    pt = pt * self.out_size / self.world_size\n    return pt.astype(np.int32)\n\n  def add_ct_detection(\n    self, img, dets, show_box=False, show_txt=True, \n    center_thresh=0.5, img_id='det'):\n    # dets: max_preds x 5\n    self.imgs[img_id] = img.copy()\n    if type(dets) == type({}):\n      for cat in dets:\n        for i in range(len(dets[cat])):\n          if dets[cat][i, 2] > center_thresh:\n            cl = (self.colors[cat, 0, 0]).tolist()\n            ct = dets[cat][i, :2].astype(np.int32)\n            if show_box:\n              w, h = dets[cat][i, -2], dets[cat][i, -1]\n              x, y = dets[cat][i, 0], dets[cat][i, 1]\n              bbox = np.array([x - w / 2, y - h / 2, x + w / 2, y + h / 2],\n                              dtype=np.float32)\n              self.add_coco_bbox(\n                bbox, cat - 1, dets[cat][i, 2], \n                show_txt=show_txt, img_id=img_id)\n    else:\n      for i in range(len(dets)):\n        if dets[i, 2] > center_thresh:\n          # print('dets', dets[i])\n          cat = int(dets[i, -1])\n          cl = (self.colors[cat, 0, 0] if self.theme == 'black' else \\\n                                       255 - self.colors[cat, 0, 0]).tolist()\n          ct = dets[i, :2].astype(np.int32) * self.down_ratio\n          cv2.circle(self.imgs[img_id], (ct[0], ct[1]), 3, cl, -1)\n          if show_box:\n            w, h = dets[i, -3] * self.down_ratio, dets[i, -2] * self.down_ratio\n            x, y = dets[i, 0] * self.down_ratio, dets[i, 1] * self.down_ratio\n            bbox = np.array([x - w / 2, y - h / 2, x + w / 2, y + h / 2],\n                            dtype=np.float32)\n            self.add_coco_bbox(bbox, dets[i, -1], dets[i, 2], img_id=img_id)\n\n\n  def add_3d_detection(\n    self, image_or_path, dets, calib, show_txt=False, \n    center_thresh=0.5, img_id='det'):\n    if isinstance(image_or_path, np.ndarray):\n      self.imgs[img_id] = image_or_path\n    else: \n      self.imgs[img_id] = cv2.imread(image_or_path)\n    for cat in dets:\n      for i in range(len(dets[cat])):\n        cl = (self.colors[cat - 1, 0, 0]).tolist()\n        if dets[cat][i, -1] > center_thresh:\n          dim = dets[cat][i, 5:8]\n          loc  = dets[cat][i, 8:11]\n          rot_y = dets[cat][i, 11]\n          # loc[1] = loc[1] - dim[0] / 2 + dim[0] / 2 / self.dim_scale\n          # dim = dim / self.dim_scale\n          if loc[2] > 1:\n            box_3d = compute_box_3d(dim, loc, rot_y)\n            box_2d = project_to_image(box_3d, calib)\n            self.imgs[img_id] = draw_box_3d(self.imgs[img_id], box_2d, cl)\n\n  def compose_vis_add(\n    self, img_path, dets, calib,\n    center_thresh, pred, bev, img_id='out'):\n    self.imgs[img_id] = cv2.imread(img_path)\n    # h, w = self.imgs[img_id].shape[:2]\n    # pred = cv2.resize(pred, (h, w))\n    h, w = pred.shape[:2]\n    hs, ws = self.imgs[img_id].shape[0] / h, self.imgs[img_id].shape[1] / w\n    self.imgs[img_id] = cv2.resize(self.imgs[img_id], (w, h))\n    self.add_blend_img(self.imgs[img_id], pred, img_id)\n    for cat in dets:\n      for i in range(len(dets[cat])):\n        cl = (self.colors[cat - 1, 0, 0]).tolist()\n        if dets[cat][i, -1] > center_thresh:\n          dim = dets[cat][i, 5:8]\n          loc  = dets[cat][i, 8:11]\n          rot_y = dets[cat][i, 11]\n          # loc[1] = loc[1] - dim[0] / 2 + dim[0] / 2 / self.dim_scale\n          # dim = dim / self.dim_scale\n          if loc[2] > 1:\n            box_3d = compute_box_3d(dim, loc, rot_y)\n            box_2d = project_to_image(box_3d, calib)\n            box_2d[:, 0] /= hs\n            box_2d[:, 1] /= ws\n            self.imgs[img_id] = draw_box_3d(self.imgs[img_id], box_2d, cl)\n    self.imgs[img_id] = np.concatenate(\n      [self.imgs[img_id], self.imgs[bev]], axis=1)\n\n  def add_2d_detection(\n    self, img, dets, show_box=False, show_txt=True, \n    center_thresh=0.5, img_id='det'):\n    self.imgs[img_id] = img\n    for cat in dets:\n      for i in range(len(dets[cat])):\n        cl = (self.colors[cat - 1, 0, 0]).tolist()\n        if dets[cat][i, -1] > center_thresh:\n          bbox = dets[cat][i, 1:5]\n          self.add_coco_bbox(\n            bbox, cat - 1, dets[cat][i, -1], \n            show_txt=show_txt, img_id=img_id)\n\n  def add_bird_view(self, dets, center_thresh=0.3, img_id='bird'):\n    bird_view = np.ones((self.out_size, self.out_size, 3), dtype=np.uint8) * 230\n    for cat in dets:\n      cl = (self.colors[cat - 1, 0, 0]).tolist()\n      lc = (250, 152, 12)\n      for i in range(len(dets[cat])):\n        if dets[cat][i, -1] > center_thresh:\n          dim = dets[cat][i, 5:8]\n          loc  = dets[cat][i, 8:11]\n          rot_y = dets[cat][i, 11]\n          rect = compute_box_3d(dim, loc, rot_y)[:4, [0, 2]]\n          for k in range(4):\n            rect[k] = self.project_3d_to_bird(rect[k])\n            # cv2.circle(bird_view, (rect[k][0], rect[k][1]), 2, lc, -1)\n          cv2.polylines(\n              bird_view,[rect.reshape(-1, 1, 2).astype(np.int32)],\n              True,lc,2,lineType=cv2.LINE_AA)\n          for e in [[0, 1]]:\n            t = 4 if e == [0, 1] else 1\n            cv2.line(bird_view, (rect[e[0]][0], rect[e[0]][1]),\n                    (rect[e[1]][0], rect[e[1]][1]), lc, t,\n                    lineType=cv2.LINE_AA)\n    self.imgs[img_id] = bird_view\n\n  def add_bird_views(self, dets_dt, dets_gt, center_thresh=0.3, img_id='bird'):\n    alpha = 0.5\n    bird_view = np.ones((self.out_size, self.out_size, 3), dtype=np.uint8) * 230\n    for ii, (dets, lc, cc) in enumerate(\n      [(dets_gt, (12, 49, 250), (0, 0, 255)), \n       (dets_dt, (250, 152, 12), (255, 0, 0))]):\n      # cc = np.array(lc, dtype=np.uint8).reshape(1, 1, 3)\n      for cat in dets:\n        cl = (self.colors[cat - 1, 0, 0]).tolist()\n        for i in range(len(dets[cat])):\n          if dets[cat][i, -1] > center_thresh:\n            dim = dets[cat][i, 5:8]\n            loc  = dets[cat][i, 8:11]\n            rot_y = dets[cat][i, 11]\n            rect = compute_box_3d(dim, loc, rot_y)[:4, [0, 2]]\n            for k in range(4):\n              rect[k] = self.project_3d_to_bird(rect[k])\n            if ii == 0:\n              cv2.fillPoly(\n                bird_view,[rect.reshape(-1, 1, 2).astype(np.int32)],\n                lc,lineType=cv2.LINE_AA)\n            else:\n              cv2.polylines(\n                bird_view,[rect.reshape(-1, 1, 2).astype(np.int32)],\n                True,lc,2,lineType=cv2.LINE_AA)\n            # for e in [[0, 1], [1, 2], [2, 3], [3, 0]]:\n            for e in [[0, 1]]:\n              t = 4 if e == [0, 1] else 1\n              cv2.line(bird_view, (rect[e[0]][0], rect[e[0]][1]),\n                      (rect[e[1]][0], rect[e[1]][1]), lc, t,\n                      lineType=cv2.LINE_AA)\n    self.imgs[img_id] = bird_view\n\n\nkitti_class_name = [\n  'p', 'v', 'b'\n]\n\ngta_class_name = [\n  'p', 'v'\n]\n\npascal_class_name = [\"aeroplane\", \"bicycle\", \"bird\", \"boat\", \"bottle\", \"bus\", \n  \"car\", \"cat\", \"chair\", \"cow\", \"diningtable\", \"dog\", \"horse\", \"motorbike\", \n  \"person\", \"pottedplant\", \"sheep\", \"sofa\", \"train\", \"tvmonitor\"]\n\ncoco_class_name = [\n     'person', 'bicycle', 'car', 'motorcycle', 'airplane',\n     'bus', 'train', 'truck', 'boat', 'traffic light', 'fire hydrant',\n     'stop sign', 'parking meter', 'bench', 'bird', 'cat', 'dog', 'horse',\n     'sheep', 'cow', 'elephant', 'bear', 'zebra', 'giraffe', 'backpack',\n     'umbrella', 'handbag', 'tie', 'suitcase', 'frisbee', 'skis',\n     'snowboard', 'sports ball', 'kite', 'baseball bat', 'baseball glove',\n     'skateboard', 'surfboard', 'tennis racket', 'bottle', 'wine glass',\n     'cup', 'fork', 'knife', 'spoon', 'bowl', 'banana', 'apple', 'sandwich',\n     'orange', 'broccoli', 'carrot', 'hot dog', 'pizza', 'donut', 'cake',\n     'chair', 'couch', 'potted plant', 'bed', 'dining table', 'toilet', 'tv',\n     'laptop', 'mouse', 'remote', 'keyboard', 'cell phone', 'microwave',\n     'oven', 'toaster', 'sink', 'refrigerator', 'book', 'clock', 'vase',\n     'scissors', 'teddy bear', 'hair drier', 'toothbrush'\n]\n\ncolor_list = np.array(\n        [\n            1.000, 1.000, 1.000,\n            0.850, 0.325, 0.098,\n            0.929, 0.694, 0.125,\n            0.494, 0.184, 0.556,\n            0.466, 0.674, 0.188,\n            0.301, 0.745, 0.933,\n            0.635, 0.078, 0.184,\n            0.300, 0.300, 0.300,\n            0.600, 0.600, 0.600,\n            1.000, 0.000, 0.000,\n            1.000, 0.500, 0.000,\n            0.749, 0.749, 0.000,\n            0.000, 1.000, 0.000,\n            0.000, 0.000, 1.000,\n            0.667, 0.000, 1.000,\n            0.333, 0.333, 0.000,\n            0.333, 0.667, 0.000,\n            0.333, 1.000, 0.000,\n            0.667, 0.333, 0.000,\n            0.667, 0.667, 0.000,\n            0.667, 1.000, 0.000,\n            1.000, 0.333, 0.000,\n            1.000, 0.667, 0.000,\n            1.000, 1.000, 0.000,\n            0.000, 0.333, 0.500,\n            0.000, 0.667, 0.500,\n            0.000, 1.000, 0.500,\n            0.333, 0.000, 0.500,\n            0.333, 0.333, 0.500,\n            0.333, 0.667, 0.500,\n            0.333, 1.000, 0.500,\n            0.667, 0.000, 0.500,\n            0.667, 0.333, 0.500,\n            0.667, 0.667, 0.500,\n            0.667, 1.000, 0.500,\n            1.000, 0.000, 0.500,\n            1.000, 0.333, 0.500,\n            1.000, 0.667, 0.500,\n            1.000, 1.000, 0.500,\n            0.000, 0.333, 1.000,\n            0.000, 0.667, 1.000,\n            0.000, 1.000, 1.000,\n            0.333, 0.000, 1.000,\n            0.333, 0.333, 1.000,\n            0.333, 0.667, 1.000,\n            0.333, 1.000, 1.000,\n            0.667, 0.000, 1.000,\n            0.667, 0.333, 1.000,\n            0.667, 0.667, 1.000,\n            0.667, 1.000, 1.000,\n            1.000, 0.000, 1.000,\n            1.000, 0.333, 1.000,\n            1.000, 0.667, 1.000,\n            0.167, 0.000, 0.000,\n            0.333, 0.000, 0.000,\n            0.500, 0.000, 0.000,\n            0.667, 0.000, 0.000,\n            0.833, 0.000, 0.000,\n            1.000, 0.000, 0.000,\n            0.000, 0.167, 0.000,\n            0.000, 0.333, 0.000,\n            0.000, 0.500, 0.000,\n            0.000, 0.667, 0.000,\n            0.000, 0.833, 0.000,\n            0.000, 1.000, 0.000,\n            0.000, 0.000, 0.167,\n            0.000, 0.000, 0.333,\n            0.000, 0.000, 0.500,\n            0.000, 0.000, 0.667,\n            0.000, 0.000, 0.833,\n            0.000, 0.000, 1.000,\n            0.000, 0.000, 0.000,\n            0.143, 0.143, 0.143,\n            0.286, 0.286, 0.286,\n            0.429, 0.429, 0.429,\n            0.571, 0.571, 0.571,\n            0.714, 0.714, 0.714,\n            0.857, 0.857, 0.857,\n            0.000, 0.447, 0.741,\n            0.50, 0.5, 0\n        ]\n    ).astype(np.float32)\ncolor_list = color_list.reshape((-1, 3)) * 255\n"
  },
  {
    "path": "src/lib/utils/image.py",
    "content": "# ------------------------------------------------------------------------------\n# Copyright (c) Microsoft\n# Licensed under the MIT License.\n# Written by Bin Xiao (Bin.Xiao@microsoft.com)\n# Modified by Xingyi Zhou\n# ------------------------------------------------------------------------------\n\nfrom __future__ import absolute_import\nfrom __future__ import division\nfrom __future__ import print_function\n\nimport numpy as np\nimport cv2\nimport random\n\ndef flip(img):\n  return img[:, :, ::-1].copy()  \n\ndef transform_preds(coords, center, scale, output_size):\n    target_coords = np.zeros(coords.shape)\n    trans = get_affine_transform(center, scale, 0, output_size, inv=1)\n    for p in range(coords.shape[0]):\n        target_coords[p, 0:2] = affine_transform(coords[p, 0:2], trans)\n    return target_coords\n\n\ndef get_affine_transform(center,\n                         scale,\n                         rot,\n                         output_size,\n                         shift=np.array([0, 0], dtype=np.float32),\n                         inv=0):\n    if not isinstance(scale, np.ndarray) and not isinstance(scale, list):\n        scale = np.array([scale, scale], dtype=np.float32)\n\n    scale_tmp = scale\n    src_w = scale_tmp[0]\n    dst_w = output_size[0]\n    dst_h = output_size[1]\n\n    rot_rad = np.pi * rot / 180\n    src_dir = get_dir([0, src_w * -0.5], rot_rad)\n    dst_dir = np.array([0, dst_w * -0.5], np.float32)\n\n    src = np.zeros((3, 2), dtype=np.float32)\n    dst = np.zeros((3, 2), dtype=np.float32)\n    src[0, :] = center + scale_tmp * shift\n    src[1, :] = center + src_dir + scale_tmp * shift\n    dst[0, :] = [dst_w * 0.5, dst_h * 0.5]\n    dst[1, :] = np.array([dst_w * 0.5, dst_h * 0.5], np.float32) + dst_dir\n\n    src[2:, :] = get_3rd_point(src[0, :], src[1, :])\n    dst[2:, :] = get_3rd_point(dst[0, :], dst[1, :])\n\n    if inv:\n        trans = cv2.getAffineTransform(np.float32(dst), np.float32(src))\n    else:\n        trans = cv2.getAffineTransform(np.float32(src), np.float32(dst))\n\n    return trans\n\n\ndef affine_transform(pt, t):\n    new_pt = np.array([pt[0], pt[1], 1.], dtype=np.float32).T\n    new_pt = np.dot(t, new_pt)\n    return new_pt[:2]\n\n\ndef get_3rd_point(a, b):\n    direct = a - b\n    return b + np.array([-direct[1], direct[0]], dtype=np.float32)\n\n\ndef get_dir(src_point, rot_rad):\n    sn, cs = np.sin(rot_rad), np.cos(rot_rad)\n\n    src_result = [0, 0]\n    src_result[0] = src_point[0] * cs - src_point[1] * sn\n    src_result[1] = src_point[0] * sn + src_point[1] * cs\n\n    return src_result\n\n\ndef crop(img, center, scale, output_size, rot=0):\n    trans = get_affine_transform(center, scale, rot, output_size)\n\n    dst_img = cv2.warpAffine(img,\n                             trans,\n                             (int(output_size[0]), int(output_size[1])),\n                             flags=cv2.INTER_LINEAR)\n\n    return dst_img\n\n\ndef gaussian_radius(det_size, min_overlap=0.7):\n  height, width = det_size\n\n  a1  = 1\n  b1  = (height + width)\n  c1  = width * height * (1 - min_overlap) / (1 + min_overlap)\n  sq1 = np.sqrt(b1 ** 2 - 4 * a1 * c1)\n  r1  = (b1 + sq1) / 2\n\n  a2  = 4\n  b2  = 2 * (height + width)\n  c2  = (1 - min_overlap) * width * height\n  sq2 = np.sqrt(b2 ** 2 - 4 * a2 * c2)\n  r2  = (b2 + sq2) / 2\n\n  a3  = 4 * min_overlap\n  b3  = -2 * min_overlap * (height + width)\n  c3  = (min_overlap - 1) * width * height\n  sq3 = np.sqrt(b3 ** 2 - 4 * a3 * c3)\n  r3  = (b3 + sq3) / 2\n  return min(r1, r2, r3)\n\n\ndef gaussian2D(shape, sigma=1):\n    m, n = [(ss - 1.) / 2. for ss in shape]\n    y, x = np.ogrid[-m:m+1,-n:n+1]\n\n    h = np.exp(-(x * x + y * y) / (2 * sigma * sigma))\n    h[h < np.finfo(h.dtype).eps * h.max()] = 0\n    return h\n\ndef draw_umich_gaussian(heatmap, center, radius, k=1):\n  diameter = 2 * radius + 1\n  gaussian = gaussian2D((diameter, diameter), sigma=diameter / 6)\n  \n  x, y = int(center[0]), int(center[1])\n\n  height, width = heatmap.shape[0:2]\n    \n  left, right = min(x, radius), min(width - x, radius + 1)\n  top, bottom = min(y, radius), min(height - y, radius + 1)\n\n  masked_heatmap  = heatmap[y - top:y + bottom, x - left:x + right]\n  masked_gaussian = gaussian[radius - top:radius + bottom, radius - left:radius + right]\n  if min(masked_gaussian.shape) > 0 and min(masked_heatmap.shape) > 0: # TODO debug\n    np.maximum(masked_heatmap, masked_gaussian * k, out=masked_heatmap)\n  return heatmap\n\ndef draw_dense_reg(regmap, heatmap, center, value, radius, is_offset=False):\n  diameter = 2 * radius + 1\n  gaussian = gaussian2D((diameter, diameter), sigma=diameter / 6)\n  value = np.array(value, dtype=np.float32).reshape(-1, 1, 1)\n  dim = value.shape[0]\n  reg = np.ones((dim, diameter*2+1, diameter*2+1), dtype=np.float32) * value\n  if is_offset and dim == 2:\n    delta = np.arange(diameter*2+1) - radius\n    reg[0] = reg[0] - delta.reshape(1, -1)\n    reg[1] = reg[1] - delta.reshape(-1, 1)\n  \n  x, y = int(center[0]), int(center[1])\n\n  height, width = heatmap.shape[0:2]\n    \n  left, right = min(x, radius), min(width - x, radius + 1)\n  top, bottom = min(y, radius), min(height - y, radius + 1)\n\n  masked_heatmap = heatmap[y - top:y + bottom, x - left:x + right]\n  masked_regmap = regmap[:, y - top:y + bottom, x - left:x + right]\n  masked_gaussian = gaussian[radius - top:radius + bottom,\n                             radius - left:radius + right]\n  masked_reg = reg[:, radius - top:radius + bottom,\n                      radius - left:radius + right]\n  if min(masked_gaussian.shape) > 0 and min(masked_heatmap.shape) > 0: # TODO debug\n    idx = (masked_gaussian >= masked_heatmap).reshape(\n      1, masked_gaussian.shape[0], masked_gaussian.shape[1])\n    masked_regmap = (1-idx) * masked_regmap + idx * masked_reg\n  regmap[:, y - top:y + bottom, x - left:x + right] = masked_regmap\n  return regmap\n\n\ndef draw_msra_gaussian(heatmap, center, sigma):\n  tmp_size = sigma * 3\n  mu_x = int(center[0] + 0.5)\n  mu_y = int(center[1] + 0.5)\n  w, h = heatmap.shape[0], heatmap.shape[1]\n  ul = [int(mu_x - tmp_size), int(mu_y - tmp_size)]\n  br = [int(mu_x + tmp_size + 1), int(mu_y + tmp_size + 1)]\n  if ul[0] >= h or ul[1] >= w or br[0] < 0 or br[1] < 0:\n    return heatmap\n  size = 2 * tmp_size + 1\n  x = np.arange(0, size, 1, np.float32)\n  y = x[:, np.newaxis]\n  x0 = y0 = size // 2\n  g = np.exp(- ((x - x0) ** 2 + (y - y0) ** 2) / (2 * sigma ** 2))\n  g_x = max(0, -ul[0]), min(br[0], h) - ul[0]\n  g_y = max(0, -ul[1]), min(br[1], w) - ul[1]\n  img_x = max(0, ul[0]), min(br[0], h)\n  img_y = max(0, ul[1]), min(br[1], w)\n  heatmap[img_y[0]:img_y[1], img_x[0]:img_x[1]] = np.maximum(\n    heatmap[img_y[0]:img_y[1], img_x[0]:img_x[1]],\n    g[g_y[0]:g_y[1], g_x[0]:g_x[1]])\n  return heatmap\n\ndef grayscale(image):\n    return cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)\n\ndef lighting_(data_rng, image, alphastd, eigval, eigvec):\n    alpha = data_rng.normal(scale=alphastd, size=(3, ))\n    image += np.dot(eigvec, eigval * alpha)\n\ndef blend_(alpha, image1, image2):\n    image1 *= alpha\n    image2 *= (1 - alpha)\n    image1 += image2\n\ndef saturation_(data_rng, image, gs, gs_mean, var):\n    alpha = 1. + data_rng.uniform(low=-var, high=var)\n    blend_(alpha, image, gs[:, :, None])\n\ndef brightness_(data_rng, image, gs, gs_mean, var):\n    alpha = 1. + data_rng.uniform(low=-var, high=var)\n    image *= alpha\n\ndef contrast_(data_rng, image, gs, gs_mean, var):\n    alpha = 1. + data_rng.uniform(low=-var, high=var)\n    blend_(alpha, image, gs_mean)\n\ndef color_aug(data_rng, image, eig_val, eig_vec):\n    functions = [brightness_, contrast_, saturation_]\n    random.shuffle(functions)\n\n    gs = grayscale(image)\n    gs_mean = gs.mean()\n    for f in functions:\n        f(data_rng, image, gs, gs_mean, 0.4)\n    lighting_(data_rng, image, 0.1, eig_val, eig_vec)\n"
  },
  {
    "path": "src/lib/utils/oracle_utils.py",
    "content": "from __future__ import absolute_import\nfrom __future__ import division\nfrom __future__ import print_function\n\nimport numpy as np\nimport numba\n\n@numba.jit(nopython=True, nogil=True)\ndef gen_oracle_map(feat, ind, w, h):\n  # feat: B x maxN x featDim\n  # ind: B x maxN\n  batch_size = feat.shape[0]\n  max_objs = feat.shape[1]\n  feat_dim = feat.shape[2]\n  out = np.zeros((batch_size, feat_dim, h, w), dtype=np.float32)\n  vis = np.zeros((batch_size, h, w), dtype=np.uint8)\n  ds = [(0, 1), (0, -1), (1, 0), (-1, 0)]\n  for i in range(batch_size):\n    queue_ind = np.zeros((h*w*2, 2), dtype=np.int32)\n    queue_feat = np.zeros((h*w*2, feat_dim), dtype=np.float32)\n    head, tail = 0, 0\n    for j in range(max_objs):\n      if ind[i][j] > 0:\n        x, y = ind[i][j] % w, ind[i][j] // w\n        out[i, :, y, x] = feat[i][j]\n        vis[i, y, x] = 1\n        queue_ind[tail] = x, y\n        queue_feat[tail] = feat[i][j]\n        tail += 1\n    while tail - head > 0:\n      x, y = queue_ind[head]\n      f = queue_feat[head]\n      head += 1\n      for (dx, dy) in ds:\n        xx, yy = x + dx, y + dy\n        if xx >= 0 and yy >= 0 and xx < w and yy < h and vis[i, yy, xx] < 1:\n          out[i, :, yy, xx] = f\n          vis[i, yy, xx] = 1\n          queue_ind[tail] = xx, yy\n          queue_feat[tail] = f\n          tail += 1\n  return out"
  },
  {
    "path": "src/lib/utils/post_process.py",
    "content": "from __future__ import absolute_import\nfrom __future__ import division\nfrom __future__ import print_function\n\nimport numpy as np\nfrom .image import transform_preds\nfrom .ddd_utils import ddd2locrot\n\n\ndef get_pred_depth(depth):\n  return depth\n\ndef get_alpha(rot):\n  # output: (B, 8) [bin1_cls[0], bin1_cls[1], bin1_sin, bin1_cos, \n  #                 bin2_cls[0], bin2_cls[1], bin2_sin, bin2_cos]\n  # return rot[:, 0]\n  idx = rot[:, 1] > rot[:, 5]\n  alpha1 = np.arctan2(rot[:, 2], rot[:, 3]) + (-0.5 * np.pi)\n  alpha2 = np.arctan2(rot[:, 6], rot[:, 7]) + ( 0.5 * np.pi)\n  return alpha1 * idx + alpha2 * (1 - idx)\n  \n\ndef ddd_post_process_2d(dets, c, s, opt):\n  # dets: batch x max_dets x dim\n  # return 1-based class det list\n  ret = []\n  include_wh = dets.shape[2] > 16\n  for i in range(dets.shape[0]):\n    top_preds = {}\n    dets[i, :, :2] = transform_preds(\n          dets[i, :, 0:2], c[i], s[i], (opt.output_w, opt.output_h))\n    classes = dets[i, :, -1]\n    for j in range(opt.num_classes):\n      inds = (classes == j)\n      top_preds[j + 1] = np.concatenate([\n        dets[i, inds, :3].astype(np.float32),\n        get_alpha(dets[i, inds, 3:11])[:, np.newaxis].astype(np.float32),\n        get_pred_depth(dets[i, inds, 11:12]).astype(np.float32),\n        dets[i, inds, 12:15].astype(np.float32)], axis=1)\n      if include_wh:\n        top_preds[j + 1] = np.concatenate([\n          top_preds[j + 1],\n          transform_preds(\n            dets[i, inds, 15:17], c[i], s[i], (opt.output_w, opt.output_h))\n          .astype(np.float32)], axis=1)\n    ret.append(top_preds)\n  return ret\n\ndef ddd_post_process_3d(dets, calibs):\n  # dets: batch x max_dets x dim\n  # return 1-based class det list\n  ret = []\n  for i in range(len(dets)):\n    preds = {}\n    for cls_ind in dets[i].keys():\n      preds[cls_ind] = []\n      for j in range(len(dets[i][cls_ind])):\n        center = dets[i][cls_ind][j][:2]\n        score = dets[i][cls_ind][j][2]\n        alpha = dets[i][cls_ind][j][3]\n        depth = dets[i][cls_ind][j][4]\n        dimensions = dets[i][cls_ind][j][5:8]\n        wh = dets[i][cls_ind][j][8:10]\n        locations, rotation_y = ddd2locrot(\n          center, alpha, dimensions, depth, calibs[0])\n        bbox = [center[0] - wh[0] / 2, center[1] - wh[1] / 2,\n                center[0] + wh[0] / 2, center[1] + wh[1] / 2]\n        pred = [alpha] + bbox + dimensions.tolist() + \\\n               locations.tolist() + [rotation_y, score]\n        preds[cls_ind].append(pred)\n      preds[cls_ind] = np.array(preds[cls_ind], dtype=np.float32)\n    ret.append(preds)\n  return ret\n\ndef ddd_post_process(dets, c, s, calibs, opt):\n  # dets: batch x max_dets x dim\n  # return 1-based class det list\n  dets = ddd_post_process_2d(dets, c, s, opt)\n  dets = ddd_post_process_3d(dets, calibs)\n  return dets\n\n\ndef ctdet_post_process(dets, c, s, h, w, num_classes):\n  # dets: batch x max_dets x dim\n  # return 1-based class det dict\n  ret = []\n  for i in range(dets.shape[0]):\n    top_preds = {}\n    dets[i, :, :2] = transform_preds(\n          dets[i, :, 0:2], c[i], s[i], (w, h))\n    dets[i, :, 2:4] = transform_preds(\n          dets[i, :, 2:4], c[i], s[i], (w, h))\n    classes = dets[i, :, -1]\n    for j in range(num_classes):\n      inds = (classes == j)\n      top_preds[j + 1] = np.concatenate([\n        dets[i, inds, :4].astype(np.float32),\n        dets[i, inds, 4:5].astype(np.float32)], axis=1).tolist()\n    ret.append(top_preds)\n  return ret\n\n\ndef multi_pose_post_process(dets, c, s, h, w):\n  # dets: batch x max_dets x 40\n  # return list of 39 in image coord\n  ret = []\n  for i in range(dets.shape[0]):\n    bbox = transform_preds(dets[i, :, :4].reshape(-1, 2), c[i], s[i], (w, h))\n    pts = transform_preds(dets[i, :, 5:39].reshape(-1, 2), c[i], s[i], (w, h))\n    top_preds = np.concatenate(\n      [bbox.reshape(-1, 4), dets[i, :, 4:5], \n       pts.reshape(-1, 34)], axis=1).astype(np.float32).tolist()\n    ret.append({np.ones(1, dtype=np.int32)[0]: top_preds})\n  return ret\n"
  },
  {
    "path": "src/lib/utils/utils.py",
    "content": "from __future__ import absolute_import\nfrom __future__ import division\nfrom __future__ import print_function\n\nimport torch\n\nclass AverageMeter(object):\n    \"\"\"Computes and stores the average and current value\"\"\"\n    def __init__(self):\n        self.reset()\n\n    def reset(self):\n        self.val = 0\n        self.avg = 0\n        self.sum = 0\n        self.count = 0\n\n    def update(self, val, n=1):\n        self.val = val\n        self.sum += val * n\n        self.count += n\n        if self.count > 0:\n          self.avg = self.sum / self.count"
  },
  {
    "path": "src/main.py",
    "content": "from __future__ import absolute_import\nfrom __future__ import division\nfrom __future__ import print_function\n\nimport _init_paths\n\nimport os\n\nimport torch\nimport torch.utils.data\nfrom opts import opts\nfrom models.model import create_model, load_model, save_model\nfrom models.data_parallel import DataParallel\nfrom logger import Logger\nfrom datasets.dataset_factory import get_dataset\nfrom trains.train_factory import train_factory\n\n\ndef main(opt):\n  torch.manual_seed(opt.seed)\n  torch.backends.cudnn.benchmark = not opt.not_cuda_benchmark and not opt.test\n  Dataset = get_dataset(opt.dataset, opt.task)\n  opt = opts().update_dataset_info_and_set_heads(opt, Dataset)\n  print(opt)\n\n  logger = Logger(opt)\n\n  os.environ['CUDA_VISIBLE_DEVICES'] = opt.gpus_str\n  opt.device = torch.device('cuda' if opt.gpus[0] >= 0 else 'cpu')\n  \n  print('Creating model...')\n  model = create_model(opt.arch, opt.heads, opt.head_conv)\n  optimizer = torch.optim.Adam(model.parameters(), opt.lr)\n  start_epoch = 0\n  if opt.load_model != '':\n    model, optimizer, start_epoch = load_model(\n      model, opt.load_model, optimizer, opt.resume, opt.lr, opt.lr_step)\n\n  Trainer = train_factory[opt.task]\n  trainer = Trainer(opt, model, optimizer)\n  trainer.set_device(opt.gpus, opt.chunk_sizes, opt.device)\n\n  print('Setting up data...')\n  val_loader = torch.utils.data.DataLoader(\n      Dataset(opt, 'val'), \n      batch_size=1, \n      shuffle=False,\n      num_workers=1,\n      pin_memory=True\n  )\n\n  if opt.test:\n    _, preds = trainer.val(0, val_loader)\n    val_loader.dataset.run_eval(preds, opt.save_dir)\n    return\n\n  train_loader = torch.utils.data.DataLoader(\n      Dataset(opt, 'train'), \n      batch_size=opt.batch_size, \n      shuffle=True,\n      num_workers=opt.num_workers,\n      pin_memory=True,\n      drop_last=True\n  )\n\n  print('Starting training...')\n  best = 1e10\n  for epoch in range(start_epoch + 1, opt.num_epochs + 1):\n    mark = epoch if opt.save_all else 'last'\n    log_dict_train, _ = trainer.train(epoch, train_loader)\n    logger.write('epoch: {} |'.format(epoch))\n    for k, v in log_dict_train.items():\n      logger.scalar_summary('train_{}'.format(k), v, epoch)\n      logger.write('{} {:8f} | '.format(k, v))\n    if opt.val_intervals > 0 and epoch % opt.val_intervals == 0:\n      save_model(os.path.join(opt.save_dir, 'model_{}.pth'.format(mark)), \n                 epoch, model, optimizer)\n      with torch.no_grad():\n        log_dict_val, preds = trainer.val(epoch, val_loader)\n      for k, v in log_dict_val.items():\n        logger.scalar_summary('val_{}'.format(k), v, epoch)\n        logger.write('{} {:8f} | '.format(k, v))\n      if log_dict_val[opt.metric] < best:\n        best = log_dict_val[opt.metric]\n        save_model(os.path.join(opt.save_dir, 'model_best.pth'), \n                   epoch, model)\n    else:\n      save_model(os.path.join(opt.save_dir, 'model_last.pth'), \n                 epoch, model, optimizer)\n    logger.write('\\n')\n    if epoch in opt.lr_step:\n      save_model(os.path.join(opt.save_dir, 'model_{}.pth'.format(epoch)), \n                 epoch, model, optimizer)\n      lr = opt.lr * (0.1 ** (opt.lr_step.index(epoch) + 1))\n      print('Drop LR to', lr)\n      for param_group in optimizer.param_groups:\n          param_group['lr'] = lr\n  logger.close()\n\nif __name__ == '__main__':\n  opt = opts().parse()\n  main(opt)"
  },
  {
    "path": "src/test.py",
    "content": "from __future__ import absolute_import\nfrom __future__ import division\nfrom __future__ import print_function\n\nimport _init_paths\n\nimport os\nimport json\nimport cv2\nimport numpy as np\nimport time\nfrom progress.bar import Bar\nimport torch\n\nfrom external.nms import soft_nms\nfrom opts import opts\nfrom logger import Logger\nfrom utils.utils import AverageMeter\nfrom datasets.dataset_factory import dataset_factory\nfrom detectors.detector_factory import detector_factory\n\nclass PrefetchDataset(torch.utils.data.Dataset):\n  def __init__(self, opt, dataset, pre_process_func):\n    self.images = dataset.images\n    self.load_image_func = dataset.coco.loadImgs\n    self.img_dir = dataset.img_dir\n    self.pre_process_func = pre_process_func\n    self.opt = opt\n  \n  def __getitem__(self, index):\n    img_id = self.images[index]\n    img_info = self.load_image_func(ids=[img_id])[0]\n    img_path = os.path.join(self.img_dir, img_info['file_name'])\n    image = cv2.imread(img_path)\n    images, meta = {}, {}\n    for scale in opt.test_scales:\n      if opt.task == 'ddd':\n        images[scale], meta[scale] = self.pre_process_func(\n          image, scale, img_info['calib'])\n      else:\n        images[scale], meta[scale] = self.pre_process_func(image, scale)\n    return img_id, {'images': images, 'image': image, 'meta': meta}\n\n  def __len__(self):\n    return len(self.images)\n\ndef prefetch_test(opt):\n  os.environ['CUDA_VISIBLE_DEVICES'] = opt.gpus_str\n\n  Dataset = dataset_factory[opt.dataset]\n  opt = opts().update_dataset_info_and_set_heads(opt, Dataset)\n  print(opt)\n  Logger(opt)\n  Detector = detector_factory[opt.task]\n  \n  split = 'val' if not opt.trainval else 'test'\n  dataset = Dataset(opt, split)\n  detector = Detector(opt)\n  \n  data_loader = torch.utils.data.DataLoader(\n    PrefetchDataset(opt, dataset, detector.pre_process), \n    batch_size=1, shuffle=False, num_workers=1, pin_memory=True)\n\n  results = {}\n  num_iters = len(dataset)\n  bar = Bar('{}'.format(opt.exp_id), max=num_iters)\n  time_stats = ['tot', 'load', 'pre', 'net', 'dec', 'post', 'merge']\n  avg_time_stats = {t: AverageMeter() for t in time_stats}\n  for ind, (img_id, pre_processed_images) in enumerate(data_loader):\n    ret = detector.run(pre_processed_images)\n    results[img_id.numpy().astype(np.int32)[0]] = ret['results']\n    Bar.suffix = '[{0}/{1}]|Tot: {total:} |ETA: {eta:} '.format(\n                   ind, num_iters, total=bar.elapsed_td, eta=bar.eta_td)\n    for t in avg_time_stats:\n      avg_time_stats[t].update(ret[t])\n      Bar.suffix = Bar.suffix + '|{} {tm.val:.3f}s ({tm.avg:.3f}s) '.format(\n        t, tm = avg_time_stats[t])\n    bar.next()\n  bar.finish()\n  dataset.run_eval(results, opt.save_dir)\n\ndef test(opt):\n  os.environ['CUDA_VISIBLE_DEVICES'] = opt.gpus_str\n\n  Dataset = dataset_factory[opt.dataset]\n  opt = opts().update_dataset_info_and_set_heads(opt, Dataset)\n  print(opt)\n  Logger(opt)\n  Detector = detector_factory[opt.task]\n  \n  split = 'val' if not opt.trainval else 'test'\n  dataset = Dataset(opt, split)\n  detector = Detector(opt)\n\n  results = {}\n  num_iters = len(dataset)\n  bar = Bar('{}'.format(opt.exp_id), max=num_iters)\n  time_stats = ['tot', 'load', 'pre', 'net', 'dec', 'post', 'merge']\n  avg_time_stats = {t: AverageMeter() for t in time_stats}\n  for ind in range(num_iters):\n    img_id = dataset.images[ind]\n    img_info = dataset.coco.loadImgs(ids=[img_id])[0]\n    img_path = os.path.join(dataset.img_dir, img_info['file_name'])\n\n    if opt.task == 'ddd':\n      ret = detector.run(img_path, img_info['calib'])\n    else:\n      ret = detector.run(img_path)\n    \n    results[img_id] = ret['results']\n\n    Bar.suffix = '[{0}/{1}]|Tot: {total:} |ETA: {eta:} '.format(\n                   ind, num_iters, total=bar.elapsed_td, eta=bar.eta_td)\n    for t in avg_time_stats:\n      avg_time_stats[t].update(ret[t])\n      Bar.suffix = Bar.suffix + '|{} {:.3f} '.format(t, avg_time_stats[t].avg)\n    bar.next()\n  bar.finish()\n  dataset.run_eval(results, opt.save_dir)\n\nif __name__ == '__main__':\n  opt = opts().parse()\n  if opt.not_prefetch_test:\n    test(opt)\n  else:\n    prefetch_test(opt)"
  },
  {
    "path": "src/tools/_init_paths.py",
    "content": "import os.path as osp\nimport sys\n\ndef add_path(path):\n    if path not in sys.path:\n        sys.path.insert(0, path)\n\nthis_dir = osp.dirname(__file__)\n\n# Add lib to PYTHONPATH\nlib_path = osp.join(this_dir, '../lib')\nadd_path(lib_path)\n"
  },
  {
    "path": "src/tools/calc_coco_overlap.py",
    "content": "from __future__ import absolute_import\nfrom __future__ import division\nfrom __future__ import print_function\n\nimport pycocotools.coco as COCO\nimport cv2\nimport numpy as np\nfrom pycocotools import mask as maskUtils\nANN_PATH = '../../data/coco/annotations/'\nIMG_PATH = '../../data/coco/'\nANN_FILES = {'train': 'instances_train2017.json',\n             'val': 'instances_val2017.json'}\nDEBUG = False\nRESIZE = True\n\nclass_name = [\n    '__background__', 'person', 'bicycle', 'car', 'motorcycle', 'airplane',\n    'bus', 'train', 'truck', 'boat', 'traffic light', 'fire hydrant',\n    'stop sign', 'parking meter', 'bench', 'bird', 'cat', 'dog', 'horse',\n    'sheep', 'cow', 'elephant', 'bear', 'zebra', 'giraffe', 'backpack',\n    'umbrella', 'handbag', 'tie', 'suitcase', 'frisbee', 'skis',\n    'snowboard', 'sports ball', 'kite', 'baseball bat', 'baseball glove',\n    'skateboard', 'surfboard', 'tennis racket', 'bottle', 'wine glass',\n    'cup', 'fork', 'knife', 'spoon', 'bowl', 'banana', 'apple', 'sandwich',\n    'orange', 'broccoli', 'carrot', 'hot dog', 'pizza', 'donut', 'cake',\n    'chair', 'couch', 'potted plant', 'bed', 'dining table', 'toilet', 'tv',\n    'laptop', 'mouse', 'remote', 'keyboard', 'cell phone', 'microwave',\n    'oven', 'toaster', 'sink', 'refrigerator', 'book', 'clock', 'vase',\n    'scissors', 'teddy bear', 'hair drier', 'toothbrush'\n]\n\ndef iou(box1, box2):\n  area1 = (box1[2] - box1[0] + 1) * (box1[3] - box1[1] + 1)\n  area2 = (box2[2] - box2[0] + 1) * (box2[3] - box2[1] + 1)\n  inter = max(min(box1[2], box2[2]) - max(box1[0], box2[0]) + 1, 0) * \\\n          max(min(box1[3], box2[3]) - max(box1[1], box2[1]) + 1, 0)\n  iou = 1.0 * inter / (area1 + area2 - inter)\n  return iou\n\ndef generate_anchors(\n    stride=16, sizes=(32, 64, 128, 256, 512), aspect_ratios=(0.5, 1, 2)\n):\n    \"\"\"Generates a matrix of anchor boxes in (x1, y1, x2, y2) format. Anchors\n    are centered on stride / 2, have (approximate) sqrt areas of the specified\n    sizes, and aspect ratios as given.\n    \"\"\"\n    return _generate_anchors(\n        stride,\n        np.array(sizes, dtype=np.float) / stride,\n        np.array(aspect_ratios, dtype=np.float)\n    )\n\n\ndef _generate_anchors(base_size, scales, aspect_ratios):\n    \"\"\"Generate anchor (reference) windows by enumerating aspect ratios X\n    scales wrt a reference (0, 0, base_size - 1, base_size - 1) window.\n    \"\"\"\n    anchor = np.array([1, 1, base_size, base_size], dtype=np.float) - 1\n    anchors = _ratio_enum(anchor, aspect_ratios)\n    anchors = np.vstack(\n        [_scale_enum(anchors[i, :], scales) for i in range(anchors.shape[0])]\n    )\n    return anchors\n\n\ndef _whctrs(anchor):\n    \"\"\"Return width, height, x center, and y center for an anchor (window).\"\"\"\n    w = anchor[2] - anchor[0] + 1\n    h = anchor[3] - anchor[1] + 1\n    x_ctr = anchor[0] + 0.5 * (w - 1)\n    y_ctr = anchor[1] + 0.5 * (h - 1)\n    return w, h, x_ctr, y_ctr\n\n\ndef _mkanchors(ws, hs, x_ctr, y_ctr):\n    \"\"\"Given a vector of widths (ws) and heights (hs) around a center\n    (x_ctr, y_ctr), output a set of anchors (windows).\n    \"\"\"\n    ws = ws[:, np.newaxis]\n    hs = hs[:, np.newaxis]\n    anchors = np.hstack(\n        (\n            x_ctr - 0.5 * (ws - 1),\n            y_ctr - 0.5 * (hs - 1),\n            x_ctr + 0.5 * (ws - 1),\n            y_ctr + 0.5 * (hs - 1)\n        )\n    )\n    return anchors\n\n\ndef _ratio_enum(anchor, ratios):\n    \"\"\"Enumerate a set of anchors for each aspect ratio wrt an anchor.\"\"\"\n    w, h, x_ctr, y_ctr = _whctrs(anchor)\n    size = w * h\n    size_ratios = size / ratios\n    ws = np.round(np.sqrt(size_ratios))\n    hs = np.round(ws * ratios)\n    anchors = _mkanchors(ws, hs, x_ctr, y_ctr)\n    return anchors\n\n\ndef _scale_enum(anchor, scales):\n    \"\"\"Enumerate a set of anchors for each scale wrt an anchor.\"\"\"\n    w, h, x_ctr, y_ctr = _whctrs(anchor)\n    ws = w * scales\n    hs = h * scales\n    anchors = _mkanchors(ws, hs, x_ctr, y_ctr)\n    return anchors\n\n\ndef _coco_box_to_bbox(box):\n    bbox = np.array([box[0], box[1], box[0] + box[2], box[1] + box[3]],\n                    dtype=np.float32)\n    return bbox\n\ndef count_agnostic(split):\n  coco = COCO.COCO(ANN_PATH + ANN_FILES[split])\n  images = coco.getImgIds()\n  cnt = 0\n  for img_id in images:\n    ann_ids = coco.getAnnIds(imgIds=[img_id])\n    anns = coco.loadAnns(ids=ann_ids)\n    centers = []\n    for ann in anns:\n      bbox = ann['bbox']\n      center = ((bbox[0] + bbox[2] / 2) // 4, (bbox[1] + bbox[3] / 2) // 4)\n      for c in centers:\n        if center[0] == c[0] and center[1] == c[1]:\n          cnt += 1\n      centers.append(center)\n  print('find {} collisions!'.format(cnt))\n\n\ndef count(split):\n  coco = COCO.COCO(ANN_PATH + ANN_FILES[split])\n  images = coco.getImgIds()\n  cnt = 0\n  obj = 0\n  for img_id in images:\n    ann_ids = coco.getAnnIds(imgIds=[img_id])\n    anns = coco.loadAnns(ids=ann_ids)\n    centers = []\n    obj += len(anns)\n    for ann in anns:\n      if ann['iscrowd'] > 0:\n        continue\n      bbox = ann['bbox']\n      center = ((bbox[0] + bbox[2] / 2) // 4, (bbox[1] + bbox[3] / 2) // 4, ann['category_id'], bbox)\n      for c in centers:\n        if center[0] == c[0] and center[1] == c[1] and center[2] == c[2] and \\\n           iou(_coco_box_to_bbox(bbox), _coco_box_to_bbox(c[3])) < 2:# 0.5:\n          cnt += 1\n          if DEBUG:\n            file_name = coco.loadImgs(ids=[img_id])[0]['file_name']\n            img = cv2.imread('{}/{}2017/{}'.format(IMG_PATH, split, file_name))\n            x1, y1 = int(c[3][0]), int(c[3][1]), \n            x2, y2 = int(c[3][0] + c[3][2]), int(c[3][1] + c[3][3]) \n            cv2.rectangle(img, (x1, y1), (x2, y2), (255, 0, 0), 2, cv2.LINE_AA)\n            x1, y1 = int(center[3][0]), int(center[3][1]), \n            x2, y2 = int(center[3][0] + center[3][2]), int(center[3][1] + center[3][3]) \n            cv2.rectangle(img, (x1, y1), (x2, y2), (0, 0, 255), 2, cv2.LINE_AA)\n            cv2.imshow('img', img)\n            cv2.waitKey()\n      centers.append(center)\n  print('find {} collisions of {} objects!'.format(cnt, obj))\n\ndef count_iou(split):\n  coco = COCO.COCO(ANN_PATH + ANN_FILES[split])\n  images = coco.getImgIds()\n  cnt = 0\n  obj = 0\n  for img_id in images:\n    ann_ids = coco.getAnnIds(imgIds=[img_id])\n    anns = coco.loadAnns(ids=ann_ids)\n    bboxes = []\n    obj += len(anns)\n    for ann in anns:\n      if ann['iscrowd'] > 0:\n        continue\n      bbox = _coco_box_to_bbox(ann['bbox']).tolist() + [ann['category_id']]\n      for b in bboxes:\n        if iou(b, bbox) > 0.5 and b[4] == bbox[4]:\n          cnt += 1\n          if DEBUG:\n            file_name = coco.loadImgs(ids=[img_id])[0]['file_name']\n            img = cv2.imread('{}/{}2017/{}'.format(IMG_PATH, split, file_name))\n            x1, y1 = int(b[0]), int(b[1]), \n            x2, y2 = int(b[2]), int(b[3]) \n            cv2.rectangle(img, (x1, y1), (x2, y2), (255, 0, 0), 2, cv2.LINE_AA)\n            x1, y1 = int(bbox[0]), int(bbox[1]), \n            x2, y2 = int(bbox[2]), int(bbox[3]) \n            cv2.rectangle(img, (x1, y1), (x2, y2), (0, 0, 255), 2, cv2.LINE_AA)\n            cv2.imshow('img', img)\n            print('cats', class_name[b[4]], class_name[bbox[4]])\n            cv2.waitKey()\n      bboxes.append(bbox)\n  print('find {} collisions of {} objects!'.format(cnt, obj))\n\n\ndef count_anchor(split):\n  coco = COCO.COCO(ANN_PATH + ANN_FILES[split])\n  images = coco.getImgIds()\n  cnt = 0\n  obj = 0\n  stride = 16\n  anchor = generate_anchors().reshape(15, 2, 2)\n  miss_s, miss_m, miss_l = 0, 0, 0\n  N = len(images)\n  print(N, 'images')\n  for ind, img_id in enumerate(images):\n    if ind % 1000 == 0:\n      print(ind, N)\n    anchors = []\n    ann_ids = coco.getAnnIds(imgIds=[img_id])\n    anns = coco.loadAnns(ids=ann_ids)\n    obj += len(anns)\n    img_info = coco.loadImgs(ids=[img_id])[0]\n    h, w = img_info['height'], img_info['width']\n    if RESIZE:\n      if h > w:\n        for i in range(len(anns)):\n          anns[i]['bbox'][0] *= 800 / w\n          anns[i]['bbox'][1] *= 800 / w\n          anns[i]['bbox'][2] *= 800 / w\n          anns[i]['bbox'][3] *= 800 / w\n        h = h * 800 // w\n        w = 800 \n      else:\n        for i in range(len(anns)):\n          anns[i]['bbox'][0] *= 800 / h\n          anns[i]['bbox'][1] *= 800 / h\n          anns[i]['bbox'][2] *= 800 / h\n          anns[i]['bbox'][3] *= 800 / h\n        w = w * 800 // h\n        h = 800 \n    for i in range(w // stride):\n      for j in range(h // stride):\n        ct = np.array([i * stride, j * stride], dtype=np.float32).reshape(1, 1, 2)\n        anchors.append(anchor + ct)\n    anchors = np.concatenate(anchors, axis=0).reshape(-1, 4)\n    anchors[:, 2:4] = anchors[:, 2:4] - anchors[:, 0:2]\n    anchors = anchors.tolist()\n    # import pdb; pdb.set_trace()\n    g = [g['bbox'] for g in anns]\n    iscrowd = [int(o['iscrowd']) for o in anns]\n    ious = maskUtils.iou(anchors,g,iscrowd)\n    for t in range(len(g)):\n      if ious[:, t].max() < 0.5:\n        s = anns[t]['area']\n        if s < 32 ** 2:\n          miss_s += 1\n        elif s < 96 ** 2:\n          miss_m += 1\n        else:\n          miss_l += 1\n    if DEBUG:\n      file_name = coco.loadImgs(ids=[img_id])[0]['file_name']\n      img = cv2.imread('{}/{}2017/{}'.format(IMG_PATH, split, file_name))\n      if RESIZE:\n        img = cv2.resize(img, (w, h))\n      for t, gt in enumerate(g):\n        if anns[t]['iscrowd'] > 0:\n          continue\n        x1, y1, x2, y2 = _coco_box_to_bbox(gt)\n        cl = (0, 0, 255) if ious[:, t].max() < 0.5 else (0, 255, 0)\n        cv2.rectangle(img, (x1, y1), (x2, y2), cl, 2, cv2.LINE_AA)\n        for k in range(len(anchors)):\n          if ious[k, t] > 0.5:\n            x1, y1, x2, y2 = _coco_box_to_bbox(anchors[k])\n            cl = (np.array([255, 0, 0]) * ious[k, t]).astype(np.int32).tolist()\n            cv2.rectangle(img, (x1, y1), (x2, y2), cl, 1, cv2.LINE_AA)\n      cv2.imshow('img', img)\n      cv2.waitKey()\n    miss = 0\n    if len(ious) > 0:\n      miss = (ious.max(axis=0) < 0.5).sum()\n    cnt += miss\n  print('cnt, obj, ratio ', cnt, obj, cnt / obj)\n  print('s, m, l ', miss_s, miss_m, miss_l)\n    # import pdb; pdb.set_trace()\n\n\ndef count_size(split):\n  coco = COCO.COCO(ANN_PATH + ANN_FILES[split])\n  images = coco.getImgIds()\n  cnt = 0\n  obj = 0\n  stride = 16\n  anchor = generate_anchors().reshape(15, 2, 2)\n  cnt_s, cnt_m, cnt_l = 0, 0, 0\n  N = len(images)\n  print(N, 'images')\n  for ind, img_id in enumerate(images):\n    anchors = []\n    ann_ids = coco.getAnnIds(imgIds=[img_id])\n    anns = coco.loadAnns(ids=ann_ids)\n    obj += len(anns)\n    img_info = coco.loadImgs(ids=[img_id])[0]\n    for t in range(len(anns)):\n      if 1:\n        s = anns[t]['area']\n        if s < 32 ** 2:\n          cnt_s += 1\n        elif s < 96 ** 2:\n          cnt_m += 1\n        else:\n          cnt_l += 1\n      cnt += 1\n  print('cnt', cnt)\n  print('s, m, l ', cnt_s, cnt_m, cnt_l)\n \n\n# count_iou('train')\n# count_anchor('train')\n# count('train')\ncount_size('train')\n\n\n\n\n\n"
  },
  {
    "path": "src/tools/convert_hourglass_weight.py",
    "content": "from __future__ import absolute_import\nfrom __future__ import division\nfrom __future__ import print_function\n\nMODEL_PATH = '../../models/ExtremeNet_500000.pkl'\nOUT_PATH = '../../models/ExtremeNet_500000.pth'\n\nimport torch\nstate_dict = torch.load(MODEL_PATH)\nkey_map = {'t_heats': 'hm_t', 'l_heats': 'hm_l', 'b_heats': 'hm_b', \\\n           'r_heats': 'hm_r', 'ct_heats': 'hm_c', \\\n           't_regrs': 'reg_t', 'l_regrs': 'reg_l', \\\n           'b_regrs': 'reg_b', 'r_regrs': 'reg_r'}\n\nout = {}\nfor k in state_dict.keys():\n  changed = False\n  for m in key_map.keys():\n    if m in k:\n      if 'ct_heats' in k and m == 't_heats':\n        continue\n      new_k = k.replace(m, key_map[m])\n      out[new_k] = state_dict[k]\n      changed = True\n      print('replace {} to {}'.format(k, new_k))\n  if not changed:\n    out[k] = state_dict[k]\ndata = {'epoch': 0,\n        'state_dict': out}\ntorch.save(data, OUT_PATH)\n"
  },
  {
    "path": "src/tools/convert_kitti_to_coco.py",
    "content": "from __future__ import absolute_import\nfrom __future__ import division\nfrom __future__ import print_function\n\nimport pickle\nimport json\nimport numpy as np\nimport cv2\nDATA_PATH = '../../data/kitti/'\nDEBUG = False\n# VAL_PATH = DATA_PATH + 'training/label_val/'\nimport os\nSPLITS = ['3dop', 'subcnn'] \nimport _init_paths\nfrom utils.ddd_utils import compute_box_3d, project_to_image, alpha2rot_y\nfrom utils.ddd_utils import draw_box_3d, unproject_2d_to_3d\n\n'''\n#Values    Name      Description\n----------------------------------------------------------------------------\n   1    type         Describes the type of object: 'Car', 'Van', 'Truck',\n                     'Pedestrian', 'Person_sitting', 'Cyclist', 'Tram',\n                     'Misc' or 'DontCare'\n   1    truncated    Float from 0 (non-truncated) to 1 (truncated), where\n                     truncated refers to the object leaving image boundaries\n   1    occluded     Integer (0,1,2,3) indicating occlusion state:\n                     0 = fully visible, 1 = partly occluded\n                     2 = largely occluded, 3 = unknown\n   1    alpha        Observation angle of object, ranging [-pi..pi]\n   4    bbox         2D bounding box of object in the image (0-based index):\n                     contains left, top, right, bottom pixel coordinates\n   3    dimensions   3D object dimensions: height, width, length (in meters)\n   3    location     3D object location x,y,z in camera coordinates (in meters)\n   1    rotation_y   Rotation ry around Y-axis in camera coordinates [-pi..pi]\n   1    score        Only for results: Float, indicating confidence in\n                     detection, needed for p/r curves, higher is better.\n'''\n\ndef _bbox_to_coco_bbox(bbox):\n  return [(bbox[0]), (bbox[1]),\n          (bbox[2] - bbox[0]), (bbox[3] - bbox[1])]\n\ndef read_clib(calib_path):\n  f = open(calib_path, 'r')\n  for i, line in enumerate(f):\n    if i == 2:\n      calib = np.array(line[:-1].split(' ')[1:], dtype=np.float32)\n      calib = calib.reshape(3, 4)\n      return calib\n\ncats = ['Pedestrian', 'Car', 'Cyclist', 'Van', 'Truck',  'Person_sitting',\n        'Tram', 'Misc', 'DontCare']\ncat_ids = {cat: i + 1 for i, cat in enumerate(cats)}\n# cat_info = [{\"name\": \"pedestrian\", \"id\": 1}, {\"name\": \"vehicle\", \"id\": 2}]\nF = 721\nH = 384 # 375\nW = 1248 # 1242\nEXT = [45.75, -0.34, 0.005]\nCALIB = np.array([[F, 0, W / 2, EXT[0]], [0, F, H / 2, EXT[1]], \n                  [0, 0, 1, EXT[2]]], dtype=np.float32)\n\ncat_info = []\nfor i, cat in enumerate(cats):\n  cat_info.append({'name': cat, 'id': i + 1})\n\nfor SPLIT in SPLITS:\n  image_set_path = DATA_PATH + 'ImageSets_{}/'.format(SPLIT)\n  ann_dir = DATA_PATH + 'training/label_2/'\n  calib_dir = DATA_PATH + '{}/calib/'\n  splits = ['train', 'val']\n  # splits = ['trainval', 'test']\n  calib_type = {'train': 'training', 'val': 'training', 'trainval': 'training',\n                'test': 'testing'}\n\n  for split in splits:\n    ret = {'images': [], 'annotations': [], \"categories\": cat_info}\n    image_set = open(image_set_path + '{}.txt'.format(split), 'r')\n    image_to_id = {}\n    for line in image_set:\n      if line[-1] == '\\n':\n        line = line[:-1]\n      image_id = int(line)\n      calib_path = calib_dir.format(calib_type[split]) + '{}.txt'.format(line)\n      calib = read_clib(calib_path)\n      image_info = {'file_name': '{}.png'.format(line),\n                    'id': int(image_id),\n                    'calib': calib.tolist()}\n      ret['images'].append(image_info)\n      if split == 'test':\n        continue\n      ann_path = ann_dir + '{}.txt'.format(line)\n      # if split == 'val':\n      #   os.system('cp {} {}/'.format(ann_path, VAL_PATH))\n      anns = open(ann_path, 'r')\n      \n      if DEBUG:\n        image = cv2.imread(\n          DATA_PATH + 'images/trainval/' + image_info['file_name'])\n\n      for ann_ind, txt in enumerate(anns):\n        tmp = txt[:-1].split(' ')\n        cat_id = cat_ids[tmp[0]]\n        truncated = int(float(tmp[1]))\n        occluded = int(tmp[2])\n        alpha = float(tmp[3])\n        bbox = [float(tmp[4]), float(tmp[5]), float(tmp[6]), float(tmp[7])]\n        dim = [float(tmp[8]), float(tmp[9]), float(tmp[10])]\n        location = [float(tmp[11]), float(tmp[12]), float(tmp[13])]\n        rotation_y = float(tmp[14])\n\n        ann = {'image_id': image_id,\n               'id': int(len(ret['annotations']) + 1),\n               'category_id': cat_id,\n               'dim': dim,\n               'bbox': _bbox_to_coco_bbox(bbox),\n               'depth': location[2],\n               'alpha': alpha,\n               'truncated': truncated,\n               'occluded': occluded,\n               'location': location,\n               'rotation_y': rotation_y}\n        ret['annotations'].append(ann)\n        if DEBUG and tmp[0] != 'DontCare':\n          box_3d = compute_box_3d(dim, location, rotation_y)\n          box_2d = project_to_image(box_3d, calib)\n          # print('box_2d', box_2d)\n          image = draw_box_3d(image, box_2d)\n          x = (bbox[0] + bbox[2]) / 2\n          '''\n          print('rot_y, alpha2rot_y, dlt', tmp[0], \n                rotation_y, alpha2rot_y(alpha, x, calib[0, 2], calib[0, 0]),\n                np.cos(\n                  rotation_y - alpha2rot_y(alpha, x, calib[0, 2], calib[0, 0])))\n          '''\n          depth = np.array([location[2]], dtype=np.float32)\n          pt_2d = np.array([(bbox[0] + bbox[2]) / 2, (bbox[1] + bbox[3]) / 2],\n                            dtype=np.float32)\n          pt_3d = unproject_2d_to_3d(pt_2d, depth, calib)\n          pt_3d[1] += dim[0] / 2\n          print('pt_3d', pt_3d)\n          print('location', location)\n      if DEBUG:\n        cv2.imshow('image', image)\n        cv2.waitKey()\n\n\n    print(\"# images: \", len(ret['images']))\n    print(\"# annotations: \", len(ret['annotations']))\n    # import pdb; pdb.set_trace()\n    out_path = '{}/annotations/kitti_{}_{}.json'.format(DATA_PATH, SPLIT, split)\n    json.dump(ret, open(out_path, 'w'))\n  \n"
  },
  {
    "path": "src/tools/eval_coco.py",
    "content": "from __future__ import absolute_import\nfrom __future__ import division\nfrom __future__ import print_function\n\nimport pycocotools.coco as coco\nfrom pycocotools.cocoeval import COCOeval\nimport sys\nimport cv2\nimport numpy as np\nimport pickle\nimport os\n\nthis_dir = os.path.dirname(__file__)\nANN_PATH = this_dir + '../../data/coco/annotations/instances_val2017.json'\nprint(ANN_PATH)\nif __name__ == '__main__':\n  pred_path = sys.argv[1]\n  coco = coco.COCO(ANN_PATH)\n  dets = coco.loadRes(pred_path)\n  img_ids = coco.getImgIds()\n  num_images = len(img_ids)\n  coco_eval = COCOeval(coco, dets, \"bbox\")\n  coco_eval.evaluate()\n  coco_eval.accumulate()\n  coco_eval.summarize()\n\n  \n"
  },
  {
    "path": "src/tools/eval_coco_hp.py",
    "content": "from __future__ import absolute_import\nfrom __future__ import division\nfrom __future__ import print_function\n\nimport pycocotools.coco as coco\nfrom pycocotools.cocoeval import COCOeval\nimport sys\nimport cv2\nimport numpy as np\nimport pickle\nimport os\n\nthis_dir = os.path.dirname(__file__)\nANN_PATH = this_dir + '../../data/coco/annotations/person_keypoints_val2017.json'\nprint(ANN_PATH)\nif __name__ == '__main__':\n  pred_path = sys.argv[1]\n  coco = coco.COCO(ANN_PATH)\n  dets = coco.loadRes(pred_path)\n  img_ids = coco.getImgIds()\n  num_images = len(img_ids)\n  coco_eval = COCOeval(coco, dets, \"keypoints\")\n  coco_eval.evaluate()\n  coco_eval.accumulate()\n  coco_eval.summarize()\n  coco_eval = COCOeval(coco, dets, \"bbox\")\n  coco_eval.evaluate()\n  coco_eval.accumulate()\n  coco_eval.summarize()\n  \n"
  },
  {
    "path": "src/tools/get_kitti.sh",
    "content": "mkdir kitti\ncd kitti\nwget http://www.cvlibs.net/download.php?file=data_object_image_2.zip\nwget http://www.cvlibs.net/download.php?file=data_object_label_2.zip\nwget http://www.cvlibs.net/download.php?file=data_object_calib.zip\nunzip data_object_image_2.zip\nunzip data_object_label_2.zip\nunzip data_object_calib.zip\n\n"
  },
  {
    "path": "src/tools/get_pascal_voc.sh",
    "content": "mkdir voc\ncd voc\nwget http://host.robots.ox.ac.uk/pascal/VOC/voc2007/VOCtrainval_06-Nov-2007.tar\nwget http://host.robots.ox.ac.uk/pascal/VOC/voc2007/VOCtest_06-Nov-2007.tar\nwget http://host.robots.ox.ac.uk/pascal/VOC/voc2007/VOCdevkit_08-Jun-2007.tar\nwget http://host.robots.ox.ac.uk/pascal/VOC/voc2012/VOCtrainval_11-May-2012.tar\nwget http://host.robots.ox.ac.uk/pascal/VOC/voc2012/VOCdevkit_18-May-2011.tar\ntar xvf VOCtrainval_06-Nov-2007.tar\ntar xvf VOCtest_06-Nov-2007.tar\ntar xvf VOCdevkit_08-Jun-2007.tar\ntar xvf VOCtrainval_11-May-2012.tar\ntar xvf VOCdevkit_18-May-2011.tar\nrm VOCtrainval_06-Nov-2007.tar\nrm VOCtest_06-Nov-2007.tar\nrm VOCdevkit_08-Jun-2007.tar\nrm VOCtrainval_11-May-2012.tar\nrm VOCdevkit_18-May-2011.tar\nmkdir images\ncp VOCdevkit/VOC2007/JPEGImages/* images/\ncp VOCdevkit/VOC2012/JPEGImages/* images/\nwget https://storage.googleapis.com/coco-dataset/external/PASCAL_VOC.zip\nunzip PASCAL_VOC.zip\nrm PASCAL_VOC.zip\nmv PASCAL_VOC annotations/\ncd ..\npython merge_pascal_json.py\n"
  },
  {
    "path": "src/tools/kitti_eval/README.md",
    "content": "# kitti_eval\n\n`evaluate_object_3d_offline.cpp`evaluates your KITTI detection locally on your own computer using your validation data selected from KITTI training dataset, with the following metrics:\n\n- overlap on image (AP)\n- oriented overlap on image (AOS)\n- overlap on ground-plane (AP)\n- overlap in 3D (AP)\n\nCompile `evaluate_object_3d_offline.cpp` with dependency of Boost and Linux `dirent.h` (You should already have it under most Linux).\n\nRun the evalutaion by:\n\n    ./evaluate_object_3d_offline groundtruth_dir result_dir\n    \nNote that you don't have to detect over all KITTI training data. The evaluator only evaluates samples whose result files exist.\n\n\n### Updates\n\n- June, 2017:\n  * Fixed the bug of detection box filtering based on min height according to KITTI's note on 25.04.2017.\n"
  },
  {
    "path": "src/tools/kitti_eval/evaluate_object_3d.cpp",
    "content": "// from https://github.com/prclibo/kitti_eval\n#include <iostream>\n#include <algorithm>\n#include <stdio.h>\n#include <math.h>\n#include <vector>\n#include <numeric>\n#include <strings.h>\n#include <assert.h>\n\n#include <dirent.h>\n\n#include <boost/numeric/ublas/matrix.hpp>\n#include <boost/numeric/ublas/io.hpp>\n\n#include <boost/geometry.hpp>\n#include <boost/geometry/geometries/point_xy.hpp>\n#include <boost/geometry/geometries/polygon.hpp>\n#include <boost/geometry/geometries/adapted/c_array.hpp>\n\n#include \"mail.h\"\n\nBOOST_GEOMETRY_REGISTER_C_ARRAY_CS(cs::cartesian)\n\ntypedef boost::geometry::model::polygon<boost::geometry::model::d2::point_xy<double> > Polygon;\n\n\nusing namespace std;\n\n/*=======================================================================\nSTATIC EVALUATION PARAMETERS\n=======================================================================*/\n\n// holds the number of test images on the server\nconst int32_t N_TESTIMAGES = 7518;\n\n// easy, moderate and hard evaluation level\nenum DIFFICULTY{EASY=0, MODERATE=1, HARD=2};\n\n// evaluation metrics: image, ground or 3D\nenum METRIC{IMAGE=0, GROUND=1, BOX3D=2};\n\n// evaluation parameter\nconst int32_t MIN_HEIGHT[3]     = {40, 25, 25};     // minimum height for evaluated groundtruth/detections\nconst int32_t MAX_OCCLUSION[3]  = {0, 1, 2};        // maximum occlusion level of the groundtruth used for evaluation\nconst double  MAX_TRUNCATION[3] = {0.15, 0.3, 0.5}; // maximum truncation level of the groundtruth used for evaluation\n\n// evaluated object classes\nenum CLASSES{CAR=0, PEDESTRIAN=1, CYCLIST=2};\nconst int NUM_CLASS = 3;\n\n// parameters varying per class\nvector<string> CLASS_NAMES;\n// the minimum overlap required for 2D evaluation on the image/ground plane and 3D evaluation\nconst double MIN_OVERLAP[3][3] = {{0.7, 0.5, 0.5}, {0.5, 0.25, 0.25}, {0.5, 0.25, 0.25}};\n\n// no. of recall steps that should be evaluated (discretized)\nconst double N_SAMPLE_PTS = 41;\n\n\n// initialize class names\nvoid initGlobals () {\n  CLASS_NAMES.push_back(\"car\");\n  CLASS_NAMES.push_back(\"pedestrian\");\n  CLASS_NAMES.push_back(\"cyclist\");\n}\n\n/*=======================================================================\nDATA TYPES FOR EVALUATION\n=======================================================================*/\n\n// holding data needed for precision-recall and precision-aos\nstruct tPrData {\n  vector<double> v;           // detection score for computing score thresholds\n  double         similarity;  // orientation similarity\n  int32_t        tp;          // true positives\n  int32_t        fp;          // false positives\n  int32_t        fn;          // false negatives\n  tPrData () :\n    similarity(0), tp(0), fp(0), fn(0) {}\n};\n\n// holding bounding boxes for ground truth and detections\nstruct tBox {\n  string  type;     // object type as car, pedestrian or cyclist,...\n  double   x1;      // left corner\n  double   y1;      // top corner\n  double   x2;      // right corner\n  double   y2;      // bottom corner\n  double   alpha;   // image orientation\n  tBox (string type, double x1,double y1,double x2,double y2,double alpha) :\n    type(type),x1(x1),y1(y1),x2(x2),y2(y2),alpha(alpha) {}\n};\n\n// holding ground truth data\nstruct tGroundtruth {\n  tBox    box;        // object type, box, orientation\n  double  truncation; // truncation 0..1\n  int32_t occlusion;  // occlusion 0,1,2 (non, partly, fully)\n  double ry;\n  double  t1, t2, t3;\n  double h, w, l;\n  tGroundtruth () :\n    box(tBox(\"invalild\",-1,-1,-1,-1,-10)),truncation(-1),occlusion(-1) {}\n  tGroundtruth (tBox box,double truncation,int32_t occlusion) :\n    box(box),truncation(truncation),occlusion(occlusion) {}\n  tGroundtruth (string type,double x1,double y1,double x2,double y2,double alpha,double truncation,int32_t occlusion) :\n    box(tBox(type,x1,y1,x2,y2,alpha)),truncation(truncation),occlusion(occlusion) {}\n};\n\n// holding detection data\nstruct tDetection {\n  tBox    box;    // object type, box, orientation\n  double  thresh; // detection score\n  double  ry;\n  double  t1, t2, t3;\n  double  h, w, l;\n  tDetection ():\n    box(tBox(\"invalid\",-1,-1,-1,-1,-10)),thresh(-1000) {}\n  tDetection (tBox box,double thresh) :\n    box(box),thresh(thresh) {}\n  tDetection (string type,double x1,double y1,double x2,double y2,double alpha,double thresh) :\n    box(tBox(type,x1,y1,x2,y2,alpha)),thresh(thresh) {}\n};\n\n\n/*=======================================================================\nFUNCTIONS TO LOAD DETECTION AND GROUND TRUTH DATA ONCE, SAVE RESULTS\n=======================================================================*/\nvector<int32_t> indices;\n\nvector<tDetection> loadDetections(string file_name, bool &compute_aos,\n        vector<bool> &eval_image, vector<bool> &eval_ground,\n        vector<bool> &eval_3d, bool &success) {\n\n  // holds all detections (ignored detections are indicated by an index vector\n  vector<tDetection> detections;\n  FILE *fp = fopen(file_name.c_str(),\"r\");\n  if (!fp) {\n    success = false;\n    return detections;\n  }\n  while (!feof(fp)) {\n    tDetection d;\n    double trash;\n    char str[255];\n    if (fscanf(fp, \"%s %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf\",\n                   str, &trash, &trash, &d.box.alpha, &d.box.x1, &d.box.y1,\n                   &d.box.x2, &d.box.y2, &d.h, &d.w, &d.l, &d.t1, &d.t2, &d.t3,\n                   &d.ry, &d.thresh)==16) {\n\n        // d.thresh = 1;\n      d.box.type = str;\n      detections.push_back(d);\n\n      // orientation=-10 is invalid, AOS is not evaluated if at least one orientation is invalid\n      if(d.box.alpha == -10)\n        compute_aos = false;\n\n      // a class is only evaluated if it is detected at least once\n      for (int c = 0; c < NUM_CLASS; c++) {\n        if (!strcasecmp(d.box.type.c_str(), CLASS_NAMES[c].c_str())) {\n          if (!eval_image[c] && d.box.x1 >= 0)\n            eval_image[c] = true;\n          if (!eval_ground[c] && d.t1 != -1000)\n            eval_ground[c] = true;\n          if (!eval_3d[c] && d.t2 != -1000)\n            eval_3d[c] = true;\n          break;\n        }\n      }\n    }\n  }\n  fclose(fp);\n  success = true;\n  return detections;\n}\n\nvector<tGroundtruth> loadGroundtruth(string file_name,bool &success) {\n\n  // holds all ground truth (ignored ground truth is indicated by an index vector\n  vector<tGroundtruth> groundtruth;\n  FILE *fp = fopen(file_name.c_str(),\"r\");\n  if (!fp) {\n    success = false;\n    return groundtruth;\n  }\n  while (!feof(fp)) {\n    tGroundtruth g;\n    char str[255];\n    if (fscanf(fp, \"%s %lf %d %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf\",\n                   str, &g.truncation, &g.occlusion, &g.box.alpha,\n                   &g.box.x1,   &g.box.y1,     &g.box.x2,    &g.box.y2,\n                   &g.h,      &g.w,        &g.l,       &g.t1,\n                   &g.t2,      &g.t3,        &g.ry )==15) {\n      g.box.type = str;\n      groundtruth.push_back(g);\n    }\n  }\n  fclose(fp);\n  success = true;\n  return groundtruth;\n}\n\nvoid saveStats (const vector<double> &precision, const vector<double> &aos, FILE *fp_det, FILE *fp_ori) {\n\n  // save precision to file\n  if(precision.empty())\n    return;\n  for (int32_t i=0; i<precision.size(); i++)\n    fprintf(fp_det,\"%f \",precision[i]);\n  fprintf(fp_det,\"\\n\");\n\n  // save orientation similarity, only if there were no invalid orientation entries in submission (alpha=-10)\n  if(aos.empty())\n    return;\n  for (int32_t i=0; i<aos.size(); i++)\n    fprintf(fp_ori,\"%f \",aos[i]);\n  fprintf(fp_ori,\"\\n\");\n}\n\n/*=======================================================================\nEVALUATION HELPER FUNCTIONS\n=======================================================================*/\n\n// criterion defines whether the overlap is computed with respect to both areas (ground truth and detection)\n// or with respect to box a or b (detection and \"dontcare\" areas)\ninline double imageBoxOverlap(tBox a, tBox b, int32_t criterion=-1){\n\n  // overlap is invalid in the beginning\n  double o = -1;\n\n  // get overlapping area\n  double x1 = max(a.x1, b.x1);\n  double y1 = max(a.y1, b.y1);\n  double x2 = min(a.x2, b.x2);\n  double y2 = min(a.y2, b.y2);\n\n  // compute width and height of overlapping area\n  double w = x2-x1;\n  double h = y2-y1;\n\n  // set invalid entries to 0 overlap\n  if(w<=0 || h<=0)\n    return 0;\n\n  // get overlapping areas\n  double inter = w*h;\n  double a_area = (a.x2-a.x1) * (a.y2-a.y1);\n  double b_area = (b.x2-b.x1) * (b.y2-b.y1);\n\n  // intersection over union overlap depending on users choice\n  if(criterion==-1)     // union\n    o = inter / (a_area+b_area-inter);\n  else if(criterion==0) // bbox_a\n    o = inter / a_area;\n  else if(criterion==1) // bbox_b\n    o = inter / b_area;\n\n  // overlap\n  return o;\n}\n\ninline double imageBoxOverlap(tDetection a, tGroundtruth b, int32_t criterion=-1){\n  return imageBoxOverlap(a.box, b.box, criterion);\n}\n\n// compute polygon of an oriented bounding box\ntemplate <typename T>\nPolygon toPolygon(const T& g) {\n    using namespace boost::numeric::ublas;\n    using namespace boost::geometry;\n    matrix<double> mref(2, 2);\n    mref(0, 0) = cos(g.ry); mref(0, 1) = sin(g.ry);\n    mref(1, 0) = -sin(g.ry); mref(1, 1) = cos(g.ry);\n\n    static int count = 0;\n    matrix<double> corners(2, 4);\n    double data[] = {g.l / 2, g.l / 2, -g.l / 2, -g.l / 2,\n                     g.w / 2, -g.w / 2, -g.w / 2, g.w / 2};\n    std::copy(data, data + 8, corners.data().begin());\n    matrix<double> gc = prod(mref, corners);\n    for (int i = 0; i < 4; ++i) {\n        gc(0, i) += g.t1;\n        gc(1, i) += g.t3;\n    }\n\n    double points[][2] = {{gc(0, 0), gc(1, 0)},{gc(0, 1), gc(1, 1)},{gc(0, 2), gc(1, 2)},{gc(0, 3), gc(1, 3)},{gc(0, 0), gc(1, 0)}};\n    Polygon poly;\n    append(poly, points);\n    return poly;\n}\n\n// measure overlap between bird's eye view bounding boxes, parametrized by (ry, l, w, tx, tz)\ninline double groundBoxOverlap(tDetection d, tGroundtruth g, int32_t criterion = -1) {\n    using namespace boost::geometry;\n    Polygon gp = toPolygon(g);\n    Polygon dp = toPolygon(d);\n\n    std::vector<Polygon> in, un;\n    intersection(gp, dp, in);\n    union_(gp, dp, un);\n\n    double inter_area = in.empty() ? 0 : area(in.front());\n    double union_area = area(un.front());\n    double o;\n    if(criterion==-1)     // union\n        o = inter_area / union_area;\n    else if(criterion==0) // bbox_a\n        o = inter_area / area(dp);\n    else if(criterion==1) // bbox_b\n        o = inter_area / area(gp);\n\n    return o;\n}\n\n// measure overlap between 3D bounding boxes, parametrized by (ry, h, w, l, tx, ty, tz)\ninline double box3DOverlap(tDetection d, tGroundtruth g, int32_t criterion = -1) {\n    using namespace boost::geometry;\n    Polygon gp = toPolygon(g);\n    Polygon dp = toPolygon(d);\n\n    std::vector<Polygon> in, un;\n    intersection(gp, dp, in);\n    union_(gp, dp, un);\n\n    double ymax = min(d.t2, g.t2);\n    double ymin = max(d.t2 - d.h, g.t2 - g.h);\n\n    double inter_area = in.empty() ? 0 : area(in.front());\n    double inter_vol = inter_area * max(0.0, ymax - ymin);\n\n    double det_vol = d.h * d.l * d.w;\n    double gt_vol = g.h * g.l * g.w;\n\n    double o;\n    if(criterion==-1)     // union\n        o = inter_vol / (det_vol + gt_vol - inter_vol);\n    else if(criterion==0) // bbox_a\n        o = inter_vol / det_vol;\n    else if(criterion==1) // bbox_b\n        o = inter_vol / gt_vol;\n\n    return o;\n}\n\nvector<double> getThresholds(vector<double> &v, double n_groundtruth){\n\n  // holds scores needed to compute N_SAMPLE_PTS recall values\n  vector<double> t;\n\n  // sort scores in descending order\n  // (highest score is assumed to give best/most confident detections)\n  sort(v.begin(), v.end(), greater<double>());\n\n  // get scores for linearly spaced recall\n  double current_recall = 0;\n  for(int32_t i=0; i<v.size(); i++){\n\n    // check if right-hand-side recall with respect to current recall is close than left-hand-side one\n    // in this case, skip the current detection score\n    double l_recall, r_recall, recall;\n    l_recall = (double)(i+1)/n_groundtruth;\n    if(i<(v.size()-1))\n      r_recall = (double)(i+2)/n_groundtruth;\n    else\n      r_recall = l_recall;\n\n    if( (r_recall-current_recall) < (current_recall-l_recall) && i<(v.size()-1))\n      continue;\n\n    // left recall is the best approximation, so use this and goto next recall step for approximation\n    recall = l_recall;\n\n    // the next recall step was reached\n    t.push_back(v[i]);\n    current_recall += 1.0/(N_SAMPLE_PTS-1.0);\n  }\n  return t;\n}\n\nvoid cleanData(CLASSES current_class, const vector<tGroundtruth> &gt, const vector<tDetection> &det, vector<int32_t> &ignored_gt, vector<tGroundtruth> &dc, vector<int32_t> &ignored_det, int32_t &n_gt, DIFFICULTY difficulty){\n\n  // extract ground truth bounding boxes for current evaluation class\n  for(int32_t i=0;i<gt.size(); i++){\n\n    // only bounding boxes with a minimum height are used for evaluation\n    double height = gt[i].box.y2 - gt[i].box.y1;\n\n    // neighboring classes are ignored (\"van\" for \"car\" and \"person_sitting\" for \"pedestrian\")\n    // (lower/upper cases are ignored)\n    int32_t valid_class;\n\n    // all classes without a neighboring class\n    if(!strcasecmp(gt[i].box.type.c_str(), CLASS_NAMES[current_class].c_str()))\n      valid_class = 1;\n\n    // classes with a neighboring class\n    else if(!strcasecmp(CLASS_NAMES[current_class].c_str(), \"Pedestrian\") && !strcasecmp(\"Person_sitting\", gt[i].box.type.c_str()))\n      valid_class = 0;\n    else if(!strcasecmp(CLASS_NAMES[current_class].c_str(), \"Car\") && !strcasecmp(\"Van\", gt[i].box.type.c_str()))\n      valid_class = 0;\n\n    // classes not used for evaluation\n    else\n      valid_class = -1;\n\n    // ground truth is ignored, if occlusion, truncation exceeds the difficulty or ground truth is too small\n    // (doesn't count as FN nor TP, although detections may be assigned)\n    bool ignore = false;\n    if(gt[i].occlusion>MAX_OCCLUSION[difficulty] || gt[i].truncation>MAX_TRUNCATION[difficulty] || height<MIN_HEIGHT[difficulty])\n      ignore = true;\n\n    // set ignored vector for ground truth\n    // current class and not ignored (total no. of ground truth is detected for recall denominator)\n    if(valid_class==1 && !ignore){\n      ignored_gt.push_back(0);\n      n_gt++;\n    }\n\n    // neighboring class, or current class but ignored\n    else if(valid_class==0 || (ignore && valid_class==1))\n      ignored_gt.push_back(1);\n\n    // all other classes which are FN in the evaluation\n    else\n      ignored_gt.push_back(-1);\n  }\n\n  // extract dontcare areas\n  for(int32_t i=0;i<gt.size(); i++)\n    if(!strcasecmp(\"DontCare\", gt[i].box.type.c_str()))\n      dc.push_back(gt[i]);\n\n  // extract detections bounding boxes of the current class\n  for(int32_t i=0;i<det.size(); i++){\n\n    // neighboring classes are not evaluated\n    int32_t valid_class;\n    if(!strcasecmp(det[i].box.type.c_str(), CLASS_NAMES[current_class].c_str()))\n      valid_class = 1;\n    else\n      valid_class = -1;\n\n    int32_t height = fabs(det[i].box.y1 - det[i].box.y2);\n    // set ignored vector for detections\n    if(height<MIN_HEIGHT[difficulty])\n      ignored_det.push_back(1);\n    else if(valid_class==1)\n      ignored_det.push_back(0);\n    else\n      ignored_det.push_back(-1);\n  }\n}\n\ntPrData computeStatistics(CLASSES current_class, const vector<tGroundtruth> &gt,\n        const vector<tDetection> &det, const vector<tGroundtruth> &dc,\n        const vector<int32_t> &ignored_gt, const vector<int32_t>  &ignored_det,\n        bool compute_fp, double (*boxoverlap)(tDetection, tGroundtruth, int32_t),\n        METRIC metric, bool compute_aos=false, double thresh=0, bool debug=false){\n\n  tPrData stat = tPrData();\n  const double NO_DETECTION = -10000000;\n  vector<double> delta;            // holds angular difference for TPs (needed for AOS evaluation)\n  vector<bool> assigned_detection; // holds wether a detection was assigned to a valid or ignored ground truth\n  assigned_detection.assign(det.size(), false);\n  vector<bool> ignored_threshold;\n  ignored_threshold.assign(det.size(), false); // holds detections with a threshold lower than thresh if FP are computed\n\n  // detections with a low score are ignored for computing precision (needs FP)\n  if(compute_fp)\n    for(int32_t i=0; i<det.size(); i++)\n      if(det[i].thresh<thresh)\n        ignored_threshold[i] = true;\n\n  // evaluate all ground truth boxes\n  for(int32_t i=0; i<gt.size(); i++){\n\n    // this ground truth is not of the current or a neighboring class and therefore ignored\n    if(ignored_gt[i]==-1)\n      continue;\n\n    /*=======================================================================\n    find candidates (overlap with ground truth > 0.5) (logical len(det))\n    =======================================================================*/\n    int32_t det_idx          = -1;\n    double valid_detection = NO_DETECTION;\n    double max_overlap     = 0;\n\n    // search for a possible detection\n    bool assigned_ignored_det = false;\n    for(int32_t j=0; j<det.size(); j++){\n\n      // detections not of the current class, already assigned or with a low threshold are ignored\n      if(ignored_det[j]==-1)\n        continue;\n      if(assigned_detection[j])\n        continue;\n      if(ignored_threshold[j])\n        continue;\n\n      // find the maximum score for the candidates and get idx of respective detection\n      double overlap = boxoverlap(det[j], gt[i], -1);\n\n      // for computing recall thresholds, the candidate with highest score is considered\n      if(!compute_fp && overlap>MIN_OVERLAP[metric][current_class] && det[j].thresh>valid_detection){\n        det_idx         = j;\n        valid_detection = det[j].thresh;\n      }\n\n      // for computing pr curve values, the candidate with the greatest overlap is considered\n      // if the greatest overlap is an ignored detection (min_height), the overlapping detection is used\n      else if(compute_fp && overlap>MIN_OVERLAP[metric][current_class] && (overlap>max_overlap || assigned_ignored_det) && ignored_det[j]==0){\n        max_overlap     = overlap;\n        det_idx         = j;\n        valid_detection = 1;\n        assigned_ignored_det = false;\n      }\n      else if(compute_fp && overlap>MIN_OVERLAP[metric][current_class] && valid_detection==NO_DETECTION && ignored_det[j]==1){\n        det_idx              = j;\n        valid_detection      = 1;\n        assigned_ignored_det = true;\n      }\n    }\n\n    /*=======================================================================\n    compute TP, FP and FN\n    =======================================================================*/\n\n    // nothing was assigned to this valid ground truth\n    if(valid_detection==NO_DETECTION && ignored_gt[i]==0) {\n      stat.fn++;\n    }\n\n    // only evaluate valid ground truth <=> detection assignments (considering difficulty level)\n    else if(valid_detection!=NO_DETECTION && (ignored_gt[i]==1 || ignored_det[det_idx]==1))\n      assigned_detection[det_idx] = true;\n\n    // found a valid true positive\n    else if(valid_detection!=NO_DETECTION){\n\n      // write highest score to threshold vector\n      stat.tp++;\n      stat.v.push_back(det[det_idx].thresh);\n\n      // compute angular difference of detection and ground truth if valid detection orientation was provided\n      if(compute_aos)\n        delta.push_back(gt[i].box.alpha - det[det_idx].box.alpha);\n\n      // clean up\n      assigned_detection[det_idx] = true;\n    }\n  }\n\n  // if FP are requested, consider stuff area\n  if(compute_fp){\n\n    // count fp\n    for(int32_t i=0; i<det.size(); i++){\n\n      // count false positives if required (height smaller than required is ignored (ignored_det==1)\n      if(!(assigned_detection[i] || ignored_det[i]==-1 || ignored_det[i]==1 || ignored_threshold[i]))\n        stat.fp++;\n    }\n\n    // do not consider detections overlapping with stuff area\n    int32_t nstuff = 0;\n    for(int32_t i=0; i<dc.size(); i++){\n      for(int32_t j=0; j<det.size(); j++){\n\n        // detections not of the current class, already assigned, with a low threshold or a low minimum height are ignored\n        if(assigned_detection[j])\n          continue;\n        if(ignored_det[j]==-1 || ignored_det[j]==1)\n          continue;\n        if(ignored_threshold[j])\n          continue;\n\n        // compute overlap and assign to stuff area, if overlap exceeds class specific value\n        double overlap = boxoverlap(det[j], dc[i], 0);\n        if(overlap>MIN_OVERLAP[metric][current_class]){\n          assigned_detection[j] = true;\n          nstuff++;\n        }\n      }\n    }\n\n    // FP = no. of all not to ground truth assigned detections - detections assigned to stuff areas\n    stat.fp -= nstuff;\n\n    // if all orientation values are valid, the AOS is computed\n    if(compute_aos){\n      vector<double> tmp;\n\n      // FP have a similarity of 0, for all TP compute AOS\n      tmp.assign(stat.fp, 0);\n      for(int32_t i=0; i<delta.size(); i++)\n        tmp.push_back((1.0+cos(delta[i]))/2.0);\n\n      // be sure, that all orientation deltas are computed\n      assert(tmp.size()==stat.fp+stat.tp);\n      assert(delta.size()==stat.tp);\n\n      // get the mean orientation similarity for this image\n      if(stat.tp>0 || stat.fp>0)\n        stat.similarity = accumulate(tmp.begin(), tmp.end(), 0.0);\n\n      // there was neither a FP nor a TP, so the similarity is ignored in the evaluation\n      else\n        stat.similarity = -1;\n    }\n  }\n  return stat;\n}\n\n/*=======================================================================\nEVALUATE CLASS-WISE\n=======================================================================*/\n\nbool eval_class (FILE *fp_det, FILE *fp_ori, CLASSES current_class,\n        const vector< vector<tGroundtruth> > &groundtruth,\n        const vector< vector<tDetection> > &detections, bool compute_aos,\n        double (*boxoverlap)(tDetection, tGroundtruth, int32_t),\n        vector<double> &precision, vector<double> &aos,\n        DIFFICULTY difficulty, METRIC metric) {\n    assert(groundtruth.size() == detections.size());\n\n  // init\n  int32_t n_gt=0;                                     // total no. of gt (denominator of recall)\n  vector<double> v, thresholds;                       // detection scores, evaluated for recall discretization\n  vector< vector<int32_t> > ignored_gt, ignored_det;  // index of ignored gt detection for current class/difficulty\n  vector< vector<tGroundtruth> > dontcare;            // index of dontcare areas, included in ground truth\n\n  // for all test images do\n  for (int32_t i=0; i<groundtruth.size(); i++){\n\n    // holds ignored ground truth, ignored detections and dontcare areas for current frame\n    vector<int32_t> i_gt, i_det;\n    vector<tGroundtruth> dc;\n\n    // only evaluate objects of current class and ignore occluded, truncated objects\n    cleanData(current_class, groundtruth[i], detections[i], i_gt, dc, i_det, n_gt, difficulty);\n    ignored_gt.push_back(i_gt);\n    ignored_det.push_back(i_det);\n    dontcare.push_back(dc);\n\n    // compute statistics to get recall values\n    tPrData pr_tmp = tPrData();\n    pr_tmp = computeStatistics(current_class, groundtruth[i], detections[i], dc, i_gt, i_det, false, boxoverlap, metric);\n\n    // add detection scores to vector over all images\n    for(int32_t j=0; j<pr_tmp.v.size(); j++)\n      v.push_back(pr_tmp.v[j]);\n  }\n\n  // get scores that must be evaluated for recall discretization\n  thresholds = getThresholds(v, n_gt);\n\n  // compute TP,FP,FN for relevant scores\n  vector<tPrData> pr;\n  pr.assign(thresholds.size(),tPrData());\n  for (int32_t i=0; i<groundtruth.size(); i++){\n\n    // for all scores/recall thresholds do:\n    for(int32_t t=0; t<thresholds.size(); t++){\n      tPrData tmp = tPrData();\n      tmp = computeStatistics(current_class, groundtruth[i], detections[i], dontcare[i],\n                              ignored_gt[i], ignored_det[i], true, boxoverlap, metric,\n                              compute_aos, thresholds[t], t==38);\n\n      // add no. of TP, FP, FN, AOS for current frame to total evaluation for current threshold\n      pr[t].tp += tmp.tp;\n      pr[t].fp += tmp.fp;\n      pr[t].fn += tmp.fn;\n      if(tmp.similarity!=-1)\n        pr[t].similarity += tmp.similarity;\n    }\n  }\n\n  // compute recall, precision and AOS\n  vector<double> recall;\n  precision.assign(N_SAMPLE_PTS, 0);\n  if(compute_aos)\n    aos.assign(N_SAMPLE_PTS, 0);\n  double r=0;\n  for (int32_t i=0; i<thresholds.size(); i++){\n    r = pr[i].tp/(double)(pr[i].tp + pr[i].fn);\n    recall.push_back(r);\n    precision[i] = pr[i].tp/(double)(pr[i].tp + pr[i].fp);\n    if(compute_aos)\n      aos[i] = pr[i].similarity/(double)(pr[i].tp + pr[i].fp);\n  }\n\n  // filter precision and AOS using max_{i..end}(precision)\n  for (int32_t i=0; i<thresholds.size(); i++){\n    precision[i] = *max_element(precision.begin()+i, precision.end());\n    if(compute_aos)\n      aos[i] = *max_element(aos.begin()+i, aos.end());\n  }\n\n  // save statisics and finish with success\n  saveStats(precision, aos, fp_det, fp_ori);\n    return true;\n}\n\nvoid saveAndPlotPlots(string dir_name,string file_name,string obj_type,vector<double> vals[],bool is_aos){\n\n  char command[1024];\n\n  // save plot data to file\n  FILE *fp = fopen((dir_name + \"/\" + file_name + \".txt\").c_str(),\"w\");\n  printf(\"save %s\\n\", (dir_name + \"/\" + file_name + \".txt\").c_str());\n  for (int32_t i=0; i<(int)N_SAMPLE_PTS; i++)\n    fprintf(fp,\"%f %f %f %f\\n\",(double)i/(N_SAMPLE_PTS-1.0),vals[0][i],vals[1][i],vals[2][i]);\n  fclose(fp);\n\n  // create png + eps\n  for (int32_t j=0; j<2; j++) {\n\n    // open file\n    FILE *fp = fopen((dir_name + \"/\" + file_name + \".gp\").c_str(),\"w\");\n\n    // save gnuplot instructions\n    if (j==0) {\n      fprintf(fp,\"set term png size 450,315 font \\\"Helvetica\\\" 11\\n\");\n      fprintf(fp,\"set output \\\"%s.png\\\"\\n\",file_name.c_str());\n    } else {\n      fprintf(fp,\"set term postscript eps enhanced color font \\\"Helvetica\\\" 20\\n\");\n      fprintf(fp,\"set output \\\"%s.eps\\\"\\n\",file_name.c_str());\n    }\n\n    // set labels and ranges\n    fprintf(fp,\"set size ratio 0.7\\n\");\n    fprintf(fp,\"set xrange [0:1]\\n\");\n    fprintf(fp,\"set yrange [0:1]\\n\");\n    fprintf(fp,\"set xlabel \\\"Recall\\\"\\n\");\n    if (!is_aos) fprintf(fp,\"set ylabel \\\"Precision\\\"\\n\");\n    else         fprintf(fp,\"set ylabel \\\"Orientation Similarity\\\"\\n\");\n    obj_type[0] = toupper(obj_type[0]);\n    fprintf(fp,\"set title \\\"%s\\\"\\n\",obj_type.c_str());\n\n    // line width\n    int32_t   lw = 5;\n    if (j==0) lw = 3;\n\n    // plot error curve\n    fprintf(fp,\"plot \");\n    fprintf(fp,\"\\\"%s.txt\\\" using 1:2 title 'Easy' with lines ls 1 lw %d,\",file_name.c_str(),lw);\n    fprintf(fp,\"\\\"%s.txt\\\" using 1:3 title 'Moderate' with lines ls 2 lw %d,\",file_name.c_str(),lw);\n    fprintf(fp,\"\\\"%s.txt\\\" using 1:4 title 'Hard' with lines ls 3 lw %d\",file_name.c_str(),lw);\n\n    // close file\n    fclose(fp);\n\n    // run gnuplot => create png + eps\n    sprintf(command,\"cd %s; gnuplot %s\",dir_name.c_str(),(file_name + \".gp\").c_str());\n    system(command);\n  }\n\n  // create pdf and crop\n  sprintf(command,\"cd %s; ps2pdf %s.eps %s_large.pdf\",dir_name.c_str(),file_name.c_str(),file_name.c_str());\n  system(command);\n  sprintf(command,\"cd %s; pdfcrop %s_large.pdf %s.pdf\",dir_name.c_str(),file_name.c_str(),file_name.c_str());\n  system(command);\n  sprintf(command,\"cd %s; rm %s_large.pdf\",dir_name.c_str(),file_name.c_str());\n  system(command);\n}\n\nbool eval(string result_sha,Mail* mail){\n\n  // set some global parameters\n  initGlobals();\n\n  // ground truth and result directories\n  string gt_dir         = \"data/object/label_2\";\n  string result_dir     = \"results/\" + result_sha;\n  string plot_dir       = result_dir + \"/plot\";\n\n  // create output directories\n  system((\"mkdir \" + plot_dir).c_str());\n\n  // hold detections and ground truth in memory\n  vector< vector<tGroundtruth> > groundtruth;\n  vector< vector<tDetection> >   detections;\n\n  // holds wether orientation similarity shall be computed (might be set to false while loading detections)\n  // and which labels where provided by this submission\n  bool compute_aos=true;\n  vector<bool> eval_image(NUM_CLASS, false);\n  vector<bool> eval_ground(NUM_CLASS, false);\n  vector<bool> eval_3d(NUM_CLASS, false);\n\n  // for all images read groundtruth and detections\n  mail->msg(\"Loading detections...\");\n  for (int32_t i=0; i<N_TESTIMAGES; i++) {\n\n    // file name\n    char file_name[256];\n    sprintf(file_name,\"%06d.txt\",indices.at(i));\n\n    // read ground truth and result poses\n    bool gt_success,det_success;\n    vector<tGroundtruth> gt   = loadGroundtruth(gt_dir + \"/\" + file_name,gt_success);\n    vector<tDetection>   det  = loadDetections(result_dir + \"/data/\" + file_name,\n            compute_aos, eval_image, eval_ground, eval_3d, det_success);\n    groundtruth.push_back(gt);\n    detections.push_back(det);\n\n    // check for errors\n    if (!gt_success) {\n      mail->msg(\"ERROR: Couldn't read: %s of ground truth. Please write me an email!\", file_name);\n      return false;\n    }\n    if (!det_success) {\n      mail->msg(\"ERROR: Couldn't read: %s\", file_name);\n      return false;\n    }\n  }\n  mail->msg(\"  done.\");\n\n  // holds pointers for result files\n  FILE *fp_det=0, *fp_ori=0;\n\n  // eval image 2D bounding boxes\n  for (int c = 0; c < NUM_CLASS; c++) {\n    CLASSES cls = (CLASSES)c;\n    if (eval_image[c]) {\n      fp_det = fopen((result_dir + \"/stats_\" + CLASS_NAMES[c] + \"_detection.txt\").c_str(), \"w\");\n      if(compute_aos)\n        fp_ori = fopen((result_dir + \"/stats_\" + CLASS_NAMES[c] + \"_orientation.txt\").c_str(),\"w\");\n      vector<double> precision[3], aos[3];\n      if(   !eval_class(fp_det, fp_ori, cls, groundtruth, detections, compute_aos, imageBoxOverlap, precision[0], aos[0], EASY, IMAGE)\n         || !eval_class(fp_det, fp_ori, cls, groundtruth, detections, compute_aos, imageBoxOverlap, precision[1], aos[1], MODERATE, IMAGE)\n         || !eval_class(fp_det, fp_ori, cls, groundtruth, detections, compute_aos, imageBoxOverlap, precision[2], aos[2], HARD, IMAGE)) {\n        mail->msg(\"%s evaluation failed.\", CLASS_NAMES[c].c_str());\n        return false;\n      }\n      fclose(fp_det);\n      saveAndPlotPlots(plot_dir, CLASS_NAMES[c] + \"_detection\", CLASS_NAMES[c], precision, 0);\n      if(compute_aos){\n        saveAndPlotPlots(plot_dir, CLASS_NAMES[c] + \"_orientation\", CLASS_NAMES[c], aos, 1);\n        fclose(fp_ori);\n      }\n    }\n  }\n\n  // don't evaluate AOS for birdview boxes and 3D boxes\n  compute_aos = false;\n\n  // eval bird's eye view bounding boxes\n  for (int c = 0; c < NUM_CLASS; c++) {\n    CLASSES cls = (CLASSES)c;\n    if (eval_ground[c]) {\n      fp_det = fopen((result_dir + \"/stats_\" + CLASS_NAMES[c] + \"_detection_ground.txt\").c_str(), \"w\");\n      vector<double> precision[3], aos[3];\n      if(   !eval_class(fp_det, fp_ori, cls, groundtruth, detections, compute_aos, groundBoxOverlap, precision[0], aos[0], EASY, GROUND)\n         || !eval_class(fp_det, fp_ori, cls, groundtruth, detections, compute_aos, groundBoxOverlap, precision[1], aos[1], MODERATE, GROUND)\n         || !eval_class(fp_det, fp_ori, cls, groundtruth, detections, compute_aos, groundBoxOverlap, precision[2], aos[2], HARD, GROUND)) {\n        mail->msg(\"%s evaluation failed.\", CLASS_NAMES[c].c_str());\n        return false;\n      }\n      fclose(fp_det);\n      saveAndPlotPlots(plot_dir, CLASS_NAMES[c] + \"_detection_ground\", CLASS_NAMES[c], precision, 0);\n    }\n  }\n\n  // eval 3D bounding boxes\n  for (int c = 0; c < NUM_CLASS; c++) {\n    CLASSES cls = (CLASSES)c;\n    if (eval_3d[c]) {\n      fp_det = fopen((result_dir + \"/stats_\" + CLASS_NAMES[c] + \"_detection_3d.txt\").c_str(), \"w\");\n      vector<double> precision[3], aos[3];\n      if(   !eval_class(fp_det, fp_ori, cls, groundtruth, detections, compute_aos, box3DOverlap, precision[0], aos[0], EASY, BOX3D)\n         || !eval_class(fp_det, fp_ori, cls, groundtruth, detections, compute_aos, box3DOverlap, precision[1], aos[1], MODERATE, BOX3D)\n         || !eval_class(fp_det, fp_ori, cls, groundtruth, detections, compute_aos, box3DOverlap, precision[2], aos[2], HARD, BOX3D)) {\n        mail->msg(\"%s evaluation failed.\", CLASS_NAMES[c].c_str());\n        return false;\n      }\n      fclose(fp_det);\n      saveAndPlotPlots(plot_dir, CLASS_NAMES[c] + \"_detection_3d\", CLASS_NAMES[c], precision, 0);\n    }\n  }\n\n  // success\n  return true;\n}\n\nint32_t main (int32_t argc,char *argv[]) {\n\n  // we need 2 or 4 arguments!\n  if (argc!=2 && argc!=4) {\n    cout << \"Usage: ./eval_detection result_sha [user_sha email]\" << endl;\n    return 1;\n  }\n\n  // read arguments\n  string result_sha = argv[1];\n\n  // init notification mail\n  Mail *mail;\n  if (argc==4) mail = new Mail(argv[3]);\n  else         mail = new Mail();\n  mail->msg(\"Thank you for participating in our evaluation!\");\n\n  // run evaluation\n  if (eval(result_sha,mail)) {\n    mail->msg(\"Your evaluation results are available at:\");\n    mail->msg(\"http://www.cvlibs.net/datasets/kitti/user_submit_check_login.php?benchmark=object&user=%s&result=%s\",argv[2], result_sha.c_str());\n  } else {\n    system((\"rm -r results/\" + result_sha).c_str());\n    mail->msg(\"An error occured while processing your results.\");\n    mail->msg(\"Please make sure that the data in your zip archive has the right format!\");\n  }\n\n  // send mail and exit\n  delete mail;\n\n  return 0;\n}\n\n\n"
  },
  {
    "path": "src/tools/kitti_eval/evaluate_object_3d_offline.cpp",
    "content": "#include <iostream>\n#include <algorithm>\n#include <stdio.h>\n#include <math.h>\n#include <vector>\n#include <numeric>\n#include <strings.h>\n#include <assert.h>\n\n#include <dirent.h>\n\n#include <boost/numeric/ublas/matrix.hpp>\n#include <boost/numeric/ublas/io.hpp>\n\n#include <boost/geometry.hpp>\n#include <boost/geometry/geometries/point_xy.hpp>\n#include <boost/geometry/geometries/polygon.hpp>\n#include <boost/geometry/geometries/adapted/c_array.hpp>\n\n#include \"mail.h\"\n\nBOOST_GEOMETRY_REGISTER_C_ARRAY_CS(cs::cartesian)\n\ntypedef boost::geometry::model::polygon<boost::geometry::model::d2::point_xy<double> > Polygon;\n\n\nusing namespace std;\n\n/*=======================================================================\nSTATIC EVALUATION PARAMETERS\n=======================================================================*/\n\n// holds the number of test images on the server\nconst int32_t N_TESTIMAGES = 7518;\n\n// easy, moderate and hard evaluation level\nenum DIFFICULTY{EASY=0, MODERATE=1, HARD=2};\n\n// evaluation metrics: image, ground or 3D\nenum METRIC{IMAGE=0, GROUND=1, BOX3D=2};\n\n// evaluation parameter\nconst int32_t MIN_HEIGHT[3]     = {40, 25, 25};     // minimum height for evaluated groundtruth/detections\nconst int32_t MAX_OCCLUSION[3]  = {0, 1, 2};        // maximum occlusion level of the groundtruth used for evaluation\nconst double  MAX_TRUNCATION[3] = {0.15, 0.3, 0.5}; // maximum truncation level of the groundtruth used for evaluation\n\n// evaluated object classes\nenum CLASSES{CAR=0, PEDESTRIAN=1, CYCLIST=2};\nconst int NUM_CLASS = 3;\n\n// parameters varying per class\nvector<string> CLASS_NAMES;\n// the minimum overlap required for 2D evaluation on the image/ground plane and 3D evaluation\nconst double MIN_OVERLAP[3][3] = {{0.7, 0.5, 0.5}, {0.5, 0.25, 0.25}, {0.5, 0.25, 0.25}};\n// const double MIN_OVERLAP[3][3] = {{0.7, 0.5, 0.5}, {0.7, 0.5, 0.5}, {0.7, 0.5, 0.5}};\n\n// no. of recall steps that should be evaluated (discretized)\nconst double N_SAMPLE_PTS = 41;\n\n\n// initialize class names\nvoid initGlobals () {\n  CLASS_NAMES.push_back(\"car\");\n  CLASS_NAMES.push_back(\"pedestrian\");\n  CLASS_NAMES.push_back(\"cyclist\");\n}\n\n/*=======================================================================\nDATA TYPES FOR EVALUATION\n=======================================================================*/\n\n// holding data needed for precision-recall and precision-aos\nstruct tPrData {\n  vector<double> v;           // detection score for computing score thresholds\n  double         similarity;  // orientation similarity\n  int32_t        tp;          // true positives\n  int32_t        fp;          // false positives\n  int32_t        fn;          // false negatives\n  tPrData () :\n    similarity(0), tp(0), fp(0), fn(0) {}\n};\n\n// holding bounding boxes for ground truth and detections\nstruct tBox {\n  string  type;     // object type as car, pedestrian or cyclist,...\n  double   x1;      // left corner\n  double   y1;      // top corner\n  double   x2;      // right corner\n  double   y2;      // bottom corner\n  double   alpha;   // image orientation\n  tBox (string type, double x1,double y1,double x2,double y2,double alpha) :\n    type(type),x1(x1),y1(y1),x2(x2),y2(y2),alpha(alpha) {}\n};\n\n// holding ground truth data\nstruct tGroundtruth {\n  tBox    box;        // object type, box, orientation\n  double  truncation; // truncation 0..1\n  int32_t occlusion;  // occlusion 0,1,2 (non, partly, fully)\n  double ry;\n  double  t1, t2, t3;\n  double h, w, l;\n  tGroundtruth () :\n    box(tBox(\"invalild\",-1,-1,-1,-1,-10)),truncation(-1),occlusion(-1) {}\n  tGroundtruth (tBox box,double truncation,int32_t occlusion) :\n    box(box),truncation(truncation),occlusion(occlusion) {}\n  tGroundtruth (string type,double x1,double y1,double x2,double y2,double alpha,double truncation,int32_t occlusion) :\n    box(tBox(type,x1,y1,x2,y2,alpha)),truncation(truncation),occlusion(occlusion) {}\n};\n\n// holding detection data\nstruct tDetection {\n  tBox    box;    // object type, box, orientation\n  double  thresh; // detection score\n  double  ry;\n  double  t1, t2, t3;\n  double  h, w, l;\n  tDetection ():\n    box(tBox(\"invalid\",-1,-1,-1,-1,-10)),thresh(-1000) {}\n  tDetection (tBox box,double thresh) :\n    box(box),thresh(thresh) {}\n  tDetection (string type,double x1,double y1,double x2,double y2,double alpha,double thresh) :\n    box(tBox(type,x1,y1,x2,y2,alpha)),thresh(thresh) {}\n};\n\n\n/*=======================================================================\nFUNCTIONS TO LOAD DETECTION AND GROUND TRUTH DATA ONCE, SAVE RESULTS\n=======================================================================*/\nvector<int32_t> indices;\n\nvector<tDetection> loadDetections(string file_name, bool &compute_aos,\n        vector<bool> &eval_image, vector<bool> &eval_ground,\n        vector<bool> &eval_3d, bool &success) {\n\n  // holds all detections (ignored detections are indicated by an index vector\n  vector<tDetection> detections;\n  FILE *fp = fopen(file_name.c_str(),\"r\");\n  if (!fp) {\n    success = false;\n    return detections;\n  }\n  while (!feof(fp)) {\n    tDetection d;\n    double trash;\n    char str[255];\n    if (fscanf(fp, \"%s %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf\",\n                   str, &trash, &trash, &d.box.alpha, &d.box.x1, &d.box.y1,\n                   &d.box.x2, &d.box.y2, &d.h, &d.w, &d.l, &d.t1, &d.t2, &d.t3,\n                   &d.ry, &d.thresh)==16) {\n\n        // d.thresh = 1;\n      d.box.type = str;\n      detections.push_back(d);\n\n      // orientation=-10 is invalid, AOS is not evaluated if at least one orientation is invalid\n      if(d.box.alpha == -10)\n        compute_aos = false;\n\n      // a class is only evaluated if it is detected at least once\n      for (int c = 0; c < NUM_CLASS; c++) {\n        if (!strcasecmp(d.box.type.c_str(), CLASS_NAMES[c].c_str())) {\n          if (!eval_image[c] && d.box.x1 >= 0)\n            eval_image[c] = true;\n          if (!eval_ground[c] && d.t1 != -1000)\n            eval_ground[c] = true;\n          if (!eval_3d[c] && d.t2 != -1000)\n            eval_3d[c] = true;\n          break;\n        }\n      }\n    }\n  }\n  fclose(fp);\n  success = true;\n  return detections;\n}\n\nvector<tGroundtruth> loadGroundtruth(string file_name,bool &success) {\n\n  // holds all ground truth (ignored ground truth is indicated by an index vector\n  vector<tGroundtruth> groundtruth;\n  FILE *fp = fopen(file_name.c_str(),\"r\");\n  if (!fp) {\n    success = false;\n    return groundtruth;\n  }\n  while (!feof(fp)) {\n    tGroundtruth g;\n    char str[255];\n    if (fscanf(fp, \"%s %lf %d %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf\",\n                   str, &g.truncation, &g.occlusion, &g.box.alpha,\n                   &g.box.x1,   &g.box.y1,     &g.box.x2,    &g.box.y2,\n                   &g.h,      &g.w,        &g.l,       &g.t1,\n                   &g.t2,      &g.t3,        &g.ry )==15) {\n      g.box.type = str;\n      groundtruth.push_back(g);\n    }\n  }\n  fclose(fp);\n  success = true;\n  return groundtruth;\n}\n\nvoid saveStats (const vector<double> &precision, const vector<double> &aos, FILE *fp_det, FILE *fp_ori) {\n\n  // save precision to file\n  if(precision.empty())\n    return;\n  for (int32_t i=0; i<precision.size(); i++)\n    fprintf(fp_det,\"%f \",precision[i]);\n  fprintf(fp_det,\"\\n\");\n\n  // save orientation similarity, only if there were no invalid orientation entries in submission (alpha=-10)\n  if(aos.empty())\n    return;\n  for (int32_t i=0; i<aos.size(); i++)\n    fprintf(fp_ori,\"%f \",aos[i]);\n  fprintf(fp_ori,\"\\n\");\n}\n\n/*=======================================================================\nEVALUATION HELPER FUNCTIONS\n=======================================================================*/\n\n// criterion defines whether the overlap is computed with respect to both areas (ground truth and detection)\n// or with respect to box a or b (detection and \"dontcare\" areas)\ninline double imageBoxOverlap(tBox a, tBox b, int32_t criterion=-1){\n\n  // overlap is invalid in the beginning\n  double o = -1;\n\n  // get overlapping area\n  double x1 = max(a.x1, b.x1);\n  double y1 = max(a.y1, b.y1);\n  double x2 = min(a.x2, b.x2);\n  double y2 = min(a.y2, b.y2);\n\n  // compute width and height of overlapping area\n  double w = x2-x1;\n  double h = y2-y1;\n\n  // set invalid entries to 0 overlap\n  if(w<=0 || h<=0)\n    return 0;\n\n  // get overlapping areas\n  double inter = w*h;\n  double a_area = (a.x2-a.x1) * (a.y2-a.y1);\n  double b_area = (b.x2-b.x1) * (b.y2-b.y1);\n\n  // intersection over union overlap depending on users choice\n  if(criterion==-1)     // union\n    o = inter / (a_area+b_area-inter);\n  else if(criterion==0) // bbox_a\n    o = inter / a_area;\n  else if(criterion==1) // bbox_b\n    o = inter / b_area;\n\n  // overlap\n  return o;\n}\n\ninline double imageBoxOverlap(tDetection a, tGroundtruth b, int32_t criterion=-1){\n  return imageBoxOverlap(a.box, b.box, criterion);\n}\n\n// compute polygon of an oriented bounding box\ntemplate <typename T>\nPolygon toPolygon(const T& g) {\n    using namespace boost::numeric::ublas;\n    using namespace boost::geometry;\n    matrix<double> mref(2, 2);\n    mref(0, 0) = cos(g.ry); mref(0, 1) = sin(g.ry);\n    mref(1, 0) = -sin(g.ry); mref(1, 1) = cos(g.ry);\n\n    static int count = 0;\n    matrix<double> corners(2, 4);\n    double data[] = {g.l / 2, g.l / 2, -g.l / 2, -g.l / 2,\n                     g.w / 2, -g.w / 2, -g.w / 2, g.w / 2};\n    std::copy(data, data + 8, corners.data().begin());\n    matrix<double> gc = prod(mref, corners);\n    for (int i = 0; i < 4; ++i) {\n        gc(0, i) += g.t1;\n        gc(1, i) += g.t3;\n    }\n\n    double points[][2] = {{gc(0, 0), gc(1, 0)},{gc(0, 1), gc(1, 1)},{gc(0, 2), gc(1, 2)},{gc(0, 3), gc(1, 3)},{gc(0, 0), gc(1, 0)}};\n    Polygon poly;\n    append(poly, points);\n    return poly;\n}\n\n// measure overlap between bird's eye view bounding boxes, parametrized by (ry, l, w, tx, tz)\ninline double groundBoxOverlap(tDetection d, tGroundtruth g, int32_t criterion = -1) {\n    using namespace boost::geometry;\n    Polygon gp = toPolygon(g);\n    Polygon dp = toPolygon(d);\n\n    std::vector<Polygon> in, un;\n    intersection(gp, dp, in);\n    union_(gp, dp, un);\n\n    double inter_area = in.empty() ? 0 : area(in.front());\n    double union_area = area(un.front());\n    double o;\n    if(criterion==-1)     // union\n        o = inter_area / union_area;\n    else if(criterion==0) // bbox_a\n        o = inter_area / area(dp);\n    else if(criterion==1) // bbox_b\n        o = inter_area / area(gp);\n\n    return o;\n}\n\n// measure overlap between 3D bounding boxes, parametrized by (ry, h, w, l, tx, ty, tz)\ninline double box3DOverlap(tDetection d, tGroundtruth g, int32_t criterion = -1) {\n    using namespace boost::geometry;\n    Polygon gp = toPolygon(g);\n    Polygon dp = toPolygon(d);\n\n    std::vector<Polygon> in, un;\n    intersection(gp, dp, in);\n    union_(gp, dp, un);\n\n    double ymax = min(d.t2, g.t2);\n    double ymin = max(d.t2 - d.h, g.t2 - g.h);\n\n    double inter_area = in.empty() ? 0 : area(in.front());\n    double inter_vol = inter_area * max(0.0, ymax - ymin);\n\n    double det_vol = d.h * d.l * d.w;\n    double gt_vol = g.h * g.l * g.w;\n\n    double o;\n    if(criterion==-1)     // union\n        o = inter_vol / (det_vol + gt_vol - inter_vol);\n    else if(criterion==0) // bbox_a\n        o = inter_vol / det_vol;\n    else if(criterion==1) // bbox_b\n        o = inter_vol / gt_vol;\n\n    return o;\n}\n\nvector<double> getThresholds(vector<double> &v, double n_groundtruth){\n\n  // holds scores needed to compute N_SAMPLE_PTS recall values\n  vector<double> t;\n\n  // sort scores in descending order\n  // (highest score is assumed to give best/most confident detections)\n  sort(v.begin(), v.end(), greater<double>());\n\n  // get scores for linearly spaced recall\n  double current_recall = 0;\n  for(int32_t i=0; i<v.size(); i++){\n\n    // check if right-hand-side recall with respect to current recall is close than left-hand-side one\n    // in this case, skip the current detection score\n    double l_recall, r_recall, recall;\n    l_recall = (double)(i+1)/n_groundtruth;\n    if(i<(v.size()-1))\n      r_recall = (double)(i+2)/n_groundtruth;\n    else\n      r_recall = l_recall;\n\n    if( (r_recall-current_recall) < (current_recall-l_recall) && i<(v.size()-1))\n      continue;\n\n    // left recall is the best approximation, so use this and goto next recall step for approximation\n    recall = l_recall;\n\n    // the next recall step was reached\n    t.push_back(v[i]);\n    current_recall += 1.0/(N_SAMPLE_PTS-1.0);\n  }\n  return t;\n}\n\nvoid cleanData(CLASSES current_class, const vector<tGroundtruth> &gt, const vector<tDetection> &det, vector<int32_t> &ignored_gt, vector<tGroundtruth> &dc, vector<int32_t> &ignored_det, int32_t &n_gt, DIFFICULTY difficulty){\n\n  // extract ground truth bounding boxes for current evaluation class\n  for(int32_t i=0;i<gt.size(); i++){\n\n    // only bounding boxes with a minimum height are used for evaluation\n    double height = gt[i].box.y2 - gt[i].box.y1;\n\n    // neighboring classes are ignored (\"van\" for \"car\" and \"person_sitting\" for \"pedestrian\")\n    // (lower/upper cases are ignored)\n    int32_t valid_class;\n\n    // all classes without a neighboring class\n    if(!strcasecmp(gt[i].box.type.c_str(), CLASS_NAMES[current_class].c_str()))\n      valid_class = 1;\n\n    // classes with a neighboring class\n    else if(!strcasecmp(CLASS_NAMES[current_class].c_str(), \"Pedestrian\") && !strcasecmp(\"Person_sitting\", gt[i].box.type.c_str()))\n      valid_class = 0;\n    else if(!strcasecmp(CLASS_NAMES[current_class].c_str(), \"Car\") && !strcasecmp(\"Van\", gt[i].box.type.c_str()))\n      valid_class = 0;\n\n    // classes not used for evaluation\n    else\n      valid_class = -1;\n\n    // ground truth is ignored, if occlusion, truncation exceeds the difficulty or ground truth is too small\n    // (doesn't count as FN nor TP, although detections may be assigned)\n    bool ignore = false;\n    if(gt[i].occlusion>MAX_OCCLUSION[difficulty] || gt[i].truncation>MAX_TRUNCATION[difficulty] || height<MIN_HEIGHT[difficulty])\n      ignore = true;\n\n    // set ignored vector for ground truth\n    // current class and not ignored (total no. of ground truth is detected for recall denominator)\n    if(valid_class==1 && !ignore){\n      ignored_gt.push_back(0);\n      n_gt++;\n    }\n\n    // neighboring class, or current class but ignored\n    else if(valid_class==0 || (ignore && valid_class==1))\n      ignored_gt.push_back(1);\n\n    // all other classes which are FN in the evaluation\n    else\n      ignored_gt.push_back(-1);\n  }\n\n  // extract dontcare areas\n  for(int32_t i=0;i<gt.size(); i++)\n    if(!strcasecmp(\"DontCare\", gt[i].box.type.c_str()))\n      dc.push_back(gt[i]);\n\n  // extract detections bounding boxes of the current class\n  for(int32_t i=0;i<det.size(); i++){\n\n    // neighboring classes are not evaluated\n    int32_t valid_class;\n    if(!strcasecmp(det[i].box.type.c_str(), CLASS_NAMES[current_class].c_str()))\n      valid_class = 1;\n    else\n      valid_class = -1;\n\n    int32_t height = fabs(det[i].box.y1 - det[i].box.y2);\n\n    // set ignored vector for detections\n    if(height<MIN_HEIGHT[difficulty])\n      ignored_det.push_back(1);\n    else if(valid_class==1)\n      ignored_det.push_back(0);\n    else\n      ignored_det.push_back(-1);\n  }\n}\n\ntPrData computeStatistics(CLASSES current_class, const vector<tGroundtruth> &gt,\n        const vector<tDetection> &det, const vector<tGroundtruth> &dc,\n        const vector<int32_t> &ignored_gt, const vector<int32_t>  &ignored_det,\n        bool compute_fp, double (*boxoverlap)(tDetection, tGroundtruth, int32_t),\n        METRIC metric, bool compute_aos=false, double thresh=0, bool debug=false){\n\n  tPrData stat = tPrData();\n  const double NO_DETECTION = -10000000;\n  vector<double> delta;            // holds angular difference for TPs (needed for AOS evaluation)\n  vector<bool> assigned_detection; // holds wether a detection was assigned to a valid or ignored ground truth\n  assigned_detection.assign(det.size(), false);\n  vector<bool> ignored_threshold;\n  ignored_threshold.assign(det.size(), false); // holds detections with a threshold lower than thresh if FP are computed\n\n  // detections with a low score are ignored for computing precision (needs FP)\n  if(compute_fp)\n    for(int32_t i=0; i<det.size(); i++)\n      if(det[i].thresh<thresh)\n        ignored_threshold[i] = true;\n\n  // evaluate all ground truth boxes\n  for(int32_t i=0; i<gt.size(); i++){\n\n    // this ground truth is not of the current or a neighboring class and therefore ignored\n    if(ignored_gt[i]==-1)\n      continue;\n\n    /*=======================================================================\n    find candidates (overlap with ground truth > 0.5) (logical len(det))\n    =======================================================================*/\n    int32_t det_idx          = -1;\n    double valid_detection = NO_DETECTION;\n    double max_overlap     = 0;\n\n    // search for a possible detection\n    bool assigned_ignored_det = false;\n    for(int32_t j=0; j<det.size(); j++){\n\n      // detections not of the current class, already assigned or with a low threshold are ignored\n      if(ignored_det[j]==-1)\n        continue;\n      if(assigned_detection[j])\n        continue;\n      if(ignored_threshold[j])\n        continue;\n\n      // find the maximum score for the candidates and get idx of respective detection\n      double overlap = boxoverlap(det[j], gt[i], -1);\n\n      // for computing recall thresholds, the candidate with highest score is considered\n      if(!compute_fp && overlap>MIN_OVERLAP[metric][current_class] && det[j].thresh>valid_detection){\n        det_idx         = j;\n        valid_detection = det[j].thresh;\n      }\n\n      // for computing pr curve values, the candidate with the greatest overlap is considered\n      // if the greatest overlap is an ignored detection (min_height), the overlapping detection is used\n      else if(compute_fp && overlap>MIN_OVERLAP[metric][current_class] && (overlap>max_overlap || assigned_ignored_det) && ignored_det[j]==0){\n        max_overlap     = overlap;\n        det_idx         = j;\n        valid_detection = 1;\n        assigned_ignored_det = false;\n      }\n      else if(compute_fp && overlap>MIN_OVERLAP[metric][current_class] && valid_detection==NO_DETECTION && ignored_det[j]==1){\n        det_idx              = j;\n        valid_detection      = 1;\n        assigned_ignored_det = true;\n      }\n    }\n\n    /*=======================================================================\n    compute TP, FP and FN\n    =======================================================================*/\n\n    // nothing was assigned to this valid ground truth\n    if(valid_detection==NO_DETECTION && ignored_gt[i]==0) {\n      stat.fn++;\n    }\n\n    // only evaluate valid ground truth <=> detection assignments (considering difficulty level)\n    else if(valid_detection!=NO_DETECTION && (ignored_gt[i]==1 || ignored_det[det_idx]==1))\n      assigned_detection[det_idx] = true;\n\n    // found a valid true positive\n    else if(valid_detection!=NO_DETECTION){\n\n      // write highest score to threshold vector\n      stat.tp++;\n      stat.v.push_back(det[det_idx].thresh);\n\n      // compute angular difference of detection and ground truth if valid detection orientation was provided\n      if(compute_aos)\n        delta.push_back(gt[i].box.alpha - det[det_idx].box.alpha);\n\n      // clean up\n      assigned_detection[det_idx] = true;\n    }\n  }\n\n  // if FP are requested, consider stuff area\n  if(compute_fp){\n\n    // count fp\n    for(int32_t i=0; i<det.size(); i++){\n\n      // count false positives if required (height smaller than required is ignored (ignored_det==1)\n      if(!(assigned_detection[i] || ignored_det[i]==-1 || ignored_det[i]==1 || ignored_threshold[i]))\n        stat.fp++;\n    }\n\n    // do not consider detections overlapping with stuff area\n    int32_t nstuff = 0;\n    for(int32_t i=0; i<dc.size(); i++){\n      for(int32_t j=0; j<det.size(); j++){\n\n        // detections not of the current class, already assigned, with a low threshold or a low minimum height are ignored\n        if(assigned_detection[j])\n          continue;\n        if(ignored_det[j]==-1 || ignored_det[j]==1)\n          continue;\n        if(ignored_threshold[j])\n          continue;\n\n        // compute overlap and assign to stuff area, if overlap exceeds class specific value\n        double overlap = boxoverlap(det[j], dc[i], 0);\n        if(overlap>MIN_OVERLAP[metric][current_class]){\n          assigned_detection[j] = true;\n          nstuff++;\n        }\n      }\n    }\n\n    // FP = no. of all not to ground truth assigned detections - detections assigned to stuff areas\n    stat.fp -= nstuff;\n\n    // if all orientation values are valid, the AOS is computed\n    if(compute_aos){\n      vector<double> tmp;\n\n      // FP have a similarity of 0, for all TP compute AOS\n      tmp.assign(stat.fp, 0);\n      for(int32_t i=0; i<delta.size(); i++)\n        tmp.push_back((1.0+cos(delta[i]))/2.0);\n\n      // be sure, that all orientation deltas are computed\n      assert(tmp.size()==stat.fp+stat.tp);\n      assert(delta.size()==stat.tp);\n\n      // get the mean orientation similarity for this image\n      if(stat.tp>0 || stat.fp>0)\n        stat.similarity = accumulate(tmp.begin(), tmp.end(), 0.0);\n\n      // there was neither a FP nor a TP, so the similarity is ignored in the evaluation\n      else\n        stat.similarity = -1;\n    }\n  }\n  return stat;\n}\n\n/*=======================================================================\nEVALUATE CLASS-WISE\n=======================================================================*/\n\nbool eval_class (FILE *fp_det, FILE *fp_ori, CLASSES current_class,\n        const vector< vector<tGroundtruth> > &groundtruth,\n        const vector< vector<tDetection> > &detections, bool compute_aos,\n        double (*boxoverlap)(tDetection, tGroundtruth, int32_t),\n        vector<double> &precision, vector<double> &aos,\n        DIFFICULTY difficulty, METRIC metric) {\n    assert(groundtruth.size() == detections.size());\n\n  // init\n  int32_t n_gt=0;                                     // total no. of gt (denominator of recall)\n  vector<double> v, thresholds;                       // detection scores, evaluated for recall discretization\n  vector< vector<int32_t> > ignored_gt, ignored_det;  // index of ignored gt detection for current class/difficulty\n  vector< vector<tGroundtruth> > dontcare;            // index of dontcare areas, included in ground truth\n\n  // for all test images do\n  for (int32_t i=0; i<groundtruth.size(); i++){\n\n    // holds ignored ground truth, ignored detections and dontcare areas for current frame\n    vector<int32_t> i_gt, i_det;\n    vector<tGroundtruth> dc;\n\n    // only evaluate objects of current class and ignore occluded, truncated objects\n    cleanData(current_class, groundtruth[i], detections[i], i_gt, dc, i_det, n_gt, difficulty);\n    ignored_gt.push_back(i_gt);\n    ignored_det.push_back(i_det);\n    dontcare.push_back(dc);\n\n    // compute statistics to get recall values\n    tPrData pr_tmp = tPrData();\n    pr_tmp = computeStatistics(current_class, groundtruth[i], detections[i], dc, i_gt, i_det, false, boxoverlap, metric);\n\n    // add detection scores to vector over all images\n    for(int32_t j=0; j<pr_tmp.v.size(); j++)\n      v.push_back(pr_tmp.v[j]);\n  }\n\n  // get scores that must be evaluated for recall discretization\n  thresholds = getThresholds(v, n_gt);\n\n  // compute TP,FP,FN for relevant scores\n  vector<tPrData> pr;\n  pr.assign(thresholds.size(),tPrData());\n  for (int32_t i=0; i<groundtruth.size(); i++){\n\n    // for all scores/recall thresholds do:\n    for(int32_t t=0; t<thresholds.size(); t++){\n      tPrData tmp = tPrData();\n      tmp = computeStatistics(current_class, groundtruth[i], detections[i], dontcare[i],\n                              ignored_gt[i], ignored_det[i], true, boxoverlap, metric,\n                              compute_aos, thresholds[t], t==38);\n\n      // add no. of TP, FP, FN, AOS for current frame to total evaluation for current threshold\n      pr[t].tp += tmp.tp;\n      pr[t].fp += tmp.fp;\n      pr[t].fn += tmp.fn;\n      if(tmp.similarity!=-1)\n        pr[t].similarity += tmp.similarity;\n    }\n  }\n\n  // compute recall, precision and AOS\n  vector<double> recall;\n  precision.assign(N_SAMPLE_PTS, 0);\n  if(compute_aos)\n    aos.assign(N_SAMPLE_PTS, 0);\n  double r=0;\n  for (int32_t i=0; i<thresholds.size(); i++){\n    r = pr[i].tp/(double)(pr[i].tp + pr[i].fn);\n    recall.push_back(r);\n    precision[i] = pr[i].tp/(double)(pr[i].tp + pr[i].fp);\n    if(compute_aos)\n      aos[i] = pr[i].similarity/(double)(pr[i].tp + pr[i].fp);\n  }\n\n  // filter precision and AOS using max_{i..end}(precision)\n  for (int32_t i=0; i<thresholds.size(); i++){\n    precision[i] = *max_element(precision.begin()+i, precision.end());\n    if(compute_aos)\n      aos[i] = *max_element(aos.begin()+i, aos.end());\n  }\n\n  // save statisics and finish with success\n  saveStats(precision, aos, fp_det, fp_ori);\n    return true;\n}\n\nvoid saveAndPlotPlots(string dir_name,string file_name,string obj_type,vector<double> vals[],bool is_aos){\n\n  char command[1024];\n\n  // save plot data to file\n  FILE *fp = fopen((dir_name + \"/\" + file_name + \".txt\").c_str(),\"w\");\n  printf(\"save %s\\n\", (dir_name + \"/\" + file_name + \".txt\").c_str());\n  for (int32_t i=0; i<(int)N_SAMPLE_PTS; i++)\n    fprintf(fp,\"%f %f %f %f\\n\",(double)i/(N_SAMPLE_PTS-1.0),vals[0][i],vals[1][i],vals[2][i]);\n  fclose(fp);\n\n  float sum[3] = {0, 0, 0};\n  for (int v = 0; v < 3; ++v)\n      for (int i = 0; i < vals[v].size(); i = i + 4)\n          sum[v] += vals[v][i];\n  printf(\"%s AP: %f %f %f\\n\", file_name.c_str(), sum[0] / 11 * 100, sum[1] / 11 * 100, sum[2] / 11 * 100);\n\n\n  // create png + eps\n  for (int32_t j=0; j<2; j++) {\n\n    // open file\n    FILE *fp = fopen((dir_name + \"/\" + file_name + \".gp\").c_str(),\"w\");\n\n    // save gnuplot instructions\n    if (j==0) {\n      fprintf(fp,\"set term png size 450,315 font \\\"Helvetica\\\" 11\\n\");\n      fprintf(fp,\"set output \\\"%s.png\\\"\\n\",file_name.c_str());\n    } else {\n      fprintf(fp,\"set term postscript eps enhanced color font \\\"Helvetica\\\" 20\\n\");\n      fprintf(fp,\"set output \\\"%s.eps\\\"\\n\",file_name.c_str());\n    }\n\n    // set labels and ranges\n    fprintf(fp,\"set size ratio 0.7\\n\");\n    fprintf(fp,\"set xrange [0:1]\\n\");\n    fprintf(fp,\"set yrange [0:1]\\n\");\n    fprintf(fp,\"set xlabel \\\"Recall\\\"\\n\");\n    if (!is_aos) fprintf(fp,\"set ylabel \\\"Precision\\\"\\n\");\n    else         fprintf(fp,\"set ylabel \\\"Orientation Similarity\\\"\\n\");\n    obj_type[0] = toupper(obj_type[0]);\n    fprintf(fp,\"set title \\\"%s\\\"\\n\",obj_type.c_str());\n\n    // line width\n    int32_t   lw = 5;\n    if (j==0) lw = 3;\n\n    // plot error curve\n    fprintf(fp,\"plot \");\n    fprintf(fp,\"\\\"%s.txt\\\" using 1:2 title 'Easy' with lines ls 1 lw %d,\",file_name.c_str(),lw);\n    fprintf(fp,\"\\\"%s.txt\\\" using 1:3 title 'Moderate' with lines ls 2 lw %d,\",file_name.c_str(),lw);\n    fprintf(fp,\"\\\"%s.txt\\\" using 1:4 title 'Hard' with lines ls 3 lw %d\",file_name.c_str(),lw);\n\n    // close file\n    fclose(fp);\n\n    // run gnuplot => create png + eps\n    sprintf(command,\"cd %s; gnuplot %s\",dir_name.c_str(),(file_name + \".gp\").c_str());\n    system(command);\n  }\n\n  // create pdf and crop\n  sprintf(command,\"cd %s; ps2pdf %s.eps %s_large.pdf\",dir_name.c_str(),file_name.c_str(),file_name.c_str());\n  system(command);\n  sprintf(command,\"cd %s; pdfcrop %s_large.pdf %s.pdf\",dir_name.c_str(),file_name.c_str(),file_name.c_str());\n  system(command);\n  sprintf(command,\"cd %s; rm %s_large.pdf\",dir_name.c_str(),file_name.c_str());\n  system(command);\n}\n\nvector<int32_t> getEvalIndices(const string& result_dir) {\n\n    DIR* dir;\n    dirent* entity;\n    dir = opendir(result_dir.c_str());\n    if (dir) {\n        while (entity = readdir(dir)) {\n            string path(entity->d_name);\n            int32_t len = path.size();\n            if (len < 10) continue;\n            int32_t index = atoi(path.substr(len - 10, 10).c_str());\n            indices.push_back(index);\n        }\n    }\n    return indices;\n}\n\nbool eval(string gt_dir, string result_dir, Mail* mail){\n\n  // set some global parameters\n  initGlobals();\n\n  // ground truth and result directories\n  // string gt_dir         = \"data/object/label_2\";\n  // string result_dir     = \"results/\" + result_sha;\n  string plot_dir       = result_dir + \"/../plot\";\n\n  // create output directories\n  system((\"mkdir \" + plot_dir).c_str());\n\n  // hold detections and ground truth in memory\n  vector< vector<tGroundtruth> > groundtruth;\n  vector< vector<tDetection> >   detections;\n\n  // holds wether orientation similarity shall be computed (might be set to false while loading detections)\n  // and which labels where provided by this submission\n  bool compute_aos=true;\n  vector<bool> eval_image(NUM_CLASS, false);\n  vector<bool> eval_ground(NUM_CLASS, false);\n  vector<bool> eval_3d(NUM_CLASS, false);\n\n  // for all images read groundtruth and detections\n  mail->msg(\"Loading detections...\");\n  std::vector<int32_t> indices = getEvalIndices(result_dir);\n  printf(\"number of files for evaluation: %d\\n\", (int)indices.size());\n\n  for (int32_t i=0; i<indices.size(); i++) {\n\n    // file name\n    char file_name[256];\n    sprintf(file_name,\"%06d.txt\",indices.at(i));\n\n    // read ground truth and result poses\n    bool gt_success,det_success;\n    vector<tGroundtruth> gt   = loadGroundtruth(gt_dir + \"/\" + file_name,gt_success);\n    vector<tDetection>   det  = loadDetections(result_dir + file_name,\n            compute_aos, eval_image, eval_ground, eval_3d, det_success);\n    groundtruth.push_back(gt);\n    detections.push_back(det);\n\n    // check for errors\n    if (!gt_success) {\n      mail->msg(\"ERROR: Couldn't read: %s of ground truth. Please write me an email!\", file_name);\n      return false;\n    }\n    if (!det_success) {\n      mail->msg(\"ERROR: Couldn't read: %s\", file_name);\n      return false;\n    }\n  }\n  mail->msg(\"  done.\");\n\n  // holds pointers for result files\n  FILE *fp_det=0, *fp_ori=0;\n\n  // eval image 2D bounding boxes\n  for (int c = 0; c < NUM_CLASS; c++) {\n    CLASSES cls = (CLASSES)c;\n    if (eval_image[c]) {\n      fp_det = fopen((result_dir + \"/../stats_\" + CLASS_NAMES[c] + \"_detection.txt\").c_str(), \"w\");\n      if(compute_aos)\n        fp_ori = fopen((result_dir + \"/../stats_\" + CLASS_NAMES[c] + \"_orientation.txt\").c_str(),\"w\");\n      vector<double> precision[3], aos[3];\n      if(   !eval_class(fp_det, fp_ori, cls, groundtruth, detections, compute_aos, imageBoxOverlap, precision[0], aos[0], EASY, IMAGE)\n         || !eval_class(fp_det, fp_ori, cls, groundtruth, detections, compute_aos, imageBoxOverlap, precision[1], aos[1], MODERATE, IMAGE)\n         || !eval_class(fp_det, fp_ori, cls, groundtruth, detections, compute_aos, imageBoxOverlap, precision[2], aos[2], HARD, IMAGE)) {\n        mail->msg(\"%s evaluation failed.\", CLASS_NAMES[c].c_str());\n        return false;\n      }\n      fclose(fp_det);\n      saveAndPlotPlots(plot_dir, CLASS_NAMES[c] + \"_detection\", CLASS_NAMES[c], precision, 0);\n      if(compute_aos){\n        saveAndPlotPlots(plot_dir, CLASS_NAMES[c] + \"_orientation\", CLASS_NAMES[c], aos, 1);\n        fclose(fp_ori);\n      }\n    }\n  }\n\n  // don't evaluate AOS for birdview boxes and 3D boxes\n  compute_aos = false;\n\n  // eval bird's eye view bounding boxes\n  for (int c = 0; c < NUM_CLASS; c++) {\n    CLASSES cls = (CLASSES)c;\n    if (eval_ground[c]) {\n      fp_det = fopen((result_dir + \"/../stats_\" + CLASS_NAMES[c] + \"_detection_ground.txt\").c_str(), \"w\");\n      vector<double> precision[3], aos[3];\n      if(   !eval_class(fp_det, fp_ori, cls, groundtruth, detections, compute_aos, groundBoxOverlap, precision[0], aos[0], EASY, GROUND)\n         || !eval_class(fp_det, fp_ori, cls, groundtruth, detections, compute_aos, groundBoxOverlap, precision[1], aos[1], MODERATE, GROUND)\n         || !eval_class(fp_det, fp_ori, cls, groundtruth, detections, compute_aos, groundBoxOverlap, precision[2], aos[2], HARD, GROUND)) {\n        mail->msg(\"%s evaluation failed.\", CLASS_NAMES[c].c_str());\n        return false;\n      }\n      fclose(fp_det);\n      saveAndPlotPlots(plot_dir, CLASS_NAMES[c] + \"_detection_ground\", CLASS_NAMES[c], precision, 0);\n    }\n  }\n\n  // eval 3D bounding boxes\n  for (int c = 0; c < NUM_CLASS; c++) {\n    CLASSES cls = (CLASSES)c;\n    if (eval_3d[c]) {\n      fp_det = fopen((result_dir + \"/../stats_\" + CLASS_NAMES[c] + \"_detection_3d.txt\").c_str(), \"w\");\n      vector<double> precision[3], aos[3];\n      if(   !eval_class(fp_det, fp_ori, cls, groundtruth, detections, compute_aos, box3DOverlap, precision[0], aos[0], EASY, BOX3D)\n         || !eval_class(fp_det, fp_ori, cls, groundtruth, detections, compute_aos, box3DOverlap, precision[1], aos[1], MODERATE, BOX3D)\n         || !eval_class(fp_det, fp_ori, cls, groundtruth, detections, compute_aos, box3DOverlap, precision[2], aos[2], HARD, BOX3D)) {\n        mail->msg(\"%s evaluation failed.\", CLASS_NAMES[c].c_str());\n        return false;\n      }\n      fclose(fp_det);\n      saveAndPlotPlots(plot_dir, CLASS_NAMES[c] + \"_detection_3d\", CLASS_NAMES[c], precision, 0);\n    }\n  }\n\n  // success\n  return true;\n}\n\nint32_t main (int32_t argc,char *argv[]) {\n\n  // we need 2 or 4 arguments!\n  if (argc!=3) {\n    cout << \"Usage: ./eval_detection_3d_offline gt_dir result_dir\" << endl;\n    return 1;\n  }\n\n  // read arguments\n  string gt_dir = argv[1];\n  string result_dir = argv[2];\n\n  // init notification mail\n  Mail *mail;\n  mail = new Mail();\n  mail->msg(\"Thank you for participating in our evaluation!\");\n\n  // run evaluation\n  if (eval(gt_dir, result_dir, mail)) {\n    mail->msg(\"Your evaluation results are available at:\");\n    mail->msg(result_dir.c_str());\n  } else {\n    system((\"rm -r \" + result_dir + \"/../plot\").c_str());\n    mail->msg(\"An error occured while processing your results.\");\n  }\n\n  // send mail and exit\n  delete mail;\n\n  return 0;\n}\n\n\n"
  },
  {
    "path": "src/tools/kitti_eval/mail.h",
    "content": "#ifndef MAIL_H\n#define MAIL_H\n\n#include <stdio.h>\n#include <stdarg.h>\n#include <string.h>\n\nclass Mail {\n\npublic:\n\n  Mail (std::string email = \"\") {\n    if (email.compare(\"\")) {\n      mail = popen(\"/usr/lib/sendmail -t -f noreply@cvlibs.net\",\"w\");\n      fprintf(mail,\"To: %s\\n\", email.c_str());\n      fprintf(mail,\"From: noreply@cvlibs.net\\n\");\n      fprintf(mail,\"Subject: KITTI Evaluation Benchmark\\n\");\n      fprintf(mail,\"\\n\\n\");\n    } else {\n      mail = 0;\n    }\n  }\n  \n  ~Mail() {\n    if (mail) {\n      pclose(mail);\n    }\n  }\n  \n  void msg (const char *format, ...) {\n    va_list args;\n    va_start(args,format);\n    if (mail) {\n      vfprintf(mail,format,args);\n      fprintf(mail,\"\\n\");\n    }\n    vprintf(format,args);\n    printf(\"\\n\");\n    va_end(args);\n  }\n    \nprivate:\n\n  FILE *mail;\n  \n};\n\n#endif\n"
  },
  {
    "path": "src/tools/merge_pascal_json.py",
    "content": "import json\n\n# ANNOT_PATH = '/home/zxy/Datasets/VOC/annotations/'\nANNOT_PATH = 'voc/annotations/'\nOUT_PATH = ANNOT_PATH\nINPUT_FILES = ['pascal_train2012.json', 'pascal_val2012.json',\n               'pascal_train2007.json', 'pascal_val2007.json']\nOUTPUT_FILE = 'pascal_trainval0712.json'\nKEYS = ['images', 'type', 'annotations', 'categories']\nMERGE_KEYS = ['images', 'annotations']\n\nout = {}\ntot_anns = 0\nfor i, file_name in enumerate(INPUT_FILES):\n  data = json.load(open(ANNOT_PATH + file_name, 'r'))\n  print('keys', data.keys())\n  if i == 0:\n    for key in KEYS:\n      out[key] = data[key]\n      print(file_name, key, len(data[key]))\n  else:\n    out['images'] += data['images']\n    for j in range(len(data['annotations'])):\n      data['annotations'][j]['id'] += tot_anns\n    out['annotations'] += data['annotations']\n    print(file_name, 'images', len(data['images']))\n    print(file_name, 'annotations', len(data['annotations']))\n  tot_anns = len(out['annotations'])\nprint('tot', len(out['annotations']))\njson.dump(out, open(OUT_PATH + OUTPUT_FILE, 'w'))\n"
  },
  {
    "path": "src/tools/reval.py",
    "content": "#!/usr/bin/env python\n\n# --------------------------------------------------------\n# Fast R-CNN\n# Copyright (c) 2015 Microsoft\n# Licensed under The MIT License [see LICENSE for details]\n# Written by Ross Girshick\n# Modified by Xingyi Zhou\n# --------------------------------------------------------\n\n# Reval = re-eval. Re-evaluate saved detections.\nfrom __future__ import absolute_import\nfrom __future__ import division\nfrom __future__ import print_function\n\nimport sys\nimport os.path as osp\nsys.path.insert(0, osp.join(osp.dirname(__file__), 'voc_eval_lib'))\n\nfrom model.test import apply_nms\nfrom datasets.pascal_voc import pascal_voc\nimport pickle\nimport os, argparse\nimport numpy as np\nimport json\n\ndef parse_args():\n  \"\"\"\n  Parse input arguments\n  \"\"\"\n  parser = argparse.ArgumentParser(description='Re-evaluate results')\n  parser.add_argument('detection_file', type=str)\n  parser.add_argument('--output_dir', help='results directory', type=str)\n  parser.add_argument('--imdb', dest='imdb_name',\n                      help='dataset to re-evaluate',\n                      default='voc_2007_test', type=str)\n  parser.add_argument('--matlab', dest='matlab_eval',\n                      help='use matlab for evaluation',\n                      action='store_true')\n  parser.add_argument('--comp', dest='comp_mode', help='competition mode',\n                      action='store_true')\n  parser.add_argument('--nms', dest='apply_nms', help='apply nms',\n                      action='store_true')\n\n  if len(sys.argv) == 1:\n    parser.print_help()\n    sys.exit(1)\n\n  args = parser.parse_args()\n  return args\n\n\ndef from_dets(imdb_name, detection_file, args):\n  imdb = pascal_voc('test', '2007')\n  imdb.competition_mode(args.comp_mode)\n  imdb.config['matlab_eval'] = args.matlab_eval\n  with open(os.path.join(detection_file), 'rb') as f:\n    if 'json' in detection_file:\n      dets = json.load(f)\n    else:\n      dets = pickle.load(f, encoding='latin1')\n  # import pdb; pdb.set_trace()\n  if args.apply_nms:\n    print('Applying NMS to all detections')\n    test_nms = 0.3\n    nms_dets = apply_nms(dets, test_nms)\n  else:\n    nms_dets = dets\n\n  print('Evaluating detections')\n  imdb.evaluate_detections(nms_dets)\n\n\nif __name__ == '__main__':\n  args = parse_args()\n\n  imdb_name = args.imdb_name\n  from_dets(imdb_name, args.detection_file, args)\n"
  },
  {
    "path": "src/tools/vis_pred.py",
    "content": "import pycocotools.coco as coco\nfrom pycocotools.cocoeval import COCOeval\nimport sys\nimport cv2\nimport numpy as np\nimport pickle\nIMG_PATH = '../../data/coco/val2017/'\nANN_PATH = '../../data/coco/annotations/instances_val2017.json'\nDEBUG = True\n\ndef _coco_box_to_bbox(box):\n  bbox = np.array([box[0], box[1], box[0] + box[2], box[1] + box[3]],\n                  dtype=np.int32)\n  return bbox\n\n_cat_ids = [\n  1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, \n  14, 15, 16, 17, 18, 19, 20, 21, 22, 23, \n  24, 25, 27, 28, 31, 32, 33, 34, 35, 36, \n  37, 38, 39, 40, 41, 42, 43, 44, 46, 47, \n  48, 49, 50, 51, 52, 53, 54, 55, 56, 57, \n  58, 59, 60, 61, 62, 63, 64, 65, 67, 70, \n  72, 73, 74, 75, 76, 77, 78, 79, 80, 81, \n  82, 84, 85, 86, 87, 88, 89, 90\n]\nnum_classes = 80\n_classes = {\n  ind + 1: cat_id for ind, cat_id in enumerate(_cat_ids)\n}\n_to_order = {cat_id: ind for ind, cat_id in enumerate(_cat_ids)}\ncoco = coco.COCO(ANN_PATH)\nCAT_NAMES = [coco.loadCats([_classes[i + 1]])[0]['name'] \\\n              for i in range(num_classes)]\nCOLORS = [((np.random.random((3, )) * 0.6 + 0.4)*255).astype(np.uint8) \\\n              for _ in range(num_classes)]\n\n\ndef add_box(image, bbox, sc, cat_id):\n  cat_id = _to_order[cat_id]\n  cat_name = CAT_NAMES[cat_id]\n  cat_size  = cv2.getTextSize(cat_name + '0', cv2.FONT_HERSHEY_SIMPLEX, 0.5, 2)[0]\n  color = np.array(COLORS[cat_id]).astype(np.int32).tolist()\n  txt = '{}{:.0f}'.format(cat_name, sc * 10)\n  if bbox[1] - cat_size[1] - 2 < 0:\n    cv2.rectangle(image,\n                  (bbox[0], bbox[1] + 2),\n                  (bbox[0] + cat_size[0], bbox[1] + cat_size[1] + 2),\n                  color, -1)\n    cv2.putText(image, txt, \n                (bbox[0], bbox[1] + cat_size[1] + 2), \n                cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 0), thickness=1)\n  else:\n    cv2.rectangle(image,\n                  (bbox[0], bbox[1] - cat_size[1] - 2),\n                  (bbox[0] + cat_size[0], bbox[1] - 2),\n                  color, -1)\n    cv2.putText(image, txt, \n                (bbox[0], bbox[1] - 2), \n                cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 0), thickness=1)\n  cv2.rectangle(image,\n                (bbox[0], bbox[1]),\n                (bbox[2], bbox[3]),\n                color, 2)\n  return image\n\nif __name__ == '__main__':\n  dets = []\n  img_ids = coco.getImgIds()\n  num_images = len(img_ids)\n  for k in range(1, len(sys.argv)):\n    pred_path = sys.argv[k]\n    dets.append(coco.loadRes(pred_path))\n  # import pdb; pdb.set_trace()\n  for i, img_id in enumerate(img_ids):\n    img_info = coco.loadImgs(ids=[img_id])[0]\n    img_path = IMG_PATH + img_info['file_name']\n    img = cv2.imread(img_path)\n    gt_ids = coco.getAnnIds(imgIds=[img_id])\n    gts = coco.loadAnns(gt_ids)\n    gt_img = img.copy()\n    for j, pred in enumerate(gts):\n      bbox = _coco_box_to_bbox(pred['bbox'])\n      cat_id = pred['category_id']\n      gt_img = add_box(gt_img, bbox, 0, cat_id)\n    for k in range(len(dets)):\n      pred_ids = dets[k].getAnnIds(imgIds=[img_id])\n      preds = dets[k].loadAnns(pred_ids)\n      pred_img = img.copy()\n      for j, pred in enumerate(preds):\n        bbox = _coco_box_to_bbox(pred['bbox'])\n        sc = pred['score']\n        cat_id = pred['category_id']\n        if sc > 0.2:\n          pred_img = add_box(pred_img, bbox, sc, cat_id)\n      cv2.imshow('pred{}'.format(k), pred_img)\n      # cv2.imwrite('vis/{}_pred{}.png'.format(i, k), pred_img)\n    cv2.imshow('gt', gt_img)\n    # cv2.imwrite('vis/{}_gt.png'.format(i), gt_img)\n    cv2.waitKey()\n  # coco_eval.evaluate()\n  # coco_eval.accumulate()\n  # coco_eval.summarize()\n\n  \n"
  },
  {
    "path": "src/tools/voc_eval_lib/LICENSE",
    "content": "MIT License\n\nCopyright (c) 2017 Xinlei Chen\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "src/tools/voc_eval_lib/Makefile",
    "content": "all:\n\tpython setup.py build_ext --inplace\n\trm -rf build\nclean:\n\trm -rf */*.pyc\n\trm -rf */*.so\n"
  },
  {
    "path": "src/tools/voc_eval_lib/__init__.py",
    "content": ""
  },
  {
    "path": "src/tools/voc_eval_lib/datasets/__init__.py",
    "content": ""
  },
  {
    "path": "src/tools/voc_eval_lib/datasets/bbox.pyx",
    "content": "# --------------------------------------------------------\n# Fast R-CNN\n# Copyright (c) 2015 Microsoft\n# Licensed under The MIT License [see LICENSE for details]\n# Written by Sergey Karayev\n# --------------------------------------------------------\n\ncimport cython\nimport numpy as np\ncimport numpy as np\n\nDTYPE = np.float\nctypedef np.float_t DTYPE_t\n\ndef bbox_overlaps(\n        np.ndarray[DTYPE_t, ndim=2] boxes,\n        np.ndarray[DTYPE_t, ndim=2] query_boxes):\n    \"\"\"\n    Parameters\n    ----------\n    boxes: (N, 4) ndarray of float\n    query_boxes: (K, 4) ndarray of float\n    Returns\n    -------\n    overlaps: (N, K) ndarray of overlap between boxes and query_boxes\n    \"\"\"\n    cdef unsigned int N = boxes.shape[0]\n    cdef unsigned int K = query_boxes.shape[0]\n    cdef np.ndarray[DTYPE_t, ndim=2] overlaps = np.zeros((N, K), dtype=DTYPE)\n    cdef DTYPE_t iw, ih, box_area\n    cdef DTYPE_t ua\n    cdef unsigned int k, n\n    for k in range(K):\n        box_area = (\n            (query_boxes[k, 2] - query_boxes[k, 0] + 1) *\n            (query_boxes[k, 3] - query_boxes[k, 1] + 1)\n        )\n        for n in range(N):\n            iw = (\n                min(boxes[n, 2], query_boxes[k, 2]) -\n                max(boxes[n, 0], query_boxes[k, 0]) + 1\n            )\n            if iw > 0:\n                ih = (\n                    min(boxes[n, 3], query_boxes[k, 3]) -\n                    max(boxes[n, 1], query_boxes[k, 1]) + 1\n                )\n                if ih > 0:\n                    ua = float(\n                        (boxes[n, 2] - boxes[n, 0] + 1) *\n                        (boxes[n, 3] - boxes[n, 1] + 1) +\n                        box_area - iw * ih\n                    )\n                    overlaps[n, k] = iw * ih / ua\n    return overlaps\n\n"
  },
  {
    "path": "src/tools/voc_eval_lib/datasets/ds_utils.py",
    "content": "# --------------------------------------------------------\n# Fast/er R-CNN\n# Licensed under The MIT License [see LICENSE for details]\n# Written by Ross Girshick\n# --------------------------------------------------------\nfrom __future__ import absolute_import\nfrom __future__ import division\nfrom __future__ import print_function\n\nimport numpy as np\n\n\ndef unique_boxes(boxes, scale=1.0):\n  \"\"\"Return indices of unique boxes.\"\"\"\n  v = np.array([1, 1e3, 1e6, 1e9])\n  hashes = np.round(boxes * scale).dot(v)\n  _, index = np.unique(hashes, return_index=True)\n  return np.sort(index)\n\n\ndef xywh_to_xyxy(boxes):\n  \"\"\"Convert [x y w h] box format to [x1 y1 x2 y2] format.\"\"\"\n  return np.hstack((boxes[:, 0:2], boxes[:, 0:2] + boxes[:, 2:4] - 1))\n\n\ndef xyxy_to_xywh(boxes):\n  \"\"\"Convert [x1 y1 x2 y2] box format to [x y w h] format.\"\"\"\n  return np.hstack((boxes[:, 0:2], boxes[:, 2:4] - boxes[:, 0:2] + 1))\n\n\ndef validate_boxes(boxes, width=0, height=0):\n  \"\"\"Check that a set of boxes are valid.\"\"\"\n  x1 = boxes[:, 0]\n  y1 = boxes[:, 1]\n  x2 = boxes[:, 2]\n  y2 = boxes[:, 3]\n  assert (x1 >= 0).all()\n  assert (y1 >= 0).all()\n  assert (x2 >= x1).all()\n  assert (y2 >= y1).all()\n  assert (x2 < width).all()\n  assert (y2 < height).all()\n\n\ndef filter_small_boxes(boxes, min_size):\n  w = boxes[:, 2] - boxes[:, 0]\n  h = boxes[:, 3] - boxes[:, 1]\n  keep = np.where((w >= min_size) & (h > min_size))[0]\n  return keep\n"
  },
  {
    "path": "src/tools/voc_eval_lib/datasets/imdb.py",
    "content": "# --------------------------------------------------------\n# Fast R-CNN\n# Copyright (c) 2015 Microsoft\n# Licensed under The MIT License [see LICENSE for details]\n# Written by Ross Girshick and Xinlei Chen\n# Modified by Xingyi Zhou\n# --------------------------------------------------------\nfrom __future__ import absolute_import\nfrom __future__ import division\nfrom __future__ import print_function\n\nimport os\nimport os.path as osp\nimport PIL\n# from utils.cython_bbox import bbox_overlaps\nimport numpy as np\nimport scipy.sparse\nfrom model.config import cfg\n\ndef bbox_overlaps(box1, box2):\n  area1 = (box1[2] - box1[0] + 1) * (box1[3] - box1[1] + 1)\n  area2 = (box2[2] - box2[0] + 1) * (box2[3] - box2[1] + 1)\n  inter = max(min(box1[2], box2[2]) - max(box1[0], box2[0]) + 1, 0) * \\\n          max(min(box1[3], box2[3]) - max(box1[1], box2[1]) + 1, 0)\n  iou = 1.0 * inter / (area1 + area2 - inter)\n  return iou\n \nclass imdb(object):\n  \"\"\"Image database.\"\"\"\n\n  def __init__(self, name, classes=None):\n    self._name = name\n    self._num_classes = 0\n    if not classes:\n      self._classes = []\n    else:\n      self._classes = classes\n    self._image_index = []\n    self._obj_proposer = 'gt'\n    self._roidb = None\n    self._roidb_handler = self.default_roidb\n    # Use this dict for storing dataset specific config options\n    self.config = {}\n\n  @property\n  def name(self):\n    return self._name\n\n  @property\n  def num_classes(self):\n    return len(self._classes)\n\n  @property\n  def classes(self):\n    return self._classes\n\n  @property\n  def image_index(self):\n    return self._image_index\n\n  @property\n  def roidb_handler(self):\n    return self._roidb_handler\n\n  @roidb_handler.setter\n  def roidb_handler(self, val):\n    self._roidb_handler = val\n\n  def set_proposal_method(self, method):\n    method = eval('self.' + method + '_roidb')\n    self.roidb_handler = method\n\n  @property\n  def roidb(self):\n    # A roidb is a list of dictionaries, each with the following keys:\n    #   boxes\n    #   gt_overlaps\n    #   gt_classes\n    #   flipped\n    if self._roidb is not None:\n      return self._roidb\n    self._roidb = self.roidb_handler()\n    return self._roidb\n\n  @property\n  def cache_path(self):\n    cache_path = osp.abspath(osp.join(cfg.DATA_DIR, 'cache'))\n    if not os.path.exists(cache_path):\n      os.makedirs(cache_path)\n    return cache_path\n\n  @property\n  def num_images(self):\n    return len(self.image_index)\n\n  def image_path_at(self, i):\n    raise NotImplementedError\n\n  def default_roidb(self):\n    raise NotImplementedError\n\n  def evaluate_detections(self, all_boxes, output_dir=None):\n    \"\"\"\n    all_boxes is a list of length number-of-classes.\n    Each list element is a list of length number-of-images.\n    Each of those list elements is either an empty list []\n    or a numpy array of detection.\n\n    all_boxes[class][image] = [] or np.array of shape #dets x 5\n    \"\"\"\n    raise NotImplementedError\n\n  def _get_widths(self):\n    return [PIL.Image.open(self.image_path_at(i)).size[0]\n            for i in range(self.num_images)]\n\n  def append_flipped_images(self):\n    num_images = self.num_images\n    widths = self._get_widths()\n    for i in range(num_images):\n      boxes = self.roidb[i]['boxes'].copy()\n      oldx1 = boxes[:, 0].copy()\n      oldx2 = boxes[:, 2].copy()\n      boxes[:, 0] = widths[i] - oldx2 - 1\n      boxes[:, 2] = widths[i] - oldx1 - 1\n      assert (boxes[:, 2] >= boxes[:, 0]).all()\n      entry = {'boxes': boxes,\n               'gt_overlaps': self.roidb[i]['gt_overlaps'],\n               'gt_classes': self.roidb[i]['gt_classes'],\n               'flipped': True}\n      self.roidb.append(entry)\n    self._image_index = self._image_index * 2\n\n  def evaluate_recall(self, candidate_boxes=None, thresholds=None,\n                      area='all', limit=None):\n    \"\"\"Evaluate detection proposal recall metrics.\n\n    Returns:\n        results: dictionary of results with keys\n            'ar': average recall\n            'recalls': vector recalls at each IoU overlap threshold\n            'thresholds': vector of IoU overlap thresholds\n            'gt_overlaps': vector of all ground-truth overlaps\n    \"\"\"\n    # Record max overlap value for each gt box\n    # Return vector of overlap values\n    areas = {'all': 0, 'small': 1, 'medium': 2, 'large': 3,\n             '96-128': 4, '128-256': 5, '256-512': 6, '512-inf': 7}\n    area_ranges = [[0 ** 2, 1e5 ** 2],  # all\n                   [0 ** 2, 32 ** 2],  # small\n                   [32 ** 2, 96 ** 2],  # medium\n                   [96 ** 2, 1e5 ** 2],  # large\n                   [96 ** 2, 128 ** 2],  # 96-128\n                   [128 ** 2, 256 ** 2],  # 128-256\n                   [256 ** 2, 512 ** 2],  # 256-512\n                   [512 ** 2, 1e5 ** 2],  # 512-inf\n                   ]\n    assert area in areas, 'unknown area range: {}'.format(area)\n    area_range = area_ranges[areas[area]]\n    gt_overlaps = np.zeros(0)\n    num_pos = 0\n    for i in range(self.num_images):\n      # Checking for max_overlaps == 1 avoids including crowd annotations\n      # (...pretty hacking :/)\n      max_gt_overlaps = self.roidb[i]['gt_overlaps'].toarray().max(axis=1)\n      gt_inds = np.where((self.roidb[i]['gt_classes'] > 0) &\n                         (max_gt_overlaps == 1))[0]\n      gt_boxes = self.roidb[i]['boxes'][gt_inds, :]\n      gt_areas = self.roidb[i]['seg_areas'][gt_inds]\n      valid_gt_inds = np.where((gt_areas >= area_range[0]) &\n                               (gt_areas <= area_range[1]))[0]\n      gt_boxes = gt_boxes[valid_gt_inds, :]\n      num_pos += len(valid_gt_inds)\n\n      if candidate_boxes is None:\n        # If candidate_boxes is not supplied, the default is to use the\n        # non-ground-truth boxes from this roidb\n        non_gt_inds = np.where(self.roidb[i]['gt_classes'] == 0)[0]\n        boxes = self.roidb[i]['boxes'][non_gt_inds, :]\n      else:\n        boxes = candidate_boxes[i]\n      if boxes.shape[0] == 0:\n        continue\n      if limit is not None and boxes.shape[0] > limit:\n        boxes = boxes[:limit, :]\n\n      overlaps = bbox_overlaps(boxes.astype(np.float),\n                               gt_boxes.astype(np.float))\n\n      _gt_overlaps = np.zeros((gt_boxes.shape[0]))\n      for j in range(gt_boxes.shape[0]):\n        # find which proposal box maximally covers each gt box\n        argmax_overlaps = overlaps.argmax(axis=0)\n        # and get the iou amount of coverage for each gt box\n        max_overlaps = overlaps.max(axis=0)\n        # find which gt box is 'best' covered (i.e. 'best' = most iou)\n        gt_ind = max_overlaps.argmax()\n        gt_ovr = max_overlaps.max()\n        assert (gt_ovr >= 0)\n        # find the proposal box that covers the best covered gt box\n        box_ind = argmax_overlaps[gt_ind]\n        # record the iou coverage of this gt box\n        _gt_overlaps[j] = overlaps[box_ind, gt_ind]\n        assert (_gt_overlaps[j] == gt_ovr)\n        # mark the proposal box and the gt box as used\n        overlaps[box_ind, :] = -1\n        overlaps[:, gt_ind] = -1\n      # append recorded iou coverage level\n      gt_overlaps = np.hstack((gt_overlaps, _gt_overlaps))\n\n    gt_overlaps = np.sort(gt_overlaps)\n    if thresholds is None:\n      step = 0.05\n      thresholds = np.arange(0.5, 0.95 + 1e-5, step)\n    recalls = np.zeros_like(thresholds)\n    # compute recall for each iou threshold\n    for i, t in enumerate(thresholds):\n      recalls[i] = (gt_overlaps >= t).sum() / float(num_pos)\n    # ar = 2 * np.trapz(recalls, thresholds)\n    ar = recalls.mean()\n    return {'ar': ar, 'recalls': recalls, 'thresholds': thresholds,\n            'gt_overlaps': gt_overlaps}\n\n  def create_roidb_from_box_list(self, box_list, gt_roidb):\n    assert len(box_list) == self.num_images, \\\n      'Number of boxes must match number of ground-truth images'\n    roidb = []\n    for i in range(self.num_images):\n      boxes = box_list[i]\n      num_boxes = boxes.shape[0]\n      overlaps = np.zeros((num_boxes, self.num_classes), dtype=np.float32)\n\n      if gt_roidb is not None and gt_roidb[i]['boxes'].size > 0:\n        gt_boxes = gt_roidb[i]['boxes']\n        gt_classes = gt_roidb[i]['gt_classes']\n        gt_overlaps = bbox_overlaps(boxes.astype(np.float),\n                                    gt_boxes.astype(np.float))\n        argmaxes = gt_overlaps.argmax(axis=1)\n        maxes = gt_overlaps.max(axis=1)\n        I = np.where(maxes > 0)[0]\n        overlaps[I, gt_classes[argmaxes[I]]] = maxes[I]\n\n      overlaps = scipy.sparse.csr_matrix(overlaps)\n      roidb.append({\n        'boxes': boxes,\n        'gt_classes': np.zeros((num_boxes,), dtype=np.int32),\n        'gt_overlaps': overlaps,\n        'flipped': False,\n        'seg_areas': np.zeros((num_boxes,), dtype=np.float32),\n      })\n    return roidb\n\n  @staticmethod\n  def merge_roidbs(a, b):\n    assert len(a) == len(b)\n    for i in range(len(a)):\n      a[i]['boxes'] = np.vstack((a[i]['boxes'], b[i]['boxes']))\n      a[i]['gt_classes'] = np.hstack((a[i]['gt_classes'],\n                                      b[i]['gt_classes']))\n      a[i]['gt_overlaps'] = scipy.sparse.vstack([a[i]['gt_overlaps'],\n                                                 b[i]['gt_overlaps']])\n      a[i]['seg_areas'] = np.hstack((a[i]['seg_areas'],\n                                     b[i]['seg_areas']))\n    return a\n\n  def competition_mode(self, on):\n    \"\"\"Turn competition mode on or off.\"\"\"\n    pass\n"
  },
  {
    "path": "src/tools/voc_eval_lib/datasets/pascal_voc.py",
    "content": "# --------------------------------------------------------\n# Fast R-CNN\n# Copyright (c) 2015 Microsoft\n# Licensed under The MIT License [see LICENSE for details]\n# Written by Ross Girshick and Xinlei Chen\n# --------------------------------------------------------\nfrom __future__ import absolute_import\nfrom __future__ import division\nfrom __future__ import print_function\n\nimport os\nfrom datasets.imdb import imdb\nimport datasets.ds_utils as ds_utils\nimport xml.etree.ElementTree as ET\nimport numpy as np\nimport scipy.sparse\nimport scipy.io as sio\n# import utils.cython_bbox\nimport pickle\nimport subprocess\nimport uuid\nfrom .voc_eval import voc_eval\nfrom model.config import cfg\n\n\nclass pascal_voc(imdb):\n  def __init__(self, image_set, year, use_diff=False):\n    name = 'voc_' + year + '_' + image_set\n    if use_diff:\n      name += '_diff'\n    imdb.__init__(self, name)\n    self._year = year\n    self._image_set = image_set\n    self._devkit_path = self._get_default_path()\n    self._data_path = os.path.join(self._devkit_path, 'VOC' + self._year)\n    self._classes = ('__background__',  # always index 0\n                     'aeroplane', 'bicycle', 'bird', 'boat',\n                     'bottle', 'bus', 'car', 'cat', 'chair',\n                     'cow', 'diningtable', 'dog', 'horse',\n                     'motorbike', 'person', 'pottedplant',\n                     'sheep', 'sofa', 'train', 'tvmonitor')\n    self._class_to_ind = dict(list(zip(self.classes, list(range(self.num_classes)))))\n    self._image_ext = '.jpg'\n    self._image_index = self._load_image_set_index()\n    # Default to roidb handler\n    self._roidb_handler = self.gt_roidb\n    self._salt = str(uuid.uuid4())\n    self._comp_id = 'comp4'\n\n    # PASCAL specific config options\n    self.config = {'cleanup': True,\n                   'use_salt': True,\n                   'use_diff': use_diff,\n                   'matlab_eval': False,\n                   'rpn_file': None}\n\n    assert os.path.exists(self._devkit_path), \\\n      'VOCdevkit path does not exist: {}'.format(self._devkit_path)\n    assert os.path.exists(self._data_path), \\\n      'Path does not exist: {}'.format(self._data_path)\n\n  def image_path_at(self, i):\n    \"\"\"\n    Return the absolute path to image i in the image sequence.\n    \"\"\"\n    return self.image_path_from_index(self._image_index[i])\n\n  def image_path_from_index(self, index):\n    \"\"\"\n    Construct an image path from the image's \"index\" identifier.\n    \"\"\"\n    image_path = os.path.join(self._data_path, 'JPEGImages',\n                              index + self._image_ext)\n    assert os.path.exists(image_path), \\\n      'Path does not exist: {}'.format(image_path)\n    return image_path\n\n  def _load_image_set_index(self):\n    \"\"\"\n    Load the indexes listed in this dataset's image set file.\n    \"\"\"\n    # Example path to image set file:\n    # self._devkit_path + /VOCdevkit2007/VOC2007/ImageSets/Main/val.txt\n    image_set_file = os.path.join(self._data_path, 'ImageSets', 'Main',\n                                  self._image_set + '.txt')\n    assert os.path.exists(image_set_file), \\\n      'Path does not exist: {}'.format(image_set_file)\n    with open(image_set_file) as f:\n      image_index = [x.strip() for x in f.readlines()]\n    return image_index\n\n  def _get_default_path(self):\n    \"\"\"\n    Return the default path where PASCAL VOC is expected to be installed.\n    \"\"\"\n    return os.path.join(cfg.DATA_DIR, 'voc', 'VOCdevkit')\n\n  def gt_roidb(self):\n    \"\"\"\n    Return the database of ground-truth regions of interest.\n\n    This function loads/saves from/to a cache file to speed up future calls.\n    \"\"\"\n    cache_file = os.path.join(self.cache_path, self.name + '_gt_roidb.pkl')\n    if os.path.exists(cache_file):\n      with open(cache_file, 'rb') as fid:\n        try:\n          roidb = pickle.load(fid)\n        except:\n          roidb = pickle.load(fid, encoding='bytes')\n      print('{} gt roidb loaded from {}'.format(self.name, cache_file))\n      return roidb\n\n    gt_roidb = [self._load_pascal_annotation(index)\n                for index in self.image_index]\n    with open(cache_file, 'wb') as fid:\n      pickle.dump(gt_roidb, fid, pickle.HIGHEST_PROTOCOL)\n    print('wrote gt roidb to {}'.format(cache_file))\n\n    return gt_roidb\n\n  def rpn_roidb(self):\n    if int(self._year) == 2007 or self._image_set != 'test':\n      gt_roidb = self.gt_roidb()\n      rpn_roidb = self._load_rpn_roidb(gt_roidb)\n      roidb = imdb.merge_roidbs(gt_roidb, rpn_roidb)\n    else:\n      roidb = self._load_rpn_roidb(None)\n\n    return roidb\n\n  def _load_rpn_roidb(self, gt_roidb):\n    filename = self.config['rpn_file']\n    print('loading {}'.format(filename))\n    assert os.path.exists(filename), \\\n      'rpn data not found at: {}'.format(filename)\n    with open(filename, 'rb') as f:\n      box_list = pickle.load(f)\n    return self.create_roidb_from_box_list(box_list, gt_roidb)\n\n  def _load_pascal_annotation(self, index):\n    \"\"\"\n    Load image and bounding boxes info from XML file in the PASCAL VOC\n    format.\n    \"\"\"\n    filename = os.path.join(self._data_path, 'Annotations', index + '.xml')\n    tree = ET.parse(filename)\n    objs = tree.findall('object')\n    if not self.config['use_diff']:\n      # Exclude the samples labeled as difficult\n      non_diff_objs = [\n        obj for obj in objs if int(obj.find('difficult').text) == 0]\n      # if len(non_diff_objs) != len(objs):\n      #     print 'Removed {} difficult objects'.format(\n      #         len(objs) - len(non_diff_objs))\n      objs = non_diff_objs\n    num_objs = len(objs)\n\n    boxes = np.zeros((num_objs, 4), dtype=np.uint16)\n    gt_classes = np.zeros((num_objs), dtype=np.int32)\n    overlaps = np.zeros((num_objs, self.num_classes), dtype=np.float32)\n    # \"Seg\" area for pascal is just the box area\n    seg_areas = np.zeros((num_objs), dtype=np.float32)\n\n    # Load object bounding boxes into a data frame.\n    for ix, obj in enumerate(objs):\n      bbox = obj.find('bndbox')\n      # Make pixel indexes 0-based\n      x1 = float(bbox.find('xmin').text) - 1\n      y1 = float(bbox.find('ymin').text) - 1\n      x2 = float(bbox.find('xmax').text) - 1\n      y2 = float(bbox.find('ymax').text) - 1\n      cls = self._class_to_ind[obj.find('name').text.lower().strip()]\n      boxes[ix, :] = [x1, y1, x2, y2]\n      gt_classes[ix] = cls\n      overlaps[ix, cls] = 1.0\n      seg_areas[ix] = (x2 - x1 + 1) * (y2 - y1 + 1)\n\n    overlaps = scipy.sparse.csr_matrix(overlaps)\n\n    return {'boxes': boxes,\n            'gt_classes': gt_classes,\n            'gt_overlaps': overlaps,\n            'flipped': False,\n            'seg_areas': seg_areas}\n\n  def _get_comp_id(self):\n    comp_id = (self._comp_id + '_' + self._salt if self.config['use_salt']\n               else self._comp_id)\n    return comp_id\n\n  def _get_voc_results_file_template(self):\n    # VOCdevkit/results/VOC2007/Main/<comp_id>_det_test_aeroplane.txt\n    filename = self._get_comp_id() + '_det_' + self._image_set + '_{:s}.txt'\n    path = os.path.join(\n      self._devkit_path,\n      'results',\n      'VOC' + self._year,\n      'Main',\n      filename)\n    return path\n\n  def _write_voc_results_file(self, all_boxes):\n    for cls_ind, cls in enumerate(self.classes):\n      if cls == '__background__':\n        continue\n      # print('Writing {} VOC results file'.format(cls))\n      filename = self._get_voc_results_file_template().format(cls)\n      # print(filename)\n      with open(filename, 'wt') as f:\n        for im_ind, index in enumerate(self.image_index):\n          dets = np.array(all_boxes[cls_ind][im_ind])\n          if len(dets) == 0:\n            continue\n          # the VOCdevkit expects 1-based indices\n          for k in range(dets.shape[0]):\n            f.write('{:s} {:.3f} {:.1f} {:.1f} {:.1f} {:.1f}\\n'.\n                    format(index, dets[k, -1],\n                           dets[k, 0] + 1, dets[k, 1] + 1,\n                           dets[k, 2] + 1, dets[k, 3] + 1))\n\n  def _do_python_eval(self, output_dir=None):\n    annopath = os.path.join(\n      self._devkit_path,\n      'VOC' + self._year,\n      'Annotations',\n      '{:s}.xml')\n    imagesetfile = os.path.join(\n      self._devkit_path,\n      'VOC' + self._year,\n      'ImageSets',\n      'Main',\n      self._image_set + '.txt')\n    cachedir = os.path.join(self._devkit_path, 'annotations_cache')\n    aps = []\n    # The PASCAL VOC metric changed in 2010\n    use_07_metric = True if int(self._year) < 2010 else False\n    print('VOC07 metric? ' + ('Yes' if use_07_metric else 'No'))\n    if output_dir is not None and not os.path.isdir(output_dir):\n      os.mkdir(output_dir)\n    for i, cls in enumerate(self._classes):\n      if cls == '__background__':\n        continue\n      filename = self._get_voc_results_file_template().format(cls)\n      rec, prec, ap = voc_eval(\n        filename, annopath, imagesetfile, cls, cachedir, ovthresh=0.5,\n        use_07_metric=use_07_metric, use_diff=self.config['use_diff'])\n      aps += [ap]\n      print(('AP for {} = {:.4f}'.format(cls, ap)))\n      if output_dir is not None:\n        with open(os.path.join(output_dir, cls + '_pr.pkl'), 'wb') as f:\n          pickle.dump({'rec': rec, 'prec': prec, 'ap': ap}, f)\n    print(('Mean AP = {:.4f}'.format(np.mean(aps))))\n    print('~~~~~~~~')\n    '''\n    print('Results:')\n    for ap in aps:\n      print(('{:.3f}'.format(ap)))\n    print(('{:.3f}'.format(np.mean(aps))))\n    print('~~~~~~~~')\n    print('')\n    print('--------------------------------------------------------------')\n    print('Results computed with the **unofficial** Python eval code.')\n    print('Results should be very close to the official MATLAB eval code.')\n    print('Recompute with `./tools/reval.py --matlab ...` for your paper.')\n    print('-- Thanks, The Management')\n    print('--------------------------------------------------------------')\n    '''\n    \n  def _do_matlab_eval(self, output_dir='output'):\n    print('-----------------------------------------------------')\n    print('Computing results with the official MATLAB eval code.')\n    print('-----------------------------------------------------')\n    path = os.path.join(cfg.ROOT_DIR, 'lib', 'datasets',\n                        'VOCdevkit-matlab-wrapper')\n    cmd = 'cd {} && '.format(path)\n    cmd += '{:s} -nodisplay -nodesktop '.format(cfg.MATLAB)\n    cmd += '-r \"dbstop if error; '\n    cmd += 'voc_eval(\\'{:s}\\',\\'{:s}\\',\\'{:s}\\',\\'{:s}\\'); quit;\"' \\\n      .format(self._devkit_path, self._get_comp_id(),\n              self._image_set, output_dir)\n    print(('Running:\\n{}'.format(cmd)))\n    status = subprocess.call(cmd, shell=True)\n\n  def evaluate_detections(self, all_boxes, output_dir=None):\n    self._write_voc_results_file(all_boxes)\n    self._do_python_eval(output_dir)\n    if self.config['matlab_eval']:\n      self._do_matlab_eval(output_dir)\n    if self.config['cleanup']:\n      for cls in self._classes:\n        if cls == '__background__':\n          continue\n        filename = self._get_voc_results_file_template().format(cls)\n        os.remove(filename)\n\n  def competition_mode(self, on):\n    if on:\n      self.config['use_salt'] = False\n      self.config['cleanup'] = False\n    else:\n      self.config['use_salt'] = True\n      self.config['cleanup'] = True\n\n\nif __name__ == '__main__':\n  from datasets.pascal_voc import pascal_voc\n\n  d = pascal_voc('trainval', '2007')\n  res = d.roidb\n  from IPython import embed;\n\n  embed()\n"
  },
  {
    "path": "src/tools/voc_eval_lib/datasets/voc_eval.py",
    "content": "# --------------------------------------------------------\n# Fast/er R-CNN\n# Licensed under The MIT License [see LICENSE for details]\n# Written by Bharath Hariharan\n# --------------------------------------------------------\nfrom __future__ import absolute_import\nfrom __future__ import division\nfrom __future__ import print_function\n\nimport xml.etree.ElementTree as ET\nimport os\nimport pickle\nimport numpy as np\n\ndef parse_rec(filename):\n  \"\"\" Parse a PASCAL VOC xml file \"\"\"\n  tree = ET.parse(filename)\n  objects = []\n  for obj in tree.findall('object'):\n    obj_struct = {}\n    obj_struct['name'] = obj.find('name').text\n    obj_struct['pose'] = obj.find('pose').text\n    obj_struct['truncated'] = int(obj.find('truncated').text)\n    obj_struct['difficult'] = int(obj.find('difficult').text)\n    bbox = obj.find('bndbox')\n    obj_struct['bbox'] = [int(bbox.find('xmin').text),\n                          int(bbox.find('ymin').text),\n                          int(bbox.find('xmax').text),\n                          int(bbox.find('ymax').text)]\n    objects.append(obj_struct)\n\n  return objects\n\n\ndef voc_ap(rec, prec, use_07_metric=False):\n  \"\"\" ap = voc_ap(rec, prec, [use_07_metric])\n  Compute VOC AP given precision and recall.\n  If use_07_metric is true, uses the\n  VOC 07 11 point method (default:False).\n  \"\"\"\n  if use_07_metric:\n    # 11 point metric\n    ap = 0.\n    for t in np.arange(0., 1.1, 0.1):\n      if np.sum(rec >= t) == 0:\n        p = 0\n      else:\n        p = np.max(prec[rec >= t])\n        # print(t, p)\n      ap = ap + p / 11.\n  else:\n    # correct AP calculation\n    # first append sentinel values at the end\n    mrec = np.concatenate(([0.], rec, [1.]))\n    mpre = np.concatenate(([0.], prec, [0.]))\n\n    # compute the precision envelope\n    for i in range(mpre.size - 1, 0, -1):\n      mpre[i - 1] = np.maximum(mpre[i - 1], mpre[i])\n\n    # to calculate area under PR curve, look for points\n    # where X axis (recall) changes value\n    i = np.where(mrec[1:] != mrec[:-1])[0]\n\n    # and sum (\\Delta recall) * prec\n    ap = np.sum((mrec[i + 1] - mrec[i]) * mpre[i + 1])\n  return ap\n\n\ndef voc_eval(detpath,\n             annopath,\n             imagesetfile,\n             classname,\n             cachedir,\n             ovthresh=0.5,\n             use_07_metric=False,\n             use_diff=False):\n  \"\"\"rec, prec, ap = voc_eval(detpath,\n                              annopath,\n                              imagesetfile,\n                              classname,\n                              [ovthresh],\n                              [use_07_metric])\n\n  Top level function that does the PASCAL VOC evaluation.\n\n  detpath: Path to detections\n      detpath.format(classname) should produce the detection results file.\n  annopath: Path to annotations\n      annopath.format(imagename) should be the xml annotations file.\n  imagesetfile: Text file containing the list of images, one image per line.\n  classname: Category name (duh)\n  cachedir: Directory for caching the annotations\n  [ovthresh]: Overlap threshold (default = 0.5)\n  [use_07_metric]: Whether to use VOC07's 11 point AP computation\n      (default False)\n  \"\"\"\n  # assumes detections are in detpath.format(classname)\n  # assumes annotations are in annopath.format(imagename)\n  # assumes imagesetfile is a text file with each line an image name\n  # cachedir caches the annotations in a pickle file\n\n  # first load gt\n  if not os.path.isdir(cachedir):\n    os.mkdir(cachedir)\n  cachefile = os.path.join(cachedir, '%s_annots.pkl' % imagesetfile)\n  # read list of images\n  with open(imagesetfile, 'r') as f:\n    lines = f.readlines()\n  imagenames = [x.strip() for x in lines]\n\n  if not os.path.isfile(cachefile):\n    # load annotations\n    recs = {}\n    for i, imagename in enumerate(imagenames):\n      recs[imagename] = parse_rec(annopath.format(imagename))\n      if i % 100 == 0:\n        print('Reading annotation for {:d}/{:d}'.format(\n          i + 1, len(imagenames)))\n    # save\n    print('Saving cached annotations to {:s}'.format(cachefile))\n    with open(cachefile, 'wb') as f:\n      pickle.dump(recs, f)\n  else:\n    # load\n    with open(cachefile, 'rb') as f:\n      try:\n        recs = pickle.load(f)\n      except:\n        recs = pickle.load(f, encoding='bytes')\n\n  # extract gt objects for this class\n  class_recs = {}\n  npos = 0\n  for imagename in imagenames:\n    R = [obj for obj in recs[imagename] if obj['name'] == classname]\n    bbox = np.array([x['bbox'] for x in R])\n    if use_diff:\n      difficult = np.array([False for x in R]).astype(np.bool)\n    else:\n      difficult = np.array([x['difficult'] for x in R]).astype(np.bool)\n    det = [False] * len(R)\n    npos = npos + sum(~difficult)\n    class_recs[imagename] = {'bbox': bbox,\n                             'difficult': difficult,\n                             'det': det}\n\n  # read dets\n  detfile = detpath.format(classname)\n  with open(detfile, 'r') as f:\n    lines = f.readlines()\n\n  splitlines = [x.strip().split(' ') for x in lines]\n  image_ids = [x[0] for x in splitlines]\n  confidence = np.array([float(x[1]) for x in splitlines])\n  BB = np.array([[float(z) for z in x[2:]] for x in splitlines])\n\n  nd = len(image_ids)\n  tp = np.zeros(nd)\n  fp = np.zeros(nd)\n\n  if BB.shape[0] > 0:\n    # sort by confidence\n    sorted_ind = np.argsort(-confidence)\n    sorted_scores = np.sort(-confidence)\n    BB = BB[sorted_ind, :]\n    image_ids = [image_ids[x] for x in sorted_ind]\n\n    # go down dets and mark TPs and FPs\n    for d in range(nd):\n      R = class_recs[image_ids[d]]\n      bb = BB[d, :].astype(float)\n      ovmax = -np.inf\n      BBGT = R['bbox'].astype(float)\n\n      if BBGT.size > 0:\n        # compute overlaps\n        # intersection\n        ixmin = np.maximum(BBGT[:, 0], bb[0])\n        iymin = np.maximum(BBGT[:, 1], bb[1])\n        ixmax = np.minimum(BBGT[:, 2], bb[2])\n        iymax = np.minimum(BBGT[:, 3], bb[3])\n        iw = np.maximum(ixmax - ixmin + 1., 0.)\n        ih = np.maximum(iymax - iymin + 1., 0.)\n        inters = iw * ih\n\n        # union\n        uni = ((bb[2] - bb[0] + 1.) * (bb[3] - bb[1] + 1.) +\n               (BBGT[:, 2] - BBGT[:, 0] + 1.) *\n               (BBGT[:, 3] - BBGT[:, 1] + 1.) - inters)\n\n        overlaps = inters / uni\n        ovmax = np.max(overlaps)\n        jmax = np.argmax(overlaps)\n\n      if ovmax > ovthresh:\n        if not R['difficult'][jmax]:\n          if not R['det'][jmax]:\n            tp[d] = 1.\n            R['det'][jmax] = 1\n          else:\n            fp[d] = 1.\n      else:\n        fp[d] = 1.\n\n  # compute precision recall\n  fp = np.cumsum(fp)\n  tp = np.cumsum(tp)\n  rec = tp / float(npos)\n  # avoid divide by zero in case the first detection matches a difficult\n  # ground truth\n  prec = tp / np.maximum(tp + fp, np.finfo(np.float64).eps)\n  ap = voc_ap(rec, prec, use_07_metric)\n\n  return rec, prec, ap\n"
  },
  {
    "path": "src/tools/voc_eval_lib/model/__init__.py",
    "content": ""
  },
  {
    "path": "src/tools/voc_eval_lib/model/bbox_transform.py",
    "content": "# --------------------------------------------------------\n# Fast R-CNN\n# Copyright (c) 2015 Microsoft\n# Licensed under The MIT License [see LICENSE for details]\n# Written by Ross Girshick\n# --------------------------------------------------------\nfrom __future__ import absolute_import\nfrom __future__ import division\nfrom __future__ import print_function\n\nimport numpy as np\n\ndef bbox_transform(ex_rois, gt_rois):\n  ex_widths = ex_rois[:, 2] - ex_rois[:, 0] + 1.0\n  ex_heights = ex_rois[:, 3] - ex_rois[:, 1] + 1.0\n  ex_ctr_x = ex_rois[:, 0] + 0.5 * ex_widths\n  ex_ctr_y = ex_rois[:, 1] + 0.5 * ex_heights\n\n  gt_widths = gt_rois[:, 2] - gt_rois[:, 0] + 1.0\n  gt_heights = gt_rois[:, 3] - gt_rois[:, 1] + 1.0\n  gt_ctr_x = gt_rois[:, 0] + 0.5 * gt_widths\n  gt_ctr_y = gt_rois[:, 1] + 0.5 * gt_heights\n\n  targets_dx = (gt_ctr_x - ex_ctr_x) / ex_widths\n  targets_dy = (gt_ctr_y - ex_ctr_y) / ex_heights\n  targets_dw = np.log(gt_widths / ex_widths)\n  targets_dh = np.log(gt_heights / ex_heights)\n\n  targets = np.vstack(\n    (targets_dx, targets_dy, targets_dw, targets_dh)).transpose()\n  return targets\n\n\ndef bbox_transform_inv(boxes, deltas):\n  if boxes.shape[0] == 0:\n    return np.zeros((0, deltas.shape[1]), dtype=deltas.dtype)\n\n  boxes = boxes.astype(deltas.dtype, copy=False)\n  widths = boxes[:, 2] - boxes[:, 0] + 1.0\n  heights = boxes[:, 3] - boxes[:, 1] + 1.0\n  ctr_x = boxes[:, 0] + 0.5 * widths\n  ctr_y = boxes[:, 1] + 0.5 * heights\n\n  dx = deltas[:, 0::4]\n  dy = deltas[:, 1::4]\n  dw = deltas[:, 2::4]\n  dh = deltas[:, 3::4]\n  \n  pred_ctr_x = dx * widths[:, np.newaxis] + ctr_x[:, np.newaxis]\n  pred_ctr_y = dy * heights[:, np.newaxis] + ctr_y[:, np.newaxis]\n  pred_w = np.exp(dw) * widths[:, np.newaxis]\n  pred_h = np.exp(dh) * heights[:, np.newaxis]\n\n  pred_boxes = np.zeros(deltas.shape, dtype=deltas.dtype)\n  # x1\n  pred_boxes[:, 0::4] = pred_ctr_x - 0.5 * pred_w\n  # y1\n  pred_boxes[:, 1::4] = pred_ctr_y - 0.5 * pred_h\n  # x2\n  pred_boxes[:, 2::4] = pred_ctr_x + 0.5 * pred_w\n  # y2\n  pred_boxes[:, 3::4] = pred_ctr_y + 0.5 * pred_h\n\n  return pred_boxes\n\n\ndef clip_boxes(boxes, im_shape):\n  \"\"\"\n  Clip boxes to image boundaries.\n  \"\"\"\n\n  # x1 >= 0\n  boxes[:, 0::4] = np.maximum(np.minimum(boxes[:, 0::4], im_shape[1] - 1), 0)\n  # y1 >= 0\n  boxes[:, 1::4] = np.maximum(np.minimum(boxes[:, 1::4], im_shape[0] - 1), 0)\n  # x2 < im_shape[1]\n  boxes[:, 2::4] = np.maximum(np.minimum(boxes[:, 2::4], im_shape[1] - 1), 0)\n  # y2 < im_shape[0]\n  boxes[:, 3::4] = np.maximum(np.minimum(boxes[:, 3::4], im_shape[0] - 1), 0)\n  return boxes\n\n\n\n\n\n"
  },
  {
    "path": "src/tools/voc_eval_lib/model/config.py",
    "content": "from __future__ import absolute_import\nfrom __future__ import division\nfrom __future__ import print_function\n\nimport os\nimport os.path as osp\nimport numpy as np\n# `pip install easydict` if you don't have it\nfrom easydict import EasyDict as edict\n\n__C = edict()\n# Consumers can get config by:\n#   from fast_rcnn_config import cfg\ncfg = __C\n\n#\n# Training options\n#\n__C.TRAIN = edict()\n\n# Initial learning rate\n__C.TRAIN.LEARNING_RATE = 0.001\n\n# Momentum\n__C.TRAIN.MOMENTUM = 0.9\n\n# Weight decay, for regularization\n__C.TRAIN.WEIGHT_DECAY = 0.0001\n\n# Factor for reducing the learning rate\n__C.TRAIN.GAMMA = 0.1\n\n# Step size for reducing the learning rate, currently only support one step\n__C.TRAIN.STEPSIZE = [30000]\n\n# Iteration intervals for showing the loss during training, on command line interface\n__C.TRAIN.DISPLAY = 10\n\n# Whether to double the learning rate for bias\n__C.TRAIN.DOUBLE_BIAS = True\n\n# Whether to initialize the weights with truncated normal distribution \n__C.TRAIN.TRUNCATED = False\n\n# Whether to have weight decay on bias as well\n__C.TRAIN.BIAS_DECAY = False\n\n# Whether to add ground truth boxes to the pool when sampling regions\n__C.TRAIN.USE_GT = False\n\n# Whether to use aspect-ratio grouping of training images, introduced merely for saving\n# GPU memory\n__C.TRAIN.ASPECT_GROUPING = False\n\n# The number of snapshots kept, older ones are deleted to save space\n__C.TRAIN.SNAPSHOT_KEPT = 3\n\n# The time interval for saving tensorflow summaries\n__C.TRAIN.SUMMARY_INTERVAL = 180\n\n# Scale to use during training (can list multiple scales)\n# The scale is the pixel size of an image's shortest side\n__C.TRAIN.SCALES = (600,)\n\n# Max pixel size of the longest side of a scaled input image\n__C.TRAIN.MAX_SIZE = 1000\n\n# Images to use per minibatch\n__C.TRAIN.IMS_PER_BATCH = 1\n\n# Minibatch size (number of regions of interest [ROIs])\n__C.TRAIN.BATCH_SIZE = 128\n\n# Fraction of minibatch that is labeled foreground (i.e. class > 0)\n__C.TRAIN.FG_FRACTION = 0.25\n\n# Overlap threshold for a ROI to be considered foreground (if >= FG_THRESH)\n__C.TRAIN.FG_THRESH = 0.5\n\n# Overlap threshold for a ROI to be considered background (class = 0 if\n# overlap in [LO, HI))\n__C.TRAIN.BG_THRESH_HI = 0.5\n__C.TRAIN.BG_THRESH_LO = 0.1\n\n# Use horizontally-flipped images during training?\n__C.TRAIN.USE_FLIPPED = True\n\n# Train bounding-box regressors\n__C.TRAIN.BBOX_REG = True\n\n# Overlap required between a ROI and ground-truth box in order for that ROI to\n# be used as a bounding-box regression training example\n__C.TRAIN.BBOX_THRESH = 0.5\n\n# Iterations between snapshots\n__C.TRAIN.SNAPSHOT_ITERS = 5000\n\n# solver.prototxt specifies the snapshot path prefix, this adds an optional\n# infix to yield the path: <prefix>[_<infix>]_iters_XYZ.caffemodel\n__C.TRAIN.SNAPSHOT_PREFIX = 'res101_faster_rcnn'\n\n# Normalize the targets (subtract empirical mean, divide by empirical stddev)\n__C.TRAIN.BBOX_NORMALIZE_TARGETS = True\n\n# Deprecated (inside weights)\n__C.TRAIN.BBOX_INSIDE_WEIGHTS = (1.0, 1.0, 1.0, 1.0)\n\n# Normalize the targets using \"precomputed\" (or made up) means and stdevs\n# (BBOX_NORMALIZE_TARGETS must also be True)\n__C.TRAIN.BBOX_NORMALIZE_TARGETS_PRECOMPUTED = True\n\n__C.TRAIN.BBOX_NORMALIZE_MEANS = (0.0, 0.0, 0.0, 0.0)\n\n__C.TRAIN.BBOX_NORMALIZE_STDS = (0.1, 0.1, 0.2, 0.2)\n\n# Train using these proposals\n__C.TRAIN.PROPOSAL_METHOD = 'gt'\n\n# Make minibatches from images that have similar aspect ratios (i.e. both\n# tall and thin or both short and wide) in order to avoid wasting computation\n# on zero-padding.\n\n# Use RPN to detect objects\n__C.TRAIN.HAS_RPN = True\n\n# IOU >= thresh: positive example\n__C.TRAIN.RPN_POSITIVE_OVERLAP = 0.7\n\n# IOU < thresh: negative example\n__C.TRAIN.RPN_NEGATIVE_OVERLAP = 0.3\n\n# If an anchor satisfied by positive and negative conditions set to negative\n__C.TRAIN.RPN_CLOBBER_POSITIVES = False\n\n# Max number of foreground examples\n__C.TRAIN.RPN_FG_FRACTION = 0.5\n\n# Total number of examples\n__C.TRAIN.RPN_BATCHSIZE = 256\n\n# NMS threshold used on RPN proposals\n__C.TRAIN.RPN_NMS_THRESH = 0.7\n\n# Number of top scoring boxes to keep before apply NMS to RPN proposals\n__C.TRAIN.RPN_PRE_NMS_TOP_N = 12000\n\n# Number of top scoring boxes to keep after applying NMS to RPN proposals\n__C.TRAIN.RPN_POST_NMS_TOP_N = 2000\n\n# Deprecated (outside weights)\n__C.TRAIN.RPN_BBOX_INSIDE_WEIGHTS = (1.0, 1.0, 1.0, 1.0)\n\n# Give the positive RPN examples weight of p * 1 / {num positives}\n# and give negatives a weight of (1 - p)\n# Set to -1.0 to use uniform example weighting\n__C.TRAIN.RPN_POSITIVE_WEIGHT = -1.0\n\n# Whether to use all ground truth bounding boxes for training, \n# For COCO, setting USE_ALL_GT to False will exclude boxes that are flagged as ''iscrowd''\n__C.TRAIN.USE_ALL_GT = True\n\n#\n# Testing options\n#\n__C.TEST = edict()\n\n# Scale to use during testing (can NOT list multiple scales)\n# The scale is the pixel size of an image's shortest side\n__C.TEST.SCALES = (600,)\n\n# Max pixel size of the longest side of a scaled input image\n__C.TEST.MAX_SIZE = 1000\n\n# Overlap threshold used for non-maximum suppression (suppress boxes with\n# IoU >= this threshold)\n__C.TEST.NMS = 0.3\n\n# Experimental: treat the (K+1) units in the cls_score layer as linear\n# predictors (trained, eg, with one-vs-rest SVMs).\n__C.TEST.SVM = False\n\n# Test using bounding-box regressors\n__C.TEST.BBOX_REG = True\n\n# Propose boxes\n__C.TEST.HAS_RPN = False\n\n# Test using these proposals\n__C.TEST.PROPOSAL_METHOD = 'gt'\n\n## NMS threshold used on RPN proposals\n__C.TEST.RPN_NMS_THRESH = 0.7\n\n# Number of top scoring boxes to keep before apply NMS to RPN proposals\n__C.TEST.RPN_PRE_NMS_TOP_N = 6000\n\n# Number of top scoring boxes to keep after applying NMS to RPN proposals\n__C.TEST.RPN_POST_NMS_TOP_N = 300\n\n# Proposal height and width both need to be greater than RPN_MIN_SIZE (at orig image scale)\n# __C.TEST.RPN_MIN_SIZE = 16\n\n# Testing mode, default to be 'nms', 'top' is slower but better\n# See report for details\n__C.TEST.MODE = 'nms'\n\n# Only useful when TEST.MODE is 'top', specifies the number of top proposals to select\n__C.TEST.RPN_TOP_N = 5000\n\n#\n# ResNet options\n#\n\n__C.RESNET = edict()\n\n# Option to set if max-pooling is appended after crop_and_resize. \n# if true, the region will be resized to a square of 2xPOOLING_SIZE, \n# then 2x2 max-pooling is applied; otherwise the region will be directly\n# resized to a square of POOLING_SIZE\n__C.RESNET.MAX_POOL = False\n\n# Number of fixed blocks during training, by default the first of all 4 blocks is fixed\n# Range: 0 (none) to 3 (all)\n__C.RESNET.FIXED_BLOCKS = 1\n\n#\n# MobileNet options\n#\n\n__C.MOBILENET = edict()\n\n# Whether to regularize the depth-wise filters during training\n__C.MOBILENET.REGU_DEPTH = False\n\n# Number of fixed layers during training, by default the bottom 5 of 14 layers is fixed\n# Range: 0 (none) to 12 (all)\n__C.MOBILENET.FIXED_LAYERS = 5\n\n# Weight decay for the mobilenet weights\n__C.MOBILENET.WEIGHT_DECAY = 0.00004\n\n# Depth multiplier\n__C.MOBILENET.DEPTH_MULTIPLIER = 1.\n\n#\n# MISC\n#\n\n# Pixel mean values (BGR order) as a (1, 1, 3) array\n# We use the same pixel mean for all networks even though it's not exactly what\n# they were trained with\n__C.PIXEL_MEANS = np.array([[[102.9801, 115.9465, 122.7717]]])\n\n# For reproducibility\n__C.RNG_SEED = 3\n\n# Root directory of project\n__C.ROOT_DIR = osp.abspath(osp.join(osp.dirname(__file__), '..', '..', '..', '..'))\n\n# Data directory\n__C.DATA_DIR = osp.abspath(osp.join(__C.ROOT_DIR, 'data'))\n\n# Name (or path to) the matlab executable\n__C.MATLAB = 'matlab'\n\n# Place outputs under an experiments directory\n__C.EXP_DIR = 'default'\n\n# Use GPU implementation of non-maximum suppression\n__C.USE_GPU_NMS = True\n\n# Use an end-to-end tensorflow model.\n# Note: models in E2E tensorflow mode have only been tested in feed-forward mode,\n#       but these models are exportable to other tensorflow instances as GraphDef files.\n__C.USE_E2E_TF = True\n\n# Default pooling mode, only 'crop' is available\n__C.POOLING_MODE = 'crop'\n\n# Size of the pooled region after RoI pooling\n__C.POOLING_SIZE = 7\n\n# Anchor scales for RPN\n__C.ANCHOR_SCALES = [8,16,32]\n\n# Anchor ratios for RPN\n__C.ANCHOR_RATIOS = [0.5,1,2]\n\n# Number of filters for the RPN layer\n__C.RPN_CHANNELS = 512\n\n\ndef get_output_dir(imdb, weights_filename):\n  \"\"\"Return the directory where experimental artifacts are placed.\n  If the directory does not exist, it is created.\n\n  A canonical path is built using the name from an imdb and a network\n  (if not None).\n  \"\"\"\n  outdir = osp.abspath(osp.join(__C.ROOT_DIR, 'output', __C.EXP_DIR, imdb.name))\n  if weights_filename is None:\n    weights_filename = 'default'\n  outdir = osp.join(outdir, weights_filename)\n  if not os.path.exists(outdir):\n    os.makedirs(outdir)\n  return outdir\n\n\ndef get_output_tb_dir(imdb, weights_filename):\n  \"\"\"Return the directory where tensorflow summaries are placed.\n  If the directory does not exist, it is created.\n\n  A canonical path is built using the name from an imdb and a network\n  (if not None).\n  \"\"\"\n  outdir = osp.abspath(osp.join(__C.ROOT_DIR, 'tensorboard', __C.EXP_DIR, imdb.name))\n  if weights_filename is None:\n    weights_filename = 'default'\n  outdir = osp.join(outdir, weights_filename)\n  if not os.path.exists(outdir):\n    os.makedirs(outdir)\n  return outdir\n\n\ndef _merge_a_into_b(a, b):\n  \"\"\"Merge config dictionary a into config dictionary b, clobbering the\n  options in b whenever they are also specified in a.\n  \"\"\"\n  if type(a) is not edict:\n    return\n\n  for k, v in a.items():\n    # a must specify keys that are in b\n    if k not in b:\n      raise KeyError('{} is not a valid config key'.format(k))\n\n    # the types must match, too\n    old_type = type(b[k])\n    if old_type is not type(v):\n      if isinstance(b[k], np.ndarray):\n        v = np.array(v, dtype=b[k].dtype)\n      else:\n        raise ValueError(('Type mismatch ({} vs. {}) '\n                          'for config key: {}').format(type(b[k]),\n                                                       type(v), k))\n\n    # recursively merge dicts\n    if type(v) is edict:\n      try:\n        _merge_a_into_b(a[k], b[k])\n      except:\n        print(('Error under config key: {}'.format(k)))\n        raise\n    else:\n      b[k] = v\n\n\ndef cfg_from_file(filename):\n  \"\"\"Load a config file and merge it into the default options.\"\"\"\n  import yaml\n  with open(filename, 'r') as f:\n    yaml_cfg = edict(yaml.load(f))\n\n  _merge_a_into_b(yaml_cfg, __C)\n\n\ndef cfg_from_list(cfg_list):\n  \"\"\"Set config keys via list (e.g., from command line).\"\"\"\n  from ast import literal_eval\n  assert len(cfg_list) % 2 == 0\n  for k, v in zip(cfg_list[0::2], cfg_list[1::2]):\n    key_list = k.split('.')\n    d = __C\n    for subkey in key_list[:-1]:\n      assert subkey in d\n      d = d[subkey]\n    subkey = key_list[-1]\n    assert subkey in d\n    try:\n      value = literal_eval(v)\n    except:\n      # handle the case when v is a string literal\n      value = v\n    assert type(value) == type(d[subkey]), \\\n      'type {} does not match original type {}'.format(\n        type(value), type(d[subkey]))\n    d[subkey] = value\n"
  },
  {
    "path": "src/tools/voc_eval_lib/model/nms_wrapper.py",
    "content": "# --------------------------------------------------------\n# Fast R-CNN\n# Copyright (c) 2015 Microsoft\n# Licensed under The MIT License [see LICENSE for details]\n# Written by Ross Girshick\n# --------------------------------------------------------\nfrom __future__ import absolute_import\nfrom __future__ import division\nfrom __future__ import print_function\n\nfrom model.config import cfg\nfrom nms.gpu_nms import gpu_nms\nfrom nms.cpu_nms import cpu_nms\n\ndef nms(dets, thresh, force_cpu=False):\n  \"\"\"Dispatch to either CPU or GPU NMS implementations.\"\"\"\n\n  if dets.shape[0] == 0:\n    return []\n  if cfg.USE_GPU_NMS and not force_cpu:\n    return gpu_nms(dets, thresh, device_id=0)\n  else:\n    return cpu_nms(dets, thresh)\n"
  },
  {
    "path": "src/tools/voc_eval_lib/model/test.py",
    "content": "# --------------------------------------------------------\n# Tensorflow Faster R-CNN\n# Licensed under The MIT License [see LICENSE for details]\n# Written by Xinlei Chen\n# --------------------------------------------------------\nfrom __future__ import absolute_import\nfrom __future__ import division\nfrom __future__ import print_function\n\nimport cv2\nimport numpy as np\ntry:\n  import cPickle as pickle\nexcept ImportError:\n  import pickle\nimport os\nimport math\n\nfrom utils.timer import Timer\nfrom utils.blob import im_list_to_blob\n\nfrom model.config import cfg, get_output_dir\nfrom model.bbox_transform import clip_boxes, bbox_transform_inv\n# from model.nms_wrapper import nms  # need to compile cython nms before import nms\nnms = None  # not needed in pascal evaluation\n\ndef _get_image_blob(im):\n  \"\"\"Converts an image into a network input.\n  Arguments:\n    im (ndarray): a color image in BGR order\n  Returns:\n    blob (ndarray): a data blob holding an image pyramid\n    im_scale_factors (list): list of image scales (relative to im) used\n      in the image pyramid\n  \"\"\"\n  im_orig = im.astype(np.float32, copy=True)\n  im_orig -= cfg.PIXEL_MEANS\n\n  im_shape = im_orig.shape\n  im_size_min = np.min(im_shape[0:2])\n  im_size_max = np.max(im_shape[0:2])\n\n  processed_ims = []\n  im_scale_factors = []\n\n  for target_size in cfg.TEST.SCALES:\n    im_scale = float(target_size) / float(im_size_min)\n    # Prevent the biggest axis from being more than MAX_SIZE\n    if np.round(im_scale * im_size_max) > cfg.TEST.MAX_SIZE:\n      im_scale = float(cfg.TEST.MAX_SIZE) / float(im_size_max)\n    im = cv2.resize(im_orig, None, None, fx=im_scale, fy=im_scale,\n            interpolation=cv2.INTER_LINEAR)\n    im_scale_factors.append(im_scale)\n    processed_ims.append(im)\n\n  # Create a blob to hold the input images\n  blob = im_list_to_blob(processed_ims)\n\n  return blob, np.array(im_scale_factors)\n\ndef _get_blobs(im):\n  \"\"\"Convert an image and RoIs within that image into network inputs.\"\"\"\n  blobs = {}\n  blobs['data'], im_scale_factors = _get_image_blob(im)\n\n  return blobs, im_scale_factors\n\ndef _clip_boxes(boxes, im_shape):\n  \"\"\"Clip boxes to image boundaries.\"\"\"\n  # x1 >= 0\n  boxes[:, 0::4] = np.maximum(boxes[:, 0::4], 0)\n  # y1 >= 0\n  boxes[:, 1::4] = np.maximum(boxes[:, 1::4], 0)\n  # x2 < im_shape[1]\n  boxes[:, 2::4] = np.minimum(boxes[:, 2::4], im_shape[1] - 1)\n  # y2 < im_shape[0]\n  boxes[:, 3::4] = np.minimum(boxes[:, 3::4], im_shape[0] - 1)\n  return boxes\n\ndef _rescale_boxes(boxes, inds, scales):\n  \"\"\"Rescale boxes according to image rescaling.\"\"\"\n  for i in range(boxes.shape[0]):\n    boxes[i,:] = boxes[i,:] / scales[int(inds[i])]\n\n  return boxes\n\ndef im_detect(sess, net, im):\n  blobs, im_scales = _get_blobs(im)\n  assert len(im_scales) == 1, \"Only single-image batch implemented\"\n\n  im_blob = blobs['data']\n  blobs['im_info'] = np.array([im_blob.shape[1], im_blob.shape[2], im_scales[0]], dtype=np.float32)\n\n  _, scores, bbox_pred, rois = net.test_image(sess, blobs['data'], blobs['im_info'])\n  \n  boxes = rois[:, 1:5] / im_scales[0]\n  scores = np.reshape(scores, [scores.shape[0], -1])\n  bbox_pred = np.reshape(bbox_pred, [bbox_pred.shape[0], -1])\n  if cfg.TEST.BBOX_REG:\n    # Apply bounding-box regression deltas\n    box_deltas = bbox_pred\n    pred_boxes = bbox_transform_inv(boxes, box_deltas)\n    pred_boxes = _clip_boxes(pred_boxes, im.shape)\n  else:\n    # Simply repeat the boxes, once for each class\n    pred_boxes = np.tile(boxes, (1, scores.shape[1]))\n\n  return scores, pred_boxes\n\ndef apply_nms(all_boxes, thresh):\n  \"\"\"Apply non-maximum suppression to all predicted boxes output by the\n  test_net method.\n  \"\"\"\n  num_classes = len(all_boxes)\n  num_images = len(all_boxes[0])\n  nms_boxes = [[[] for _ in range(num_images)] for _ in range(num_classes)]\n  for cls_ind in range(num_classes):\n    for im_ind in range(num_images):\n      dets = np.array(all_boxes[cls_ind][im_ind], dtype=np.float32)\n      if len(dets) == 0:\n        continue\n      #print('dets', dets)\n      x1 = dets[:, 0]\n      y1 = dets[:, 1]\n      x2 = dets[:, 2]\n      y2 = dets[:, 3]\n      scores = dets[:, 4]\n      inds = np.where((x2 > x1) & (y2 > y1))[0]\n      dets = dets[inds,:]\n      if dets == []:\n        continue\n\n      keep = nms(dets, thresh)\n      if len(keep) == 0:\n        continue\n      nms_boxes[cls_ind][im_ind] = dets[keep, :].copy()\n  return nms_boxes\n\ndef test_net(sess, net, imdb, weights_filename, max_per_image=100, thresh=0.):\n  np.random.seed(cfg.RNG_SEED)\n  \"\"\"Test a Fast R-CNN network on an image database.\"\"\"\n  num_images = len(imdb.image_index)\n  # all detections are collected into:\n  #  all_boxes[cls][image] = N x 5 array of detections in\n  #  (x1, y1, x2, y2, score)\n  all_boxes = [[[] for _ in range(num_images)]\n         for _ in range(imdb.num_classes)]\n\n  output_dir = get_output_dir(imdb, weights_filename)\n  # timers\n  _t = {'im_detect' : Timer(), 'misc' : Timer()}\n\n  for i in range(num_images):\n    im = cv2.imread(imdb.image_path_at(i))\n\n    _t['im_detect'].tic()\n    scores, boxes = im_detect(sess, net, im)\n    _t['im_detect'].toc()\n\n    _t['misc'].tic()\n\n    # skip j = 0, because it's the background class\n    for j in range(1, imdb.num_classes):\n      inds = np.where(scores[:, j] > thresh)[0]\n      cls_scores = scores[inds, j]\n      cls_boxes = boxes[inds, j*4:(j+1)*4]\n      cls_dets = np.hstack((cls_boxes, cls_scores[:, np.newaxis])) \\\n        .astype(np.float32, copy=False)\n      keep = nms(cls_dets, cfg.TEST.NMS)\n      cls_dets = cls_dets[keep, :]\n      all_boxes[j][i] = cls_dets\n\n    # Limit to max_per_image detections *over all classes*\n    if max_per_image > 0:\n      image_scores = np.hstack([all_boxes[j][i][:, -1]\n                    for j in range(1, imdb.num_classes)])\n      if len(image_scores) > max_per_image:\n        image_thresh = np.sort(image_scores)[-max_per_image]\n        for j in range(1, imdb.num_classes):\n          keep = np.where(all_boxes[j][i][:, -1] >= image_thresh)[0]\n          all_boxes[j][i] = all_boxes[j][i][keep, :]\n    _t['misc'].toc()\n\n    print('im_detect: {:d}/{:d} {:.3f}s {:.3f}s' \\\n        .format(i + 1, num_images, _t['im_detect'].average_time,\n            _t['misc'].average_time))\n\n  det_file = os.path.join(output_dir, 'detections.pkl')\n  with open(det_file, 'wb') as f:\n    pickle.dump(all_boxes, f, pickle.HIGHEST_PROTOCOL)\n\n  print('Evaluating detections')\n  imdb.evaluate_detections(all_boxes, output_dir)\n"
  },
  {
    "path": "src/tools/voc_eval_lib/nms/.gitignore",
    "content": ""
  },
  {
    "path": "src/tools/voc_eval_lib/nms/__init__.py",
    "content": ""
  },
  {
    "path": "src/tools/voc_eval_lib/nms/cpu_nms.c",
    "content": "/* Generated by Cython 0.20.1 on Wed Oct  5 13:15:30 2016 */\n\n#define PY_SSIZE_T_CLEAN\n#ifndef CYTHON_USE_PYLONG_INTERNALS\n#ifdef PYLONG_BITS_IN_DIGIT\n#define CYTHON_USE_PYLONG_INTERNALS 0\n#else\n#include \"pyconfig.h\"\n#ifdef PYLONG_BITS_IN_DIGIT\n#define CYTHON_USE_PYLONG_INTERNALS 1\n#else\n#define CYTHON_USE_PYLONG_INTERNALS 0\n#endif\n#endif\n#endif\n#include \"Python.h\"\n#ifndef Py_PYTHON_H\n    #error Python headers needed to compile C extensions, please install development version of Python.\n#elif PY_VERSION_HEX < 0x02040000\n    #error Cython requires Python 2.4+.\n#else\n#define CYTHON_ABI \"0_20_1\"\n#include <stddef.h> /* For offsetof */\n#ifndef offsetof\n#define offsetof(type, member) ( (size_t) & ((type*)0) -> member )\n#endif\n#if !defined(WIN32) && !defined(MS_WINDOWS)\n  #ifndef __stdcall\n    #define __stdcall\n  #endif\n  #ifndef __cdecl\n    #define __cdecl\n  #endif\n  #ifndef __fastcall\n    #define __fastcall\n  #endif\n#endif\n#ifndef DL_IMPORT\n  #define DL_IMPORT(t) t\n#endif\n#ifndef DL_EXPORT\n  #define DL_EXPORT(t) t\n#endif\n#ifndef PY_LONG_LONG\n  #define PY_LONG_LONG LONG_LONG\n#endif\n#ifndef Py_HUGE_VAL\n  #define Py_HUGE_VAL HUGE_VAL\n#endif\n#ifdef PYPY_VERSION\n#define CYTHON_COMPILING_IN_PYPY 1\n#define CYTHON_COMPILING_IN_CPYTHON 0\n#else\n#define CYTHON_COMPILING_IN_PYPY 0\n#define CYTHON_COMPILING_IN_CPYTHON 1\n#endif\n#if CYTHON_COMPILING_IN_PYPY\n#define Py_OptimizeFlag 0\n#endif\n#if PY_VERSION_HEX < 0x02050000\n  typedef int Py_ssize_t;\n  #define PY_SSIZE_T_MAX INT_MAX\n  #define PY_SSIZE_T_MIN INT_MIN\n  #define PY_FORMAT_SIZE_T \"\"\n  #define CYTHON_FORMAT_SSIZE_T \"\"\n  #define PyInt_FromSsize_t(z) PyInt_FromLong(z)\n  #define PyInt_AsSsize_t(o)   __Pyx_PyInt_As_int(o)\n  #define PyNumber_Index(o)    ((PyNumber_Check(o) && !PyFloat_Check(o)) ? PyNumber_Int(o) : \\\n                                (PyErr_Format(PyExc_TypeError, \\\n                                              \"expected index value, got %.200s\", Py_TYPE(o)->tp_name), \\\n                                 (PyObject*)0))\n  #define __Pyx_PyIndex_Check(o) (PyNumber_Check(o) && !PyFloat_Check(o) && \\\n                                  !PyComplex_Check(o))\n  #define PyIndex_Check __Pyx_PyIndex_Check\n  #define PyErr_WarnEx(category, message, stacklevel) PyErr_Warn(category, message)\n  #define __PYX_BUILD_PY_SSIZE_T \"i\"\n#else\n  #define __PYX_BUILD_PY_SSIZE_T \"n\"\n  #define CYTHON_FORMAT_SSIZE_T \"z\"\n  #define __Pyx_PyIndex_Check PyIndex_Check\n#endif\n#if PY_VERSION_HEX < 0x02060000\n  #define Py_REFCNT(ob) (((PyObject*)(ob))->ob_refcnt)\n  #define Py_TYPE(ob)   (((PyObject*)(ob))->ob_type)\n  #define Py_SIZE(ob)   (((PyVarObject*)(ob))->ob_size)\n  #define PyVarObject_HEAD_INIT(type, size) \\\n          PyObject_HEAD_INIT(type) size,\n  #define PyType_Modified(t)\n  typedef struct {\n     void *buf;\n     PyObject *obj;\n     Py_ssize_t len;\n     Py_ssize_t itemsize;\n     int readonly;\n     int ndim;\n     char *format;\n     Py_ssize_t *shape;\n     Py_ssize_t *strides;\n     Py_ssize_t *suboffsets;\n     void *internal;\n  } Py_buffer;\n  #define PyBUF_SIMPLE 0\n  #define PyBUF_WRITABLE 0x0001\n  #define PyBUF_FORMAT 0x0004\n  #define PyBUF_ND 0x0008\n  #define PyBUF_STRIDES (0x0010 | PyBUF_ND)\n  #define PyBUF_C_CONTIGUOUS (0x0020 | PyBUF_STRIDES)\n  #define PyBUF_F_CONTIGUOUS (0x0040 | PyBUF_STRIDES)\n  #define PyBUF_ANY_CONTIGUOUS (0x0080 | PyBUF_STRIDES)\n  #define PyBUF_INDIRECT (0x0100 | PyBUF_STRIDES)\n  #define PyBUF_RECORDS (PyBUF_STRIDES | PyBUF_FORMAT | PyBUF_WRITABLE)\n  #define PyBUF_FULL (PyBUF_INDIRECT | PyBUF_FORMAT | PyBUF_WRITABLE)\n  typedef int (*getbufferproc)(PyObject *, Py_buffer *, int);\n  typedef void (*releasebufferproc)(PyObject *, Py_buffer *);\n#endif\n#if PY_MAJOR_VERSION < 3\n  #define __Pyx_BUILTIN_MODULE_NAME \"__builtin__\"\n  #define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) \\\n          PyCode_New(a+k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)\n  #define __Pyx_DefaultClassType PyClass_Type\n#else\n  #define __Pyx_BUILTIN_MODULE_NAME \"builtins\"\n  #define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) \\\n          PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)\n  #define __Pyx_DefaultClassType PyType_Type\n#endif\n#if PY_VERSION_HEX < 0x02060000\n  #define PyUnicode_FromString(s) PyUnicode_Decode(s, strlen(s), \"UTF-8\", \"strict\")\n#endif\n#if PY_MAJOR_VERSION >= 3\n  #define Py_TPFLAGS_CHECKTYPES 0\n  #define Py_TPFLAGS_HAVE_INDEX 0\n#endif\n#if (PY_VERSION_HEX < 0x02060000) || (PY_MAJOR_VERSION >= 3)\n  #define Py_TPFLAGS_HAVE_NEWBUFFER 0\n#endif\n#if PY_VERSION_HEX < 0x02060000\n  #define Py_TPFLAGS_HAVE_VERSION_TAG 0\n#endif\n#if PY_VERSION_HEX < 0x02060000 && !defined(Py_TPFLAGS_IS_ABSTRACT)\n  #define Py_TPFLAGS_IS_ABSTRACT 0\n#endif\n#if PY_VERSION_HEX < 0x030400a1 && !defined(Py_TPFLAGS_HAVE_FINALIZE)\n  #define Py_TPFLAGS_HAVE_FINALIZE 0\n#endif\n#if PY_VERSION_HEX > 0x03030000 && defined(PyUnicode_KIND)\n  #define CYTHON_PEP393_ENABLED 1\n  #define __Pyx_PyUnicode_READY(op)       (likely(PyUnicode_IS_READY(op)) ? \\\n                                              0 : _PyUnicode_Ready((PyObject *)(op)))\n  #define __Pyx_PyUnicode_GET_LENGTH(u)   PyUnicode_GET_LENGTH(u)\n  #define __Pyx_PyUnicode_READ_CHAR(u, i) PyUnicode_READ_CHAR(u, i)\n  #define __Pyx_PyUnicode_KIND(u)         PyUnicode_KIND(u)\n  #define __Pyx_PyUnicode_DATA(u)         PyUnicode_DATA(u)\n  #define __Pyx_PyUnicode_READ(k, d, i)   PyUnicode_READ(k, d, i)\n#else\n  #define CYTHON_PEP393_ENABLED 0\n  #define __Pyx_PyUnicode_READY(op)       (0)\n  #define __Pyx_PyUnicode_GET_LENGTH(u)   PyUnicode_GET_SIZE(u)\n  #define __Pyx_PyUnicode_READ_CHAR(u, i) ((Py_UCS4)(PyUnicode_AS_UNICODE(u)[i]))\n  #define __Pyx_PyUnicode_KIND(u)         (sizeof(Py_UNICODE))\n  #define __Pyx_PyUnicode_DATA(u)         ((void*)PyUnicode_AS_UNICODE(u))\n  #define __Pyx_PyUnicode_READ(k, d, i)   ((void)(k), (Py_UCS4)(((Py_UNICODE*)d)[i]))\n#endif\n#if CYTHON_COMPILING_IN_PYPY\n  #define __Pyx_PyUnicode_Concat(a, b)      PyNumber_Add(a, b)\n  #define __Pyx_PyUnicode_ConcatSafe(a, b)  PyNumber_Add(a, b)\n#else\n  #define __Pyx_PyUnicode_Concat(a, b)      PyUnicode_Concat(a, b)\n  #define __Pyx_PyUnicode_ConcatSafe(a, b)  ((unlikely((a) == Py_None) || unlikely((b) == Py_None)) ? \\\n      PyNumber_Add(a, b) : __Pyx_PyUnicode_Concat(a, b))\n#endif\n#define __Pyx_PyString_FormatSafe(a, b)  ((unlikely((a) == Py_None)) ? PyNumber_Remainder(a, b) : __Pyx_PyString_Format(a, b))\n#define __Pyx_PyUnicode_FormatSafe(a, b)  ((unlikely((a) == Py_None)) ? PyNumber_Remainder(a, b) : PyUnicode_Format(a, b))\n#if PY_MAJOR_VERSION >= 3\n  #define __Pyx_PyString_Format(a, b)  PyUnicode_Format(a, b)\n#else\n  #define __Pyx_PyString_Format(a, b)  PyString_Format(a, b)\n#endif\n#if PY_MAJOR_VERSION >= 3\n  #define PyBaseString_Type            PyUnicode_Type\n  #define PyStringObject               PyUnicodeObject\n  #define PyString_Type                PyUnicode_Type\n  #define PyString_Check               PyUnicode_Check\n  #define PyString_CheckExact          PyUnicode_CheckExact\n#endif\n#if PY_VERSION_HEX < 0x02060000\n  #define PyBytesObject                PyStringObject\n  #define PyBytes_Type                 PyString_Type\n  #define PyBytes_Check                PyString_Check\n  #define PyBytes_CheckExact           PyString_CheckExact\n  #define PyBytes_FromString           PyString_FromString\n  #define PyBytes_FromStringAndSize    PyString_FromStringAndSize\n  #define PyBytes_FromFormat           PyString_FromFormat\n  #define PyBytes_DecodeEscape         PyString_DecodeEscape\n  #define PyBytes_AsString             PyString_AsString\n  #define PyBytes_AsStringAndSize      PyString_AsStringAndSize\n  #define PyBytes_Size                 PyString_Size\n  #define PyBytes_AS_STRING            PyString_AS_STRING\n  #define PyBytes_GET_SIZE             PyString_GET_SIZE\n  #define PyBytes_Repr                 PyString_Repr\n  #define PyBytes_Concat               PyString_Concat\n  #define PyBytes_ConcatAndDel         PyString_ConcatAndDel\n#endif\n#if PY_MAJOR_VERSION >= 3\n  #define __Pyx_PyBaseString_Check(obj) PyUnicode_Check(obj)\n  #define __Pyx_PyBaseString_CheckExact(obj) PyUnicode_CheckExact(obj)\n#else\n  #define __Pyx_PyBaseString_Check(obj) (PyString_CheckExact(obj) || PyUnicode_CheckExact(obj) || \\\n                                         PyString_Check(obj) || PyUnicode_Check(obj))\n  #define __Pyx_PyBaseString_CheckExact(obj) (PyString_CheckExact(obj) || PyUnicode_CheckExact(obj))\n#endif\n#if PY_VERSION_HEX < 0x02060000\n  #define PySet_Check(obj)             PyObject_TypeCheck(obj, &PySet_Type)\n  #define PyFrozenSet_Check(obj)       PyObject_TypeCheck(obj, &PyFrozenSet_Type)\n#endif\n#ifndef PySet_CheckExact\n  #define PySet_CheckExact(obj)        (Py_TYPE(obj) == &PySet_Type)\n#endif\n#define __Pyx_TypeCheck(obj, type) PyObject_TypeCheck(obj, (PyTypeObject *)type)\n#if PY_MAJOR_VERSION >= 3\n  #define PyIntObject                  PyLongObject\n  #define PyInt_Type                   PyLong_Type\n  #define PyInt_Check(op)              PyLong_Check(op)\n  #define PyInt_CheckExact(op)         PyLong_CheckExact(op)\n  #define PyInt_FromString             PyLong_FromString\n  #define PyInt_FromUnicode            PyLong_FromUnicode\n  #define PyInt_FromLong               PyLong_FromLong\n  #define PyInt_FromSize_t             PyLong_FromSize_t\n  #define PyInt_FromSsize_t            PyLong_FromSsize_t\n  #define PyInt_AsLong                 PyLong_AsLong\n  #define PyInt_AS_LONG                PyLong_AS_LONG\n  #define PyInt_AsSsize_t              PyLong_AsSsize_t\n  #define PyInt_AsUnsignedLongMask     PyLong_AsUnsignedLongMask\n  #define PyInt_AsUnsignedLongLongMask PyLong_AsUnsignedLongLongMask\n  #define PyNumber_Int                 PyNumber_Long\n#endif\n#if PY_MAJOR_VERSION >= 3\n  #define PyBoolObject                 PyLongObject\n#endif\n#if PY_VERSION_HEX < 0x030200A4\n  typedef long Py_hash_t;\n  #define __Pyx_PyInt_FromHash_t PyInt_FromLong\n  #define __Pyx_PyInt_AsHash_t   PyInt_AsLong\n#else\n  #define __Pyx_PyInt_FromHash_t PyInt_FromSsize_t\n  #define __Pyx_PyInt_AsHash_t   PyInt_AsSsize_t\n#endif\n#if (PY_MAJOR_VERSION < 3) || (PY_VERSION_HEX >= 0x03010300)\n  #define __Pyx_PySequence_GetSlice(obj, a, b) PySequence_GetSlice(obj, a, b)\n  #define __Pyx_PySequence_SetSlice(obj, a, b, value) PySequence_SetSlice(obj, a, b, value)\n  #define __Pyx_PySequence_DelSlice(obj, a, b) PySequence_DelSlice(obj, a, b)\n#else\n  #define __Pyx_PySequence_GetSlice(obj, a, b) (unlikely(!(obj)) ? \\\n        (PyErr_SetString(PyExc_SystemError, \"null argument to internal routine\"), (PyObject*)0) : \\\n        (likely((obj)->ob_type->tp_as_mapping) ? (PySequence_GetSlice(obj, a, b)) : \\\n            (PyErr_Format(PyExc_TypeError, \"'%.200s' object is unsliceable\", (obj)->ob_type->tp_name), (PyObject*)0)))\n  #define __Pyx_PySequence_SetSlice(obj, a, b, value) (unlikely(!(obj)) ? \\\n        (PyErr_SetString(PyExc_SystemError, \"null argument to internal routine\"), -1) : \\\n        (likely((obj)->ob_type->tp_as_mapping) ? (PySequence_SetSlice(obj, a, b, value)) : \\\n            (PyErr_Format(PyExc_TypeError, \"'%.200s' object doesn't support slice assignment\", (obj)->ob_type->tp_name), -1)))\n  #define __Pyx_PySequence_DelSlice(obj, a, b) (unlikely(!(obj)) ? \\\n        (PyErr_SetString(PyExc_SystemError, \"null argument to internal routine\"), -1) : \\\n        (likely((obj)->ob_type->tp_as_mapping) ? (PySequence_DelSlice(obj, a, b)) : \\\n            (PyErr_Format(PyExc_TypeError, \"'%.200s' object doesn't support slice deletion\", (obj)->ob_type->tp_name), -1)))\n#endif\n#if PY_MAJOR_VERSION >= 3\n  #define PyMethod_New(func, self, klass) ((self) ? PyMethod_New(func, self) : PyInstanceMethod_New(func))\n#endif\n#if PY_VERSION_HEX < 0x02050000\n  #define __Pyx_GetAttrString(o,n)   PyObject_GetAttrString((o),((char *)(n)))\n  #define __Pyx_SetAttrString(o,n,a) PyObject_SetAttrString((o),((char *)(n)),(a))\n  #define __Pyx_DelAttrString(o,n)   PyObject_DelAttrString((o),((char *)(n)))\n#else\n  #define __Pyx_GetAttrString(o,n)   PyObject_GetAttrString((o),(n))\n  #define __Pyx_SetAttrString(o,n,a) PyObject_SetAttrString((o),(n),(a))\n  #define __Pyx_DelAttrString(o,n)   PyObject_DelAttrString((o),(n))\n#endif\n#if PY_VERSION_HEX < 0x02050000\n  #define __Pyx_NAMESTR(n) ((char *)(n))\n  #define __Pyx_DOCSTR(n)  ((char *)(n))\n#else\n  #define __Pyx_NAMESTR(n) (n)\n  #define __Pyx_DOCSTR(n)  (n)\n#endif\n#ifndef CYTHON_INLINE\n  #if defined(__GNUC__)\n    #define CYTHON_INLINE __inline__\n  #elif defined(_MSC_VER)\n    #define CYTHON_INLINE __inline\n  #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L\n    #define CYTHON_INLINE inline\n  #else\n    #define CYTHON_INLINE\n  #endif\n#endif\n#ifndef CYTHON_RESTRICT\n  #if defined(__GNUC__)\n    #define CYTHON_RESTRICT __restrict__\n  #elif defined(_MSC_VER) && _MSC_VER >= 1400\n    #define CYTHON_RESTRICT __restrict\n  #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L\n    #define CYTHON_RESTRICT restrict\n  #else\n    #define CYTHON_RESTRICT\n  #endif\n#endif\n#ifdef NAN\n#define __PYX_NAN() ((float) NAN)\n#else\nstatic CYTHON_INLINE float __PYX_NAN() {\n  /* Initialize NaN. The sign is irrelevant, an exponent with all bits 1 and\n   a nonzero mantissa means NaN. If the first bit in the mantissa is 1, it is\n   a quiet NaN. */\n  float value;\n  memset(&value, 0xFF, sizeof(value));\n  return value;\n}\n#endif\n\n\n#if PY_MAJOR_VERSION >= 3\n  #define __Pyx_PyNumber_Divide(x,y)         PyNumber_TrueDivide(x,y)\n  #define __Pyx_PyNumber_InPlaceDivide(x,y)  PyNumber_InPlaceTrueDivide(x,y)\n#else\n  #define __Pyx_PyNumber_Divide(x,y)         PyNumber_Divide(x,y)\n  #define __Pyx_PyNumber_InPlaceDivide(x,y)  PyNumber_InPlaceDivide(x,y)\n#endif\n\n#ifndef __PYX_EXTERN_C\n  #ifdef __cplusplus\n    #define __PYX_EXTERN_C extern \"C\"\n  #else\n    #define __PYX_EXTERN_C extern\n  #endif\n#endif\n\n#if defined(WIN32) || defined(MS_WINDOWS)\n#define _USE_MATH_DEFINES\n#endif\n#include <math.h>\n#define __PYX_HAVE__nms__cpu_nms\n#define __PYX_HAVE_API__nms__cpu_nms\n#include \"string.h\"\n#include \"stdio.h\"\n#include \"stdlib.h\"\n#include \"numpy/arrayobject.h\"\n#include \"numpy/ufuncobject.h\"\n#ifdef _OPENMP\n#include <omp.h>\n#endif /* _OPENMP */\n\n#ifdef PYREX_WITHOUT_ASSERTIONS\n#define CYTHON_WITHOUT_ASSERTIONS\n#endif\n\n#ifndef CYTHON_UNUSED\n# if defined(__GNUC__)\n#   if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4))\n#     define CYTHON_UNUSED __attribute__ ((__unused__))\n#   else\n#     define CYTHON_UNUSED\n#   endif\n# elif defined(__ICC) || (defined(__INTEL_COMPILER) && !defined(_MSC_VER))\n#   define CYTHON_UNUSED __attribute__ ((__unused__))\n# else\n#   define CYTHON_UNUSED\n# endif\n#endif\ntypedef struct {PyObject **p; char *s; const Py_ssize_t n; const char* encoding;\n                const char is_unicode; const char is_str; const char intern; } __Pyx_StringTabEntry; /*proto*/\n\n#define __PYX_DEFAULT_STRING_ENCODING_IS_ASCII 0\n#define __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT 0\n#define __PYX_DEFAULT_STRING_ENCODING \"\"\n#define __Pyx_PyObject_FromString __Pyx_PyBytes_FromString\n#define __Pyx_PyObject_FromStringAndSize __Pyx_PyBytes_FromStringAndSize\n#define __Pyx_fits_Py_ssize_t(v, type, is_signed)  (    \\\n    (sizeof(type) < sizeof(Py_ssize_t))  ||             \\\n    (sizeof(type) > sizeof(Py_ssize_t) &&               \\\n          likely(v < (type)PY_SSIZE_T_MAX ||            \\\n                 v == (type)PY_SSIZE_T_MAX)  &&         \\\n          (!is_signed || likely(v > (type)PY_SSIZE_T_MIN ||       \\\n                                v == (type)PY_SSIZE_T_MIN)))  ||  \\\n    (sizeof(type) == sizeof(Py_ssize_t) &&              \\\n          (is_signed || likely(v < (type)PY_SSIZE_T_MAX ||        \\\n                               v == (type)PY_SSIZE_T_MAX)))  )\nstatic CYTHON_INLINE char* __Pyx_PyObject_AsString(PyObject*);\nstatic CYTHON_INLINE char* __Pyx_PyObject_AsStringAndSize(PyObject*, Py_ssize_t* length);\n#define __Pyx_PyByteArray_FromString(s) PyByteArray_FromStringAndSize((const char*)s, strlen((const char*)s))\n#define __Pyx_PyByteArray_FromStringAndSize(s, l) PyByteArray_FromStringAndSize((const char*)s, l)\n#define __Pyx_PyBytes_FromString        PyBytes_FromString\n#define __Pyx_PyBytes_FromStringAndSize PyBytes_FromStringAndSize\nstatic CYTHON_INLINE PyObject* __Pyx_PyUnicode_FromString(char*);\n#if PY_MAJOR_VERSION < 3\n    #define __Pyx_PyStr_FromString        __Pyx_PyBytes_FromString\n    #define __Pyx_PyStr_FromStringAndSize __Pyx_PyBytes_FromStringAndSize\n#else\n    #define __Pyx_PyStr_FromString        __Pyx_PyUnicode_FromString\n    #define __Pyx_PyStr_FromStringAndSize __Pyx_PyUnicode_FromStringAndSize\n#endif\n#define __Pyx_PyObject_AsSString(s)    ((signed char*) __Pyx_PyObject_AsString(s))\n#define __Pyx_PyObject_AsUString(s)    ((unsigned char*) __Pyx_PyObject_AsString(s))\n#define __Pyx_PyObject_FromUString(s)  __Pyx_PyObject_FromString((char*)s)\n#define __Pyx_PyBytes_FromUString(s)   __Pyx_PyBytes_FromString((char*)s)\n#define __Pyx_PyByteArray_FromUString(s)   __Pyx_PyByteArray_FromString((char*)s)\n#define __Pyx_PyStr_FromUString(s)     __Pyx_PyStr_FromString((char*)s)\n#define __Pyx_PyUnicode_FromUString(s) __Pyx_PyUnicode_FromString((char*)s)\n#if PY_MAJOR_VERSION < 3\nstatic CYTHON_INLINE size_t __Pyx_Py_UNICODE_strlen(const Py_UNICODE *u)\n{\n    const Py_UNICODE *u_end = u;\n    while (*u_end++) ;\n    return u_end - u - 1;\n}\n#else\n#define __Pyx_Py_UNICODE_strlen Py_UNICODE_strlen\n#endif\n#define __Pyx_PyUnicode_FromUnicode(u)       PyUnicode_FromUnicode(u, __Pyx_Py_UNICODE_strlen(u))\n#define __Pyx_PyUnicode_FromUnicodeAndLength PyUnicode_FromUnicode\n#define __Pyx_PyUnicode_AsUnicode            PyUnicode_AsUnicode\n#define __Pyx_Owned_Py_None(b) (Py_INCREF(Py_None), Py_None)\n#define __Pyx_PyBool_FromLong(b) ((b) ? (Py_INCREF(Py_True), Py_True) : (Py_INCREF(Py_False), Py_False))\nstatic CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject*);\nstatic CYTHON_INLINE PyObject* __Pyx_PyNumber_Int(PyObject* x);\nstatic CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject*);\nstatic CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t);\n#if CYTHON_COMPILING_IN_CPYTHON\n#define __pyx_PyFloat_AsDouble(x) (PyFloat_CheckExact(x) ? PyFloat_AS_DOUBLE(x) : PyFloat_AsDouble(x))\n#else\n#define __pyx_PyFloat_AsDouble(x) PyFloat_AsDouble(x)\n#endif\n#define __pyx_PyFloat_AsFloat(x) ((float) __pyx_PyFloat_AsDouble(x))\n#if PY_MAJOR_VERSION < 3 && __PYX_DEFAULT_STRING_ENCODING_IS_ASCII\nstatic int __Pyx_sys_getdefaultencoding_not_ascii;\nstatic int __Pyx_init_sys_getdefaultencoding_params(void) {\n    PyObject* sys = NULL;\n    PyObject* default_encoding = NULL;\n    PyObject* ascii_chars_u = NULL;\n    PyObject* ascii_chars_b = NULL;\n    sys = PyImport_ImportModule(\"sys\");\n    if (sys == NULL) goto bad;\n    default_encoding = PyObject_CallMethod(sys, (char*) (const char*) \"getdefaultencoding\", NULL);\n    if (default_encoding == NULL) goto bad;\n    if (strcmp(PyBytes_AsString(default_encoding), \"ascii\") == 0) {\n        __Pyx_sys_getdefaultencoding_not_ascii = 0;\n    } else {\n        const char* default_encoding_c = PyBytes_AS_STRING(default_encoding);\n        char ascii_chars[128];\n        int c;\n        for (c = 0; c < 128; c++) {\n            ascii_chars[c] = c;\n        }\n        __Pyx_sys_getdefaultencoding_not_ascii = 1;\n        ascii_chars_u = PyUnicode_DecodeASCII(ascii_chars, 128, NULL);\n        if (ascii_chars_u == NULL) goto bad;\n        ascii_chars_b = PyUnicode_AsEncodedString(ascii_chars_u, default_encoding_c, NULL);\n        if (ascii_chars_b == NULL || strncmp(ascii_chars, PyBytes_AS_STRING(ascii_chars_b), 128) != 0) {\n            PyErr_Format(\n                PyExc_ValueError,\n                \"This module compiled with c_string_encoding=ascii, but default encoding '%.200s' is not a superset of ascii.\",\n                default_encoding_c);\n            goto bad;\n        }\n    }\n    Py_XDECREF(sys);\n    Py_XDECREF(default_encoding);\n    Py_XDECREF(ascii_chars_u);\n    Py_XDECREF(ascii_chars_b);\n    return 0;\nbad:\n    Py_XDECREF(sys);\n    Py_XDECREF(default_encoding);\n    Py_XDECREF(ascii_chars_u);\n    Py_XDECREF(ascii_chars_b);\n    return -1;\n}\n#endif\n#if __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT && PY_MAJOR_VERSION >= 3\n#define __Pyx_PyUnicode_FromStringAndSize(c_str, size) PyUnicode_DecodeUTF8(c_str, size, NULL)\n#else\n#define __Pyx_PyUnicode_FromStringAndSize(c_str, size) PyUnicode_Decode(c_str, size, __PYX_DEFAULT_STRING_ENCODING, NULL)\n#if __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT\nstatic char* __PYX_DEFAULT_STRING_ENCODING;\nstatic int __Pyx_init_sys_getdefaultencoding_params(void) {\n    PyObject* sys = NULL;\n    PyObject* default_encoding = NULL;\n    char* default_encoding_c;\n    sys = PyImport_ImportModule(\"sys\");\n    if (sys == NULL) goto bad;\n    default_encoding = PyObject_CallMethod(sys, (char*) (const char*) \"getdefaultencoding\", NULL);\n    if (default_encoding == NULL) goto bad;\n    default_encoding_c = PyBytes_AS_STRING(default_encoding);\n    __PYX_DEFAULT_STRING_ENCODING = (char*) malloc(strlen(default_encoding_c));\n    strcpy(__PYX_DEFAULT_STRING_ENCODING, default_encoding_c);\n    Py_DECREF(sys);\n    Py_DECREF(default_encoding);\n    return 0;\nbad:\n    Py_XDECREF(sys);\n    Py_XDECREF(default_encoding);\n    return -1;\n}\n#endif\n#endif\n\n\n#ifdef __GNUC__\n  /* Test for GCC > 2.95 */\n  #if __GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95))\n    #define likely(x)   __builtin_expect(!!(x), 1)\n    #define unlikely(x) __builtin_expect(!!(x), 0)\n  #else /* __GNUC__ > 2 ... */\n    #define likely(x)   (x)\n    #define unlikely(x) (x)\n  #endif /* __GNUC__ > 2 ... */\n#else /* __GNUC__ */\n  #define likely(x)   (x)\n  #define unlikely(x) (x)\n#endif /* __GNUC__ */\n\nstatic PyObject *__pyx_m;\nstatic PyObject *__pyx_d;\nstatic PyObject *__pyx_b;\nstatic PyObject *__pyx_empty_tuple;\nstatic PyObject *__pyx_empty_bytes;\nstatic int __pyx_lineno;\nstatic int __pyx_clineno = 0;\nstatic const char * __pyx_cfilenm= __FILE__;\nstatic const char *__pyx_filename;\n\n#if !defined(CYTHON_CCOMPLEX)\n  #if defined(__cplusplus)\n    #define CYTHON_CCOMPLEX 1\n  #elif defined(_Complex_I)\n    #define CYTHON_CCOMPLEX 1\n  #else\n    #define CYTHON_CCOMPLEX 0\n  #endif\n#endif\n#if CYTHON_CCOMPLEX\n  #ifdef __cplusplus\n    #include <complex>\n  #else\n    #include <complex.h>\n  #endif\n#endif\n#if CYTHON_CCOMPLEX && !defined(__cplusplus) && defined(__sun__) && defined(__GNUC__)\n  #undef _Complex_I\n  #define _Complex_I 1.0fj\n#endif\n\n\nstatic const char *__pyx_f[] = {\n  \"cpu_nms.pyx\",\n  \"__init__.pxd\",\n  \"type.pxd\",\n};\n#define IS_UNSIGNED(type) (((type) -1) > 0)\nstruct __Pyx_StructField_;\n#define __PYX_BUF_FLAGS_PACKED_STRUCT (1 << 0)\ntypedef struct {\n  const char* name; /* for error messages only */\n  struct __Pyx_StructField_* fields;\n  size_t size;     /* sizeof(type) */\n  size_t arraysize[8]; /* length of array in each dimension */\n  int ndim;\n  char typegroup; /* _R_eal, _C_omplex, Signed _I_nt, _U_nsigned int, _S_truct, _P_ointer, _O_bject, c_H_ar */\n  char is_unsigned;\n  int flags;\n} __Pyx_TypeInfo;\ntypedef struct __Pyx_StructField_ {\n  __Pyx_TypeInfo* type;\n  const char* name;\n  size_t offset;\n} __Pyx_StructField;\ntypedef struct {\n  __Pyx_StructField* field;\n  size_t parent_offset;\n} __Pyx_BufFmt_StackElem;\ntypedef struct {\n  __Pyx_StructField root;\n  __Pyx_BufFmt_StackElem* head;\n  size_t fmt_offset;\n  size_t new_count, enc_count;\n  size_t struct_alignment;\n  int is_complex;\n  char enc_type;\n  char new_packmode;\n  char enc_packmode;\n  char is_valid_array;\n} __Pyx_BufFmt_Context;\n\n\n/* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":723\n * # in Cython to enable them only on the right systems.\n * \n * ctypedef npy_int8       int8_t             # <<<<<<<<<<<<<<\n * ctypedef npy_int16      int16_t\n * ctypedef npy_int32      int32_t\n */\ntypedef npy_int8 __pyx_t_5numpy_int8_t;\n\n/* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":724\n * \n * ctypedef npy_int8       int8_t\n * ctypedef npy_int16      int16_t             # <<<<<<<<<<<<<<\n * ctypedef npy_int32      int32_t\n * ctypedef npy_int64      int64_t\n */\ntypedef npy_int16 __pyx_t_5numpy_int16_t;\n\n/* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":725\n * ctypedef npy_int8       int8_t\n * ctypedef npy_int16      int16_t\n * ctypedef npy_int32      int32_t             # <<<<<<<<<<<<<<\n * ctypedef npy_int64      int64_t\n * #ctypedef npy_int96      int96_t\n */\ntypedef npy_int32 __pyx_t_5numpy_int32_t;\n\n/* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":726\n * ctypedef npy_int16      int16_t\n * ctypedef npy_int32      int32_t\n * ctypedef npy_int64      int64_t             # <<<<<<<<<<<<<<\n * #ctypedef npy_int96      int96_t\n * #ctypedef npy_int128     int128_t\n */\ntypedef npy_int64 __pyx_t_5numpy_int64_t;\n\n/* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":730\n * #ctypedef npy_int128     int128_t\n * \n * ctypedef npy_uint8      uint8_t             # <<<<<<<<<<<<<<\n * ctypedef npy_uint16     uint16_t\n * ctypedef npy_uint32     uint32_t\n */\ntypedef npy_uint8 __pyx_t_5numpy_uint8_t;\n\n/* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":731\n * \n * ctypedef npy_uint8      uint8_t\n * ctypedef npy_uint16     uint16_t             # <<<<<<<<<<<<<<\n * ctypedef npy_uint32     uint32_t\n * ctypedef npy_uint64     uint64_t\n */\ntypedef npy_uint16 __pyx_t_5numpy_uint16_t;\n\n/* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":732\n * ctypedef npy_uint8      uint8_t\n * ctypedef npy_uint16     uint16_t\n * ctypedef npy_uint32     uint32_t             # <<<<<<<<<<<<<<\n * ctypedef npy_uint64     uint64_t\n * #ctypedef npy_uint96     uint96_t\n */\ntypedef npy_uint32 __pyx_t_5numpy_uint32_t;\n\n/* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":733\n * ctypedef npy_uint16     uint16_t\n * ctypedef npy_uint32     uint32_t\n * ctypedef npy_uint64     uint64_t             # <<<<<<<<<<<<<<\n * #ctypedef npy_uint96     uint96_t\n * #ctypedef npy_uint128    uint128_t\n */\ntypedef npy_uint64 __pyx_t_5numpy_uint64_t;\n\n/* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":737\n * #ctypedef npy_uint128    uint128_t\n * \n * ctypedef npy_float32    float32_t             # <<<<<<<<<<<<<<\n * ctypedef npy_float64    float64_t\n * #ctypedef npy_float80    float80_t\n */\ntypedef npy_float32 __pyx_t_5numpy_float32_t;\n\n/* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":738\n * \n * ctypedef npy_float32    float32_t\n * ctypedef npy_float64    float64_t             # <<<<<<<<<<<<<<\n * #ctypedef npy_float80    float80_t\n * #ctypedef npy_float128   float128_t\n */\ntypedef npy_float64 __pyx_t_5numpy_float64_t;\n\n/* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":747\n * # The int types are mapped a bit surprising --\n * # numpy.int corresponds to 'l' and numpy.long to 'q'\n * ctypedef npy_long       int_t             # <<<<<<<<<<<<<<\n * ctypedef npy_longlong   long_t\n * ctypedef npy_longlong   longlong_t\n */\ntypedef npy_long __pyx_t_5numpy_int_t;\n\n/* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":748\n * # numpy.int corresponds to 'l' and numpy.long to 'q'\n * ctypedef npy_long       int_t\n * ctypedef npy_longlong   long_t             # <<<<<<<<<<<<<<\n * ctypedef npy_longlong   longlong_t\n * \n */\ntypedef npy_longlong __pyx_t_5numpy_long_t;\n\n/* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":749\n * ctypedef npy_long       int_t\n * ctypedef npy_longlong   long_t\n * ctypedef npy_longlong   longlong_t             # <<<<<<<<<<<<<<\n * \n * ctypedef npy_ulong      uint_t\n */\ntypedef npy_longlong __pyx_t_5numpy_longlong_t;\n\n/* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":751\n * ctypedef npy_longlong   longlong_t\n * \n * ctypedef npy_ulong      uint_t             # <<<<<<<<<<<<<<\n * ctypedef npy_ulonglong  ulong_t\n * ctypedef npy_ulonglong  ulonglong_t\n */\ntypedef npy_ulong __pyx_t_5numpy_uint_t;\n\n/* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":752\n * \n * ctypedef npy_ulong      uint_t\n * ctypedef npy_ulonglong  ulong_t             # <<<<<<<<<<<<<<\n * ctypedef npy_ulonglong  ulonglong_t\n * \n */\ntypedef npy_ulonglong __pyx_t_5numpy_ulong_t;\n\n/* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":753\n * ctypedef npy_ulong      uint_t\n * ctypedef npy_ulonglong  ulong_t\n * ctypedef npy_ulonglong  ulonglong_t             # <<<<<<<<<<<<<<\n * \n * ctypedef npy_intp       intp_t\n */\ntypedef npy_ulonglong __pyx_t_5numpy_ulonglong_t;\n\n/* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":755\n * ctypedef npy_ulonglong  ulonglong_t\n * \n * ctypedef npy_intp       intp_t             # <<<<<<<<<<<<<<\n * ctypedef npy_uintp      uintp_t\n * \n */\ntypedef npy_intp __pyx_t_5numpy_intp_t;\n\n/* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":756\n * \n * ctypedef npy_intp       intp_t\n * ctypedef npy_uintp      uintp_t             # <<<<<<<<<<<<<<\n * \n * ctypedef npy_double     float_t\n */\ntypedef npy_uintp __pyx_t_5numpy_uintp_t;\n\n/* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":758\n * ctypedef npy_uintp      uintp_t\n * \n * ctypedef npy_double     float_t             # <<<<<<<<<<<<<<\n * ctypedef npy_double     double_t\n * ctypedef npy_longdouble longdouble_t\n */\ntypedef npy_double __pyx_t_5numpy_float_t;\n\n/* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":759\n * \n * ctypedef npy_double     float_t\n * ctypedef npy_double     double_t             # <<<<<<<<<<<<<<\n * ctypedef npy_longdouble longdouble_t\n * \n */\ntypedef npy_double __pyx_t_5numpy_double_t;\n\n/* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":760\n * ctypedef npy_double     float_t\n * ctypedef npy_double     double_t\n * ctypedef npy_longdouble longdouble_t             # <<<<<<<<<<<<<<\n * \n * ctypedef npy_cfloat      cfloat_t\n */\ntypedef npy_longdouble __pyx_t_5numpy_longdouble_t;\n#if CYTHON_CCOMPLEX\n  #ifdef __cplusplus\n    typedef ::std::complex< float > __pyx_t_float_complex;\n  #else\n    typedef float _Complex __pyx_t_float_complex;\n  #endif\n#else\n    typedef struct { float real, imag; } __pyx_t_float_complex;\n#endif\n\n#if CYTHON_CCOMPLEX\n  #ifdef __cplusplus\n    typedef ::std::complex< double > __pyx_t_double_complex;\n  #else\n    typedef double _Complex __pyx_t_double_complex;\n  #endif\n#else\n    typedef struct { double real, imag; } __pyx_t_double_complex;\n#endif\n\n\n/*--- Type declarations ---*/\n\n/* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":762\n * ctypedef npy_longdouble longdouble_t\n * \n * ctypedef npy_cfloat      cfloat_t             # <<<<<<<<<<<<<<\n * ctypedef npy_cdouble     cdouble_t\n * ctypedef npy_clongdouble clongdouble_t\n */\ntypedef npy_cfloat __pyx_t_5numpy_cfloat_t;\n\n/* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":763\n * \n * ctypedef npy_cfloat      cfloat_t\n * ctypedef npy_cdouble     cdouble_t             # <<<<<<<<<<<<<<\n * ctypedef npy_clongdouble clongdouble_t\n * \n */\ntypedef npy_cdouble __pyx_t_5numpy_cdouble_t;\n\n/* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":764\n * ctypedef npy_cfloat      cfloat_t\n * ctypedef npy_cdouble     cdouble_t\n * ctypedef npy_clongdouble clongdouble_t             # <<<<<<<<<<<<<<\n * \n * ctypedef npy_cdouble     complex_t\n */\ntypedef npy_clongdouble __pyx_t_5numpy_clongdouble_t;\n\n/* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":766\n * ctypedef npy_clongdouble clongdouble_t\n * \n * ctypedef npy_cdouble     complex_t             # <<<<<<<<<<<<<<\n * \n * cdef inline object PyArray_MultiIterNew1(a):\n */\ntypedef npy_cdouble __pyx_t_5numpy_complex_t;\n#ifndef CYTHON_REFNANNY\n  #define CYTHON_REFNANNY 0\n#endif\n#if CYTHON_REFNANNY\n  typedef struct {\n    void (*INCREF)(void*, PyObject*, int);\n    void (*DECREF)(void*, PyObject*, int);\n    void (*GOTREF)(void*, PyObject*, int);\n    void (*GIVEREF)(void*, PyObject*, int);\n    void* (*SetupContext)(const char*, int, const char*);\n    void (*FinishContext)(void**);\n  } __Pyx_RefNannyAPIStruct;\n  static __Pyx_RefNannyAPIStruct *__Pyx_RefNanny = NULL;\n  static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname); /*proto*/\n  #define __Pyx_RefNannyDeclarations void *__pyx_refnanny = NULL;\n#ifdef WITH_THREAD\n  #define __Pyx_RefNannySetupContext(name, acquire_gil) \\\n          if (acquire_gil) { \\\n              PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure(); \\\n              __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__); \\\n              PyGILState_Release(__pyx_gilstate_save); \\\n          } else { \\\n              __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__); \\\n          }\n#else\n  #define __Pyx_RefNannySetupContext(name, acquire_gil) \\\n          __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__)\n#endif\n  #define __Pyx_RefNannyFinishContext() \\\n          __Pyx_RefNanny->FinishContext(&__pyx_refnanny)\n  #define __Pyx_INCREF(r)  __Pyx_RefNanny->INCREF(__pyx_refnanny, (PyObject *)(r), __LINE__)\n  #define __Pyx_DECREF(r)  __Pyx_RefNanny->DECREF(__pyx_refnanny, (PyObject *)(r), __LINE__)\n  #define __Pyx_GOTREF(r)  __Pyx_RefNanny->GOTREF(__pyx_refnanny, (PyObject *)(r), __LINE__)\n  #define __Pyx_GIVEREF(r) __Pyx_RefNanny->GIVEREF(__pyx_refnanny, (PyObject *)(r), __LINE__)\n  #define __Pyx_XINCREF(r)  do { if((r) != NULL) {__Pyx_INCREF(r); }} while(0)\n  #define __Pyx_XDECREF(r)  do { if((r) != NULL) {__Pyx_DECREF(r); }} while(0)\n  #define __Pyx_XGOTREF(r)  do { if((r) != NULL) {__Pyx_GOTREF(r); }} while(0)\n  #define __Pyx_XGIVEREF(r) do { if((r) != NULL) {__Pyx_GIVEREF(r);}} while(0)\n#else\n  #define __Pyx_RefNannyDeclarations\n  #define __Pyx_RefNannySetupContext(name, acquire_gil)\n  #define __Pyx_RefNannyFinishContext()\n  #define __Pyx_INCREF(r) Py_INCREF(r)\n  #define __Pyx_DECREF(r) Py_DECREF(r)\n  #define __Pyx_GOTREF(r)\n  #define __Pyx_GIVEREF(r)\n  #define __Pyx_XINCREF(r) Py_XINCREF(r)\n  #define __Pyx_XDECREF(r) Py_XDECREF(r)\n  #define __Pyx_XGOTREF(r)\n  #define __Pyx_XGIVEREF(r)\n#endif /* CYTHON_REFNANNY */\n#define __Pyx_XDECREF_SET(r, v) do {                            \\\n        PyObject *tmp = (PyObject *) r;                         \\\n        r = v; __Pyx_XDECREF(tmp);                              \\\n    } while (0)\n#define __Pyx_DECREF_SET(r, v) do {                             \\\n        PyObject *tmp = (PyObject *) r;                         \\\n        r = v; __Pyx_DECREF(tmp);                               \\\n    } while (0)\n#define __Pyx_CLEAR(r)    do { PyObject* tmp = ((PyObject*)(r)); r = NULL; __Pyx_DECREF(tmp);} while(0)\n#define __Pyx_XCLEAR(r)   do { if((r) != NULL) {PyObject* tmp = ((PyObject*)(r)); r = NULL; __Pyx_DECREF(tmp);}} while(0)\n\n#if CYTHON_COMPILING_IN_CPYTHON\nstatic CYTHON_INLINE PyObject* __Pyx_PyObject_GetAttrStr(PyObject* obj, PyObject* attr_name) {\n    PyTypeObject* tp = Py_TYPE(obj);\n    if (likely(tp->tp_getattro))\n        return tp->tp_getattro(obj, attr_name);\n#if PY_MAJOR_VERSION < 3\n    if (likely(tp->tp_getattr))\n        return tp->tp_getattr(obj, PyString_AS_STRING(attr_name));\n#endif\n    return PyObject_GetAttr(obj, attr_name);\n}\n#else\n#define __Pyx_PyObject_GetAttrStr(o,n) PyObject_GetAttr(o,n)\n#endif\n\nstatic PyObject *__Pyx_GetBuiltinName(PyObject *name); /*proto*/\n\nstatic void __Pyx_RaiseArgtupleInvalid(const char* func_name, int exact,\n    Py_ssize_t num_min, Py_ssize_t num_max, Py_ssize_t num_found); /*proto*/\n\nstatic void __Pyx_RaiseDoubleKeywordsError(const char* func_name, PyObject* kw_name); /*proto*/\n\nstatic int __Pyx_ParseOptionalKeywords(PyObject *kwds, PyObject **argnames[], \\\n    PyObject *kwds2, PyObject *values[], Py_ssize_t num_pos_args, \\\n    const char* function_name); /*proto*/\n\nstatic CYTHON_INLINE int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed,\n    const char *name, int exact); /*proto*/\n\nstatic CYTHON_INLINE int  __Pyx_GetBufferAndValidate(Py_buffer* buf, PyObject* obj,\n    __Pyx_TypeInfo* dtype, int flags, int nd, int cast, __Pyx_BufFmt_StackElem* stack);\nstatic CYTHON_INLINE void __Pyx_SafeReleaseBuffer(Py_buffer* info);\n\nstatic CYTHON_INLINE int __Pyx_TypeTest(PyObject *obj, PyTypeObject *type); /*proto*/\n\n#if CYTHON_COMPILING_IN_CPYTHON\nstatic CYTHON_INLINE PyObject* __Pyx_PyObject_Call(PyObject *func, PyObject *arg, PyObject *kw); /*proto*/\n#else\n#define __Pyx_PyObject_Call(func, arg, kw) PyObject_Call(func, arg, kw)\n#endif\n\nstatic CYTHON_INLINE PyObject *__Pyx_GetModuleGlobalName(PyObject *name); /*proto*/\n\nstatic void __Pyx_RaiseBufferIndexError(int axis); /*proto*/\n\n#define __Pyx_BufPtrStrided1d(type, buf, i0, s0) (type)((char*)buf + i0 * s0)\n#if CYTHON_COMPILING_IN_CPYTHON\nstatic CYTHON_INLINE int __Pyx_PyList_Append(PyObject* list, PyObject* x) {\n    PyListObject* L = (PyListObject*) list;\n    Py_ssize_t len = Py_SIZE(list);\n    if (likely(L->allocated > len) & likely(len > (L->allocated >> 1))) {\n        Py_INCREF(x);\n        PyList_SET_ITEM(list, len, x);\n        Py_SIZE(list) = len+1;\n        return 0;\n    }\n    return PyList_Append(list, x);\n}\n#else\n#define __Pyx_PyList_Append(L,x) PyList_Append(L,x)\n#endif\n\n#ifndef __PYX_FORCE_INIT_THREADS\n  #define __PYX_FORCE_INIT_THREADS 0\n#endif\n\nstatic CYTHON_INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb); /*proto*/\nstatic CYTHON_INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb); /*proto*/\n\nstatic void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject *cause); /*proto*/\n\nstatic CYTHON_INLINE void __Pyx_RaiseTooManyValuesError(Py_ssize_t expected);\n\nstatic CYTHON_INLINE void __Pyx_RaiseNeedMoreValuesError(Py_ssize_t index);\n\nstatic CYTHON_INLINE void __Pyx_RaiseNoneNotIterableError(void);\n\ntypedef struct {\n  Py_ssize_t shape, strides, suboffsets;\n} __Pyx_Buf_DimInfo;\ntypedef struct {\n  size_t refcount;\n  Py_buffer pybuffer;\n} __Pyx_Buffer;\ntypedef struct {\n  __Pyx_Buffer *rcbuffer;\n  char *data;\n  __Pyx_Buf_DimInfo diminfo[8];\n} __Pyx_LocalBuf_ND;\n\n#if PY_MAJOR_VERSION < 3\n    static int __Pyx_GetBuffer(PyObject *obj, Py_buffer *view, int flags);\n    static void __Pyx_ReleaseBuffer(Py_buffer *view);\n#else\n    #define __Pyx_GetBuffer PyObject_GetBuffer\n    #define __Pyx_ReleaseBuffer PyBuffer_Release\n#endif\n\n\nstatic Py_ssize_t __Pyx_zeros[] = {0, 0, 0, 0, 0, 0, 0, 0};\nstatic Py_ssize_t __Pyx_minusones[] = {-1, -1, -1, -1, -1, -1, -1, -1};\n\nstatic PyObject *__Pyx_Import(PyObject *name, PyObject *from_list, int level); /*proto*/\n\nstatic CYTHON_INLINE PyObject* __Pyx_PyInt_From_int(int value);\n\nstatic CYTHON_INLINE int __Pyx_PyInt_As_int(PyObject *);\n\nstatic CYTHON_INLINE PyObject* __Pyx_PyInt_From_long(long value);\n\n#if CYTHON_CCOMPLEX\n  #ifdef __cplusplus\n    #define __Pyx_CREAL(z) ((z).real())\n    #define __Pyx_CIMAG(z) ((z).imag())\n  #else\n    #define __Pyx_CREAL(z) (__real__(z))\n    #define __Pyx_CIMAG(z) (__imag__(z))\n  #endif\n#else\n    #define __Pyx_CREAL(z) ((z).real)\n    #define __Pyx_CIMAG(z) ((z).imag)\n#endif\n#if (defined(_WIN32) || defined(__clang__)) && defined(__cplusplus) && CYTHON_CCOMPLEX\n    #define __Pyx_SET_CREAL(z,x) ((z).real(x))\n    #define __Pyx_SET_CIMAG(z,y) ((z).imag(y))\n#else\n    #define __Pyx_SET_CREAL(z,x) __Pyx_CREAL(z) = (x)\n    #define __Pyx_SET_CIMAG(z,y) __Pyx_CIMAG(z) = (y)\n#endif\n\nstatic CYTHON_INLINE __pyx_t_float_complex __pyx_t_float_complex_from_parts(float, float);\n\n#if CYTHON_CCOMPLEX\n    #define __Pyx_c_eqf(a, b)   ((a)==(b))\n    #define __Pyx_c_sumf(a, b)  ((a)+(b))\n    #define __Pyx_c_difff(a, b) ((a)-(b))\n    #define __Pyx_c_prodf(a, b) ((a)*(b))\n    #define __Pyx_c_quotf(a, b) ((a)/(b))\n    #define __Pyx_c_negf(a)     (-(a))\n  #ifdef __cplusplus\n    #define __Pyx_c_is_zerof(z) ((z)==(float)0)\n    #define __Pyx_c_conjf(z)    (::std::conj(z))\n    #if 1\n        #define __Pyx_c_absf(z)     (::std::abs(z))\n        #define __Pyx_c_powf(a, b)  (::std::pow(a, b))\n    #endif\n  #else\n    #define __Pyx_c_is_zerof(z) ((z)==0)\n    #define __Pyx_c_conjf(z)    (conjf(z))\n    #if 1\n        #define __Pyx_c_absf(z)     (cabsf(z))\n        #define __Pyx_c_powf(a, b)  (cpowf(a, b))\n    #endif\n #endif\n#else\n    static CYTHON_INLINE int __Pyx_c_eqf(__pyx_t_float_complex, __pyx_t_float_complex);\n    static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_sumf(__pyx_t_float_complex, __pyx_t_float_complex);\n    static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_difff(__pyx_t_float_complex, __pyx_t_float_complex);\n    static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_prodf(__pyx_t_float_complex, __pyx_t_float_complex);\n    static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_quotf(__pyx_t_float_complex, __pyx_t_float_complex);\n    static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_negf(__pyx_t_float_complex);\n    static CYTHON_INLINE int __Pyx_c_is_zerof(__pyx_t_float_complex);\n    static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_conjf(__pyx_t_float_complex);\n    #if 1\n        static CYTHON_INLINE float __Pyx_c_absf(__pyx_t_float_complex);\n        static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_powf(__pyx_t_float_complex, __pyx_t_float_complex);\n    #endif\n#endif\n\nstatic CYTHON_INLINE __pyx_t_double_complex __pyx_t_double_complex_from_parts(double, double);\n\n#if CYTHON_CCOMPLEX\n    #define __Pyx_c_eq(a, b)   ((a)==(b))\n    #define __Pyx_c_sum(a, b)  ((a)+(b))\n    #define __Pyx_c_diff(a, b) ((a)-(b))\n    #define __Pyx_c_prod(a, b) ((a)*(b))\n    #define __Pyx_c_quot(a, b) ((a)/(b))\n    #define __Pyx_c_neg(a)     (-(a))\n  #ifdef __cplusplus\n    #define __Pyx_c_is_zero(z) ((z)==(double)0)\n    #define __Pyx_c_conj(z)    (::std::conj(z))\n    #if 1\n        #define __Pyx_c_abs(z)     (::std::abs(z))\n        #define __Pyx_c_pow(a, b)  (::std::pow(a, b))\n    #endif\n  #else\n    #define __Pyx_c_is_zero(z) ((z)==0)\n    #define __Pyx_c_conj(z)    (conj(z))\n    #if 1\n        #define __Pyx_c_abs(z)     (cabs(z))\n        #define __Pyx_c_pow(a, b)  (cpow(a, b))\n    #endif\n #endif\n#else\n    static CYTHON_INLINE int __Pyx_c_eq(__pyx_t_double_complex, __pyx_t_double_complex);\n    static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_sum(__pyx_t_double_complex, __pyx_t_double_complex);\n    static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_diff(__pyx_t_double_complex, __pyx_t_double_complex);\n    static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_prod(__pyx_t_double_complex, __pyx_t_double_complex);\n    static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_quot(__pyx_t_double_complex, __pyx_t_double_complex);\n    static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_neg(__pyx_t_double_complex);\n    static CYTHON_INLINE int __Pyx_c_is_zero(__pyx_t_double_complex);\n    static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_conj(__pyx_t_double_complex);\n    #if 1\n        static CYTHON_INLINE double __Pyx_c_abs(__pyx_t_double_complex);\n        static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_pow(__pyx_t_double_complex, __pyx_t_double_complex);\n    #endif\n#endif\n\nstatic CYTHON_INLINE long __Pyx_PyInt_As_long(PyObject *);\n\nstatic int __Pyx_check_binary_version(void);\n\n#if !defined(__Pyx_PyIdentifier_FromString)\n#if PY_MAJOR_VERSION < 3\n  #define __Pyx_PyIdentifier_FromString(s) PyString_FromString(s)\n#else\n  #define __Pyx_PyIdentifier_FromString(s) PyUnicode_FromString(s)\n#endif\n#endif\n\nstatic PyObject *__Pyx_ImportModule(const char *name); /*proto*/\n\nstatic PyTypeObject *__Pyx_ImportType(const char *module_name, const char *class_name, size_t size, int strict);  /*proto*/\n\ntypedef struct {\n    int code_line;\n    PyCodeObject* code_object;\n} __Pyx_CodeObjectCacheEntry;\nstruct __Pyx_CodeObjectCache {\n    int count;\n    int max_count;\n    __Pyx_CodeObjectCacheEntry* entries;\n};\nstatic struct __Pyx_CodeObjectCache __pyx_code_cache = {0,0,NULL};\nstatic int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line);\nstatic PyCodeObject *__pyx_find_code_object(int code_line);\nstatic void __pyx_insert_code_object(int code_line, PyCodeObject* code_object);\n\nstatic void __Pyx_AddTraceback(const char *funcname, int c_line,\n                               int py_line, const char *filename); /*proto*/\n\nstatic int __Pyx_InitStrings(__Pyx_StringTabEntry *t); /*proto*/\n\n\n/* Module declarations from 'cpython.buffer' */\n\n/* Module declarations from 'cpython.ref' */\n\n/* Module declarations from 'libc.string' */\n\n/* Module declarations from 'libc.stdio' */\n\n/* Module declarations from 'cpython.object' */\n\n/* Module declarations from '__builtin__' */\n\n/* Module declarations from 'cpython.type' */\nstatic PyTypeObject *__pyx_ptype_7cpython_4type_type = 0;\n\n/* Module declarations from 'libc.stdlib' */\n\n/* Module declarations from 'numpy' */\n\n/* Module declarations from 'numpy' */\nstatic PyTypeObject *__pyx_ptype_5numpy_dtype = 0;\nstatic PyTypeObject *__pyx_ptype_5numpy_flatiter = 0;\nstatic PyTypeObject *__pyx_ptype_5numpy_broadcast = 0;\nstatic PyTypeObject *__pyx_ptype_5numpy_ndarray = 0;\nstatic PyTypeObject *__pyx_ptype_5numpy_ufunc = 0;\nstatic CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *, char *, char *, int *); /*proto*/\n\n/* Module declarations from 'nms.cpu_nms' */\nstatic CYTHON_INLINE __pyx_t_5numpy_float32_t __pyx_f_3nms_7cpu_nms_max(__pyx_t_5numpy_float32_t, __pyx_t_5numpy_float32_t); /*proto*/\nstatic CYTHON_INLINE __pyx_t_5numpy_float32_t __pyx_f_3nms_7cpu_nms_min(__pyx_t_5numpy_float32_t, __pyx_t_5numpy_float32_t); /*proto*/\nstatic __Pyx_TypeInfo __Pyx_TypeInfo_nn___pyx_t_5numpy_float32_t = { \"float32_t\", NULL, sizeof(__pyx_t_5numpy_float32_t), { 0 }, 0, 'R', 0, 0 };\nstatic __Pyx_TypeInfo __Pyx_TypeInfo_nn___pyx_t_5numpy_int_t = { \"int_t\", NULL, sizeof(__pyx_t_5numpy_int_t), { 0 }, 0, IS_UNSIGNED(__pyx_t_5numpy_int_t) ? 'U' : 'I', IS_UNSIGNED(__pyx_t_5numpy_int_t), 0 };\n#define __Pyx_MODULE_NAME \"nms.cpu_nms\"\nint __pyx_module_is_main_nms__cpu_nms = 0;\n\n/* Implementation of 'nms.cpu_nms' */\nstatic PyObject *__pyx_builtin_range;\nstatic PyObject *__pyx_builtin_ValueError;\nstatic PyObject *__pyx_builtin_RuntimeError;\nstatic PyObject *__pyx_pf_3nms_7cpu_nms_cpu_nms(CYTHON_UNUSED PyObject *__pyx_self, PyArrayObject *__pyx_v_dets, PyObject *__pyx_v_thresh); /* proto */\nstatic int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags); /* proto */\nstatic void __pyx_pf_5numpy_7ndarray_2__releasebuffer__(PyArrayObject *__pyx_v_self, Py_buffer *__pyx_v_info); /* proto */\nstatic char __pyx_k_B[] = \"B\";\nstatic char __pyx_k_H[] = \"H\";\nstatic char __pyx_k_I[] = \"I\";\nstatic char __pyx_k_L[] = \"L\";\nstatic char __pyx_k_O[] = \"O\";\nstatic char __pyx_k_Q[] = \"Q\";\nstatic char __pyx_k_b[] = \"b\";\nstatic char __pyx_k_d[] = \"d\";\nstatic char __pyx_k_f[] = \"f\";\nstatic char __pyx_k_g[] = \"g\";\nstatic char __pyx_k_h[] = \"h\";\nstatic char __pyx_k_i[] = \"i\";\nstatic char __pyx_k_j[] = \"_j\";\nstatic char __pyx_k_l[] = \"l\";\nstatic char __pyx_k_q[] = \"q\";\nstatic char __pyx_k_w[] = \"w\";\nstatic char __pyx_k_Zd[] = \"Zd\";\nstatic char __pyx_k_Zf[] = \"Zf\";\nstatic char __pyx_k_Zg[] = \"Zg\";\nstatic char __pyx_k_np[] = \"np\";\nstatic char __pyx_k_x1[] = \"x1\";\nstatic char __pyx_k_x2[] = \"x2\";\nstatic char __pyx_k_y1[] = \"y1\";\nstatic char __pyx_k_y2[] = \"y2\";\nstatic char __pyx_k_i_2[] = \"_i\";\nstatic char __pyx_k_int[] = \"int\";\nstatic char __pyx_k_ix1[] = \"ix1\";\nstatic char __pyx_k_ix2[] = \"ix2\";\nstatic char __pyx_k_iy1[] = \"iy1\";\nstatic char __pyx_k_iy2[] = \"iy2\";\nstatic char __pyx_k_j_2[] = \"j\";\nstatic char __pyx_k_ovr[] = \"ovr\";\nstatic char __pyx_k_xx1[] = \"xx1\";\nstatic char __pyx_k_xx2[] = \"xx2\";\nstatic char __pyx_k_yy1[] = \"yy1\";\nstatic char __pyx_k_yy2[] = \"yy2\";\nstatic char __pyx_k_dets[] = \"dets\";\nstatic char __pyx_k_keep[] = \"keep\";\nstatic char __pyx_k_main[] = \"__main__\";\nstatic char __pyx_k_test[] = \"__test__\";\nstatic char __pyx_k_areas[] = \"areas\";\nstatic char __pyx_k_dtype[] = \"dtype\";\nstatic char __pyx_k_iarea[] = \"iarea\";\nstatic char __pyx_k_inter[] = \"inter\";\nstatic char __pyx_k_ndets[] = \"ndets\";\nstatic char __pyx_k_numpy[] = \"numpy\";\nstatic char __pyx_k_order[] = \"order\";\nstatic char __pyx_k_range[] = \"range\";\nstatic char __pyx_k_zeros[] = \"zeros\";\nstatic char __pyx_k_import[] = \"__import__\";\nstatic char __pyx_k_scores[] = \"scores\";\nstatic char __pyx_k_thresh[] = \"thresh\";\nstatic char __pyx_k_argsort[] = \"argsort\";\nstatic char __pyx_k_cpu_nms[] = \"cpu_nms\";\nstatic char __pyx_k_ValueError[] = \"ValueError\";\nstatic char __pyx_k_suppressed[] = \"suppressed\";\nstatic char __pyx_k_nms_cpu_nms[] = \"nms.cpu_nms\";\nstatic char __pyx_k_RuntimeError[] = \"RuntimeError\";\nstatic char __pyx_k_pyx_getbuffer[] = \"__pyx_getbuffer\";\nstatic char __pyx_k_pyx_releasebuffer[] = \"__pyx_releasebuffer\";\nstatic char __pyx_k_ndarray_is_not_C_contiguous[] = \"ndarray is not C contiguous\";\nstatic char __pyx_k_nfs_yoda_xinleic_Inf_Code_Faste[] = \"/nfs.yoda/xinleic/Inf/Code/Faster-RCNN_TF/lib/nms/cpu_nms.pyx\";\nstatic char __pyx_k_unknown_dtype_code_in_numpy_pxd[] = \"unknown dtype code in numpy.pxd (%d)\";\nstatic char __pyx_k_Format_string_allocated_too_shor[] = \"Format string allocated too short, see comment in numpy.pxd\";\nstatic char __pyx_k_Non_native_byte_order_not_suppor[] = \"Non-native byte order not supported\";\nstatic char __pyx_k_ndarray_is_not_Fortran_contiguou[] = \"ndarray is not Fortran contiguous\";\nstatic char __pyx_k_Format_string_allocated_too_shor_2[] = \"Format string allocated too short.\";\nstatic PyObject *__pyx_kp_u_Format_string_allocated_too_shor;\nstatic PyObject *__pyx_kp_u_Format_string_allocated_too_shor_2;\nstatic PyObject *__pyx_kp_u_Non_native_byte_order_not_suppor;\nstatic PyObject *__pyx_n_s_RuntimeError;\nstatic PyObject *__pyx_n_s_ValueError;\nstatic PyObject *__pyx_n_s_areas;\nstatic PyObject *__pyx_n_s_argsort;\nstatic PyObject *__pyx_n_s_cpu_nms;\nstatic PyObject *__pyx_n_s_dets;\nstatic PyObject *__pyx_n_s_dtype;\nstatic PyObject *__pyx_n_s_h;\nstatic PyObject *__pyx_n_s_i;\nstatic PyObject *__pyx_n_s_i_2;\nstatic PyObject *__pyx_n_s_iarea;\nstatic PyObject *__pyx_n_s_import;\nstatic PyObject *__pyx_n_s_int;\nstatic PyObject *__pyx_n_s_inter;\nstatic PyObject *__pyx_n_s_ix1;\nstatic PyObject *__pyx_n_s_ix2;\nstatic PyObject *__pyx_n_s_iy1;\nstatic PyObject *__pyx_n_s_iy2;\nstatic PyObject *__pyx_n_s_j;\nstatic PyObject *__pyx_n_s_j_2;\nstatic PyObject *__pyx_n_s_keep;\nstatic PyObject *__pyx_n_s_main;\nstatic PyObject *__pyx_kp_u_ndarray_is_not_C_contiguous;\nstatic PyObject *__pyx_kp_u_ndarray_is_not_Fortran_contiguou;\nstatic PyObject *__pyx_n_s_ndets;\nstatic PyObject *__pyx_kp_s_nfs_yoda_xinleic_Inf_Code_Faste;\nstatic PyObject *__pyx_n_s_nms_cpu_nms;\nstatic PyObject *__pyx_n_s_np;\nstatic PyObject *__pyx_n_s_numpy;\nstatic PyObject *__pyx_n_s_order;\nstatic PyObject *__pyx_n_s_ovr;\nstatic PyObject *__pyx_n_s_pyx_getbuffer;\nstatic PyObject *__pyx_n_s_pyx_releasebuffer;\nstatic PyObject *__pyx_n_s_range;\nstatic PyObject *__pyx_n_s_scores;\nstatic PyObject *__pyx_n_s_suppressed;\nstatic PyObject *__pyx_n_s_test;\nstatic PyObject *__pyx_n_s_thresh;\nstatic PyObject *__pyx_kp_u_unknown_dtype_code_in_numpy_pxd;\nstatic PyObject *__pyx_n_s_w;\nstatic PyObject *__pyx_n_s_x1;\nstatic PyObject *__pyx_n_s_x2;\nstatic PyObject *__pyx_n_s_xx1;\nstatic PyObject *__pyx_n_s_xx2;\nstatic PyObject *__pyx_n_s_y1;\nstatic PyObject *__pyx_n_s_y2;\nstatic PyObject *__pyx_n_s_yy1;\nstatic PyObject *__pyx_n_s_yy2;\nstatic PyObject *__pyx_n_s_zeros;\nstatic PyObject *__pyx_int_0;\nstatic PyObject *__pyx_int_1;\nstatic PyObject *__pyx_int_2;\nstatic PyObject *__pyx_int_3;\nstatic PyObject *__pyx_int_4;\nstatic PyObject *__pyx_int_neg_1;\nstatic PyObject *__pyx_slice_;\nstatic PyObject *__pyx_slice__3;\nstatic PyObject *__pyx_slice__5;\nstatic PyObject *__pyx_slice__7;\nstatic PyObject *__pyx_slice__9;\nstatic PyObject *__pyx_tuple__2;\nstatic PyObject *__pyx_tuple__4;\nstatic PyObject *__pyx_tuple__6;\nstatic PyObject *__pyx_tuple__8;\nstatic PyObject *__pyx_slice__11;\nstatic PyObject *__pyx_tuple__10;\nstatic PyObject *__pyx_tuple__12;\nstatic PyObject *__pyx_tuple__13;\nstatic PyObject *__pyx_tuple__14;\nstatic PyObject *__pyx_tuple__15;\nstatic PyObject *__pyx_tuple__16;\nstatic PyObject *__pyx_tuple__17;\nstatic PyObject *__pyx_tuple__18;\nstatic PyObject *__pyx_codeobj__19;\n\n/* \"nms/cpu_nms.pyx\":11\n * cimport numpy as np\n * \n * cdef inline np.float32_t max(np.float32_t a, np.float32_t b):             # <<<<<<<<<<<<<<\n *     return a if a >= b else b\n * \n */\n\nstatic CYTHON_INLINE __pyx_t_5numpy_float32_t __pyx_f_3nms_7cpu_nms_max(__pyx_t_5numpy_float32_t __pyx_v_a, __pyx_t_5numpy_float32_t __pyx_v_b) {\n  __pyx_t_5numpy_float32_t __pyx_r;\n  __Pyx_RefNannyDeclarations\n  __pyx_t_5numpy_float32_t __pyx_t_1;\n  __Pyx_RefNannySetupContext(\"max\", 0);\n\n  /* \"nms/cpu_nms.pyx\":12\n * \n * cdef inline np.float32_t max(np.float32_t a, np.float32_t b):\n *     return a if a >= b else b             # <<<<<<<<<<<<<<\n * \n * cdef inline np.float32_t min(np.float32_t a, np.float32_t b):\n */\n  if (((__pyx_v_a >= __pyx_v_b) != 0)) {\n    __pyx_t_1 = __pyx_v_a;\n  } else {\n    __pyx_t_1 = __pyx_v_b;\n  }\n  __pyx_r = __pyx_t_1;\n  goto __pyx_L0;\n\n  /* \"nms/cpu_nms.pyx\":11\n * cimport numpy as np\n * \n * cdef inline np.float32_t max(np.float32_t a, np.float32_t b):             # <<<<<<<<<<<<<<\n *     return a if a >= b else b\n * \n */\n\n  /* function exit code */\n  __pyx_L0:;\n  __Pyx_RefNannyFinishContext();\n  return __pyx_r;\n}\n\n/* \"nms/cpu_nms.pyx\":14\n *     return a if a >= b else b\n * \n * cdef inline np.float32_t min(np.float32_t a, np.float32_t b):             # <<<<<<<<<<<<<<\n *     return a if a <= b else b\n * \n */\n\nstatic CYTHON_INLINE __pyx_t_5numpy_float32_t __pyx_f_3nms_7cpu_nms_min(__pyx_t_5numpy_float32_t __pyx_v_a, __pyx_t_5numpy_float32_t __pyx_v_b) {\n  __pyx_t_5numpy_float32_t __pyx_r;\n  __Pyx_RefNannyDeclarations\n  __pyx_t_5numpy_float32_t __pyx_t_1;\n  __Pyx_RefNannySetupContext(\"min\", 0);\n\n  /* \"nms/cpu_nms.pyx\":15\n * \n * cdef inline np.float32_t min(np.float32_t a, np.float32_t b):\n *     return a if a <= b else b             # <<<<<<<<<<<<<<\n * \n * def cpu_nms(np.ndarray[np.float32_t, ndim=2] dets, np.float thresh):\n */\n  if (((__pyx_v_a <= __pyx_v_b) != 0)) {\n    __pyx_t_1 = __pyx_v_a;\n  } else {\n    __pyx_t_1 = __pyx_v_b;\n  }\n  __pyx_r = __pyx_t_1;\n  goto __pyx_L0;\n\n  /* \"nms/cpu_nms.pyx\":14\n *     return a if a >= b else b\n * \n * cdef inline np.float32_t min(np.float32_t a, np.float32_t b):             # <<<<<<<<<<<<<<\n *     return a if a <= b else b\n * \n */\n\n  /* function exit code */\n  __pyx_L0:;\n  __Pyx_RefNannyFinishContext();\n  return __pyx_r;\n}\n\n/* \"nms/cpu_nms.pyx\":17\n *     return a if a <= b else b\n * \n * def cpu_nms(np.ndarray[np.float32_t, ndim=2] dets, np.float thresh):             # <<<<<<<<<<<<<<\n *     cdef np.ndarray[np.float32_t, ndim=1] x1 = dets[:, 0]\n *     cdef np.ndarray[np.float32_t, ndim=1] y1 = dets[:, 1]\n */\n\n/* Python wrapper */\nstatic PyObject *__pyx_pw_3nms_7cpu_nms_1cpu_nms(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/\nstatic PyMethodDef __pyx_mdef_3nms_7cpu_nms_1cpu_nms = {__Pyx_NAMESTR(\"cpu_nms\"), (PyCFunction)__pyx_pw_3nms_7cpu_nms_1cpu_nms, METH_VARARGS|METH_KEYWORDS, __Pyx_DOCSTR(0)};\nstatic PyObject *__pyx_pw_3nms_7cpu_nms_1cpu_nms(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {\n  PyArrayObject *__pyx_v_dets = 0;\n  PyObject *__pyx_v_thresh = 0;\n  int __pyx_lineno = 0;\n  const char *__pyx_filename = NULL;\n  int __pyx_clineno = 0;\n  PyObject *__pyx_r = 0;\n  __Pyx_RefNannyDeclarations\n  __Pyx_RefNannySetupContext(\"cpu_nms (wrapper)\", 0);\n  {\n    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_dets,&__pyx_n_s_thresh,0};\n    PyObject* values[2] = {0,0};\n    if (unlikely(__pyx_kwds)) {\n      Py_ssize_t kw_args;\n      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);\n      switch (pos_args) {\n        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);\n        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);\n        case  0: break;\n        default: goto __pyx_L5_argtuple_error;\n      }\n      kw_args = PyDict_Size(__pyx_kwds);\n      switch (pos_args) {\n        case  0:\n        if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_dets)) != 0)) kw_args--;\n        else goto __pyx_L5_argtuple_error;\n        case  1:\n        if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_thresh)) != 0)) kw_args--;\n        else {\n          __Pyx_RaiseArgtupleInvalid(\"cpu_nms\", 1, 2, 2, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 17; __pyx_clineno = __LINE__; goto __pyx_L3_error;}\n        }\n      }\n      if (unlikely(kw_args > 0)) {\n        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, \"cpu_nms\") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 17; __pyx_clineno = __LINE__; goto __pyx_L3_error;}\n      }\n    } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {\n      goto __pyx_L5_argtuple_error;\n    } else {\n      values[0] = PyTuple_GET_ITEM(__pyx_args, 0);\n      values[1] = PyTuple_GET_ITEM(__pyx_args, 1);\n    }\n    __pyx_v_dets = ((PyArrayObject *)values[0]);\n    __pyx_v_thresh = ((PyObject*)values[1]);\n  }\n  goto __pyx_L4_argument_unpacking_done;\n  __pyx_L5_argtuple_error:;\n  __Pyx_RaiseArgtupleInvalid(\"cpu_nms\", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 17; __pyx_clineno = __LINE__; goto __pyx_L3_error;}\n  __pyx_L3_error:;\n  __Pyx_AddTraceback(\"nms.cpu_nms.cpu_nms\", __pyx_clineno, __pyx_lineno, __pyx_filename);\n  __Pyx_RefNannyFinishContext();\n  return NULL;\n  __pyx_L4_argument_unpacking_done:;\n  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_dets), __pyx_ptype_5numpy_ndarray, 1, \"dets\", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 17; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_thresh), (&PyFloat_Type), 1, \"thresh\", 1))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 17; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n  __pyx_r = __pyx_pf_3nms_7cpu_nms_cpu_nms(__pyx_self, __pyx_v_dets, __pyx_v_thresh);\n\n  /* function exit code */\n  goto __pyx_L0;\n  __pyx_L1_error:;\n  __pyx_r = NULL;\n  __pyx_L0:;\n  __Pyx_RefNannyFinishContext();\n  return __pyx_r;\n}\n\nstatic PyObject *__pyx_pf_3nms_7cpu_nms_cpu_nms(CYTHON_UNUSED PyObject *__pyx_self, PyArrayObject *__pyx_v_dets, PyObject *__pyx_v_thresh) {\n  PyArrayObject *__pyx_v_x1 = 0;\n  PyArrayObject *__pyx_v_y1 = 0;\n  PyArrayObject *__pyx_v_x2 = 0;\n  PyArrayObject *__pyx_v_y2 = 0;\n  PyArrayObject *__pyx_v_scores = 0;\n  PyArrayObject *__pyx_v_areas = 0;\n  PyArrayObject *__pyx_v_order = 0;\n  int __pyx_v_ndets;\n  PyArrayObject *__pyx_v_suppressed = 0;\n  int __pyx_v__i;\n  int __pyx_v__j;\n  int __pyx_v_i;\n  int __pyx_v_j;\n  __pyx_t_5numpy_float32_t __pyx_v_ix1;\n  __pyx_t_5numpy_float32_t __pyx_v_iy1;\n  __pyx_t_5numpy_float32_t __pyx_v_ix2;\n  __pyx_t_5numpy_float32_t __pyx_v_iy2;\n  __pyx_t_5numpy_float32_t __pyx_v_iarea;\n  __pyx_t_5numpy_float32_t __pyx_v_xx1;\n  __pyx_t_5numpy_float32_t __pyx_v_yy1;\n  __pyx_t_5numpy_float32_t __pyx_v_xx2;\n  __pyx_t_5numpy_float32_t __pyx_v_yy2;\n  __pyx_t_5numpy_float32_t __pyx_v_w;\n  __pyx_t_5numpy_float32_t __pyx_v_h;\n  __pyx_t_5numpy_float32_t __pyx_v_inter;\n  __pyx_t_5numpy_float32_t __pyx_v_ovr;\n  PyObject *__pyx_v_keep = NULL;\n  __Pyx_LocalBuf_ND __pyx_pybuffernd_areas;\n  __Pyx_Buffer __pyx_pybuffer_areas;\n  __Pyx_LocalBuf_ND __pyx_pybuffernd_dets;\n  __Pyx_Buffer __pyx_pybuffer_dets;\n  __Pyx_LocalBuf_ND __pyx_pybuffernd_order;\n  __Pyx_Buffer __pyx_pybuffer_order;\n  __Pyx_LocalBuf_ND __pyx_pybuffernd_scores;\n  __Pyx_Buffer __pyx_pybuffer_scores;\n  __Pyx_LocalBuf_ND __pyx_pybuffernd_suppressed;\n  __Pyx_Buffer __pyx_pybuffer_suppressed;\n  __Pyx_LocalBuf_ND __pyx_pybuffernd_x1;\n  __Pyx_Buffer __pyx_pybuffer_x1;\n  __Pyx_LocalBuf_ND __pyx_pybuffernd_x2;\n  __Pyx_Buffer __pyx_pybuffer_x2;\n  __Pyx_LocalBuf_ND __pyx_pybuffernd_y1;\n  __Pyx_Buffer __pyx_pybuffer_y1;\n  __Pyx_LocalBuf_ND __pyx_pybuffernd_y2;\n  __Pyx_Buffer __pyx_pybuffer_y2;\n  PyObject *__pyx_r = NULL;\n  __Pyx_RefNannyDeclarations\n  PyObject *__pyx_t_1 = NULL;\n  PyArrayObject *__pyx_t_2 = NULL;\n  PyArrayObject *__pyx_t_3 = NULL;\n  PyArrayObject *__pyx_t_4 = NULL;\n  PyArrayObject *__pyx_t_5 = NULL;\n  PyArrayObject *__pyx_t_6 = NULL;\n  PyObject *__pyx_t_7 = NULL;\n  PyObject *__pyx_t_8 = NULL;\n  PyArrayObject *__pyx_t_9 = NULL;\n  PyArrayObject *__pyx_t_10 = NULL;\n  PyObject *__pyx_t_11 = NULL;\n  PyObject *__pyx_t_12 = NULL;\n  PyArrayObject *__pyx_t_13 = NULL;\n  int __pyx_t_14;\n  int __pyx_t_15;\n  int __pyx_t_16;\n  int __pyx_t_17;\n  int __pyx_t_18;\n  int __pyx_t_19;\n  int __pyx_t_20;\n  int __pyx_t_21;\n  int __pyx_t_22;\n  int __pyx_t_23;\n  int __pyx_t_24;\n  int __pyx_t_25;\n  int __pyx_t_26;\n  int __pyx_t_27;\n  int __pyx_t_28;\n  int __pyx_t_29;\n  int __pyx_t_30;\n  int __pyx_t_31;\n  int __pyx_t_32;\n  int __pyx_t_33;\n  int __pyx_t_34;\n  __pyx_t_5numpy_float32_t __pyx_t_35;\n  int __pyx_t_36;\n  int __pyx_lineno = 0;\n  const char *__pyx_filename = NULL;\n  int __pyx_clineno = 0;\n  __Pyx_RefNannySetupContext(\"cpu_nms\", 0);\n  __pyx_pybuffer_x1.pybuffer.buf = NULL;\n  __pyx_pybuffer_x1.refcount = 0;\n  __pyx_pybuffernd_x1.data = NULL;\n  __pyx_pybuffernd_x1.rcbuffer = &__pyx_pybuffer_x1;\n  __pyx_pybuffer_y1.pybuffer.buf = NULL;\n  __pyx_pybuffer_y1.refcount = 0;\n  __pyx_pybuffernd_y1.data = NULL;\n  __pyx_pybuffernd_y1.rcbuffer = &__pyx_pybuffer_y1;\n  __pyx_pybuffer_x2.pybuffer.buf = NULL;\n  __pyx_pybuffer_x2.refcount = 0;\n  __pyx_pybuffernd_x2.data = NULL;\n  __pyx_pybuffernd_x2.rcbuffer = &__pyx_pybuffer_x2;\n  __pyx_pybuffer_y2.pybuffer.buf = NULL;\n  __pyx_pybuffer_y2.refcount = 0;\n  __pyx_pybuffernd_y2.data = NULL;\n  __pyx_pybuffernd_y2.rcbuffer = &__pyx_pybuffer_y2;\n  __pyx_pybuffer_scores.pybuffer.buf = NULL;\n  __pyx_pybuffer_scores.refcount = 0;\n  __pyx_pybuffernd_scores.data = NULL;\n  __pyx_pybuffernd_scores.rcbuffer = &__pyx_pybuffer_scores;\n  __pyx_pybuffer_areas.pybuffer.buf = NULL;\n  __pyx_pybuffer_areas.refcount = 0;\n  __pyx_pybuffernd_areas.data = NULL;\n  __pyx_pybuffernd_areas.rcbuffer = &__pyx_pybuffer_areas;\n  __pyx_pybuffer_order.pybuffer.buf = NULL;\n  __pyx_pybuffer_order.refcount = 0;\n  __pyx_pybuffernd_order.data = NULL;\n  __pyx_pybuffernd_order.rcbuffer = &__pyx_pybuffer_order;\n  __pyx_pybuffer_suppressed.pybuffer.buf = NULL;\n  __pyx_pybuffer_suppressed.refcount = 0;\n  __pyx_pybuffernd_suppressed.data = NULL;\n  __pyx_pybuffernd_suppressed.rcbuffer = &__pyx_pybuffer_suppressed;\n  __pyx_pybuffer_dets.pybuffer.buf = NULL;\n  __pyx_pybuffer_dets.refcount = 0;\n  __pyx_pybuffernd_dets.data = NULL;\n  __pyx_pybuffernd_dets.rcbuffer = &__pyx_pybuffer_dets;\n  {\n    __Pyx_BufFmt_StackElem __pyx_stack[1];\n    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_dets.rcbuffer->pybuffer, (PyObject*)__pyx_v_dets, &__Pyx_TypeInfo_nn___pyx_t_5numpy_float32_t, PyBUF_FORMAT| PyBUF_STRIDES, 2, 0, __pyx_stack) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 17; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n  }\n  __pyx_pybuffernd_dets.diminfo[0].strides = __pyx_pybuffernd_dets.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_dets.diminfo[0].shape = __pyx_pybuffernd_dets.rcbuffer->pybuffer.shape[0]; __pyx_pybuffernd_dets.diminfo[1].strides = __pyx_pybuffernd_dets.rcbuffer->pybuffer.strides[1]; __pyx_pybuffernd_dets.diminfo[1].shape = __pyx_pybuffernd_dets.rcbuffer->pybuffer.shape[1];\n\n  /* \"nms/cpu_nms.pyx\":18\n * \n * def cpu_nms(np.ndarray[np.float32_t, ndim=2] dets, np.float thresh):\n *     cdef np.ndarray[np.float32_t, ndim=1] x1 = dets[:, 0]             # <<<<<<<<<<<<<<\n *     cdef np.ndarray[np.float32_t, ndim=1] y1 = dets[:, 1]\n *     cdef np.ndarray[np.float32_t, ndim=1] x2 = dets[:, 2]\n */\n  __pyx_t_1 = PyObject_GetItem(((PyObject *)__pyx_v_dets), __pyx_tuple__2); if (unlikely(__pyx_t_1 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 18; __pyx_clineno = __LINE__; goto __pyx_L1_error;};\n  __Pyx_GOTREF(__pyx_t_1);\n  if (!(likely(((__pyx_t_1) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_5numpy_ndarray))))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 18; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n  __pyx_t_2 = ((PyArrayObject *)__pyx_t_1);\n  {\n    __Pyx_BufFmt_StackElem __pyx_stack[1];\n    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_x1.rcbuffer->pybuffer, (PyObject*)__pyx_t_2, &__Pyx_TypeInfo_nn___pyx_t_5numpy_float32_t, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {\n      __pyx_v_x1 = ((PyArrayObject *)Py_None); __Pyx_INCREF(Py_None); __pyx_pybuffernd_x1.rcbuffer->pybuffer.buf = NULL;\n      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 18; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n    } else {__pyx_pybuffernd_x1.diminfo[0].strides = __pyx_pybuffernd_x1.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_x1.diminfo[0].shape = __pyx_pybuffernd_x1.rcbuffer->pybuffer.shape[0];\n    }\n  }\n  __pyx_t_2 = 0;\n  __pyx_v_x1 = ((PyArrayObject *)__pyx_t_1);\n  __pyx_t_1 = 0;\n\n  /* \"nms/cpu_nms.pyx\":19\n * def cpu_nms(np.ndarray[np.float32_t, ndim=2] dets, np.float thresh):\n *     cdef np.ndarray[np.float32_t, ndim=1] x1 = dets[:, 0]\n *     cdef np.ndarray[np.float32_t, ndim=1] y1 = dets[:, 1]             # <<<<<<<<<<<<<<\n *     cdef np.ndarray[np.float32_t, ndim=1] x2 = dets[:, 2]\n *     cdef np.ndarray[np.float32_t, ndim=1] y2 = dets[:, 3]\n */\n  __pyx_t_1 = PyObject_GetItem(((PyObject *)__pyx_v_dets), __pyx_tuple__4); if (unlikely(__pyx_t_1 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 19; __pyx_clineno = __LINE__; goto __pyx_L1_error;};\n  __Pyx_GOTREF(__pyx_t_1);\n  if (!(likely(((__pyx_t_1) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_5numpy_ndarray))))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 19; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n  __pyx_t_3 = ((PyArrayObject *)__pyx_t_1);\n  {\n    __Pyx_BufFmt_StackElem __pyx_stack[1];\n    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_y1.rcbuffer->pybuffer, (PyObject*)__pyx_t_3, &__Pyx_TypeInfo_nn___pyx_t_5numpy_float32_t, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {\n      __pyx_v_y1 = ((PyArrayObject *)Py_None); __Pyx_INCREF(Py_None); __pyx_pybuffernd_y1.rcbuffer->pybuffer.buf = NULL;\n      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 19; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n    } else {__pyx_pybuffernd_y1.diminfo[0].strides = __pyx_pybuffernd_y1.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_y1.diminfo[0].shape = __pyx_pybuffernd_y1.rcbuffer->pybuffer.shape[0];\n    }\n  }\n  __pyx_t_3 = 0;\n  __pyx_v_y1 = ((PyArrayObject *)__pyx_t_1);\n  __pyx_t_1 = 0;\n\n  /* \"nms/cpu_nms.pyx\":20\n *     cdef np.ndarray[np.float32_t, ndim=1] x1 = dets[:, 0]\n *     cdef np.ndarray[np.float32_t, ndim=1] y1 = dets[:, 1]\n *     cdef np.ndarray[np.float32_t, ndim=1] x2 = dets[:, 2]             # <<<<<<<<<<<<<<\n *     cdef np.ndarray[np.float32_t, ndim=1] y2 = dets[:, 3]\n *     cdef np.ndarray[np.float32_t, ndim=1] scores = dets[:, 4]\n */\n  __pyx_t_1 = PyObject_GetItem(((PyObject *)__pyx_v_dets), __pyx_tuple__6); if (unlikely(__pyx_t_1 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 20; __pyx_clineno = __LINE__; goto __pyx_L1_error;};\n  __Pyx_GOTREF(__pyx_t_1);\n  if (!(likely(((__pyx_t_1) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_5numpy_ndarray))))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 20; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n  __pyx_t_4 = ((PyArrayObject *)__pyx_t_1);\n  {\n    __Pyx_BufFmt_StackElem __pyx_stack[1];\n    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_x2.rcbuffer->pybuffer, (PyObject*)__pyx_t_4, &__Pyx_TypeInfo_nn___pyx_t_5numpy_float32_t, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {\n      __pyx_v_x2 = ((PyArrayObject *)Py_None); __Pyx_INCREF(Py_None); __pyx_pybuffernd_x2.rcbuffer->pybuffer.buf = NULL;\n      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 20; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n    } else {__pyx_pybuffernd_x2.diminfo[0].strides = __pyx_pybuffernd_x2.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_x2.diminfo[0].shape = __pyx_pybuffernd_x2.rcbuffer->pybuffer.shape[0];\n    }\n  }\n  __pyx_t_4 = 0;\n  __pyx_v_x2 = ((PyArrayObject *)__pyx_t_1);\n  __pyx_t_1 = 0;\n\n  /* \"nms/cpu_nms.pyx\":21\n *     cdef np.ndarray[np.float32_t, ndim=1] y1 = dets[:, 1]\n *     cdef np.ndarray[np.float32_t, ndim=1] x2 = dets[:, 2]\n *     cdef np.ndarray[np.float32_t, ndim=1] y2 = dets[:, 3]             # <<<<<<<<<<<<<<\n *     cdef np.ndarray[np.float32_t, ndim=1] scores = dets[:, 4]\n * \n */\n  __pyx_t_1 = PyObject_GetItem(((PyObject *)__pyx_v_dets), __pyx_tuple__8); if (unlikely(__pyx_t_1 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 21; __pyx_clineno = __LINE__; goto __pyx_L1_error;};\n  __Pyx_GOTREF(__pyx_t_1);\n  if (!(likely(((__pyx_t_1) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_5numpy_ndarray))))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 21; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n  __pyx_t_5 = ((PyArrayObject *)__pyx_t_1);\n  {\n    __Pyx_BufFmt_StackElem __pyx_stack[1];\n    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_y2.rcbuffer->pybuffer, (PyObject*)__pyx_t_5, &__Pyx_TypeInfo_nn___pyx_t_5numpy_float32_t, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {\n      __pyx_v_y2 = ((PyArrayObject *)Py_None); __Pyx_INCREF(Py_None); __pyx_pybuffernd_y2.rcbuffer->pybuffer.buf = NULL;\n      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 21; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n    } else {__pyx_pybuffernd_y2.diminfo[0].strides = __pyx_pybuffernd_y2.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_y2.diminfo[0].shape = __pyx_pybuffernd_y2.rcbuffer->pybuffer.shape[0];\n    }\n  }\n  __pyx_t_5 = 0;\n  __pyx_v_y2 = ((PyArrayObject *)__pyx_t_1);\n  __pyx_t_1 = 0;\n\n  /* \"nms/cpu_nms.pyx\":22\n *     cdef np.ndarray[np.float32_t, ndim=1] x2 = dets[:, 2]\n *     cdef np.ndarray[np.float32_t, ndim=1] y2 = dets[:, 3]\n *     cdef np.ndarray[np.float32_t, ndim=1] scores = dets[:, 4]             # <<<<<<<<<<<<<<\n * \n *     cdef np.ndarray[np.float32_t, ndim=1] areas = (x2 - x1 + 1) * (y2 - y1 + 1)\n */\n  __pyx_t_1 = PyObject_GetItem(((PyObject *)__pyx_v_dets), __pyx_tuple__10); if (unlikely(__pyx_t_1 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 22; __pyx_clineno = __LINE__; goto __pyx_L1_error;};\n  __Pyx_GOTREF(__pyx_t_1);\n  if (!(likely(((__pyx_t_1) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_5numpy_ndarray))))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 22; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n  __pyx_t_6 = ((PyArrayObject *)__pyx_t_1);\n  {\n    __Pyx_BufFmt_StackElem __pyx_stack[1];\n    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_scores.rcbuffer->pybuffer, (PyObject*)__pyx_t_6, &__Pyx_TypeInfo_nn___pyx_t_5numpy_float32_t, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {\n      __pyx_v_scores = ((PyArrayObject *)Py_None); __Pyx_INCREF(Py_None); __pyx_pybuffernd_scores.rcbuffer->pybuffer.buf = NULL;\n      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 22; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n    } else {__pyx_pybuffernd_scores.diminfo[0].strides = __pyx_pybuffernd_scores.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_scores.diminfo[0].shape = __pyx_pybuffernd_scores.rcbuffer->pybuffer.shape[0];\n    }\n  }\n  __pyx_t_6 = 0;\n  __pyx_v_scores = ((PyArrayObject *)__pyx_t_1);\n  __pyx_t_1 = 0;\n\n  /* \"nms/cpu_nms.pyx\":24\n *     cdef np.ndarray[np.float32_t, ndim=1] scores = dets[:, 4]\n * \n *     cdef np.ndarray[np.float32_t, ndim=1] areas = (x2 - x1 + 1) * (y2 - y1 + 1)             # <<<<<<<<<<<<<<\n *     cdef np.ndarray[np.int_t, ndim=1] order = scores.argsort()[::-1]\n * \n */\n  __pyx_t_1 = PyNumber_Subtract(((PyObject *)__pyx_v_x2), ((PyObject *)__pyx_v_x1)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 24; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n  __Pyx_GOTREF(__pyx_t_1);\n  __pyx_t_7 = PyNumber_Add(__pyx_t_1, __pyx_int_1); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 24; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n  __Pyx_GOTREF(__pyx_t_7);\n  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;\n  __pyx_t_1 = PyNumber_Subtract(((PyObject *)__pyx_v_y2), ((PyObject *)__pyx_v_y1)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 24; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n  __Pyx_GOTREF(__pyx_t_1);\n  __pyx_t_8 = PyNumber_Add(__pyx_t_1, __pyx_int_1); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 24; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n  __Pyx_GOTREF(__pyx_t_8);\n  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;\n  __pyx_t_1 = PyNumber_Multiply(__pyx_t_7, __pyx_t_8); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 24; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n  __Pyx_GOTREF(__pyx_t_1);\n  __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;\n  __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;\n  if (!(likely(((__pyx_t_1) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_5numpy_ndarray))))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 24; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n  __pyx_t_9 = ((PyArrayObject *)__pyx_t_1);\n  {\n    __Pyx_BufFmt_StackElem __pyx_stack[1];\n    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_areas.rcbuffer->pybuffer, (PyObject*)__pyx_t_9, &__Pyx_TypeInfo_nn___pyx_t_5numpy_float32_t, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {\n      __pyx_v_areas = ((PyArrayObject *)Py_None); __Pyx_INCREF(Py_None); __pyx_pybuffernd_areas.rcbuffer->pybuffer.buf = NULL;\n      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 24; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n    } else {__pyx_pybuffernd_areas.diminfo[0].strides = __pyx_pybuffernd_areas.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_areas.diminfo[0].shape = __pyx_pybuffernd_areas.rcbuffer->pybuffer.shape[0];\n    }\n  }\n  __pyx_t_9 = 0;\n  __pyx_v_areas = ((PyArrayObject *)__pyx_t_1);\n  __pyx_t_1 = 0;\n\n  /* \"nms/cpu_nms.pyx\":25\n * \n *     cdef np.ndarray[np.float32_t, ndim=1] areas = (x2 - x1 + 1) * (y2 - y1 + 1)\n *     cdef np.ndarray[np.int_t, ndim=1] order = scores.argsort()[::-1]             # <<<<<<<<<<<<<<\n * \n *     cdef int ndets = dets.shape[0]\n */\n  __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_scores), __pyx_n_s_argsort); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 25; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n  __Pyx_GOTREF(__pyx_t_1);\n  __pyx_t_8 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_empty_tuple, NULL); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 25; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n  __Pyx_GOTREF(__pyx_t_8);\n  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;\n  __pyx_t_1 = PyObject_GetItem(__pyx_t_8, __pyx_slice__11); if (unlikely(__pyx_t_1 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 25; __pyx_clineno = __LINE__; goto __pyx_L1_error;};\n  __Pyx_GOTREF(__pyx_t_1);\n  __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;\n  if (!(likely(((__pyx_t_1) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_5numpy_ndarray))))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 25; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n  __pyx_t_10 = ((PyArrayObject *)__pyx_t_1);\n  {\n    __Pyx_BufFmt_StackElem __pyx_stack[1];\n    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_order.rcbuffer->pybuffer, (PyObject*)__pyx_t_10, &__Pyx_TypeInfo_nn___pyx_t_5numpy_int_t, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {\n      __pyx_v_order = ((PyArrayObject *)Py_None); __Pyx_INCREF(Py_None); __pyx_pybuffernd_order.rcbuffer->pybuffer.buf = NULL;\n      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 25; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n    } else {__pyx_pybuffernd_order.diminfo[0].strides = __pyx_pybuffernd_order.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_order.diminfo[0].shape = __pyx_pybuffernd_order.rcbuffer->pybuffer.shape[0];\n    }\n  }\n  __pyx_t_10 = 0;\n  __pyx_v_order = ((PyArrayObject *)__pyx_t_1);\n  __pyx_t_1 = 0;\n\n  /* \"nms/cpu_nms.pyx\":27\n *     cdef np.ndarray[np.int_t, ndim=1] order = scores.argsort()[::-1]\n * \n *     cdef int ndets = dets.shape[0]             # <<<<<<<<<<<<<<\n *     cdef np.ndarray[np.int_t, ndim=1] suppressed = \\\n *             np.zeros((ndets), dtype=np.int)\n */\n  __pyx_v_ndets = (__pyx_v_dets->dimensions[0]);\n\n  /* \"nms/cpu_nms.pyx\":29\n *     cdef int ndets = dets.shape[0]\n *     cdef np.ndarray[np.int_t, ndim=1] suppressed = \\\n *             np.zeros((ndets), dtype=np.int)             # <<<<<<<<<<<<<<\n * \n *     # nominal indices\n */\n  __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 29; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n  __Pyx_GOTREF(__pyx_t_1);\n  __pyx_t_8 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_zeros); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 29; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n  __Pyx_GOTREF(__pyx_t_8);\n  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;\n  __pyx_t_1 = __Pyx_PyInt_From_int(__pyx_v_ndets); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 29; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n  __Pyx_GOTREF(__pyx_t_1);\n  __pyx_t_7 = PyTuple_New(1); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 29; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n  __Pyx_GOTREF(__pyx_t_7);\n  PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_1);\n  __Pyx_GIVEREF(__pyx_t_1);\n  __pyx_t_1 = 0;\n  __pyx_t_1 = PyDict_New(); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 29; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n  __Pyx_GOTREF(__pyx_t_1);\n  __pyx_t_11 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 29; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n  __Pyx_GOTREF(__pyx_t_11);\n  __pyx_t_12 = __Pyx_PyObject_GetAttrStr(__pyx_t_11, __pyx_n_s_int); if (unlikely(!__pyx_t_12)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 29; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n  __Pyx_GOTREF(__pyx_t_12);\n  __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;\n  if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_dtype, __pyx_t_12) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 29; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n  __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0;\n  __pyx_t_12 = __Pyx_PyObject_Call(__pyx_t_8, __pyx_t_7, __pyx_t_1); if (unlikely(!__pyx_t_12)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 29; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n  __Pyx_GOTREF(__pyx_t_12);\n  __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;\n  __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;\n  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;\n  if (!(likely(((__pyx_t_12) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_12, __pyx_ptype_5numpy_ndarray))))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 29; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n  __pyx_t_13 = ((PyArrayObject *)__pyx_t_12);\n  {\n    __Pyx_BufFmt_StackElem __pyx_stack[1];\n    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_suppressed.rcbuffer->pybuffer, (PyObject*)__pyx_t_13, &__Pyx_TypeInfo_nn___pyx_t_5numpy_int_t, PyBUF_FORMAT| PyBUF_STRIDES| PyBUF_WRITABLE, 1, 0, __pyx_stack) == -1)) {\n      __pyx_v_suppressed = ((PyArrayObject *)Py_None); __Pyx_INCREF(Py_None); __pyx_pybuffernd_suppressed.rcbuffer->pybuffer.buf = NULL;\n      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 28; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n    } else {__pyx_pybuffernd_suppressed.diminfo[0].strides = __pyx_pybuffernd_suppressed.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_suppressed.diminfo[0].shape = __pyx_pybuffernd_suppressed.rcbuffer->pybuffer.shape[0];\n    }\n  }\n  __pyx_t_13 = 0;\n  __pyx_v_suppressed = ((PyArrayObject *)__pyx_t_12);\n  __pyx_t_12 = 0;\n\n  /* \"nms/cpu_nms.pyx\":42\n *     cdef np.float32_t inter, ovr\n * \n *     keep = []             # <<<<<<<<<<<<<<\n *     for _i in range(ndets):\n *         i = order[_i]\n */\n  __pyx_t_12 = PyList_New(0); if (unlikely(!__pyx_t_12)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 42; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n  __Pyx_GOTREF(__pyx_t_12);\n  __pyx_v_keep = ((PyObject*)__pyx_t_12);\n  __pyx_t_12 = 0;\n\n  /* \"nms/cpu_nms.pyx\":43\n * \n *     keep = []\n *     for _i in range(ndets):             # <<<<<<<<<<<<<<\n *         i = order[_i]\n *         if suppressed[i] == 1:\n */\n  __pyx_t_14 = __pyx_v_ndets;\n  for (__pyx_t_15 = 0; __pyx_t_15 < __pyx_t_14; __pyx_t_15+=1) {\n    __pyx_v__i = __pyx_t_15;\n\n    /* \"nms/cpu_nms.pyx\":44\n *     keep = []\n *     for _i in range(ndets):\n *         i = order[_i]             # <<<<<<<<<<<<<<\n *         if suppressed[i] == 1:\n *             continue\n */\n    __pyx_t_16 = __pyx_v__i;\n    __pyx_t_17 = -1;\n    if (__pyx_t_16 < 0) {\n      __pyx_t_16 += __pyx_pybuffernd_order.diminfo[0].shape;\n      if (unlikely(__pyx_t_16 < 0)) __pyx_t_17 = 0;\n    } else if (unlikely(__pyx_t_16 >= __pyx_pybuffernd_order.diminfo[0].shape)) __pyx_t_17 = 0;\n    if (unlikely(__pyx_t_17 != -1)) {\n      __Pyx_RaiseBufferIndexError(__pyx_t_17);\n      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 44; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n    }\n    __pyx_v_i = (*__Pyx_BufPtrStrided1d(__pyx_t_5numpy_int_t *, __pyx_pybuffernd_order.rcbuffer->pybuffer.buf, __pyx_t_16, __pyx_pybuffernd_order.diminfo[0].strides));\n\n    /* \"nms/cpu_nms.pyx\":45\n *     for _i in range(ndets):\n *         i = order[_i]\n *         if suppressed[i] == 1:             # <<<<<<<<<<<<<<\n *             continue\n *         keep.append(i)\n */\n    __pyx_t_17 = __pyx_v_i;\n    __pyx_t_18 = -1;\n    if (__pyx_t_17 < 0) {\n      __pyx_t_17 += __pyx_pybuffernd_suppressed.diminfo[0].shape;\n      if (unlikely(__pyx_t_17 < 0)) __pyx_t_18 = 0;\n    } else if (unlikely(__pyx_t_17 >= __pyx_pybuffernd_suppressed.diminfo[0].shape)) __pyx_t_18 = 0;\n    if (unlikely(__pyx_t_18 != -1)) {\n      __Pyx_RaiseBufferIndexError(__pyx_t_18);\n      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 45; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n    }\n    __pyx_t_19 = (((*__Pyx_BufPtrStrided1d(__pyx_t_5numpy_int_t *, __pyx_pybuffernd_suppressed.rcbuffer->pybuffer.buf, __pyx_t_17, __pyx_pybuffernd_suppressed.diminfo[0].strides)) == 1) != 0);\n    if (__pyx_t_19) {\n\n      /* \"nms/cpu_nms.pyx\":46\n *         i = order[_i]\n *         if suppressed[i] == 1:\n *             continue             # <<<<<<<<<<<<<<\n *         keep.append(i)\n *         ix1 = x1[i]\n */\n      goto __pyx_L3_continue;\n    }\n\n    /* \"nms/cpu_nms.pyx\":47\n *         if suppressed[i] == 1:\n *             continue\n *         keep.append(i)             # <<<<<<<<<<<<<<\n *         ix1 = x1[i]\n *         iy1 = y1[i]\n */\n    __pyx_t_12 = __Pyx_PyInt_From_int(__pyx_v_i); if (unlikely(!__pyx_t_12)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 47; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n    __Pyx_GOTREF(__pyx_t_12);\n    __pyx_t_20 = __Pyx_PyList_Append(__pyx_v_keep, __pyx_t_12); if (unlikely(__pyx_t_20 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 47; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n    __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0;\n\n    /* \"nms/cpu_nms.pyx\":48\n *             continue\n *         keep.append(i)\n *         ix1 = x1[i]             # <<<<<<<<<<<<<<\n *         iy1 = y1[i]\n *         ix2 = x2[i]\n */\n    __pyx_t_18 = __pyx_v_i;\n    __pyx_t_21 = -1;\n    if (__pyx_t_18 < 0) {\n      __pyx_t_18 += __pyx_pybuffernd_x1.diminfo[0].shape;\n      if (unlikely(__pyx_t_18 < 0)) __pyx_t_21 = 0;\n    } else if (unlikely(__pyx_t_18 >= __pyx_pybuffernd_x1.diminfo[0].shape)) __pyx_t_21 = 0;\n    if (unlikely(__pyx_t_21 != -1)) {\n      __Pyx_RaiseBufferIndexError(__pyx_t_21);\n      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 48; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n    }\n    __pyx_v_ix1 = (*__Pyx_BufPtrStrided1d(__pyx_t_5numpy_float32_t *, __pyx_pybuffernd_x1.rcbuffer->pybuffer.buf, __pyx_t_18, __pyx_pybuffernd_x1.diminfo[0].strides));\n\n    /* \"nms/cpu_nms.pyx\":49\n *         keep.append(i)\n *         ix1 = x1[i]\n *         iy1 = y1[i]             # <<<<<<<<<<<<<<\n *         ix2 = x2[i]\n *         iy2 = y2[i]\n */\n    __pyx_t_21 = __pyx_v_i;\n    __pyx_t_22 = -1;\n    if (__pyx_t_21 < 0) {\n      __pyx_t_21 += __pyx_pybuffernd_y1.diminfo[0].shape;\n      if (unlikely(__pyx_t_21 < 0)) __pyx_t_22 = 0;\n    } else if (unlikely(__pyx_t_21 >= __pyx_pybuffernd_y1.diminfo[0].shape)) __pyx_t_22 = 0;\n    if (unlikely(__pyx_t_22 != -1)) {\n      __Pyx_RaiseBufferIndexError(__pyx_t_22);\n      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 49; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n    }\n    __pyx_v_iy1 = (*__Pyx_BufPtrStrided1d(__pyx_t_5numpy_float32_t *, __pyx_pybuffernd_y1.rcbuffer->pybuffer.buf, __pyx_t_21, __pyx_pybuffernd_y1.diminfo[0].strides));\n\n    /* \"nms/cpu_nms.pyx\":50\n *         ix1 = x1[i]\n *         iy1 = y1[i]\n *         ix2 = x2[i]             # <<<<<<<<<<<<<<\n *         iy2 = y2[i]\n *         iarea = areas[i]\n */\n    __pyx_t_22 = __pyx_v_i;\n    __pyx_t_23 = -1;\n    if (__pyx_t_22 < 0) {\n      __pyx_t_22 += __pyx_pybuffernd_x2.diminfo[0].shape;\n      if (unlikely(__pyx_t_22 < 0)) __pyx_t_23 = 0;\n    } else if (unlikely(__pyx_t_22 >= __pyx_pybuffernd_x2.diminfo[0].shape)) __pyx_t_23 = 0;\n    if (unlikely(__pyx_t_23 != -1)) {\n      __Pyx_RaiseBufferIndexError(__pyx_t_23);\n      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 50; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n    }\n    __pyx_v_ix2 = (*__Pyx_BufPtrStrided1d(__pyx_t_5numpy_float32_t *, __pyx_pybuffernd_x2.rcbuffer->pybuffer.buf, __pyx_t_22, __pyx_pybuffernd_x2.diminfo[0].strides));\n\n    /* \"nms/cpu_nms.pyx\":51\n *         iy1 = y1[i]\n *         ix2 = x2[i]\n *         iy2 = y2[i]             # <<<<<<<<<<<<<<\n *         iarea = areas[i]\n *         for _j in range(_i + 1, ndets):\n */\n    __pyx_t_23 = __pyx_v_i;\n    __pyx_t_24 = -1;\n    if (__pyx_t_23 < 0) {\n      __pyx_t_23 += __pyx_pybuffernd_y2.diminfo[0].shape;\n      if (unlikely(__pyx_t_23 < 0)) __pyx_t_24 = 0;\n    } else if (unlikely(__pyx_t_23 >= __pyx_pybuffernd_y2.diminfo[0].shape)) __pyx_t_24 = 0;\n    if (unlikely(__pyx_t_24 != -1)) {\n      __Pyx_RaiseBufferIndexError(__pyx_t_24);\n      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 51; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n    }\n    __pyx_v_iy2 = (*__Pyx_BufPtrStrided1d(__pyx_t_5numpy_float32_t *, __pyx_pybuffernd_y2.rcbuffer->pybuffer.buf, __pyx_t_23, __pyx_pybuffernd_y2.diminfo[0].strides));\n\n    /* \"nms/cpu_nms.pyx\":52\n *         ix2 = x2[i]\n *         iy2 = y2[i]\n *         iarea = areas[i]             # <<<<<<<<<<<<<<\n *         for _j in range(_i + 1, ndets):\n *             j = order[_j]\n */\n    __pyx_t_24 = __pyx_v_i;\n    __pyx_t_25 = -1;\n    if (__pyx_t_24 < 0) {\n      __pyx_t_24 += __pyx_pybuffernd_areas.diminfo[0].shape;\n      if (unlikely(__pyx_t_24 < 0)) __pyx_t_25 = 0;\n    } else if (unlikely(__pyx_t_24 >= __pyx_pybuffernd_areas.diminfo[0].shape)) __pyx_t_25 = 0;\n    if (unlikely(__pyx_t_25 != -1)) {\n      __Pyx_RaiseBufferIndexError(__pyx_t_25);\n      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 52; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n    }\n    __pyx_v_iarea = (*__Pyx_BufPtrStrided1d(__pyx_t_5numpy_float32_t *, __pyx_pybuffernd_areas.rcbuffer->pybuffer.buf, __pyx_t_24, __pyx_pybuffernd_areas.diminfo[0].strides));\n\n    /* \"nms/cpu_nms.pyx\":53\n *         iy2 = y2[i]\n *         iarea = areas[i]\n *         for _j in range(_i + 1, ndets):             # <<<<<<<<<<<<<<\n *             j = order[_j]\n *             if suppressed[j] == 1:\n */\n    __pyx_t_25 = __pyx_v_ndets;\n    for (__pyx_t_26 = (__pyx_v__i + 1); __pyx_t_26 < __pyx_t_25; __pyx_t_26+=1) {\n      __pyx_v__j = __pyx_t_26;\n\n      /* \"nms/cpu_nms.pyx\":54\n *         iarea = areas[i]\n *         for _j in range(_i + 1, ndets):\n *             j = order[_j]             # <<<<<<<<<<<<<<\n *             if suppressed[j] == 1:\n *                 continue\n */\n      __pyx_t_27 = __pyx_v__j;\n      __pyx_t_28 = -1;\n      if (__pyx_t_27 < 0) {\n        __pyx_t_27 += __pyx_pybuffernd_order.diminfo[0].shape;\n        if (unlikely(__pyx_t_27 < 0)) __pyx_t_28 = 0;\n      } else if (unlikely(__pyx_t_27 >= __pyx_pybuffernd_order.diminfo[0].shape)) __pyx_t_28 = 0;\n      if (unlikely(__pyx_t_28 != -1)) {\n        __Pyx_RaiseBufferIndexError(__pyx_t_28);\n        {__pyx_filename = __pyx_f[0]; __pyx_lineno = 54; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n      }\n      __pyx_v_j = (*__Pyx_BufPtrStrided1d(__pyx_t_5numpy_int_t *, __pyx_pybuffernd_order.rcbuffer->pybuffer.buf, __pyx_t_27, __pyx_pybuffernd_order.diminfo[0].strides));\n\n      /* \"nms/cpu_nms.pyx\":55\n *         for _j in range(_i + 1, ndets):\n *             j = order[_j]\n *             if suppressed[j] == 1:             # <<<<<<<<<<<<<<\n *                 continue\n *             xx1 = max(ix1, x1[j])\n */\n      __pyx_t_28 = __pyx_v_j;\n      __pyx_t_29 = -1;\n      if (__pyx_t_28 < 0) {\n        __pyx_t_28 += __pyx_pybuffernd_suppressed.diminfo[0].shape;\n        if (unlikely(__pyx_t_28 < 0)) __pyx_t_29 = 0;\n      } else if (unlikely(__pyx_t_28 >= __pyx_pybuffernd_suppressed.diminfo[0].shape)) __pyx_t_29 = 0;\n      if (unlikely(__pyx_t_29 != -1)) {\n        __Pyx_RaiseBufferIndexError(__pyx_t_29);\n        {__pyx_filename = __pyx_f[0]; __pyx_lineno = 55; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n      }\n      __pyx_t_19 = (((*__Pyx_BufPtrStrided1d(__pyx_t_5numpy_int_t *, __pyx_pybuffernd_suppressed.rcbuffer->pybuffer.buf, __pyx_t_28, __pyx_pybuffernd_suppressed.diminfo[0].strides)) == 1) != 0);\n      if (__pyx_t_19) {\n\n        /* \"nms/cpu_nms.pyx\":56\n *             j = order[_j]\n *             if suppressed[j] == 1:\n *                 continue             # <<<<<<<<<<<<<<\n *             xx1 = max(ix1, x1[j])\n *             yy1 = max(iy1, y1[j])\n */\n        goto __pyx_L6_continue;\n      }\n\n      /* \"nms/cpu_nms.pyx\":57\n *             if suppressed[j] == 1:\n *                 continue\n *             xx1 = max(ix1, x1[j])             # <<<<<<<<<<<<<<\n *             yy1 = max(iy1, y1[j])\n *             xx2 = min(ix2, x2[j])\n */\n      __pyx_t_29 = __pyx_v_j;\n      __pyx_t_30 = -1;\n      if (__pyx_t_29 < 0) {\n        __pyx_t_29 += __pyx_pybuffernd_x1.diminfo[0].shape;\n        if (unlikely(__pyx_t_29 < 0)) __pyx_t_30 = 0;\n      } else if (unlikely(__pyx_t_29 >= __pyx_pybuffernd_x1.diminfo[0].shape)) __pyx_t_30 = 0;\n      if (unlikely(__pyx_t_30 != -1)) {\n        __Pyx_RaiseBufferIndexError(__pyx_t_30);\n        {__pyx_filename = __pyx_f[0]; __pyx_lineno = 57; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n      }\n      __pyx_v_xx1 = __pyx_f_3nms_7cpu_nms_max(__pyx_v_ix1, (*__Pyx_BufPtrStrided1d(__pyx_t_5numpy_float32_t *, __pyx_pybuffernd_x1.rcbuffer->pybuffer.buf, __pyx_t_29, __pyx_pybuffernd_x1.diminfo[0].strides)));\n\n      /* \"nms/cpu_nms.pyx\":58\n *                 continue\n *             xx1 = max(ix1, x1[j])\n *             yy1 = max(iy1, y1[j])             # <<<<<<<<<<<<<<\n *             xx2 = min(ix2, x2[j])\n *             yy2 = min(iy2, y2[j])\n */\n      __pyx_t_30 = __pyx_v_j;\n      __pyx_t_31 = -1;\n      if (__pyx_t_30 < 0) {\n        __pyx_t_30 += __pyx_pybuffernd_y1.diminfo[0].shape;\n        if (unlikely(__pyx_t_30 < 0)) __pyx_t_31 = 0;\n      } else if (unlikely(__pyx_t_30 >= __pyx_pybuffernd_y1.diminfo[0].shape)) __pyx_t_31 = 0;\n      if (unlikely(__pyx_t_31 != -1)) {\n        __Pyx_RaiseBufferIndexError(__pyx_t_31);\n        {__pyx_filename = __pyx_f[0]; __pyx_lineno = 58; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n      }\n      __pyx_v_yy1 = __pyx_f_3nms_7cpu_nms_max(__pyx_v_iy1, (*__Pyx_BufPtrStrided1d(__pyx_t_5numpy_float32_t *, __pyx_pybuffernd_y1.rcbuffer->pybuffer.buf, __pyx_t_30, __pyx_pybuffernd_y1.diminfo[0].strides)));\n\n      /* \"nms/cpu_nms.pyx\":59\n *             xx1 = max(ix1, x1[j])\n *             yy1 = max(iy1, y1[j])\n *             xx2 = min(ix2, x2[j])             # <<<<<<<<<<<<<<\n *             yy2 = min(iy2, y2[j])\n *             w = max(0.0, xx2 - xx1 + 1)\n */\n      __pyx_t_31 = __pyx_v_j;\n      __pyx_t_32 = -1;\n      if (__pyx_t_31 < 0) {\n        __pyx_t_31 += __pyx_pybuffernd_x2.diminfo[0].shape;\n        if (unlikely(__pyx_t_31 < 0)) __pyx_t_32 = 0;\n      } else if (unlikely(__pyx_t_31 >= __pyx_pybuffernd_x2.diminfo[0].shape)) __pyx_t_32 = 0;\n      if (unlikely(__pyx_t_32 != -1)) {\n        __Pyx_RaiseBufferIndexError(__pyx_t_32);\n        {__pyx_filename = __pyx_f[0]; __pyx_lineno = 59; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n      }\n      __pyx_v_xx2 = __pyx_f_3nms_7cpu_nms_min(__pyx_v_ix2, (*__Pyx_BufPtrStrided1d(__pyx_t_5numpy_float32_t *, __pyx_pybuffernd_x2.rcbuffer->pybuffer.buf, __pyx_t_31, __pyx_pybuffernd_x2.diminfo[0].strides)));\n\n      /* \"nms/cpu_nms.pyx\":60\n *             yy1 = max(iy1, y1[j])\n *             xx2 = min(ix2, x2[j])\n *             yy2 = min(iy2, y2[j])             # <<<<<<<<<<<<<<\n *             w = max(0.0, xx2 - xx1 + 1)\n *             h = max(0.0, yy2 - yy1 + 1)\n */\n      __pyx_t_32 = __pyx_v_j;\n      __pyx_t_33 = -1;\n      if (__pyx_t_32 < 0) {\n        __pyx_t_32 += __pyx_pybuffernd_y2.diminfo[0].shape;\n        if (unlikely(__pyx_t_32 < 0)) __pyx_t_33 = 0;\n      } else if (unlikely(__pyx_t_32 >= __pyx_pybuffernd_y2.diminfo[0].shape)) __pyx_t_33 = 0;\n      if (unlikely(__pyx_t_33 != -1)) {\n        __Pyx_RaiseBufferIndexError(__pyx_t_33);\n        {__pyx_filename = __pyx_f[0]; __pyx_lineno = 60; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n      }\n      __pyx_v_yy2 = __pyx_f_3nms_7cpu_nms_min(__pyx_v_iy2, (*__Pyx_BufPtrStrided1d(__pyx_t_5numpy_float32_t *, __pyx_pybuffernd_y2.rcbuffer->pybuffer.buf, __pyx_t_32, __pyx_pybuffernd_y2.diminfo[0].strides)));\n\n      /* \"nms/cpu_nms.pyx\":61\n *             xx2 = min(ix2, x2[j])\n *             yy2 = min(iy2, y2[j])\n *             w = max(0.0, xx2 - xx1 + 1)             # <<<<<<<<<<<<<<\n *             h = max(0.0, yy2 - yy1 + 1)\n *             inter = w * h\n */\n      __pyx_v_w = __pyx_f_3nms_7cpu_nms_max(0.0, ((__pyx_v_xx2 - __pyx_v_xx1) + 1.0));\n\n      /* \"nms/cpu_nms.pyx\":62\n *             yy2 = min(iy2, y2[j])\n *             w = max(0.0, xx2 - xx1 + 1)\n *             h = max(0.0, yy2 - yy1 + 1)             # <<<<<<<<<<<<<<\n *             inter = w * h\n *             ovr = inter / (iarea + areas[j] - inter)\n */\n      __pyx_v_h = __pyx_f_3nms_7cpu_nms_max(0.0, ((__pyx_v_yy2 - __pyx_v_yy1) + 1.0));\n\n      /* \"nms/cpu_nms.pyx\":63\n *             w = max(0.0, xx2 - xx1 + 1)\n *             h = max(0.0, yy2 - yy1 + 1)\n *             inter = w * h             # <<<<<<<<<<<<<<\n *             ovr = inter / (iarea + areas[j] - inter)\n *             if ovr >= thresh:\n */\n      __pyx_v_inter = (__pyx_v_w * __pyx_v_h);\n\n      /* \"nms/cpu_nms.pyx\":64\n *             h = max(0.0, yy2 - yy1 + 1)\n *             inter = w * h\n *             ovr = inter / (iarea + areas[j] - inter)             # <<<<<<<<<<<<<<\n *             if ovr >= thresh:\n *                 suppressed[j] = 1\n */\n      __pyx_t_33 = __pyx_v_j;\n      __pyx_t_34 = -1;\n      if (__pyx_t_33 < 0) {\n        __pyx_t_33 += __pyx_pybuffernd_areas.diminfo[0].shape;\n        if (unlikely(__pyx_t_33 < 0)) __pyx_t_34 = 0;\n      } else if (unlikely(__pyx_t_33 >= __pyx_pybuffernd_areas.diminfo[0].shape)) __pyx_t_34 = 0;\n      if (unlikely(__pyx_t_34 != -1)) {\n        __Pyx_RaiseBufferIndexError(__pyx_t_34);\n        {__pyx_filename = __pyx_f[0]; __pyx_lineno = 64; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n      }\n      __pyx_t_35 = ((__pyx_v_iarea + (*__Pyx_BufPtrStrided1d(__pyx_t_5numpy_float32_t *, __pyx_pybuffernd_areas.rcbuffer->pybuffer.buf, __pyx_t_33, __pyx_pybuffernd_areas.diminfo[0].strides))) - __pyx_v_inter);\n      if (unlikely(__pyx_t_35 == 0)) {\n        #ifdef WITH_THREAD\n        PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();\n        #endif\n        PyErr_SetString(PyExc_ZeroDivisionError, \"float division\");\n        #ifdef WITH_THREAD\n        PyGILState_Release(__pyx_gilstate_save);\n        #endif\n        {__pyx_filename = __pyx_f[0]; __pyx_lineno = 64; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n      }\n      __pyx_v_ovr = (__pyx_v_inter / __pyx_t_35);\n\n      /* \"nms/cpu_nms.pyx\":65\n *             inter = w * h\n *             ovr = inter / (iarea + areas[j] - inter)\n *             if ovr >= thresh:             # <<<<<<<<<<<<<<\n *                 suppressed[j] = 1\n * \n */\n      __pyx_t_12 = PyFloat_FromDouble(__pyx_v_ovr); if (unlikely(!__pyx_t_12)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 65; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n      __Pyx_GOTREF(__pyx_t_12);\n      __pyx_t_1 = PyObject_RichCompare(__pyx_t_12, __pyx_v_thresh, Py_GE); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 65; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n      __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0;\n      __pyx_t_19 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_19 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 65; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;\n      if (__pyx_t_19) {\n\n        /* \"nms/cpu_nms.pyx\":66\n *             ovr = inter / (iarea + areas[j] - inter)\n *             if ovr >= thresh:\n *                 suppressed[j] = 1             # <<<<<<<<<<<<<<\n * \n *     return keep\n */\n        __pyx_t_34 = __pyx_v_j;\n        __pyx_t_36 = -1;\n        if (__pyx_t_34 < 0) {\n          __pyx_t_34 += __pyx_pybuffernd_suppressed.diminfo[0].shape;\n          if (unlikely(__pyx_t_34 < 0)) __pyx_t_36 = 0;\n        } else if (unlikely(__pyx_t_34 >= __pyx_pybuffernd_suppressed.diminfo[0].shape)) __pyx_t_36 = 0;\n        if (unlikely(__pyx_t_36 != -1)) {\n          __Pyx_RaiseBufferIndexError(__pyx_t_36);\n          {__pyx_filename = __pyx_f[0]; __pyx_lineno = 66; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n        }\n        *__Pyx_BufPtrStrided1d(__pyx_t_5numpy_int_t *, __pyx_pybuffernd_suppressed.rcbuffer->pybuffer.buf, __pyx_t_34, __pyx_pybuffernd_suppressed.diminfo[0].strides) = 1;\n        goto __pyx_L9;\n      }\n      __pyx_L9:;\n      __pyx_L6_continue:;\n    }\n    __pyx_L3_continue:;\n  }\n\n  /* \"nms/cpu_nms.pyx\":68\n *                 suppressed[j] = 1\n * \n *     return keep             # <<<<<<<<<<<<<<\n */\n  __Pyx_XDECREF(__pyx_r);\n  __Pyx_INCREF(__pyx_v_keep);\n  __pyx_r = __pyx_v_keep;\n  goto __pyx_L0;\n\n  /* \"nms/cpu_nms.pyx\":17\n *     return a if a <= b else b\n * \n * def cpu_nms(np.ndarray[np.float32_t, ndim=2] dets, np.float thresh):             # <<<<<<<<<<<<<<\n *     cdef np.ndarray[np.float32_t, ndim=1] x1 = dets[:, 0]\n *     cdef np.ndarray[np.float32_t, ndim=1] y1 = dets[:, 1]\n */\n\n  /* function exit code */\n  __pyx_L1_error:;\n  __Pyx_XDECREF(__pyx_t_1);\n  __Pyx_XDECREF(__pyx_t_7);\n  __Pyx_XDECREF(__pyx_t_8);\n  __Pyx_XDECREF(__pyx_t_11);\n  __Pyx_XDECREF(__pyx_t_12);\n  { PyObject *__pyx_type, *__pyx_value, *__pyx_tb;\n    __Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb);\n    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_areas.rcbuffer->pybuffer);\n    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_dets.rcbuffer->pybuffer);\n    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_order.rcbuffer->pybuffer);\n    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_scores.rcbuffer->pybuffer);\n    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_suppressed.rcbuffer->pybuffer);\n    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_x1.rcbuffer->pybuffer);\n    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_x2.rcbuffer->pybuffer);\n    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_y1.rcbuffer->pybuffer);\n    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_y2.rcbuffer->pybuffer);\n  __Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);}\n  __Pyx_AddTraceback(\"nms.cpu_nms.cpu_nms\", __pyx_clineno, __pyx_lineno, __pyx_filename);\n  __pyx_r = NULL;\n  goto __pyx_L2;\n  __pyx_L0:;\n  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_areas.rcbuffer->pybuffer);\n  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_dets.rcbuffer->pybuffer);\n  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_order.rcbuffer->pybuffer);\n  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_scores.rcbuffer->pybuffer);\n  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_suppressed.rcbuffer->pybuffer);\n  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_x1.rcbuffer->pybuffer);\n  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_x2.rcbuffer->pybuffer);\n  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_y1.rcbuffer->pybuffer);\n  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_y2.rcbuffer->pybuffer);\n  __pyx_L2:;\n  __Pyx_XDECREF((PyObject *)__pyx_v_x1);\n  __Pyx_XDECREF((PyObject *)__pyx_v_y1);\n  __Pyx_XDECREF((PyObject *)__pyx_v_x2);\n  __Pyx_XDECREF((PyObject *)__pyx_v_y2);\n  __Pyx_XDECREF((PyObject *)__pyx_v_scores);\n  __Pyx_XDECREF((PyObject *)__pyx_v_areas);\n  __Pyx_XDECREF((PyObject *)__pyx_v_order);\n  __Pyx_XDECREF((PyObject *)__pyx_v_suppressed);\n  __Pyx_XDECREF(__pyx_v_keep);\n  __Pyx_XGIVEREF(__pyx_r);\n  __Pyx_RefNannyFinishContext();\n  return __pyx_r;\n}\n\n/* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":194\n *         # experimental exception made for __getbuffer__ and __releasebuffer__\n *         # -- the details of this may change.\n *         def __getbuffer__(ndarray self, Py_buffer* info, int flags):             # <<<<<<<<<<<<<<\n *             # This implementation of getbuffer is geared towards Cython\n *             # requirements, and does not yet fullfill the PEP.\n */\n\n/* Python wrapper */\nstatic CYTHON_UNUSED int __pyx_pw_5numpy_7ndarray_1__getbuffer__(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags); /*proto*/\nstatic CYTHON_UNUSED int __pyx_pw_5numpy_7ndarray_1__getbuffer__(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags) {\n  int __pyx_r;\n  __Pyx_RefNannyDeclarations\n  __Pyx_RefNannySetupContext(\"__getbuffer__ (wrapper)\", 0);\n  __pyx_r = __pyx_pf_5numpy_7ndarray___getbuffer__(((PyArrayObject *)__pyx_v_self), ((Py_buffer *)__pyx_v_info), ((int)__pyx_v_flags));\n\n  /* function exit code */\n  __Pyx_RefNannyFinishContext();\n  return __pyx_r;\n}\n\nstatic int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags) {\n  int __pyx_v_copy_shape;\n  int __pyx_v_i;\n  int __pyx_v_ndim;\n  int __pyx_v_endian_detector;\n  int __pyx_v_little_endian;\n  int __pyx_v_t;\n  char *__pyx_v_f;\n  PyArray_Descr *__pyx_v_descr = 0;\n  int __pyx_v_offset;\n  int __pyx_v_hasfields;\n  int __pyx_r;\n  __Pyx_RefNannyDeclarations\n  int __pyx_t_1;\n  int __pyx_t_2;\n  int __pyx_t_3;\n  PyObject *__pyx_t_4 = NULL;\n  int __pyx_t_5;\n  int __pyx_t_6;\n  int __pyx_t_7;\n  PyObject *__pyx_t_8 = NULL;\n  char *__pyx_t_9;\n  int __pyx_lineno = 0;\n  const char *__pyx_filename = NULL;\n  int __pyx_clineno = 0;\n  __Pyx_RefNannySetupContext(\"__getbuffer__\", 0);\n  if (__pyx_v_info != NULL) {\n    __pyx_v_info->obj = Py_None; __Pyx_INCREF(Py_None);\n    __Pyx_GIVEREF(__pyx_v_info->obj);\n  }\n\n  /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":200\n *             # of flags\n * \n *             if info == NULL: return             # <<<<<<<<<<<<<<\n * \n *             cdef int copy_shape, i, ndim\n */\n  __pyx_t_1 = ((__pyx_v_info == NULL) != 0);\n  if (__pyx_t_1) {\n    __pyx_r = 0;\n    goto __pyx_L0;\n  }\n\n  /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":203\n * \n *             cdef int copy_shape, i, ndim\n *             cdef int endian_detector = 1             # <<<<<<<<<<<<<<\n *             cdef bint little_endian = ((<char*>&endian_detector)[0] != 0)\n * \n */\n  __pyx_v_endian_detector = 1;\n\n  /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":204\n *             cdef int copy_shape, i, ndim\n *             cdef int endian_detector = 1\n *             cdef bint little_endian = ((<char*>&endian_detector)[0] != 0)             # <<<<<<<<<<<<<<\n * \n *             ndim = PyArray_NDIM(self)\n */\n  __pyx_v_little_endian = ((((char *)(&__pyx_v_endian_detector))[0]) != 0);\n\n  /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":206\n *             cdef bint little_endian = ((<char*>&endian_detector)[0] != 0)\n * \n *             ndim = PyArray_NDIM(self)             # <<<<<<<<<<<<<<\n * \n *             if sizeof(npy_intp) != sizeof(Py_ssize_t):\n */\n  __pyx_v_ndim = PyArray_NDIM(__pyx_v_self);\n\n  /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":208\n *             ndim = PyArray_NDIM(self)\n * \n *             if sizeof(npy_intp) != sizeof(Py_ssize_t):             # <<<<<<<<<<<<<<\n *                 copy_shape = 1\n *             else:\n */\n  __pyx_t_1 = (((sizeof(npy_intp)) != (sizeof(Py_ssize_t))) != 0);\n  if (__pyx_t_1) {\n\n    /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":209\n * \n *             if sizeof(npy_intp) != sizeof(Py_ssize_t):\n *                 copy_shape = 1             # <<<<<<<<<<<<<<\n *             else:\n *                 copy_shape = 0\n */\n    __pyx_v_copy_shape = 1;\n    goto __pyx_L4;\n  }\n  /*else*/ {\n\n    /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":211\n *                 copy_shape = 1\n *             else:\n *                 copy_shape = 0             # <<<<<<<<<<<<<<\n * \n *             if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS)\n */\n    __pyx_v_copy_shape = 0;\n  }\n  __pyx_L4:;\n\n  /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":213\n *                 copy_shape = 0\n * \n *             if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS)             # <<<<<<<<<<<<<<\n *                 and not PyArray_CHKFLAGS(self, NPY_C_CONTIGUOUS)):\n *                 raise ValueError(u\"ndarray is not C contiguous\")\n */\n  __pyx_t_1 = (((__pyx_v_flags & PyBUF_C_CONTIGUOUS) == PyBUF_C_CONTIGUOUS) != 0);\n  if (__pyx_t_1) {\n\n    /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":214\n * \n *             if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS)\n *                 and not PyArray_CHKFLAGS(self, NPY_C_CONTIGUOUS)):             # <<<<<<<<<<<<<<\n *                 raise ValueError(u\"ndarray is not C contiguous\")\n * \n */\n    __pyx_t_2 = ((!(PyArray_CHKFLAGS(__pyx_v_self, NPY_C_CONTIGUOUS) != 0)) != 0);\n    __pyx_t_3 = __pyx_t_2;\n  } else {\n    __pyx_t_3 = __pyx_t_1;\n  }\n  if (__pyx_t_3) {\n\n    /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":215\n *             if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS)\n *                 and not PyArray_CHKFLAGS(self, NPY_C_CONTIGUOUS)):\n *                 raise ValueError(u\"ndarray is not C contiguous\")             # <<<<<<<<<<<<<<\n * \n *             if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS)\n */\n    __pyx_t_4 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__12, NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 215; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n    __Pyx_GOTREF(__pyx_t_4);\n    __Pyx_Raise(__pyx_t_4, 0, 0, 0);\n    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;\n    {__pyx_filename = __pyx_f[1]; __pyx_lineno = 215; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n  }\n\n  /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":217\n *                 raise ValueError(u\"ndarray is not C contiguous\")\n * \n *             if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS)             # <<<<<<<<<<<<<<\n *                 and not PyArray_CHKFLAGS(self, NPY_F_CONTIGUOUS)):\n *                 raise ValueError(u\"ndarray is not Fortran contiguous\")\n */\n  __pyx_t_3 = (((__pyx_v_flags & PyBUF_F_CONTIGUOUS) == PyBUF_F_CONTIGUOUS) != 0);\n  if (__pyx_t_3) {\n\n    /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":218\n * \n *             if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS)\n *                 and not PyArray_CHKFLAGS(self, NPY_F_CONTIGUOUS)):             # <<<<<<<<<<<<<<\n *                 raise ValueError(u\"ndarray is not Fortran contiguous\")\n * \n */\n    __pyx_t_1 = ((!(PyArray_CHKFLAGS(__pyx_v_self, NPY_F_CONTIGUOUS) != 0)) != 0);\n    __pyx_t_2 = __pyx_t_1;\n  } else {\n    __pyx_t_2 = __pyx_t_3;\n  }\n  if (__pyx_t_2) {\n\n    /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":219\n *             if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS)\n *                 and not PyArray_CHKFLAGS(self, NPY_F_CONTIGUOUS)):\n *                 raise ValueError(u\"ndarray is not Fortran contiguous\")             # <<<<<<<<<<<<<<\n * \n *             info.buf = PyArray_DATA(self)\n */\n    __pyx_t_4 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__13, NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 219; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n    __Pyx_GOTREF(__pyx_t_4);\n    __Pyx_Raise(__pyx_t_4, 0, 0, 0);\n    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;\n    {__pyx_filename = __pyx_f[1]; __pyx_lineno = 219; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n  }\n\n  /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":221\n *                 raise ValueError(u\"ndarray is not Fortran contiguous\")\n * \n *             info.buf = PyArray_DATA(self)             # <<<<<<<<<<<<<<\n *             info.ndim = ndim\n *             if copy_shape:\n */\n  __pyx_v_info->buf = PyArray_DATA(__pyx_v_self);\n\n  /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":222\n * \n *             info.buf = PyArray_DATA(self)\n *             info.ndim = ndim             # <<<<<<<<<<<<<<\n *             if copy_shape:\n *                 # Allocate new buffer for strides and shape info.\n */\n  __pyx_v_info->ndim = __pyx_v_ndim;\n\n  /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":223\n *             info.buf = PyArray_DATA(self)\n *             info.ndim = ndim\n *             if copy_shape:             # <<<<<<<<<<<<<<\n *                 # Allocate new buffer for strides and shape info.\n *                 # This is allocated as one block, strides first.\n */\n  __pyx_t_2 = (__pyx_v_copy_shape != 0);\n  if (__pyx_t_2) {\n\n    /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":226\n *                 # Allocate new buffer for strides and shape info.\n *                 # This is allocated as one block, strides first.\n *                 info.strides = <Py_ssize_t*>stdlib.malloc(sizeof(Py_ssize_t) * <size_t>ndim * 2)             # <<<<<<<<<<<<<<\n *                 info.shape = info.strides + ndim\n *                 for i in range(ndim):\n */\n    __pyx_v_info->strides = ((Py_ssize_t *)malloc((((sizeof(Py_ssize_t)) * ((size_t)__pyx_v_ndim)) * 2)));\n\n    /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":227\n *                 # This is allocated as one block, strides first.\n *                 info.strides = <Py_ssize_t*>stdlib.malloc(sizeof(Py_ssize_t) * <size_t>ndim * 2)\n *                 info.shape = info.strides + ndim             # <<<<<<<<<<<<<<\n *                 for i in range(ndim):\n *                     info.strides[i] = PyArray_STRIDES(self)[i]\n */\n    __pyx_v_info->shape = (__pyx_v_info->strides + __pyx_v_ndim);\n\n    /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":228\n *                 info.strides = <Py_ssize_t*>stdlib.malloc(sizeof(Py_ssize_t) * <size_t>ndim * 2)\n *                 info.shape = info.strides + ndim\n *                 for i in range(ndim):             # <<<<<<<<<<<<<<\n *                     info.strides[i] = PyArray_STRIDES(self)[i]\n *                     info.shape[i] = PyArray_DIMS(self)[i]\n */\n    __pyx_t_5 = __pyx_v_ndim;\n    for (__pyx_t_6 = 0; __pyx_t_6 < __pyx_t_5; __pyx_t_6+=1) {\n      __pyx_v_i = __pyx_t_6;\n\n      /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":229\n *                 info.shape = info.strides + ndim\n *                 for i in range(ndim):\n *                     info.strides[i] = PyArray_STRIDES(self)[i]             # <<<<<<<<<<<<<<\n *                     info.shape[i] = PyArray_DIMS(self)[i]\n *             else:\n */\n      (__pyx_v_info->strides[__pyx_v_i]) = (PyArray_STRIDES(__pyx_v_self)[__pyx_v_i]);\n\n      /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":230\n *                 for i in range(ndim):\n *                     info.strides[i] = PyArray_STRIDES(self)[i]\n *                     info.shape[i] = PyArray_DIMS(self)[i]             # <<<<<<<<<<<<<<\n *             else:\n *                 info.strides = <Py_ssize_t*>PyArray_STRIDES(self)\n */\n      (__pyx_v_info->shape[__pyx_v_i]) = (PyArray_DIMS(__pyx_v_self)[__pyx_v_i]);\n    }\n    goto __pyx_L7;\n  }\n  /*else*/ {\n\n    /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":232\n *                     info.shape[i] = PyArray_DIMS(self)[i]\n *             else:\n *                 info.strides = <Py_ssize_t*>PyArray_STRIDES(self)             # <<<<<<<<<<<<<<\n *                 info.shape = <Py_ssize_t*>PyArray_DIMS(self)\n *             info.suboffsets = NULL\n */\n    __pyx_v_info->strides = ((Py_ssize_t *)PyArray_STRIDES(__pyx_v_self));\n\n    /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":233\n *             else:\n *                 info.strides = <Py_ssize_t*>PyArray_STRIDES(self)\n *                 info.shape = <Py_ssize_t*>PyArray_DIMS(self)             # <<<<<<<<<<<<<<\n *             info.suboffsets = NULL\n *             info.itemsize = PyArray_ITEMSIZE(self)\n */\n    __pyx_v_info->shape = ((Py_ssize_t *)PyArray_DIMS(__pyx_v_self));\n  }\n  __pyx_L7:;\n\n  /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":234\n *                 info.strides = <Py_ssize_t*>PyArray_STRIDES(self)\n *                 info.shape = <Py_ssize_t*>PyArray_DIMS(self)\n *             info.suboffsets = NULL             # <<<<<<<<<<<<<<\n *             info.itemsize = PyArray_ITEMSIZE(self)\n *             info.readonly = not PyArray_ISWRITEABLE(self)\n */\n  __pyx_v_info->suboffsets = NULL;\n\n  /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":235\n *                 info.shape = <Py_ssize_t*>PyArray_DIMS(self)\n *             info.suboffsets = NULL\n *             info.itemsize = PyArray_ITEMSIZE(self)             # <<<<<<<<<<<<<<\n *             info.readonly = not PyArray_ISWRITEABLE(self)\n * \n */\n  __pyx_v_info->itemsize = PyArray_ITEMSIZE(__pyx_v_self);\n\n  /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":236\n *             info.suboffsets = NULL\n *             info.itemsize = PyArray_ITEMSIZE(self)\n *             info.readonly = not PyArray_ISWRITEABLE(self)             # <<<<<<<<<<<<<<\n * \n *             cdef int t\n */\n  __pyx_v_info->readonly = (!(PyArray_ISWRITEABLE(__pyx_v_self) != 0));\n\n  /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":239\n * \n *             cdef int t\n *             cdef char* f = NULL             # <<<<<<<<<<<<<<\n *             cdef dtype descr = self.descr\n *             cdef list stack\n */\n  __pyx_v_f = NULL;\n\n  /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":240\n *             cdef int t\n *             cdef char* f = NULL\n *             cdef dtype descr = self.descr             # <<<<<<<<<<<<<<\n *             cdef list stack\n *             cdef int offset\n */\n  __pyx_t_4 = ((PyObject *)__pyx_v_self->descr);\n  __Pyx_INCREF(__pyx_t_4);\n  __pyx_v_descr = ((PyArray_Descr *)__pyx_t_4);\n  __pyx_t_4 = 0;\n\n  /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":244\n *             cdef int offset\n * \n *             cdef bint hasfields = PyDataType_HASFIELDS(descr)             # <<<<<<<<<<<<<<\n * \n *             if not hasfields and not copy_shape:\n */\n  __pyx_v_hasfields = PyDataType_HASFIELDS(__pyx_v_descr);\n\n  /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":246\n *             cdef bint hasfields = PyDataType_HASFIELDS(descr)\n * \n *             if not hasfields and not copy_shape:             # <<<<<<<<<<<<<<\n *                 # do not call releasebuffer\n *                 info.obj = None\n */\n  __pyx_t_2 = ((!(__pyx_v_hasfields != 0)) != 0);\n  if (__pyx_t_2) {\n    __pyx_t_3 = ((!(__pyx_v_copy_shape != 0)) != 0);\n    __pyx_t_1 = __pyx_t_3;\n  } else {\n    __pyx_t_1 = __pyx_t_2;\n  }\n  if (__pyx_t_1) {\n\n    /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":248\n *             if not hasfields and not copy_shape:\n *                 # do not call releasebuffer\n *                 info.obj = None             # <<<<<<<<<<<<<<\n *             else:\n *                 # need to call releasebuffer\n */\n    __Pyx_INCREF(Py_None);\n    __Pyx_GIVEREF(Py_None);\n    __Pyx_GOTREF(__pyx_v_info->obj);\n    __Pyx_DECREF(__pyx_v_info->obj);\n    __pyx_v_info->obj = Py_None;\n    goto __pyx_L10;\n  }\n  /*else*/ {\n\n    /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":251\n *             else:\n *                 # need to call releasebuffer\n *                 info.obj = self             # <<<<<<<<<<<<<<\n * \n *             if not hasfields:\n */\n    __Pyx_INCREF(((PyObject *)__pyx_v_self));\n    __Pyx_GIVEREF(((PyObject *)__pyx_v_self));\n    __Pyx_GOTREF(__pyx_v_info->obj);\n    __Pyx_DECREF(__pyx_v_info->obj);\n    __pyx_v_info->obj = ((PyObject *)__pyx_v_self);\n  }\n  __pyx_L10:;\n\n  /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":253\n *                 info.obj = self\n * \n *             if not hasfields:             # <<<<<<<<<<<<<<\n *                 t = descr.type_num\n *                 if ((descr.byteorder == c'>' and little_endian) or\n */\n  __pyx_t_1 = ((!(__pyx_v_hasfields != 0)) != 0);\n  if (__pyx_t_1) {\n\n    /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":254\n * \n *             if not hasfields:\n *                 t = descr.type_num             # <<<<<<<<<<<<<<\n *                 if ((descr.byteorder == c'>' and little_endian) or\n *                     (descr.byteorder == c'<' and not little_endian)):\n */\n    __pyx_t_5 = __pyx_v_descr->type_num;\n    __pyx_v_t = __pyx_t_5;\n\n    /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":255\n *             if not hasfields:\n *                 t = descr.type_num\n *                 if ((descr.byteorder == c'>' and little_endian) or             # <<<<<<<<<<<<<<\n *                     (descr.byteorder == c'<' and not little_endian)):\n *                     raise ValueError(u\"Non-native byte order not supported\")\n */\n    __pyx_t_1 = ((__pyx_v_descr->byteorder == '>') != 0);\n    if (__pyx_t_1) {\n      __pyx_t_2 = (__pyx_v_little_endian != 0);\n    } else {\n      __pyx_t_2 = __pyx_t_1;\n    }\n    if (!__pyx_t_2) {\n\n      /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":256\n *                 t = descr.type_num\n *                 if ((descr.byteorder == c'>' and little_endian) or\n *                     (descr.byteorder == c'<' and not little_endian)):             # <<<<<<<<<<<<<<\n *                     raise ValueError(u\"Non-native byte order not supported\")\n *                 if   t == NPY_BYTE:        f = \"b\"\n */\n      __pyx_t_1 = ((__pyx_v_descr->byteorder == '<') != 0);\n      if (__pyx_t_1) {\n        __pyx_t_3 = ((!(__pyx_v_little_endian != 0)) != 0);\n        __pyx_t_7 = __pyx_t_3;\n      } else {\n        __pyx_t_7 = __pyx_t_1;\n      }\n      __pyx_t_1 = __pyx_t_7;\n    } else {\n      __pyx_t_1 = __pyx_t_2;\n    }\n    if (__pyx_t_1) {\n\n      /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":257\n *                 if ((descr.byteorder == c'>' and little_endian) or\n *                     (descr.byteorder == c'<' and not little_endian)):\n *                     raise ValueError(u\"Non-native byte order not supported\")             # <<<<<<<<<<<<<<\n *                 if   t == NPY_BYTE:        f = \"b\"\n *                 elif t == NPY_UBYTE:       f = \"B\"\n */\n      __pyx_t_4 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__14, NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 257; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n      __Pyx_GOTREF(__pyx_t_4);\n      __Pyx_Raise(__pyx_t_4, 0, 0, 0);\n      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;\n      {__pyx_filename = __pyx_f[1]; __pyx_lineno = 257; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n    }\n\n    /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":274\n *                 elif t == NPY_CDOUBLE:     f = \"Zd\"\n *                 elif t == NPY_CLONGDOUBLE: f = \"Zg\"\n *                 elif t == NPY_OBJECT:      f = \"O\"             # <<<<<<<<<<<<<<\n *                 else:\n *                     raise ValueError(u\"unknown dtype code in numpy.pxd (%d)\" % t)\n */\n    switch (__pyx_v_t) {\n\n      /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":258\n *                     (descr.byteorder == c'<' and not little_endian)):\n *                     raise ValueError(u\"Non-native byte order not supported\")\n *                 if   t == NPY_BYTE:        f = \"b\"             # <<<<<<<<<<<<<<\n *                 elif t == NPY_UBYTE:       f = \"B\"\n *                 elif t == NPY_SHORT:       f = \"h\"\n */\n      case NPY_BYTE:\n      __pyx_v_f = __pyx_k_b;\n      break;\n\n      /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":259\n *                     raise ValueError(u\"Non-native byte order not supported\")\n *                 if   t == NPY_BYTE:        f = \"b\"\n *                 elif t == NPY_UBYTE:       f = \"B\"             # <<<<<<<<<<<<<<\n *                 elif t == NPY_SHORT:       f = \"h\"\n *                 elif t == NPY_USHORT:      f = \"H\"\n */\n      case NPY_UBYTE:\n      __pyx_v_f = __pyx_k_B;\n      break;\n\n      /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":260\n *                 if   t == NPY_BYTE:        f = \"b\"\n *                 elif t == NPY_UBYTE:       f = \"B\"\n *                 elif t == NPY_SHORT:       f = \"h\"             # <<<<<<<<<<<<<<\n *                 elif t == NPY_USHORT:      f = \"H\"\n *                 elif t == NPY_INT:         f = \"i\"\n */\n      case NPY_SHORT:\n      __pyx_v_f = __pyx_k_h;\n      break;\n\n      /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":261\n *                 elif t == NPY_UBYTE:       f = \"B\"\n *                 elif t == NPY_SHORT:       f = \"h\"\n *                 elif t == NPY_USHORT:      f = \"H\"             # <<<<<<<<<<<<<<\n *                 elif t == NPY_INT:         f = \"i\"\n *                 elif t == NPY_UINT:        f = \"I\"\n */\n      case NPY_USHORT:\n      __pyx_v_f = __pyx_k_H;\n      break;\n\n      /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":262\n *                 elif t == NPY_SHORT:       f = \"h\"\n *                 elif t == NPY_USHORT:      f = \"H\"\n *                 elif t == NPY_INT:         f = \"i\"             # <<<<<<<<<<<<<<\n *                 elif t == NPY_UINT:        f = \"I\"\n *                 elif t == NPY_LONG:        f = \"l\"\n */\n      case NPY_INT:\n      __pyx_v_f = __pyx_k_i;\n      break;\n\n      /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":263\n *                 elif t == NPY_USHORT:      f = \"H\"\n *                 elif t == NPY_INT:         f = \"i\"\n *                 elif t == NPY_UINT:        f = \"I\"             # <<<<<<<<<<<<<<\n *                 elif t == NPY_LONG:        f = \"l\"\n *                 elif t == NPY_ULONG:       f = \"L\"\n */\n      case NPY_UINT:\n      __pyx_v_f = __pyx_k_I;\n      break;\n\n      /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":264\n *                 elif t == NPY_INT:         f = \"i\"\n *                 elif t == NPY_UINT:        f = \"I\"\n *                 elif t == NPY_LONG:        f = \"l\"             # <<<<<<<<<<<<<<\n *                 elif t == NPY_ULONG:       f = \"L\"\n *                 elif t == NPY_LONGLONG:    f = \"q\"\n */\n      case NPY_LONG:\n      __pyx_v_f = __pyx_k_l;\n      break;\n\n      /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":265\n *                 elif t == NPY_UINT:        f = \"I\"\n *                 elif t == NPY_LONG:        f = \"l\"\n *                 elif t == NPY_ULONG:       f = \"L\"             # <<<<<<<<<<<<<<\n *                 elif t == NPY_LONGLONG:    f = \"q\"\n *                 elif t == NPY_ULONGLONG:   f = \"Q\"\n */\n      case NPY_ULONG:\n      __pyx_v_f = __pyx_k_L;\n      break;\n\n      /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":266\n *                 elif t == NPY_LONG:        f = \"l\"\n *                 elif t == NPY_ULONG:       f = \"L\"\n *                 elif t == NPY_LONGLONG:    f = \"q\"             # <<<<<<<<<<<<<<\n *                 elif t == NPY_ULONGLONG:   f = \"Q\"\n *                 elif t == NPY_FLOAT:       f = \"f\"\n */\n      case NPY_LONGLONG:\n      __pyx_v_f = __pyx_k_q;\n      break;\n\n      /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":267\n *                 elif t == NPY_ULONG:       f = \"L\"\n *                 elif t == NPY_LONGLONG:    f = \"q\"\n *                 elif t == NPY_ULONGLONG:   f = \"Q\"             # <<<<<<<<<<<<<<\n *                 elif t == NPY_FLOAT:       f = \"f\"\n *                 elif t == NPY_DOUBLE:      f = \"d\"\n */\n      case NPY_ULONGLONG:\n      __pyx_v_f = __pyx_k_Q;\n      break;\n\n      /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":268\n *                 elif t == NPY_LONGLONG:    f = \"q\"\n *                 elif t == NPY_ULONGLONG:   f = \"Q\"\n *                 elif t == NPY_FLOAT:       f = \"f\"             # <<<<<<<<<<<<<<\n *                 elif t == NPY_DOUBLE:      f = \"d\"\n *                 elif t == NPY_LONGDOUBLE:  f = \"g\"\n */\n      case NPY_FLOAT:\n      __pyx_v_f = __pyx_k_f;\n      break;\n\n      /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":269\n *                 elif t == NPY_ULONGLONG:   f = \"Q\"\n *                 elif t == NPY_FLOAT:       f = \"f\"\n *                 elif t == NPY_DOUBLE:      f = \"d\"             # <<<<<<<<<<<<<<\n *                 elif t == NPY_LONGDOUBLE:  f = \"g\"\n *                 elif t == NPY_CFLOAT:      f = \"Zf\"\n */\n      case NPY_DOUBLE:\n      __pyx_v_f = __pyx_k_d;\n      break;\n\n      /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":270\n *                 elif t == NPY_FLOAT:       f = \"f\"\n *                 elif t == NPY_DOUBLE:      f = \"d\"\n *                 elif t == NPY_LONGDOUBLE:  f = \"g\"             # <<<<<<<<<<<<<<\n *                 elif t == NPY_CFLOAT:      f = \"Zf\"\n *                 elif t == NPY_CDOUBLE:     f = \"Zd\"\n */\n      case NPY_LONGDOUBLE:\n      __pyx_v_f = __pyx_k_g;\n      break;\n\n      /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":271\n *                 elif t == NPY_DOUBLE:      f = \"d\"\n *                 elif t == NPY_LONGDOUBLE:  f = \"g\"\n *                 elif t == NPY_CFLOAT:      f = \"Zf\"             # <<<<<<<<<<<<<<\n *                 elif t == NPY_CDOUBLE:     f = \"Zd\"\n *                 elif t == NPY_CLONGDOUBLE: f = \"Zg\"\n */\n      case NPY_CFLOAT:\n      __pyx_v_f = __pyx_k_Zf;\n      break;\n\n      /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":272\n *                 elif t == NPY_LONGDOUBLE:  f = \"g\"\n *                 elif t == NPY_CFLOAT:      f = \"Zf\"\n *                 elif t == NPY_CDOUBLE:     f = \"Zd\"             # <<<<<<<<<<<<<<\n *                 elif t == NPY_CLONGDOUBLE: f = \"Zg\"\n *                 elif t == NPY_OBJECT:      f = \"O\"\n */\n      case NPY_CDOUBLE:\n      __pyx_v_f = __pyx_k_Zd;\n      break;\n\n      /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":273\n *                 elif t == NPY_CFLOAT:      f = \"Zf\"\n *                 elif t == NPY_CDOUBLE:     f = \"Zd\"\n *                 elif t == NPY_CLONGDOUBLE: f = \"Zg\"             # <<<<<<<<<<<<<<\n *                 elif t == NPY_OBJECT:      f = \"O\"\n *                 else:\n */\n      case NPY_CLONGDOUBLE:\n      __pyx_v_f = __pyx_k_Zg;\n      break;\n\n      /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":274\n *                 elif t == NPY_CDOUBLE:     f = \"Zd\"\n *                 elif t == NPY_CLONGDOUBLE: f = \"Zg\"\n *                 elif t == NPY_OBJECT:      f = \"O\"             # <<<<<<<<<<<<<<\n *                 else:\n *                     raise ValueError(u\"unknown dtype code in numpy.pxd (%d)\" % t)\n */\n      case NPY_OBJECT:\n      __pyx_v_f = __pyx_k_O;\n      break;\n      default:\n\n      /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":276\n *                 elif t == NPY_OBJECT:      f = \"O\"\n *                 else:\n *                     raise ValueError(u\"unknown dtype code in numpy.pxd (%d)\" % t)             # <<<<<<<<<<<<<<\n *                 info.format = f\n *                 return\n */\n      __pyx_t_4 = __Pyx_PyInt_From_int(__pyx_v_t); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 276; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n      __Pyx_GOTREF(__pyx_t_4);\n      __pyx_t_8 = PyUnicode_Format(__pyx_kp_u_unknown_dtype_code_in_numpy_pxd, __pyx_t_4); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 276; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n      __Pyx_GOTREF(__pyx_t_8);\n      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;\n      __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 276; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n      __Pyx_GOTREF(__pyx_t_4);\n      PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_8);\n      __Pyx_GIVEREF(__pyx_t_8);\n      __pyx_t_8 = 0;\n      __pyx_t_8 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_t_4, NULL); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 276; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n      __Pyx_GOTREF(__pyx_t_8);\n      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;\n      __Pyx_Raise(__pyx_t_8, 0, 0, 0);\n      __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;\n      {__pyx_filename = __pyx_f[1]; __pyx_lineno = 276; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n      break;\n    }\n\n    /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":277\n *                 else:\n *                     raise ValueError(u\"unknown dtype code in numpy.pxd (%d)\" % t)\n *                 info.format = f             # <<<<<<<<<<<<<<\n *                 return\n *             else:\n */\n    __pyx_v_info->format = __pyx_v_f;\n\n    /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":278\n *                     raise ValueError(u\"unknown dtype code in numpy.pxd (%d)\" % t)\n *                 info.format = f\n *                 return             # <<<<<<<<<<<<<<\n *             else:\n *                 info.format = <char*>stdlib.malloc(_buffer_format_string_len)\n */\n    __pyx_r = 0;\n    goto __pyx_L0;\n  }\n  /*else*/ {\n\n    /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":280\n *                 return\n *             else:\n *                 info.format = <char*>stdlib.malloc(_buffer_format_string_len)             # <<<<<<<<<<<<<<\n *                 info.format[0] = c'^' # Native data types, manual alignment\n *                 offset = 0\n */\n    __pyx_v_info->format = ((char *)malloc(255));\n\n    /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":281\n *             else:\n *                 info.format = <char*>stdlib.malloc(_buffer_format_string_len)\n *                 info.format[0] = c'^' # Native data types, manual alignment             # <<<<<<<<<<<<<<\n *                 offset = 0\n *                 f = _util_dtypestring(descr, info.format + 1,\n */\n    (__pyx_v_info->format[0]) = '^';\n\n    /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":282\n *                 info.format = <char*>stdlib.malloc(_buffer_format_string_len)\n *                 info.format[0] = c'^' # Native data types, manual alignment\n *                 offset = 0             # <<<<<<<<<<<<<<\n *                 f = _util_dtypestring(descr, info.format + 1,\n *                                       info.format + _buffer_format_string_len,\n */\n    __pyx_v_offset = 0;\n\n    /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":283\n *                 info.format[0] = c'^' # Native data types, manual alignment\n *                 offset = 0\n *                 f = _util_dtypestring(descr, info.format + 1,             # <<<<<<<<<<<<<<\n *                                       info.format + _buffer_format_string_len,\n *                                       &offset)\n */\n    __pyx_t_9 = __pyx_f_5numpy__util_dtypestring(__pyx_v_descr, (__pyx_v_info->format + 1), (__pyx_v_info->format + 255), (&__pyx_v_offset)); if (unlikely(__pyx_t_9 == NULL)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 283; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n    __pyx_v_f = __pyx_t_9;\n\n    /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":286\n *                                       info.format + _buffer_format_string_len,\n *                                       &offset)\n *                 f[0] = c'\\0' # Terminate format string             # <<<<<<<<<<<<<<\n * \n *         def __releasebuffer__(ndarray self, Py_buffer* info):\n */\n    (__pyx_v_f[0]) = '\\x00';\n  }\n\n  /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":194\n *         # experimental exception made for __getbuffer__ and __releasebuffer__\n *         # -- the details of this may change.\n *         def __getbuffer__(ndarray self, Py_buffer* info, int flags):             # <<<<<<<<<<<<<<\n *             # This implementation of getbuffer is geared towards Cython\n *             # requirements, and does not yet fullfill the PEP.\n */\n\n  /* function exit code */\n  __pyx_r = 0;\n  goto __pyx_L0;\n  __pyx_L1_error:;\n  __Pyx_XDECREF(__pyx_t_4);\n  __Pyx_XDECREF(__pyx_t_8);\n  __Pyx_AddTraceback(\"numpy.ndarray.__getbuffer__\", __pyx_clineno, __pyx_lineno, __pyx_filename);\n  __pyx_r = -1;\n  if (__pyx_v_info != NULL && __pyx_v_info->obj != NULL) {\n    __Pyx_GOTREF(__pyx_v_info->obj);\n    __Pyx_DECREF(__pyx_v_info->obj); __pyx_v_info->obj = NULL;\n  }\n  goto __pyx_L2;\n  __pyx_L0:;\n  if (__pyx_v_info != NULL && __pyx_v_info->obj == Py_None) {\n    __Pyx_GOTREF(Py_None);\n    __Pyx_DECREF(Py_None); __pyx_v_info->obj = NULL;\n  }\n  __pyx_L2:;\n  __Pyx_XDECREF((PyObject *)__pyx_v_descr);\n  __Pyx_RefNannyFinishContext();\n  return __pyx_r;\n}\n\n/* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":288\n *                 f[0] = c'\\0' # Terminate format string\n * \n *         def __releasebuffer__(ndarray self, Py_buffer* info):             # <<<<<<<<<<<<<<\n *             if PyArray_HASFIELDS(self):\n *                 stdlib.free(info.format)\n */\n\n/* Python wrapper */\nstatic CYTHON_UNUSED void __pyx_pw_5numpy_7ndarray_3__releasebuffer__(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info); /*proto*/\nstatic CYTHON_UNUSED void __pyx_pw_5numpy_7ndarray_3__releasebuffer__(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info) {\n  __Pyx_RefNannyDeclarations\n  __Pyx_RefNannySetupContext(\"__releasebuffer__ (wrapper)\", 0);\n  __pyx_pf_5numpy_7ndarray_2__releasebuffer__(((PyArrayObject *)__pyx_v_self), ((Py_buffer *)__pyx_v_info));\n\n  /* function exit code */\n  __Pyx_RefNannyFinishContext();\n}\n\nstatic void __pyx_pf_5numpy_7ndarray_2__releasebuffer__(PyArrayObject *__pyx_v_self, Py_buffer *__pyx_v_info) {\n  __Pyx_RefNannyDeclarations\n  int __pyx_t_1;\n  __Pyx_RefNannySetupContext(\"__releasebuffer__\", 0);\n\n  /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":289\n * \n *         def __releasebuffer__(ndarray self, Py_buffer* info):\n *             if PyArray_HASFIELDS(self):             # <<<<<<<<<<<<<<\n *                 stdlib.free(info.format)\n *             if sizeof(npy_intp) != sizeof(Py_ssize_t):\n */\n  __pyx_t_1 = (PyArray_HASFIELDS(__pyx_v_self) != 0);\n  if (__pyx_t_1) {\n\n    /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":290\n *         def __releasebuffer__(ndarray self, Py_buffer* info):\n *             if PyArray_HASFIELDS(self):\n *                 stdlib.free(info.format)             # <<<<<<<<<<<<<<\n *             if sizeof(npy_intp) != sizeof(Py_ssize_t):\n *                 stdlib.free(info.strides)\n */\n    free(__pyx_v_info->format);\n    goto __pyx_L3;\n  }\n  __pyx_L3:;\n\n  /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":291\n *             if PyArray_HASFIELDS(self):\n *                 stdlib.free(info.format)\n *             if sizeof(npy_intp) != sizeof(Py_ssize_t):             # <<<<<<<<<<<<<<\n *                 stdlib.free(info.strides)\n *                 # info.shape was stored after info.strides in the same block\n */\n  __pyx_t_1 = (((sizeof(npy_intp)) != (sizeof(Py_ssize_t))) != 0);\n  if (__pyx_t_1) {\n\n    /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":292\n *                 stdlib.free(info.format)\n *             if sizeof(npy_intp) != sizeof(Py_ssize_t):\n *                 stdlib.free(info.strides)             # <<<<<<<<<<<<<<\n *                 # info.shape was stored after info.strides in the same block\n * \n */\n    free(__pyx_v_info->strides);\n    goto __pyx_L4;\n  }\n  __pyx_L4:;\n\n  /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":288\n *                 f[0] = c'\\0' # Terminate format string\n * \n *         def __releasebuffer__(ndarray self, Py_buffer* info):             # <<<<<<<<<<<<<<\n *             if PyArray_HASFIELDS(self):\n *                 stdlib.free(info.format)\n */\n\n  /* function exit code */\n  __Pyx_RefNannyFinishContext();\n}\n\n/* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":768\n * ctypedef npy_cdouble     complex_t\n * \n * cdef inline object PyArray_MultiIterNew1(a):             # <<<<<<<<<<<<<<\n *     return PyArray_MultiIterNew(1, <void*>a)\n * \n */\n\nstatic CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew1(PyObject *__pyx_v_a) {\n  PyObject *__pyx_r = NULL;\n  __Pyx_RefNannyDeclarations\n  PyObject *__pyx_t_1 = NULL;\n  int __pyx_lineno = 0;\n  const char *__pyx_filename = NULL;\n  int __pyx_clineno = 0;\n  __Pyx_RefNannySetupContext(\"PyArray_MultiIterNew1\", 0);\n\n  /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":769\n * \n * cdef inline object PyArray_MultiIterNew1(a):\n *     return PyArray_MultiIterNew(1, <void*>a)             # <<<<<<<<<<<<<<\n * \n * cdef inline object PyArray_MultiIterNew2(a, b):\n */\n  __Pyx_XDECREF(__pyx_r);\n  __pyx_t_1 = PyArray_MultiIterNew(1, ((void *)__pyx_v_a)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 769; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n  __Pyx_GOTREF(__pyx_t_1);\n  __pyx_r = __pyx_t_1;\n  __pyx_t_1 = 0;\n  goto __pyx_L0;\n\n  /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":768\n * ctypedef npy_cdouble     complex_t\n * \n * cdef inline object PyArray_MultiIterNew1(a):             # <<<<<<<<<<<<<<\n *     return PyArray_MultiIterNew(1, <void*>a)\n * \n */\n\n  /* function exit code */\n  __pyx_L1_error:;\n  __Pyx_XDECREF(__pyx_t_1);\n  __Pyx_AddTraceback(\"numpy.PyArray_MultiIterNew1\", __pyx_clineno, __pyx_lineno, __pyx_filename);\n  __pyx_r = 0;\n  __pyx_L0:;\n  __Pyx_XGIVEREF(__pyx_r);\n  __Pyx_RefNannyFinishContext();\n  return __pyx_r;\n}\n\n/* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":771\n *     return PyArray_MultiIterNew(1, <void*>a)\n * \n * cdef inline object PyArray_MultiIterNew2(a, b):             # <<<<<<<<<<<<<<\n *     return PyArray_MultiIterNew(2, <void*>a, <void*>b)\n * \n */\n\nstatic CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew2(PyObject *__pyx_v_a, PyObject *__pyx_v_b) {\n  PyObject *__pyx_r = NULL;\n  __Pyx_RefNannyDeclarations\n  PyObject *__pyx_t_1 = NULL;\n  int __pyx_lineno = 0;\n  const char *__pyx_filename = NULL;\n  int __pyx_clineno = 0;\n  __Pyx_RefNannySetupContext(\"PyArray_MultiIterNew2\", 0);\n\n  /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":772\n * \n * cdef inline object PyArray_MultiIterNew2(a, b):\n *     return PyArray_MultiIterNew(2, <void*>a, <void*>b)             # <<<<<<<<<<<<<<\n * \n * cdef inline object PyArray_MultiIterNew3(a, b, c):\n */\n  __Pyx_XDECREF(__pyx_r);\n  __pyx_t_1 = PyArray_MultiIterNew(2, ((void *)__pyx_v_a), ((void *)__pyx_v_b)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 772; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n  __Pyx_GOTREF(__pyx_t_1);\n  __pyx_r = __pyx_t_1;\n  __pyx_t_1 = 0;\n  goto __pyx_L0;\n\n  /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":771\n *     return PyArray_MultiIterNew(1, <void*>a)\n * \n * cdef inline object PyArray_MultiIterNew2(a, b):             # <<<<<<<<<<<<<<\n *     return PyArray_MultiIterNew(2, <void*>a, <void*>b)\n * \n */\n\n  /* function exit code */\n  __pyx_L1_error:;\n  __Pyx_XDECREF(__pyx_t_1);\n  __Pyx_AddTraceback(\"numpy.PyArray_MultiIterNew2\", __pyx_clineno, __pyx_lineno, __pyx_filename);\n  __pyx_r = 0;\n  __pyx_L0:;\n  __Pyx_XGIVEREF(__pyx_r);\n  __Pyx_RefNannyFinishContext();\n  return __pyx_r;\n}\n\n/* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":774\n *     return PyArray_MultiIterNew(2, <void*>a, <void*>b)\n * \n * cdef inline object PyArray_MultiIterNew3(a, b, c):             # <<<<<<<<<<<<<<\n *     return PyArray_MultiIterNew(3, <void*>a, <void*>b, <void*> c)\n * \n */\n\nstatic CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew3(PyObject *__pyx_v_a, PyObject *__pyx_v_b, PyObject *__pyx_v_c) {\n  PyObject *__pyx_r = NULL;\n  __Pyx_RefNannyDeclarations\n  PyObject *__pyx_t_1 = NULL;\n  int __pyx_lineno = 0;\n  const char *__pyx_filename = NULL;\n  int __pyx_clineno = 0;\n  __Pyx_RefNannySetupContext(\"PyArray_MultiIterNew3\", 0);\n\n  /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":775\n * \n * cdef inline object PyArray_MultiIterNew3(a, b, c):\n *     return PyArray_MultiIterNew(3, <void*>a, <void*>b, <void*> c)             # <<<<<<<<<<<<<<\n * \n * cdef inline object PyArray_MultiIterNew4(a, b, c, d):\n */\n  __Pyx_XDECREF(__pyx_r);\n  __pyx_t_1 = PyArray_MultiIterNew(3, ((void *)__pyx_v_a), ((void *)__pyx_v_b), ((void *)__pyx_v_c)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 775; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n  __Pyx_GOTREF(__pyx_t_1);\n  __pyx_r = __pyx_t_1;\n  __pyx_t_1 = 0;\n  goto __pyx_L0;\n\n  /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":774\n *     return PyArray_MultiIterNew(2, <void*>a, <void*>b)\n * \n * cdef inline object PyArray_MultiIterNew3(a, b, c):             # <<<<<<<<<<<<<<\n *     return PyArray_MultiIterNew(3, <void*>a, <void*>b, <void*> c)\n * \n */\n\n  /* function exit code */\n  __pyx_L1_error:;\n  __Pyx_XDECREF(__pyx_t_1);\n  __Pyx_AddTraceback(\"numpy.PyArray_MultiIterNew3\", __pyx_clineno, __pyx_lineno, __pyx_filename);\n  __pyx_r = 0;\n  __pyx_L0:;\n  __Pyx_XGIVEREF(__pyx_r);\n  __Pyx_RefNannyFinishContext();\n  return __pyx_r;\n}\n\n/* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":777\n *     return PyArray_MultiIterNew(3, <void*>a, <void*>b, <void*> c)\n * \n * cdef inline object PyArray_MultiIterNew4(a, b, c, d):             # <<<<<<<<<<<<<<\n *     return PyArray_MultiIterNew(4, <void*>a, <void*>b, <void*>c, <void*> d)\n * \n */\n\nstatic CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew4(PyObject *__pyx_v_a, PyObject *__pyx_v_b, PyObject *__pyx_v_c, PyObject *__pyx_v_d) {\n  PyObject *__pyx_r = NULL;\n  __Pyx_RefNannyDeclarations\n  PyObject *__pyx_t_1 = NULL;\n  int __pyx_lineno = 0;\n  const char *__pyx_filename = NULL;\n  int __pyx_clineno = 0;\n  __Pyx_RefNannySetupContext(\"PyArray_MultiIterNew4\", 0);\n\n  /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":778\n * \n * cdef inline object PyArray_MultiIterNew4(a, b, c, d):\n *     return PyArray_MultiIterNew(4, <void*>a, <void*>b, <void*>c, <void*> d)             # <<<<<<<<<<<<<<\n * \n * cdef inline object PyArray_MultiIterNew5(a, b, c, d, e):\n */\n  __Pyx_XDECREF(__pyx_r);\n  __pyx_t_1 = PyArray_MultiIterNew(4, ((void *)__pyx_v_a), ((void *)__pyx_v_b), ((void *)__pyx_v_c), ((void *)__pyx_v_d)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 778; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n  __Pyx_GOTREF(__pyx_t_1);\n  __pyx_r = __pyx_t_1;\n  __pyx_t_1 = 0;\n  goto __pyx_L0;\n\n  /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":777\n *     return PyArray_MultiIterNew(3, <void*>a, <void*>b, <void*> c)\n * \n * cdef inline object PyArray_MultiIterNew4(a, b, c, d):             # <<<<<<<<<<<<<<\n *     return PyArray_MultiIterNew(4, <void*>a, <void*>b, <void*>c, <void*> d)\n * \n */\n\n  /* function exit code */\n  __pyx_L1_error:;\n  __Pyx_XDECREF(__pyx_t_1);\n  __Pyx_AddTraceback(\"numpy.PyArray_MultiIterNew4\", __pyx_clineno, __pyx_lineno, __pyx_filename);\n  __pyx_r = 0;\n  __pyx_L0:;\n  __Pyx_XGIVEREF(__pyx_r);\n  __Pyx_RefNannyFinishContext();\n  return __pyx_r;\n}\n\n/* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":780\n *     return PyArray_MultiIterNew(4, <void*>a, <void*>b, <void*>c, <void*> d)\n * \n * cdef inline object PyArray_MultiIterNew5(a, b, c, d, e):             # <<<<<<<<<<<<<<\n *     return PyArray_MultiIterNew(5, <void*>a, <void*>b, <void*>c, <void*> d, <void*> e)\n * \n */\n\nstatic CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew5(PyObject *__pyx_v_a, PyObject *__pyx_v_b, PyObject *__pyx_v_c, PyObject *__pyx_v_d, PyObject *__pyx_v_e) {\n  PyObject *__pyx_r = NULL;\n  __Pyx_RefNannyDeclarations\n  PyObject *__pyx_t_1 = NULL;\n  int __pyx_lineno = 0;\n  const char *__pyx_filename = NULL;\n  int __pyx_clineno = 0;\n  __Pyx_RefNannySetupContext(\"PyArray_MultiIterNew5\", 0);\n\n  /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":781\n * \n * cdef inline object PyArray_MultiIterNew5(a, b, c, d, e):\n *     return PyArray_MultiIterNew(5, <void*>a, <void*>b, <void*>c, <void*> d, <void*> e)             # <<<<<<<<<<<<<<\n * \n * cdef inline char* _util_dtypestring(dtype descr, char* f, char* end, int* offset) except NULL:\n */\n  __Pyx_XDECREF(__pyx_r);\n  __pyx_t_1 = PyArray_MultiIterNew(5, ((void *)__pyx_v_a), ((void *)__pyx_v_b), ((void *)__pyx_v_c), ((void *)__pyx_v_d), ((void *)__pyx_v_e)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 781; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n  __Pyx_GOTREF(__pyx_t_1);\n  __pyx_r = __pyx_t_1;\n  __pyx_t_1 = 0;\n  goto __pyx_L0;\n\n  /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":780\n *     return PyArray_MultiIterNew(4, <void*>a, <void*>b, <void*>c, <void*> d)\n * \n * cdef inline object PyArray_MultiIterNew5(a, b, c, d, e):             # <<<<<<<<<<<<<<\n *     return PyArray_MultiIterNew(5, <void*>a, <void*>b, <void*>c, <void*> d, <void*> e)\n * \n */\n\n  /* function exit code */\n  __pyx_L1_error:;\n  __Pyx_XDECREF(__pyx_t_1);\n  __Pyx_AddTraceback(\"numpy.PyArray_MultiIterNew5\", __pyx_clineno, __pyx_lineno, __pyx_filename);\n  __pyx_r = 0;\n  __pyx_L0:;\n  __Pyx_XGIVEREF(__pyx_r);\n  __Pyx_RefNannyFinishContext();\n  return __pyx_r;\n}\n\n/* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":783\n *     return PyArray_MultiIterNew(5, <void*>a, <void*>b, <void*>c, <void*> d, <void*> e)\n * \n * cdef inline char* _util_dtypestring(dtype descr, char* f, char* end, int* offset) except NULL:             # <<<<<<<<<<<<<<\n *     # Recursive utility function used in __getbuffer__ to get format\n *     # string. The new location in the format string is returned.\n */\n\nstatic CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx_v_descr, char *__pyx_v_f, char *__pyx_v_end, int *__pyx_v_offset) {\n  PyArray_Descr *__pyx_v_child = 0;\n  int __pyx_v_endian_detector;\n  int __pyx_v_little_endian;\n  PyObject *__pyx_v_fields = 0;\n  PyObject *__pyx_v_childname = NULL;\n  PyObject *__pyx_v_new_offset = NULL;\n  PyObject *__pyx_v_t = NULL;\n  char *__pyx_r;\n  __Pyx_RefNannyDeclarations\n  PyObject *__pyx_t_1 = NULL;\n  Py_ssize_t __pyx_t_2;\n  PyObject *__pyx_t_3 = NULL;\n  PyObject *__pyx_t_4 = NULL;\n  int __pyx_t_5;\n  int __pyx_t_6;\n  int __pyx_t_7;\n  int __pyx_t_8;\n  int __pyx_t_9;\n  long __pyx_t_10;\n  char *__pyx_t_11;\n  int __pyx_lineno = 0;\n  const char *__pyx_filename = NULL;\n  int __pyx_clineno = 0;\n  __Pyx_RefNannySetupContext(\"_util_dtypestring\", 0);\n\n  /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":790\n *     cdef int delta_offset\n *     cdef tuple i\n *     cdef int endian_detector = 1             # <<<<<<<<<<<<<<\n *     cdef bint little_endian = ((<char*>&endian_detector)[0] != 0)\n *     cdef tuple fields\n */\n  __pyx_v_endian_detector = 1;\n\n  /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":791\n *     cdef tuple i\n *     cdef int endian_detector = 1\n *     cdef bint little_endian = ((<char*>&endian_detector)[0] != 0)             # <<<<<<<<<<<<<<\n *     cdef tuple fields\n * \n */\n  __pyx_v_little_endian = ((((char *)(&__pyx_v_endian_detector))[0]) != 0);\n\n  /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":794\n *     cdef tuple fields\n * \n *     for childname in descr.names:             # <<<<<<<<<<<<<<\n *         fields = descr.fields[childname]\n *         child, new_offset = fields\n */\n  if (unlikely(__pyx_v_descr->names == Py_None)) {\n    PyErr_SetString(PyExc_TypeError, \"'NoneType' object is not iterable\");\n    {__pyx_filename = __pyx_f[1]; __pyx_lineno = 794; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n  }\n  __pyx_t_1 = __pyx_v_descr->names; __Pyx_INCREF(__pyx_t_1); __pyx_t_2 = 0;\n  for (;;) {\n    if (__pyx_t_2 >= PyTuple_GET_SIZE(__pyx_t_1)) break;\n    #if CYTHON_COMPILING_IN_CPYTHON\n    __pyx_t_3 = PyTuple_GET_ITEM(__pyx_t_1, __pyx_t_2); __Pyx_INCREF(__pyx_t_3); __pyx_t_2++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 794; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n    #else\n    __pyx_t_3 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 794; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n    #endif\n    __Pyx_XDECREF_SET(__pyx_v_childname, __pyx_t_3);\n    __pyx_t_3 = 0;\n\n    /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":795\n * \n *     for childname in descr.names:\n *         fields = descr.fields[childname]             # <<<<<<<<<<<<<<\n *         child, new_offset = fields\n * \n */\n    __pyx_t_3 = PyObject_GetItem(__pyx_v_descr->fields, __pyx_v_childname); if (unlikely(__pyx_t_3 == NULL)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 795; __pyx_clineno = __LINE__; goto __pyx_L1_error;};\n    __Pyx_GOTREF(__pyx_t_3);\n    if (!(likely(PyTuple_CheckExact(__pyx_t_3))||((__pyx_t_3) == Py_None)||(PyErr_Format(PyExc_TypeError, \"Expected %.16s, got %.200s\", \"tuple\", Py_TYPE(__pyx_t_3)->tp_name), 0))) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 795; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n    __Pyx_XDECREF_SET(__pyx_v_fields, ((PyObject*)__pyx_t_3));\n    __pyx_t_3 = 0;\n\n    /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":796\n *     for childname in descr.names:\n *         fields = descr.fields[childname]\n *         child, new_offset = fields             # <<<<<<<<<<<<<<\n * \n *         if (end - f) - <int>(new_offset - offset[0]) < 15:\n */\n    if (likely(__pyx_v_fields != Py_None)) {\n      PyObject* sequence = __pyx_v_fields;\n      #if CYTHON_COMPILING_IN_CPYTHON\n      Py_ssize_t size = Py_SIZE(sequence);\n      #else\n      Py_ssize_t size = PySequence_Size(sequence);\n      #endif\n      if (unlikely(size != 2)) {\n        if (size > 2) __Pyx_RaiseTooManyValuesError(2);\n        else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size);\n        {__pyx_filename = __pyx_f[1]; __pyx_lineno = 796; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n      }\n      #if CYTHON_COMPILING_IN_CPYTHON\n      __pyx_t_3 = PyTuple_GET_ITEM(sequence, 0); \n      __pyx_t_4 = PyTuple_GET_ITEM(sequence, 1); \n      __Pyx_INCREF(__pyx_t_3);\n      __Pyx_INCREF(__pyx_t_4);\n      #else\n      __pyx_t_3 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 796; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n      __Pyx_GOTREF(__pyx_t_3);\n      __pyx_t_4 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 796; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n      __Pyx_GOTREF(__pyx_t_4);\n      #endif\n    } else {\n      __Pyx_RaiseNoneNotIterableError(); {__pyx_filename = __pyx_f[1]; __pyx_lineno = 796; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n    }\n    if (!(likely(((__pyx_t_3) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_3, __pyx_ptype_5numpy_dtype))))) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 796; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n    __Pyx_XDECREF_SET(__pyx_v_child, ((PyArray_Descr *)__pyx_t_3));\n    __pyx_t_3 = 0;\n    __Pyx_XDECREF_SET(__pyx_v_new_offset, __pyx_t_4);\n    __pyx_t_4 = 0;\n\n    /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":798\n *         child, new_offset = fields\n * \n *         if (end - f) - <int>(new_offset - offset[0]) < 15:             # <<<<<<<<<<<<<<\n *             raise RuntimeError(u\"Format string allocated too short, see comment in numpy.pxd\")\n * \n */\n    __pyx_t_4 = __Pyx_PyInt_From_int((__pyx_v_offset[0])); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 798; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n    __Pyx_GOTREF(__pyx_t_4);\n    __pyx_t_3 = PyNumber_Subtract(__pyx_v_new_offset, __pyx_t_4); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 798; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n    __Pyx_GOTREF(__pyx_t_3);\n    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;\n    __pyx_t_5 = __Pyx_PyInt_As_int(__pyx_t_3); if (unlikely((__pyx_t_5 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 798; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;\n    __pyx_t_6 = ((((__pyx_v_end - __pyx_v_f) - ((int)__pyx_t_5)) < 15) != 0);\n    if (__pyx_t_6) {\n\n      /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":799\n * \n *         if (end - f) - <int>(new_offset - offset[0]) < 15:\n *             raise RuntimeError(u\"Format string allocated too short, see comment in numpy.pxd\")             # <<<<<<<<<<<<<<\n * \n *         if ((child.byteorder == c'>' and little_endian) or\n */\n      __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_RuntimeError, __pyx_tuple__15, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 799; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n      __Pyx_GOTREF(__pyx_t_3);\n      __Pyx_Raise(__pyx_t_3, 0, 0, 0);\n      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;\n      {__pyx_filename = __pyx_f[1]; __pyx_lineno = 799; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n    }\n\n    /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":801\n *             raise RuntimeError(u\"Format string allocated too short, see comment in numpy.pxd\")\n * \n *         if ((child.byteorder == c'>' and little_endian) or             # <<<<<<<<<<<<<<\n *             (child.byteorder == c'<' and not little_endian)):\n *             raise ValueError(u\"Non-native byte order not supported\")\n */\n    __pyx_t_6 = ((__pyx_v_child->byteorder == '>') != 0);\n    if (__pyx_t_6) {\n      __pyx_t_7 = (__pyx_v_little_endian != 0);\n    } else {\n      __pyx_t_7 = __pyx_t_6;\n    }\n    if (!__pyx_t_7) {\n\n      /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":802\n * \n *         if ((child.byteorder == c'>' and little_endian) or\n *             (child.byteorder == c'<' and not little_endian)):             # <<<<<<<<<<<<<<\n *             raise ValueError(u\"Non-native byte order not supported\")\n *             # One could encode it in the format string and have Cython\n */\n      __pyx_t_6 = ((__pyx_v_child->byteorder == '<') != 0);\n      if (__pyx_t_6) {\n        __pyx_t_8 = ((!(__pyx_v_little_endian != 0)) != 0);\n        __pyx_t_9 = __pyx_t_8;\n      } else {\n        __pyx_t_9 = __pyx_t_6;\n      }\n      __pyx_t_6 = __pyx_t_9;\n    } else {\n      __pyx_t_6 = __pyx_t_7;\n    }\n    if (__pyx_t_6) {\n\n      /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":803\n *         if ((child.byteorder == c'>' and little_endian) or\n *             (child.byteorder == c'<' and not little_endian)):\n *             raise ValueError(u\"Non-native byte order not supported\")             # <<<<<<<<<<<<<<\n *             # One could encode it in the format string and have Cython\n *             # complain instead, BUT: < and > in format strings also imply\n */\n      __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__16, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 803; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n      __Pyx_GOTREF(__pyx_t_3);\n      __Pyx_Raise(__pyx_t_3, 0, 0, 0);\n      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;\n      {__pyx_filename = __pyx_f[1]; __pyx_lineno = 803; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n    }\n\n    /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":813\n * \n *         # Output padding bytes\n *         while offset[0] < new_offset:             # <<<<<<<<<<<<<<\n *             f[0] = 120 # \"x\"; pad byte\n *             f += 1\n */\n    while (1) {\n      __pyx_t_3 = __Pyx_PyInt_From_int((__pyx_v_offset[0])); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 813; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n      __Pyx_GOTREF(__pyx_t_3);\n      __pyx_t_4 = PyObject_RichCompare(__pyx_t_3, __pyx_v_new_offset, Py_LT); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 813; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;\n      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 813; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;\n      if (!__pyx_t_6) break;\n\n      /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":814\n *         # Output padding bytes\n *         while offset[0] < new_offset:\n *             f[0] = 120 # \"x\"; pad byte             # <<<<<<<<<<<<<<\n *             f += 1\n *             offset[0] += 1\n */\n      (__pyx_v_f[0]) = 120;\n\n      /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":815\n *         while offset[0] < new_offset:\n *             f[0] = 120 # \"x\"; pad byte\n *             f += 1             # <<<<<<<<<<<<<<\n *             offset[0] += 1\n * \n */\n      __pyx_v_f = (__pyx_v_f + 1);\n\n      /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":816\n *             f[0] = 120 # \"x\"; pad byte\n *             f += 1\n *             offset[0] += 1             # <<<<<<<<<<<<<<\n * \n *         offset[0] += child.itemsize\n */\n      __pyx_t_10 = 0;\n      (__pyx_v_offset[__pyx_t_10]) = ((__pyx_v_offset[__pyx_t_10]) + 1);\n    }\n\n    /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":818\n *             offset[0] += 1\n * \n *         offset[0] += child.itemsize             # <<<<<<<<<<<<<<\n * \n *         if not PyDataType_HASFIELDS(child):\n */\n    __pyx_t_10 = 0;\n    (__pyx_v_offset[__pyx_t_10]) = ((__pyx_v_offset[__pyx_t_10]) + __pyx_v_child->elsize);\n\n    /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":820\n *         offset[0] += child.itemsize\n * \n *         if not PyDataType_HASFIELDS(child):             # <<<<<<<<<<<<<<\n *             t = child.type_num\n *             if end - f < 5:\n */\n    __pyx_t_6 = ((!(PyDataType_HASFIELDS(__pyx_v_child) != 0)) != 0);\n    if (__pyx_t_6) {\n\n      /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":821\n * \n *         if not PyDataType_HASFIELDS(child):\n *             t = child.type_num             # <<<<<<<<<<<<<<\n *             if end - f < 5:\n *                 raise RuntimeError(u\"Format string allocated too short.\")\n */\n      __pyx_t_4 = __Pyx_PyInt_From_int(__pyx_v_child->type_num); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 821; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n      __Pyx_GOTREF(__pyx_t_4);\n      __Pyx_XDECREF_SET(__pyx_v_t, __pyx_t_4);\n      __pyx_t_4 = 0;\n\n      /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":822\n *         if not PyDataType_HASFIELDS(child):\n *             t = child.type_num\n *             if end - f < 5:             # <<<<<<<<<<<<<<\n *                 raise RuntimeError(u\"Format string allocated too short.\")\n * \n */\n      __pyx_t_6 = (((__pyx_v_end - __pyx_v_f) < 5) != 0);\n      if (__pyx_t_6) {\n\n        /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":823\n *             t = child.type_num\n *             if end - f < 5:\n *                 raise RuntimeError(u\"Format string allocated too short.\")             # <<<<<<<<<<<<<<\n * \n *             # Until ticket #99 is fixed, use integers to avoid warnings\n */\n        __pyx_t_4 = __Pyx_PyObject_Call(__pyx_builtin_RuntimeError, __pyx_tuple__17, NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 823; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n        __Pyx_GOTREF(__pyx_t_4);\n        __Pyx_Raise(__pyx_t_4, 0, 0, 0);\n        __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;\n        {__pyx_filename = __pyx_f[1]; __pyx_lineno = 823; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n      }\n\n      /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":826\n * \n *             # Until ticket #99 is fixed, use integers to avoid warnings\n *             if   t == NPY_BYTE:        f[0] =  98 #\"b\"             # <<<<<<<<<<<<<<\n *             elif t == NPY_UBYTE:       f[0] =  66 #\"B\"\n *             elif t == NPY_SHORT:       f[0] = 104 #\"h\"\n */\n      __pyx_t_4 = PyInt_FromLong(NPY_BYTE); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 826; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n      __Pyx_GOTREF(__pyx_t_4);\n      __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 826; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;\n      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 826; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;\n      if (__pyx_t_6) {\n        (__pyx_v_f[0]) = 98;\n        goto __pyx_L11;\n      }\n\n      /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":827\n *             # Until ticket #99 is fixed, use integers to avoid warnings\n *             if   t == NPY_BYTE:        f[0] =  98 #\"b\"\n *             elif t == NPY_UBYTE:       f[0] =  66 #\"B\"             # <<<<<<<<<<<<<<\n *             elif t == NPY_SHORT:       f[0] = 104 #\"h\"\n *             elif t == NPY_USHORT:      f[0] =  72 #\"H\"\n */\n      __pyx_t_3 = PyInt_FromLong(NPY_UBYTE); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 827; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n      __Pyx_GOTREF(__pyx_t_3);\n      __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 827; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;\n      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 827; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;\n      if (__pyx_t_6) {\n        (__pyx_v_f[0]) = 66;\n        goto __pyx_L11;\n      }\n\n      /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":828\n *             if   t == NPY_BYTE:        f[0] =  98 #\"b\"\n *             elif t == NPY_UBYTE:       f[0] =  66 #\"B\"\n *             elif t == NPY_SHORT:       f[0] = 104 #\"h\"             # <<<<<<<<<<<<<<\n *             elif t == NPY_USHORT:      f[0] =  72 #\"H\"\n *             elif t == NPY_INT:         f[0] = 105 #\"i\"\n */\n      __pyx_t_4 = PyInt_FromLong(NPY_SHORT); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 828; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n      __Pyx_GOTREF(__pyx_t_4);\n      __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 828; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;\n      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 828; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;\n      if (__pyx_t_6) {\n        (__pyx_v_f[0]) = 104;\n        goto __pyx_L11;\n      }\n\n      /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":829\n *             elif t == NPY_UBYTE:       f[0] =  66 #\"B\"\n *             elif t == NPY_SHORT:       f[0] = 104 #\"h\"\n *             elif t == NPY_USHORT:      f[0] =  72 #\"H\"             # <<<<<<<<<<<<<<\n *             elif t == NPY_INT:         f[0] = 105 #\"i\"\n *             elif t == NPY_UINT:        f[0] =  73 #\"I\"\n */\n      __pyx_t_3 = PyInt_FromLong(NPY_USHORT); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 829; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n      __Pyx_GOTREF(__pyx_t_3);\n      __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 829; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;\n      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 829; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;\n      if (__pyx_t_6) {\n        (__pyx_v_f[0]) = 72;\n        goto __pyx_L11;\n      }\n\n      /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":830\n *             elif t == NPY_SHORT:       f[0] = 104 #\"h\"\n *             elif t == NPY_USHORT:      f[0] =  72 #\"H\"\n *             elif t == NPY_INT:         f[0] = 105 #\"i\"             # <<<<<<<<<<<<<<\n *             elif t == NPY_UINT:        f[0] =  73 #\"I\"\n *             elif t == NPY_LONG:        f[0] = 108 #\"l\"\n */\n      __pyx_t_4 = PyInt_FromLong(NPY_INT); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 830; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n      __Pyx_GOTREF(__pyx_t_4);\n      __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 830; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;\n      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 830; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;\n      if (__pyx_t_6) {\n        (__pyx_v_f[0]) = 105;\n        goto __pyx_L11;\n      }\n\n      /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":831\n *             elif t == NPY_USHORT:      f[0] =  72 #\"H\"\n *             elif t == NPY_INT:         f[0] = 105 #\"i\"\n *             elif t == NPY_UINT:        f[0] =  73 #\"I\"             # <<<<<<<<<<<<<<\n *             elif t == NPY_LONG:        f[0] = 108 #\"l\"\n *             elif t == NPY_ULONG:       f[0] = 76  #\"L\"\n */\n      __pyx_t_3 = PyInt_FromLong(NPY_UINT); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 831; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n      __Pyx_GOTREF(__pyx_t_3);\n      __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 831; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;\n      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 831; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;\n      if (__pyx_t_6) {\n        (__pyx_v_f[0]) = 73;\n        goto __pyx_L11;\n      }\n\n      /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":832\n *             elif t == NPY_INT:         f[0] = 105 #\"i\"\n *             elif t == NPY_UINT:        f[0] =  73 #\"I\"\n *             elif t == NPY_LONG:        f[0] = 108 #\"l\"             # <<<<<<<<<<<<<<\n *             elif t == NPY_ULONG:       f[0] = 76  #\"L\"\n *             elif t == NPY_LONGLONG:    f[0] = 113 #\"q\"\n */\n      __pyx_t_4 = PyInt_FromLong(NPY_LONG); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 832; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n      __Pyx_GOTREF(__pyx_t_4);\n      __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 832; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;\n      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 832; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;\n      if (__pyx_t_6) {\n        (__pyx_v_f[0]) = 108;\n        goto __pyx_L11;\n      }\n\n      /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":833\n *             elif t == NPY_UINT:        f[0] =  73 #\"I\"\n *             elif t == NPY_LONG:        f[0] = 108 #\"l\"\n *             elif t == NPY_ULONG:       f[0] = 76  #\"L\"             # <<<<<<<<<<<<<<\n *             elif t == NPY_LONGLONG:    f[0] = 113 #\"q\"\n *             elif t == NPY_ULONGLONG:   f[0] = 81  #\"Q\"\n */\n      __pyx_t_3 = PyInt_FromLong(NPY_ULONG); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 833; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n      __Pyx_GOTREF(__pyx_t_3);\n      __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 833; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;\n      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 833; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;\n      if (__pyx_t_6) {\n        (__pyx_v_f[0]) = 76;\n        goto __pyx_L11;\n      }\n\n      /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":834\n *             elif t == NPY_LONG:        f[0] = 108 #\"l\"\n *             elif t == NPY_ULONG:       f[0] = 76  #\"L\"\n *             elif t == NPY_LONGLONG:    f[0] = 113 #\"q\"             # <<<<<<<<<<<<<<\n *             elif t == NPY_ULONGLONG:   f[0] = 81  #\"Q\"\n *             elif t == NPY_FLOAT:       f[0] = 102 #\"f\"\n */\n      __pyx_t_4 = PyInt_FromLong(NPY_LONGLONG); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 834; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n      __Pyx_GOTREF(__pyx_t_4);\n      __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 834; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;\n      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 834; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;\n      if (__pyx_t_6) {\n        (__pyx_v_f[0]) = 113;\n        goto __pyx_L11;\n      }\n\n      /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":835\n *             elif t == NPY_ULONG:       f[0] = 76  #\"L\"\n *             elif t == NPY_LONGLONG:    f[0] = 113 #\"q\"\n *             elif t == NPY_ULONGLONG:   f[0] = 81  #\"Q\"             # <<<<<<<<<<<<<<\n *             elif t == NPY_FLOAT:       f[0] = 102 #\"f\"\n *             elif t == NPY_DOUBLE:      f[0] = 100 #\"d\"\n */\n      __pyx_t_3 = PyInt_FromLong(NPY_ULONGLONG); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 835; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n      __Pyx_GOTREF(__pyx_t_3);\n      __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 835; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;\n      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 835; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;\n      if (__pyx_t_6) {\n        (__pyx_v_f[0]) = 81;\n        goto __pyx_L11;\n      }\n\n      /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":836\n *             elif t == NPY_LONGLONG:    f[0] = 113 #\"q\"\n *             elif t == NPY_ULONGLONG:   f[0] = 81  #\"Q\"\n *             elif t == NPY_FLOAT:       f[0] = 102 #\"f\"             # <<<<<<<<<<<<<<\n *             elif t == NPY_DOUBLE:      f[0] = 100 #\"d\"\n *             elif t == NPY_LONGDOUBLE:  f[0] = 103 #\"g\"\n */\n      __pyx_t_4 = PyInt_FromLong(NPY_FLOAT); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 836; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n      __Pyx_GOTREF(__pyx_t_4);\n      __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 836; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;\n      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 836; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;\n      if (__pyx_t_6) {\n        (__pyx_v_f[0]) = 102;\n        goto __pyx_L11;\n      }\n\n      /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":837\n *             elif t == NPY_ULONGLONG:   f[0] = 81  #\"Q\"\n *             elif t == NPY_FLOAT:       f[0] = 102 #\"f\"\n *             elif t == NPY_DOUBLE:      f[0] = 100 #\"d\"             # <<<<<<<<<<<<<<\n *             elif t == NPY_LONGDOUBLE:  f[0] = 103 #\"g\"\n *             elif t == NPY_CFLOAT:      f[0] = 90; f[1] = 102; f += 1 # Zf\n */\n      __pyx_t_3 = PyInt_FromLong(NPY_DOUBLE); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 837; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n      __Pyx_GOTREF(__pyx_t_3);\n      __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 837; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;\n      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 837; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;\n      if (__pyx_t_6) {\n        (__pyx_v_f[0]) = 100;\n        goto __pyx_L11;\n      }\n\n      /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":838\n *             elif t == NPY_FLOAT:       f[0] = 102 #\"f\"\n *             elif t == NPY_DOUBLE:      f[0] = 100 #\"d\"\n *             elif t == NPY_LONGDOUBLE:  f[0] = 103 #\"g\"             # <<<<<<<<<<<<<<\n *             elif t == NPY_CFLOAT:      f[0] = 90; f[1] = 102; f += 1 # Zf\n *             elif t == NPY_CDOUBLE:     f[0] = 90; f[1] = 100; f += 1 # Zd\n */\n      __pyx_t_4 = PyInt_FromLong(NPY_LONGDOUBLE); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 838; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n      __Pyx_GOTREF(__pyx_t_4);\n      __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 838; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;\n      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 838; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;\n      if (__pyx_t_6) {\n        (__pyx_v_f[0]) = 103;\n        goto __pyx_L11;\n      }\n\n      /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":839\n *             elif t == NPY_DOUBLE:      f[0] = 100 #\"d\"\n *             elif t == NPY_LONGDOUBLE:  f[0] = 103 #\"g\"\n *             elif t == NPY_CFLOAT:      f[0] = 90; f[1] = 102; f += 1 # Zf             # <<<<<<<<<<<<<<\n *             elif t == NPY_CDOUBLE:     f[0] = 90; f[1] = 100; f += 1 # Zd\n *             elif t == NPY_CLONGDOUBLE: f[0] = 90; f[1] = 103; f += 1 # Zg\n */\n      __pyx_t_3 = PyInt_FromLong(NPY_CFLOAT); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 839; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n      __Pyx_GOTREF(__pyx_t_3);\n      __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 839; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;\n      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 839; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;\n      if (__pyx_t_6) {\n        (__pyx_v_f[0]) = 90;\n        (__pyx_v_f[1]) = 102;\n        __pyx_v_f = (__pyx_v_f + 1);\n        goto __pyx_L11;\n      }\n\n      /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":840\n *             elif t == NPY_LONGDOUBLE:  f[0] = 103 #\"g\"\n *             elif t == NPY_CFLOAT:      f[0] = 90; f[1] = 102; f += 1 # Zf\n *             elif t == NPY_CDOUBLE:     f[0] = 90; f[1] = 100; f += 1 # Zd             # <<<<<<<<<<<<<<\n *             elif t == NPY_CLONGDOUBLE: f[0] = 90; f[1] = 103; f += 1 # Zg\n *             elif t == NPY_OBJECT:      f[0] = 79 #\"O\"\n */\n      __pyx_t_4 = PyInt_FromLong(NPY_CDOUBLE); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 840; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n      __Pyx_GOTREF(__pyx_t_4);\n      __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 840; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;\n      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 840; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;\n      if (__pyx_t_6) {\n        (__pyx_v_f[0]) = 90;\n        (__pyx_v_f[1]) = 100;\n        __pyx_v_f = (__pyx_v_f + 1);\n        goto __pyx_L11;\n      }\n\n      /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":841\n *             elif t == NPY_CFLOAT:      f[0] = 90; f[1] = 102; f += 1 # Zf\n *             elif t == NPY_CDOUBLE:     f[0] = 90; f[1] = 100; f += 1 # Zd\n *             elif t == NPY_CLONGDOUBLE: f[0] = 90; f[1] = 103; f += 1 # Zg             # <<<<<<<<<<<<<<\n *             elif t == NPY_OBJECT:      f[0] = 79 #\"O\"\n *             else:\n */\n      __pyx_t_3 = PyInt_FromLong(NPY_CLONGDOUBLE); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 841; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n      __Pyx_GOTREF(__pyx_t_3);\n      __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 841; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;\n      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 841; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;\n      if (__pyx_t_6) {\n        (__pyx_v_f[0]) = 90;\n        (__pyx_v_f[1]) = 103;\n        __pyx_v_f = (__pyx_v_f + 1);\n        goto __pyx_L11;\n      }\n\n      /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":842\n *             elif t == NPY_CDOUBLE:     f[0] = 90; f[1] = 100; f += 1 # Zd\n *             elif t == NPY_CLONGDOUBLE: f[0] = 90; f[1] = 103; f += 1 # Zg\n *             elif t == NPY_OBJECT:      f[0] = 79 #\"O\"             # <<<<<<<<<<<<<<\n *             else:\n *                 raise ValueError(u\"unknown dtype code in numpy.pxd (%d)\" % t)\n */\n      __pyx_t_4 = PyInt_FromLong(NPY_OBJECT); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 842; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n      __Pyx_GOTREF(__pyx_t_4);\n      __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 842; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;\n      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 842; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;\n      if (__pyx_t_6) {\n        (__pyx_v_f[0]) = 79;\n        goto __pyx_L11;\n      }\n      /*else*/ {\n\n        /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":844\n *             elif t == NPY_OBJECT:      f[0] = 79 #\"O\"\n *             else:\n *                 raise ValueError(u\"unknown dtype code in numpy.pxd (%d)\" % t)             # <<<<<<<<<<<<<<\n *             f += 1\n *         else:\n */\n        __pyx_t_3 = PyUnicode_Format(__pyx_kp_u_unknown_dtype_code_in_numpy_pxd, __pyx_v_t); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 844; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n        __Pyx_GOTREF(__pyx_t_3);\n        __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 844; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n        __Pyx_GOTREF(__pyx_t_4);\n        PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_3);\n        __Pyx_GIVEREF(__pyx_t_3);\n        __pyx_t_3 = 0;\n        __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_t_4, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 844; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n        __Pyx_GOTREF(__pyx_t_3);\n        __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;\n        __Pyx_Raise(__pyx_t_3, 0, 0, 0);\n        __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;\n        {__pyx_filename = __pyx_f[1]; __pyx_lineno = 844; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n      }\n      __pyx_L11:;\n\n      /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":845\n *             else:\n *                 raise ValueError(u\"unknown dtype code in numpy.pxd (%d)\" % t)\n *             f += 1             # <<<<<<<<<<<<<<\n *         else:\n *             # Cython ignores struct boundary information (\"T{...}\"),\n */\n      __pyx_v_f = (__pyx_v_f + 1);\n      goto __pyx_L9;\n    }\n    /*else*/ {\n\n      /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":849\n *             # Cython ignores struct boundary information (\"T{...}\"),\n *             # so don't output it\n *             f = _util_dtypestring(child, f, end, offset)             # <<<<<<<<<<<<<<\n *     return f\n * \n */\n      __pyx_t_11 = __pyx_f_5numpy__util_dtypestring(__pyx_v_child, __pyx_v_f, __pyx_v_end, __pyx_v_offset); if (unlikely(__pyx_t_11 == NULL)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 849; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n      __pyx_v_f = __pyx_t_11;\n    }\n    __pyx_L9:;\n  }\n  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;\n\n  /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":850\n *             # so don't output it\n *             f = _util_dtypestring(child, f, end, offset)\n *     return f             # <<<<<<<<<<<<<<\n * \n * \n */\n  __pyx_r = __pyx_v_f;\n  goto __pyx_L0;\n\n  /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":783\n *     return PyArray_MultiIterNew(5, <void*>a, <void*>b, <void*>c, <void*> d, <void*> e)\n * \n * cdef inline char* _util_dtypestring(dtype descr, char* f, char* end, int* offset) except NULL:             # <<<<<<<<<<<<<<\n *     # Recursive utility function used in __getbuffer__ to get format\n *     # string. The new location in the format string is returned.\n */\n\n  /* function exit code */\n  __pyx_L1_error:;\n  __Pyx_XDECREF(__pyx_t_1);\n  __Pyx_XDECREF(__pyx_t_3);\n  __Pyx_XDECREF(__pyx_t_4);\n  __Pyx_AddTraceback(\"numpy._util_dtypestring\", __pyx_clineno, __pyx_lineno, __pyx_filename);\n  __pyx_r = NULL;\n  __pyx_L0:;\n  __Pyx_XDECREF((PyObject *)__pyx_v_child);\n  __Pyx_XDECREF(__pyx_v_fields);\n  __Pyx_XDECREF(__pyx_v_childname);\n  __Pyx_XDECREF(__pyx_v_new_offset);\n  __Pyx_XDECREF(__pyx_v_t);\n  __Pyx_RefNannyFinishContext();\n  return __pyx_r;\n}\n\n/* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":966\n * \n * \n * cdef inline void set_array_base(ndarray arr, object base):             # <<<<<<<<<<<<<<\n *      cdef PyObject* baseptr\n *      if base is None:\n */\n\nstatic CYTHON_INLINE void __pyx_f_5numpy_set_array_base(PyArrayObject *__pyx_v_arr, PyObject *__pyx_v_base) {\n  PyObject *__pyx_v_baseptr;\n  __Pyx_RefNannyDeclarations\n  int __pyx_t_1;\n  int __pyx_t_2;\n  __Pyx_RefNannySetupContext(\"set_array_base\", 0);\n\n  /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":968\n * cdef inline void set_array_base(ndarray arr, object base):\n *      cdef PyObject* baseptr\n *      if base is None:             # <<<<<<<<<<<<<<\n *          baseptr = NULL\n *      else:\n */\n  __pyx_t_1 = (__pyx_v_base == Py_None);\n  __pyx_t_2 = (__pyx_t_1 != 0);\n  if (__pyx_t_2) {\n\n    /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":969\n *      cdef PyObject* baseptr\n *      if base is None:\n *          baseptr = NULL             # <<<<<<<<<<<<<<\n *      else:\n *          Py_INCREF(base) # important to do this before decref below!\n */\n    __pyx_v_baseptr = NULL;\n    goto __pyx_L3;\n  }\n  /*else*/ {\n\n    /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":971\n *          baseptr = NULL\n *      else:\n *          Py_INCREF(base) # important to do this before decref below!             # <<<<<<<<<<<<<<\n *          baseptr = <PyObject*>base\n *      Py_XDECREF(arr.base)\n */\n    Py_INCREF(__pyx_v_base);\n\n    /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":972\n *      else:\n *          Py_INCREF(base) # important to do this before decref below!\n *          baseptr = <PyObject*>base             # <<<<<<<<<<<<<<\n *      Py_XDECREF(arr.base)\n *      arr.base = baseptr\n */\n    __pyx_v_baseptr = ((PyObject *)__pyx_v_base);\n  }\n  __pyx_L3:;\n\n  /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":973\n *          Py_INCREF(base) # important to do this before decref below!\n *          baseptr = <PyObject*>base\n *      Py_XDECREF(arr.base)             # <<<<<<<<<<<<<<\n *      arr.base = baseptr\n * \n */\n  Py_XDECREF(__pyx_v_arr->base);\n\n  /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":974\n *          baseptr = <PyObject*>base\n *      Py_XDECREF(arr.base)\n *      arr.base = baseptr             # <<<<<<<<<<<<<<\n * \n * cdef inline object get_array_base(ndarray arr):\n */\n  __pyx_v_arr->base = __pyx_v_baseptr;\n\n  /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":966\n * \n * \n * cdef inline void set_array_base(ndarray arr, object base):             # <<<<<<<<<<<<<<\n *      cdef PyObject* baseptr\n *      if base is None:\n */\n\n  /* function exit code */\n  __Pyx_RefNannyFinishContext();\n}\n\n/* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":976\n *      arr.base = baseptr\n * \n * cdef inline object get_array_base(ndarray arr):             # <<<<<<<<<<<<<<\n *     if arr.base is NULL:\n *         return None\n */\n\nstatic CYTHON_INLINE PyObject *__pyx_f_5numpy_get_array_base(PyArrayObject *__pyx_v_arr) {\n  PyObject *__pyx_r = NULL;\n  __Pyx_RefNannyDeclarations\n  int __pyx_t_1;\n  __Pyx_RefNannySetupContext(\"get_array_base\", 0);\n\n  /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":977\n * \n * cdef inline object get_array_base(ndarray arr):\n *     if arr.base is NULL:             # <<<<<<<<<<<<<<\n *         return None\n *     else:\n */\n  __pyx_t_1 = ((__pyx_v_arr->base == NULL) != 0);\n  if (__pyx_t_1) {\n\n    /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":978\n * cdef inline object get_array_base(ndarray arr):\n *     if arr.base is NULL:\n *         return None             # <<<<<<<<<<<<<<\n *     else:\n *         return <object>arr.base\n */\n    __Pyx_XDECREF(__pyx_r);\n    __Pyx_INCREF(Py_None);\n    __pyx_r = Py_None;\n    goto __pyx_L0;\n  }\n  /*else*/ {\n\n    /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":980\n *         return None\n *     else:\n *         return <object>arr.base             # <<<<<<<<<<<<<<\n */\n    __Pyx_XDECREF(__pyx_r);\n    __Pyx_INCREF(((PyObject *)__pyx_v_arr->base));\n    __pyx_r = ((PyObject *)__pyx_v_arr->base);\n    goto __pyx_L0;\n  }\n\n  /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":976\n *      arr.base = baseptr\n * \n * cdef inline object get_array_base(ndarray arr):             # <<<<<<<<<<<<<<\n *     if arr.base is NULL:\n *         return None\n */\n\n  /* function exit code */\n  __pyx_L0:;\n  __Pyx_XGIVEREF(__pyx_r);\n  __Pyx_RefNannyFinishContext();\n  return __pyx_r;\n}\n\nstatic PyMethodDef __pyx_methods[] = {\n  {0, 0, 0, 0}\n};\n\n#if PY_MAJOR_VERSION >= 3\nstatic struct PyModuleDef __pyx_moduledef = {\n  #if PY_VERSION_HEX < 0x03020000\n    { PyObject_HEAD_INIT(NULL) NULL, 0, NULL },\n  #else\n    PyModuleDef_HEAD_INIT,\n  #endif\n    __Pyx_NAMESTR(\"cpu_nms\"),\n    0, /* m_doc */\n    -1, /* m_size */\n    __pyx_methods /* m_methods */,\n    NULL, /* m_reload */\n    NULL, /* m_traverse */\n    NULL, /* m_clear */\n    NULL /* m_free */\n};\n#endif\n\nstatic __Pyx_StringTabEntry __pyx_string_tab[] = {\n  {&__pyx_kp_u_Format_string_allocated_too_shor, __pyx_k_Format_string_allocated_too_shor, sizeof(__pyx_k_Format_string_allocated_too_shor), 0, 1, 0, 0},\n  {&__pyx_kp_u_Format_string_allocated_too_shor_2, __pyx_k_Format_string_allocated_too_shor_2, sizeof(__pyx_k_Format_string_allocated_too_shor_2), 0, 1, 0, 0},\n  {&__pyx_kp_u_Non_native_byte_order_not_suppor, __pyx_k_Non_native_byte_order_not_suppor, sizeof(__pyx_k_Non_native_byte_order_not_suppor), 0, 1, 0, 0},\n  {&__pyx_n_s_RuntimeError, __pyx_k_RuntimeError, sizeof(__pyx_k_RuntimeError), 0, 0, 1, 1},\n  {&__pyx_n_s_ValueError, __pyx_k_ValueError, sizeof(__pyx_k_ValueError), 0, 0, 1, 1},\n  {&__pyx_n_s_areas, __pyx_k_areas, sizeof(__pyx_k_areas), 0, 0, 1, 1},\n  {&__pyx_n_s_argsort, __pyx_k_argsort, sizeof(__pyx_k_argsort), 0, 0, 1, 1},\n  {&__pyx_n_s_cpu_nms, __pyx_k_cpu_nms, sizeof(__pyx_k_cpu_nms), 0, 0, 1, 1},\n  {&__pyx_n_s_dets, __pyx_k_dets, sizeof(__pyx_k_dets), 0, 0, 1, 1},\n  {&__pyx_n_s_dtype, __pyx_k_dtype, sizeof(__pyx_k_dtype), 0, 0, 1, 1},\n  {&__pyx_n_s_h, __pyx_k_h, sizeof(__pyx_k_h), 0, 0, 1, 1},\n  {&__pyx_n_s_i, __pyx_k_i, sizeof(__pyx_k_i), 0, 0, 1, 1},\n  {&__pyx_n_s_i_2, __pyx_k_i_2, sizeof(__pyx_k_i_2), 0, 0, 1, 1},\n  {&__pyx_n_s_iarea, __pyx_k_iarea, sizeof(__pyx_k_iarea), 0, 0, 1, 1},\n  {&__pyx_n_s_import, __pyx_k_import, sizeof(__pyx_k_import), 0, 0, 1, 1},\n  {&__pyx_n_s_int, __pyx_k_int, sizeof(__pyx_k_int), 0, 0, 1, 1},\n  {&__pyx_n_s_inter, __pyx_k_inter, sizeof(__pyx_k_inter), 0, 0, 1, 1},\n  {&__pyx_n_s_ix1, __pyx_k_ix1, sizeof(__pyx_k_ix1), 0, 0, 1, 1},\n  {&__pyx_n_s_ix2, __pyx_k_ix2, sizeof(__pyx_k_ix2), 0, 0, 1, 1},\n  {&__pyx_n_s_iy1, __pyx_k_iy1, sizeof(__pyx_k_iy1), 0, 0, 1, 1},\n  {&__pyx_n_s_iy2, __pyx_k_iy2, sizeof(__pyx_k_iy2), 0, 0, 1, 1},\n  {&__pyx_n_s_j, __pyx_k_j, sizeof(__pyx_k_j), 0, 0, 1, 1},\n  {&__pyx_n_s_j_2, __pyx_k_j_2, sizeof(__pyx_k_j_2), 0, 0, 1, 1},\n  {&__pyx_n_s_keep, __pyx_k_keep, sizeof(__pyx_k_keep), 0, 0, 1, 1},\n  {&__pyx_n_s_main, __pyx_k_main, sizeof(__pyx_k_main), 0, 0, 1, 1},\n  {&__pyx_kp_u_ndarray_is_not_C_contiguous, __pyx_k_ndarray_is_not_C_contiguous, sizeof(__pyx_k_ndarray_is_not_C_contiguous), 0, 1, 0, 0},\n  {&__pyx_kp_u_ndarray_is_not_Fortran_contiguou, __pyx_k_ndarray_is_not_Fortran_contiguou, sizeof(__pyx_k_ndarray_is_not_Fortran_contiguou), 0, 1, 0, 0},\n  {&__pyx_n_s_ndets, __pyx_k_ndets, sizeof(__pyx_k_ndets), 0, 0, 1, 1},\n  {&__pyx_kp_s_nfs_yoda_xinleic_Inf_Code_Faste, __pyx_k_nfs_yoda_xinleic_Inf_Code_Faste, sizeof(__pyx_k_nfs_yoda_xinleic_Inf_Code_Faste), 0, 0, 1, 0},\n  {&__pyx_n_s_nms_cpu_nms, __pyx_k_nms_cpu_nms, sizeof(__pyx_k_nms_cpu_nms), 0, 0, 1, 1},\n  {&__pyx_n_s_np, __pyx_k_np, sizeof(__pyx_k_np), 0, 0, 1, 1},\n  {&__pyx_n_s_numpy, __pyx_k_numpy, sizeof(__pyx_k_numpy), 0, 0, 1, 1},\n  {&__pyx_n_s_order, __pyx_k_order, sizeof(__pyx_k_order), 0, 0, 1, 1},\n  {&__pyx_n_s_ovr, __pyx_k_ovr, sizeof(__pyx_k_ovr), 0, 0, 1, 1},\n  {&__pyx_n_s_pyx_getbuffer, __pyx_k_pyx_getbuffer, sizeof(__pyx_k_pyx_getbuffer), 0, 0, 1, 1},\n  {&__pyx_n_s_pyx_releasebuffer, __pyx_k_pyx_releasebuffer, sizeof(__pyx_k_pyx_releasebuffer), 0, 0, 1, 1},\n  {&__pyx_n_s_range, __pyx_k_range, sizeof(__pyx_k_range), 0, 0, 1, 1},\n  {&__pyx_n_s_scores, __pyx_k_scores, sizeof(__pyx_k_scores), 0, 0, 1, 1},\n  {&__pyx_n_s_suppressed, __pyx_k_suppressed, sizeof(__pyx_k_suppressed), 0, 0, 1, 1},\n  {&__pyx_n_s_test, __pyx_k_test, sizeof(__pyx_k_test), 0, 0, 1, 1},\n  {&__pyx_n_s_thresh, __pyx_k_thresh, sizeof(__pyx_k_thresh), 0, 0, 1, 1},\n  {&__pyx_kp_u_unknown_dtype_code_in_numpy_pxd, __pyx_k_unknown_dtype_code_in_numpy_pxd, sizeof(__pyx_k_unknown_dtype_code_in_numpy_pxd), 0, 1, 0, 0},\n  {&__pyx_n_s_w, __pyx_k_w, sizeof(__pyx_k_w), 0, 0, 1, 1},\n  {&__pyx_n_s_x1, __pyx_k_x1, sizeof(__pyx_k_x1), 0, 0, 1, 1},\n  {&__pyx_n_s_x2, __pyx_k_x2, sizeof(__pyx_k_x2), 0, 0, 1, 1},\n  {&__pyx_n_s_xx1, __pyx_k_xx1, sizeof(__pyx_k_xx1), 0, 0, 1, 1},\n  {&__pyx_n_s_xx2, __pyx_k_xx2, sizeof(__pyx_k_xx2), 0, 0, 1, 1},\n  {&__pyx_n_s_y1, __pyx_k_y1, sizeof(__pyx_k_y1), 0, 0, 1, 1},\n  {&__pyx_n_s_y2, __pyx_k_y2, sizeof(__pyx_k_y2), 0, 0, 1, 1},\n  {&__pyx_n_s_yy1, __pyx_k_yy1, sizeof(__pyx_k_yy1), 0, 0, 1, 1},\n  {&__pyx_n_s_yy2, __pyx_k_yy2, sizeof(__pyx_k_yy2), 0, 0, 1, 1},\n  {&__pyx_n_s_zeros, __pyx_k_zeros, sizeof(__pyx_k_zeros), 0, 0, 1, 1},\n  {0, 0, 0, 0, 0, 0, 0}\n};\nstatic int __Pyx_InitCachedBuiltins(void) {\n  __pyx_builtin_range = __Pyx_GetBuiltinName(__pyx_n_s_range); if (!__pyx_builtin_range) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 43; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n  __pyx_builtin_ValueError = __Pyx_GetBuiltinName(__pyx_n_s_ValueError); if (!__pyx_builtin_ValueError) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 215; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n  __pyx_builtin_RuntimeError = __Pyx_GetBuiltinName(__pyx_n_s_RuntimeError); if (!__pyx_builtin_RuntimeError) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 799; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n  return 0;\n  __pyx_L1_error:;\n  return -1;\n}\n\nstatic int __Pyx_InitCachedConstants(void) {\n  __Pyx_RefNannyDeclarations\n  __Pyx_RefNannySetupContext(\"__Pyx_InitCachedConstants\", 0);\n\n  /* \"nms/cpu_nms.pyx\":18\n * \n * def cpu_nms(np.ndarray[np.float32_t, ndim=2] dets, np.float thresh):\n *     cdef np.ndarray[np.float32_t, ndim=1] x1 = dets[:, 0]             # <<<<<<<<<<<<<<\n *     cdef np.ndarray[np.float32_t, ndim=1] y1 = dets[:, 1]\n *     cdef np.ndarray[np.float32_t, ndim=1] x2 = dets[:, 2]\n */\n  __pyx_slice_ = PySlice_New(Py_None, Py_None, Py_None); if (unlikely(!__pyx_slice_)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 18; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n  __Pyx_GOTREF(__pyx_slice_);\n  __Pyx_GIVEREF(__pyx_slice_);\n  __pyx_tuple__2 = PyTuple_Pack(2, __pyx_slice_, __pyx_int_0); if (unlikely(!__pyx_tuple__2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 18; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n  __Pyx_GOTREF(__pyx_tuple__2);\n  __Pyx_GIVEREF(__pyx_tuple__2);\n\n  /* \"nms/cpu_nms.pyx\":19\n * def cpu_nms(np.ndarray[np.float32_t, ndim=2] dets, np.float thresh):\n *     cdef np.ndarray[np.float32_t, ndim=1] x1 = dets[:, 0]\n *     cdef np.ndarray[np.float32_t, ndim=1] y1 = dets[:, 1]             # <<<<<<<<<<<<<<\n *     cdef np.ndarray[np.float32_t, ndim=1] x2 = dets[:, 2]\n *     cdef np.ndarray[np.float32_t, ndim=1] y2 = dets[:, 3]\n */\n  __pyx_slice__3 = PySlice_New(Py_None, Py_None, Py_None); if (unlikely(!__pyx_slice__3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 19; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n  __Pyx_GOTREF(__pyx_slice__3);\n  __Pyx_GIVEREF(__pyx_slice__3);\n  __pyx_tuple__4 = PyTuple_Pack(2, __pyx_slice__3, __pyx_int_1); if (unlikely(!__pyx_tuple__4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 19; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n  __Pyx_GOTREF(__pyx_tuple__4);\n  __Pyx_GIVEREF(__pyx_tuple__4);\n\n  /* \"nms/cpu_nms.pyx\":20\n *     cdef np.ndarray[np.float32_t, ndim=1] x1 = dets[:, 0]\n *     cdef np.ndarray[np.float32_t, ndim=1] y1 = dets[:, 1]\n *     cdef np.ndarray[np.float32_t, ndim=1] x2 = dets[:, 2]             # <<<<<<<<<<<<<<\n *     cdef np.ndarray[np.float32_t, ndim=1] y2 = dets[:, 3]\n *     cdef np.ndarray[np.float32_t, ndim=1] scores = dets[:, 4]\n */\n  __pyx_slice__5 = PySlice_New(Py_None, Py_None, Py_None); if (unlikely(!__pyx_slice__5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 20; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n  __Pyx_GOTREF(__pyx_slice__5);\n  __Pyx_GIVEREF(__pyx_slice__5);\n  __pyx_tuple__6 = PyTuple_Pack(2, __pyx_slice__5, __pyx_int_2); if (unlikely(!__pyx_tuple__6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 20; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n  __Pyx_GOTREF(__pyx_tuple__6);\n  __Pyx_GIVEREF(__pyx_tuple__6);\n\n  /* \"nms/cpu_nms.pyx\":21\n *     cdef np.ndarray[np.float32_t, ndim=1] y1 = dets[:, 1]\n *     cdef np.ndarray[np.float32_t, ndim=1] x2 = dets[:, 2]\n *     cdef np.ndarray[np.float32_t, ndim=1] y2 = dets[:, 3]             # <<<<<<<<<<<<<<\n *     cdef np.ndarray[np.float32_t, ndim=1] scores = dets[:, 4]\n * \n */\n  __pyx_slice__7 = PySlice_New(Py_None, Py_None, Py_None); if (unlikely(!__pyx_slice__7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 21; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n  __Pyx_GOTREF(__pyx_slice__7);\n  __Pyx_GIVEREF(__pyx_slice__7);\n  __pyx_tuple__8 = PyTuple_Pack(2, __pyx_slice__7, __pyx_int_3); if (unlikely(!__pyx_tuple__8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 21; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n  __Pyx_GOTREF(__pyx_tuple__8);\n  __Pyx_GIVEREF(__pyx_tuple__8);\n\n  /* \"nms/cpu_nms.pyx\":22\n *     cdef np.ndarray[np.float32_t, ndim=1] x2 = dets[:, 2]\n *     cdef np.ndarray[np.float32_t, ndim=1] y2 = dets[:, 3]\n *     cdef np.ndarray[np.float32_t, ndim=1] scores = dets[:, 4]             # <<<<<<<<<<<<<<\n * \n *     cdef np.ndarray[np.float32_t, ndim=1] areas = (x2 - x1 + 1) * (y2 - y1 + 1)\n */\n  __pyx_slice__9 = PySlice_New(Py_None, Py_None, Py_None); if (unlikely(!__pyx_slice__9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 22; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n  __Pyx_GOTREF(__pyx_slice__9);\n  __Pyx_GIVEREF(__pyx_slice__9);\n  __pyx_tuple__10 = PyTuple_Pack(2, __pyx_slice__9, __pyx_int_4); if (unlikely(!__pyx_tuple__10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 22; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n  __Pyx_GOTREF(__pyx_tuple__10);\n  __Pyx_GIVEREF(__pyx_tuple__10);\n\n  /* \"nms/cpu_nms.pyx\":25\n * \n *     cdef np.ndarray[np.float32_t, ndim=1] areas = (x2 - x1 + 1) * (y2 - y1 + 1)\n *     cdef np.ndarray[np.int_t, ndim=1] order = scores.argsort()[::-1]             # <<<<<<<<<<<<<<\n * \n *     cdef int ndets = dets.shape[0]\n */\n  __pyx_slice__11 = PySlice_New(Py_None, Py_None, __pyx_int_neg_1); if (unlikely(!__pyx_slice__11)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 25; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n  __Pyx_GOTREF(__pyx_slice__11);\n  __Pyx_GIVEREF(__pyx_slice__11);\n\n  /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":215\n *             if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS)\n *                 and not PyArray_CHKFLAGS(self, NPY_C_CONTIGUOUS)):\n *                 raise ValueError(u\"ndarray is not C contiguous\")             # <<<<<<<<<<<<<<\n * \n *             if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS)\n */\n  __pyx_tuple__12 = PyTuple_Pack(1, __pyx_kp_u_ndarray_is_not_C_contiguous); if (unlikely(!__pyx_tuple__12)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 215; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n  __Pyx_GOTREF(__pyx_tuple__12);\n  __Pyx_GIVEREF(__pyx_tuple__12);\n\n  /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":219\n *             if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS)\n *                 and not PyArray_CHKFLAGS(self, NPY_F_CONTIGUOUS)):\n *                 raise ValueError(u\"ndarray is not Fortran contiguous\")             # <<<<<<<<<<<<<<\n * \n *             info.buf = PyArray_DATA(self)\n */\n  __pyx_tuple__13 = PyTuple_Pack(1, __pyx_kp_u_ndarray_is_not_Fortran_contiguou); if (unlikely(!__pyx_tuple__13)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 219; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n  __Pyx_GOTREF(__pyx_tuple__13);\n  __Pyx_GIVEREF(__pyx_tuple__13);\n\n  /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":257\n *                 if ((descr.byteorder == c'>' and little_endian) or\n *                     (descr.byteorder == c'<' and not little_endian)):\n *                     raise ValueError(u\"Non-native byte order not supported\")             # <<<<<<<<<<<<<<\n *                 if   t == NPY_BYTE:        f = \"b\"\n *                 elif t == NPY_UBYTE:       f = \"B\"\n */\n  __pyx_tuple__14 = PyTuple_Pack(1, __pyx_kp_u_Non_native_byte_order_not_suppor); if (unlikely(!__pyx_tuple__14)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 257; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n  __Pyx_GOTREF(__pyx_tuple__14);\n  __Pyx_GIVEREF(__pyx_tuple__14);\n\n  /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":799\n * \n *         if (end - f) - <int>(new_offset - offset[0]) < 15:\n *             raise RuntimeError(u\"Format string allocated too short, see comment in numpy.pxd\")             # <<<<<<<<<<<<<<\n * \n *         if ((child.byteorder == c'>' and little_endian) or\n */\n  __pyx_tuple__15 = PyTuple_Pack(1, __pyx_kp_u_Format_string_allocated_too_shor); if (unlikely(!__pyx_tuple__15)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 799; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n  __Pyx_GOTREF(__pyx_tuple__15);\n  __Pyx_GIVEREF(__pyx_tuple__15);\n\n  /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":803\n *         if ((child.byteorder == c'>' and little_endian) or\n *             (child.byteorder == c'<' and not little_endian)):\n *             raise ValueError(u\"Non-native byte order not supported\")             # <<<<<<<<<<<<<<\n *             # One could encode it in the format string and have Cython\n *             # complain instead, BUT: < and > in format strings also imply\n */\n  __pyx_tuple__16 = PyTuple_Pack(1, __pyx_kp_u_Non_native_byte_order_not_suppor); if (unlikely(!__pyx_tuple__16)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 803; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n  __Pyx_GOTREF(__pyx_tuple__16);\n  __Pyx_GIVEREF(__pyx_tuple__16);\n\n  /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":823\n *             t = child.type_num\n *             if end - f < 5:\n *                 raise RuntimeError(u\"Format string allocated too short.\")             # <<<<<<<<<<<<<<\n * \n *             # Until ticket #99 is fixed, use integers to avoid warnings\n */\n  __pyx_tuple__17 = PyTuple_Pack(1, __pyx_kp_u_Format_string_allocated_too_shor_2); if (unlikely(!__pyx_tuple__17)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 823; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n  __Pyx_GOTREF(__pyx_tuple__17);\n  __Pyx_GIVEREF(__pyx_tuple__17);\n\n  /* \"nms/cpu_nms.pyx\":17\n *     return a if a <= b else b\n * \n * def cpu_nms(np.ndarray[np.float32_t, ndim=2] dets, np.float thresh):             # <<<<<<<<<<<<<<\n *     cdef np.ndarray[np.float32_t, ndim=1] x1 = dets[:, 0]\n *     cdef np.ndarray[np.float32_t, ndim=1] y1 = dets[:, 1]\n */\n  __pyx_tuple__18 = PyTuple_Pack(29, __pyx_n_s_dets, __pyx_n_s_thresh, __pyx_n_s_x1, __pyx_n_s_y1, __pyx_n_s_x2, __pyx_n_s_y2, __pyx_n_s_scores, __pyx_n_s_areas, __pyx_n_s_order, __pyx_n_s_ndets, __pyx_n_s_suppressed, __pyx_n_s_i_2, __pyx_n_s_j, __pyx_n_s_i, __pyx_n_s_j_2, __pyx_n_s_ix1, __pyx_n_s_iy1, __pyx_n_s_ix2, __pyx_n_s_iy2, __pyx_n_s_iarea, __pyx_n_s_xx1, __pyx_n_s_yy1, __pyx_n_s_xx2, __pyx_n_s_yy2, __pyx_n_s_w, __pyx_n_s_h, __pyx_n_s_inter, __pyx_n_s_ovr, __pyx_n_s_keep); if (unlikely(!__pyx_tuple__18)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 17; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n  __Pyx_GOTREF(__pyx_tuple__18);\n  __Pyx_GIVEREF(__pyx_tuple__18);\n  __pyx_codeobj__19 = (PyObject*)__Pyx_PyCode_New(2, 0, 29, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__18, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_nfs_yoda_xinleic_Inf_Code_Faste, __pyx_n_s_cpu_nms, 17, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__19)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 17; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n  __Pyx_RefNannyFinishContext();\n  return 0;\n  __pyx_L1_error:;\n  __Pyx_RefNannyFinishContext();\n  return -1;\n}\n\nstatic int __Pyx_InitGlobals(void) {\n  if (__Pyx_InitStrings(__pyx_string_tab) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};\n  __pyx_int_0 = PyInt_FromLong(0); if (unlikely(!__pyx_int_0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n  __pyx_int_1 = PyInt_FromLong(1); if (unlikely(!__pyx_int_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n  __pyx_int_2 = PyInt_FromLong(2); if (unlikely(!__pyx_int_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n  __pyx_int_3 = PyInt_FromLong(3); if (unlikely(!__pyx_int_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n  __pyx_int_4 = PyInt_FromLong(4); if (unlikely(!__pyx_int_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n  __pyx_int_neg_1 = PyInt_FromLong(-1); if (unlikely(!__pyx_int_neg_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n  return 0;\n  __pyx_L1_error:;\n  return -1;\n}\n\n#if PY_MAJOR_VERSION < 3\nPyMODINIT_FUNC initcpu_nms(void); /*proto*/\nPyMODINIT_FUNC initcpu_nms(void)\n#else\nPyMODINIT_FUNC PyInit_cpu_nms(void); /*proto*/\nPyMODINIT_FUNC PyInit_cpu_nms(void)\n#endif\n{\n  PyObject *__pyx_t_1 = NULL;\n  int __pyx_lineno = 0;\n  const char *__pyx_filename = NULL;\n  int __pyx_clineno = 0;\n  __Pyx_RefNannyDeclarations\n  #if CYTHON_REFNANNY\n  __Pyx_RefNanny = __Pyx_RefNannyImportAPI(\"refnanny\");\n  if (!__Pyx_RefNanny) {\n      PyErr_Clear();\n      __Pyx_RefNanny = __Pyx_RefNannyImportAPI(\"Cython.Runtime.refnanny\");\n      if (!__Pyx_RefNanny)\n          Py_FatalError(\"failed to import 'refnanny' module\");\n  }\n  #endif\n  __Pyx_RefNannySetupContext(\"PyMODINIT_FUNC PyInit_cpu_nms(void)\", 0);\n  if ( __Pyx_check_binary_version() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n  __pyx_empty_tuple = PyTuple_New(0); if (unlikely(!__pyx_empty_tuple)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n  __pyx_empty_bytes = PyBytes_FromStringAndSize(\"\", 0); if (unlikely(!__pyx_empty_bytes)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n  #ifdef __Pyx_CyFunction_USED\n  if (__Pyx_CyFunction_init() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n  #endif\n  #ifdef __Pyx_FusedFunction_USED\n  if (__pyx_FusedFunction_init() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n  #endif\n  #ifdef __Pyx_Generator_USED\n  if (__pyx_Generator_init() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n  #endif\n  /*--- Library function declarations ---*/\n  /*--- Threads initialization code ---*/\n  #if defined(__PYX_FORCE_INIT_THREADS) && __PYX_FORCE_INIT_THREADS\n  #ifdef WITH_THREAD /* Python build with threading support? */\n  PyEval_InitThreads();\n  #endif\n  #endif\n  /*--- Module creation code ---*/\n  #if PY_MAJOR_VERSION < 3\n  __pyx_m = Py_InitModule4(__Pyx_NAMESTR(\"cpu_nms\"), __pyx_methods, 0, 0, PYTHON_API_VERSION); Py_XINCREF(__pyx_m);\n  #else\n  __pyx_m = PyModule_Create(&__pyx_moduledef);\n  #endif\n  if (unlikely(!__pyx_m)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n  __pyx_d = PyModule_GetDict(__pyx_m); if (unlikely(!__pyx_d)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n  Py_INCREF(__pyx_d);\n  __pyx_b = PyImport_AddModule(__Pyx_NAMESTR(__Pyx_BUILTIN_MODULE_NAME)); if (unlikely(!__pyx_b)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n  #if CYTHON_COMPILING_IN_PYPY\n  Py_INCREF(__pyx_b);\n  #endif\n  if (__Pyx_SetAttrString(__pyx_m, \"__builtins__\", __pyx_b) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};\n  /*--- Initialize various global constants etc. ---*/\n  if (unlikely(__Pyx_InitGlobals() < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n  #if PY_MAJOR_VERSION < 3 && (__PYX_DEFAULT_STRING_ENCODING_IS_ASCII || __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT)\n  if (__Pyx_init_sys_getdefaultencoding_params() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n  #endif\n  if (__pyx_module_is_main_nms__cpu_nms) {\n    if (__Pyx_SetAttrString(__pyx_m, \"__name__\", __pyx_n_s_main) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};\n  }\n  #if PY_MAJOR_VERSION >= 3\n  {\n    PyObject *modules = PyImport_GetModuleDict(); if (unlikely(!modules)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n    if (!PyDict_GetItemString(modules, \"nms.cpu_nms\")) {\n      if (unlikely(PyDict_SetItemString(modules, \"nms.cpu_nms\", __pyx_m) < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n    }\n  }\n  #endif\n  /*--- Builtin init code ---*/\n  if (unlikely(__Pyx_InitCachedBuiltins() < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n  /*--- Constants init code ---*/\n  if (unlikely(__Pyx_InitCachedConstants() < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n  /*--- Global init code ---*/\n  /*--- Variable export code ---*/\n  /*--- Function export code ---*/\n  /*--- Type init code ---*/\n  /*--- Type import code ---*/\n  __pyx_ptype_7cpython_4type_type = __Pyx_ImportType(__Pyx_BUILTIN_MODULE_NAME, \"type\", \n  #if CYTHON_COMPILING_IN_PYPY\n  sizeof(PyTypeObject),\n  #else\n  sizeof(PyHeapTypeObject),\n  #endif\n  0); if (unlikely(!__pyx_ptype_7cpython_4type_type)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 9; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n  __pyx_ptype_5numpy_dtype = __Pyx_ImportType(\"numpy\", \"dtype\", sizeof(PyArray_Descr), 0); if (unlikely(!__pyx_ptype_5numpy_dtype)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 155; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n  __pyx_ptype_5numpy_flatiter = __Pyx_ImportType(\"numpy\", \"flatiter\", sizeof(PyArrayIterObject), 0); if (unlikely(!__pyx_ptype_5numpy_flatiter)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 165; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n  __pyx_ptype_5numpy_broadcast = __Pyx_ImportType(\"numpy\", \"broadcast\", sizeof(PyArrayMultiIterObject), 0); if (unlikely(!__pyx_ptype_5numpy_broadcast)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 169; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n  __pyx_ptype_5numpy_ndarray = __Pyx_ImportType(\"numpy\", \"ndarray\", sizeof(PyArrayObject), 0); if (unlikely(!__pyx_ptype_5numpy_ndarray)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 178; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n  __pyx_ptype_5numpy_ufunc = __Pyx_ImportType(\"numpy\", \"ufunc\", sizeof(PyUFuncObject), 0); if (unlikely(!__pyx_ptype_5numpy_ufunc)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 861; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n  /*--- Variable import code ---*/\n  /*--- Function import code ---*/\n  /*--- Execution code ---*/\n\n  /* \"nms/cpu_nms.pyx\":8\n * # --------------------------------------------------------\n * \n * import numpy as np             # <<<<<<<<<<<<<<\n * cimport numpy as np\n * \n */\n  __pyx_t_1 = __Pyx_Import(__pyx_n_s_numpy, 0, -1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 8; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n  __Pyx_GOTREF(__pyx_t_1);\n  if (PyDict_SetItem(__pyx_d, __pyx_n_s_np, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 8; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;\n\n  /* \"nms/cpu_nms.pyx\":17\n *     return a if a <= b else b\n * \n * def cpu_nms(np.ndarray[np.float32_t, ndim=2] dets, np.float thresh):             # <<<<<<<<<<<<<<\n *     cdef np.ndarray[np.float32_t, ndim=1] x1 = dets[:, 0]\n *     cdef np.ndarray[np.float32_t, ndim=1] y1 = dets[:, 1]\n */\n  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_3nms_7cpu_nms_1cpu_nms, NULL, __pyx_n_s_nms_cpu_nms); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 17; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n  __Pyx_GOTREF(__pyx_t_1);\n  if (PyDict_SetItem(__pyx_d, __pyx_n_s_cpu_nms, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 17; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;\n\n  /* \"nms/cpu_nms.pyx\":1\n * # --------------------------------------------------------             # <<<<<<<<<<<<<<\n * # Fast R-CNN\n * # Copyright (c) 2015 Microsoft\n */\n  __pyx_t_1 = PyDict_New(); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n  __Pyx_GOTREF(__pyx_t_1);\n  if (PyDict_SetItem(__pyx_d, __pyx_n_s_test, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;\n\n  /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":976\n *      arr.base = baseptr\n * \n * cdef inline object get_array_base(ndarray arr):             # <<<<<<<<<<<<<<\n *     if arr.base is NULL:\n *         return None\n */\n  goto __pyx_L0;\n  __pyx_L1_error:;\n  __Pyx_XDECREF(__pyx_t_1);\n  if (__pyx_m) {\n    __Pyx_AddTraceback(\"init nms.cpu_nms\", __pyx_clineno, __pyx_lineno, __pyx_filename);\n    Py_DECREF(__pyx_m); __pyx_m = 0;\n  } else if (!PyErr_Occurred()) {\n    PyErr_SetString(PyExc_ImportError, \"init nms.cpu_nms\");\n  }\n  __pyx_L0:;\n  __Pyx_RefNannyFinishContext();\n  #if PY_MAJOR_VERSION < 3\n  return;\n  #else\n  return __pyx_m;\n  #endif\n}\n\n/* Runtime support code */\n#if CYTHON_REFNANNY\nstatic __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname) {\n    PyObject *m = NULL, *p = NULL;\n    void *r = NULL;\n    m = PyImport_ImportModule((char *)modname);\n    if (!m) goto end;\n    p = PyObject_GetAttrString(m, (char *)\"RefNannyAPI\");\n    if (!p) goto end;\n    r = PyLong_AsVoidPtr(p);\nend:\n    Py_XDECREF(p);\n    Py_XDECREF(m);\n    return (__Pyx_RefNannyAPIStruct *)r;\n}\n#endif /* CYTHON_REFNANNY */\n\nstatic PyObject *__Pyx_GetBuiltinName(PyObject *name) {\n    PyObject* result = __Pyx_PyObject_GetAttrStr(__pyx_b, name);\n    if (unlikely(!result)) {\n        PyErr_Format(PyExc_NameError,\n#if PY_MAJOR_VERSION >= 3\n            \"name '%U' is not defined\", name);\n#else\n            \"name '%.200s' is not defined\", PyString_AS_STRING(name));\n#endif\n    }\n    return result;\n}\n\nstatic void __Pyx_RaiseArgtupleInvalid(\n    const char* func_name,\n    int exact,\n    Py_ssize_t num_min,\n    Py_ssize_t num_max,\n    Py_ssize_t num_found)\n{\n    Py_ssize_t num_expected;\n    const char *more_or_less;\n    if (num_found < num_min) {\n        num_expected = num_min;\n        more_or_less = \"at least\";\n    } else {\n        num_expected = num_max;\n        more_or_less = \"at most\";\n    }\n    if (exact) {\n        more_or_less = \"exactly\";\n    }\n    PyErr_Format(PyExc_TypeError,\n                 \"%.200s() takes %.8s %\" CYTHON_FORMAT_SSIZE_T \"d positional argument%.1s (%\" CYTHON_FORMAT_SSIZE_T \"d given)\",\n                 func_name, more_or_less, num_expected,\n                 (num_expected == 1) ? \"\" : \"s\", num_found);\n}\n\nstatic void __Pyx_RaiseDoubleKeywordsError(\n    const char* func_name,\n    PyObject* kw_name)\n{\n    PyErr_Format(PyExc_TypeError,\n        #if PY_MAJOR_VERSION >= 3\n        \"%s() got multiple values for keyword argument '%U'\", func_name, kw_name);\n        #else\n        \"%s() got multiple values for keyword argument '%s'\", func_name,\n        PyString_AsString(kw_name));\n        #endif\n}\n\nstatic int __Pyx_ParseOptionalKeywords(\n    PyObject *kwds,\n    PyObject **argnames[],\n    PyObject *kwds2,\n    PyObject *values[],\n    Py_ssize_t num_pos_args,\n    const char* function_name)\n{\n    PyObject *key = 0, *value = 0;\n    Py_ssize_t pos = 0;\n    PyObject*** name;\n    PyObject*** first_kw_arg = argnames + num_pos_args;\n    while (PyDict_Next(kwds, &pos, &key, &value)) {\n        name = first_kw_arg;\n        while (*name && (**name != key)) name++;\n        if (*name) {\n            values[name-argnames] = value;\n            continue;\n        }\n        name = first_kw_arg;\n        #if PY_MAJOR_VERSION < 3\n        if (likely(PyString_CheckExact(key)) || likely(PyString_Check(key))) {\n            while (*name) {\n                if ((CYTHON_COMPILING_IN_PYPY || PyString_GET_SIZE(**name) == PyString_GET_SIZE(key))\n                        && _PyString_Eq(**name, key)) {\n                    values[name-argnames] = value;\n                    break;\n                }\n                name++;\n            }\n            if (*name) continue;\n            else {\n                PyObject*** argname = argnames;\n                while (argname != first_kw_arg) {\n                    if ((**argname == key) || (\n                            (CYTHON_COMPILING_IN_PYPY || PyString_GET_SIZE(**argname) == PyString_GET_SIZE(key))\n                             && _PyString_Eq(**argname, key))) {\n                        goto arg_passed_twice;\n                    }\n                    argname++;\n                }\n            }\n        } else\n        #endif\n        if (likely(PyUnicode_Check(key))) {\n            while (*name) {\n                int cmp = (**name == key) ? 0 :\n                #if !CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION >= 3\n                    (PyUnicode_GET_SIZE(**name) != PyUnicode_GET_SIZE(key)) ? 1 :\n                #endif\n                    PyUnicode_Compare(**name, key);\n                if (cmp < 0 && unlikely(PyErr_Occurred())) goto bad;\n                if (cmp == 0) {\n                    values[name-argnames] = value;\n                    break;\n                }\n                name++;\n            }\n            if (*name) continue;\n            else {\n                PyObject*** argname = argnames;\n                while (argname != first_kw_arg) {\n                    int cmp = (**argname == key) ? 0 :\n                    #if !CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION >= 3\n                        (PyUnicode_GET_SIZE(**argname) != PyUnicode_GET_SIZE(key)) ? 1 :\n                    #endif\n                        PyUnicode_Compare(**argname, key);\n                    if (cmp < 0 && unlikely(PyErr_Occurred())) goto bad;\n                    if (cmp == 0) goto arg_passed_twice;\n                    argname++;\n                }\n            }\n        } else\n            goto invalid_keyword_type;\n        if (kwds2) {\n            if (unlikely(PyDict_SetItem(kwds2, key, value))) goto bad;\n        } else {\n            goto invalid_keyword;\n        }\n    }\n    return 0;\narg_passed_twice:\n    __Pyx_RaiseDoubleKeywordsError(function_name, key);\n    goto bad;\ninvalid_keyword_type:\n    PyErr_Format(PyExc_TypeError,\n        \"%.200s() keywords must be strings\", function_name);\n    goto bad;\ninvalid_keyword:\n    PyErr_Format(PyExc_TypeError,\n    #if PY_MAJOR_VERSION < 3\n        \"%.200s() got an unexpected keyword argument '%.200s'\",\n        function_name, PyString_AsString(key));\n    #else\n        \"%s() got an unexpected keyword argument '%U'\",\n        function_name, key);\n    #endif\nbad:\n    return -1;\n}\n\nstatic void __Pyx_RaiseArgumentTypeInvalid(const char* name, PyObject *obj, PyTypeObject *type) {\n    PyErr_Format(PyExc_TypeError,\n        \"Argument '%.200s' has incorrect type (expected %.200s, got %.200s)\",\n        name, type->tp_name, Py_TYPE(obj)->tp_name);\n}\nstatic CYTHON_INLINE int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed,\n    const char *name, int exact)\n{\n    if (unlikely(!type)) {\n        PyErr_SetString(PyExc_SystemError, \"Missing type object\");\n        return 0;\n    }\n    if (none_allowed && obj == Py_None) return 1;\n    else if (exact) {\n        if (likely(Py_TYPE(obj) == type)) return 1;\n        #if PY_MAJOR_VERSION == 2\n        else if ((type == &PyBaseString_Type) && likely(__Pyx_PyBaseString_CheckExact(obj))) return 1;\n        #endif\n    }\n    else {\n        if (likely(PyObject_TypeCheck(obj, type))) return 1;\n    }\n    __Pyx_RaiseArgumentTypeInvalid(name, obj, type);\n    return 0;\n}\n\nstatic CYTHON_INLINE int __Pyx_IsLittleEndian(void) {\n  unsigned int n = 1;\n  return *(unsigned char*)(&n) != 0;\n}\nstatic void __Pyx_BufFmt_Init(__Pyx_BufFmt_Context* ctx,\n                              __Pyx_BufFmt_StackElem* stack,\n                              __Pyx_TypeInfo* type) {\n  stack[0].field = &ctx->root;\n  stack[0].parent_offset = 0;\n  ctx->root.type = type;\n  ctx->root.name = \"buffer dtype\";\n  ctx->root.offset = 0;\n  ctx->head = stack;\n  ctx->head->field = &ctx->root;\n  ctx->fmt_offset = 0;\n  ctx->head->parent_offset = 0;\n  ctx->new_packmode = '@';\n  ctx->enc_packmode = '@';\n  ctx->new_count = 1;\n  ctx->enc_count = 0;\n  ctx->enc_type = 0;\n  ctx->is_complex = 0;\n  ctx->is_valid_array = 0;\n  ctx->struct_alignment = 0;\n  while (type->typegroup == 'S') {\n    ++ctx->head;\n    ctx->head->field = type->fields;\n    ctx->head->parent_offset = 0;\n    type = type->fields->type;\n  }\n}\nstatic int __Pyx_BufFmt_ParseNumber(const char** ts) {\n    int count;\n    const char* t = *ts;\n    if (*t < '0' || *t > '9') {\n      return -1;\n    } else {\n        count = *t++ - '0';\n        while (*t >= '0' && *t < '9') {\n            count *= 10;\n            count += *t++ - '0';\n        }\n    }\n    *ts = t;\n    return count;\n}\nstatic int __Pyx_BufFmt_ExpectNumber(const char **ts) {\n    int number = __Pyx_BufFmt_ParseNumber(ts);\n    if (number == -1) /* First char was not a digit */\n        PyErr_Format(PyExc_ValueError,\\\n                     \"Does not understand character buffer dtype format string ('%c')\", **ts);\n    return number;\n}\nstatic void __Pyx_BufFmt_RaiseUnexpectedChar(char ch) {\n  PyErr_Format(PyExc_ValueError,\n               \"Unexpected format string character: '%c'\", ch);\n}\nstatic const char* __Pyx_BufFmt_DescribeTypeChar(char ch, int is_complex) {\n  switch (ch) {\n    case 'c': return \"'char'\";\n    case 'b': return \"'signed char'\";\n    case 'B': return \"'unsigned char'\";\n    case 'h': return \"'short'\";\n    case 'H': return \"'unsigned short'\";\n    case 'i': return \"'int'\";\n    case 'I': return \"'unsigned int'\";\n    case 'l': return \"'long'\";\n    case 'L': return \"'unsigned long'\";\n    case 'q': return \"'long long'\";\n    case 'Q': return \"'unsigned long long'\";\n    case 'f': return (is_complex ? \"'complex float'\" : \"'float'\");\n    case 'd': return (is_complex ? \"'complex double'\" : \"'double'\");\n    case 'g': return (is_complex ? \"'complex long double'\" : \"'long double'\");\n    case 'T': return \"a struct\";\n    case 'O': return \"Python object\";\n    case 'P': return \"a pointer\";\n    case 's': case 'p': return \"a string\";\n    case 0: return \"end\";\n    default: return \"unparseable format string\";\n  }\n}\nstatic size_t __Pyx_BufFmt_TypeCharToStandardSize(char ch, int is_complex) {\n  switch (ch) {\n    case '?': case 'c': case 'b': case 'B': case 's': case 'p': return 1;\n    case 'h': case 'H': return 2;\n    case 'i': case 'I': case 'l': case 'L': return 4;\n    case 'q': case 'Q': return 8;\n    case 'f': return (is_complex ? 8 : 4);\n    case 'd': return (is_complex ? 16 : 8);\n    case 'g': {\n      PyErr_SetString(PyExc_ValueError, \"Python does not define a standard format string size for long double ('g')..\");\n      return 0;\n    }\n    case 'O': case 'P': return sizeof(void*);\n    default:\n      __Pyx_BufFmt_RaiseUnexpectedChar(ch);\n      return 0;\n    }\n}\nstatic size_t __Pyx_BufFmt_TypeCharToNativeSize(char ch, int is_complex) {\n  switch (ch) {\n    case 'c': case 'b': case 'B': case 's': case 'p': return 1;\n    case 'h': case 'H': return sizeof(short);\n    case 'i': case 'I': return sizeof(int);\n    case 'l': case 'L': return sizeof(long);\n    #ifdef HAVE_LONG_LONG\n    case 'q': case 'Q': return sizeof(PY_LONG_LONG);\n    #endif\n    case 'f': return sizeof(float) * (is_complex ? 2 : 1);\n    case 'd': return sizeof(double) * (is_complex ? 2 : 1);\n    case 'g': return sizeof(long double) * (is_complex ? 2 : 1);\n    case 'O': case 'P': return sizeof(void*);\n    default: {\n      __Pyx_BufFmt_RaiseUnexpectedChar(ch);\n      return 0;\n    }\n  }\n}\ntypedef struct { char c; short x; } __Pyx_st_short;\ntypedef struct { char c; int x; } __Pyx_st_int;\ntypedef struct { char c; long x; } __Pyx_st_long;\ntypedef struct { char c; float x; } __Pyx_st_float;\ntypedef struct { char c; double x; } __Pyx_st_double;\ntypedef struct { char c; long double x; } __Pyx_st_longdouble;\ntypedef struct { char c; void *x; } __Pyx_st_void_p;\n#ifdef HAVE_LONG_LONG\ntypedef struct { char c; PY_LONG_LONG x; } __Pyx_st_longlong;\n#endif\nstatic size_t __Pyx_BufFmt_TypeCharToAlignment(char ch, CYTHON_UNUSED int is_complex) {\n  switch (ch) {\n    case '?': case 'c': case 'b': case 'B': case 's': case 'p': return 1;\n    case 'h': case 'H': return sizeof(__Pyx_st_short) - sizeof(short);\n    case 'i': case 'I': return sizeof(__Pyx_st_int) - sizeof(int);\n    case 'l': case 'L': return sizeof(__Pyx_st_long) - sizeof(long);\n#ifdef HAVE_LONG_LONG\n    case 'q': case 'Q': return sizeof(__Pyx_st_longlong) - sizeof(PY_LONG_LONG);\n#endif\n    case 'f': return sizeof(__Pyx_st_float) - sizeof(float);\n    case 'd': return sizeof(__Pyx_st_double) - sizeof(double);\n    case 'g': return sizeof(__Pyx_st_longdouble) - sizeof(long double);\n    case 'P': case 'O': return sizeof(__Pyx_st_void_p) - sizeof(void*);\n    default:\n      __Pyx_BufFmt_RaiseUnexpectedChar(ch);\n      return 0;\n    }\n}\n/* These are for computing the padding at the end of the struct to align\n   on the first member of the struct. This will probably the same as above,\n   but we don't have any guarantees.\n */\ntypedef struct { short x; char c; } __Pyx_pad_short;\ntypedef struct { int x; char c; } __Pyx_pad_int;\ntypedef struct { long x; char c; } __Pyx_pad_long;\ntypedef struct { float x; char c; } __Pyx_pad_float;\ntypedef struct { double x; char c; } __Pyx_pad_double;\ntypedef struct { long double x; char c; } __Pyx_pad_longdouble;\ntypedef struct { void *x; char c; } __Pyx_pad_void_p;\n#ifdef HAVE_LONG_LONG\ntypedef struct { PY_LONG_LONG x; char c; } __Pyx_pad_longlong;\n#endif\nstatic size_t __Pyx_BufFmt_TypeCharToPadding(char ch, CYTHON_UNUSED int is_complex) {\n  switch (ch) {\n    case '?': case 'c': case 'b': case 'B': case 's': case 'p': return 1;\n    case 'h': case 'H': return sizeof(__Pyx_pad_short) - sizeof(short);\n    case 'i': case 'I': return sizeof(__Pyx_pad_int) - sizeof(int);\n    case 'l': case 'L': return sizeof(__Pyx_pad_long) - sizeof(long);\n#ifdef HAVE_LONG_LONG\n    case 'q': case 'Q': return sizeof(__Pyx_pad_longlong) - sizeof(PY_LONG_LONG);\n#endif\n    case 'f': return sizeof(__Pyx_pad_float) - sizeof(float);\n    case 'd': return sizeof(__Pyx_pad_double) - sizeof(double);\n    case 'g': return sizeof(__Pyx_pad_longdouble) - sizeof(long double);\n    case 'P': case 'O': return sizeof(__Pyx_pad_void_p) - sizeof(void*);\n    default:\n      __Pyx_BufFmt_RaiseUnexpectedChar(ch);\n      return 0;\n    }\n}\nstatic char __Pyx_BufFmt_TypeCharToGroup(char ch, int is_complex) {\n  switch (ch) {\n    case 'c':\n        return 'H';\n    case 'b': case 'h': case 'i':\n    case 'l': case 'q': case 's': case 'p':\n        return 'I';\n    case 'B': case 'H': case 'I': case 'L': case 'Q':\n        return 'U';\n    case 'f': case 'd': case 'g':\n        return (is_complex ? 'C' : 'R');\n    case 'O':\n        return 'O';\n    case 'P':\n        return 'P';\n    default: {\n      __Pyx_BufFmt_RaiseUnexpectedChar(ch);\n      return 0;\n    }\n  }\n}\nstatic void __Pyx_BufFmt_RaiseExpected(__Pyx_BufFmt_Context* ctx) {\n  if (ctx->head == NULL || ctx->head->field == &ctx->root) {\n    const char* expected;\n    const char* quote;\n    if (ctx->head == NULL) {\n      expected = \"end\";\n      quote = \"\";\n    } else {\n      expected = ctx->head->field->type->name;\n      quote = \"'\";\n    }\n    PyErr_Format(PyExc_ValueError,\n                 \"Buffer dtype mismatch, expected %s%s%s but got %s\",\n                 quote, expected, quote,\n                 __Pyx_BufFmt_DescribeTypeChar(ctx->enc_type, ctx->is_complex));\n  } else {\n    __Pyx_StructField* field = ctx->head->field;\n    __Pyx_StructField* parent = (ctx->head - 1)->field;\n    PyErr_Format(PyExc_ValueError,\n                 \"Buffer dtype mismatch, expected '%s' but got %s in '%s.%s'\",\n                 field->type->name, __Pyx_BufFmt_DescribeTypeChar(ctx->enc_type, ctx->is_complex),\n                 parent->type->name, field->name);\n  }\n}\nstatic int __Pyx_BufFmt_ProcessTypeChunk(__Pyx_BufFmt_Context* ctx) {\n  char group;\n  size_t size, offset, arraysize = 1;\n  if (ctx->enc_type == 0) return 0;\n  if (ctx->head->field->type->arraysize[0]) {\n    int i, ndim = 0;\n    if (ctx->enc_type == 's' || ctx->enc_type == 'p') {\n        ctx->is_valid_array = ctx->head->field->type->ndim == 1;\n        ndim = 1;\n        if (ctx->enc_count != ctx->head->field->type->arraysize[0]) {\n            PyErr_Format(PyExc_ValueError,\n                         \"Expected a dimension of size %zu, got %zu\",\n                         ctx->head->field->type->arraysize[0], ctx->enc_count);\n            return -1;\n        }\n    }\n    if (!ctx->is_valid_array) {\n      PyErr_Format(PyExc_ValueError, \"Expected %d dimensions, got %d\",\n                   ctx->head->field->type->ndim, ndim);\n      return -1;\n    }\n    for (i = 0; i < ctx->head->field->type->ndim; i++) {\n      arraysize *= ctx->head->field->type->arraysize[i];\n    }\n    ctx->is_valid_array = 0;\n    ctx->enc_count = 1;\n  }\n  group = __Pyx_BufFmt_TypeCharToGroup(ctx->enc_type, ctx->is_complex);\n  do {\n    __Pyx_StructField* field = ctx->head->field;\n    __Pyx_TypeInfo* type = field->type;\n    if (ctx->enc_packmode == '@' || ctx->enc_packmode == '^') {\n      size = __Pyx_BufFmt_TypeCharToNativeSize(ctx->enc_type, ctx->is_complex);\n    } else {\n      size = __Pyx_BufFmt_TypeCharToStandardSize(ctx->enc_type, ctx->is_complex);\n    }\n    if (ctx->enc_packmode == '@') {\n      size_t align_at = __Pyx_BufFmt_TypeCharToAlignment(ctx->enc_type, ctx->is_complex);\n      size_t align_mod_offset;\n      if (align_at == 0) return -1;\n      align_mod_offset = ctx->fmt_offset % align_at;\n      if (align_mod_offset > 0) ctx->fmt_offset += align_at - align_mod_offset;\n      if (ctx->struct_alignment == 0)\n          ctx->struct_alignment = __Pyx_BufFmt_TypeCharToPadding(ctx->enc_type,\n                                                                 ctx->is_complex);\n    }\n    if (type->size != size || type->typegroup != group) {\n      if (type->typegroup == 'C' && type->fields != NULL) {\n        size_t parent_offset = ctx->head->parent_offset + field->offset;\n        ++ctx->head;\n        ctx->head->field = type->fields;\n        ctx->head->parent_offset = parent_offset;\n        continue;\n      }\n      if ((type->typegroup == 'H' || group == 'H') && type->size == size) {\n      } else {\n          __Pyx_BufFmt_RaiseExpected(ctx);\n          return -1;\n      }\n    }\n    offset = ctx->head->parent_offset + field->offset;\n    if (ctx->fmt_offset != offset) {\n      PyErr_Format(PyExc_ValueError,\n                   \"Buffer dtype mismatch; next field is at offset %\" CYTHON_FORMAT_SSIZE_T \"d but %\" CYTHON_FORMAT_SSIZE_T \"d expected\",\n                   (Py_ssize_t)ctx->fmt_offset, (Py_ssize_t)offset);\n      return -1;\n    }\n    ctx->fmt_offset += size;\n    if (arraysize)\n      ctx->fmt_offset += (arraysize - 1) * size;\n    --ctx->enc_count; /* Consume from buffer string */\n    while (1) {\n      if (field == &ctx->root) {\n        ctx->head = NULL;\n        if (ctx->enc_count != 0) {\n          __Pyx_BufFmt_RaiseExpected(ctx);\n          return -1;\n        }\n        break; /* breaks both loops as ctx->enc_count == 0 */\n      }\n      ctx->head->field = ++field;\n      if (field->type == NULL) {\n        --ctx->head;\n        field = ctx->head->field;\n        continue;\n      } else if (field->type->typegroup == 'S') {\n        size_t parent_offset = ctx->head->parent_offset + field->offset;\n        if (field->type->fields->type == NULL) continue; /* empty struct */\n        field = field->type->fields;\n        ++ctx->head;\n        ctx->head->field = field;\n        ctx->head->parent_offset = parent_offset;\n        break;\n      } else {\n        break;\n      }\n    }\n  } while (ctx->enc_count);\n  ctx->enc_type = 0;\n  ctx->is_complex = 0;\n  return 0;\n}\nstatic CYTHON_INLINE PyObject *\n__pyx_buffmt_parse_array(__Pyx_BufFmt_Context* ctx, const char** tsp)\n{\n    const char *ts = *tsp;\n    int i = 0, number;\n    int ndim = ctx->head->field->type->ndim;\n;\n    ++ts;\n    if (ctx->new_count != 1) {\n        PyErr_SetString(PyExc_ValueError,\n                        \"Cannot handle repeated arrays in format string\");\n        return NULL;\n    }\n    if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL;\n    while (*ts && *ts != ')') {\n        switch (*ts) {\n            case ' ': case '\\f': case '\\r': case '\\n': case '\\t': case '\\v':  continue;\n            default:  break;  /* not a 'break' in the loop */\n        }\n        number = __Pyx_BufFmt_ExpectNumber(&ts);\n        if (number == -1) return NULL;\n        if (i < ndim && (size_t) number != ctx->head->field->type->arraysize[i])\n            return PyErr_Format(PyExc_ValueError,\n                        \"Expected a dimension of size %zu, got %d\",\n                        ctx->head->field->type->arraysize[i], number);\n        if (*ts != ',' && *ts != ')')\n            return PyErr_Format(PyExc_ValueError,\n                                \"Expected a comma in format string, got '%c'\", *ts);\n        if (*ts == ',') ts++;\n        i++;\n    }\n    if (i != ndim)\n        return PyErr_Format(PyExc_ValueError, \"Expected %d dimension(s), got %d\",\n                            ctx->head->field->type->ndim, i);\n    if (!*ts) {\n        PyErr_SetString(PyExc_ValueError,\n                        \"Unexpected end of format string, expected ')'\");\n        return NULL;\n    }\n    ctx->is_valid_array = 1;\n    ctx->new_count = 1;\n    *tsp = ++ts;\n    return Py_None;\n}\nstatic const char* __Pyx_BufFmt_CheckString(__Pyx_BufFmt_Context* ctx, const char* ts) {\n  int got_Z = 0;\n  while (1) {\n    switch(*ts) {\n      case 0:\n        if (ctx->enc_type != 0 && ctx->head == NULL) {\n          __Pyx_BufFmt_RaiseExpected(ctx);\n          return NULL;\n        }\n        if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL;\n        if (ctx->head != NULL) {\n          __Pyx_BufFmt_RaiseExpected(ctx);\n          return NULL;\n        }\n                return ts;\n      case ' ':\n      case 10:\n      case 13:\n        ++ts;\n        break;\n      case '<':\n        if (!__Pyx_IsLittleEndian()) {\n          PyErr_SetString(PyExc_ValueError, \"Little-endian buffer not supported on big-endian compiler\");\n          return NULL;\n        }\n        ctx->new_packmode = '=';\n        ++ts;\n        break;\n      case '>':\n      case '!':\n        if (__Pyx_IsLittleEndian()) {\n          PyErr_SetString(PyExc_ValueError, \"Big-endian buffer not supported on little-endian compiler\");\n          return NULL;\n        }\n        ctx->new_packmode = '=';\n        ++ts;\n        break;\n      case '=':\n      case '@':\n      case '^':\n        ctx->new_packmode = *ts++;\n        break;\n      case 'T': /* substruct */\n        {\n          const char* ts_after_sub;\n          size_t i, struct_count = ctx->new_count;\n          size_t struct_alignment = ctx->struct_alignment;\n          ctx->new_count = 1;\n          ++ts;\n          if (*ts != '{') {\n            PyErr_SetString(PyExc_ValueError, \"Buffer acquisition: Expected '{' after 'T'\");\n            return NULL;\n          }\n          if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL;\n          ctx->enc_type = 0; /* Erase processed last struct element */\n          ctx->enc_count = 0;\n          ctx->struct_alignment = 0;\n          ++ts;\n          ts_after_sub = ts;\n          for (i = 0; i != struct_count; ++i) {\n            ts_after_sub = __Pyx_BufFmt_CheckString(ctx, ts);\n            if (!ts_after_sub) return NULL;\n          }\n          ts = ts_after_sub;\n          if (struct_alignment) ctx->struct_alignment = struct_alignment;\n        }\n        break;\n      case '}': /* end of substruct; either repeat or move on */\n        {\n          size_t alignment = ctx->struct_alignment;\n          ++ts;\n          if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL;\n          ctx->enc_type = 0; /* Erase processed last struct element */\n          if (alignment && ctx->fmt_offset % alignment) {\n            ctx->fmt_offset += alignment - (ctx->fmt_offset % alignment);\n          }\n        }\n        return ts;\n      case 'x':\n        if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL;\n        ctx->fmt_offset += ctx->new_count;\n        ctx->new_count = 1;\n        ctx->enc_count = 0;\n        ctx->enc_type = 0;\n        ctx->enc_packmode = ctx->new_packmode;\n        ++ts;\n        break;\n      case 'Z':\n        got_Z = 1;\n        ++ts;\n        if (*ts != 'f' && *ts != 'd' && *ts != 'g') {\n          __Pyx_BufFmt_RaiseUnexpectedChar('Z');\n          return NULL;\n        }        /* fall through */\n      case 'c': case 'b': case 'B': case 'h': case 'H': case 'i': case 'I':\n      case 'l': case 'L': case 'q': case 'Q':\n      case 'f': case 'd': case 'g':\n      case 'O': case 's': case 'p':\n        if (ctx->enc_type == *ts && got_Z == ctx->is_complex &&\n            ctx->enc_packmode == ctx->new_packmode) {\n          ctx->enc_count += ctx->new_count;\n        } else {\n          if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL;\n          ctx->enc_count = ctx->new_count;\n          ctx->enc_packmode = ctx->new_packmode;\n          ctx->enc_type = *ts;\n          ctx->is_complex = got_Z;\n        }\n        ++ts;\n        ctx->new_count = 1;\n        got_Z = 0;\n        break;\n      case ':':\n        ++ts;\n        while(*ts != ':') ++ts;\n        ++ts;\n        break;\n      case '(':\n        if (!__pyx_buffmt_parse_array(ctx, &ts)) return NULL;\n        break;\n      default:\n        {\n          int number = __Pyx_BufFmt_ExpectNumber(&ts);\n          if (number == -1) return NULL;\n          ctx->new_count = (size_t)number;\n        }\n    }\n  }\n}\nstatic CYTHON_INLINE void __Pyx_ZeroBuffer(Py_buffer* buf) {\n  buf->buf = NULL;\n  buf->obj = NULL;\n  buf->strides = __Pyx_zeros;\n  buf->shape = __Pyx_zeros;\n  buf->suboffsets = __Pyx_minusones;\n}\nstatic CYTHON_INLINE int __Pyx_GetBufferAndValidate(\n        Py_buffer* buf, PyObject* obj,  __Pyx_TypeInfo* dtype, int flags,\n        int nd, int cast, __Pyx_BufFmt_StackElem* stack)\n{\n  if (obj == Py_None || obj == NULL) {\n    __Pyx_ZeroBuffer(buf);\n    return 0;\n  }\n  buf->buf = NULL;\n  if (__Pyx_GetBuffer(obj, buf, flags) == -1) goto fail;\n  if (buf->ndim != nd) {\n    PyErr_Format(PyExc_ValueError,\n                 \"Buffer has wrong number of dimensions (expected %d, got %d)\",\n                 nd, buf->ndim);\n    goto fail;\n  }\n  if (!cast) {\n    __Pyx_BufFmt_Context ctx;\n    __Pyx_BufFmt_Init(&ctx, stack, dtype);\n    if (!__Pyx_BufFmt_CheckString(&ctx, buf->format)) goto fail;\n  }\n  if ((unsigned)buf->itemsize != dtype->size) {\n    PyErr_Format(PyExc_ValueError,\n      \"Item size of buffer (%\" CYTHON_FORMAT_SSIZE_T \"d byte%s) does not match size of '%s' (%\" CYTHON_FORMAT_SSIZE_T \"d byte%s)\",\n      buf->itemsize, (buf->itemsize > 1) ? \"s\" : \"\",\n      dtype->name, (Py_ssize_t)dtype->size, (dtype->size > 1) ? \"s\" : \"\");\n    goto fail;\n  }\n  if (buf->suboffsets == NULL) buf->suboffsets = __Pyx_minusones;\n  return 0;\nfail:;\n  __Pyx_ZeroBuffer(buf);\n  return -1;\n}\nstatic CYTHON_INLINE void __Pyx_SafeReleaseBuffer(Py_buffer* info) {\n  if (info->buf == NULL) return;\n  if (info->suboffsets == __Pyx_minusones) info->suboffsets = NULL;\n  __Pyx_ReleaseBuffer(info);\n}\n\nstatic CYTHON_INLINE int __Pyx_TypeTest(PyObject *obj, PyTypeObject *type) {\n    if (unlikely(!type)) {\n        PyErr_SetString(PyExc_SystemError, \"Missing type object\");\n        return 0;\n    }\n    if (likely(PyObject_TypeCheck(obj, type)))\n        return 1;\n    PyErr_Format(PyExc_TypeError, \"Cannot convert %.200s to %.200s\",\n                 Py_TYPE(obj)->tp_name, type->tp_name);\n    return 0;\n}\n\n#if CYTHON_COMPILING_IN_CPYTHON\nstatic CYTHON_INLINE PyObject* __Pyx_PyObject_Call(PyObject *func, PyObject *arg, PyObject *kw) {\n    PyObject *result;\n    ternaryfunc call = func->ob_type->tp_call;\n    if (unlikely(!call))\n        return PyObject_Call(func, arg, kw);\n#if PY_VERSION_HEX >= 0x02060000\n    if (unlikely(Py_EnterRecursiveCall((char*)\" while calling a Python object\")))\n        return NULL;\n#endif\n    result = (*call)(func, arg, kw);\n#if PY_VERSION_HEX >= 0x02060000\n    Py_LeaveRecursiveCall();\n#endif\n    if (unlikely(!result) && unlikely(!PyErr_Occurred())) {\n        PyErr_SetString(\n            PyExc_SystemError,\n            \"NULL result without error in PyObject_Call\");\n    }\n    return result;\n}\n#endif\n\nstatic CYTHON_INLINE PyObject *__Pyx_GetModuleGlobalName(PyObject *name) {\n    PyObject *result;\n#if CYTHON_COMPILING_IN_CPYTHON\n    result = PyDict_GetItem(__pyx_d, name);\n    if (result) {\n        Py_INCREF(result);\n    } else {\n#else\n    result = PyObject_GetItem(__pyx_d, name);\n    if (!result) {\n        PyErr_Clear();\n#endif\n        result = __Pyx_GetBuiltinName(name);\n    }\n    return result;\n}\n\nstatic void __Pyx_RaiseBufferIndexError(int axis) {\n  PyErr_Format(PyExc_IndexError,\n     \"Out of bounds on buffer access (axis %d)\", axis);\n}\n\nstatic CYTHON_INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb) {\n#if CYTHON_COMPILING_IN_CPYTHON\n    PyObject *tmp_type, *tmp_value, *tmp_tb;\n    PyThreadState *tstate = PyThreadState_GET();\n    tmp_type = tstate->curexc_type;\n    tmp_value = tstate->curexc_value;\n    tmp_tb = tstate->curexc_traceback;\n    tstate->curexc_type = type;\n    tstate->curexc_value = value;\n    tstate->curexc_traceback = tb;\n    Py_XDECREF(tmp_type);\n    Py_XDECREF(tmp_value);\n    Py_XDECREF(tmp_tb);\n#else\n    PyErr_Restore(type, value, tb);\n#endif\n}\nstatic CYTHON_INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb) {\n#if CYTHON_COMPILING_IN_CPYTHON\n    PyThreadState *tstate = PyThreadState_GET();\n    *type = tstate->curexc_type;\n    *value = tstate->curexc_value;\n    *tb = tstate->curexc_traceback;\n    tstate->curexc_type = 0;\n    tstate->curexc_value = 0;\n    tstate->curexc_traceback = 0;\n#else\n    PyErr_Fetch(type, value, tb);\n#endif\n}\n\n#if PY_MAJOR_VERSION < 3\nstatic void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb,\n                        CYTHON_UNUSED PyObject *cause) {\n    Py_XINCREF(type);\n    if (!value || value == Py_None)\n        value = NULL;\n    else\n        Py_INCREF(value);\n    if (!tb || tb == Py_None)\n        tb = NULL;\n    else {\n        Py_INCREF(tb);\n        if (!PyTraceBack_Check(tb)) {\n            PyErr_SetString(PyExc_TypeError,\n                \"raise: arg 3 must be a traceback or None\");\n            goto raise_error;\n        }\n    }\n    #if PY_VERSION_HEX < 0x02050000\n    if (PyClass_Check(type)) {\n    #else\n    if (PyType_Check(type)) {\n    #endif\n#if CYTHON_COMPILING_IN_PYPY\n        if (!value) {\n            Py_INCREF(Py_None);\n            value = Py_None;\n        }\n#endif\n        PyErr_NormalizeException(&type, &value, &tb);\n    } else {\n        if (value) {\n            PyErr_SetString(PyExc_TypeError,\n                \"instance exception may not have a separate value\");\n            goto raise_error;\n        }\n        value = type;\n        #if PY_VERSION_HEX < 0x02050000\n        if (PyInstance_Check(type)) {\n            type = (PyObject*) ((PyInstanceObject*)type)->in_class;\n            Py_INCREF(type);\n        } else {\n            type = 0;\n            PyErr_SetString(PyExc_TypeError,\n                \"raise: exception must be an old-style class or instance\");\n            goto raise_error;\n        }\n        #else\n        type = (PyObject*) Py_TYPE(type);\n        Py_INCREF(type);\n        if (!PyType_IsSubtype((PyTypeObject *)type, (PyTypeObject *)PyExc_BaseException)) {\n            PyErr_SetString(PyExc_TypeError,\n                \"raise: exception class must be a subclass of BaseException\");\n            goto raise_error;\n        }\n        #endif\n    }\n    __Pyx_ErrRestore(type, value, tb);\n    return;\nraise_error:\n    Py_XDECREF(value);\n    Py_XDECREF(type);\n    Py_XDECREF(tb);\n    return;\n}\n#else /* Python 3+ */\nstatic void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject *cause) {\n    PyObject* owned_instance = NULL;\n    if (tb == Py_None) {\n        tb = 0;\n    } else if (tb && !PyTraceBack_Check(tb)) {\n        PyErr_SetString(PyExc_TypeError,\n            \"raise: arg 3 must be a traceback or None\");\n        goto bad;\n    }\n    if (value == Py_None)\n        value = 0;\n    if (PyExceptionInstance_Check(type)) {\n        if (value) {\n            PyErr_SetString(PyExc_TypeError,\n                \"instance exception may not have a separate value\");\n            goto bad;\n        }\n        value = type;\n        type = (PyObject*) Py_TYPE(value);\n    } else if (PyExceptionClass_Check(type)) {\n        PyObject *instance_class = NULL;\n        if (value && PyExceptionInstance_Check(value)) {\n            instance_class = (PyObject*) Py_TYPE(value);\n            if (instance_class != type) {\n                if (PyObject_IsSubclass(instance_class, type)) {\n                    type = instance_class;\n                } else {\n                    instance_class = NULL;\n                }\n            }\n        }\n        if (!instance_class) {\n            PyObject *args;\n            if (!value)\n                args = PyTuple_New(0);\n            else if (PyTuple_Check(value)) {\n                Py_INCREF(value);\n                args = value;\n            } else\n                args = PyTuple_Pack(1, value);\n            if (!args)\n                goto bad;\n            owned_instance = PyObject_Call(type, args, NULL);\n            Py_DECREF(args);\n            if (!owned_instance)\n                goto bad;\n            value = owned_instance;\n            if (!PyExceptionInstance_Check(value)) {\n                PyErr_Format(PyExc_TypeError,\n                             \"calling %R should have returned an instance of \"\n                             \"BaseException, not %R\",\n                             type, Py_TYPE(value));\n                goto bad;\n            }\n        }\n    } else {\n        PyErr_SetString(PyExc_TypeError,\n            \"raise: exception class must be a subclass of BaseException\");\n        goto bad;\n    }\n#if PY_VERSION_HEX >= 0x03030000\n    if (cause) {\n#else\n    if (cause && cause != Py_None) {\n#endif\n        PyObject *fixed_cause;\n        if (cause == Py_None) {\n            fixed_cause = NULL;\n        } else if (PyExceptionClass_Check(cause)) {\n            fixed_cause = PyObject_CallObject(cause, NULL);\n            if (fixed_cause == NULL)\n                goto bad;\n        } else if (PyExceptionInstance_Check(cause)) {\n            fixed_cause = cause;\n            Py_INCREF(fixed_cause);\n        } else {\n            PyErr_SetString(PyExc_TypeError,\n                            \"exception causes must derive from \"\n                            \"BaseException\");\n            goto bad;\n        }\n        PyException_SetCause(value, fixed_cause);\n    }\n    PyErr_SetObject(type, value);\n    if (tb) {\n        PyThreadState *tstate = PyThreadState_GET();\n        PyObject* tmp_tb = tstate->curexc_traceback;\n        if (tb != tmp_tb) {\n            Py_INCREF(tb);\n            tstate->curexc_traceback = tb;\n            Py_XDECREF(tmp_tb);\n        }\n    }\nbad:\n    Py_XDECREF(owned_instance);\n    return;\n}\n#endif\n\nstatic CYTHON_INLINE void __Pyx_RaiseTooManyValuesError(Py_ssize_t expected) {\n    PyErr_Format(PyExc_ValueError,\n                 \"too many values to unpack (expected %\" CYTHON_FORMAT_SSIZE_T \"d)\", expected);\n}\n\nstatic CYTHON_INLINE void __Pyx_RaiseNeedMoreValuesError(Py_ssize_t index) {\n    PyErr_Format(PyExc_ValueError,\n                 \"need more than %\" CYTHON_FORMAT_SSIZE_T \"d value%.1s to unpack\",\n                 index, (index == 1) ? \"\" : \"s\");\n}\n\nstatic CYTHON_INLINE void __Pyx_RaiseNoneNotIterableError(void) {\n    PyErr_SetString(PyExc_TypeError, \"'NoneType' object is not iterable\");\n}\n\n#if PY_MAJOR_VERSION < 3\nstatic int __Pyx_GetBuffer(PyObject *obj, Py_buffer *view, int flags) {\n  #if PY_VERSION_HEX >= 0x02060000\n    if (PyObject_CheckBuffer(obj)) return PyObject_GetBuffer(obj, view, flags);\n  #endif\n        if (PyObject_TypeCheck(obj, __pyx_ptype_5numpy_ndarray)) return __pyx_pw_5numpy_7ndarray_1__getbuffer__(obj, view, flags);\n  #if PY_VERSION_HEX < 0x02060000\n    if (obj->ob_type->tp_dict) {\n        PyObject *getbuffer_cobj = PyObject_GetItem(\n            obj->ob_type->tp_dict, __pyx_n_s_pyx_getbuffer);\n        if (getbuffer_cobj) {\n            getbufferproc func = (getbufferproc) PyCObject_AsVoidPtr(getbuffer_cobj);\n            Py_DECREF(getbuffer_cobj);\n            if (!func)\n                goto fail;\n            return func(obj, view, flags);\n        } else {\n            PyErr_Clear();\n        }\n    }\n  #endif\n    PyErr_Format(PyExc_TypeError, \"'%.200s' does not have the buffer interface\", Py_TYPE(obj)->tp_name);\n#if PY_VERSION_HEX < 0x02060000\nfail:\n#endif\n    return -1;\n}\nstatic void __Pyx_ReleaseBuffer(Py_buffer *view) {\n    PyObject *obj = view->obj;\n    if (!obj) return;\n  #if PY_VERSION_HEX >= 0x02060000\n    if (PyObject_CheckBuffer(obj)) {\n        PyBuffer_Release(view);\n        return;\n    }\n  #endif\n        if (PyObject_TypeCheck(obj, __pyx_ptype_5numpy_ndarray)) { __pyx_pw_5numpy_7ndarray_3__releasebuffer__(obj, view); return; }\n  #if PY_VERSION_HEX < 0x02060000\n    if (obj->ob_type->tp_dict) {\n        PyObject *releasebuffer_cobj = PyObject_GetItem(\n            obj->ob_type->tp_dict, __pyx_n_s_pyx_releasebuffer);\n        if (releasebuffer_cobj) {\n            releasebufferproc func = (releasebufferproc) PyCObject_AsVoidPtr(releasebuffer_cobj);\n            Py_DECREF(releasebuffer_cobj);\n            if (!func)\n                goto fail;\n            func(obj, view);\n            return;\n        } else {\n            PyErr_Clear();\n        }\n    }\n  #endif\n    goto nofail;\n#if PY_VERSION_HEX < 0x02060000\nfail:\n#endif\n    PyErr_WriteUnraisable(obj);\nnofail:\n    Py_DECREF(obj);\n    view->obj = NULL;\n}\n#endif /*  PY_MAJOR_VERSION < 3 */\n\n\n        static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list, int level) {\n    PyObject *empty_list = 0;\n    PyObject *module = 0;\n    PyObject *global_dict = 0;\n    PyObject *empty_dict = 0;\n    PyObject *list;\n    #if PY_VERSION_HEX < 0x03030000\n    PyObject *py_import;\n    py_import = __Pyx_PyObject_GetAttrStr(__pyx_b, __pyx_n_s_import);\n    if (!py_import)\n        goto bad;\n    #endif\n    if (from_list)\n        list = from_list;\n    else {\n        empty_list = PyList_New(0);\n        if (!empty_list)\n            goto bad;\n        list = empty_list;\n    }\n    global_dict = PyModule_GetDict(__pyx_m);\n    if (!global_dict)\n        goto bad;\n    empty_dict = PyDict_New();\n    if (!empty_dict)\n        goto bad;\n    #if PY_VERSION_HEX >= 0x02050000\n    {\n        #if PY_MAJOR_VERSION >= 3\n        if (level == -1) {\n            if (strchr(__Pyx_MODULE_NAME, '.')) {\n                #if PY_VERSION_HEX < 0x03030000\n                PyObject *py_level = PyInt_FromLong(1);\n                if (!py_level)\n                    goto bad;\n                module = PyObject_CallFunctionObjArgs(py_import,\n                    name, global_dict, empty_dict, list, py_level, NULL);\n                Py_DECREF(py_level);\n                #else\n                module = PyImport_ImportModuleLevelObject(\n                    name, global_dict, empty_dict, list, 1);\n                #endif\n                if (!module) {\n                    if (!PyErr_ExceptionMatches(PyExc_ImportError))\n                        goto bad;\n                    PyErr_Clear();\n                }\n            }\n            level = 0; /* try absolute import on failure */\n        }\n        #endif\n        if (!module) {\n            #if PY_VERSION_HEX < 0x03030000\n            PyObject *py_level = PyInt_FromLong(level);\n            if (!py_level)\n                goto bad;\n            module = PyObject_CallFunctionObjArgs(py_import,\n                name, global_dict, empty_dict, list, py_level, NULL);\n            Py_DECREF(py_level);\n            #else\n            module = PyImport_ImportModuleLevelObject(\n                name, global_dict, empty_dict, list, level);\n            #endif\n        }\n    }\n    #else\n    if (level>0) {\n        PyErr_SetString(PyExc_RuntimeError, \"Relative import is not supported for Python <=2.4.\");\n        goto bad;\n    }\n    module = PyObject_CallFunctionObjArgs(py_import,\n        name, global_dict, empty_dict, list, NULL);\n    #endif\nbad:\n    #if PY_VERSION_HEX < 0x03030000\n    Py_XDECREF(py_import);\n    #endif\n    Py_XDECREF(empty_list);\n    Py_XDECREF(empty_dict);\n    return module;\n}\n\nstatic CYTHON_INLINE PyObject* __Pyx_PyInt_From_int(int value) {\n    const int neg_one = (int) -1, const_zero = 0;\n    const int is_unsigned = neg_one > const_zero;\n    if (is_unsigned) {\n        if (sizeof(int) < sizeof(long)) {\n            return PyInt_FromLong((long) value);\n        } else if (sizeof(int) <= sizeof(unsigned long)) {\n            return PyLong_FromUnsignedLong((unsigned long) value);\n        } else if (sizeof(int) <= sizeof(unsigned long long)) {\n            return PyLong_FromUnsignedLongLong((unsigned long long) value);\n        }\n    } else {\n        if (sizeof(int) <= sizeof(long)) {\n            return PyInt_FromLong((long) value);\n        } else if (sizeof(int) <= sizeof(long long)) {\n            return PyLong_FromLongLong((long long) value);\n        }\n    }\n    {\n        int one = 1; int little = (int)*(unsigned char *)&one;\n        unsigned char *bytes = (unsigned char *)&value;\n        return _PyLong_FromByteArray(bytes, sizeof(int),\n                                     little, !is_unsigned);\n    }\n}\n\n#define __PYX_VERIFY_RETURN_INT(target_type, func_type, func)             \\\n    {                                                                     \\\n        func_type value = func(x);                                        \\\n        if (sizeof(target_type) < sizeof(func_type)) {                    \\\n            if (unlikely(value != (func_type) (target_type) value)) {     \\\n                func_type zero = 0;                                       \\\n                PyErr_SetString(PyExc_OverflowError,                      \\\n                    (is_unsigned && unlikely(value < zero)) ?             \\\n                    \"can't convert negative value to \" #target_type :     \\\n                    \"value too large to convert to \" #target_type);       \\\n                return (target_type) -1;                                  \\\n            }                                                             \\\n        }                                                                 \\\n        return (target_type) value;                                       \\\n    }\n\n#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3\n #if CYTHON_USE_PYLONG_INTERNALS\n  #include \"longintrepr.h\"\n #endif\n#endif\nstatic CYTHON_INLINE int __Pyx_PyInt_As_int(PyObject *x) {\n    const int neg_one = (int) -1, const_zero = 0;\n    const int is_unsigned = neg_one > const_zero;\n#if PY_MAJOR_VERSION < 3\n    if (likely(PyInt_Check(x))) {\n        if (sizeof(int) < sizeof(long)) {\n            __PYX_VERIFY_RETURN_INT(int, long, PyInt_AS_LONG)\n        } else {\n            long val = PyInt_AS_LONG(x);\n            if (is_unsigned && unlikely(val < 0)) {\n                PyErr_SetString(PyExc_OverflowError,\n                                \"can't convert negative value to int\");\n                return (int) -1;\n            }\n            return (int) val;\n        }\n    } else\n#endif\n    if (likely(PyLong_Check(x))) {\n        if (is_unsigned) {\n#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3\n #if CYTHON_USE_PYLONG_INTERNALS\n            if (sizeof(digit) <= sizeof(int)) {\n                switch (Py_SIZE(x)) {\n                    case  0: return 0;\n                    case  1: return (int) ((PyLongObject*)x)->ob_digit[0];\n                }\n            }\n #endif\n#endif\n            if (unlikely(Py_SIZE(x) < 0)) {\n                PyErr_SetString(PyExc_OverflowError,\n                                \"can't convert negative value to int\");\n                return (int) -1;\n            }\n            if (sizeof(int) <= sizeof(unsigned long)) {\n                __PYX_VERIFY_RETURN_INT(int, unsigned long, PyLong_AsUnsignedLong)\n            } else if (sizeof(int) <= sizeof(unsigned long long)) {\n                __PYX_VERIFY_RETURN_INT(int, unsigned long long, PyLong_AsUnsignedLongLong)\n            }\n        } else {\n#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3\n #if CYTHON_USE_PYLONG_INTERNALS\n            if (sizeof(digit) <= sizeof(int)) {\n                switch (Py_SIZE(x)) {\n                    case  0: return 0;\n                    case  1: return +(int) ((PyLongObject*)x)->ob_digit[0];\n                    case -1: return -(int) ((PyLongObject*)x)->ob_digit[0];\n                }\n            }\n #endif\n#endif\n            if (sizeof(int) <= sizeof(long)) {\n                __PYX_VERIFY_RETURN_INT(int, long, PyLong_AsLong)\n            } else if (sizeof(int) <= sizeof(long long)) {\n                __PYX_VERIFY_RETURN_INT(int, long long, PyLong_AsLongLong)\n            }\n        }\n        {\n#if CYTHON_COMPILING_IN_PYPY && !defined(_PyLong_AsByteArray)\n            PyErr_SetString(PyExc_RuntimeError,\n                            \"_PyLong_AsByteArray() not available in PyPy, cannot convert large numbers\");\n#else\n            int val;\n            PyObject *v = __Pyx_PyNumber_Int(x);\n #if PY_MAJOR_VERSION < 3\n            if (likely(v) && !PyLong_Check(v)) {\n                PyObject *tmp = v;\n                v = PyNumber_Long(tmp);\n                Py_DECREF(tmp);\n            }\n #endif\n            if (likely(v)) {\n                int one = 1; int is_little = (int)*(unsigned char *)&one;\n                unsigned char *bytes = (unsigned char *)&val;\n                int ret = _PyLong_AsByteArray((PyLongObject *)v,\n                                              bytes, sizeof(val),\n                                              is_little, !is_unsigned);\n                Py_DECREF(v);\n                if (likely(!ret))\n                    return val;\n            }\n#endif\n            return (int) -1;\n        }\n    } else {\n        int val;\n        PyObject *tmp = __Pyx_PyNumber_Int(x);\n        if (!tmp) return (int) -1;\n        val = __Pyx_PyInt_As_int(tmp);\n        Py_DECREF(tmp);\n        return val;\n    }\n}\n\nstatic CYTHON_INLINE PyObject* __Pyx_PyInt_From_long(long value) {\n    const long neg_one = (long) -1, const_zero = 0;\n    const int is_unsigned = neg_one > const_zero;\n    if (is_unsigned) {\n        if (sizeof(long) < sizeof(long)) {\n            return PyInt_FromLong((long) value);\n        } else if (sizeof(long) <= sizeof(unsigned long)) {\n            return PyLong_FromUnsignedLong((unsigned long) value);\n        } else if (sizeof(long) <= sizeof(unsigned long long)) {\n            return PyLong_FromUnsignedLongLong((unsigned long long) value);\n        }\n    } else {\n        if (sizeof(long) <= sizeof(long)) {\n            return PyInt_FromLong((long) value);\n        } else if (sizeof(long) <= sizeof(long long)) {\n            return PyLong_FromLongLong((long long) value);\n        }\n    }\n    {\n        int one = 1; int little = (int)*(unsigned char *)&one;\n        unsigned char *bytes = (unsigned char *)&value;\n        return _PyLong_FromByteArray(bytes, sizeof(long),\n                                     little, !is_unsigned);\n    }\n}\n\n#if CYTHON_CCOMPLEX\n  #ifdef __cplusplus\n    static CYTHON_INLINE __pyx_t_float_complex __pyx_t_float_complex_from_parts(float x, float y) {\n      return ::std::complex< float >(x, y);\n    }\n  #else\n    static CYTHON_INLINE __pyx_t_float_complex __pyx_t_float_complex_from_parts(float x, float y) {\n      return x + y*(__pyx_t_float_complex)_Complex_I;\n    }\n  #endif\n#else\n    static CYTHON_INLINE __pyx_t_float_complex __pyx_t_float_complex_from_parts(float x, float y) {\n      __pyx_t_float_complex z;\n      z.real = x;\n      z.imag = y;\n      return z;\n    }\n#endif\n\n#if CYTHON_CCOMPLEX\n#else\n    static CYTHON_INLINE int __Pyx_c_eqf(__pyx_t_float_complex a, __pyx_t_float_complex b) {\n       return (a.real == b.real) && (a.imag == b.imag);\n    }\n    static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_sumf(__pyx_t_float_complex a, __pyx_t_float_complex b) {\n        __pyx_t_float_complex z;\n        z.real = a.real + b.real;\n        z.imag = a.imag + b.imag;\n        return z;\n    }\n    static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_difff(__pyx_t_float_complex a, __pyx_t_float_complex b) {\n        __pyx_t_float_complex z;\n        z.real = a.real - b.real;\n        z.imag = a.imag - b.imag;\n        return z;\n    }\n    static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_prodf(__pyx_t_float_complex a, __pyx_t_float_complex b) {\n        __pyx_t_float_complex z;\n        z.real = a.real * b.real - a.imag * b.imag;\n        z.imag = a.real * b.imag + a.imag * b.real;\n        return z;\n    }\n    static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_quotf(__pyx_t_float_complex a, __pyx_t_float_complex b) {\n        __pyx_t_float_complex z;\n        float denom = b.real * b.real + b.imag * b.imag;\n        z.real = (a.real * b.real + a.imag * b.imag) / denom;\n        z.imag = (a.imag * b.real - a.real * b.imag) / denom;\n        return z;\n    }\n    static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_negf(__pyx_t_float_complex a) {\n        __pyx_t_float_complex z;\n        z.real = -a.real;\n        z.imag = -a.imag;\n        return z;\n    }\n    static CYTHON_INLINE int __Pyx_c_is_zerof(__pyx_t_float_complex a) {\n       return (a.real == 0) && (a.imag == 0);\n    }\n    static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_conjf(__pyx_t_float_complex a) {\n        __pyx_t_float_complex z;\n        z.real =  a.real;\n        z.imag = -a.imag;\n        return z;\n    }\n    #if 1\n        static CYTHON_INLINE float __Pyx_c_absf(__pyx_t_float_complex z) {\n          #if !defined(HAVE_HYPOT) || defined(_MSC_VER)\n            return sqrtf(z.real*z.real + z.imag*z.imag);\n          #else\n            return hypotf(z.real, z.imag);\n          #endif\n        }\n        static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_powf(__pyx_t_float_complex a, __pyx_t_float_complex b) {\n            __pyx_t_float_complex z;\n            float r, lnr, theta, z_r, z_theta;\n            if (b.imag == 0 && b.real == (int)b.real) {\n                if (b.real < 0) {\n                    float denom = a.real * a.real + a.imag * a.imag;\n                    a.real = a.real / denom;\n                    a.imag = -a.imag / denom;\n                    b.real = -b.real;\n                }\n                switch ((int)b.real) {\n                    case 0:\n                        z.real = 1;\n                        z.imag = 0;\n                        return z;\n                    case 1:\n                        return a;\n                    case 2:\n                        z = __Pyx_c_prodf(a, a);\n                        return __Pyx_c_prodf(a, a);\n                    case 3:\n                        z = __Pyx_c_prodf(a, a);\n                        return __Pyx_c_prodf(z, a);\n                    case 4:\n                        z = __Pyx_c_prodf(a, a);\n                        return __Pyx_c_prodf(z, z);\n                }\n            }\n            if (a.imag == 0) {\n                if (a.real == 0) {\n                    return a;\n                }\n                r = a.real;\n                theta = 0;\n            } else {\n                r = __Pyx_c_absf(a);\n                theta = atan2f(a.imag, a.real);\n            }\n            lnr = logf(r);\n            z_r = expf(lnr * b.real - theta * b.imag);\n            z_theta = theta * b.real + lnr * b.imag;\n            z.real = z_r * cosf(z_theta);\n            z.imag = z_r * sinf(z_theta);\n            return z;\n        }\n    #endif\n#endif\n\n#if CYTHON_CCOMPLEX\n  #ifdef __cplusplus\n    static CYTHON_INLINE __pyx_t_double_complex __pyx_t_double_complex_from_parts(double x, double y) {\n      return ::std::complex< double >(x, y);\n    }\n  #else\n    static CYTHON_INLINE __pyx_t_double_complex __pyx_t_double_complex_from_parts(double x, double y) {\n      return x + y*(__pyx_t_double_complex)_Complex_I;\n    }\n  #endif\n#else\n    static CYTHON_INLINE __pyx_t_double_complex __pyx_t_double_complex_from_parts(double x, double y) {\n      __pyx_t_double_complex z;\n      z.real = x;\n      z.imag = y;\n      return z;\n    }\n#endif\n\n#if CYTHON_CCOMPLEX\n#else\n    static CYTHON_INLINE int __Pyx_c_eq(__pyx_t_double_complex a, __pyx_t_double_complex b) {\n       return (a.real == b.real) && (a.imag == b.imag);\n    }\n    static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_sum(__pyx_t_double_complex a, __pyx_t_double_complex b) {\n        __pyx_t_double_complex z;\n        z.real = a.real + b.real;\n        z.imag = a.imag + b.imag;\n        return z;\n    }\n    static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_diff(__pyx_t_double_complex a, __pyx_t_double_complex b) {\n        __pyx_t_double_complex z;\n        z.real = a.real - b.real;\n        z.imag = a.imag - b.imag;\n        return z;\n    }\n    static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_prod(__pyx_t_double_complex a, __pyx_t_double_complex b) {\n        __pyx_t_double_complex z;\n        z.real = a.real * b.real - a.imag * b.imag;\n        z.imag = a.real * b.imag + a.imag * b.real;\n        return z;\n    }\n    static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_quot(__pyx_t_double_complex a, __pyx_t_double_complex b) {\n        __pyx_t_double_complex z;\n        double denom = b.real * b.real + b.imag * b.imag;\n        z.real = (a.real * b.real + a.imag * b.imag) / denom;\n        z.imag = (a.imag * b.real - a.real * b.imag) / denom;\n        return z;\n    }\n    static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_neg(__pyx_t_double_complex a) {\n        __pyx_t_double_complex z;\n        z.real = -a.real;\n        z.imag = -a.imag;\n        return z;\n    }\n    static CYTHON_INLINE int __Pyx_c_is_zero(__pyx_t_double_complex a) {\n       return (a.real == 0) && (a.imag == 0);\n    }\n    static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_conj(__pyx_t_double_complex a) {\n        __pyx_t_double_complex z;\n        z.real =  a.real;\n        z.imag = -a.imag;\n        return z;\n    }\n    #if 1\n        static CYTHON_INLINE double __Pyx_c_abs(__pyx_t_double_complex z) {\n          #if !defined(HAVE_HYPOT) || defined(_MSC_VER)\n            return sqrt(z.real*z.real + z.imag*z.imag);\n          #else\n            return hypot(z.real, z.imag);\n          #endif\n        }\n        static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_pow(__pyx_t_double_complex a, __pyx_t_double_complex b) {\n            __pyx_t_double_complex z;\n            double r, lnr, theta, z_r, z_theta;\n            if (b.imag == 0 && b.real == (int)b.real) {\n                if (b.real < 0) {\n                    double denom = a.real * a.real + a.imag * a.imag;\n                    a.real = a.real / denom;\n                    a.imag = -a.imag / denom;\n                    b.real = -b.real;\n                }\n                switch ((int)b.real) {\n                    case 0:\n                        z.real = 1;\n                        z.imag = 0;\n                        return z;\n                    case 1:\n                        return a;\n                    case 2:\n                        z = __Pyx_c_prod(a, a);\n                        return __Pyx_c_prod(a, a);\n                    case 3:\n                        z = __Pyx_c_prod(a, a);\n                        return __Pyx_c_prod(z, a);\n                    case 4:\n                        z = __Pyx_c_prod(a, a);\n                        return __Pyx_c_prod(z, z);\n                }\n            }\n            if (a.imag == 0) {\n                if (a.real == 0) {\n                    return a;\n                }\n                r = a.real;\n                theta = 0;\n            } else {\n                r = __Pyx_c_abs(a);\n                theta = atan2(a.imag, a.real);\n            }\n            lnr = log(r);\n            z_r = exp(lnr * b.real - theta * b.imag);\n            z_theta = theta * b.real + lnr * b.imag;\n            z.real = z_r * cos(z_theta);\n            z.imag = z_r * sin(z_theta);\n            return z;\n        }\n    #endif\n#endif\n\n#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3\n #if CYTHON_USE_PYLONG_INTERNALS\n  #include \"longintrepr.h\"\n #endif\n#endif\nstatic CYTHON_INLINE long __Pyx_PyInt_As_long(PyObject *x) {\n    const long neg_one = (long) -1, const_zero = 0;\n    const int is_unsigned = neg_one > const_zero;\n#if PY_MAJOR_VERSION < 3\n    if (likely(PyInt_Check(x))) {\n        if (sizeof(long) < sizeof(long)) {\n            __PYX_VERIFY_RETURN_INT(long, long, PyInt_AS_LONG)\n        } else {\n            long val = PyInt_AS_LONG(x);\n            if (is_unsigned && unlikely(val < 0)) {\n                PyErr_SetString(PyExc_OverflowError,\n                                \"can't convert negative value to long\");\n                return (long) -1;\n            }\n            return (long) val;\n        }\n    } else\n#endif\n    if (likely(PyLong_Check(x))) {\n        if (is_unsigned) {\n#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3\n #if CYTHON_USE_PYLONG_INTERNALS\n            if (sizeof(digit) <= sizeof(long)) {\n                switch (Py_SIZE(x)) {\n                    case  0: return 0;\n                    case  1: return (long) ((PyLongObject*)x)->ob_digit[0];\n                }\n            }\n #endif\n#endif\n            if (unlikely(Py_SIZE(x) < 0)) {\n                PyErr_SetString(PyExc_OverflowError,\n                                \"can't convert negative value to long\");\n                return (long) -1;\n            }\n            if (sizeof(long) <= sizeof(unsigned long)) {\n                __PYX_VERIFY_RETURN_INT(long, unsigned long, PyLong_AsUnsignedLong)\n            } else if (sizeof(long) <= sizeof(unsigned long long)) {\n                __PYX_VERIFY_RETURN_INT(long, unsigned long long, PyLong_AsUnsignedLongLong)\n            }\n        } else {\n#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3\n #if CYTHON_USE_PYLONG_INTERNALS\n            if (sizeof(digit) <= sizeof(long)) {\n                switch (Py_SIZE(x)) {\n                    case  0: return 0;\n                    case  1: return +(long) ((PyLongObject*)x)->ob_digit[0];\n                    case -1: return -(long) ((PyLongObject*)x)->ob_digit[0];\n                }\n            }\n #endif\n#endif\n            if (sizeof(long) <= sizeof(long)) {\n                __PYX_VERIFY_RETURN_INT(long, long, PyLong_AsLong)\n            } else if (sizeof(long) <= sizeof(long long)) {\n                __PYX_VERIFY_RETURN_INT(long, long long, PyLong_AsLongLong)\n            }\n        }\n        {\n#if CYTHON_COMPILING_IN_PYPY && !defined(_PyLong_AsByteArray)\n            PyErr_SetString(PyExc_RuntimeError,\n                            \"_PyLong_AsByteArray() not available in PyPy, cannot convert large numbers\");\n#else\n            long val;\n            PyObject *v = __Pyx_PyNumber_Int(x);\n #if PY_MAJOR_VERSION < 3\n            if (likely(v) && !PyLong_Check(v)) {\n                PyObject *tmp = v;\n                v = PyNumber_Long(tmp);\n                Py_DECREF(tmp);\n            }\n #endif\n            if (likely(v)) {\n                int one = 1; int is_little = (int)*(unsigned char *)&one;\n                unsigned char *bytes = (unsigned char *)&val;\n                int ret = _PyLong_AsByteArray((PyLongObject *)v,\n                                              bytes, sizeof(val),\n                                              is_little, !is_unsigned);\n                Py_DECREF(v);\n                if (likely(!ret))\n                    return val;\n            }\n#endif\n            return (long) -1;\n        }\n    } else {\n        long val;\n        PyObject *tmp = __Pyx_PyNumber_Int(x);\n        if (!tmp) return (long) -1;\n        val = __Pyx_PyInt_As_long(tmp);\n        Py_DECREF(tmp);\n        return val;\n    }\n}\n\nstatic int __Pyx_check_binary_version(void) {\n    char ctversion[4], rtversion[4];\n    PyOS_snprintf(ctversion, 4, \"%d.%d\", PY_MAJOR_VERSION, PY_MINOR_VERSION);\n    PyOS_snprintf(rtversion, 4, \"%s\", Py_GetVersion());\n    if (ctversion[0] != rtversion[0] || ctversion[2] != rtversion[2]) {\n        char message[200];\n        PyOS_snprintf(message, sizeof(message),\n                      \"compiletime version %s of module '%.100s' \"\n                      \"does not match runtime version %s\",\n                      ctversion, __Pyx_MODULE_NAME, rtversion);\n        #if PY_VERSION_HEX < 0x02050000\n        return PyErr_Warn(NULL, message);\n        #else\n        return PyErr_WarnEx(NULL, message, 1);\n        #endif\n    }\n    return 0;\n}\n\n#ifndef __PYX_HAVE_RT_ImportModule\n#define __PYX_HAVE_RT_ImportModule\nstatic PyObject *__Pyx_ImportModule(const char *name) {\n    PyObject *py_name = 0;\n    PyObject *py_module = 0;\n    py_name = __Pyx_PyIdentifier_FromString(name);\n    if (!py_name)\n        goto bad;\n    py_module = PyImport_Import(py_name);\n    Py_DECREF(py_name);\n    return py_module;\nbad:\n    Py_XDECREF(py_name);\n    return 0;\n}\n#endif\n\n#ifndef __PYX_HAVE_RT_ImportType\n#define __PYX_HAVE_RT_ImportType\nstatic PyTypeObject *__Pyx_ImportType(const char *module_name, const char *class_name,\n    size_t size, int strict)\n{\n    PyObject *py_module = 0;\n    PyObject *result = 0;\n    PyObject *py_name = 0;\n    char warning[200];\n    Py_ssize_t basicsize;\n#ifdef Py_LIMITED_API\n    PyObject *py_basicsize;\n#endif\n    py_module = __Pyx_ImportModule(module_name);\n    if (!py_module)\n        goto bad;\n    py_name = __Pyx_PyIdentifier_FromString(class_name);\n    if (!py_name)\n        goto bad;\n    result = PyObject_GetAttr(py_module, py_name);\n    Py_DECREF(py_name);\n    py_name = 0;\n    Py_DECREF(py_module);\n    py_module = 0;\n    if (!result)\n        goto bad;\n    if (!PyType_Check(result)) {\n        PyErr_Format(PyExc_TypeError,\n            \"%.200s.%.200s is not a type object\",\n            module_name, class_name);\n        goto bad;\n    }\n#ifndef Py_LIMITED_API\n    basicsize = ((PyTypeObject *)result)->tp_basicsize;\n#else\n    py_basicsize = PyObject_GetAttrString(result, \"__basicsize__\");\n    if (!py_basicsize)\n        goto bad;\n    basicsize = PyLong_AsSsize_t(py_basicsize);\n    Py_DECREF(py_basicsize);\n    py_basicsize = 0;\n    if (basicsize == (Py_ssize_t)-1 && PyErr_Occurred())\n        goto bad;\n#endif\n    if (!strict && (size_t)basicsize > size) {\n        PyOS_snprintf(warning, sizeof(warning),\n            \"%s.%s size changed, may indicate binary incompatibility\",\n            module_name, class_name);\n        #if PY_VERSION_HEX < 0x02050000\n        if (PyErr_Warn(NULL, warning) < 0) goto bad;\n        #else\n        if (PyErr_WarnEx(NULL, warning, 0) < 0) goto bad;\n        #endif\n    }\n    else if ((size_t)basicsize != size) {\n        PyErr_Format(PyExc_ValueError,\n            \"%.200s.%.200s has the wrong size, try recompiling\",\n            module_name, class_name);\n        goto bad;\n    }\n    return (PyTypeObject *)result;\nbad:\n    Py_XDECREF(py_module);\n    Py_XDECREF(result);\n    return NULL;\n}\n#endif\n\nstatic int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line) {\n    int start = 0, mid = 0, end = count - 1;\n    if (end >= 0 && code_line > entries[end].code_line) {\n        return count;\n    }\n    while (start < end) {\n        mid = (start + end) / 2;\n        if (code_line < entries[mid].code_line) {\n            end = mid;\n        } else if (code_line > entries[mid].code_line) {\n             start = mid + 1;\n        } else {\n            return mid;\n        }\n    }\n    if (code_line <= entries[mid].code_line) {\n        return mid;\n    } else {\n        return mid + 1;\n    }\n}\nstatic PyCodeObject *__pyx_find_code_object(int code_line) {\n    PyCodeObject* code_object;\n    int pos;\n    if (unlikely(!code_line) || unlikely(!__pyx_code_cache.entries)) {\n        return NULL;\n    }\n    pos = __pyx_bisect_code_objects(__pyx_code_cache.entries, __pyx_code_cache.count, code_line);\n    if (unlikely(pos >= __pyx_code_cache.count) || unlikely(__pyx_code_cache.entries[pos].code_line != code_line)) {\n        return NULL;\n    }\n    code_object = __pyx_code_cache.entries[pos].code_object;\n    Py_INCREF(code_object);\n    return code_object;\n}\nstatic void __pyx_insert_code_object(int code_line, PyCodeObject* code_object) {\n    int pos, i;\n    __Pyx_CodeObjectCacheEntry* entries = __pyx_code_cache.entries;\n    if (unlikely(!code_line)) {\n        return;\n    }\n    if (unlikely(!entries)) {\n        entries = (__Pyx_CodeObjectCacheEntry*)PyMem_Malloc(64*sizeof(__Pyx_CodeObjectCacheEntry));\n        if (likely(entries)) {\n            __pyx_code_cache.entries = entries;\n            __pyx_code_cache.max_count = 64;\n            __pyx_code_cache.count = 1;\n            entries[0].code_line = code_line;\n            entries[0].code_object = code_object;\n            Py_INCREF(code_object);\n        }\n        return;\n    }\n    pos = __pyx_bisect_code_objects(__pyx_code_cache.entries, __pyx_code_cache.count, code_line);\n    if ((pos < __pyx_code_cache.count) && unlikely(__pyx_code_cache.entries[pos].code_line == code_line)) {\n        PyCodeObject* tmp = entries[pos].code_object;\n        entries[pos].code_object = code_object;\n        Py_DECREF(tmp);\n        return;\n    }\n    if (__pyx_code_cache.count == __pyx_code_cache.max_count) {\n        int new_max = __pyx_code_cache.max_count + 64;\n        entries = (__Pyx_CodeObjectCacheEntry*)PyMem_Realloc(\n            __pyx_code_cache.entries, new_max*sizeof(__Pyx_CodeObjectCacheEntry));\n        if (unlikely(!entries)) {\n            return;\n        }\n        __pyx_code_cache.entries = entries;\n        __pyx_code_cache.max_count = new_max;\n    }\n    for (i=__pyx_code_cache.count; i>pos; i--) {\n        entries[i] = entries[i-1];\n    }\n    entries[pos].code_line = code_line;\n    entries[pos].code_object = code_object;\n    __pyx_code_cache.count++;\n    Py_INCREF(code_object);\n}\n\n#include \"compile.h\"\n#include \"frameobject.h\"\n#include \"traceback.h\"\nstatic PyCodeObject* __Pyx_CreateCodeObjectForTraceback(\n            const char *funcname, int c_line,\n            int py_line, const char *filename) {\n    PyCodeObject *py_code = 0;\n    PyObject *py_srcfile = 0;\n    PyObject *py_funcname = 0;\n    #if PY_MAJOR_VERSION < 3\n    py_srcfile = PyString_FromString(filename);\n    #else\n    py_srcfile = PyUnicode_FromString(filename);\n    #endif\n    if (!py_srcfile) goto bad;\n    if (c_line) {\n        #if PY_MAJOR_VERSION < 3\n        py_funcname = PyString_FromFormat( \"%s (%s:%d)\", funcname, __pyx_cfilenm, c_line);\n        #else\n        py_funcname = PyUnicode_FromFormat( \"%s (%s:%d)\", funcname, __pyx_cfilenm, c_line);\n        #endif\n    }\n    else {\n        #if PY_MAJOR_VERSION < 3\n        py_funcname = PyString_FromString(funcname);\n        #else\n        py_funcname = PyUnicode_FromString(funcname);\n        #endif\n    }\n    if (!py_funcname) goto bad;\n    py_code = __Pyx_PyCode_New(\n        0,            /*int argcount,*/\n        0,            /*int kwonlyargcount,*/\n        0,            /*int nlocals,*/\n        0,            /*int stacksize,*/\n        0,            /*int flags,*/\n        __pyx_empty_bytes, /*PyObject *code,*/\n        __pyx_empty_tuple, /*PyObject *consts,*/\n        __pyx_empty_tuple, /*PyObject *names,*/\n        __pyx_empty_tuple, /*PyObject *varnames,*/\n        __pyx_empty_tuple, /*PyObject *freevars,*/\n        __pyx_empty_tuple, /*PyObject *cellvars,*/\n        py_srcfile,   /*PyObject *filename,*/\n        py_funcname,  /*PyObject *name,*/\n        py_line,      /*int firstlineno,*/\n        __pyx_empty_bytes  /*PyObject *lnotab*/\n    );\n    Py_DECREF(py_srcfile);\n    Py_DECREF(py_funcname);\n    return py_code;\nbad:\n    Py_XDECREF(py_srcfile);\n    Py_XDECREF(py_funcname);\n    return NULL;\n}\nstatic void __Pyx_AddTraceback(const char *funcname, int c_line,\n                               int py_line, const char *filename) {\n    PyCodeObject *py_code = 0;\n    PyObject *py_globals = 0;\n    PyFrameObject *py_frame = 0;\n    py_code = __pyx_find_code_object(c_line ? c_line : py_line);\n    if (!py_code) {\n        py_code = __Pyx_CreateCodeObjectForTraceback(\n            funcname, c_line, py_line, filename);\n        if (!py_code) goto bad;\n        __pyx_insert_code_object(c_line ? c_line : py_line, py_code);\n    }\n    py_globals = PyModule_GetDict(__pyx_m);\n    if (!py_globals) goto bad;\n    py_frame = PyFrame_New(\n        PyThreadState_GET(), /*PyThreadState *tstate,*/\n        py_code,             /*PyCodeObject *code,*/\n        py_globals,          /*PyObject *globals,*/\n        0                    /*PyObject *locals*/\n    );\n    if (!py_frame) goto bad;\n    py_frame->f_lineno = py_line;\n    PyTraceBack_Here(py_frame);\nbad:\n    Py_XDECREF(py_code);\n    Py_XDECREF(py_frame);\n}\n\nstatic int __Pyx_InitStrings(__Pyx_StringTabEntry *t) {\n    while (t->p) {\n        #if PY_MAJOR_VERSION < 3\n        if (t->is_unicode) {\n            *t->p = PyUnicode_DecodeUTF8(t->s, t->n - 1, NULL);\n        } else if (t->intern) {\n            *t->p = PyString_InternFromString(t->s);\n        } else {\n            *t->p = PyString_FromStringAndSize(t->s, t->n - 1);\n        }\n        #else  /* Python 3+ has unicode identifiers */\n        if (t->is_unicode | t->is_str) {\n            if (t->intern) {\n                *t->p = PyUnicode_InternFromString(t->s);\n            } else if (t->encoding) {\n                *t->p = PyUnicode_Decode(t->s, t->n - 1, t->encoding, NULL);\n            } else {\n                *t->p = PyUnicode_FromStringAndSize(t->s, t->n - 1);\n            }\n        } else {\n            *t->p = PyBytes_FromStringAndSize(t->s, t->n - 1);\n        }\n        #endif\n        if (!*t->p)\n            return -1;\n        ++t;\n    }\n    return 0;\n}\n\nstatic CYTHON_INLINE PyObject* __Pyx_PyUnicode_FromString(char* c_str) {\n    return __Pyx_PyUnicode_FromStringAndSize(c_str, strlen(c_str));\n}\nstatic CYTHON_INLINE char* __Pyx_PyObject_AsString(PyObject* o) {\n    Py_ssize_t ignore;\n    return __Pyx_PyObject_AsStringAndSize(o, &ignore);\n}\nstatic CYTHON_INLINE char* __Pyx_PyObject_AsStringAndSize(PyObject* o, Py_ssize_t *length) {\n#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII || __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT\n    if (\n#if PY_MAJOR_VERSION < 3 && __PYX_DEFAULT_STRING_ENCODING_IS_ASCII\n            __Pyx_sys_getdefaultencoding_not_ascii &&\n#endif\n            PyUnicode_Check(o)) {\n#if PY_VERSION_HEX < 0x03030000\n        char* defenc_c;\n        PyObject* defenc = _PyUnicode_AsDefaultEncodedString(o, NULL);\n        if (!defenc) return NULL;\n        defenc_c = PyBytes_AS_STRING(defenc);\n#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII\n        {\n            char* end = defenc_c + PyBytes_GET_SIZE(defenc);\n            char* c;\n            for (c = defenc_c; c < end; c++) {\n                if ((unsigned char) (*c) >= 128) {\n                    PyUnicode_AsASCIIString(o);\n                    return NULL;\n                }\n            }\n        }\n#endif /*__PYX_DEFAULT_STRING_ENCODING_IS_ASCII*/\n        *length = PyBytes_GET_SIZE(defenc);\n        return defenc_c;\n#else /* PY_VERSION_HEX < 0x03030000 */\n        if (PyUnicode_READY(o) == -1) return NULL;\n#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII\n        if (PyUnicode_IS_ASCII(o)) {\n            *length = PyUnicode_GET_DATA_SIZE(o);\n            return PyUnicode_AsUTF8(o);\n        } else {\n            PyUnicode_AsASCIIString(o);\n            return NULL;\n        }\n#else /* __PYX_DEFAULT_STRING_ENCODING_IS_ASCII */\n        return PyUnicode_AsUTF8AndSize(o, length);\n#endif /* __PYX_DEFAULT_STRING_ENCODING_IS_ASCII */\n#endif /* PY_VERSION_HEX < 0x03030000 */\n    } else\n#endif /* __PYX_DEFAULT_STRING_ENCODING_IS_ASCII  || __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT */\n#if !CYTHON_COMPILING_IN_PYPY\n#if PY_VERSION_HEX >= 0x02060000\n    if (PyByteArray_Check(o)) {\n        *length = PyByteArray_GET_SIZE(o);\n        return PyByteArray_AS_STRING(o);\n    } else\n#endif\n#endif\n    {\n        char* result;\n        int r = PyBytes_AsStringAndSize(o, &result, length);\n        if (unlikely(r < 0)) {\n            return NULL;\n        } else {\n            return result;\n        }\n    }\n}\nstatic CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject* x) {\n   int is_true = x == Py_True;\n   if (is_true | (x == Py_False) | (x == Py_None)) return is_true;\n   else return PyObject_IsTrue(x);\n}\nstatic CYTHON_INLINE PyObject* __Pyx_PyNumber_Int(PyObject* x) {\n  PyNumberMethods *m;\n  const char *name = NULL;\n  PyObject *res = NULL;\n#if PY_MAJOR_VERSION < 3\n  if (PyInt_Check(x) || PyLong_Check(x))\n#else\n  if (PyLong_Check(x))\n#endif\n    return Py_INCREF(x), x;\n  m = Py_TYPE(x)->tp_as_number;\n#if PY_MAJOR_VERSION < 3\n  if (m && m->nb_int) {\n    name = \"int\";\n    res = PyNumber_Int(x);\n  }\n  else if (m && m->nb_long) {\n    name = \"long\";\n    res = PyNumber_Long(x);\n  }\n#else\n  if (m && m->nb_int) {\n    name = \"int\";\n    res = PyNumber_Long(x);\n  }\n#endif\n  if (res) {\n#if PY_MAJOR_VERSION < 3\n    if (!PyInt_Check(res) && !PyLong_Check(res)) {\n#else\n    if (!PyLong_Check(res)) {\n#endif\n      PyErr_Format(PyExc_TypeError,\n                   \"__%.4s__ returned non-%.4s (type %.200s)\",\n                   name, name, Py_TYPE(res)->tp_name);\n      Py_DECREF(res);\n      return NULL;\n    }\n  }\n  else if (!PyErr_Occurred()) {\n    PyErr_SetString(PyExc_TypeError,\n                    \"an integer is required\");\n  }\n  return res;\n}\n#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3\n #if CYTHON_USE_PYLONG_INTERNALS\n  #include \"longintrepr.h\"\n #endif\n#endif\nstatic CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject* b) {\n  Py_ssize_t ival;\n  PyObject *x;\n#if PY_MAJOR_VERSION < 3\n  if (likely(PyInt_CheckExact(b)))\n      return PyInt_AS_LONG(b);\n#endif\n  if (likely(PyLong_CheckExact(b))) {\n    #if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3\n     #if CYTHON_USE_PYLONG_INTERNALS\n       switch (Py_SIZE(b)) {\n       case -1: return -(sdigit)((PyLongObject*)b)->ob_digit[0];\n       case  0: return 0;\n       case  1: return ((PyLongObject*)b)->ob_digit[0];\n       }\n     #endif\n    #endif\n  #if PY_VERSION_HEX < 0x02060000\n    return PyInt_AsSsize_t(b);\n  #else\n    return PyLong_AsSsize_t(b);\n  #endif\n  }\n  x = PyNumber_Index(b);\n  if (!x) return -1;\n  ival = PyInt_AsSsize_t(x);\n  Py_DECREF(x);\n  return ival;\n}\nstatic CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t ival) {\n#if PY_VERSION_HEX < 0x02050000\n   if (ival <= LONG_MAX)\n       return PyInt_FromLong((long)ival);\n   else {\n       unsigned char *bytes = (unsigned char *) &ival;\n       int one = 1; int little = (int)*(unsigned char*)&one;\n       return _PyLong_FromByteArray(bytes, sizeof(size_t), little, 0);\n   }\n#else\n   return PyInt_FromSize_t(ival);\n#endif\n}\n\n\n#endif /* Py_PYTHON_H */\n"
  },
  {
    "path": "src/tools/voc_eval_lib/nms/cpu_nms.pyx",
    "content": "# --------------------------------------------------------\n# Fast R-CNN\n# Copyright (c) 2015 Microsoft\n# Licensed under The MIT License [see LICENSE for details]\n# Written by Ross Girshick\n# --------------------------------------------------------\n\nimport numpy as np\ncimport numpy as np\n\ncdef inline np.float32_t max(np.float32_t a, np.float32_t b):\n    return a if a >= b else b\n\ncdef inline np.float32_t min(np.float32_t a, np.float32_t b):\n    return a if a <= b else b\n\ndef cpu_nms(np.ndarray[np.float32_t, ndim=2] dets, np.float thresh):\n    cdef np.ndarray[np.float32_t, ndim=1] x1 = dets[:, 0]\n    cdef np.ndarray[np.float32_t, ndim=1] y1 = dets[:, 1]\n    cdef np.ndarray[np.float32_t, ndim=1] x2 = dets[:, 2]\n    cdef np.ndarray[np.float32_t, ndim=1] y2 = dets[:, 3]\n    cdef np.ndarray[np.float32_t, ndim=1] scores = dets[:, 4]\n\n    cdef np.ndarray[np.float32_t, ndim=1] areas = (x2 - x1 + 1) * (y2 - y1 + 1)\n    cdef np.ndarray[np.int_t, ndim=1] order = scores.argsort()[::-1]\n\n    cdef int ndets = dets.shape[0]\n    cdef np.ndarray[np.int_t, ndim=1] suppressed = \\\n            np.zeros((ndets), dtype=np.int)\n\n    # nominal indices\n    cdef int _i, _j\n    # sorted indices\n    cdef int i, j\n    # temp variables for box i's (the box currently under consideration)\n    cdef np.float32_t ix1, iy1, ix2, iy2, iarea\n    # variables for computing overlap with box j (lower scoring box)\n    cdef np.float32_t xx1, yy1, xx2, yy2\n    cdef np.float32_t w, h\n    cdef np.float32_t inter, ovr\n\n    keep = []\n    for _i in range(ndets):\n        i = order[_i]\n        if suppressed[i] == 1:\n            continue\n        keep.append(i)\n        ix1 = x1[i]\n        iy1 = y1[i]\n        ix2 = x2[i]\n        iy2 = y2[i]\n        iarea = areas[i]\n        for _j in range(_i + 1, ndets):\n            j = order[_j]\n            if suppressed[j] == 1:\n                continue\n            xx1 = max(ix1, x1[j])\n            yy1 = max(iy1, y1[j])\n            xx2 = min(ix2, x2[j])\n            yy2 = min(iy2, y2[j])\n            w = max(0.0, xx2 - xx1 + 1)\n            h = max(0.0, yy2 - yy1 + 1)\n            inter = w * h\n            ovr = inter / (iarea + areas[j] - inter)\n            if ovr >= thresh:\n                suppressed[j] = 1\n\n    return keep\n"
  },
  {
    "path": "src/tools/voc_eval_lib/nms/gpu_nms.cpp",
    "content": "/* Generated by Cython 0.20.1 on Wed Oct  5 13:15:30 2016 */\n\n#define PY_SSIZE_T_CLEAN\n#ifndef CYTHON_USE_PYLONG_INTERNALS\n#ifdef PYLONG_BITS_IN_DIGIT\n#define CYTHON_USE_PYLONG_INTERNALS 0\n#else\n#include \"pyconfig.h\"\n#ifdef PYLONG_BITS_IN_DIGIT\n#define CYTHON_USE_PYLONG_INTERNALS 1\n#else\n#define CYTHON_USE_PYLONG_INTERNALS 0\n#endif\n#endif\n#endif\n#include \"Python.h\"\n#ifndef Py_PYTHON_H\n    #error Python headers needed to compile C extensions, please install development version of Python.\n#elif PY_VERSION_HEX < 0x02040000\n    #error Cython requires Python 2.4+.\n#else\n#define CYTHON_ABI \"0_20_1\"\n#include <stddef.h> /* For offsetof */\n#ifndef offsetof\n#define offsetof(type, member) ( (size_t) & ((type*)0) -> member )\n#endif\n#if !defined(WIN32) && !defined(MS_WINDOWS)\n  #ifndef __stdcall\n    #define __stdcall\n  #endif\n  #ifndef __cdecl\n    #define __cdecl\n  #endif\n  #ifndef __fastcall\n    #define __fastcall\n  #endif\n#endif\n#ifndef DL_IMPORT\n  #define DL_IMPORT(t) t\n#endif\n#ifndef DL_EXPORT\n  #define DL_EXPORT(t) t\n#endif\n#ifndef PY_LONG_LONG\n  #define PY_LONG_LONG LONG_LONG\n#endif\n#ifndef Py_HUGE_VAL\n  #define Py_HUGE_VAL HUGE_VAL\n#endif\n#ifdef PYPY_VERSION\n#define CYTHON_COMPILING_IN_PYPY 1\n#define CYTHON_COMPILING_IN_CPYTHON 0\n#else\n#define CYTHON_COMPILING_IN_PYPY 0\n#define CYTHON_COMPILING_IN_CPYTHON 1\n#endif\n#if CYTHON_COMPILING_IN_PYPY\n#define Py_OptimizeFlag 0\n#endif\n#if PY_VERSION_HEX < 0x02050000\n  typedef int Py_ssize_t;\n  #define PY_SSIZE_T_MAX INT_MAX\n  #define PY_SSIZE_T_MIN INT_MIN\n  #define PY_FORMAT_SIZE_T \"\"\n  #define CYTHON_FORMAT_SSIZE_T \"\"\n  #define PyInt_FromSsize_t(z) PyInt_FromLong(z)\n  #define PyInt_AsSsize_t(o)   __Pyx_PyInt_As_int(o)\n  #define PyNumber_Index(o)    ((PyNumber_Check(o) && !PyFloat_Check(o)) ? PyNumber_Int(o) : \\\n                                (PyErr_Format(PyExc_TypeError, \\\n                                              \"expected index value, got %.200s\", Py_TYPE(o)->tp_name), \\\n                                 (PyObject*)0))\n  #define __Pyx_PyIndex_Check(o) (PyNumber_Check(o) && !PyFloat_Check(o) && \\\n                                  !PyComplex_Check(o))\n  #define PyIndex_Check __Pyx_PyIndex_Check\n  #define PyErr_WarnEx(category, message, stacklevel) PyErr_Warn(category, message)\n  #define __PYX_BUILD_PY_SSIZE_T \"i\"\n#else\n  #define __PYX_BUILD_PY_SSIZE_T \"n\"\n  #define CYTHON_FORMAT_SSIZE_T \"z\"\n  #define __Pyx_PyIndex_Check PyIndex_Check\n#endif\n#if PY_VERSION_HEX < 0x02060000\n  #define Py_REFCNT(ob) (((PyObject*)(ob))->ob_refcnt)\n  #define Py_TYPE(ob)   (((PyObject*)(ob))->ob_type)\n  #define Py_SIZE(ob)   (((PyVarObject*)(ob))->ob_size)\n  #define PyVarObject_HEAD_INIT(type, size) \\\n          PyObject_HEAD_INIT(type) size,\n  #define PyType_Modified(t)\n  typedef struct {\n     void *buf;\n     PyObject *obj;\n     Py_ssize_t len;\n     Py_ssize_t itemsize;\n     int readonly;\n     int ndim;\n     char *format;\n     Py_ssize_t *shape;\n     Py_ssize_t *strides;\n     Py_ssize_t *suboffsets;\n     void *internal;\n  } Py_buffer;\n  #define PyBUF_SIMPLE 0\n  #define PyBUF_WRITABLE 0x0001\n  #define PyBUF_FORMAT 0x0004\n  #define PyBUF_ND 0x0008\n  #define PyBUF_STRIDES (0x0010 | PyBUF_ND)\n  #define PyBUF_C_CONTIGUOUS (0x0020 | PyBUF_STRIDES)\n  #define PyBUF_F_CONTIGUOUS (0x0040 | PyBUF_STRIDES)\n  #define PyBUF_ANY_CONTIGUOUS (0x0080 | PyBUF_STRIDES)\n  #define PyBUF_INDIRECT (0x0100 | PyBUF_STRIDES)\n  #define PyBUF_RECORDS (PyBUF_STRIDES | PyBUF_FORMAT | PyBUF_WRITABLE)\n  #define PyBUF_FULL (PyBUF_INDIRECT | PyBUF_FORMAT | PyBUF_WRITABLE)\n  typedef int (*getbufferproc)(PyObject *, Py_buffer *, int);\n  typedef void (*releasebufferproc)(PyObject *, Py_buffer *);\n#endif\n#if PY_MAJOR_VERSION < 3\n  #define __Pyx_BUILTIN_MODULE_NAME \"__builtin__\"\n  #define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) \\\n          PyCode_New(a+k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)\n  #define __Pyx_DefaultClassType PyClass_Type\n#else\n  #define __Pyx_BUILTIN_MODULE_NAME \"builtins\"\n  #define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) \\\n          PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)\n  #define __Pyx_DefaultClassType PyType_Type\n#endif\n#if PY_VERSION_HEX < 0x02060000\n  #define PyUnicode_FromString(s) PyUnicode_Decode(s, strlen(s), \"UTF-8\", \"strict\")\n#endif\n#if PY_MAJOR_VERSION >= 3\n  #define Py_TPFLAGS_CHECKTYPES 0\n  #define Py_TPFLAGS_HAVE_INDEX 0\n#endif\n#if (PY_VERSION_HEX < 0x02060000) || (PY_MAJOR_VERSION >= 3)\n  #define Py_TPFLAGS_HAVE_NEWBUFFER 0\n#endif\n#if PY_VERSION_HEX < 0x02060000\n  #define Py_TPFLAGS_HAVE_VERSION_TAG 0\n#endif\n#if PY_VERSION_HEX < 0x02060000 && !defined(Py_TPFLAGS_IS_ABSTRACT)\n  #define Py_TPFLAGS_IS_ABSTRACT 0\n#endif\n#if PY_VERSION_HEX < 0x030400a1 && !defined(Py_TPFLAGS_HAVE_FINALIZE)\n  #define Py_TPFLAGS_HAVE_FINALIZE 0\n#endif\n#if PY_VERSION_HEX > 0x03030000 && defined(PyUnicode_KIND)\n  #define CYTHON_PEP393_ENABLED 1\n  #define __Pyx_PyUnicode_READY(op)       (likely(PyUnicode_IS_READY(op)) ? \\\n                                              0 : _PyUnicode_Ready((PyObject *)(op)))\n  #define __Pyx_PyUnicode_GET_LENGTH(u)   PyUnicode_GET_LENGTH(u)\n  #define __Pyx_PyUnicode_READ_CHAR(u, i) PyUnicode_READ_CHAR(u, i)\n  #define __Pyx_PyUnicode_KIND(u)         PyUnicode_KIND(u)\n  #define __Pyx_PyUnicode_DATA(u)         PyUnicode_DATA(u)\n  #define __Pyx_PyUnicode_READ(k, d, i)   PyUnicode_READ(k, d, i)\n#else\n  #define CYTHON_PEP393_ENABLED 0\n  #define __Pyx_PyUnicode_READY(op)       (0)\n  #define __Pyx_PyUnicode_GET_LENGTH(u)   PyUnicode_GET_SIZE(u)\n  #define __Pyx_PyUnicode_READ_CHAR(u, i) ((Py_UCS4)(PyUnicode_AS_UNICODE(u)[i]))\n  #define __Pyx_PyUnicode_KIND(u)         (sizeof(Py_UNICODE))\n  #define __Pyx_PyUnicode_DATA(u)         ((void*)PyUnicode_AS_UNICODE(u))\n  #define __Pyx_PyUnicode_READ(k, d, i)   ((void)(k), (Py_UCS4)(((Py_UNICODE*)d)[i]))\n#endif\n#if CYTHON_COMPILING_IN_PYPY\n  #define __Pyx_PyUnicode_Concat(a, b)      PyNumber_Add(a, b)\n  #define __Pyx_PyUnicode_ConcatSafe(a, b)  PyNumber_Add(a, b)\n#else\n  #define __Pyx_PyUnicode_Concat(a, b)      PyUnicode_Concat(a, b)\n  #define __Pyx_PyUnicode_ConcatSafe(a, b)  ((unlikely((a) == Py_None) || unlikely((b) == Py_None)) ? \\\n      PyNumber_Add(a, b) : __Pyx_PyUnicode_Concat(a, b))\n#endif\n#define __Pyx_PyString_FormatSafe(a, b)  ((unlikely((a) == Py_None)) ? PyNumber_Remainder(a, b) : __Pyx_PyString_Format(a, b))\n#define __Pyx_PyUnicode_FormatSafe(a, b)  ((unlikely((a) == Py_None)) ? PyNumber_Remainder(a, b) : PyUnicode_Format(a, b))\n#if PY_MAJOR_VERSION >= 3\n  #define __Pyx_PyString_Format(a, b)  PyUnicode_Format(a, b)\n#else\n  #define __Pyx_PyString_Format(a, b)  PyString_Format(a, b)\n#endif\n#if PY_MAJOR_VERSION >= 3\n  #define PyBaseString_Type            PyUnicode_Type\n  #define PyStringObject               PyUnicodeObject\n  #define PyString_Type                PyUnicode_Type\n  #define PyString_Check               PyUnicode_Check\n  #define PyString_CheckExact          PyUnicode_CheckExact\n#endif\n#if PY_VERSION_HEX < 0x02060000\n  #define PyBytesObject                PyStringObject\n  #define PyBytes_Type                 PyString_Type\n  #define PyBytes_Check                PyString_Check\n  #define PyBytes_CheckExact           PyString_CheckExact\n  #define PyBytes_FromString           PyString_FromString\n  #define PyBytes_FromStringAndSize    PyString_FromStringAndSize\n  #define PyBytes_FromFormat           PyString_FromFormat\n  #define PyBytes_DecodeEscape         PyString_DecodeEscape\n  #define PyBytes_AsString             PyString_AsString\n  #define PyBytes_AsStringAndSize      PyString_AsStringAndSize\n  #define PyBytes_Size                 PyString_Size\n  #define PyBytes_AS_STRING            PyString_AS_STRING\n  #define PyBytes_GET_SIZE             PyString_GET_SIZE\n  #define PyBytes_Repr                 PyString_Repr\n  #define PyBytes_Concat               PyString_Concat\n  #define PyBytes_ConcatAndDel         PyString_ConcatAndDel\n#endif\n#if PY_MAJOR_VERSION >= 3\n  #define __Pyx_PyBaseString_Check(obj) PyUnicode_Check(obj)\n  #define __Pyx_PyBaseString_CheckExact(obj) PyUnicode_CheckExact(obj)\n#else\n  #define __Pyx_PyBaseString_Check(obj) (PyString_CheckExact(obj) || PyUnicode_CheckExact(obj) || \\\n                                         PyString_Check(obj) || PyUnicode_Check(obj))\n  #define __Pyx_PyBaseString_CheckExact(obj) (PyString_CheckExact(obj) || PyUnicode_CheckExact(obj))\n#endif\n#if PY_VERSION_HEX < 0x02060000\n  #define PySet_Check(obj)             PyObject_TypeCheck(obj, &PySet_Type)\n  #define PyFrozenSet_Check(obj)       PyObject_TypeCheck(obj, &PyFrozenSet_Type)\n#endif\n#ifndef PySet_CheckExact\n  #define PySet_CheckExact(obj)        (Py_TYPE(obj) == &PySet_Type)\n#endif\n#define __Pyx_TypeCheck(obj, type) PyObject_TypeCheck(obj, (PyTypeObject *)type)\n#if PY_MAJOR_VERSION >= 3\n  #define PyIntObject                  PyLongObject\n  #define PyInt_Type                   PyLong_Type\n  #define PyInt_Check(op)              PyLong_Check(op)\n  #define PyInt_CheckExact(op)         PyLong_CheckExact(op)\n  #define PyInt_FromString             PyLong_FromString\n  #define PyInt_FromUnicode            PyLong_FromUnicode\n  #define PyInt_FromLong               PyLong_FromLong\n  #define PyInt_FromSize_t             PyLong_FromSize_t\n  #define PyInt_FromSsize_t            PyLong_FromSsize_t\n  #define PyInt_AsLong                 PyLong_AsLong\n  #define PyInt_AS_LONG                PyLong_AS_LONG\n  #define PyInt_AsSsize_t              PyLong_AsSsize_t\n  #define PyInt_AsUnsignedLongMask     PyLong_AsUnsignedLongMask\n  #define PyInt_AsUnsignedLongLongMask PyLong_AsUnsignedLongLongMask\n  #define PyNumber_Int                 PyNumber_Long\n#endif\n#if PY_MAJOR_VERSION >= 3\n  #define PyBoolObject                 PyLongObject\n#endif\n#if PY_VERSION_HEX < 0x030200A4\n  typedef long Py_hash_t;\n  #define __Pyx_PyInt_FromHash_t PyInt_FromLong\n  #define __Pyx_PyInt_AsHash_t   PyInt_AsLong\n#else\n  #define __Pyx_PyInt_FromHash_t PyInt_FromSsize_t\n  #define __Pyx_PyInt_AsHash_t   PyInt_AsSsize_t\n#endif\n#if (PY_MAJOR_VERSION < 3) || (PY_VERSION_HEX >= 0x03010300)\n  #define __Pyx_PySequence_GetSlice(obj, a, b) PySequence_GetSlice(obj, a, b)\n  #define __Pyx_PySequence_SetSlice(obj, a, b, value) PySequence_SetSlice(obj, a, b, value)\n  #define __Pyx_PySequence_DelSlice(obj, a, b) PySequence_DelSlice(obj, a, b)\n#else\n  #define __Pyx_PySequence_GetSlice(obj, a, b) (unlikely(!(obj)) ? \\\n        (PyErr_SetString(PyExc_SystemError, \"null argument to internal routine\"), (PyObject*)0) : \\\n        (likely((obj)->ob_type->tp_as_mapping) ? (PySequence_GetSlice(obj, a, b)) : \\\n            (PyErr_Format(PyExc_TypeError, \"'%.200s' object is unsliceable\", (obj)->ob_type->tp_name), (PyObject*)0)))\n  #define __Pyx_PySequence_SetSlice(obj, a, b, value) (unlikely(!(obj)) ? \\\n        (PyErr_SetString(PyExc_SystemError, \"null argument to internal routine\"), -1) : \\\n        (likely((obj)->ob_type->tp_as_mapping) ? (PySequence_SetSlice(obj, a, b, value)) : \\\n            (PyErr_Format(PyExc_TypeError, \"'%.200s' object doesn't support slice assignment\", (obj)->ob_type->tp_name), -1)))\n  #define __Pyx_PySequence_DelSlice(obj, a, b) (unlikely(!(obj)) ? \\\n        (PyErr_SetString(PyExc_SystemError, \"null argument to internal routine\"), -1) : \\\n        (likely((obj)->ob_type->tp_as_mapping) ? (PySequence_DelSlice(obj, a, b)) : \\\n            (PyErr_Format(PyExc_TypeError, \"'%.200s' object doesn't support slice deletion\", (obj)->ob_type->tp_name), -1)))\n#endif\n#if PY_MAJOR_VERSION >= 3\n  #define PyMethod_New(func, self, klass) ((self) ? PyMethod_New(func, self) : PyInstanceMethod_New(func))\n#endif\n#if PY_VERSION_HEX < 0x02050000\n  #define __Pyx_GetAttrString(o,n)   PyObject_GetAttrString((o),((char *)(n)))\n  #define __Pyx_SetAttrString(o,n,a) PyObject_SetAttrString((o),((char *)(n)),(a))\n  #define __Pyx_DelAttrString(o,n)   PyObject_DelAttrString((o),((char *)(n)))\n#else\n  #define __Pyx_GetAttrString(o,n)   PyObject_GetAttrString((o),(n))\n  #define __Pyx_SetAttrString(o,n,a) PyObject_SetAttrString((o),(n),(a))\n  #define __Pyx_DelAttrString(o,n)   PyObject_DelAttrString((o),(n))\n#endif\n#if PY_VERSION_HEX < 0x02050000\n  #define __Pyx_NAMESTR(n) ((char *)(n))\n  #define __Pyx_DOCSTR(n)  ((char *)(n))\n#else\n  #define __Pyx_NAMESTR(n) (n)\n  #define __Pyx_DOCSTR(n)  (n)\n#endif\n#ifndef CYTHON_INLINE\n  #if defined(__GNUC__)\n    #define CYTHON_INLINE __inline__\n  #elif defined(_MSC_VER)\n    #define CYTHON_INLINE __inline\n  #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L\n    #define CYTHON_INLINE inline\n  #else\n    #define CYTHON_INLINE\n  #endif\n#endif\n#ifndef CYTHON_RESTRICT\n  #if defined(__GNUC__)\n    #define CYTHON_RESTRICT __restrict__\n  #elif defined(_MSC_VER) && _MSC_VER >= 1400\n    #define CYTHON_RESTRICT __restrict\n  #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L\n    #define CYTHON_RESTRICT restrict\n  #else\n    #define CYTHON_RESTRICT\n  #endif\n#endif\n#ifdef NAN\n#define __PYX_NAN() ((float) NAN)\n#else\nstatic CYTHON_INLINE float __PYX_NAN() {\n  /* Initialize NaN. The sign is irrelevant, an exponent with all bits 1 and\n   a nonzero mantissa means NaN. If the first bit in the mantissa is 1, it is\n   a quiet NaN. */\n  float value;\n  memset(&value, 0xFF, sizeof(value));\n  return value;\n}\n#endif\n\n\n#if PY_MAJOR_VERSION >= 3\n  #define __Pyx_PyNumber_Divide(x,y)         PyNumber_TrueDivide(x,y)\n  #define __Pyx_PyNumber_InPlaceDivide(x,y)  PyNumber_InPlaceTrueDivide(x,y)\n#else\n  #define __Pyx_PyNumber_Divide(x,y)         PyNumber_Divide(x,y)\n  #define __Pyx_PyNumber_InPlaceDivide(x,y)  PyNumber_InPlaceDivide(x,y)\n#endif\n\n#ifndef __PYX_EXTERN_C\n  #ifdef __cplusplus\n    #define __PYX_EXTERN_C extern \"C\"\n  #else\n    #define __PYX_EXTERN_C extern\n  #endif\n#endif\n\n#if defined(WIN32) || defined(MS_WINDOWS)\n#define _USE_MATH_DEFINES\n#endif\n#include <math.h>\n#define __PYX_HAVE__nms__gpu_nms\n#define __PYX_HAVE_API__nms__gpu_nms\n#include \"string.h\"\n#include \"stdio.h\"\n#include \"stdlib.h\"\n#include \"numpy/arrayobject.h\"\n#include \"numpy/ufuncobject.h\"\n#include \"gpu_nms.hpp\"\n#ifdef _OPENMP\n#include <omp.h>\n#endif /* _OPENMP */\n\n#ifdef PYREX_WITHOUT_ASSERTIONS\n#define CYTHON_WITHOUT_ASSERTIONS\n#endif\n\n#ifndef CYTHON_UNUSED\n# if defined(__GNUC__)\n#   if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4))\n#     define CYTHON_UNUSED __attribute__ ((__unused__))\n#   else\n#     define CYTHON_UNUSED\n#   endif\n# elif defined(__ICC) || (defined(__INTEL_COMPILER) && !defined(_MSC_VER))\n#   define CYTHON_UNUSED __attribute__ ((__unused__))\n# else\n#   define CYTHON_UNUSED\n# endif\n#endif\ntypedef struct {PyObject **p; char *s; const Py_ssize_t n; const char* encoding;\n                const char is_unicode; const char is_str; const char intern; } __Pyx_StringTabEntry; /*proto*/\n\n#define __PYX_DEFAULT_STRING_ENCODING_IS_ASCII 0\n#define __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT 0\n#define __PYX_DEFAULT_STRING_ENCODING \"\"\n#define __Pyx_PyObject_FromString __Pyx_PyBytes_FromString\n#define __Pyx_PyObject_FromStringAndSize __Pyx_PyBytes_FromStringAndSize\n#define __Pyx_fits_Py_ssize_t(v, type, is_signed)  (    \\\n    (sizeof(type) < sizeof(Py_ssize_t))  ||             \\\n    (sizeof(type) > sizeof(Py_ssize_t) &&               \\\n          likely(v < (type)PY_SSIZE_T_MAX ||            \\\n                 v == (type)PY_SSIZE_T_MAX)  &&         \\\n          (!is_signed || likely(v > (type)PY_SSIZE_T_MIN ||       \\\n                                v == (type)PY_SSIZE_T_MIN)))  ||  \\\n    (sizeof(type) == sizeof(Py_ssize_t) &&              \\\n          (is_signed || likely(v < (type)PY_SSIZE_T_MAX ||        \\\n                               v == (type)PY_SSIZE_T_MAX)))  )\nstatic CYTHON_INLINE char* __Pyx_PyObject_AsString(PyObject*);\nstatic CYTHON_INLINE char* __Pyx_PyObject_AsStringAndSize(PyObject*, Py_ssize_t* length);\n#define __Pyx_PyByteArray_FromString(s) PyByteArray_FromStringAndSize((const char*)s, strlen((const char*)s))\n#define __Pyx_PyByteArray_FromStringAndSize(s, l) PyByteArray_FromStringAndSize((const char*)s, l)\n#define __Pyx_PyBytes_FromString        PyBytes_FromString\n#define __Pyx_PyBytes_FromStringAndSize PyBytes_FromStringAndSize\nstatic CYTHON_INLINE PyObject* __Pyx_PyUnicode_FromString(char*);\n#if PY_MAJOR_VERSION < 3\n    #define __Pyx_PyStr_FromString        __Pyx_PyBytes_FromString\n    #define __Pyx_PyStr_FromStringAndSize __Pyx_PyBytes_FromStringAndSize\n#else\n    #define __Pyx_PyStr_FromString        __Pyx_PyUnicode_FromString\n    #define __Pyx_PyStr_FromStringAndSize __Pyx_PyUnicode_FromStringAndSize\n#endif\n#define __Pyx_PyObject_AsSString(s)    ((signed char*) __Pyx_PyObject_AsString(s))\n#define __Pyx_PyObject_AsUString(s)    ((unsigned char*) __Pyx_PyObject_AsString(s))\n#define __Pyx_PyObject_FromUString(s)  __Pyx_PyObject_FromString((char*)s)\n#define __Pyx_PyBytes_FromUString(s)   __Pyx_PyBytes_FromString((char*)s)\n#define __Pyx_PyByteArray_FromUString(s)   __Pyx_PyByteArray_FromString((char*)s)\n#define __Pyx_PyStr_FromUString(s)     __Pyx_PyStr_FromString((char*)s)\n#define __Pyx_PyUnicode_FromUString(s) __Pyx_PyUnicode_FromString((char*)s)\n#if PY_MAJOR_VERSION < 3\nstatic CYTHON_INLINE size_t __Pyx_Py_UNICODE_strlen(const Py_UNICODE *u)\n{\n    const Py_UNICODE *u_end = u;\n    while (*u_end++) ;\n    return u_end - u - 1;\n}\n#else\n#define __Pyx_Py_UNICODE_strlen Py_UNICODE_strlen\n#endif\n#define __Pyx_PyUnicode_FromUnicode(u)       PyUnicode_FromUnicode(u, __Pyx_Py_UNICODE_strlen(u))\n#define __Pyx_PyUnicode_FromUnicodeAndLength PyUnicode_FromUnicode\n#define __Pyx_PyUnicode_AsUnicode            PyUnicode_AsUnicode\n#define __Pyx_Owned_Py_None(b) (Py_INCREF(Py_None), Py_None)\n#define __Pyx_PyBool_FromLong(b) ((b) ? (Py_INCREF(Py_True), Py_True) : (Py_INCREF(Py_False), Py_False))\nstatic CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject*);\nstatic CYTHON_INLINE PyObject* __Pyx_PyNumber_Int(PyObject* x);\nstatic CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject*);\nstatic CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t);\n#if CYTHON_COMPILING_IN_CPYTHON\n#define __pyx_PyFloat_AsDouble(x) (PyFloat_CheckExact(x) ? PyFloat_AS_DOUBLE(x) : PyFloat_AsDouble(x))\n#else\n#define __pyx_PyFloat_AsDouble(x) PyFloat_AsDouble(x)\n#endif\n#define __pyx_PyFloat_AsFloat(x) ((float) __pyx_PyFloat_AsDouble(x))\n#if PY_MAJOR_VERSION < 3 && __PYX_DEFAULT_STRING_ENCODING_IS_ASCII\nstatic int __Pyx_sys_getdefaultencoding_not_ascii;\nstatic int __Pyx_init_sys_getdefaultencoding_params(void) {\n    PyObject* sys = NULL;\n    PyObject* default_encoding = NULL;\n    PyObject* ascii_chars_u = NULL;\n    PyObject* ascii_chars_b = NULL;\n    sys = PyImport_ImportModule(\"sys\");\n    if (sys == NULL) goto bad;\n    default_encoding = PyObject_CallMethod(sys, (char*) (const char*) \"getdefaultencoding\", NULL);\n    if (default_encoding == NULL) goto bad;\n    if (strcmp(PyBytes_AsString(default_encoding), \"ascii\") == 0) {\n        __Pyx_sys_getdefaultencoding_not_ascii = 0;\n    } else {\n        const char* default_encoding_c = PyBytes_AS_STRING(default_encoding);\n        char ascii_chars[128];\n        int c;\n        for (c = 0; c < 128; c++) {\n            ascii_chars[c] = c;\n        }\n        __Pyx_sys_getdefaultencoding_not_ascii = 1;\n        ascii_chars_u = PyUnicode_DecodeASCII(ascii_chars, 128, NULL);\n        if (ascii_chars_u == NULL) goto bad;\n        ascii_chars_b = PyUnicode_AsEncodedString(ascii_chars_u, default_encoding_c, NULL);\n        if (ascii_chars_b == NULL || strncmp(ascii_chars, PyBytes_AS_STRING(ascii_chars_b), 128) != 0) {\n            PyErr_Format(\n                PyExc_ValueError,\n                \"This module compiled with c_string_encoding=ascii, but default encoding '%.200s' is not a superset of ascii.\",\n                default_encoding_c);\n            goto bad;\n        }\n    }\n    Py_XDECREF(sys);\n    Py_XDECREF(default_encoding);\n    Py_XDECREF(ascii_chars_u);\n    Py_XDECREF(ascii_chars_b);\n    return 0;\nbad:\n    Py_XDECREF(sys);\n    Py_XDECREF(default_encoding);\n    Py_XDECREF(ascii_chars_u);\n    Py_XDECREF(ascii_chars_b);\n    return -1;\n}\n#endif\n#if __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT && PY_MAJOR_VERSION >= 3\n#define __Pyx_PyUnicode_FromStringAndSize(c_str, size) PyUnicode_DecodeUTF8(c_str, size, NULL)\n#else\n#define __Pyx_PyUnicode_FromStringAndSize(c_str, size) PyUnicode_Decode(c_str, size, __PYX_DEFAULT_STRING_ENCODING, NULL)\n#if __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT\nstatic char* __PYX_DEFAULT_STRING_ENCODING;\nstatic int __Pyx_init_sys_getdefaultencoding_params(void) {\n    PyObject* sys = NULL;\n    PyObject* default_encoding = NULL;\n    char* default_encoding_c;\n    sys = PyImport_ImportModule(\"sys\");\n    if (sys == NULL) goto bad;\n    default_encoding = PyObject_CallMethod(sys, (char*) (const char*) \"getdefaultencoding\", NULL);\n    if (default_encoding == NULL) goto bad;\n    default_encoding_c = PyBytes_AS_STRING(default_encoding);\n    __PYX_DEFAULT_STRING_ENCODING = (char*) malloc(strlen(default_encoding_c));\n    strcpy(__PYX_DEFAULT_STRING_ENCODING, default_encoding_c);\n    Py_DECREF(sys);\n    Py_DECREF(default_encoding);\n    return 0;\nbad:\n    Py_XDECREF(sys);\n    Py_XDECREF(default_encoding);\n    return -1;\n}\n#endif\n#endif\n\n\n#ifdef __GNUC__\n  /* Test for GCC > 2.95 */\n  #if __GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95))\n    #define likely(x)   __builtin_expect(!!(x), 1)\n    #define unlikely(x) __builtin_expect(!!(x), 0)\n  #else /* __GNUC__ > 2 ... */\n    #define likely(x)   (x)\n    #define unlikely(x) (x)\n  #endif /* __GNUC__ > 2 ... */\n#else /* __GNUC__ */\n  #define likely(x)   (x)\n  #define unlikely(x) (x)\n#endif /* __GNUC__ */\n\nstatic PyObject *__pyx_m;\nstatic PyObject *__pyx_d;\nstatic PyObject *__pyx_b;\nstatic PyObject *__pyx_empty_tuple;\nstatic PyObject *__pyx_empty_bytes;\nstatic int __pyx_lineno;\nstatic int __pyx_clineno = 0;\nstatic const char * __pyx_cfilenm= __FILE__;\nstatic const char *__pyx_filename;\n\n#if !defined(CYTHON_CCOMPLEX)\n  #if defined(__cplusplus)\n    #define CYTHON_CCOMPLEX 1\n  #elif defined(_Complex_I)\n    #define CYTHON_CCOMPLEX 1\n  #else\n    #define CYTHON_CCOMPLEX 0\n  #endif\n#endif\n#if CYTHON_CCOMPLEX\n  #ifdef __cplusplus\n    #include <complex>\n  #else\n    #include <complex.h>\n  #endif\n#endif\n#if CYTHON_CCOMPLEX && !defined(__cplusplus) && defined(__sun__) && defined(__GNUC__)\n  #undef _Complex_I\n  #define _Complex_I 1.0fj\n#endif\n\n\nstatic const char *__pyx_f[] = {\n  \"gpu_nms.pyx\",\n  \"__init__.pxd\",\n  \"type.pxd\",\n};\n#define IS_UNSIGNED(type) (((type) -1) > 0)\nstruct __Pyx_StructField_;\n#define __PYX_BUF_FLAGS_PACKED_STRUCT (1 << 0)\ntypedef struct {\n  const char* name; /* for error messages only */\n  struct __Pyx_StructField_* fields;\n  size_t size;     /* sizeof(type) */\n  size_t arraysize[8]; /* length of array in each dimension */\n  int ndim;\n  char typegroup; /* _R_eal, _C_omplex, Signed _I_nt, _U_nsigned int, _S_truct, _P_ointer, _O_bject, c_H_ar */\n  char is_unsigned;\n  int flags;\n} __Pyx_TypeInfo;\ntypedef struct __Pyx_StructField_ {\n  __Pyx_TypeInfo* type;\n  const char* name;\n  size_t offset;\n} __Pyx_StructField;\ntypedef struct {\n  __Pyx_StructField* field;\n  size_t parent_offset;\n} __Pyx_BufFmt_StackElem;\ntypedef struct {\n  __Pyx_StructField root;\n  __Pyx_BufFmt_StackElem* head;\n  size_t fmt_offset;\n  size_t new_count, enc_count;\n  size_t struct_alignment;\n  int is_complex;\n  char enc_type;\n  char new_packmode;\n  char enc_packmode;\n  char is_valid_array;\n} __Pyx_BufFmt_Context;\n\n\n/* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":723\n * # in Cython to enable them only on the right systems.\n * \n * ctypedef npy_int8       int8_t             # <<<<<<<<<<<<<<\n * ctypedef npy_int16      int16_t\n * ctypedef npy_int32      int32_t\n */\ntypedef npy_int8 __pyx_t_5numpy_int8_t;\n\n/* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":724\n * \n * ctypedef npy_int8       int8_t\n * ctypedef npy_int16      int16_t             # <<<<<<<<<<<<<<\n * ctypedef npy_int32      int32_t\n * ctypedef npy_int64      int64_t\n */\ntypedef npy_int16 __pyx_t_5numpy_int16_t;\n\n/* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":725\n * ctypedef npy_int8       int8_t\n * ctypedef npy_int16      int16_t\n * ctypedef npy_int32      int32_t             # <<<<<<<<<<<<<<\n * ctypedef npy_int64      int64_t\n * #ctypedef npy_int96      int96_t\n */\ntypedef npy_int32 __pyx_t_5numpy_int32_t;\n\n/* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":726\n * ctypedef npy_int16      int16_t\n * ctypedef npy_int32      int32_t\n * ctypedef npy_int64      int64_t             # <<<<<<<<<<<<<<\n * #ctypedef npy_int96      int96_t\n * #ctypedef npy_int128     int128_t\n */\ntypedef npy_int64 __pyx_t_5numpy_int64_t;\n\n/* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":730\n * #ctypedef npy_int128     int128_t\n * \n * ctypedef npy_uint8      uint8_t             # <<<<<<<<<<<<<<\n * ctypedef npy_uint16     uint16_t\n * ctypedef npy_uint32     uint32_t\n */\ntypedef npy_uint8 __pyx_t_5numpy_uint8_t;\n\n/* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":731\n * \n * ctypedef npy_uint8      uint8_t\n * ctypedef npy_uint16     uint16_t             # <<<<<<<<<<<<<<\n * ctypedef npy_uint32     uint32_t\n * ctypedef npy_uint64     uint64_t\n */\ntypedef npy_uint16 __pyx_t_5numpy_uint16_t;\n\n/* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":732\n * ctypedef npy_uint8      uint8_t\n * ctypedef npy_uint16     uint16_t\n * ctypedef npy_uint32     uint32_t             # <<<<<<<<<<<<<<\n * ctypedef npy_uint64     uint64_t\n * #ctypedef npy_uint96     uint96_t\n */\ntypedef npy_uint32 __pyx_t_5numpy_uint32_t;\n\n/* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":733\n * ctypedef npy_uint16     uint16_t\n * ctypedef npy_uint32     uint32_t\n * ctypedef npy_uint64     uint64_t             # <<<<<<<<<<<<<<\n * #ctypedef npy_uint96     uint96_t\n * #ctypedef npy_uint128    uint128_t\n */\ntypedef npy_uint64 __pyx_t_5numpy_uint64_t;\n\n/* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":737\n * #ctypedef npy_uint128    uint128_t\n * \n * ctypedef npy_float32    float32_t             # <<<<<<<<<<<<<<\n * ctypedef npy_float64    float64_t\n * #ctypedef npy_float80    float80_t\n */\ntypedef npy_float32 __pyx_t_5numpy_float32_t;\n\n/* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":738\n * \n * ctypedef npy_float32    float32_t\n * ctypedef npy_float64    float64_t             # <<<<<<<<<<<<<<\n * #ctypedef npy_float80    float80_t\n * #ctypedef npy_float128   float128_t\n */\ntypedef npy_float64 __pyx_t_5numpy_float64_t;\n\n/* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":747\n * # The int types are mapped a bit surprising --\n * # numpy.int corresponds to 'l' and numpy.long to 'q'\n * ctypedef npy_long       int_t             # <<<<<<<<<<<<<<\n * ctypedef npy_longlong   long_t\n * ctypedef npy_longlong   longlong_t\n */\ntypedef npy_long __pyx_t_5numpy_int_t;\n\n/* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":748\n * # numpy.int corresponds to 'l' and numpy.long to 'q'\n * ctypedef npy_long       int_t\n * ctypedef npy_longlong   long_t             # <<<<<<<<<<<<<<\n * ctypedef npy_longlong   longlong_t\n * \n */\ntypedef npy_longlong __pyx_t_5numpy_long_t;\n\n/* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":749\n * ctypedef npy_long       int_t\n * ctypedef npy_longlong   long_t\n * ctypedef npy_longlong   longlong_t             # <<<<<<<<<<<<<<\n * \n * ctypedef npy_ulong      uint_t\n */\ntypedef npy_longlong __pyx_t_5numpy_longlong_t;\n\n/* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":751\n * ctypedef npy_longlong   longlong_t\n * \n * ctypedef npy_ulong      uint_t             # <<<<<<<<<<<<<<\n * ctypedef npy_ulonglong  ulong_t\n * ctypedef npy_ulonglong  ulonglong_t\n */\ntypedef npy_ulong __pyx_t_5numpy_uint_t;\n\n/* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":752\n * \n * ctypedef npy_ulong      uint_t\n * ctypedef npy_ulonglong  ulong_t             # <<<<<<<<<<<<<<\n * ctypedef npy_ulonglong  ulonglong_t\n * \n */\ntypedef npy_ulonglong __pyx_t_5numpy_ulong_t;\n\n/* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":753\n * ctypedef npy_ulong      uint_t\n * ctypedef npy_ulonglong  ulong_t\n * ctypedef npy_ulonglong  ulonglong_t             # <<<<<<<<<<<<<<\n * \n * ctypedef npy_intp       intp_t\n */\ntypedef npy_ulonglong __pyx_t_5numpy_ulonglong_t;\n\n/* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":755\n * ctypedef npy_ulonglong  ulonglong_t\n * \n * ctypedef npy_intp       intp_t             # <<<<<<<<<<<<<<\n * ctypedef npy_uintp      uintp_t\n * \n */\ntypedef npy_intp __pyx_t_5numpy_intp_t;\n\n/* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":756\n * \n * ctypedef npy_intp       intp_t\n * ctypedef npy_uintp      uintp_t             # <<<<<<<<<<<<<<\n * \n * ctypedef npy_double     float_t\n */\ntypedef npy_uintp __pyx_t_5numpy_uintp_t;\n\n/* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":758\n * ctypedef npy_uintp      uintp_t\n * \n * ctypedef npy_double     float_t             # <<<<<<<<<<<<<<\n * ctypedef npy_double     double_t\n * ctypedef npy_longdouble longdouble_t\n */\ntypedef npy_double __pyx_t_5numpy_float_t;\n\n/* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":759\n * \n * ctypedef npy_double     float_t\n * ctypedef npy_double     double_t             # <<<<<<<<<<<<<<\n * ctypedef npy_longdouble longdouble_t\n * \n */\ntypedef npy_double __pyx_t_5numpy_double_t;\n\n/* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":760\n * ctypedef npy_double     float_t\n * ctypedef npy_double     double_t\n * ctypedef npy_longdouble longdouble_t             # <<<<<<<<<<<<<<\n * \n * ctypedef npy_cfloat      cfloat_t\n */\ntypedef npy_longdouble __pyx_t_5numpy_longdouble_t;\n#if CYTHON_CCOMPLEX\n  #ifdef __cplusplus\n    typedef ::std::complex< float > __pyx_t_float_complex;\n  #else\n    typedef float _Complex __pyx_t_float_complex;\n  #endif\n#else\n    typedef struct { float real, imag; } __pyx_t_float_complex;\n#endif\n\n#if CYTHON_CCOMPLEX\n  #ifdef __cplusplus\n    typedef ::std::complex< double > __pyx_t_double_complex;\n  #else\n    typedef double _Complex __pyx_t_double_complex;\n  #endif\n#else\n    typedef struct { double real, imag; } __pyx_t_double_complex;\n#endif\n\n\n/*--- Type declarations ---*/\n\n/* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":762\n * ctypedef npy_longdouble longdouble_t\n * \n * ctypedef npy_cfloat      cfloat_t             # <<<<<<<<<<<<<<\n * ctypedef npy_cdouble     cdouble_t\n * ctypedef npy_clongdouble clongdouble_t\n */\ntypedef npy_cfloat __pyx_t_5numpy_cfloat_t;\n\n/* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":763\n * \n * ctypedef npy_cfloat      cfloat_t\n * ctypedef npy_cdouble     cdouble_t             # <<<<<<<<<<<<<<\n * ctypedef npy_clongdouble clongdouble_t\n * \n */\ntypedef npy_cdouble __pyx_t_5numpy_cdouble_t;\n\n/* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":764\n * ctypedef npy_cfloat      cfloat_t\n * ctypedef npy_cdouble     cdouble_t\n * ctypedef npy_clongdouble clongdouble_t             # <<<<<<<<<<<<<<\n * \n * ctypedef npy_cdouble     complex_t\n */\ntypedef npy_clongdouble __pyx_t_5numpy_clongdouble_t;\n\n/* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":766\n * ctypedef npy_clongdouble clongdouble_t\n * \n * ctypedef npy_cdouble     complex_t             # <<<<<<<<<<<<<<\n * \n * cdef inline object PyArray_MultiIterNew1(a):\n */\ntypedef npy_cdouble __pyx_t_5numpy_complex_t;\n#ifndef CYTHON_REFNANNY\n  #define CYTHON_REFNANNY 0\n#endif\n#if CYTHON_REFNANNY\n  typedef struct {\n    void (*INCREF)(void*, PyObject*, int);\n    void (*DECREF)(void*, PyObject*, int);\n    void (*GOTREF)(void*, PyObject*, int);\n    void (*GIVEREF)(void*, PyObject*, int);\n    void* (*SetupContext)(const char*, int, const char*);\n    void (*FinishContext)(void**);\n  } __Pyx_RefNannyAPIStruct;\n  static __Pyx_RefNannyAPIStruct *__Pyx_RefNanny = NULL;\n  static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname); /*proto*/\n  #define __Pyx_RefNannyDeclarations void *__pyx_refnanny = NULL;\n#ifdef WITH_THREAD\n  #define __Pyx_RefNannySetupContext(name, acquire_gil) \\\n          if (acquire_gil) { \\\n              PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure(); \\\n              __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__); \\\n              PyGILState_Release(__pyx_gilstate_save); \\\n          } else { \\\n              __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__); \\\n          }\n#else\n  #define __Pyx_RefNannySetupContext(name, acquire_gil) \\\n          __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__)\n#endif\n  #define __Pyx_RefNannyFinishContext() \\\n          __Pyx_RefNanny->FinishContext(&__pyx_refnanny)\n  #define __Pyx_INCREF(r)  __Pyx_RefNanny->INCREF(__pyx_refnanny, (PyObject *)(r), __LINE__)\n  #define __Pyx_DECREF(r)  __Pyx_RefNanny->DECREF(__pyx_refnanny, (PyObject *)(r), __LINE__)\n  #define __Pyx_GOTREF(r)  __Pyx_RefNanny->GOTREF(__pyx_refnanny, (PyObject *)(r), __LINE__)\n  #define __Pyx_GIVEREF(r) __Pyx_RefNanny->GIVEREF(__pyx_refnanny, (PyObject *)(r), __LINE__)\n  #define __Pyx_XINCREF(r)  do { if((r) != NULL) {__Pyx_INCREF(r); }} while(0)\n  #define __Pyx_XDECREF(r)  do { if((r) != NULL) {__Pyx_DECREF(r); }} while(0)\n  #define __Pyx_XGOTREF(r)  do { if((r) != NULL) {__Pyx_GOTREF(r); }} while(0)\n  #define __Pyx_XGIVEREF(r) do { if((r) != NULL) {__Pyx_GIVEREF(r);}} while(0)\n#else\n  #define __Pyx_RefNannyDeclarations\n  #define __Pyx_RefNannySetupContext(name, acquire_gil)\n  #define __Pyx_RefNannyFinishContext()\n  #define __Pyx_INCREF(r) Py_INCREF(r)\n  #define __Pyx_DECREF(r) Py_DECREF(r)\n  #define __Pyx_GOTREF(r)\n  #define __Pyx_GIVEREF(r)\n  #define __Pyx_XINCREF(r) Py_XINCREF(r)\n  #define __Pyx_XDECREF(r) Py_XDECREF(r)\n  #define __Pyx_XGOTREF(r)\n  #define __Pyx_XGIVEREF(r)\n#endif /* CYTHON_REFNANNY */\n#define __Pyx_XDECREF_SET(r, v) do {                            \\\n        PyObject *tmp = (PyObject *) r;                         \\\n        r = v; __Pyx_XDECREF(tmp);                              \\\n    } while (0)\n#define __Pyx_DECREF_SET(r, v) do {                             \\\n        PyObject *tmp = (PyObject *) r;                         \\\n        r = v; __Pyx_DECREF(tmp);                               \\\n    } while (0)\n#define __Pyx_CLEAR(r)    do { PyObject* tmp = ((PyObject*)(r)); r = NULL; __Pyx_DECREF(tmp);} while(0)\n#define __Pyx_XCLEAR(r)   do { if((r) != NULL) {PyObject* tmp = ((PyObject*)(r)); r = NULL; __Pyx_DECREF(tmp);}} while(0)\n\nstatic void __Pyx_RaiseArgtupleInvalid(const char* func_name, int exact,\n    Py_ssize_t num_min, Py_ssize_t num_max, Py_ssize_t num_found); /*proto*/\n\nstatic void __Pyx_RaiseDoubleKeywordsError(const char* func_name, PyObject* kw_name); /*proto*/\n\nstatic int __Pyx_ParseOptionalKeywords(PyObject *kwds, PyObject **argnames[], \\\n    PyObject *kwds2, PyObject *values[], Py_ssize_t num_pos_args, \\\n    const char* function_name); /*proto*/\n\nstatic CYTHON_INLINE int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed,\n    const char *name, int exact); /*proto*/\n\nstatic CYTHON_INLINE int  __Pyx_GetBufferAndValidate(Py_buffer* buf, PyObject* obj,\n    __Pyx_TypeInfo* dtype, int flags, int nd, int cast, __Pyx_BufFmt_StackElem* stack);\nstatic CYTHON_INLINE void __Pyx_SafeReleaseBuffer(Py_buffer* info);\n\n#if CYTHON_COMPILING_IN_CPYTHON\nstatic CYTHON_INLINE PyObject* __Pyx_PyObject_GetAttrStr(PyObject* obj, PyObject* attr_name) {\n    PyTypeObject* tp = Py_TYPE(obj);\n    if (likely(tp->tp_getattro))\n        return tp->tp_getattro(obj, attr_name);\n#if PY_MAJOR_VERSION < 3\n    if (likely(tp->tp_getattr))\n        return tp->tp_getattr(obj, PyString_AS_STRING(attr_name));\n#endif\n    return PyObject_GetAttr(obj, attr_name);\n}\n#else\n#define __Pyx_PyObject_GetAttrStr(o,n) PyObject_GetAttr(o,n)\n#endif\n\nstatic PyObject *__Pyx_GetBuiltinName(PyObject *name); /*proto*/\n\nstatic CYTHON_INLINE PyObject *__Pyx_GetModuleGlobalName(PyObject *name); /*proto*/\n\n#if CYTHON_COMPILING_IN_CPYTHON\nstatic CYTHON_INLINE PyObject* __Pyx_PyObject_Call(PyObject *func, PyObject *arg, PyObject *kw); /*proto*/\n#else\n#define __Pyx_PyObject_Call(func, arg, kw) PyObject_Call(func, arg, kw)\n#endif\n\nstatic CYTHON_INLINE int __Pyx_TypeTest(PyObject *obj, PyTypeObject *type); /*proto*/\n\nstatic void __Pyx_RaiseBufferIndexError(int axis); /*proto*/\n\n#define __Pyx_BufPtrStrided1d(type, buf, i0, s0) (type)((char*)buf + i0 * s0)\n#define __Pyx_BufPtrStrided2d(type, buf, i0, s0, i1, s1) (type)((char*)buf + i0 * s0 + i1 * s1)\nstatic CYTHON_INLINE PyObject* __Pyx_PyObject_GetSlice(\n        PyObject* obj, Py_ssize_t cstart, Py_ssize_t cstop,\n        PyObject** py_start, PyObject** py_stop, PyObject** py_slice,\n        int has_cstart, int has_cstop, int wraparound);\n\nstatic void __Pyx_RaiseBufferFallbackError(void); /*proto*/\n\nstatic CYTHON_INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb); /*proto*/\nstatic CYTHON_INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb); /*proto*/\n\nstatic void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject *cause); /*proto*/\n\nstatic CYTHON_INLINE void __Pyx_RaiseTooManyValuesError(Py_ssize_t expected);\n\nstatic CYTHON_INLINE void __Pyx_RaiseNeedMoreValuesError(Py_ssize_t index);\n\nstatic CYTHON_INLINE void __Pyx_RaiseNoneNotIterableError(void);\n\ntypedef struct {\n  Py_ssize_t shape, strides, suboffsets;\n} __Pyx_Buf_DimInfo;\ntypedef struct {\n  size_t refcount;\n  Py_buffer pybuffer;\n} __Pyx_Buffer;\ntypedef struct {\n  __Pyx_Buffer *rcbuffer;\n  char *data;\n  __Pyx_Buf_DimInfo diminfo[8];\n} __Pyx_LocalBuf_ND;\n\n#if PY_MAJOR_VERSION < 3\n    static int __Pyx_GetBuffer(PyObject *obj, Py_buffer *view, int flags);\n    static void __Pyx_ReleaseBuffer(Py_buffer *view);\n#else\n    #define __Pyx_GetBuffer PyObject_GetBuffer\n    #define __Pyx_ReleaseBuffer PyBuffer_Release\n#endif\n\n\nstatic Py_ssize_t __Pyx_zeros[] = {0, 0, 0, 0, 0, 0, 0, 0};\nstatic Py_ssize_t __Pyx_minusones[] = {-1, -1, -1, -1, -1, -1, -1, -1};\n\nstatic PyObject *__Pyx_Import(PyObject *name, PyObject *from_list, int level); /*proto*/\n\nstatic CYTHON_INLINE npy_int32 __Pyx_PyInt_As_npy_int32(PyObject *);\n\nstatic CYTHON_INLINE PyObject* __Pyx_PyInt_From_int(int value);\n\n#if CYTHON_CCOMPLEX\n  #ifdef __cplusplus\n    #define __Pyx_CREAL(z) ((z).real())\n    #define __Pyx_CIMAG(z) ((z).imag())\n  #else\n    #define __Pyx_CREAL(z) (__real__(z))\n    #define __Pyx_CIMAG(z) (__imag__(z))\n  #endif\n#else\n    #define __Pyx_CREAL(z) ((z).real)\n    #define __Pyx_CIMAG(z) ((z).imag)\n#endif\n#if (defined(_WIN32) || defined(__clang__)) && defined(__cplusplus) && CYTHON_CCOMPLEX\n    #define __Pyx_SET_CREAL(z,x) ((z).real(x))\n    #define __Pyx_SET_CIMAG(z,y) ((z).imag(y))\n#else\n    #define __Pyx_SET_CREAL(z,x) __Pyx_CREAL(z) = (x)\n    #define __Pyx_SET_CIMAG(z,y) __Pyx_CIMAG(z) = (y)\n#endif\n\nstatic CYTHON_INLINE __pyx_t_float_complex __pyx_t_float_complex_from_parts(float, float);\n\n#if CYTHON_CCOMPLEX\n    #define __Pyx_c_eqf(a, b)   ((a)==(b))\n    #define __Pyx_c_sumf(a, b)  ((a)+(b))\n    #define __Pyx_c_difff(a, b) ((a)-(b))\n    #define __Pyx_c_prodf(a, b) ((a)*(b))\n    #define __Pyx_c_quotf(a, b) ((a)/(b))\n    #define __Pyx_c_negf(a)     (-(a))\n  #ifdef __cplusplus\n    #define __Pyx_c_is_zerof(z) ((z)==(float)0)\n    #define __Pyx_c_conjf(z)    (::std::conj(z))\n    #if 1\n        #define __Pyx_c_absf(z)     (::std::abs(z))\n        #define __Pyx_c_powf(a, b)  (::std::pow(a, b))\n    #endif\n  #else\n    #define __Pyx_c_is_zerof(z) ((z)==0)\n    #define __Pyx_c_conjf(z)    (conjf(z))\n    #if 1\n        #define __Pyx_c_absf(z)     (cabsf(z))\n        #define __Pyx_c_powf(a, b)  (cpowf(a, b))\n    #endif\n #endif\n#else\n    static CYTHON_INLINE int __Pyx_c_eqf(__pyx_t_float_complex, __pyx_t_float_complex);\n    static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_sumf(__pyx_t_float_complex, __pyx_t_float_complex);\n    static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_difff(__pyx_t_float_complex, __pyx_t_float_complex);\n    static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_prodf(__pyx_t_float_complex, __pyx_t_float_complex);\n    static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_quotf(__pyx_t_float_complex, __pyx_t_float_complex);\n    static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_negf(__pyx_t_float_complex);\n    static CYTHON_INLINE int __Pyx_c_is_zerof(__pyx_t_float_complex);\n    static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_conjf(__pyx_t_float_complex);\n    #if 1\n        static CYTHON_INLINE float __Pyx_c_absf(__pyx_t_float_complex);\n        static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_powf(__pyx_t_float_complex, __pyx_t_float_complex);\n    #endif\n#endif\n\nstatic CYTHON_INLINE __pyx_t_double_complex __pyx_t_double_complex_from_parts(double, double);\n\n#if CYTHON_CCOMPLEX\n    #define __Pyx_c_eq(a, b)   ((a)==(b))\n    #define __Pyx_c_sum(a, b)  ((a)+(b))\n    #define __Pyx_c_diff(a, b) ((a)-(b))\n    #define __Pyx_c_prod(a, b) ((a)*(b))\n    #define __Pyx_c_quot(a, b) ((a)/(b))\n    #define __Pyx_c_neg(a)     (-(a))\n  #ifdef __cplusplus\n    #define __Pyx_c_is_zero(z) ((z)==(double)0)\n    #define __Pyx_c_conj(z)    (::std::conj(z))\n    #if 1\n        #define __Pyx_c_abs(z)     (::std::abs(z))\n        #define __Pyx_c_pow(a, b)  (::std::pow(a, b))\n    #endif\n  #else\n    #define __Pyx_c_is_zero(z) ((z)==0)\n    #define __Pyx_c_conj(z)    (conj(z))\n    #if 1\n        #define __Pyx_c_abs(z)     (cabs(z))\n        #define __Pyx_c_pow(a, b)  (cpow(a, b))\n    #endif\n #endif\n#else\n    static CYTHON_INLINE int __Pyx_c_eq(__pyx_t_double_complex, __pyx_t_double_complex);\n    static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_sum(__pyx_t_double_complex, __pyx_t_double_complex);\n    static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_diff(__pyx_t_double_complex, __pyx_t_double_complex);\n    static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_prod(__pyx_t_double_complex, __pyx_t_double_complex);\n    static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_quot(__pyx_t_double_complex, __pyx_t_double_complex);\n    static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_neg(__pyx_t_double_complex);\n    static CYTHON_INLINE int __Pyx_c_is_zero(__pyx_t_double_complex);\n    static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_conj(__pyx_t_double_complex);\n    #if 1\n        static CYTHON_INLINE double __Pyx_c_abs(__pyx_t_double_complex);\n        static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_pow(__pyx_t_double_complex, __pyx_t_double_complex);\n    #endif\n#endif\n\nstatic CYTHON_INLINE int __Pyx_PyInt_As_int(PyObject *);\n\nstatic CYTHON_INLINE PyObject* __Pyx_PyInt_From_long(long value);\n\nstatic CYTHON_INLINE long __Pyx_PyInt_As_long(PyObject *);\n\nstatic int __Pyx_check_binary_version(void);\n\n#if !defined(__Pyx_PyIdentifier_FromString)\n#if PY_MAJOR_VERSION < 3\n  #define __Pyx_PyIdentifier_FromString(s) PyString_FromString(s)\n#else\n  #define __Pyx_PyIdentifier_FromString(s) PyUnicode_FromString(s)\n#endif\n#endif\n\nstatic PyObject *__Pyx_ImportModule(const char *name); /*proto*/\n\nstatic PyTypeObject *__Pyx_ImportType(const char *module_name, const char *class_name, size_t size, int strict);  /*proto*/\n\ntypedef struct {\n    int code_line;\n    PyCodeObject* code_object;\n} __Pyx_CodeObjectCacheEntry;\nstruct __Pyx_CodeObjectCache {\n    int count;\n    int max_count;\n    __Pyx_CodeObjectCacheEntry* entries;\n};\nstatic struct __Pyx_CodeObjectCache __pyx_code_cache = {0,0,NULL};\nstatic int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line);\nstatic PyCodeObject *__pyx_find_code_object(int code_line);\nstatic void __pyx_insert_code_object(int code_line, PyCodeObject* code_object);\n\nstatic void __Pyx_AddTraceback(const char *funcname, int c_line,\n                               int py_line, const char *filename); /*proto*/\n\nstatic int __Pyx_InitStrings(__Pyx_StringTabEntry *t); /*proto*/\n\n\n/* Module declarations from 'cpython.buffer' */\n\n/* Module declarations from 'cpython.ref' */\n\n/* Module declarations from 'libc.string' */\n\n/* Module declarations from 'libc.stdio' */\n\n/* Module declarations from 'cpython.object' */\n\n/* Module declarations from '__builtin__' */\n\n/* Module declarations from 'cpython.type' */\nstatic PyTypeObject *__pyx_ptype_7cpython_4type_type = 0;\n\n/* Module declarations from 'libc.stdlib' */\n\n/* Module declarations from 'numpy' */\n\n/* Module declarations from 'numpy' */\nstatic PyTypeObject *__pyx_ptype_5numpy_dtype = 0;\nstatic PyTypeObject *__pyx_ptype_5numpy_flatiter = 0;\nstatic PyTypeObject *__pyx_ptype_5numpy_broadcast = 0;\nstatic PyTypeObject *__pyx_ptype_5numpy_ndarray = 0;\nstatic PyTypeObject *__pyx_ptype_5numpy_ufunc = 0;\nstatic CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *, char *, char *, int *); /*proto*/\n\n/* Module declarations from 'nms.gpu_nms' */\nstatic __Pyx_TypeInfo __Pyx_TypeInfo_nn___pyx_t_5numpy_float32_t = { \"float32_t\", NULL, sizeof(__pyx_t_5numpy_float32_t), { 0 }, 0, 'R', 0, 0 };\nstatic __Pyx_TypeInfo __Pyx_TypeInfo_nn___pyx_t_5numpy_int32_t = { \"int32_t\", NULL, sizeof(__pyx_t_5numpy_int32_t), { 0 }, 0, IS_UNSIGNED(__pyx_t_5numpy_int32_t) ? 'U' : 'I', IS_UNSIGNED(__pyx_t_5numpy_int32_t), 0 };\nstatic __Pyx_TypeInfo __Pyx_TypeInfo_nn___pyx_t_5numpy_int_t = { \"int_t\", NULL, sizeof(__pyx_t_5numpy_int_t), { 0 }, 0, IS_UNSIGNED(__pyx_t_5numpy_int_t) ? 'U' : 'I', IS_UNSIGNED(__pyx_t_5numpy_int_t), 0 };\n#define __Pyx_MODULE_NAME \"nms.gpu_nms\"\nint __pyx_module_is_main_nms__gpu_nms = 0;\n\n/* Implementation of 'nms.gpu_nms' */\nstatic PyObject *__pyx_builtin_ValueError;\nstatic PyObject *__pyx_builtin_range;\nstatic PyObject *__pyx_builtin_RuntimeError;\nstatic PyObject *__pyx_pf_3nms_7gpu_nms_gpu_nms(CYTHON_UNUSED PyObject *__pyx_self, PyArrayObject *__pyx_v_dets, PyObject *__pyx_v_thresh, __pyx_t_5numpy_int32_t __pyx_v_device_id); /* proto */\nstatic int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags); /* proto */\nstatic void __pyx_pf_5numpy_7ndarray_2__releasebuffer__(PyArrayObject *__pyx_v_self, Py_buffer *__pyx_v_info); /* proto */\nstatic char __pyx_k_B[] = \"B\";\nstatic char __pyx_k_H[] = \"H\";\nstatic char __pyx_k_I[] = \"I\";\nstatic char __pyx_k_L[] = \"L\";\nstatic char __pyx_k_O[] = \"O\";\nstatic char __pyx_k_Q[] = \"Q\";\nstatic char __pyx_k_b[] = \"b\";\nstatic char __pyx_k_d[] = \"d\";\nstatic char __pyx_k_f[] = \"f\";\nstatic char __pyx_k_g[] = \"g\";\nstatic char __pyx_k_h[] = \"h\";\nstatic char __pyx_k_i[] = \"i\";\nstatic char __pyx_k_l[] = \"l\";\nstatic char __pyx_k_q[] = \"q\";\nstatic char __pyx_k_Zd[] = \"Zd\";\nstatic char __pyx_k_Zf[] = \"Zf\";\nstatic char __pyx_k_Zg[] = \"Zg\";\nstatic char __pyx_k_np[] = \"np\";\nstatic char __pyx_k_dets[] = \"dets\";\nstatic char __pyx_k_keep[] = \"keep\";\nstatic char __pyx_k_main[] = \"__main__\";\nstatic char __pyx_k_test[] = \"__test__\";\nstatic char __pyx_k_dtype[] = \"dtype\";\nstatic char __pyx_k_int32[] = \"int32\";\nstatic char __pyx_k_numpy[] = \"numpy\";\nstatic char __pyx_k_order[] = \"order\";\nstatic char __pyx_k_range[] = \"range\";\nstatic char __pyx_k_zeros[] = \"zeros\";\nstatic char __pyx_k_import[] = \"__import__\";\nstatic char __pyx_k_scores[] = \"scores\";\nstatic char __pyx_k_thresh[] = \"thresh\";\nstatic char __pyx_k_argsort[] = \"argsort\";\nstatic char __pyx_k_gpu_nms[] = \"gpu_nms\";\nstatic char __pyx_k_num_out[] = \"num_out\";\nstatic char __pyx_k_boxes_dim[] = \"boxes_dim\";\nstatic char __pyx_k_boxes_num[] = \"boxes_num\";\nstatic char __pyx_k_device_id[] = \"device_id\";\nstatic char __pyx_k_ValueError[] = \"ValueError\";\nstatic char __pyx_k_nms_gpu_nms[] = \"nms.gpu_nms\";\nstatic char __pyx_k_sorted_dets[] = \"sorted_dets\";\nstatic char __pyx_k_RuntimeError[] = \"RuntimeError\";\nstatic char __pyx_k_pyx_getbuffer[] = \"__pyx_getbuffer\";\nstatic char __pyx_k_pyx_releasebuffer[] = \"__pyx_releasebuffer\";\nstatic char __pyx_k_ndarray_is_not_C_contiguous[] = \"ndarray is not C contiguous\";\nstatic char __pyx_k_nfs_yoda_xinleic_Inf_Code_Faste[] = \"/nfs.yoda/xinleic/Inf/Code/Faster-RCNN_TF/lib/nms/gpu_nms.pyx\";\nstatic char __pyx_k_unknown_dtype_code_in_numpy_pxd[] = \"unknown dtype code in numpy.pxd (%d)\";\nstatic char __pyx_k_Format_string_allocated_too_shor[] = \"Format string allocated too short, see comment in numpy.pxd\";\nstatic char __pyx_k_Non_native_byte_order_not_suppor[] = \"Non-native byte order not supported\";\nstatic char __pyx_k_ndarray_is_not_Fortran_contiguou[] = \"ndarray is not Fortran contiguous\";\nstatic char __pyx_k_Format_string_allocated_too_shor_2[] = \"Format string allocated too short.\";\nstatic PyObject *__pyx_kp_u_Format_string_allocated_too_shor;\nstatic PyObject *__pyx_kp_u_Format_string_allocated_too_shor_2;\nstatic PyObject *__pyx_kp_u_Non_native_byte_order_not_suppor;\nstatic PyObject *__pyx_n_s_RuntimeError;\nstatic PyObject *__pyx_n_s_ValueError;\nstatic PyObject *__pyx_n_s_argsort;\nstatic PyObject *__pyx_n_s_boxes_dim;\nstatic PyObject *__pyx_n_s_boxes_num;\nstatic PyObject *__pyx_n_s_dets;\nstatic PyObject *__pyx_n_s_device_id;\nstatic PyObject *__pyx_n_s_dtype;\nstatic PyObject *__pyx_n_s_gpu_nms;\nstatic PyObject *__pyx_n_s_import;\nstatic PyObject *__pyx_n_s_int32;\nstatic PyObject *__pyx_n_s_keep;\nstatic PyObject *__pyx_n_s_main;\nstatic PyObject *__pyx_kp_u_ndarray_is_not_C_contiguous;\nstatic PyObject *__pyx_kp_u_ndarray_is_not_Fortran_contiguou;\nstatic PyObject *__pyx_kp_s_nfs_yoda_xinleic_Inf_Code_Faste;\nstatic PyObject *__pyx_n_s_nms_gpu_nms;\nstatic PyObject *__pyx_n_s_np;\nstatic PyObject *__pyx_n_s_num_out;\nstatic PyObject *__pyx_n_s_numpy;\nstatic PyObject *__pyx_n_s_order;\nstatic PyObject *__pyx_n_s_pyx_getbuffer;\nstatic PyObject *__pyx_n_s_pyx_releasebuffer;\nstatic PyObject *__pyx_n_s_range;\nstatic PyObject *__pyx_n_s_scores;\nstatic PyObject *__pyx_n_s_sorted_dets;\nstatic PyObject *__pyx_n_s_test;\nstatic PyObject *__pyx_n_s_thresh;\nstatic PyObject *__pyx_kp_u_unknown_dtype_code_in_numpy_pxd;\nstatic PyObject *__pyx_n_s_zeros;\nstatic PyObject *__pyx_int_4;\nstatic PyObject *__pyx_int_neg_1;\nstatic PyObject *__pyx_slice_;\nstatic PyObject *__pyx_slice__3;\nstatic PyObject *__pyx_slice__4;\nstatic PyObject *__pyx_tuple__2;\nstatic PyObject *__pyx_tuple__5;\nstatic PyObject *__pyx_tuple__6;\nstatic PyObject *__pyx_tuple__7;\nstatic PyObject *__pyx_tuple__8;\nstatic PyObject *__pyx_tuple__9;\nstatic PyObject *__pyx_tuple__10;\nstatic PyObject *__pyx_tuple__11;\nstatic PyObject *__pyx_codeobj__12;\n\n/* \"nms/gpu_nms.pyx\":16\n *     void _nms(np.int32_t*, int*, np.float32_t*, int, int, float, int)\n * \n * def gpu_nms(np.ndarray[np.float32_t, ndim=2] dets, np.float thresh,             # <<<<<<<<<<<<<<\n *             np.int32_t device_id=0):\n *     cdef int boxes_num = dets.shape[0]\n */\n\n/* Python wrapper */\nstatic PyObject *__pyx_pw_3nms_7gpu_nms_1gpu_nms(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/\nstatic PyMethodDef __pyx_mdef_3nms_7gpu_nms_1gpu_nms = {__Pyx_NAMESTR(\"gpu_nms\"), (PyCFunction)__pyx_pw_3nms_7gpu_nms_1gpu_nms, METH_VARARGS|METH_KEYWORDS, __Pyx_DOCSTR(0)};\nstatic PyObject *__pyx_pw_3nms_7gpu_nms_1gpu_nms(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {\n  PyArrayObject *__pyx_v_dets = 0;\n  PyObject *__pyx_v_thresh = 0;\n  __pyx_t_5numpy_int32_t __pyx_v_device_id;\n  int __pyx_lineno = 0;\n  const char *__pyx_filename = NULL;\n  int __pyx_clineno = 0;\n  PyObject *__pyx_r = 0;\n  __Pyx_RefNannyDeclarations\n  __Pyx_RefNannySetupContext(\"gpu_nms (wrapper)\", 0);\n  {\n    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_dets,&__pyx_n_s_thresh,&__pyx_n_s_device_id,0};\n    PyObject* values[3] = {0,0,0};\n    if (unlikely(__pyx_kwds)) {\n      Py_ssize_t kw_args;\n      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);\n      switch (pos_args) {\n        case  3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);\n        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);\n        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);\n        case  0: break;\n        default: goto __pyx_L5_argtuple_error;\n      }\n      kw_args = PyDict_Size(__pyx_kwds);\n      switch (pos_args) {\n        case  0:\n        if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_dets)) != 0)) kw_args--;\n        else goto __pyx_L5_argtuple_error;\n        case  1:\n        if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_thresh)) != 0)) kw_args--;\n        else {\n          __Pyx_RaiseArgtupleInvalid(\"gpu_nms\", 0, 2, 3, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 16; __pyx_clineno = __LINE__; goto __pyx_L3_error;}\n        }\n        case  2:\n        if (kw_args > 0) {\n          PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_device_id);\n          if (value) { values[2] = value; kw_args--; }\n        }\n      }\n      if (unlikely(kw_args > 0)) {\n        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, \"gpu_nms\") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 16; __pyx_clineno = __LINE__; goto __pyx_L3_error;}\n      }\n    } else {\n      switch (PyTuple_GET_SIZE(__pyx_args)) {\n        case  3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);\n        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);\n        values[0] = PyTuple_GET_ITEM(__pyx_args, 0);\n        break;\n        default: goto __pyx_L5_argtuple_error;\n      }\n    }\n    __pyx_v_dets = ((PyArrayObject *)values[0]);\n    __pyx_v_thresh = ((PyObject*)values[1]);\n    if (values[2]) {\n      __pyx_v_device_id = __Pyx_PyInt_As_npy_int32(values[2]); if (unlikely((__pyx_v_device_id == (npy_int32)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 17; __pyx_clineno = __LINE__; goto __pyx_L3_error;}\n    } else {\n      __pyx_v_device_id = ((__pyx_t_5numpy_int32_t)0);\n    }\n  }\n  goto __pyx_L4_argument_unpacking_done;\n  __pyx_L5_argtuple_error:;\n  __Pyx_RaiseArgtupleInvalid(\"gpu_nms\", 0, 2, 3, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 16; __pyx_clineno = __LINE__; goto __pyx_L3_error;}\n  __pyx_L3_error:;\n  __Pyx_AddTraceback(\"nms.gpu_nms.gpu_nms\", __pyx_clineno, __pyx_lineno, __pyx_filename);\n  __Pyx_RefNannyFinishContext();\n  return NULL;\n  __pyx_L4_argument_unpacking_done:;\n  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_dets), __pyx_ptype_5numpy_ndarray, 1, \"dets\", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 16; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_thresh), (&PyFloat_Type), 1, \"thresh\", 1))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 16; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n  __pyx_r = __pyx_pf_3nms_7gpu_nms_gpu_nms(__pyx_self, __pyx_v_dets, __pyx_v_thresh, __pyx_v_device_id);\n\n  /* function exit code */\n  goto __pyx_L0;\n  __pyx_L1_error:;\n  __pyx_r = NULL;\n  __pyx_L0:;\n  __Pyx_RefNannyFinishContext();\n  return __pyx_r;\n}\n\nstatic PyObject *__pyx_pf_3nms_7gpu_nms_gpu_nms(CYTHON_UNUSED PyObject *__pyx_self, PyArrayObject *__pyx_v_dets, PyObject *__pyx_v_thresh, __pyx_t_5numpy_int32_t __pyx_v_device_id) {\n  int __pyx_v_boxes_num;\n  int __pyx_v_boxes_dim;\n  int __pyx_v_num_out;\n  PyArrayObject *__pyx_v_keep = 0;\n  PyArrayObject *__pyx_v_scores = 0;\n  PyArrayObject *__pyx_v_order = 0;\n  PyArrayObject *__pyx_v_sorted_dets = 0;\n  __Pyx_LocalBuf_ND __pyx_pybuffernd_dets;\n  __Pyx_Buffer __pyx_pybuffer_dets;\n  __Pyx_LocalBuf_ND __pyx_pybuffernd_keep;\n  __Pyx_Buffer __pyx_pybuffer_keep;\n  __Pyx_LocalBuf_ND __pyx_pybuffernd_order;\n  __Pyx_Buffer __pyx_pybuffer_order;\n  __Pyx_LocalBuf_ND __pyx_pybuffernd_scores;\n  __Pyx_Buffer __pyx_pybuffer_scores;\n  __Pyx_LocalBuf_ND __pyx_pybuffernd_sorted_dets;\n  __Pyx_Buffer __pyx_pybuffer_sorted_dets;\n  PyObject *__pyx_r = NULL;\n  __Pyx_RefNannyDeclarations\n  PyObject *__pyx_t_1 = NULL;\n  PyObject *__pyx_t_2 = NULL;\n  PyObject *__pyx_t_3 = NULL;\n  PyObject *__pyx_t_4 = NULL;\n  PyObject *__pyx_t_5 = NULL;\n  PyArrayObject *__pyx_t_6 = NULL;\n  PyArrayObject *__pyx_t_7 = NULL;\n  PyArrayObject *__pyx_t_8 = NULL;\n  PyArrayObject *__pyx_t_9 = NULL;\n  long __pyx_t_10;\n  int __pyx_t_11;\n  long __pyx_t_12;\n  long __pyx_t_13;\n  float __pyx_t_14;\n  PyObject *__pyx_t_15 = NULL;\n  PyObject *__pyx_t_16 = NULL;\n  PyObject *__pyx_t_17 = NULL;\n  int __pyx_lineno = 0;\n  const char *__pyx_filename = NULL;\n  int __pyx_clineno = 0;\n  __Pyx_RefNannySetupContext(\"gpu_nms\", 0);\n  __pyx_pybuffer_keep.pybuffer.buf = NULL;\n  __pyx_pybuffer_keep.refcount = 0;\n  __pyx_pybuffernd_keep.data = NULL;\n  __pyx_pybuffernd_keep.rcbuffer = &__pyx_pybuffer_keep;\n  __pyx_pybuffer_scores.pybuffer.buf = NULL;\n  __pyx_pybuffer_scores.refcount = 0;\n  __pyx_pybuffernd_scores.data = NULL;\n  __pyx_pybuffernd_scores.rcbuffer = &__pyx_pybuffer_scores;\n  __pyx_pybuffer_order.pybuffer.buf = NULL;\n  __pyx_pybuffer_order.refcount = 0;\n  __pyx_pybuffernd_order.data = NULL;\n  __pyx_pybuffernd_order.rcbuffer = &__pyx_pybuffer_order;\n  __pyx_pybuffer_sorted_dets.pybuffer.buf = NULL;\n  __pyx_pybuffer_sorted_dets.refcount = 0;\n  __pyx_pybuffernd_sorted_dets.data = NULL;\n  __pyx_pybuffernd_sorted_dets.rcbuffer = &__pyx_pybuffer_sorted_dets;\n  __pyx_pybuffer_dets.pybuffer.buf = NULL;\n  __pyx_pybuffer_dets.refcount = 0;\n  __pyx_pybuffernd_dets.data = NULL;\n  __pyx_pybuffernd_dets.rcbuffer = &__pyx_pybuffer_dets;\n  {\n    __Pyx_BufFmt_StackElem __pyx_stack[1];\n    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_dets.rcbuffer->pybuffer, (PyObject*)__pyx_v_dets, &__Pyx_TypeInfo_nn___pyx_t_5numpy_float32_t, PyBUF_FORMAT| PyBUF_STRIDES, 2, 0, __pyx_stack) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 16; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n  }\n  __pyx_pybuffernd_dets.diminfo[0].strides = __pyx_pybuffernd_dets.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_dets.diminfo[0].shape = __pyx_pybuffernd_dets.rcbuffer->pybuffer.shape[0]; __pyx_pybuffernd_dets.diminfo[1].strides = __pyx_pybuffernd_dets.rcbuffer->pybuffer.strides[1]; __pyx_pybuffernd_dets.diminfo[1].shape = __pyx_pybuffernd_dets.rcbuffer->pybuffer.shape[1];\n\n  /* \"nms/gpu_nms.pyx\":18\n * def gpu_nms(np.ndarray[np.float32_t, ndim=2] dets, np.float thresh,\n *             np.int32_t device_id=0):\n *     cdef int boxes_num = dets.shape[0]             # <<<<<<<<<<<<<<\n *     cdef int boxes_dim = dets.shape[1]\n *     cdef int num_out\n */\n  __pyx_v_boxes_num = (__pyx_v_dets->dimensions[0]);\n\n  /* \"nms/gpu_nms.pyx\":19\n *             np.int32_t device_id=0):\n *     cdef int boxes_num = dets.shape[0]\n *     cdef int boxes_dim = dets.shape[1]             # <<<<<<<<<<<<<<\n *     cdef int num_out\n *     cdef np.ndarray[np.int32_t, ndim=1] \\\n */\n  __pyx_v_boxes_dim = (__pyx_v_dets->dimensions[1]);\n\n  /* \"nms/gpu_nms.pyx\":22\n *     cdef int num_out\n *     cdef np.ndarray[np.int32_t, ndim=1] \\\n *         keep = np.zeros(boxes_num, dtype=np.int32)             # <<<<<<<<<<<<<<\n *     cdef np.ndarray[np.float32_t, ndim=1] \\\n *         scores = dets[:, 4]\n */\n  __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 22; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n  __Pyx_GOTREF(__pyx_t_1);\n  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_zeros); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 22; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n  __Pyx_GOTREF(__pyx_t_2);\n  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;\n  __pyx_t_1 = __Pyx_PyInt_From_int(__pyx_v_boxes_num); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 22; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n  __Pyx_GOTREF(__pyx_t_1);\n  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 22; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n  __Pyx_GOTREF(__pyx_t_3);\n  PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_1);\n  __Pyx_GIVEREF(__pyx_t_1);\n  __pyx_t_1 = 0;\n  __pyx_t_1 = PyDict_New(); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 22; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n  __Pyx_GOTREF(__pyx_t_1);\n  __pyx_t_4 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 22; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n  __Pyx_GOTREF(__pyx_t_4);\n  __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_int32); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 22; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n  __Pyx_GOTREF(__pyx_t_5);\n  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;\n  if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_dtype, __pyx_t_5) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 22; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;\n  __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_3, __pyx_t_1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 22; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n  __Pyx_GOTREF(__pyx_t_5);\n  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;\n  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;\n  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;\n  if (!(likely(((__pyx_t_5) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_5, __pyx_ptype_5numpy_ndarray))))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 22; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n  __pyx_t_6 = ((PyArrayObject *)__pyx_t_5);\n  {\n    __Pyx_BufFmt_StackElem __pyx_stack[1];\n    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_keep.rcbuffer->pybuffer, (PyObject*)__pyx_t_6, &__Pyx_TypeInfo_nn___pyx_t_5numpy_int32_t, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {\n      __pyx_v_keep = ((PyArrayObject *)Py_None); __Pyx_INCREF(Py_None); __pyx_pybuffernd_keep.rcbuffer->pybuffer.buf = NULL;\n      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 21; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n    } else {__pyx_pybuffernd_keep.diminfo[0].strides = __pyx_pybuffernd_keep.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_keep.diminfo[0].shape = __pyx_pybuffernd_keep.rcbuffer->pybuffer.shape[0];\n    }\n  }\n  __pyx_t_6 = 0;\n  __pyx_v_keep = ((PyArrayObject *)__pyx_t_5);\n  __pyx_t_5 = 0;\n\n  /* \"nms/gpu_nms.pyx\":24\n *         keep = np.zeros(boxes_num, dtype=np.int32)\n *     cdef np.ndarray[np.float32_t, ndim=1] \\\n *         scores = dets[:, 4]             # <<<<<<<<<<<<<<\n *     cdef np.ndarray[np.int_t, ndim=1] \\\n *         order = scores.argsort()[::-1]\n */\n  __pyx_t_5 = PyObject_GetItem(((PyObject *)__pyx_v_dets), __pyx_tuple__2); if (unlikely(__pyx_t_5 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 24; __pyx_clineno = __LINE__; goto __pyx_L1_error;};\n  __Pyx_GOTREF(__pyx_t_5);\n  if (!(likely(((__pyx_t_5) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_5, __pyx_ptype_5numpy_ndarray))))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 24; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n  __pyx_t_7 = ((PyArrayObject *)__pyx_t_5);\n  {\n    __Pyx_BufFmt_StackElem __pyx_stack[1];\n    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_scores.rcbuffer->pybuffer, (PyObject*)__pyx_t_7, &__Pyx_TypeInfo_nn___pyx_t_5numpy_float32_t, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {\n      __pyx_v_scores = ((PyArrayObject *)Py_None); __Pyx_INCREF(Py_None); __pyx_pybuffernd_scores.rcbuffer->pybuffer.buf = NULL;\n      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 23; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n    } else {__pyx_pybuffernd_scores.diminfo[0].strides = __pyx_pybuffernd_scores.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_scores.diminfo[0].shape = __pyx_pybuffernd_scores.rcbuffer->pybuffer.shape[0];\n    }\n  }\n  __pyx_t_7 = 0;\n  __pyx_v_scores = ((PyArrayObject *)__pyx_t_5);\n  __pyx_t_5 = 0;\n\n  /* \"nms/gpu_nms.pyx\":26\n *         scores = dets[:, 4]\n *     cdef np.ndarray[np.int_t, ndim=1] \\\n *         order = scores.argsort()[::-1]             # <<<<<<<<<<<<<<\n *     cdef np.ndarray[np.float32_t, ndim=2] \\\n *         sorted_dets = dets[order, :]\n */\n  __pyx_t_5 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_scores), __pyx_n_s_argsort); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 26; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n  __Pyx_GOTREF(__pyx_t_5);\n  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_empty_tuple, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 26; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n  __Pyx_GOTREF(__pyx_t_1);\n  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;\n  __pyx_t_5 = PyObject_GetItem(__pyx_t_1, __pyx_slice__3); if (unlikely(__pyx_t_5 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 26; __pyx_clineno = __LINE__; goto __pyx_L1_error;};\n  __Pyx_GOTREF(__pyx_t_5);\n  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;\n  if (!(likely(((__pyx_t_5) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_5, __pyx_ptype_5numpy_ndarray))))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 26; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n  __pyx_t_8 = ((PyArrayObject *)__pyx_t_5);\n  {\n    __Pyx_BufFmt_StackElem __pyx_stack[1];\n    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_order.rcbuffer->pybuffer, (PyObject*)__pyx_t_8, &__Pyx_TypeInfo_nn___pyx_t_5numpy_int_t, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {\n      __pyx_v_order = ((PyArrayObject *)Py_None); __Pyx_INCREF(Py_None); __pyx_pybuffernd_order.rcbuffer->pybuffer.buf = NULL;\n      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 25; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n    } else {__pyx_pybuffernd_order.diminfo[0].strides = __pyx_pybuffernd_order.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_order.diminfo[0].shape = __pyx_pybuffernd_order.rcbuffer->pybuffer.shape[0];\n    }\n  }\n  __pyx_t_8 = 0;\n  __pyx_v_order = ((PyArrayObject *)__pyx_t_5);\n  __pyx_t_5 = 0;\n\n  /* \"nms/gpu_nms.pyx\":28\n *         order = scores.argsort()[::-1]\n *     cdef np.ndarray[np.float32_t, ndim=2] \\\n *         sorted_dets = dets[order, :]             # <<<<<<<<<<<<<<\n *     _nms(&keep[0], &num_out, &sorted_dets[0, 0], boxes_num, boxes_dim, thresh, device_id)\n *     keep = keep[:num_out]\n */\n  __pyx_t_5 = PyTuple_New(2); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 28; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n  __Pyx_GOTREF(__pyx_t_5);\n  __Pyx_INCREF(((PyObject *)__pyx_v_order));\n  PyTuple_SET_ITEM(__pyx_t_5, 0, ((PyObject *)__pyx_v_order));\n  __Pyx_GIVEREF(((PyObject *)__pyx_v_order));\n  __Pyx_INCREF(__pyx_slice__4);\n  PyTuple_SET_ITEM(__pyx_t_5, 1, __pyx_slice__4);\n  __Pyx_GIVEREF(__pyx_slice__4);\n  __pyx_t_1 = PyObject_GetItem(((PyObject *)__pyx_v_dets), __pyx_t_5); if (unlikely(__pyx_t_1 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 28; __pyx_clineno = __LINE__; goto __pyx_L1_error;};\n  __Pyx_GOTREF(__pyx_t_1);\n  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;\n  if (!(likely(((__pyx_t_1) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_5numpy_ndarray))))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 28; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n  __pyx_t_9 = ((PyArrayObject *)__pyx_t_1);\n  {\n    __Pyx_BufFmt_StackElem __pyx_stack[1];\n    if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_sorted_dets.rcbuffer->pybuffer, (PyObject*)__pyx_t_9, &__Pyx_TypeInfo_nn___pyx_t_5numpy_float32_t, PyBUF_FORMAT| PyBUF_STRIDES, 2, 0, __pyx_stack) == -1)) {\n      __pyx_v_sorted_dets = ((PyArrayObject *)Py_None); __Pyx_INCREF(Py_None); __pyx_pybuffernd_sorted_dets.rcbuffer->pybuffer.buf = NULL;\n      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 27; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n    } else {__pyx_pybuffernd_sorted_dets.diminfo[0].strides = __pyx_pybuffernd_sorted_dets.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_sorted_dets.diminfo[0].shape = __pyx_pybuffernd_sorted_dets.rcbuffer->pybuffer.shape[0]; __pyx_pybuffernd_sorted_dets.diminfo[1].strides = __pyx_pybuffernd_sorted_dets.rcbuffer->pybuffer.strides[1]; __pyx_pybuffernd_sorted_dets.diminfo[1].shape = __pyx_pybuffernd_sorted_dets.rcbuffer->pybuffer.shape[1];\n    }\n  }\n  __pyx_t_9 = 0;\n  __pyx_v_sorted_dets = ((PyArrayObject *)__pyx_t_1);\n  __pyx_t_1 = 0;\n\n  /* \"nms/gpu_nms.pyx\":29\n *     cdef np.ndarray[np.float32_t, ndim=2] \\\n *         sorted_dets = dets[order, :]\n *     _nms(&keep[0], &num_out, &sorted_dets[0, 0], boxes_num, boxes_dim, thresh, device_id)             # <<<<<<<<<<<<<<\n *     keep = keep[:num_out]\n *     return list(order[keep])\n */\n  __pyx_t_10 = 0;\n  __pyx_t_11 = -1;\n  if (__pyx_t_10 < 0) {\n    __pyx_t_10 += __pyx_pybuffernd_keep.diminfo[0].shape;\n    if (unlikely(__pyx_t_10 < 0)) __pyx_t_11 = 0;\n  } else if (unlikely(__pyx_t_10 >= __pyx_pybuffernd_keep.diminfo[0].shape)) __pyx_t_11 = 0;\n  if (unlikely(__pyx_t_11 != -1)) {\n    __Pyx_RaiseBufferIndexError(__pyx_t_11);\n    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 29; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n  }\n  __pyx_t_12 = 0;\n  __pyx_t_13 = 0;\n  __pyx_t_11 = -1;\n  if (__pyx_t_12 < 0) {\n    __pyx_t_12 += __pyx_pybuffernd_sorted_dets.diminfo[0].shape;\n    if (unlikely(__pyx_t_12 < 0)) __pyx_t_11 = 0;\n  } else if (unlikely(__pyx_t_12 >= __pyx_pybuffernd_sorted_dets.diminfo[0].shape)) __pyx_t_11 = 0;\n  if (__pyx_t_13 < 0) {\n    __pyx_t_13 += __pyx_pybuffernd_sorted_dets.diminfo[1].shape;\n    if (unlikely(__pyx_t_13 < 0)) __pyx_t_11 = 1;\n  } else if (unlikely(__pyx_t_13 >= __pyx_pybuffernd_sorted_dets.diminfo[1].shape)) __pyx_t_11 = 1;\n  if (unlikely(__pyx_t_11 != -1)) {\n    __Pyx_RaiseBufferIndexError(__pyx_t_11);\n    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 29; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n  }\n  __pyx_t_14 = __pyx_PyFloat_AsFloat(__pyx_v_thresh); if (unlikely((__pyx_t_14 == (float)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 29; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n  _nms((&(*__Pyx_BufPtrStrided1d(__pyx_t_5numpy_int32_t *, __pyx_pybuffernd_keep.rcbuffer->pybuffer.buf, __pyx_t_10, __pyx_pybuffernd_keep.diminfo[0].strides))), (&__pyx_v_num_out), (&(*__Pyx_BufPtrStrided2d(__pyx_t_5numpy_float32_t *, __pyx_pybuffernd_sorted_dets.rcbuffer->pybuffer.buf, __pyx_t_12, __pyx_pybuffernd_sorted_dets.diminfo[0].strides, __pyx_t_13, __pyx_pybuffernd_sorted_dets.diminfo[1].strides))), __pyx_v_boxes_num, __pyx_v_boxes_dim, __pyx_t_14, __pyx_v_device_id);\n\n  /* \"nms/gpu_nms.pyx\":30\n *         sorted_dets = dets[order, :]\n *     _nms(&keep[0], &num_out, &sorted_dets[0, 0], boxes_num, boxes_dim, thresh, device_id)\n *     keep = keep[:num_out]             # <<<<<<<<<<<<<<\n *     return list(order[keep])\n */\n  __pyx_t_1 = __Pyx_PyObject_GetSlice(((PyObject *)__pyx_v_keep), 0, __pyx_v_num_out, NULL, NULL, NULL, 0, 1, 1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 30; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n  __Pyx_GOTREF(__pyx_t_1);\n  if (!(likely(((__pyx_t_1) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_5numpy_ndarray))))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 30; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n  __pyx_t_6 = ((PyArrayObject *)__pyx_t_1);\n  {\n    __Pyx_BufFmt_StackElem __pyx_stack[1];\n    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_keep.rcbuffer->pybuffer);\n    __pyx_t_11 = __Pyx_GetBufferAndValidate(&__pyx_pybuffernd_keep.rcbuffer->pybuffer, (PyObject*)__pyx_t_6, &__Pyx_TypeInfo_nn___pyx_t_5numpy_int32_t, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack);\n    if (unlikely(__pyx_t_11 < 0)) {\n      PyErr_Fetch(&__pyx_t_15, &__pyx_t_16, &__pyx_t_17);\n      if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_keep.rcbuffer->pybuffer, (PyObject*)__pyx_v_keep, &__Pyx_TypeInfo_nn___pyx_t_5numpy_int32_t, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) {\n        Py_XDECREF(__pyx_t_15); Py_XDECREF(__pyx_t_16); Py_XDECREF(__pyx_t_17);\n        __Pyx_RaiseBufferFallbackError();\n      } else {\n        PyErr_Restore(__pyx_t_15, __pyx_t_16, __pyx_t_17);\n      }\n    }\n    __pyx_pybuffernd_keep.diminfo[0].strides = __pyx_pybuffernd_keep.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_keep.diminfo[0].shape = __pyx_pybuffernd_keep.rcbuffer->pybuffer.shape[0];\n    if (unlikely(__pyx_t_11 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 30; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n  }\n  __pyx_t_6 = 0;\n  __Pyx_DECREF_SET(__pyx_v_keep, ((PyArrayObject *)__pyx_t_1));\n  __pyx_t_1 = 0;\n\n  /* \"nms/gpu_nms.pyx\":31\n *     _nms(&keep[0], &num_out, &sorted_dets[0, 0], boxes_num, boxes_dim, thresh, device_id)\n *     keep = keep[:num_out]\n *     return list(order[keep])             # <<<<<<<<<<<<<<\n */\n  __Pyx_XDECREF(__pyx_r);\n  __pyx_t_1 = PyObject_GetItem(((PyObject *)__pyx_v_order), ((PyObject *)__pyx_v_keep)); if (unlikely(__pyx_t_1 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 31; __pyx_clineno = __LINE__; goto __pyx_L1_error;};\n  __Pyx_GOTREF(__pyx_t_1);\n  __pyx_t_5 = PyTuple_New(1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 31; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n  __Pyx_GOTREF(__pyx_t_5);\n  PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_1);\n  __Pyx_GIVEREF(__pyx_t_1);\n  __pyx_t_1 = 0;\n  __pyx_t_1 = __Pyx_PyObject_Call(((PyObject *)((PyObject*)(&PyList_Type))), __pyx_t_5, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 31; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n  __Pyx_GOTREF(__pyx_t_1);\n  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;\n  __pyx_r = __pyx_t_1;\n  __pyx_t_1 = 0;\n  goto __pyx_L0;\n\n  /* \"nms/gpu_nms.pyx\":16\n *     void _nms(np.int32_t*, int*, np.float32_t*, int, int, float, int)\n * \n * def gpu_nms(np.ndarray[np.float32_t, ndim=2] dets, np.float thresh,             # <<<<<<<<<<<<<<\n *             np.int32_t device_id=0):\n *     cdef int boxes_num = dets.shape[0]\n */\n\n  /* function exit code */\n  __pyx_L1_error:;\n  __Pyx_XDECREF(__pyx_t_1);\n  __Pyx_XDECREF(__pyx_t_2);\n  __Pyx_XDECREF(__pyx_t_3);\n  __Pyx_XDECREF(__pyx_t_4);\n  __Pyx_XDECREF(__pyx_t_5);\n  { PyObject *__pyx_type, *__pyx_value, *__pyx_tb;\n    __Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb);\n    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_dets.rcbuffer->pybuffer);\n    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_keep.rcbuffer->pybuffer);\n    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_order.rcbuffer->pybuffer);\n    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_scores.rcbuffer->pybuffer);\n    __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_sorted_dets.rcbuffer->pybuffer);\n  __Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);}\n  __Pyx_AddTraceback(\"nms.gpu_nms.gpu_nms\", __pyx_clineno, __pyx_lineno, __pyx_filename);\n  __pyx_r = NULL;\n  goto __pyx_L2;\n  __pyx_L0:;\n  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_dets.rcbuffer->pybuffer);\n  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_keep.rcbuffer->pybuffer);\n  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_order.rcbuffer->pybuffer);\n  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_scores.rcbuffer->pybuffer);\n  __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_sorted_dets.rcbuffer->pybuffer);\n  __pyx_L2:;\n  __Pyx_XDECREF((PyObject *)__pyx_v_keep);\n  __Pyx_XDECREF((PyObject *)__pyx_v_scores);\n  __Pyx_XDECREF((PyObject *)__pyx_v_order);\n  __Pyx_XDECREF((PyObject *)__pyx_v_sorted_dets);\n  __Pyx_XGIVEREF(__pyx_r);\n  __Pyx_RefNannyFinishContext();\n  return __pyx_r;\n}\n\n/* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":194\n *         # experimental exception made for __getbuffer__ and __releasebuffer__\n *         # -- the details of this may change.\n *         def __getbuffer__(ndarray self, Py_buffer* info, int flags):             # <<<<<<<<<<<<<<\n *             # This implementation of getbuffer is geared towards Cython\n *             # requirements, and does not yet fullfill the PEP.\n */\n\n/* Python wrapper */\nstatic CYTHON_UNUSED int __pyx_pw_5numpy_7ndarray_1__getbuffer__(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags); /*proto*/\nstatic CYTHON_UNUSED int __pyx_pw_5numpy_7ndarray_1__getbuffer__(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags) {\n  int __pyx_r;\n  __Pyx_RefNannyDeclarations\n  __Pyx_RefNannySetupContext(\"__getbuffer__ (wrapper)\", 0);\n  __pyx_r = __pyx_pf_5numpy_7ndarray___getbuffer__(((PyArrayObject *)__pyx_v_self), ((Py_buffer *)__pyx_v_info), ((int)__pyx_v_flags));\n\n  /* function exit code */\n  __Pyx_RefNannyFinishContext();\n  return __pyx_r;\n}\n\nstatic int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags) {\n  int __pyx_v_copy_shape;\n  int __pyx_v_i;\n  int __pyx_v_ndim;\n  int __pyx_v_endian_detector;\n  int __pyx_v_little_endian;\n  int __pyx_v_t;\n  char *__pyx_v_f;\n  PyArray_Descr *__pyx_v_descr = 0;\n  int __pyx_v_offset;\n  int __pyx_v_hasfields;\n  int __pyx_r;\n  __Pyx_RefNannyDeclarations\n  int __pyx_t_1;\n  int __pyx_t_2;\n  int __pyx_t_3;\n  PyObject *__pyx_t_4 = NULL;\n  int __pyx_t_5;\n  int __pyx_t_6;\n  int __pyx_t_7;\n  PyObject *__pyx_t_8 = NULL;\n  char *__pyx_t_9;\n  int __pyx_lineno = 0;\n  const char *__pyx_filename = NULL;\n  int __pyx_clineno = 0;\n  __Pyx_RefNannySetupContext(\"__getbuffer__\", 0);\n  if (__pyx_v_info != NULL) {\n    __pyx_v_info->obj = Py_None; __Pyx_INCREF(Py_None);\n    __Pyx_GIVEREF(__pyx_v_info->obj);\n  }\n\n  /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":200\n *             # of flags\n * \n *             if info == NULL: return             # <<<<<<<<<<<<<<\n * \n *             cdef int copy_shape, i, ndim\n */\n  __pyx_t_1 = ((__pyx_v_info == NULL) != 0);\n  if (__pyx_t_1) {\n    __pyx_r = 0;\n    goto __pyx_L0;\n  }\n\n  /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":203\n * \n *             cdef int copy_shape, i, ndim\n *             cdef int endian_detector = 1             # <<<<<<<<<<<<<<\n *             cdef bint little_endian = ((<char*>&endian_detector)[0] != 0)\n * \n */\n  __pyx_v_endian_detector = 1;\n\n  /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":204\n *             cdef int copy_shape, i, ndim\n *             cdef int endian_detector = 1\n *             cdef bint little_endian = ((<char*>&endian_detector)[0] != 0)             # <<<<<<<<<<<<<<\n * \n *             ndim = PyArray_NDIM(self)\n */\n  __pyx_v_little_endian = ((((char *)(&__pyx_v_endian_detector))[0]) != 0);\n\n  /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":206\n *             cdef bint little_endian = ((<char*>&endian_detector)[0] != 0)\n * \n *             ndim = PyArray_NDIM(self)             # <<<<<<<<<<<<<<\n * \n *             if sizeof(npy_intp) != sizeof(Py_ssize_t):\n */\n  __pyx_v_ndim = PyArray_NDIM(__pyx_v_self);\n\n  /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":208\n *             ndim = PyArray_NDIM(self)\n * \n *             if sizeof(npy_intp) != sizeof(Py_ssize_t):             # <<<<<<<<<<<<<<\n *                 copy_shape = 1\n *             else:\n */\n  __pyx_t_1 = (((sizeof(npy_intp)) != (sizeof(Py_ssize_t))) != 0);\n  if (__pyx_t_1) {\n\n    /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":209\n * \n *             if sizeof(npy_intp) != sizeof(Py_ssize_t):\n *                 copy_shape = 1             # <<<<<<<<<<<<<<\n *             else:\n *                 copy_shape = 0\n */\n    __pyx_v_copy_shape = 1;\n    goto __pyx_L4;\n  }\n  /*else*/ {\n\n    /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":211\n *                 copy_shape = 1\n *             else:\n *                 copy_shape = 0             # <<<<<<<<<<<<<<\n * \n *             if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS)\n */\n    __pyx_v_copy_shape = 0;\n  }\n  __pyx_L4:;\n\n  /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":213\n *                 copy_shape = 0\n * \n *             if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS)             # <<<<<<<<<<<<<<\n *                 and not PyArray_CHKFLAGS(self, NPY_C_CONTIGUOUS)):\n *                 raise ValueError(u\"ndarray is not C contiguous\")\n */\n  __pyx_t_1 = (((__pyx_v_flags & PyBUF_C_CONTIGUOUS) == PyBUF_C_CONTIGUOUS) != 0);\n  if (__pyx_t_1) {\n\n    /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":214\n * \n *             if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS)\n *                 and not PyArray_CHKFLAGS(self, NPY_C_CONTIGUOUS)):             # <<<<<<<<<<<<<<\n *                 raise ValueError(u\"ndarray is not C contiguous\")\n * \n */\n    __pyx_t_2 = ((!(PyArray_CHKFLAGS(__pyx_v_self, NPY_C_CONTIGUOUS) != 0)) != 0);\n    __pyx_t_3 = __pyx_t_2;\n  } else {\n    __pyx_t_3 = __pyx_t_1;\n  }\n  if (__pyx_t_3) {\n\n    /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":215\n *             if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS)\n *                 and not PyArray_CHKFLAGS(self, NPY_C_CONTIGUOUS)):\n *                 raise ValueError(u\"ndarray is not C contiguous\")             # <<<<<<<<<<<<<<\n * \n *             if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS)\n */\n    __pyx_t_4 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__5, NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 215; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n    __Pyx_GOTREF(__pyx_t_4);\n    __Pyx_Raise(__pyx_t_4, 0, 0, 0);\n    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;\n    {__pyx_filename = __pyx_f[1]; __pyx_lineno = 215; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n  }\n\n  /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":217\n *                 raise ValueError(u\"ndarray is not C contiguous\")\n * \n *             if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS)             # <<<<<<<<<<<<<<\n *                 and not PyArray_CHKFLAGS(self, NPY_F_CONTIGUOUS)):\n *                 raise ValueError(u\"ndarray is not Fortran contiguous\")\n */\n  __pyx_t_3 = (((__pyx_v_flags & PyBUF_F_CONTIGUOUS) == PyBUF_F_CONTIGUOUS) != 0);\n  if (__pyx_t_3) {\n\n    /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":218\n * \n *             if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS)\n *                 and not PyArray_CHKFLAGS(self, NPY_F_CONTIGUOUS)):             # <<<<<<<<<<<<<<\n *                 raise ValueError(u\"ndarray is not Fortran contiguous\")\n * \n */\n    __pyx_t_1 = ((!(PyArray_CHKFLAGS(__pyx_v_self, NPY_F_CONTIGUOUS) != 0)) != 0);\n    __pyx_t_2 = __pyx_t_1;\n  } else {\n    __pyx_t_2 = __pyx_t_3;\n  }\n  if (__pyx_t_2) {\n\n    /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":219\n *             if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS)\n *                 and not PyArray_CHKFLAGS(self, NPY_F_CONTIGUOUS)):\n *                 raise ValueError(u\"ndarray is not Fortran contiguous\")             # <<<<<<<<<<<<<<\n * \n *             info.buf = PyArray_DATA(self)\n */\n    __pyx_t_4 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__6, NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 219; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n    __Pyx_GOTREF(__pyx_t_4);\n    __Pyx_Raise(__pyx_t_4, 0, 0, 0);\n    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;\n    {__pyx_filename = __pyx_f[1]; __pyx_lineno = 219; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n  }\n\n  /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":221\n *                 raise ValueError(u\"ndarray is not Fortran contiguous\")\n * \n *             info.buf = PyArray_DATA(self)             # <<<<<<<<<<<<<<\n *             info.ndim = ndim\n *             if copy_shape:\n */\n  __pyx_v_info->buf = PyArray_DATA(__pyx_v_self);\n\n  /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":222\n * \n *             info.buf = PyArray_DATA(self)\n *             info.ndim = ndim             # <<<<<<<<<<<<<<\n *             if copy_shape:\n *                 # Allocate new buffer for strides and shape info.\n */\n  __pyx_v_info->ndim = __pyx_v_ndim;\n\n  /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":223\n *             info.buf = PyArray_DATA(self)\n *             info.ndim = ndim\n *             if copy_shape:             # <<<<<<<<<<<<<<\n *                 # Allocate new buffer for strides and shape info.\n *                 # This is allocated as one block, strides first.\n */\n  __pyx_t_2 = (__pyx_v_copy_shape != 0);\n  if (__pyx_t_2) {\n\n    /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":226\n *                 # Allocate new buffer for strides and shape info.\n *                 # This is allocated as one block, strides first.\n *                 info.strides = <Py_ssize_t*>stdlib.malloc(sizeof(Py_ssize_t) * <size_t>ndim * 2)             # <<<<<<<<<<<<<<\n *                 info.shape = info.strides + ndim\n *                 for i in range(ndim):\n */\n    __pyx_v_info->strides = ((Py_ssize_t *)malloc((((sizeof(Py_ssize_t)) * ((size_t)__pyx_v_ndim)) * 2)));\n\n    /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":227\n *                 # This is allocated as one block, strides first.\n *                 info.strides = <Py_ssize_t*>stdlib.malloc(sizeof(Py_ssize_t) * <size_t>ndim * 2)\n *                 info.shape = info.strides + ndim             # <<<<<<<<<<<<<<\n *                 for i in range(ndim):\n *                     info.strides[i] = PyArray_STRIDES(self)[i]\n */\n    __pyx_v_info->shape = (__pyx_v_info->strides + __pyx_v_ndim);\n\n    /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":228\n *                 info.strides = <Py_ssize_t*>stdlib.malloc(sizeof(Py_ssize_t) * <size_t>ndim * 2)\n *                 info.shape = info.strides + ndim\n *                 for i in range(ndim):             # <<<<<<<<<<<<<<\n *                     info.strides[i] = PyArray_STRIDES(self)[i]\n *                     info.shape[i] = PyArray_DIMS(self)[i]\n */\n    __pyx_t_5 = __pyx_v_ndim;\n    for (__pyx_t_6 = 0; __pyx_t_6 < __pyx_t_5; __pyx_t_6+=1) {\n      __pyx_v_i = __pyx_t_6;\n\n      /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":229\n *                 info.shape = info.strides + ndim\n *                 for i in range(ndim):\n *                     info.strides[i] = PyArray_STRIDES(self)[i]             # <<<<<<<<<<<<<<\n *                     info.shape[i] = PyArray_DIMS(self)[i]\n *             else:\n */\n      (__pyx_v_info->strides[__pyx_v_i]) = (PyArray_STRIDES(__pyx_v_self)[__pyx_v_i]);\n\n      /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":230\n *                 for i in range(ndim):\n *                     info.strides[i] = PyArray_STRIDES(self)[i]\n *                     info.shape[i] = PyArray_DIMS(self)[i]             # <<<<<<<<<<<<<<\n *             else:\n *                 info.strides = <Py_ssize_t*>PyArray_STRIDES(self)\n */\n      (__pyx_v_info->shape[__pyx_v_i]) = (PyArray_DIMS(__pyx_v_self)[__pyx_v_i]);\n    }\n    goto __pyx_L7;\n  }\n  /*else*/ {\n\n    /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":232\n *                     info.shape[i] = PyArray_DIMS(self)[i]\n *             else:\n *                 info.strides = <Py_ssize_t*>PyArray_STRIDES(self)             # <<<<<<<<<<<<<<\n *                 info.shape = <Py_ssize_t*>PyArray_DIMS(self)\n *             info.suboffsets = NULL\n */\n    __pyx_v_info->strides = ((Py_ssize_t *)PyArray_STRIDES(__pyx_v_self));\n\n    /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":233\n *             else:\n *                 info.strides = <Py_ssize_t*>PyArray_STRIDES(self)\n *                 info.shape = <Py_ssize_t*>PyArray_DIMS(self)             # <<<<<<<<<<<<<<\n *             info.suboffsets = NULL\n *             info.itemsize = PyArray_ITEMSIZE(self)\n */\n    __pyx_v_info->shape = ((Py_ssize_t *)PyArray_DIMS(__pyx_v_self));\n  }\n  __pyx_L7:;\n\n  /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":234\n *                 info.strides = <Py_ssize_t*>PyArray_STRIDES(self)\n *                 info.shape = <Py_ssize_t*>PyArray_DIMS(self)\n *             info.suboffsets = NULL             # <<<<<<<<<<<<<<\n *             info.itemsize = PyArray_ITEMSIZE(self)\n *             info.readonly = not PyArray_ISWRITEABLE(self)\n */\n  __pyx_v_info->suboffsets = NULL;\n\n  /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":235\n *                 info.shape = <Py_ssize_t*>PyArray_DIMS(self)\n *             info.suboffsets = NULL\n *             info.itemsize = PyArray_ITEMSIZE(self)             # <<<<<<<<<<<<<<\n *             info.readonly = not PyArray_ISWRITEABLE(self)\n * \n */\n  __pyx_v_info->itemsize = PyArray_ITEMSIZE(__pyx_v_self);\n\n  /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":236\n *             info.suboffsets = NULL\n *             info.itemsize = PyArray_ITEMSIZE(self)\n *             info.readonly = not PyArray_ISWRITEABLE(self)             # <<<<<<<<<<<<<<\n * \n *             cdef int t\n */\n  __pyx_v_info->readonly = (!(PyArray_ISWRITEABLE(__pyx_v_self) != 0));\n\n  /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":239\n * \n *             cdef int t\n *             cdef char* f = NULL             # <<<<<<<<<<<<<<\n *             cdef dtype descr = self.descr\n *             cdef list stack\n */\n  __pyx_v_f = NULL;\n\n  /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":240\n *             cdef int t\n *             cdef char* f = NULL\n *             cdef dtype descr = self.descr             # <<<<<<<<<<<<<<\n *             cdef list stack\n *             cdef int offset\n */\n  __pyx_t_4 = ((PyObject *)__pyx_v_self->descr);\n  __Pyx_INCREF(__pyx_t_4);\n  __pyx_v_descr = ((PyArray_Descr *)__pyx_t_4);\n  __pyx_t_4 = 0;\n\n  /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":244\n *             cdef int offset\n * \n *             cdef bint hasfields = PyDataType_HASFIELDS(descr)             # <<<<<<<<<<<<<<\n * \n *             if not hasfields and not copy_shape:\n */\n  __pyx_v_hasfields = PyDataType_HASFIELDS(__pyx_v_descr);\n\n  /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":246\n *             cdef bint hasfields = PyDataType_HASFIELDS(descr)\n * \n *             if not hasfields and not copy_shape:             # <<<<<<<<<<<<<<\n *                 # do not call releasebuffer\n *                 info.obj = None\n */\n  __pyx_t_2 = ((!(__pyx_v_hasfields != 0)) != 0);\n  if (__pyx_t_2) {\n    __pyx_t_3 = ((!(__pyx_v_copy_shape != 0)) != 0);\n    __pyx_t_1 = __pyx_t_3;\n  } else {\n    __pyx_t_1 = __pyx_t_2;\n  }\n  if (__pyx_t_1) {\n\n    /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":248\n *             if not hasfields and not copy_shape:\n *                 # do not call releasebuffer\n *                 info.obj = None             # <<<<<<<<<<<<<<\n *             else:\n *                 # need to call releasebuffer\n */\n    __Pyx_INCREF(Py_None);\n    __Pyx_GIVEREF(Py_None);\n    __Pyx_GOTREF(__pyx_v_info->obj);\n    __Pyx_DECREF(__pyx_v_info->obj);\n    __pyx_v_info->obj = Py_None;\n    goto __pyx_L10;\n  }\n  /*else*/ {\n\n    /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":251\n *             else:\n *                 # need to call releasebuffer\n *                 info.obj = self             # <<<<<<<<<<<<<<\n * \n *             if not hasfields:\n */\n    __Pyx_INCREF(((PyObject *)__pyx_v_self));\n    __Pyx_GIVEREF(((PyObject *)__pyx_v_self));\n    __Pyx_GOTREF(__pyx_v_info->obj);\n    __Pyx_DECREF(__pyx_v_info->obj);\n    __pyx_v_info->obj = ((PyObject *)__pyx_v_self);\n  }\n  __pyx_L10:;\n\n  /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":253\n *                 info.obj = self\n * \n *             if not hasfields:             # <<<<<<<<<<<<<<\n *                 t = descr.type_num\n *                 if ((descr.byteorder == c'>' and little_endian) or\n */\n  __pyx_t_1 = ((!(__pyx_v_hasfields != 0)) != 0);\n  if (__pyx_t_1) {\n\n    /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":254\n * \n *             if not hasfields:\n *                 t = descr.type_num             # <<<<<<<<<<<<<<\n *                 if ((descr.byteorder == c'>' and little_endian) or\n *                     (descr.byteorder == c'<' and not little_endian)):\n */\n    __pyx_t_5 = __pyx_v_descr->type_num;\n    __pyx_v_t = __pyx_t_5;\n\n    /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":255\n *             if not hasfields:\n *                 t = descr.type_num\n *                 if ((descr.byteorder == c'>' and little_endian) or             # <<<<<<<<<<<<<<\n *                     (descr.byteorder == c'<' and not little_endian)):\n *                     raise ValueError(u\"Non-native byte order not supported\")\n */\n    __pyx_t_1 = ((__pyx_v_descr->byteorder == '>') != 0);\n    if (__pyx_t_1) {\n      __pyx_t_2 = (__pyx_v_little_endian != 0);\n    } else {\n      __pyx_t_2 = __pyx_t_1;\n    }\n    if (!__pyx_t_2) {\n\n      /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":256\n *                 t = descr.type_num\n *                 if ((descr.byteorder == c'>' and little_endian) or\n *                     (descr.byteorder == c'<' and not little_endian)):             # <<<<<<<<<<<<<<\n *                     raise ValueError(u\"Non-native byte order not supported\")\n *                 if   t == NPY_BYTE:        f = \"b\"\n */\n      __pyx_t_1 = ((__pyx_v_descr->byteorder == '<') != 0);\n      if (__pyx_t_1) {\n        __pyx_t_3 = ((!(__pyx_v_little_endian != 0)) != 0);\n        __pyx_t_7 = __pyx_t_3;\n      } else {\n        __pyx_t_7 = __pyx_t_1;\n      }\n      __pyx_t_1 = __pyx_t_7;\n    } else {\n      __pyx_t_1 = __pyx_t_2;\n    }\n    if (__pyx_t_1) {\n\n      /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":257\n *                 if ((descr.byteorder == c'>' and little_endian) or\n *                     (descr.byteorder == c'<' and not little_endian)):\n *                     raise ValueError(u\"Non-native byte order not supported\")             # <<<<<<<<<<<<<<\n *                 if   t == NPY_BYTE:        f = \"b\"\n *                 elif t == NPY_UBYTE:       f = \"B\"\n */\n      __pyx_t_4 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__7, NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 257; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n      __Pyx_GOTREF(__pyx_t_4);\n      __Pyx_Raise(__pyx_t_4, 0, 0, 0);\n      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;\n      {__pyx_filename = __pyx_f[1]; __pyx_lineno = 257; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n    }\n\n    /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":274\n *                 elif t == NPY_CDOUBLE:     f = \"Zd\"\n *                 elif t == NPY_CLONGDOUBLE: f = \"Zg\"\n *                 elif t == NPY_OBJECT:      f = \"O\"             # <<<<<<<<<<<<<<\n *                 else:\n *                     raise ValueError(u\"unknown dtype code in numpy.pxd (%d)\" % t)\n */\n    switch (__pyx_v_t) {\n\n      /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":258\n *                     (descr.byteorder == c'<' and not little_endian)):\n *                     raise ValueError(u\"Non-native byte order not supported\")\n *                 if   t == NPY_BYTE:        f = \"b\"             # <<<<<<<<<<<<<<\n *                 elif t == NPY_UBYTE:       f = \"B\"\n *                 elif t == NPY_SHORT:       f = \"h\"\n */\n      case NPY_BYTE:\n      __pyx_v_f = __pyx_k_b;\n      break;\n\n      /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":259\n *                     raise ValueError(u\"Non-native byte order not supported\")\n *                 if   t == NPY_BYTE:        f = \"b\"\n *                 elif t == NPY_UBYTE:       f = \"B\"             # <<<<<<<<<<<<<<\n *                 elif t == NPY_SHORT:       f = \"h\"\n *                 elif t == NPY_USHORT:      f = \"H\"\n */\n      case NPY_UBYTE:\n      __pyx_v_f = __pyx_k_B;\n      break;\n\n      /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":260\n *                 if   t == NPY_BYTE:        f = \"b\"\n *                 elif t == NPY_UBYTE:       f = \"B\"\n *                 elif t == NPY_SHORT:       f = \"h\"             # <<<<<<<<<<<<<<\n *                 elif t == NPY_USHORT:      f = \"H\"\n *                 elif t == NPY_INT:         f = \"i\"\n */\n      case NPY_SHORT:\n      __pyx_v_f = __pyx_k_h;\n      break;\n\n      /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":261\n *                 elif t == NPY_UBYTE:       f = \"B\"\n *                 elif t == NPY_SHORT:       f = \"h\"\n *                 elif t == NPY_USHORT:      f = \"H\"             # <<<<<<<<<<<<<<\n *                 elif t == NPY_INT:         f = \"i\"\n *                 elif t == NPY_UINT:        f = \"I\"\n */\n      case NPY_USHORT:\n      __pyx_v_f = __pyx_k_H;\n      break;\n\n      /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":262\n *                 elif t == NPY_SHORT:       f = \"h\"\n *                 elif t == NPY_USHORT:      f = \"H\"\n *                 elif t == NPY_INT:         f = \"i\"             # <<<<<<<<<<<<<<\n *                 elif t == NPY_UINT:        f = \"I\"\n *                 elif t == NPY_LONG:        f = \"l\"\n */\n      case NPY_INT:\n      __pyx_v_f = __pyx_k_i;\n      break;\n\n      /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":263\n *                 elif t == NPY_USHORT:      f = \"H\"\n *                 elif t == NPY_INT:         f = \"i\"\n *                 elif t == NPY_UINT:        f = \"I\"             # <<<<<<<<<<<<<<\n *                 elif t == NPY_LONG:        f = \"l\"\n *                 elif t == NPY_ULONG:       f = \"L\"\n */\n      case NPY_UINT:\n      __pyx_v_f = __pyx_k_I;\n      break;\n\n      /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":264\n *                 elif t == NPY_INT:         f = \"i\"\n *                 elif t == NPY_UINT:        f = \"I\"\n *                 elif t == NPY_LONG:        f = \"l\"             # <<<<<<<<<<<<<<\n *                 elif t == NPY_ULONG:       f = \"L\"\n *                 elif t == NPY_LONGLONG:    f = \"q\"\n */\n      case NPY_LONG:\n      __pyx_v_f = __pyx_k_l;\n      break;\n\n      /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":265\n *                 elif t == NPY_UINT:        f = \"I\"\n *                 elif t == NPY_LONG:        f = \"l\"\n *                 elif t == NPY_ULONG:       f = \"L\"             # <<<<<<<<<<<<<<\n *                 elif t == NPY_LONGLONG:    f = \"q\"\n *                 elif t == NPY_ULONGLONG:   f = \"Q\"\n */\n      case NPY_ULONG:\n      __pyx_v_f = __pyx_k_L;\n      break;\n\n      /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":266\n *                 elif t == NPY_LONG:        f = \"l\"\n *                 elif t == NPY_ULONG:       f = \"L\"\n *                 elif t == NPY_LONGLONG:    f = \"q\"             # <<<<<<<<<<<<<<\n *                 elif t == NPY_ULONGLONG:   f = \"Q\"\n *                 elif t == NPY_FLOAT:       f = \"f\"\n */\n      case NPY_LONGLONG:\n      __pyx_v_f = __pyx_k_q;\n      break;\n\n      /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":267\n *                 elif t == NPY_ULONG:       f = \"L\"\n *                 elif t == NPY_LONGLONG:    f = \"q\"\n *                 elif t == NPY_ULONGLONG:   f = \"Q\"             # <<<<<<<<<<<<<<\n *                 elif t == NPY_FLOAT:       f = \"f\"\n *                 elif t == NPY_DOUBLE:      f = \"d\"\n */\n      case NPY_ULONGLONG:\n      __pyx_v_f = __pyx_k_Q;\n      break;\n\n      /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":268\n *                 elif t == NPY_LONGLONG:    f = \"q\"\n *                 elif t == NPY_ULONGLONG:   f = \"Q\"\n *                 elif t == NPY_FLOAT:       f = \"f\"             # <<<<<<<<<<<<<<\n *                 elif t == NPY_DOUBLE:      f = \"d\"\n *                 elif t == NPY_LONGDOUBLE:  f = \"g\"\n */\n      case NPY_FLOAT:\n      __pyx_v_f = __pyx_k_f;\n      break;\n\n      /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":269\n *                 elif t == NPY_ULONGLONG:   f = \"Q\"\n *                 elif t == NPY_FLOAT:       f = \"f\"\n *                 elif t == NPY_DOUBLE:      f = \"d\"             # <<<<<<<<<<<<<<\n *                 elif t == NPY_LONGDOUBLE:  f = \"g\"\n *                 elif t == NPY_CFLOAT:      f = \"Zf\"\n */\n      case NPY_DOUBLE:\n      __pyx_v_f = __pyx_k_d;\n      break;\n\n      /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":270\n *                 elif t == NPY_FLOAT:       f = \"f\"\n *                 elif t == NPY_DOUBLE:      f = \"d\"\n *                 elif t == NPY_LONGDOUBLE:  f = \"g\"             # <<<<<<<<<<<<<<\n *                 elif t == NPY_CFLOAT:      f = \"Zf\"\n *                 elif t == NPY_CDOUBLE:     f = \"Zd\"\n */\n      case NPY_LONGDOUBLE:\n      __pyx_v_f = __pyx_k_g;\n      break;\n\n      /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":271\n *                 elif t == NPY_DOUBLE:      f = \"d\"\n *                 elif t == NPY_LONGDOUBLE:  f = \"g\"\n *                 elif t == NPY_CFLOAT:      f = \"Zf\"             # <<<<<<<<<<<<<<\n *                 elif t == NPY_CDOUBLE:     f = \"Zd\"\n *                 elif t == NPY_CLONGDOUBLE: f = \"Zg\"\n */\n      case NPY_CFLOAT:\n      __pyx_v_f = __pyx_k_Zf;\n      break;\n\n      /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":272\n *                 elif t == NPY_LONGDOUBLE:  f = \"g\"\n *                 elif t == NPY_CFLOAT:      f = \"Zf\"\n *                 elif t == NPY_CDOUBLE:     f = \"Zd\"             # <<<<<<<<<<<<<<\n *                 elif t == NPY_CLONGDOUBLE: f = \"Zg\"\n *                 elif t == NPY_OBJECT:      f = \"O\"\n */\n      case NPY_CDOUBLE:\n      __pyx_v_f = __pyx_k_Zd;\n      break;\n\n      /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":273\n *                 elif t == NPY_CFLOAT:      f = \"Zf\"\n *                 elif t == NPY_CDOUBLE:     f = \"Zd\"\n *                 elif t == NPY_CLONGDOUBLE: f = \"Zg\"             # <<<<<<<<<<<<<<\n *                 elif t == NPY_OBJECT:      f = \"O\"\n *                 else:\n */\n      case NPY_CLONGDOUBLE:\n      __pyx_v_f = __pyx_k_Zg;\n      break;\n\n      /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":274\n *                 elif t == NPY_CDOUBLE:     f = \"Zd\"\n *                 elif t == NPY_CLONGDOUBLE: f = \"Zg\"\n *                 elif t == NPY_OBJECT:      f = \"O\"             # <<<<<<<<<<<<<<\n *                 else:\n *                     raise ValueError(u\"unknown dtype code in numpy.pxd (%d)\" % t)\n */\n      case NPY_OBJECT:\n      __pyx_v_f = __pyx_k_O;\n      break;\n      default:\n\n      /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":276\n *                 elif t == NPY_OBJECT:      f = \"O\"\n *                 else:\n *                     raise ValueError(u\"unknown dtype code in numpy.pxd (%d)\" % t)             # <<<<<<<<<<<<<<\n *                 info.format = f\n *                 return\n */\n      __pyx_t_4 = __Pyx_PyInt_From_int(__pyx_v_t); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 276; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n      __Pyx_GOTREF(__pyx_t_4);\n      __pyx_t_8 = PyUnicode_Format(__pyx_kp_u_unknown_dtype_code_in_numpy_pxd, __pyx_t_4); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 276; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n      __Pyx_GOTREF(__pyx_t_8);\n      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;\n      __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 276; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n      __Pyx_GOTREF(__pyx_t_4);\n      PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_8);\n      __Pyx_GIVEREF(__pyx_t_8);\n      __pyx_t_8 = 0;\n      __pyx_t_8 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_t_4, NULL); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 276; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n      __Pyx_GOTREF(__pyx_t_8);\n      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;\n      __Pyx_Raise(__pyx_t_8, 0, 0, 0);\n      __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;\n      {__pyx_filename = __pyx_f[1]; __pyx_lineno = 276; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n      break;\n    }\n\n    /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":277\n *                 else:\n *                     raise ValueError(u\"unknown dtype code in numpy.pxd (%d)\" % t)\n *                 info.format = f             # <<<<<<<<<<<<<<\n *                 return\n *             else:\n */\n    __pyx_v_info->format = __pyx_v_f;\n\n    /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":278\n *                     raise ValueError(u\"unknown dtype code in numpy.pxd (%d)\" % t)\n *                 info.format = f\n *                 return             # <<<<<<<<<<<<<<\n *             else:\n *                 info.format = <char*>stdlib.malloc(_buffer_format_string_len)\n */\n    __pyx_r = 0;\n    goto __pyx_L0;\n  }\n  /*else*/ {\n\n    /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":280\n *                 return\n *             else:\n *                 info.format = <char*>stdlib.malloc(_buffer_format_string_len)             # <<<<<<<<<<<<<<\n *                 info.format[0] = c'^' # Native data types, manual alignment\n *                 offset = 0\n */\n    __pyx_v_info->format = ((char *)malloc(255));\n\n    /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":281\n *             else:\n *                 info.format = <char*>stdlib.malloc(_buffer_format_string_len)\n *                 info.format[0] = c'^' # Native data types, manual alignment             # <<<<<<<<<<<<<<\n *                 offset = 0\n *                 f = _util_dtypestring(descr, info.format + 1,\n */\n    (__pyx_v_info->format[0]) = '^';\n\n    /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":282\n *                 info.format = <char*>stdlib.malloc(_buffer_format_string_len)\n *                 info.format[0] = c'^' # Native data types, manual alignment\n *                 offset = 0             # <<<<<<<<<<<<<<\n *                 f = _util_dtypestring(descr, info.format + 1,\n *                                       info.format + _buffer_format_string_len,\n */\n    __pyx_v_offset = 0;\n\n    /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":283\n *                 info.format[0] = c'^' # Native data types, manual alignment\n *                 offset = 0\n *                 f = _util_dtypestring(descr, info.format + 1,             # <<<<<<<<<<<<<<\n *                                       info.format + _buffer_format_string_len,\n *                                       &offset)\n */\n    __pyx_t_9 = __pyx_f_5numpy__util_dtypestring(__pyx_v_descr, (__pyx_v_info->format + 1), (__pyx_v_info->format + 255), (&__pyx_v_offset)); if (unlikely(__pyx_t_9 == NULL)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 283; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n    __pyx_v_f = __pyx_t_9;\n\n    /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":286\n *                                       info.format + _buffer_format_string_len,\n *                                       &offset)\n *                 f[0] = c'\\0' # Terminate format string             # <<<<<<<<<<<<<<\n * \n *         def __releasebuffer__(ndarray self, Py_buffer* info):\n */\n    (__pyx_v_f[0]) = '\\x00';\n  }\n\n  /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":194\n *         # experimental exception made for __getbuffer__ and __releasebuffer__\n *         # -- the details of this may change.\n *         def __getbuffer__(ndarray self, Py_buffer* info, int flags):             # <<<<<<<<<<<<<<\n *             # This implementation of getbuffer is geared towards Cython\n *             # requirements, and does not yet fullfill the PEP.\n */\n\n  /* function exit code */\n  __pyx_r = 0;\n  goto __pyx_L0;\n  __pyx_L1_error:;\n  __Pyx_XDECREF(__pyx_t_4);\n  __Pyx_XDECREF(__pyx_t_8);\n  __Pyx_AddTraceback(\"numpy.ndarray.__getbuffer__\", __pyx_clineno, __pyx_lineno, __pyx_filename);\n  __pyx_r = -1;\n  if (__pyx_v_info != NULL && __pyx_v_info->obj != NULL) {\n    __Pyx_GOTREF(__pyx_v_info->obj);\n    __Pyx_DECREF(__pyx_v_info->obj); __pyx_v_info->obj = NULL;\n  }\n  goto __pyx_L2;\n  __pyx_L0:;\n  if (__pyx_v_info != NULL && __pyx_v_info->obj == Py_None) {\n    __Pyx_GOTREF(Py_None);\n    __Pyx_DECREF(Py_None); __pyx_v_info->obj = NULL;\n  }\n  __pyx_L2:;\n  __Pyx_XDECREF((PyObject *)__pyx_v_descr);\n  __Pyx_RefNannyFinishContext();\n  return __pyx_r;\n}\n\n/* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":288\n *                 f[0] = c'\\0' # Terminate format string\n * \n *         def __releasebuffer__(ndarray self, Py_buffer* info):             # <<<<<<<<<<<<<<\n *             if PyArray_HASFIELDS(self):\n *                 stdlib.free(info.format)\n */\n\n/* Python wrapper */\nstatic CYTHON_UNUSED void __pyx_pw_5numpy_7ndarray_3__releasebuffer__(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info); /*proto*/\nstatic CYTHON_UNUSED void __pyx_pw_5numpy_7ndarray_3__releasebuffer__(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info) {\n  __Pyx_RefNannyDeclarations\n  __Pyx_RefNannySetupContext(\"__releasebuffer__ (wrapper)\", 0);\n  __pyx_pf_5numpy_7ndarray_2__releasebuffer__(((PyArrayObject *)__pyx_v_self), ((Py_buffer *)__pyx_v_info));\n\n  /* function exit code */\n  __Pyx_RefNannyFinishContext();\n}\n\nstatic void __pyx_pf_5numpy_7ndarray_2__releasebuffer__(PyArrayObject *__pyx_v_self, Py_buffer *__pyx_v_info) {\n  __Pyx_RefNannyDeclarations\n  int __pyx_t_1;\n  __Pyx_RefNannySetupContext(\"__releasebuffer__\", 0);\n\n  /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":289\n * \n *         def __releasebuffer__(ndarray self, Py_buffer* info):\n *             if PyArray_HASFIELDS(self):             # <<<<<<<<<<<<<<\n *                 stdlib.free(info.format)\n *             if sizeof(npy_intp) != sizeof(Py_ssize_t):\n */\n  __pyx_t_1 = (PyArray_HASFIELDS(__pyx_v_self) != 0);\n  if (__pyx_t_1) {\n\n    /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":290\n *         def __releasebuffer__(ndarray self, Py_buffer* info):\n *             if PyArray_HASFIELDS(self):\n *                 stdlib.free(info.format)             # <<<<<<<<<<<<<<\n *             if sizeof(npy_intp) != sizeof(Py_ssize_t):\n *                 stdlib.free(info.strides)\n */\n    free(__pyx_v_info->format);\n    goto __pyx_L3;\n  }\n  __pyx_L3:;\n\n  /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":291\n *             if PyArray_HASFIELDS(self):\n *                 stdlib.free(info.format)\n *             if sizeof(npy_intp) != sizeof(Py_ssize_t):             # <<<<<<<<<<<<<<\n *                 stdlib.free(info.strides)\n *                 # info.shape was stored after info.strides in the same block\n */\n  __pyx_t_1 = (((sizeof(npy_intp)) != (sizeof(Py_ssize_t))) != 0);\n  if (__pyx_t_1) {\n\n    /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":292\n *                 stdlib.free(info.format)\n *             if sizeof(npy_intp) != sizeof(Py_ssize_t):\n *                 stdlib.free(info.strides)             # <<<<<<<<<<<<<<\n *                 # info.shape was stored after info.strides in the same block\n * \n */\n    free(__pyx_v_info->strides);\n    goto __pyx_L4;\n  }\n  __pyx_L4:;\n\n  /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":288\n *                 f[0] = c'\\0' # Terminate format string\n * \n *         def __releasebuffer__(ndarray self, Py_buffer* info):             # <<<<<<<<<<<<<<\n *             if PyArray_HASFIELDS(self):\n *                 stdlib.free(info.format)\n */\n\n  /* function exit code */\n  __Pyx_RefNannyFinishContext();\n}\n\n/* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":768\n * ctypedef npy_cdouble     complex_t\n * \n * cdef inline object PyArray_MultiIterNew1(a):             # <<<<<<<<<<<<<<\n *     return PyArray_MultiIterNew(1, <void*>a)\n * \n */\n\nstatic CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew1(PyObject *__pyx_v_a) {\n  PyObject *__pyx_r = NULL;\n  __Pyx_RefNannyDeclarations\n  PyObject *__pyx_t_1 = NULL;\n  int __pyx_lineno = 0;\n  const char *__pyx_filename = NULL;\n  int __pyx_clineno = 0;\n  __Pyx_RefNannySetupContext(\"PyArray_MultiIterNew1\", 0);\n\n  /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":769\n * \n * cdef inline object PyArray_MultiIterNew1(a):\n *     return PyArray_MultiIterNew(1, <void*>a)             # <<<<<<<<<<<<<<\n * \n * cdef inline object PyArray_MultiIterNew2(a, b):\n */\n  __Pyx_XDECREF(__pyx_r);\n  __pyx_t_1 = PyArray_MultiIterNew(1, ((void *)__pyx_v_a)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 769; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n  __Pyx_GOTREF(__pyx_t_1);\n  __pyx_r = __pyx_t_1;\n  __pyx_t_1 = 0;\n  goto __pyx_L0;\n\n  /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":768\n * ctypedef npy_cdouble     complex_t\n * \n * cdef inline object PyArray_MultiIterNew1(a):             # <<<<<<<<<<<<<<\n *     return PyArray_MultiIterNew(1, <void*>a)\n * \n */\n\n  /* function exit code */\n  __pyx_L1_error:;\n  __Pyx_XDECREF(__pyx_t_1);\n  __Pyx_AddTraceback(\"numpy.PyArray_MultiIterNew1\", __pyx_clineno, __pyx_lineno, __pyx_filename);\n  __pyx_r = 0;\n  __pyx_L0:;\n  __Pyx_XGIVEREF(__pyx_r);\n  __Pyx_RefNannyFinishContext();\n  return __pyx_r;\n}\n\n/* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":771\n *     return PyArray_MultiIterNew(1, <void*>a)\n * \n * cdef inline object PyArray_MultiIterNew2(a, b):             # <<<<<<<<<<<<<<\n *     return PyArray_MultiIterNew(2, <void*>a, <void*>b)\n * \n */\n\nstatic CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew2(PyObject *__pyx_v_a, PyObject *__pyx_v_b) {\n  PyObject *__pyx_r = NULL;\n  __Pyx_RefNannyDeclarations\n  PyObject *__pyx_t_1 = NULL;\n  int __pyx_lineno = 0;\n  const char *__pyx_filename = NULL;\n  int __pyx_clineno = 0;\n  __Pyx_RefNannySetupContext(\"PyArray_MultiIterNew2\", 0);\n\n  /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":772\n * \n * cdef inline object PyArray_MultiIterNew2(a, b):\n *     return PyArray_MultiIterNew(2, <void*>a, <void*>b)             # <<<<<<<<<<<<<<\n * \n * cdef inline object PyArray_MultiIterNew3(a, b, c):\n */\n  __Pyx_XDECREF(__pyx_r);\n  __pyx_t_1 = PyArray_MultiIterNew(2, ((void *)__pyx_v_a), ((void *)__pyx_v_b)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 772; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n  __Pyx_GOTREF(__pyx_t_1);\n  __pyx_r = __pyx_t_1;\n  __pyx_t_1 = 0;\n  goto __pyx_L0;\n\n  /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":771\n *     return PyArray_MultiIterNew(1, <void*>a)\n * \n * cdef inline object PyArray_MultiIterNew2(a, b):             # <<<<<<<<<<<<<<\n *     return PyArray_MultiIterNew(2, <void*>a, <void*>b)\n * \n */\n\n  /* function exit code */\n  __pyx_L1_error:;\n  __Pyx_XDECREF(__pyx_t_1);\n  __Pyx_AddTraceback(\"numpy.PyArray_MultiIterNew2\", __pyx_clineno, __pyx_lineno, __pyx_filename);\n  __pyx_r = 0;\n  __pyx_L0:;\n  __Pyx_XGIVEREF(__pyx_r);\n  __Pyx_RefNannyFinishContext();\n  return __pyx_r;\n}\n\n/* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":774\n *     return PyArray_MultiIterNew(2, <void*>a, <void*>b)\n * \n * cdef inline object PyArray_MultiIterNew3(a, b, c):             # <<<<<<<<<<<<<<\n *     return PyArray_MultiIterNew(3, <void*>a, <void*>b, <void*> c)\n * \n */\n\nstatic CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew3(PyObject *__pyx_v_a, PyObject *__pyx_v_b, PyObject *__pyx_v_c) {\n  PyObject *__pyx_r = NULL;\n  __Pyx_RefNannyDeclarations\n  PyObject *__pyx_t_1 = NULL;\n  int __pyx_lineno = 0;\n  const char *__pyx_filename = NULL;\n  int __pyx_clineno = 0;\n  __Pyx_RefNannySetupContext(\"PyArray_MultiIterNew3\", 0);\n\n  /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":775\n * \n * cdef inline object PyArray_MultiIterNew3(a, b, c):\n *     return PyArray_MultiIterNew(3, <void*>a, <void*>b, <void*> c)             # <<<<<<<<<<<<<<\n * \n * cdef inline object PyArray_MultiIterNew4(a, b, c, d):\n */\n  __Pyx_XDECREF(__pyx_r);\n  __pyx_t_1 = PyArray_MultiIterNew(3, ((void *)__pyx_v_a), ((void *)__pyx_v_b), ((void *)__pyx_v_c)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 775; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n  __Pyx_GOTREF(__pyx_t_1);\n  __pyx_r = __pyx_t_1;\n  __pyx_t_1 = 0;\n  goto __pyx_L0;\n\n  /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":774\n *     return PyArray_MultiIterNew(2, <void*>a, <void*>b)\n * \n * cdef inline object PyArray_MultiIterNew3(a, b, c):             # <<<<<<<<<<<<<<\n *     return PyArray_MultiIterNew(3, <void*>a, <void*>b, <void*> c)\n * \n */\n\n  /* function exit code */\n  __pyx_L1_error:;\n  __Pyx_XDECREF(__pyx_t_1);\n  __Pyx_AddTraceback(\"numpy.PyArray_MultiIterNew3\", __pyx_clineno, __pyx_lineno, __pyx_filename);\n  __pyx_r = 0;\n  __pyx_L0:;\n  __Pyx_XGIVEREF(__pyx_r);\n  __Pyx_RefNannyFinishContext();\n  return __pyx_r;\n}\n\n/* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":777\n *     return PyArray_MultiIterNew(3, <void*>a, <void*>b, <void*> c)\n * \n * cdef inline object PyArray_MultiIterNew4(a, b, c, d):             # <<<<<<<<<<<<<<\n *     return PyArray_MultiIterNew(4, <void*>a, <void*>b, <void*>c, <void*> d)\n * \n */\n\nstatic CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew4(PyObject *__pyx_v_a, PyObject *__pyx_v_b, PyObject *__pyx_v_c, PyObject *__pyx_v_d) {\n  PyObject *__pyx_r = NULL;\n  __Pyx_RefNannyDeclarations\n  PyObject *__pyx_t_1 = NULL;\n  int __pyx_lineno = 0;\n  const char *__pyx_filename = NULL;\n  int __pyx_clineno = 0;\n  __Pyx_RefNannySetupContext(\"PyArray_MultiIterNew4\", 0);\n\n  /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":778\n * \n * cdef inline object PyArray_MultiIterNew4(a, b, c, d):\n *     return PyArray_MultiIterNew(4, <void*>a, <void*>b, <void*>c, <void*> d)             # <<<<<<<<<<<<<<\n * \n * cdef inline object PyArray_MultiIterNew5(a, b, c, d, e):\n */\n  __Pyx_XDECREF(__pyx_r);\n  __pyx_t_1 = PyArray_MultiIterNew(4, ((void *)__pyx_v_a), ((void *)__pyx_v_b), ((void *)__pyx_v_c), ((void *)__pyx_v_d)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 778; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n  __Pyx_GOTREF(__pyx_t_1);\n  __pyx_r = __pyx_t_1;\n  __pyx_t_1 = 0;\n  goto __pyx_L0;\n\n  /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":777\n *     return PyArray_MultiIterNew(3, <void*>a, <void*>b, <void*> c)\n * \n * cdef inline object PyArray_MultiIterNew4(a, b, c, d):             # <<<<<<<<<<<<<<\n *     return PyArray_MultiIterNew(4, <void*>a, <void*>b, <void*>c, <void*> d)\n * \n */\n\n  /* function exit code */\n  __pyx_L1_error:;\n  __Pyx_XDECREF(__pyx_t_1);\n  __Pyx_AddTraceback(\"numpy.PyArray_MultiIterNew4\", __pyx_clineno, __pyx_lineno, __pyx_filename);\n  __pyx_r = 0;\n  __pyx_L0:;\n  __Pyx_XGIVEREF(__pyx_r);\n  __Pyx_RefNannyFinishContext();\n  return __pyx_r;\n}\n\n/* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":780\n *     return PyArray_MultiIterNew(4, <void*>a, <void*>b, <void*>c, <void*> d)\n * \n * cdef inline object PyArray_MultiIterNew5(a, b, c, d, e):             # <<<<<<<<<<<<<<\n *     return PyArray_MultiIterNew(5, <void*>a, <void*>b, <void*>c, <void*> d, <void*> e)\n * \n */\n\nstatic CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew5(PyObject *__pyx_v_a, PyObject *__pyx_v_b, PyObject *__pyx_v_c, PyObject *__pyx_v_d, PyObject *__pyx_v_e) {\n  PyObject *__pyx_r = NULL;\n  __Pyx_RefNannyDeclarations\n  PyObject *__pyx_t_1 = NULL;\n  int __pyx_lineno = 0;\n  const char *__pyx_filename = NULL;\n  int __pyx_clineno = 0;\n  __Pyx_RefNannySetupContext(\"PyArray_MultiIterNew5\", 0);\n\n  /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":781\n * \n * cdef inline object PyArray_MultiIterNew5(a, b, c, d, e):\n *     return PyArray_MultiIterNew(5, <void*>a, <void*>b, <void*>c, <void*> d, <void*> e)             # <<<<<<<<<<<<<<\n * \n * cdef inline char* _util_dtypestring(dtype descr, char* f, char* end, int* offset) except NULL:\n */\n  __Pyx_XDECREF(__pyx_r);\n  __pyx_t_1 = PyArray_MultiIterNew(5, ((void *)__pyx_v_a), ((void *)__pyx_v_b), ((void *)__pyx_v_c), ((void *)__pyx_v_d), ((void *)__pyx_v_e)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 781; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n  __Pyx_GOTREF(__pyx_t_1);\n  __pyx_r = __pyx_t_1;\n  __pyx_t_1 = 0;\n  goto __pyx_L0;\n\n  /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":780\n *     return PyArray_MultiIterNew(4, <void*>a, <void*>b, <void*>c, <void*> d)\n * \n * cdef inline object PyArray_MultiIterNew5(a, b, c, d, e):             # <<<<<<<<<<<<<<\n *     return PyArray_MultiIterNew(5, <void*>a, <void*>b, <void*>c, <void*> d, <void*> e)\n * \n */\n\n  /* function exit code */\n  __pyx_L1_error:;\n  __Pyx_XDECREF(__pyx_t_1);\n  __Pyx_AddTraceback(\"numpy.PyArray_MultiIterNew5\", __pyx_clineno, __pyx_lineno, __pyx_filename);\n  __pyx_r = 0;\n  __pyx_L0:;\n  __Pyx_XGIVEREF(__pyx_r);\n  __Pyx_RefNannyFinishContext();\n  return __pyx_r;\n}\n\n/* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":783\n *     return PyArray_MultiIterNew(5, <void*>a, <void*>b, <void*>c, <void*> d, <void*> e)\n * \n * cdef inline char* _util_dtypestring(dtype descr, char* f, char* end, int* offset) except NULL:             # <<<<<<<<<<<<<<\n *     # Recursive utility function used in __getbuffer__ to get format\n *     # string. The new location in the format string is returned.\n */\n\nstatic CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx_v_descr, char *__pyx_v_f, char *__pyx_v_end, int *__pyx_v_offset) {\n  PyArray_Descr *__pyx_v_child = 0;\n  int __pyx_v_endian_detector;\n  int __pyx_v_little_endian;\n  PyObject *__pyx_v_fields = 0;\n  PyObject *__pyx_v_childname = NULL;\n  PyObject *__pyx_v_new_offset = NULL;\n  PyObject *__pyx_v_t = NULL;\n  char *__pyx_r;\n  __Pyx_RefNannyDeclarations\n  PyObject *__pyx_t_1 = NULL;\n  Py_ssize_t __pyx_t_2;\n  PyObject *__pyx_t_3 = NULL;\n  PyObject *__pyx_t_4 = NULL;\n  int __pyx_t_5;\n  int __pyx_t_6;\n  int __pyx_t_7;\n  int __pyx_t_8;\n  int __pyx_t_9;\n  long __pyx_t_10;\n  char *__pyx_t_11;\n  int __pyx_lineno = 0;\n  const char *__pyx_filename = NULL;\n  int __pyx_clineno = 0;\n  __Pyx_RefNannySetupContext(\"_util_dtypestring\", 0);\n\n  /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":790\n *     cdef int delta_offset\n *     cdef tuple i\n *     cdef int endian_detector = 1             # <<<<<<<<<<<<<<\n *     cdef bint little_endian = ((<char*>&endian_detector)[0] != 0)\n *     cdef tuple fields\n */\n  __pyx_v_endian_detector = 1;\n\n  /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":791\n *     cdef tuple i\n *     cdef int endian_detector = 1\n *     cdef bint little_endian = ((<char*>&endian_detector)[0] != 0)             # <<<<<<<<<<<<<<\n *     cdef tuple fields\n * \n */\n  __pyx_v_little_endian = ((((char *)(&__pyx_v_endian_detector))[0]) != 0);\n\n  /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":794\n *     cdef tuple fields\n * \n *     for childname in descr.names:             # <<<<<<<<<<<<<<\n *         fields = descr.fields[childname]\n *         child, new_offset = fields\n */\n  if (unlikely(__pyx_v_descr->names == Py_None)) {\n    PyErr_SetString(PyExc_TypeError, \"'NoneType' object is not iterable\");\n    {__pyx_filename = __pyx_f[1]; __pyx_lineno = 794; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n  }\n  __pyx_t_1 = __pyx_v_descr->names; __Pyx_INCREF(__pyx_t_1); __pyx_t_2 = 0;\n  for (;;) {\n    if (__pyx_t_2 >= PyTuple_GET_SIZE(__pyx_t_1)) break;\n    #if CYTHON_COMPILING_IN_CPYTHON\n    __pyx_t_3 = PyTuple_GET_ITEM(__pyx_t_1, __pyx_t_2); __Pyx_INCREF(__pyx_t_3); __pyx_t_2++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 794; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n    #else\n    __pyx_t_3 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 794; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n    #endif\n    __Pyx_XDECREF_SET(__pyx_v_childname, __pyx_t_3);\n    __pyx_t_3 = 0;\n\n    /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":795\n * \n *     for childname in descr.names:\n *         fields = descr.fields[childname]             # <<<<<<<<<<<<<<\n *         child, new_offset = fields\n * \n */\n    __pyx_t_3 = PyObject_GetItem(__pyx_v_descr->fields, __pyx_v_childname); if (unlikely(__pyx_t_3 == NULL)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 795; __pyx_clineno = __LINE__; goto __pyx_L1_error;};\n    __Pyx_GOTREF(__pyx_t_3);\n    if (!(likely(PyTuple_CheckExact(__pyx_t_3))||((__pyx_t_3) == Py_None)||(PyErr_Format(PyExc_TypeError, \"Expected %.16s, got %.200s\", \"tuple\", Py_TYPE(__pyx_t_3)->tp_name), 0))) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 795; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n    __Pyx_XDECREF_SET(__pyx_v_fields, ((PyObject*)__pyx_t_3));\n    __pyx_t_3 = 0;\n\n    /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":796\n *     for childname in descr.names:\n *         fields = descr.fields[childname]\n *         child, new_offset = fields             # <<<<<<<<<<<<<<\n * \n *         if (end - f) - <int>(new_offset - offset[0]) < 15:\n */\n    if (likely(__pyx_v_fields != Py_None)) {\n      PyObject* sequence = __pyx_v_fields;\n      #if CYTHON_COMPILING_IN_CPYTHON\n      Py_ssize_t size = Py_SIZE(sequence);\n      #else\n      Py_ssize_t size = PySequence_Size(sequence);\n      #endif\n      if (unlikely(size != 2)) {\n        if (size > 2) __Pyx_RaiseTooManyValuesError(2);\n        else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size);\n        {__pyx_filename = __pyx_f[1]; __pyx_lineno = 796; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n      }\n      #if CYTHON_COMPILING_IN_CPYTHON\n      __pyx_t_3 = PyTuple_GET_ITEM(sequence, 0); \n      __pyx_t_4 = PyTuple_GET_ITEM(sequence, 1); \n      __Pyx_INCREF(__pyx_t_3);\n      __Pyx_INCREF(__pyx_t_4);\n      #else\n      __pyx_t_3 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 796; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n      __Pyx_GOTREF(__pyx_t_3);\n      __pyx_t_4 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 796; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n      __Pyx_GOTREF(__pyx_t_4);\n      #endif\n    } else {\n      __Pyx_RaiseNoneNotIterableError(); {__pyx_filename = __pyx_f[1]; __pyx_lineno = 796; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n    }\n    if (!(likely(((__pyx_t_3) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_3, __pyx_ptype_5numpy_dtype))))) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 796; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n    __Pyx_XDECREF_SET(__pyx_v_child, ((PyArray_Descr *)__pyx_t_3));\n    __pyx_t_3 = 0;\n    __Pyx_XDECREF_SET(__pyx_v_new_offset, __pyx_t_4);\n    __pyx_t_4 = 0;\n\n    /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":798\n *         child, new_offset = fields\n * \n *         if (end - f) - <int>(new_offset - offset[0]) < 15:             # <<<<<<<<<<<<<<\n *             raise RuntimeError(u\"Format string allocated too short, see comment in numpy.pxd\")\n * \n */\n    __pyx_t_4 = __Pyx_PyInt_From_int((__pyx_v_offset[0])); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 798; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n    __Pyx_GOTREF(__pyx_t_4);\n    __pyx_t_3 = PyNumber_Subtract(__pyx_v_new_offset, __pyx_t_4); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 798; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n    __Pyx_GOTREF(__pyx_t_3);\n    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;\n    __pyx_t_5 = __Pyx_PyInt_As_int(__pyx_t_3); if (unlikely((__pyx_t_5 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 798; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;\n    __pyx_t_6 = ((((__pyx_v_end - __pyx_v_f) - ((int)__pyx_t_5)) < 15) != 0);\n    if (__pyx_t_6) {\n\n      /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":799\n * \n *         if (end - f) - <int>(new_offset - offset[0]) < 15:\n *             raise RuntimeError(u\"Format string allocated too short, see comment in numpy.pxd\")             # <<<<<<<<<<<<<<\n * \n *         if ((child.byteorder == c'>' and little_endian) or\n */\n      __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_RuntimeError, __pyx_tuple__8, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 799; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n      __Pyx_GOTREF(__pyx_t_3);\n      __Pyx_Raise(__pyx_t_3, 0, 0, 0);\n      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;\n      {__pyx_filename = __pyx_f[1]; __pyx_lineno = 799; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n    }\n\n    /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":801\n *             raise RuntimeError(u\"Format string allocated too short, see comment in numpy.pxd\")\n * \n *         if ((child.byteorder == c'>' and little_endian) or             # <<<<<<<<<<<<<<\n *             (child.byteorder == c'<' and not little_endian)):\n *             raise ValueError(u\"Non-native byte order not supported\")\n */\n    __pyx_t_6 = ((__pyx_v_child->byteorder == '>') != 0);\n    if (__pyx_t_6) {\n      __pyx_t_7 = (__pyx_v_little_endian != 0);\n    } else {\n      __pyx_t_7 = __pyx_t_6;\n    }\n    if (!__pyx_t_7) {\n\n      /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":802\n * \n *         if ((child.byteorder == c'>' and little_endian) or\n *             (child.byteorder == c'<' and not little_endian)):             # <<<<<<<<<<<<<<\n *             raise ValueError(u\"Non-native byte order not supported\")\n *             # One could encode it in the format string and have Cython\n */\n      __pyx_t_6 = ((__pyx_v_child->byteorder == '<') != 0);\n      if (__pyx_t_6) {\n        __pyx_t_8 = ((!(__pyx_v_little_endian != 0)) != 0);\n        __pyx_t_9 = __pyx_t_8;\n      } else {\n        __pyx_t_9 = __pyx_t_6;\n      }\n      __pyx_t_6 = __pyx_t_9;\n    } else {\n      __pyx_t_6 = __pyx_t_7;\n    }\n    if (__pyx_t_6) {\n\n      /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":803\n *         if ((child.byteorder == c'>' and little_endian) or\n *             (child.byteorder == c'<' and not little_endian)):\n *             raise ValueError(u\"Non-native byte order not supported\")             # <<<<<<<<<<<<<<\n *             # One could encode it in the format string and have Cython\n *             # complain instead, BUT: < and > in format strings also imply\n */\n      __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__9, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 803; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n      __Pyx_GOTREF(__pyx_t_3);\n      __Pyx_Raise(__pyx_t_3, 0, 0, 0);\n      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;\n      {__pyx_filename = __pyx_f[1]; __pyx_lineno = 803; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n    }\n\n    /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":813\n * \n *         # Output padding bytes\n *         while offset[0] < new_offset:             # <<<<<<<<<<<<<<\n *             f[0] = 120 # \"x\"; pad byte\n *             f += 1\n */\n    while (1) {\n      __pyx_t_3 = __Pyx_PyInt_From_int((__pyx_v_offset[0])); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 813; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n      __Pyx_GOTREF(__pyx_t_3);\n      __pyx_t_4 = PyObject_RichCompare(__pyx_t_3, __pyx_v_new_offset, Py_LT); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 813; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;\n      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 813; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;\n      if (!__pyx_t_6) break;\n\n      /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":814\n *         # Output padding bytes\n *         while offset[0] < new_offset:\n *             f[0] = 120 # \"x\"; pad byte             # <<<<<<<<<<<<<<\n *             f += 1\n *             offset[0] += 1\n */\n      (__pyx_v_f[0]) = 120;\n\n      /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":815\n *         while offset[0] < new_offset:\n *             f[0] = 120 # \"x\"; pad byte\n *             f += 1             # <<<<<<<<<<<<<<\n *             offset[0] += 1\n * \n */\n      __pyx_v_f = (__pyx_v_f + 1);\n\n      /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":816\n *             f[0] = 120 # \"x\"; pad byte\n *             f += 1\n *             offset[0] += 1             # <<<<<<<<<<<<<<\n * \n *         offset[0] += child.itemsize\n */\n      __pyx_t_10 = 0;\n      (__pyx_v_offset[__pyx_t_10]) = ((__pyx_v_offset[__pyx_t_10]) + 1);\n    }\n\n    /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":818\n *             offset[0] += 1\n * \n *         offset[0] += child.itemsize             # <<<<<<<<<<<<<<\n * \n *         if not PyDataType_HASFIELDS(child):\n */\n    __pyx_t_10 = 0;\n    (__pyx_v_offset[__pyx_t_10]) = ((__pyx_v_offset[__pyx_t_10]) + __pyx_v_child->elsize);\n\n    /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":820\n *         offset[0] += child.itemsize\n * \n *         if not PyDataType_HASFIELDS(child):             # <<<<<<<<<<<<<<\n *             t = child.type_num\n *             if end - f < 5:\n */\n    __pyx_t_6 = ((!(PyDataType_HASFIELDS(__pyx_v_child) != 0)) != 0);\n    if (__pyx_t_6) {\n\n      /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":821\n * \n *         if not PyDataType_HASFIELDS(child):\n *             t = child.type_num             # <<<<<<<<<<<<<<\n *             if end - f < 5:\n *                 raise RuntimeError(u\"Format string allocated too short.\")\n */\n      __pyx_t_4 = __Pyx_PyInt_From_int(__pyx_v_child->type_num); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 821; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n      __Pyx_GOTREF(__pyx_t_4);\n      __Pyx_XDECREF_SET(__pyx_v_t, __pyx_t_4);\n      __pyx_t_4 = 0;\n\n      /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":822\n *         if not PyDataType_HASFIELDS(child):\n *             t = child.type_num\n *             if end - f < 5:             # <<<<<<<<<<<<<<\n *                 raise RuntimeError(u\"Format string allocated too short.\")\n * \n */\n      __pyx_t_6 = (((__pyx_v_end - __pyx_v_f) < 5) != 0);\n      if (__pyx_t_6) {\n\n        /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":823\n *             t = child.type_num\n *             if end - f < 5:\n *                 raise RuntimeError(u\"Format string allocated too short.\")             # <<<<<<<<<<<<<<\n * \n *             # Until ticket #99 is fixed, use integers to avoid warnings\n */\n        __pyx_t_4 = __Pyx_PyObject_Call(__pyx_builtin_RuntimeError, __pyx_tuple__10, NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 823; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n        __Pyx_GOTREF(__pyx_t_4);\n        __Pyx_Raise(__pyx_t_4, 0, 0, 0);\n        __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;\n        {__pyx_filename = __pyx_f[1]; __pyx_lineno = 823; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n      }\n\n      /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":826\n * \n *             # Until ticket #99 is fixed, use integers to avoid warnings\n *             if   t == NPY_BYTE:        f[0] =  98 #\"b\"             # <<<<<<<<<<<<<<\n *             elif t == NPY_UBYTE:       f[0] =  66 #\"B\"\n *             elif t == NPY_SHORT:       f[0] = 104 #\"h\"\n */\n      __pyx_t_4 = PyInt_FromLong(NPY_BYTE); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 826; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n      __Pyx_GOTREF(__pyx_t_4);\n      __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 826; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;\n      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 826; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;\n      if (__pyx_t_6) {\n        (__pyx_v_f[0]) = 98;\n        goto __pyx_L11;\n      }\n\n      /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":827\n *             # Until ticket #99 is fixed, use integers to avoid warnings\n *             if   t == NPY_BYTE:        f[0] =  98 #\"b\"\n *             elif t == NPY_UBYTE:       f[0] =  66 #\"B\"             # <<<<<<<<<<<<<<\n *             elif t == NPY_SHORT:       f[0] = 104 #\"h\"\n *             elif t == NPY_USHORT:      f[0] =  72 #\"H\"\n */\n      __pyx_t_3 = PyInt_FromLong(NPY_UBYTE); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 827; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n      __Pyx_GOTREF(__pyx_t_3);\n      __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 827; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;\n      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 827; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;\n      if (__pyx_t_6) {\n        (__pyx_v_f[0]) = 66;\n        goto __pyx_L11;\n      }\n\n      /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":828\n *             if   t == NPY_BYTE:        f[0] =  98 #\"b\"\n *             elif t == NPY_UBYTE:       f[0] =  66 #\"B\"\n *             elif t == NPY_SHORT:       f[0] = 104 #\"h\"             # <<<<<<<<<<<<<<\n *             elif t == NPY_USHORT:      f[0] =  72 #\"H\"\n *             elif t == NPY_INT:         f[0] = 105 #\"i\"\n */\n      __pyx_t_4 = PyInt_FromLong(NPY_SHORT); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 828; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n      __Pyx_GOTREF(__pyx_t_4);\n      __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 828; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;\n      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 828; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;\n      if (__pyx_t_6) {\n        (__pyx_v_f[0]) = 104;\n        goto __pyx_L11;\n      }\n\n      /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":829\n *             elif t == NPY_UBYTE:       f[0] =  66 #\"B\"\n *             elif t == NPY_SHORT:       f[0] = 104 #\"h\"\n *             elif t == NPY_USHORT:      f[0] =  72 #\"H\"             # <<<<<<<<<<<<<<\n *             elif t == NPY_INT:         f[0] = 105 #\"i\"\n *             elif t == NPY_UINT:        f[0] =  73 #\"I\"\n */\n      __pyx_t_3 = PyInt_FromLong(NPY_USHORT); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 829; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n      __Pyx_GOTREF(__pyx_t_3);\n      __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 829; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;\n      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 829; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;\n      if (__pyx_t_6) {\n        (__pyx_v_f[0]) = 72;\n        goto __pyx_L11;\n      }\n\n      /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":830\n *             elif t == NPY_SHORT:       f[0] = 104 #\"h\"\n *             elif t == NPY_USHORT:      f[0] =  72 #\"H\"\n *             elif t == NPY_INT:         f[0] = 105 #\"i\"             # <<<<<<<<<<<<<<\n *             elif t == NPY_UINT:        f[0] =  73 #\"I\"\n *             elif t == NPY_LONG:        f[0] = 108 #\"l\"\n */\n      __pyx_t_4 = PyInt_FromLong(NPY_INT); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 830; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n      __Pyx_GOTREF(__pyx_t_4);\n      __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 830; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;\n      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 830; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;\n      if (__pyx_t_6) {\n        (__pyx_v_f[0]) = 105;\n        goto __pyx_L11;\n      }\n\n      /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":831\n *             elif t == NPY_USHORT:      f[0] =  72 #\"H\"\n *             elif t == NPY_INT:         f[0] = 105 #\"i\"\n *             elif t == NPY_UINT:        f[0] =  73 #\"I\"             # <<<<<<<<<<<<<<\n *             elif t == NPY_LONG:        f[0] = 108 #\"l\"\n *             elif t == NPY_ULONG:       f[0] = 76  #\"L\"\n */\n      __pyx_t_3 = PyInt_FromLong(NPY_UINT); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 831; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n      __Pyx_GOTREF(__pyx_t_3);\n      __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 831; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;\n      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 831; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;\n      if (__pyx_t_6) {\n        (__pyx_v_f[0]) = 73;\n        goto __pyx_L11;\n      }\n\n      /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":832\n *             elif t == NPY_INT:         f[0] = 105 #\"i\"\n *             elif t == NPY_UINT:        f[0] =  73 #\"I\"\n *             elif t == NPY_LONG:        f[0] = 108 #\"l\"             # <<<<<<<<<<<<<<\n *             elif t == NPY_ULONG:       f[0] = 76  #\"L\"\n *             elif t == NPY_LONGLONG:    f[0] = 113 #\"q\"\n */\n      __pyx_t_4 = PyInt_FromLong(NPY_LONG); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 832; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n      __Pyx_GOTREF(__pyx_t_4);\n      __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 832; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;\n      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 832; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;\n      if (__pyx_t_6) {\n        (__pyx_v_f[0]) = 108;\n        goto __pyx_L11;\n      }\n\n      /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":833\n *             elif t == NPY_UINT:        f[0] =  73 #\"I\"\n *             elif t == NPY_LONG:        f[0] = 108 #\"l\"\n *             elif t == NPY_ULONG:       f[0] = 76  #\"L\"             # <<<<<<<<<<<<<<\n *             elif t == NPY_LONGLONG:    f[0] = 113 #\"q\"\n *             elif t == NPY_ULONGLONG:   f[0] = 81  #\"Q\"\n */\n      __pyx_t_3 = PyInt_FromLong(NPY_ULONG); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 833; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n      __Pyx_GOTREF(__pyx_t_3);\n      __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 833; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;\n      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 833; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;\n      if (__pyx_t_6) {\n        (__pyx_v_f[0]) = 76;\n        goto __pyx_L11;\n      }\n\n      /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":834\n *             elif t == NPY_LONG:        f[0] = 108 #\"l\"\n *             elif t == NPY_ULONG:       f[0] = 76  #\"L\"\n *             elif t == NPY_LONGLONG:    f[0] = 113 #\"q\"             # <<<<<<<<<<<<<<\n *             elif t == NPY_ULONGLONG:   f[0] = 81  #\"Q\"\n *             elif t == NPY_FLOAT:       f[0] = 102 #\"f\"\n */\n      __pyx_t_4 = PyInt_FromLong(NPY_LONGLONG); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 834; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n      __Pyx_GOTREF(__pyx_t_4);\n      __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 834; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;\n      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 834; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;\n      if (__pyx_t_6) {\n        (__pyx_v_f[0]) = 113;\n        goto __pyx_L11;\n      }\n\n      /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":835\n *             elif t == NPY_ULONG:       f[0] = 76  #\"L\"\n *             elif t == NPY_LONGLONG:    f[0] = 113 #\"q\"\n *             elif t == NPY_ULONGLONG:   f[0] = 81  #\"Q\"             # <<<<<<<<<<<<<<\n *             elif t == NPY_FLOAT:       f[0] = 102 #\"f\"\n *             elif t == NPY_DOUBLE:      f[0] = 100 #\"d\"\n */\n      __pyx_t_3 = PyInt_FromLong(NPY_ULONGLONG); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 835; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n      __Pyx_GOTREF(__pyx_t_3);\n      __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 835; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;\n      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 835; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;\n      if (__pyx_t_6) {\n        (__pyx_v_f[0]) = 81;\n        goto __pyx_L11;\n      }\n\n      /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":836\n *             elif t == NPY_LONGLONG:    f[0] = 113 #\"q\"\n *             elif t == NPY_ULONGLONG:   f[0] = 81  #\"Q\"\n *             elif t == NPY_FLOAT:       f[0] = 102 #\"f\"             # <<<<<<<<<<<<<<\n *             elif t == NPY_DOUBLE:      f[0] = 100 #\"d\"\n *             elif t == NPY_LONGDOUBLE:  f[0] = 103 #\"g\"\n */\n      __pyx_t_4 = PyInt_FromLong(NPY_FLOAT); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 836; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n      __Pyx_GOTREF(__pyx_t_4);\n      __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 836; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;\n      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 836; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;\n      if (__pyx_t_6) {\n        (__pyx_v_f[0]) = 102;\n        goto __pyx_L11;\n      }\n\n      /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":837\n *             elif t == NPY_ULONGLONG:   f[0] = 81  #\"Q\"\n *             elif t == NPY_FLOAT:       f[0] = 102 #\"f\"\n *             elif t == NPY_DOUBLE:      f[0] = 100 #\"d\"             # <<<<<<<<<<<<<<\n *             elif t == NPY_LONGDOUBLE:  f[0] = 103 #\"g\"\n *             elif t == NPY_CFLOAT:      f[0] = 90; f[1] = 102; f += 1 # Zf\n */\n      __pyx_t_3 = PyInt_FromLong(NPY_DOUBLE); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 837; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n      __Pyx_GOTREF(__pyx_t_3);\n      __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 837; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;\n      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 837; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;\n      if (__pyx_t_6) {\n        (__pyx_v_f[0]) = 100;\n        goto __pyx_L11;\n      }\n\n      /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":838\n *             elif t == NPY_FLOAT:       f[0] = 102 #\"f\"\n *             elif t == NPY_DOUBLE:      f[0] = 100 #\"d\"\n *             elif t == NPY_LONGDOUBLE:  f[0] = 103 #\"g\"             # <<<<<<<<<<<<<<\n *             elif t == NPY_CFLOAT:      f[0] = 90; f[1] = 102; f += 1 # Zf\n *             elif t == NPY_CDOUBLE:     f[0] = 90; f[1] = 100; f += 1 # Zd\n */\n      __pyx_t_4 = PyInt_FromLong(NPY_LONGDOUBLE); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 838; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n      __Pyx_GOTREF(__pyx_t_4);\n      __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 838; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;\n      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 838; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;\n      if (__pyx_t_6) {\n        (__pyx_v_f[0]) = 103;\n        goto __pyx_L11;\n      }\n\n      /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":839\n *             elif t == NPY_DOUBLE:      f[0] = 100 #\"d\"\n *             elif t == NPY_LONGDOUBLE:  f[0] = 103 #\"g\"\n *             elif t == NPY_CFLOAT:      f[0] = 90; f[1] = 102; f += 1 # Zf             # <<<<<<<<<<<<<<\n *             elif t == NPY_CDOUBLE:     f[0] = 90; f[1] = 100; f += 1 # Zd\n *             elif t == NPY_CLONGDOUBLE: f[0] = 90; f[1] = 103; f += 1 # Zg\n */\n      __pyx_t_3 = PyInt_FromLong(NPY_CFLOAT); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 839; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n      __Pyx_GOTREF(__pyx_t_3);\n      __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 839; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;\n      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 839; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;\n      if (__pyx_t_6) {\n        (__pyx_v_f[0]) = 90;\n        (__pyx_v_f[1]) = 102;\n        __pyx_v_f = (__pyx_v_f + 1);\n        goto __pyx_L11;\n      }\n\n      /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":840\n *             elif t == NPY_LONGDOUBLE:  f[0] = 103 #\"g\"\n *             elif t == NPY_CFLOAT:      f[0] = 90; f[1] = 102; f += 1 # Zf\n *             elif t == NPY_CDOUBLE:     f[0] = 90; f[1] = 100; f += 1 # Zd             # <<<<<<<<<<<<<<\n *             elif t == NPY_CLONGDOUBLE: f[0] = 90; f[1] = 103; f += 1 # Zg\n *             elif t == NPY_OBJECT:      f[0] = 79 #\"O\"\n */\n      __pyx_t_4 = PyInt_FromLong(NPY_CDOUBLE); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 840; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n      __Pyx_GOTREF(__pyx_t_4);\n      __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 840; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;\n      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 840; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;\n      if (__pyx_t_6) {\n        (__pyx_v_f[0]) = 90;\n        (__pyx_v_f[1]) = 100;\n        __pyx_v_f = (__pyx_v_f + 1);\n        goto __pyx_L11;\n      }\n\n      /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":841\n *             elif t == NPY_CFLOAT:      f[0] = 90; f[1] = 102; f += 1 # Zf\n *             elif t == NPY_CDOUBLE:     f[0] = 90; f[1] = 100; f += 1 # Zd\n *             elif t == NPY_CLONGDOUBLE: f[0] = 90; f[1] = 103; f += 1 # Zg             # <<<<<<<<<<<<<<\n *             elif t == NPY_OBJECT:      f[0] = 79 #\"O\"\n *             else:\n */\n      __pyx_t_3 = PyInt_FromLong(NPY_CLONGDOUBLE); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 841; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n      __Pyx_GOTREF(__pyx_t_3);\n      __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 841; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;\n      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 841; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;\n      if (__pyx_t_6) {\n        (__pyx_v_f[0]) = 90;\n        (__pyx_v_f[1]) = 103;\n        __pyx_v_f = (__pyx_v_f + 1);\n        goto __pyx_L11;\n      }\n\n      /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":842\n *             elif t == NPY_CDOUBLE:     f[0] = 90; f[1] = 100; f += 1 # Zd\n *             elif t == NPY_CLONGDOUBLE: f[0] = 90; f[1] = 103; f += 1 # Zg\n *             elif t == NPY_OBJECT:      f[0] = 79 #\"O\"             # <<<<<<<<<<<<<<\n *             else:\n *                 raise ValueError(u\"unknown dtype code in numpy.pxd (%d)\" % t)\n */\n      __pyx_t_4 = PyInt_FromLong(NPY_OBJECT); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 842; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n      __Pyx_GOTREF(__pyx_t_4);\n      __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 842; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;\n      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 842; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;\n      if (__pyx_t_6) {\n        (__pyx_v_f[0]) = 79;\n        goto __pyx_L11;\n      }\n      /*else*/ {\n\n        /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":844\n *             elif t == NPY_OBJECT:      f[0] = 79 #\"O\"\n *             else:\n *                 raise ValueError(u\"unknown dtype code in numpy.pxd (%d)\" % t)             # <<<<<<<<<<<<<<\n *             f += 1\n *         else:\n */\n        __pyx_t_3 = PyUnicode_Format(__pyx_kp_u_unknown_dtype_code_in_numpy_pxd, __pyx_v_t); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 844; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n        __Pyx_GOTREF(__pyx_t_3);\n        __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 844; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n        __Pyx_GOTREF(__pyx_t_4);\n        PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_3);\n        __Pyx_GIVEREF(__pyx_t_3);\n        __pyx_t_3 = 0;\n        __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_t_4, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 844; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n        __Pyx_GOTREF(__pyx_t_3);\n        __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;\n        __Pyx_Raise(__pyx_t_3, 0, 0, 0);\n        __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;\n        {__pyx_filename = __pyx_f[1]; __pyx_lineno = 844; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n      }\n      __pyx_L11:;\n\n      /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":845\n *             else:\n *                 raise ValueError(u\"unknown dtype code in numpy.pxd (%d)\" % t)\n *             f += 1             # <<<<<<<<<<<<<<\n *         else:\n *             # Cython ignores struct boundary information (\"T{...}\"),\n */\n      __pyx_v_f = (__pyx_v_f + 1);\n      goto __pyx_L9;\n    }\n    /*else*/ {\n\n      /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":849\n *             # Cython ignores struct boundary information (\"T{...}\"),\n *             # so don't output it\n *             f = _util_dtypestring(child, f, end, offset)             # <<<<<<<<<<<<<<\n *     return f\n * \n */\n      __pyx_t_11 = __pyx_f_5numpy__util_dtypestring(__pyx_v_child, __pyx_v_f, __pyx_v_end, __pyx_v_offset); if (unlikely(__pyx_t_11 == NULL)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 849; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n      __pyx_v_f = __pyx_t_11;\n    }\n    __pyx_L9:;\n  }\n  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;\n\n  /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":850\n *             # so don't output it\n *             f = _util_dtypestring(child, f, end, offset)\n *     return f             # <<<<<<<<<<<<<<\n * \n * \n */\n  __pyx_r = __pyx_v_f;\n  goto __pyx_L0;\n\n  /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":783\n *     return PyArray_MultiIterNew(5, <void*>a, <void*>b, <void*>c, <void*> d, <void*> e)\n * \n * cdef inline char* _util_dtypestring(dtype descr, char* f, char* end, int* offset) except NULL:             # <<<<<<<<<<<<<<\n *     # Recursive utility function used in __getbuffer__ to get format\n *     # string. The new location in the format string is returned.\n */\n\n  /* function exit code */\n  __pyx_L1_error:;\n  __Pyx_XDECREF(__pyx_t_1);\n  __Pyx_XDECREF(__pyx_t_3);\n  __Pyx_XDECREF(__pyx_t_4);\n  __Pyx_AddTraceback(\"numpy._util_dtypestring\", __pyx_clineno, __pyx_lineno, __pyx_filename);\n  __pyx_r = NULL;\n  __pyx_L0:;\n  __Pyx_XDECREF((PyObject *)__pyx_v_child);\n  __Pyx_XDECREF(__pyx_v_fields);\n  __Pyx_XDECREF(__pyx_v_childname);\n  __Pyx_XDECREF(__pyx_v_new_offset);\n  __Pyx_XDECREF(__pyx_v_t);\n  __Pyx_RefNannyFinishContext();\n  return __pyx_r;\n}\n\n/* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":966\n * \n * \n * cdef inline void set_array_base(ndarray arr, object base):             # <<<<<<<<<<<<<<\n *      cdef PyObject* baseptr\n *      if base is None:\n */\n\nstatic CYTHON_INLINE void __pyx_f_5numpy_set_array_base(PyArrayObject *__pyx_v_arr, PyObject *__pyx_v_base) {\n  PyObject *__pyx_v_baseptr;\n  __Pyx_RefNannyDeclarations\n  int __pyx_t_1;\n  int __pyx_t_2;\n  __Pyx_RefNannySetupContext(\"set_array_base\", 0);\n\n  /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":968\n * cdef inline void set_array_base(ndarray arr, object base):\n *      cdef PyObject* baseptr\n *      if base is None:             # <<<<<<<<<<<<<<\n *          baseptr = NULL\n *      else:\n */\n  __pyx_t_1 = (__pyx_v_base == Py_None);\n  __pyx_t_2 = (__pyx_t_1 != 0);\n  if (__pyx_t_2) {\n\n    /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":969\n *      cdef PyObject* baseptr\n *      if base is None:\n *          baseptr = NULL             # <<<<<<<<<<<<<<\n *      else:\n *          Py_INCREF(base) # important to do this before decref below!\n */\n    __pyx_v_baseptr = NULL;\n    goto __pyx_L3;\n  }\n  /*else*/ {\n\n    /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":971\n *          baseptr = NULL\n *      else:\n *          Py_INCREF(base) # important to do this before decref below!             # <<<<<<<<<<<<<<\n *          baseptr = <PyObject*>base\n *      Py_XDECREF(arr.base)\n */\n    Py_INCREF(__pyx_v_base);\n\n    /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":972\n *      else:\n *          Py_INCREF(base) # important to do this before decref below!\n *          baseptr = <PyObject*>base             # <<<<<<<<<<<<<<\n *      Py_XDECREF(arr.base)\n *      arr.base = baseptr\n */\n    __pyx_v_baseptr = ((PyObject *)__pyx_v_base);\n  }\n  __pyx_L3:;\n\n  /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":973\n *          Py_INCREF(base) # important to do this before decref below!\n *          baseptr = <PyObject*>base\n *      Py_XDECREF(arr.base)             # <<<<<<<<<<<<<<\n *      arr.base = baseptr\n * \n */\n  Py_XDECREF(__pyx_v_arr->base);\n\n  /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":974\n *          baseptr = <PyObject*>base\n *      Py_XDECREF(arr.base)\n *      arr.base = baseptr             # <<<<<<<<<<<<<<\n * \n * cdef inline object get_array_base(ndarray arr):\n */\n  __pyx_v_arr->base = __pyx_v_baseptr;\n\n  /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":966\n * \n * \n * cdef inline void set_array_base(ndarray arr, object base):             # <<<<<<<<<<<<<<\n *      cdef PyObject* baseptr\n *      if base is None:\n */\n\n  /* function exit code */\n  __Pyx_RefNannyFinishContext();\n}\n\n/* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":976\n *      arr.base = baseptr\n * \n * cdef inline object get_array_base(ndarray arr):             # <<<<<<<<<<<<<<\n *     if arr.base is NULL:\n *         return None\n */\n\nstatic CYTHON_INLINE PyObject *__pyx_f_5numpy_get_array_base(PyArrayObject *__pyx_v_arr) {\n  PyObject *__pyx_r = NULL;\n  __Pyx_RefNannyDeclarations\n  int __pyx_t_1;\n  __Pyx_RefNannySetupContext(\"get_array_base\", 0);\n\n  /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":977\n * \n * cdef inline object get_array_base(ndarray arr):\n *     if arr.base is NULL:             # <<<<<<<<<<<<<<\n *         return None\n *     else:\n */\n  __pyx_t_1 = ((__pyx_v_arr->base == NULL) != 0);\n  if (__pyx_t_1) {\n\n    /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":978\n * cdef inline object get_array_base(ndarray arr):\n *     if arr.base is NULL:\n *         return None             # <<<<<<<<<<<<<<\n *     else:\n *         return <object>arr.base\n */\n    __Pyx_XDECREF(__pyx_r);\n    __Pyx_INCREF(Py_None);\n    __pyx_r = Py_None;\n    goto __pyx_L0;\n  }\n  /*else*/ {\n\n    /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":980\n *         return None\n *     else:\n *         return <object>arr.base             # <<<<<<<<<<<<<<\n */\n    __Pyx_XDECREF(__pyx_r);\n    __Pyx_INCREF(((PyObject *)__pyx_v_arr->base));\n    __pyx_r = ((PyObject *)__pyx_v_arr->base);\n    goto __pyx_L0;\n  }\n\n  /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":976\n *      arr.base = baseptr\n * \n * cdef inline object get_array_base(ndarray arr):             # <<<<<<<<<<<<<<\n *     if arr.base is NULL:\n *         return None\n */\n\n  /* function exit code */\n  __pyx_L0:;\n  __Pyx_XGIVEREF(__pyx_r);\n  __Pyx_RefNannyFinishContext();\n  return __pyx_r;\n}\n\nstatic PyMethodDef __pyx_methods[] = {\n  {0, 0, 0, 0}\n};\n\n#if PY_MAJOR_VERSION >= 3\nstatic struct PyModuleDef __pyx_moduledef = {\n  #if PY_VERSION_HEX < 0x03020000\n    { PyObject_HEAD_INIT(NULL) NULL, 0, NULL },\n  #else\n    PyModuleDef_HEAD_INIT,\n  #endif\n    __Pyx_NAMESTR(\"gpu_nms\"),\n    0, /* m_doc */\n    -1, /* m_size */\n    __pyx_methods /* m_methods */,\n    NULL, /* m_reload */\n    NULL, /* m_traverse */\n    NULL, /* m_clear */\n    NULL /* m_free */\n};\n#endif\n\nstatic __Pyx_StringTabEntry __pyx_string_tab[] = {\n  {&__pyx_kp_u_Format_string_allocated_too_shor, __pyx_k_Format_string_allocated_too_shor, sizeof(__pyx_k_Format_string_allocated_too_shor), 0, 1, 0, 0},\n  {&__pyx_kp_u_Format_string_allocated_too_shor_2, __pyx_k_Format_string_allocated_too_shor_2, sizeof(__pyx_k_Format_string_allocated_too_shor_2), 0, 1, 0, 0},\n  {&__pyx_kp_u_Non_native_byte_order_not_suppor, __pyx_k_Non_native_byte_order_not_suppor, sizeof(__pyx_k_Non_native_byte_order_not_suppor), 0, 1, 0, 0},\n  {&__pyx_n_s_RuntimeError, __pyx_k_RuntimeError, sizeof(__pyx_k_RuntimeError), 0, 0, 1, 1},\n  {&__pyx_n_s_ValueError, __pyx_k_ValueError, sizeof(__pyx_k_ValueError), 0, 0, 1, 1},\n  {&__pyx_n_s_argsort, __pyx_k_argsort, sizeof(__pyx_k_argsort), 0, 0, 1, 1},\n  {&__pyx_n_s_boxes_dim, __pyx_k_boxes_dim, sizeof(__pyx_k_boxes_dim), 0, 0, 1, 1},\n  {&__pyx_n_s_boxes_num, __pyx_k_boxes_num, sizeof(__pyx_k_boxes_num), 0, 0, 1, 1},\n  {&__pyx_n_s_dets, __pyx_k_dets, sizeof(__pyx_k_dets), 0, 0, 1, 1},\n  {&__pyx_n_s_device_id, __pyx_k_device_id, sizeof(__pyx_k_device_id), 0, 0, 1, 1},\n  {&__pyx_n_s_dtype, __pyx_k_dtype, sizeof(__pyx_k_dtype), 0, 0, 1, 1},\n  {&__pyx_n_s_gpu_nms, __pyx_k_gpu_nms, sizeof(__pyx_k_gpu_nms), 0, 0, 1, 1},\n  {&__pyx_n_s_import, __pyx_k_import, sizeof(__pyx_k_import), 0, 0, 1, 1},\n  {&__pyx_n_s_int32, __pyx_k_int32, sizeof(__pyx_k_int32), 0, 0, 1, 1},\n  {&__pyx_n_s_keep, __pyx_k_keep, sizeof(__pyx_k_keep), 0, 0, 1, 1},\n  {&__pyx_n_s_main, __pyx_k_main, sizeof(__pyx_k_main), 0, 0, 1, 1},\n  {&__pyx_kp_u_ndarray_is_not_C_contiguous, __pyx_k_ndarray_is_not_C_contiguous, sizeof(__pyx_k_ndarray_is_not_C_contiguous), 0, 1, 0, 0},\n  {&__pyx_kp_u_ndarray_is_not_Fortran_contiguou, __pyx_k_ndarray_is_not_Fortran_contiguou, sizeof(__pyx_k_ndarray_is_not_Fortran_contiguou), 0, 1, 0, 0},\n  {&__pyx_kp_s_nfs_yoda_xinleic_Inf_Code_Faste, __pyx_k_nfs_yoda_xinleic_Inf_Code_Faste, sizeof(__pyx_k_nfs_yoda_xinleic_Inf_Code_Faste), 0, 0, 1, 0},\n  {&__pyx_n_s_nms_gpu_nms, __pyx_k_nms_gpu_nms, sizeof(__pyx_k_nms_gpu_nms), 0, 0, 1, 1},\n  {&__pyx_n_s_np, __pyx_k_np, sizeof(__pyx_k_np), 0, 0, 1, 1},\n  {&__pyx_n_s_num_out, __pyx_k_num_out, sizeof(__pyx_k_num_out), 0, 0, 1, 1},\n  {&__pyx_n_s_numpy, __pyx_k_numpy, sizeof(__pyx_k_numpy), 0, 0, 1, 1},\n  {&__pyx_n_s_order, __pyx_k_order, sizeof(__pyx_k_order), 0, 0, 1, 1},\n  {&__pyx_n_s_pyx_getbuffer, __pyx_k_pyx_getbuffer, sizeof(__pyx_k_pyx_getbuffer), 0, 0, 1, 1},\n  {&__pyx_n_s_pyx_releasebuffer, __pyx_k_pyx_releasebuffer, sizeof(__pyx_k_pyx_releasebuffer), 0, 0, 1, 1},\n  {&__pyx_n_s_range, __pyx_k_range, sizeof(__pyx_k_range), 0, 0, 1, 1},\n  {&__pyx_n_s_scores, __pyx_k_scores, sizeof(__pyx_k_scores), 0, 0, 1, 1},\n  {&__pyx_n_s_sorted_dets, __pyx_k_sorted_dets, sizeof(__pyx_k_sorted_dets), 0, 0, 1, 1},\n  {&__pyx_n_s_test, __pyx_k_test, sizeof(__pyx_k_test), 0, 0, 1, 1},\n  {&__pyx_n_s_thresh, __pyx_k_thresh, sizeof(__pyx_k_thresh), 0, 0, 1, 1},\n  {&__pyx_kp_u_unknown_dtype_code_in_numpy_pxd, __pyx_k_unknown_dtype_code_in_numpy_pxd, sizeof(__pyx_k_unknown_dtype_code_in_numpy_pxd), 0, 1, 0, 0},\n  {&__pyx_n_s_zeros, __pyx_k_zeros, sizeof(__pyx_k_zeros), 0, 0, 1, 1},\n  {0, 0, 0, 0, 0, 0, 0}\n};\nstatic int __Pyx_InitCachedBuiltins(void) {\n  __pyx_builtin_ValueError = __Pyx_GetBuiltinName(__pyx_n_s_ValueError); if (!__pyx_builtin_ValueError) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 215; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n  __pyx_builtin_range = __Pyx_GetBuiltinName(__pyx_n_s_range); if (!__pyx_builtin_range) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 228; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n  __pyx_builtin_RuntimeError = __Pyx_GetBuiltinName(__pyx_n_s_RuntimeError); if (!__pyx_builtin_RuntimeError) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 799; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n  return 0;\n  __pyx_L1_error:;\n  return -1;\n}\n\nstatic int __Pyx_InitCachedConstants(void) {\n  __Pyx_RefNannyDeclarations\n  __Pyx_RefNannySetupContext(\"__Pyx_InitCachedConstants\", 0);\n\n  /* \"nms/gpu_nms.pyx\":24\n *         keep = np.zeros(boxes_num, dtype=np.int32)\n *     cdef np.ndarray[np.float32_t, ndim=1] \\\n *         scores = dets[:, 4]             # <<<<<<<<<<<<<<\n *     cdef np.ndarray[np.int_t, ndim=1] \\\n *         order = scores.argsort()[::-1]\n */\n  __pyx_slice_ = PySlice_New(Py_None, Py_None, Py_None); if (unlikely(!__pyx_slice_)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 24; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n  __Pyx_GOTREF(__pyx_slice_);\n  __Pyx_GIVEREF(__pyx_slice_);\n  __pyx_tuple__2 = PyTuple_Pack(2, __pyx_slice_, __pyx_int_4); if (unlikely(!__pyx_tuple__2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 24; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n  __Pyx_GOTREF(__pyx_tuple__2);\n  __Pyx_GIVEREF(__pyx_tuple__2);\n\n  /* \"nms/gpu_nms.pyx\":26\n *         scores = dets[:, 4]\n *     cdef np.ndarray[np.int_t, ndim=1] \\\n *         order = scores.argsort()[::-1]             # <<<<<<<<<<<<<<\n *     cdef np.ndarray[np.float32_t, ndim=2] \\\n *         sorted_dets = dets[order, :]\n */\n  __pyx_slice__3 = PySlice_New(Py_None, Py_None, __pyx_int_neg_1); if (unlikely(!__pyx_slice__3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 26; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n  __Pyx_GOTREF(__pyx_slice__3);\n  __Pyx_GIVEREF(__pyx_slice__3);\n\n  /* \"nms/gpu_nms.pyx\":28\n *         order = scores.argsort()[::-1]\n *     cdef np.ndarray[np.float32_t, ndim=2] \\\n *         sorted_dets = dets[order, :]             # <<<<<<<<<<<<<<\n *     _nms(&keep[0], &num_out, &sorted_dets[0, 0], boxes_num, boxes_dim, thresh, device_id)\n *     keep = keep[:num_out]\n */\n  __pyx_slice__4 = PySlice_New(Py_None, Py_None, Py_None); if (unlikely(!__pyx_slice__4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 28; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n  __Pyx_GOTREF(__pyx_slice__4);\n  __Pyx_GIVEREF(__pyx_slice__4);\n\n  /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":215\n *             if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS)\n *                 and not PyArray_CHKFLAGS(self, NPY_C_CONTIGUOUS)):\n *                 raise ValueError(u\"ndarray is not C contiguous\")             # <<<<<<<<<<<<<<\n * \n *             if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS)\n */\n  __pyx_tuple__5 = PyTuple_Pack(1, __pyx_kp_u_ndarray_is_not_C_contiguous); if (unlikely(!__pyx_tuple__5)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 215; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n  __Pyx_GOTREF(__pyx_tuple__5);\n  __Pyx_GIVEREF(__pyx_tuple__5);\n\n  /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":219\n *             if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS)\n *                 and not PyArray_CHKFLAGS(self, NPY_F_CONTIGUOUS)):\n *                 raise ValueError(u\"ndarray is not Fortran contiguous\")             # <<<<<<<<<<<<<<\n * \n *             info.buf = PyArray_DATA(self)\n */\n  __pyx_tuple__6 = PyTuple_Pack(1, __pyx_kp_u_ndarray_is_not_Fortran_contiguou); if (unlikely(!__pyx_tuple__6)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 219; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n  __Pyx_GOTREF(__pyx_tuple__6);\n  __Pyx_GIVEREF(__pyx_tuple__6);\n\n  /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":257\n *                 if ((descr.byteorder == c'>' and little_endian) or\n *                     (descr.byteorder == c'<' and not little_endian)):\n *                     raise ValueError(u\"Non-native byte order not supported\")             # <<<<<<<<<<<<<<\n *                 if   t == NPY_BYTE:        f = \"b\"\n *                 elif t == NPY_UBYTE:       f = \"B\"\n */\n  __pyx_tuple__7 = PyTuple_Pack(1, __pyx_kp_u_Non_native_byte_order_not_suppor); if (unlikely(!__pyx_tuple__7)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 257; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n  __Pyx_GOTREF(__pyx_tuple__7);\n  __Pyx_GIVEREF(__pyx_tuple__7);\n\n  /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":799\n * \n *         if (end - f) - <int>(new_offset - offset[0]) < 15:\n *             raise RuntimeError(u\"Format string allocated too short, see comment in numpy.pxd\")             # <<<<<<<<<<<<<<\n * \n *         if ((child.byteorder == c'>' and little_endian) or\n */\n  __pyx_tuple__8 = PyTuple_Pack(1, __pyx_kp_u_Format_string_allocated_too_shor); if (unlikely(!__pyx_tuple__8)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 799; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n  __Pyx_GOTREF(__pyx_tuple__8);\n  __Pyx_GIVEREF(__pyx_tuple__8);\n\n  /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":803\n *         if ((child.byteorder == c'>' and little_endian) or\n *             (child.byteorder == c'<' and not little_endian)):\n *             raise ValueError(u\"Non-native byte order not supported\")             # <<<<<<<<<<<<<<\n *             # One could encode it in the format string and have Cython\n *             # complain instead, BUT: < and > in format strings also imply\n */\n  __pyx_tuple__9 = PyTuple_Pack(1, __pyx_kp_u_Non_native_byte_order_not_suppor); if (unlikely(!__pyx_tuple__9)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 803; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n  __Pyx_GOTREF(__pyx_tuple__9);\n  __Pyx_GIVEREF(__pyx_tuple__9);\n\n  /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":823\n *             t = child.type_num\n *             if end - f < 5:\n *                 raise RuntimeError(u\"Format string allocated too short.\")             # <<<<<<<<<<<<<<\n * \n *             # Until ticket #99 is fixed, use integers to avoid warnings\n */\n  __pyx_tuple__10 = PyTuple_Pack(1, __pyx_kp_u_Format_string_allocated_too_shor_2); if (unlikely(!__pyx_tuple__10)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 823; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n  __Pyx_GOTREF(__pyx_tuple__10);\n  __Pyx_GIVEREF(__pyx_tuple__10);\n\n  /* \"nms/gpu_nms.pyx\":16\n *     void _nms(np.int32_t*, int*, np.float32_t*, int, int, float, int)\n * \n * def gpu_nms(np.ndarray[np.float32_t, ndim=2] dets, np.float thresh,             # <<<<<<<<<<<<<<\n *             np.int32_t device_id=0):\n *     cdef int boxes_num = dets.shape[0]\n */\n  __pyx_tuple__11 = PyTuple_Pack(10, __pyx_n_s_dets, __pyx_n_s_thresh, __pyx_n_s_device_id, __pyx_n_s_boxes_num, __pyx_n_s_boxes_dim, __pyx_n_s_num_out, __pyx_n_s_keep, __pyx_n_s_scores, __pyx_n_s_order, __pyx_n_s_sorted_dets); if (unlikely(!__pyx_tuple__11)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 16; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n  __Pyx_GOTREF(__pyx_tuple__11);\n  __Pyx_GIVEREF(__pyx_tuple__11);\n  __pyx_codeobj__12 = (PyObject*)__Pyx_PyCode_New(3, 0, 10, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__11, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_nfs_yoda_xinleic_Inf_Code_Faste, __pyx_n_s_gpu_nms, 16, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__12)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 16; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n  __Pyx_RefNannyFinishContext();\n  return 0;\n  __pyx_L1_error:;\n  __Pyx_RefNannyFinishContext();\n  return -1;\n}\n\nstatic int __Pyx_InitGlobals(void) {\n  if (__Pyx_InitStrings(__pyx_string_tab) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};\n  __pyx_int_4 = PyInt_FromLong(4); if (unlikely(!__pyx_int_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n  __pyx_int_neg_1 = PyInt_FromLong(-1); if (unlikely(!__pyx_int_neg_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n  return 0;\n  __pyx_L1_error:;\n  return -1;\n}\n\n#if PY_MAJOR_VERSION < 3\nPyMODINIT_FUNC initgpu_nms(void); /*proto*/\nPyMODINIT_FUNC initgpu_nms(void)\n#else\nPyMODINIT_FUNC PyInit_gpu_nms(void); /*proto*/\nPyMODINIT_FUNC PyInit_gpu_nms(void)\n#endif\n{\n  PyObject *__pyx_t_1 = NULL;\n  int __pyx_lineno = 0;\n  const char *__pyx_filename = NULL;\n  int __pyx_clineno = 0;\n  __Pyx_RefNannyDeclarations\n  #if CYTHON_REFNANNY\n  __Pyx_RefNanny = __Pyx_RefNannyImportAPI(\"refnanny\");\n  if (!__Pyx_RefNanny) {\n      PyErr_Clear();\n      __Pyx_RefNanny = __Pyx_RefNannyImportAPI(\"Cython.Runtime.refnanny\");\n      if (!__Pyx_RefNanny)\n          Py_FatalError(\"failed to import 'refnanny' module\");\n  }\n  #endif\n  __Pyx_RefNannySetupContext(\"PyMODINIT_FUNC PyInit_gpu_nms(void)\", 0);\n  if ( __Pyx_check_binary_version() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n  __pyx_empty_tuple = PyTuple_New(0); if (unlikely(!__pyx_empty_tuple)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n  __pyx_empty_bytes = PyBytes_FromStringAndSize(\"\", 0); if (unlikely(!__pyx_empty_bytes)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n  #ifdef __Pyx_CyFunction_USED\n  if (__Pyx_CyFunction_init() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n  #endif\n  #ifdef __Pyx_FusedFunction_USED\n  if (__pyx_FusedFunction_init() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n  #endif\n  #ifdef __Pyx_Generator_USED\n  if (__pyx_Generator_init() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n  #endif\n  /*--- Library function declarations ---*/\n  /*--- Threads initialization code ---*/\n  #if defined(__PYX_FORCE_INIT_THREADS) && __PYX_FORCE_INIT_THREADS\n  #ifdef WITH_THREAD /* Python build with threading support? */\n  PyEval_InitThreads();\n  #endif\n  #endif\n  /*--- Module creation code ---*/\n  #if PY_MAJOR_VERSION < 3\n  __pyx_m = Py_InitModule4(__Pyx_NAMESTR(\"gpu_nms\"), __pyx_methods, 0, 0, PYTHON_API_VERSION); Py_XINCREF(__pyx_m);\n  #else\n  __pyx_m = PyModule_Create(&__pyx_moduledef);\n  #endif\n  if (unlikely(!__pyx_m)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n  __pyx_d = PyModule_GetDict(__pyx_m); if (unlikely(!__pyx_d)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n  Py_INCREF(__pyx_d);\n  __pyx_b = PyImport_AddModule(__Pyx_NAMESTR(__Pyx_BUILTIN_MODULE_NAME)); if (unlikely(!__pyx_b)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n  #if CYTHON_COMPILING_IN_PYPY\n  Py_INCREF(__pyx_b);\n  #endif\n  if (__Pyx_SetAttrString(__pyx_m, \"__builtins__\", __pyx_b) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};\n  /*--- Initialize various global constants etc. ---*/\n  if (unlikely(__Pyx_InitGlobals() < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n  #if PY_MAJOR_VERSION < 3 && (__PYX_DEFAULT_STRING_ENCODING_IS_ASCII || __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT)\n  if (__Pyx_init_sys_getdefaultencoding_params() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n  #endif\n  if (__pyx_module_is_main_nms__gpu_nms) {\n    if (__Pyx_SetAttrString(__pyx_m, \"__name__\", __pyx_n_s_main) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};\n  }\n  #if PY_MAJOR_VERSION >= 3\n  {\n    PyObject *modules = PyImport_GetModuleDict(); if (unlikely(!modules)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n    if (!PyDict_GetItemString(modules, \"nms.gpu_nms\")) {\n      if (unlikely(PyDict_SetItemString(modules, \"nms.gpu_nms\", __pyx_m) < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n    }\n  }\n  #endif\n  /*--- Builtin init code ---*/\n  if (unlikely(__Pyx_InitCachedBuiltins() < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n  /*--- Constants init code ---*/\n  if (unlikely(__Pyx_InitCachedConstants() < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n  /*--- Global init code ---*/\n  /*--- Variable export code ---*/\n  /*--- Function export code ---*/\n  /*--- Type init code ---*/\n  /*--- Type import code ---*/\n  __pyx_ptype_7cpython_4type_type = __Pyx_ImportType(__Pyx_BUILTIN_MODULE_NAME, \"type\", \n  #if CYTHON_COMPILING_IN_PYPY\n  sizeof(PyTypeObject),\n  #else\n  sizeof(PyHeapTypeObject),\n  #endif\n  0); if (unlikely(!__pyx_ptype_7cpython_4type_type)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 9; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n  __pyx_ptype_5numpy_dtype = __Pyx_ImportType(\"numpy\", \"dtype\", sizeof(PyArray_Descr), 0); if (unlikely(!__pyx_ptype_5numpy_dtype)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 155; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n  __pyx_ptype_5numpy_flatiter = __Pyx_ImportType(\"numpy\", \"flatiter\", sizeof(PyArrayIterObject), 0); if (unlikely(!__pyx_ptype_5numpy_flatiter)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 165; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n  __pyx_ptype_5numpy_broadcast = __Pyx_ImportType(\"numpy\", \"broadcast\", sizeof(PyArrayMultiIterObject), 0); if (unlikely(!__pyx_ptype_5numpy_broadcast)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 169; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n  __pyx_ptype_5numpy_ndarray = __Pyx_ImportType(\"numpy\", \"ndarray\", sizeof(PyArrayObject), 0); if (unlikely(!__pyx_ptype_5numpy_ndarray)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 178; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n  __pyx_ptype_5numpy_ufunc = __Pyx_ImportType(\"numpy\", \"ufunc\", sizeof(PyUFuncObject), 0); if (unlikely(!__pyx_ptype_5numpy_ufunc)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 861; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n  /*--- Variable import code ---*/\n  /*--- Function import code ---*/\n  /*--- Execution code ---*/\n\n  /* \"nms/gpu_nms.pyx\":8\n * # --------------------------------------------------------\n * \n * import numpy as np             # <<<<<<<<<<<<<<\n * cimport numpy as np\n * \n */\n  __pyx_t_1 = __Pyx_Import(__pyx_n_s_numpy, 0, -1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 8; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n  __Pyx_GOTREF(__pyx_t_1);\n  if (PyDict_SetItem(__pyx_d, __pyx_n_s_np, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 8; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;\n\n  /* \"nms/gpu_nms.pyx\":11\n * cimport numpy as np\n * \n * assert sizeof(int) == sizeof(np.int32_t)             # <<<<<<<<<<<<<<\n * \n * cdef extern from \"gpu_nms.hpp\":\n */\n  #ifndef CYTHON_WITHOUT_ASSERTIONS\n  if (unlikely(!Py_OptimizeFlag)) {\n    if (unlikely(!(((sizeof(int)) == (sizeof(__pyx_t_5numpy_int32_t))) != 0))) {\n      PyErr_SetNone(PyExc_AssertionError);\n      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 11; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n    }\n  }\n  #endif\n\n  /* \"nms/gpu_nms.pyx\":16\n *     void _nms(np.int32_t*, int*, np.float32_t*, int, int, float, int)\n * \n * def gpu_nms(np.ndarray[np.float32_t, ndim=2] dets, np.float thresh,             # <<<<<<<<<<<<<<\n *             np.int32_t device_id=0):\n *     cdef int boxes_num = dets.shape[0]\n */\n  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_3nms_7gpu_nms_1gpu_nms, NULL, __pyx_n_s_nms_gpu_nms); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 16; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n  __Pyx_GOTREF(__pyx_t_1);\n  if (PyDict_SetItem(__pyx_d, __pyx_n_s_gpu_nms, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 16; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;\n\n  /* \"nms/gpu_nms.pyx\":1\n * # --------------------------------------------------------             # <<<<<<<<<<<<<<\n * # Faster R-CNN\n * # Copyright (c) 2015 Microsoft\n */\n  __pyx_t_1 = PyDict_New(); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n  __Pyx_GOTREF(__pyx_t_1);\n  if (PyDict_SetItem(__pyx_d, __pyx_n_s_test, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}\n  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;\n\n  /* \"/home/xinleic/anaconda/lib/python2.7/site-packages/Cython/Includes/numpy/__init__.pxd\":976\n *      arr.base = baseptr\n * \n * cdef inline object get_array_base(ndarray arr):             # <<<<<<<<<<<<<<\n *     if arr.base is NULL:\n *         return None\n */\n  goto __pyx_L0;\n  __pyx_L1_error:;\n  __Pyx_XDECREF(__pyx_t_1);\n  if (__pyx_m) {\n    __Pyx_AddTraceback(\"init nms.gpu_nms\", __pyx_clineno, __pyx_lineno, __pyx_filename);\n    Py_DECREF(__pyx_m); __pyx_m = 0;\n  } else if (!PyErr_Occurred()) {\n    PyErr_SetString(PyExc_ImportError, \"init nms.gpu_nms\");\n  }\n  __pyx_L0:;\n  __Pyx_RefNannyFinishContext();\n  #if PY_MAJOR_VERSION < 3\n  return;\n  #else\n  return __pyx_m;\n  #endif\n}\n\n/* Runtime support code */\n#if CYTHON_REFNANNY\nstatic __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname) {\n    PyObject *m = NULL, *p = NULL;\n    void *r = NULL;\n    m = PyImport_ImportModule((char *)modname);\n    if (!m) goto end;\n    p = PyObject_GetAttrString(m, (char *)\"RefNannyAPI\");\n    if (!p) goto end;\n    r = PyLong_AsVoidPtr(p);\nend:\n    Py_XDECREF(p);\n    Py_XDECREF(m);\n    return (__Pyx_RefNannyAPIStruct *)r;\n}\n#endif /* CYTHON_REFNANNY */\n\nstatic void __Pyx_RaiseArgtupleInvalid(\n    const char* func_name,\n    int exact,\n    Py_ssize_t num_min,\n    Py_ssize_t num_max,\n    Py_ssize_t num_found)\n{\n    Py_ssize_t num_expected;\n    const char *more_or_less;\n    if (num_found < num_min) {\n        num_expected = num_min;\n        more_or_less = \"at least\";\n    } else {\n        num_expected = num_max;\n        more_or_less = \"at most\";\n    }\n    if (exact) {\n        more_or_less = \"exactly\";\n    }\n    PyErr_Format(PyExc_TypeError,\n                 \"%.200s() takes %.8s %\" CYTHON_FORMAT_SSIZE_T \"d positional argument%.1s (%\" CYTHON_FORMAT_SSIZE_T \"d given)\",\n                 func_name, more_or_less, num_expected,\n                 (num_expected == 1) ? \"\" : \"s\", num_found);\n}\n\nstatic void __Pyx_RaiseDoubleKeywordsError(\n    const char* func_name,\n    PyObject* kw_name)\n{\n    PyErr_Format(PyExc_TypeError,\n        #if PY_MAJOR_VERSION >= 3\n        \"%s() got multiple values for keyword argument '%U'\", func_name, kw_name);\n        #else\n        \"%s() got multiple values for keyword argument '%s'\", func_name,\n        PyString_AsString(kw_name));\n        #endif\n}\n\nstatic int __Pyx_ParseOptionalKeywords(\n    PyObject *kwds,\n    PyObject **argnames[],\n    PyObject *kwds2,\n    PyObject *values[],\n    Py_ssize_t num_pos_args,\n    const char* function_name)\n{\n    PyObject *key = 0, *value = 0;\n    Py_ssize_t pos = 0;\n    PyObject*** name;\n    PyObject*** first_kw_arg = argnames + num_pos_args;\n    while (PyDict_Next(kwds, &pos, &key, &value)) {\n        name = first_kw_arg;\n        while (*name && (**name != key)) name++;\n        if (*name) {\n            values[name-argnames] = value;\n            continue;\n        }\n        name = first_kw_arg;\n        #if PY_MAJOR_VERSION < 3\n        if (likely(PyString_CheckExact(key)) || likely(PyString_Check(key))) {\n            while (*name) {\n                if ((CYTHON_COMPILING_IN_PYPY || PyString_GET_SIZE(**name) == PyString_GET_SIZE(key))\n                        && _PyString_Eq(**name, key)) {\n                    values[name-argnames] = value;\n                    break;\n                }\n                name++;\n            }\n            if (*name) continue;\n            else {\n                PyObject*** argname = argnames;\n                while (argname != first_kw_arg) {\n                    if ((**argname == key) || (\n                            (CYTHON_COMPILING_IN_PYPY || PyString_GET_SIZE(**argname) == PyString_GET_SIZE(key))\n                             && _PyString_Eq(**argname, key))) {\n                        goto arg_passed_twice;\n                    }\n                    argname++;\n                }\n            }\n        } else\n        #endif\n        if (likely(PyUnicode_Check(key))) {\n            while (*name) {\n                int cmp = (**name == key) ? 0 :\n                #if !CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION >= 3\n                    (PyUnicode_GET_SIZE(**name) != PyUnicode_GET_SIZE(key)) ? 1 :\n                #endif\n                    PyUnicode_Compare(**name, key);\n                if (cmp < 0 && unlikely(PyErr_Occurred())) goto bad;\n                if (cmp == 0) {\n                    values[name-argnames] = value;\n                    break;\n                }\n                name++;\n            }\n            if (*name) continue;\n            else {\n                PyObject*** argname = argnames;\n                while (argname != first_kw_arg) {\n                    int cmp = (**argname == key) ? 0 :\n                    #if !CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION >= 3\n                        (PyUnicode_GET_SIZE(**argname) != PyUnicode_GET_SIZE(key)) ? 1 :\n                    #endif\n                        PyUnicode_Compare(**argname, key);\n                    if (cmp < 0 && unlikely(PyErr_Occurred())) goto bad;\n                    if (cmp == 0) goto arg_passed_twice;\n                    argname++;\n                }\n            }\n        } else\n            goto invalid_keyword_type;\n        if (kwds2) {\n            if (unlikely(PyDict_SetItem(kwds2, key, value))) goto bad;\n        } else {\n            goto invalid_keyword;\n        }\n    }\n    return 0;\narg_passed_twice:\n    __Pyx_RaiseDoubleKeywordsError(function_name, key);\n    goto bad;\ninvalid_keyword_type:\n    PyErr_Format(PyExc_TypeError,\n        \"%.200s() keywords must be strings\", function_name);\n    goto bad;\ninvalid_keyword:\n    PyErr_Format(PyExc_TypeError,\n    #if PY_MAJOR_VERSION < 3\n        \"%.200s() got an unexpected keyword argument '%.200s'\",\n        function_name, PyString_AsString(key));\n    #else\n        \"%s() got an unexpected keyword argument '%U'\",\n        function_name, key);\n    #endif\nbad:\n    return -1;\n}\n\nstatic void __Pyx_RaiseArgumentTypeInvalid(const char* name, PyObject *obj, PyTypeObject *type) {\n    PyErr_Format(PyExc_TypeError,\n        \"Argument '%.200s' has incorrect type (expected %.200s, got %.200s)\",\n        name, type->tp_name, Py_TYPE(obj)->tp_name);\n}\nstatic CYTHON_INLINE int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed,\n    const char *name, int exact)\n{\n    if (unlikely(!type)) {\n        PyErr_SetString(PyExc_SystemError, \"Missing type object\");\n        return 0;\n    }\n    if (none_allowed && obj == Py_None) return 1;\n    else if (exact) {\n        if (likely(Py_TYPE(obj) == type)) return 1;\n        #if PY_MAJOR_VERSION == 2\n        else if ((type == &PyBaseString_Type) && likely(__Pyx_PyBaseString_CheckExact(obj))) return 1;\n        #endif\n    }\n    else {\n        if (likely(PyObject_TypeCheck(obj, type))) return 1;\n    }\n    __Pyx_RaiseArgumentTypeInvalid(name, obj, type);\n    return 0;\n}\n\nstatic CYTHON_INLINE int __Pyx_IsLittleEndian(void) {\n  unsigned int n = 1;\n  return *(unsigned char*)(&n) != 0;\n}\nstatic void __Pyx_BufFmt_Init(__Pyx_BufFmt_Context* ctx,\n                              __Pyx_BufFmt_StackElem* stack,\n                              __Pyx_TypeInfo* type) {\n  stack[0].field = &ctx->root;\n  stack[0].parent_offset = 0;\n  ctx->root.type = type;\n  ctx->root.name = \"buffer dtype\";\n  ctx->root.offset = 0;\n  ctx->head = stack;\n  ctx->head->field = &ctx->root;\n  ctx->fmt_offset = 0;\n  ctx->head->parent_offset = 0;\n  ctx->new_packmode = '@';\n  ctx->enc_packmode = '@';\n  ctx->new_count = 1;\n  ctx->enc_count = 0;\n  ctx->enc_type = 0;\n  ctx->is_complex = 0;\n  ctx->is_valid_array = 0;\n  ctx->struct_alignment = 0;\n  while (type->typegroup == 'S') {\n    ++ctx->head;\n    ctx->head->field = type->fields;\n    ctx->head->parent_offset = 0;\n    type = type->fields->type;\n  }\n}\nstatic int __Pyx_BufFmt_ParseNumber(const char** ts) {\n    int count;\n    const char* t = *ts;\n    if (*t < '0' || *t > '9') {\n      return -1;\n    } else {\n        count = *t++ - '0';\n        while (*t >= '0' && *t < '9') {\n            count *= 10;\n            count += *t++ - '0';\n        }\n    }\n    *ts = t;\n    return count;\n}\nstatic int __Pyx_BufFmt_ExpectNumber(const char **ts) {\n    int number = __Pyx_BufFmt_ParseNumber(ts);\n    if (number == -1) /* First char was not a digit */\n        PyErr_Format(PyExc_ValueError,\\\n                     \"Does not understand character buffer dtype format string ('%c')\", **ts);\n    return number;\n}\nstatic void __Pyx_BufFmt_RaiseUnexpectedChar(char ch) {\n  PyErr_Format(PyExc_ValueError,\n               \"Unexpected format string character: '%c'\", ch);\n}\nstatic const char* __Pyx_BufFmt_DescribeTypeChar(char ch, int is_complex) {\n  switch (ch) {\n    case 'c': return \"'char'\";\n    case 'b': return \"'signed char'\";\n    case 'B': return \"'unsigned char'\";\n    case 'h': return \"'short'\";\n    case 'H': return \"'unsigned short'\";\n    case 'i': return \"'int'\";\n    case 'I': return \"'unsigned int'\";\n    case 'l': return \"'long'\";\n    case 'L': return \"'unsigned long'\";\n    case 'q': return \"'long long'\";\n    case 'Q': return \"'unsigned long long'\";\n    case 'f': return (is_complex ? \"'complex float'\" : \"'float'\");\n    case 'd': return (is_complex ? \"'complex double'\" : \"'double'\");\n    case 'g': return (is_complex ? \"'complex long double'\" : \"'long double'\");\n    case 'T': return \"a struct\";\n    case 'O': return \"Python object\";\n    case 'P': return \"a pointer\";\n    case 's': case 'p': return \"a string\";\n    case 0: return \"end\";\n    default: return \"unparseable format string\";\n  }\n}\nstatic size_t __Pyx_BufFmt_TypeCharToStandardSize(char ch, int is_complex) {\n  switch (ch) {\n    case '?': case 'c': case 'b': case 'B': case 's': case 'p': return 1;\n    case 'h': case 'H': return 2;\n    case 'i': case 'I': case 'l': case 'L': return 4;\n    case 'q': case 'Q': return 8;\n    case 'f': return (is_complex ? 8 : 4);\n    case 'd': return (is_complex ? 16 : 8);\n    case 'g': {\n      PyErr_SetString(PyExc_ValueError, \"Python does not define a standard format string size for long double ('g')..\");\n      return 0;\n    }\n    case 'O': case 'P': return sizeof(void*);\n    default:\n      __Pyx_BufFmt_RaiseUnexpectedChar(ch);\n      return 0;\n    }\n}\nstatic size_t __Pyx_BufFmt_TypeCharToNativeSize(char ch, int is_complex) {\n  switch (ch) {\n    case 'c': case 'b': case 'B': case 's': case 'p': return 1;\n    case 'h': case 'H': return sizeof(short);\n    case 'i': case 'I': return sizeof(int);\n    case 'l': case 'L': return sizeof(long);\n    #ifdef HAVE_LONG_LONG\n    case 'q': case 'Q': return sizeof(PY_LONG_LONG);\n    #endif\n    case 'f': return sizeof(float) * (is_complex ? 2 : 1);\n    case 'd': return sizeof(double) * (is_complex ? 2 : 1);\n    case 'g': return sizeof(long double) * (is_complex ? 2 : 1);\n    case 'O': case 'P': return sizeof(void*);\n    default: {\n      __Pyx_BufFmt_RaiseUnexpectedChar(ch);\n      return 0;\n    }\n  }\n}\ntypedef struct { char c; short x; } __Pyx_st_short;\ntypedef struct { char c; int x; } __Pyx_st_int;\ntypedef struct { char c; long x; } __Pyx_st_long;\ntypedef struct { char c; float x; } __Pyx_st_float;\ntypedef struct { char c; double x; } __Pyx_st_double;\ntypedef struct { char c; long double x; } __Pyx_st_longdouble;\ntypedef struct { char c; void *x; } __Pyx_st_void_p;\n#ifdef HAVE_LONG_LONG\ntypedef struct { char c; PY_LONG_LONG x; } __Pyx_st_longlong;\n#endif\nstatic size_t __Pyx_BufFmt_TypeCharToAlignment(char ch, CYTHON_UNUSED int is_complex) {\n  switch (ch) {\n    case '?': case 'c': case 'b': case 'B': case 's': case 'p': return 1;\n    case 'h': case 'H': return sizeof(__Pyx_st_short) - sizeof(short);\n    case 'i': case 'I': return sizeof(__Pyx_st_int) - sizeof(int);\n    case 'l': case 'L': return sizeof(__Pyx_st_long) - sizeof(long);\n#ifdef HAVE_LONG_LONG\n    case 'q': case 'Q': return sizeof(__Pyx_st_longlong) - sizeof(PY_LONG_LONG);\n#endif\n    case 'f': return sizeof(__Pyx_st_float) - sizeof(float);\n    case 'd': return sizeof(__Pyx_st_double) - sizeof(double);\n    case 'g': return sizeof(__Pyx_st_longdouble) - sizeof(long double);\n    case 'P': case 'O': return sizeof(__Pyx_st_void_p) - sizeof(void*);\n    default:\n      __Pyx_BufFmt_RaiseUnexpectedChar(ch);\n      return 0;\n    }\n}\n/* These are for computing the padding at the end of the struct to align\n   on the first member of the struct. This will probably the same as above,\n   but we don't have any guarantees.\n */\ntypedef struct { short x; char c; } __Pyx_pad_short;\ntypedef struct { int x; char c; } __Pyx_pad_int;\ntypedef struct { long x; char c; } __Pyx_pad_long;\ntypedef struct { float x; char c; } __Pyx_pad_float;\ntypedef struct { double x; char c; } __Pyx_pad_double;\ntypedef struct { long double x; char c; } __Pyx_pad_longdouble;\ntypedef struct { void *x; char c; } __Pyx_pad_void_p;\n#ifdef HAVE_LONG_LONG\ntypedef struct { PY_LONG_LONG x; char c; } __Pyx_pad_longlong;\n#endif\nstatic size_t __Pyx_BufFmt_TypeCharToPadding(char ch, CYTHON_UNUSED int is_complex) {\n  switch (ch) {\n    case '?': case 'c': case 'b': case 'B': case 's': case 'p': return 1;\n    case 'h': case 'H': return sizeof(__Pyx_pad_short) - sizeof(short);\n    case 'i': case 'I': return sizeof(__Pyx_pad_int) - sizeof(int);\n    case 'l': case 'L': return sizeof(__Pyx_pad_long) - sizeof(long);\n#ifdef HAVE_LONG_LONG\n    case 'q': case 'Q': return sizeof(__Pyx_pad_longlong) - sizeof(PY_LONG_LONG);\n#endif\n    case 'f': return sizeof(__Pyx_pad_float) - sizeof(float);\n    case 'd': return sizeof(__Pyx_pad_double) - sizeof(double);\n    case 'g': return sizeof(__Pyx_pad_longdouble) - sizeof(long double);\n    case 'P': case 'O': return sizeof(__Pyx_pad_void_p) - sizeof(void*);\n    default:\n      __Pyx_BufFmt_RaiseUnexpectedChar(ch);\n      return 0;\n    }\n}\nstatic char __Pyx_BufFmt_TypeCharToGroup(char ch, int is_complex) {\n  switch (ch) {\n    case 'c':\n        return 'H';\n    case 'b': case 'h': case 'i':\n    case 'l': case 'q': case 's': case 'p':\n        return 'I';\n    case 'B': case 'H': case 'I': case 'L': case 'Q':\n        return 'U';\n    case 'f': case 'd': case 'g':\n        return (is_complex ? 'C' : 'R');\n    case 'O':\n        return 'O';\n    case 'P':\n        return 'P';\n    default: {\n      __Pyx_BufFmt_RaiseUnexpectedChar(ch);\n      return 0;\n    }\n  }\n}\nstatic void __Pyx_BufFmt_RaiseExpected(__Pyx_BufFmt_Context* ctx) {\n  if (ctx->head == NULL || ctx->head->field == &ctx->root) {\n    const char* expected;\n    const char* quote;\n    if (ctx->head == NULL) {\n      expected = \"end\";\n      quote = \"\";\n    } else {\n      expected = ctx->head->field->type->name;\n      quote = \"'\";\n    }\n    PyErr_Format(PyExc_ValueError,\n                 \"Buffer dtype mismatch, expected %s%s%s but got %s\",\n                 quote, expected, quote,\n                 __Pyx_BufFmt_DescribeTypeChar(ctx->enc_type, ctx->is_complex));\n  } else {\n    __Pyx_StructField* field = ctx->head->field;\n    __Pyx_StructField* parent = (ctx->head - 1)->field;\n    PyErr_Format(PyExc_ValueError,\n                 \"Buffer dtype mismatch, expected '%s' but got %s in '%s.%s'\",\n                 field->type->name, __Pyx_BufFmt_DescribeTypeChar(ctx->enc_type, ctx->is_complex),\n                 parent->type->name, field->name);\n  }\n}\nstatic int __Pyx_BufFmt_ProcessTypeChunk(__Pyx_BufFmt_Context* ctx) {\n  char group;\n  size_t size, offset, arraysize = 1;\n  if (ctx->enc_type == 0) return 0;\n  if (ctx->head->field->type->arraysize[0]) {\n    int i, ndim = 0;\n    if (ctx->enc_type == 's' || ctx->enc_type == 'p') {\n        ctx->is_valid_array = ctx->head->field->type->ndim == 1;\n        ndim = 1;\n        if (ctx->enc_count != ctx->head->field->type->arraysize[0]) {\n            PyErr_Format(PyExc_ValueError,\n                         \"Expected a dimension of size %zu, got %zu\",\n                         ctx->head->field->type->arraysize[0], ctx->enc_count);\n            return -1;\n        }\n    }\n    if (!ctx->is_valid_array) {\n      PyErr_Format(PyExc_ValueError, \"Expected %d dimensions, got %d\",\n                   ctx->head->field->type->ndim, ndim);\n      return -1;\n    }\n    for (i = 0; i < ctx->head->field->type->ndim; i++) {\n      arraysize *= ctx->head->field->type->arraysize[i];\n    }\n    ctx->is_valid_array = 0;\n    ctx->enc_count = 1;\n  }\n  group = __Pyx_BufFmt_TypeCharToGroup(ctx->enc_type, ctx->is_complex);\n  do {\n    __Pyx_StructField* field = ctx->head->field;\n    __Pyx_TypeInfo* type = field->type;\n    if (ctx->enc_packmode == '@' || ctx->enc_packmode == '^') {\n      size = __Pyx_BufFmt_TypeCharToNativeSize(ctx->enc_type, ctx->is_complex);\n    } else {\n      size = __Pyx_BufFmt_TypeCharToStandardSize(ctx->enc_type, ctx->is_complex);\n    }\n    if (ctx->enc_packmode == '@') {\n      size_t align_at = __Pyx_BufFmt_TypeCharToAlignment(ctx->enc_type, ctx->is_complex);\n      size_t align_mod_offset;\n      if (align_at == 0) return -1;\n      align_mod_offset = ctx->fmt_offset % align_at;\n      if (align_mod_offset > 0) ctx->fmt_offset += align_at - align_mod_offset;\n      if (ctx->struct_alignment == 0)\n          ctx->struct_alignment = __Pyx_BufFmt_TypeCharToPadding(ctx->enc_type,\n                                                                 ctx->is_complex);\n    }\n    if (type->size != size || type->typegroup != group) {\n      if (type->typegroup == 'C' && type->fields != NULL) {\n        size_t parent_offset = ctx->head->parent_offset + field->offset;\n        ++ctx->head;\n        ctx->head->field = type->fields;\n        ctx->head->parent_offset = parent_offset;\n        continue;\n      }\n      if ((type->typegroup == 'H' || group == 'H') && type->size == size) {\n      } else {\n          __Pyx_BufFmt_RaiseExpected(ctx);\n          return -1;\n      }\n    }\n    offset = ctx->head->parent_offset + field->offset;\n    if (ctx->fmt_offset != offset) {\n      PyErr_Format(PyExc_ValueError,\n                   \"Buffer dtype mismatch; next field is at offset %\" CYTHON_FORMAT_SSIZE_T \"d but %\" CYTHON_FORMAT_SSIZE_T \"d expected\",\n                   (Py_ssize_t)ctx->fmt_offset, (Py_ssize_t)offset);\n      return -1;\n    }\n    ctx->fmt_offset += size;\n    if (arraysize)\n      ctx->fmt_offset += (arraysize - 1) * size;\n    --ctx->enc_count; /* Consume from buffer string */\n    while (1) {\n      if (field == &ctx->root) {\n        ctx->head = NULL;\n        if (ctx->enc_count != 0) {\n          __Pyx_BufFmt_RaiseExpected(ctx);\n          return -1;\n        }\n        break; /* breaks both loops as ctx->enc_count == 0 */\n      }\n      ctx->head->field = ++field;\n      if (field->type == NULL) {\n        --ctx->head;\n        field = ctx->head->field;\n        continue;\n      } else if (field->type->typegroup == 'S') {\n        size_t parent_offset = ctx->head->parent_offset + field->offset;\n        if (field->type->fields->type == NULL) continue; /* empty struct */\n        field = field->type->fields;\n        ++ctx->head;\n        ctx->head->field = field;\n        ctx->head->parent_offset = parent_offset;\n        break;\n      } else {\n        break;\n      }\n    }\n  } while (ctx->enc_count);\n  ctx->enc_type = 0;\n  ctx->is_complex = 0;\n  return 0;\n}\nstatic CYTHON_INLINE PyObject *\n__pyx_buffmt_parse_array(__Pyx_BufFmt_Context* ctx, const char** tsp)\n{\n    const char *ts = *tsp;\n    int i = 0, number;\n    int ndim = ctx->head->field->type->ndim;\n;\n    ++ts;\n    if (ctx->new_count != 1) {\n        PyErr_SetString(PyExc_ValueError,\n                        \"Cannot handle repeated arrays in format string\");\n        return NULL;\n    }\n    if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL;\n    while (*ts && *ts != ')') {\n        switch (*ts) {\n            case ' ': case '\\f': case '\\r': case '\\n': case '\\t': case '\\v':  continue;\n            default:  break;  /* not a 'break' in the loop */\n        }\n        number = __Pyx_BufFmt_ExpectNumber(&ts);\n        if (number == -1) return NULL;\n        if (i < ndim && (size_t) number != ctx->head->field->type->arraysize[i])\n            return PyErr_Format(PyExc_ValueError,\n                        \"Expected a dimension of size %zu, got %d\",\n                        ctx->head->field->type->arraysize[i], number);\n        if (*ts != ',' && *ts != ')')\n            return PyErr_Format(PyExc_ValueError,\n                                \"Expected a comma in format string, got '%c'\", *ts);\n        if (*ts == ',') ts++;\n        i++;\n    }\n    if (i != ndim)\n        return PyErr_Format(PyExc_ValueError, \"Expected %d dimension(s), got %d\",\n                            ctx->head->field->type->ndim, i);\n    if (!*ts) {\n        PyErr_SetString(PyExc_ValueError,\n                        \"Unexpected end of format string, expected ')'\");\n        return NULL;\n    }\n    ctx->is_valid_array = 1;\n    ctx->new_count = 1;\n    *tsp = ++ts;\n    return Py_None;\n}\nstatic const char* __Pyx_BufFmt_CheckString(__Pyx_BufFmt_Context* ctx, const char* ts) {\n  int got_Z = 0;\n  while (1) {\n    switch(*ts) {\n      case 0:\n        if (ctx->enc_type != 0 && ctx->head == NULL) {\n          __Pyx_BufFmt_RaiseExpected(ctx);\n          return NULL;\n        }\n        if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL;\n        if (ctx->head != NULL) {\n          __Pyx_BufFmt_RaiseExpected(ctx);\n          return NULL;\n        }\n                return ts;\n      case ' ':\n      case 10:\n      case 13:\n        ++ts;\n        break;\n      case '<':\n        if (!__Pyx_IsLittleEndian()) {\n          PyErr_SetString(PyExc_ValueError, \"Little-endian buffer not supported on big-endian compiler\");\n          return NULL;\n        }\n        ctx->new_packmode = '=';\n        ++ts;\n        break;\n      case '>':\n      case '!':\n        if (__Pyx_IsLittleEndian()) {\n          PyErr_SetString(PyExc_ValueError, \"Big-endian buffer not supported on little-endian compiler\");\n          return NULL;\n        }\n        ctx->new_packmode = '=';\n        ++ts;\n        break;\n      case '=':\n      case '@':\n      case '^':\n        ctx->new_packmode = *ts++;\n        break;\n      case 'T': /* substruct */\n        {\n          const char* ts_after_sub;\n          size_t i, struct_count = ctx->new_count;\n          size_t struct_alignment = ctx->struct_alignment;\n          ctx->new_count = 1;\n          ++ts;\n          if (*ts != '{') {\n            PyErr_SetString(PyExc_ValueError, \"Buffer acquisition: Expected '{' after 'T'\");\n            return NULL;\n          }\n          if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL;\n          ctx->enc_type = 0; /* Erase processed last struct element */\n          ctx->enc_count = 0;\n          ctx->struct_alignment = 0;\n          ++ts;\n          ts_after_sub = ts;\n          for (i = 0; i != struct_count; ++i) {\n            ts_after_sub = __Pyx_BufFmt_CheckString(ctx, ts);\n            if (!ts_after_sub) return NULL;\n          }\n          ts = ts_after_sub;\n          if (struct_alignment) ctx->struct_alignment = struct_alignment;\n        }\n        break;\n      case '}': /* end of substruct; either repeat or move on */\n        {\n          size_t alignment = ctx->struct_alignment;\n          ++ts;\n          if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL;\n          ctx->enc_type = 0; /* Erase processed last struct element */\n          if (alignment && ctx->fmt_offset % alignment) {\n            ctx->fmt_offset += alignment - (ctx->fmt_offset % alignment);\n          }\n        }\n        return ts;\n      case 'x':\n        if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL;\n        ctx->fmt_offset += ctx->new_count;\n        ctx->new_count = 1;\n        ctx->enc_count = 0;\n        ctx->enc_type = 0;\n        ctx->enc_packmode = ctx->new_packmode;\n        ++ts;\n        break;\n      case 'Z':\n        got_Z = 1;\n        ++ts;\n        if (*ts != 'f' && *ts != 'd' && *ts != 'g') {\n          __Pyx_BufFmt_RaiseUnexpectedChar('Z');\n          return NULL;\n        }        /* fall through */\n      case 'c': case 'b': case 'B': case 'h': case 'H': case 'i': case 'I':\n      case 'l': case 'L': case 'q': case 'Q':\n      case 'f': case 'd': case 'g':\n      case 'O': case 's': case 'p':\n        if (ctx->enc_type == *ts && got_Z == ctx->is_complex &&\n            ctx->enc_packmode == ctx->new_packmode) {\n          ctx->enc_count += ctx->new_count;\n        } else {\n          if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL;\n          ctx->enc_count = ctx->new_count;\n          ctx->enc_packmode = ctx->new_packmode;\n          ctx->enc_type = *ts;\n          ctx->is_complex = got_Z;\n        }\n        ++ts;\n        ctx->new_count = 1;\n        got_Z = 0;\n        break;\n      case ':':\n        ++ts;\n        while(*ts != ':') ++ts;\n        ++ts;\n        break;\n      case '(':\n        if (!__pyx_buffmt_parse_array(ctx, &ts)) return NULL;\n        break;\n      default:\n        {\n          int number = __Pyx_BufFmt_ExpectNumber(&ts);\n          if (number == -1) return NULL;\n          ctx->new_count = (size_t)number;\n        }\n    }\n  }\n}\nstatic CYTHON_INLINE void __Pyx_ZeroBuffer(Py_buffer* buf) {\n  buf->buf = NULL;\n  buf->obj = NULL;\n  buf->strides = __Pyx_zeros;\n  buf->shape = __Pyx_zeros;\n  buf->suboffsets = __Pyx_minusones;\n}\nstatic CYTHON_INLINE int __Pyx_GetBufferAndValidate(\n        Py_buffer* buf, PyObject* obj,  __Pyx_TypeInfo* dtype, int flags,\n        int nd, int cast, __Pyx_BufFmt_StackElem* stack)\n{\n  if (obj == Py_None || obj == NULL) {\n    __Pyx_ZeroBuffer(buf);\n    return 0;\n  }\n  buf->buf = NULL;\n  if (__Pyx_GetBuffer(obj, buf, flags) == -1) goto fail;\n  if (buf->ndim != nd) {\n    PyErr_Format(PyExc_ValueError,\n                 \"Buffer has wrong number of dimensions (expected %d, got %d)\",\n                 nd, buf->ndim);\n    goto fail;\n  }\n  if (!cast) {\n    __Pyx_BufFmt_Context ctx;\n    __Pyx_BufFmt_Init(&ctx, stack, dtype);\n    if (!__Pyx_BufFmt_CheckString(&ctx, buf->format)) goto fail;\n  }\n  if ((unsigned)buf->itemsize != dtype->size) {\n    PyErr_Format(PyExc_ValueError,\n      \"Item size of buffer (%\" CYTHON_FORMAT_SSIZE_T \"d byte%s) does not match size of '%s' (%\" CYTHON_FORMAT_SSIZE_T \"d byte%s)\",\n      buf->itemsize, (buf->itemsize > 1) ? \"s\" : \"\",\n      dtype->name, (Py_ssize_t)dtype->size, (dtype->size > 1) ? \"s\" : \"\");\n    goto fail;\n  }\n  if (buf->suboffsets == NULL) buf->suboffsets = __Pyx_minusones;\n  return 0;\nfail:;\n  __Pyx_ZeroBuffer(buf);\n  return -1;\n}\nstatic CYTHON_INLINE void __Pyx_SafeReleaseBuffer(Py_buffer* info) {\n  if (info->buf == NULL) return;\n  if (info->suboffsets == __Pyx_minusones) info->suboffsets = NULL;\n  __Pyx_ReleaseBuffer(info);\n}\n\nstatic PyObject *__Pyx_GetBuiltinName(PyObject *name) {\n    PyObject* result = __Pyx_PyObject_GetAttrStr(__pyx_b, name);\n    if (unlikely(!result)) {\n        PyErr_Format(PyExc_NameError,\n#if PY_MAJOR_VERSION >= 3\n            \"name '%U' is not defined\", name);\n#else\n            \"name '%.200s' is not defined\", PyString_AS_STRING(name));\n#endif\n    }\n    return result;\n}\n\nstatic CYTHON_INLINE PyObject *__Pyx_GetModuleGlobalName(PyObject *name) {\n    PyObject *result;\n#if CYTHON_COMPILING_IN_CPYTHON\n    result = PyDict_GetItem(__pyx_d, name);\n    if (result) {\n        Py_INCREF(result);\n    } else {\n#else\n    result = PyObject_GetItem(__pyx_d, name);\n    if (!result) {\n        PyErr_Clear();\n#endif\n        result = __Pyx_GetBuiltinName(name);\n    }\n    return result;\n}\n\n#if CYTHON_COMPILING_IN_CPYTHON\nstatic CYTHON_INLINE PyObject* __Pyx_PyObject_Call(PyObject *func, PyObject *arg, PyObject *kw) {\n    PyObject *result;\n    ternaryfunc call = func->ob_type->tp_call;\n    if (unlikely(!call))\n        return PyObject_Call(func, arg, kw);\n#if PY_VERSION_HEX >= 0x02060000\n    if (unlikely(Py_EnterRecursiveCall((char*)\" while calling a Python object\")))\n        return NULL;\n#endif\n    result = (*call)(func, arg, kw);\n#if PY_VERSION_HEX >= 0x02060000\n    Py_LeaveRecursiveCall();\n#endif\n    if (unlikely(!result) && unlikely(!PyErr_Occurred())) {\n        PyErr_SetString(\n            PyExc_SystemError,\n            \"NULL result without error in PyObject_Call\");\n    }\n    return result;\n}\n#endif\n\nstatic CYTHON_INLINE int __Pyx_TypeTest(PyObject *obj, PyTypeObject *type) {\n    if (unlikely(!type)) {\n        PyErr_SetString(PyExc_SystemError, \"Missing type object\");\n        return 0;\n    }\n    if (likely(PyObject_TypeCheck(obj, type)))\n        return 1;\n    PyErr_Format(PyExc_TypeError, \"Cannot convert %.200s to %.200s\",\n                 Py_TYPE(obj)->tp_name, type->tp_name);\n    return 0;\n}\n\nstatic void __Pyx_RaiseBufferIndexError(int axis) {\n  PyErr_Format(PyExc_IndexError,\n     \"Out of bounds on buffer access (axis %d)\", axis);\n}\n\nstatic CYTHON_INLINE PyObject* __Pyx_PyObject_GetSlice(\n        PyObject* obj, Py_ssize_t cstart, Py_ssize_t cstop,\n        PyObject** _py_start, PyObject** _py_stop, PyObject** _py_slice,\n        int has_cstart, int has_cstop, CYTHON_UNUSED int wraparound) {\n#if CYTHON_COMPILING_IN_CPYTHON\n    PyMappingMethods* mp;\n#if PY_MAJOR_VERSION < 3\n    PySequenceMethods* ms = Py_TYPE(obj)->tp_as_sequence;\n    if (likely(ms && ms->sq_slice)) {\n        if (!has_cstart) {\n            if (_py_start && (*_py_start != Py_None)) {\n                cstart = __Pyx_PyIndex_AsSsize_t(*_py_start);\n                if ((cstart == (Py_ssize_t)-1) && PyErr_Occurred()) goto bad;\n            } else\n                cstart = 0;\n        }\n        if (!has_cstop) {\n            if (_py_stop && (*_py_stop != Py_None)) {\n                cstop = __Pyx_PyIndex_AsSsize_t(*_py_stop);\n                if ((cstop == (Py_ssize_t)-1) && PyErr_Occurred()) goto bad;\n            } else\n                cstop = PY_SSIZE_T_MAX;\n        }\n        if (wraparound && unlikely((cstart < 0) | (cstop < 0)) && likely(ms->sq_length)) {\n            Py_ssize_t l = ms->sq_length(obj);\n            if (likely(l >= 0)) {\n                if (cstop < 0) {\n                    cstop += l;\n                    if (cstop < 0) cstop = 0;\n                }\n                if (cstart < 0) {\n                    cstart += l;\n                    if (cstart < 0) cstart = 0;\n                }\n            } else {\n                if (PyErr_ExceptionMatches(PyExc_OverflowError))\n                    PyErr_Clear();\n                else\n                    goto bad;\n            }\n        }\n        return ms->sq_slice(obj, cstart, cstop);\n    }\n#endif\n    mp = Py_TYPE(obj)->tp_as_mapping;\n    if (likely(mp && mp->mp_subscript))\n#endif\n    {\n        PyObject* result;\n        PyObject *py_slice, *py_start, *py_stop;\n        if (_py_slice) {\n            py_slice = *_py_slice;\n        } else {\n            PyObject* owned_start = NULL;\n            PyObject* owned_stop = NULL;\n            if (_py_start) {\n                py_start = *_py_start;\n            } else {\n                if (has_cstart) {\n                    owned_start = py_start = PyInt_FromSsize_t(cstart);\n                    if (unlikely(!py_start)) goto bad;\n                } else\n                    py_start = Py_None;\n            }\n            if (_py_stop) {\n                py_stop = *_py_stop;\n            } else {\n                if (has_cstop) {\n                    owned_stop = py_stop = PyInt_FromSsize_t(cstop);\n                    if (unlikely(!py_stop)) {\n                        Py_XDECREF(owned_start);\n                        goto bad;\n                    }\n                } else\n                    py_stop = Py_None;\n            }\n            py_slice = PySlice_New(py_start, py_stop, Py_None);\n            Py_XDECREF(owned_start);\n            Py_XDECREF(owned_stop);\n            if (unlikely(!py_slice)) goto bad;\n        }\n#if CYTHON_COMPILING_IN_CPYTHON\n        result = mp->mp_subscript(obj, py_slice);\n#else\n        result = PyObject_GetItem(obj, py_slice);\n#endif\n        if (!_py_slice) {\n            Py_DECREF(py_slice);\n        }\n        return result;\n    }\n    PyErr_Format(PyExc_TypeError,\n        \"'%.200s' object is unsliceable\", Py_TYPE(obj)->tp_name);\nbad:\n    return NULL;\n}\n\nstatic void __Pyx_RaiseBufferFallbackError(void) {\n  PyErr_SetString(PyExc_ValueError,\n     \"Buffer acquisition failed on assignment; and then reacquiring the old buffer failed too!\");\n}\n\nstatic CYTHON_INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb) {\n#if CYTHON_COMPILING_IN_CPYTHON\n    PyObject *tmp_type, *tmp_value, *tmp_tb;\n    PyThreadState *tstate = PyThreadState_GET();\n    tmp_type = tstate->curexc_type;\n    tmp_value = tstate->curexc_value;\n    tmp_tb = tstate->curexc_traceback;\n    tstate->curexc_type = type;\n    tstate->curexc_value = value;\n    tstate->curexc_traceback = tb;\n    Py_XDECREF(tmp_type);\n    Py_XDECREF(tmp_value);\n    Py_XDECREF(tmp_tb);\n#else\n    PyErr_Restore(type, value, tb);\n#endif\n}\nstatic CYTHON_INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb) {\n#if CYTHON_COMPILING_IN_CPYTHON\n    PyThreadState *tstate = PyThreadState_GET();\n    *type = tstate->curexc_type;\n    *value = tstate->curexc_value;\n    *tb = tstate->curexc_traceback;\n    tstate->curexc_type = 0;\n    tstate->curexc_value = 0;\n    tstate->curexc_traceback = 0;\n#else\n    PyErr_Fetch(type, value, tb);\n#endif\n}\n\n#if PY_MAJOR_VERSION < 3\nstatic void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb,\n                        CYTHON_UNUSED PyObject *cause) {\n    Py_XINCREF(type);\n    if (!value || value == Py_None)\n        value = NULL;\n    else\n        Py_INCREF(value);\n    if (!tb || tb == Py_None)\n        tb = NULL;\n    else {\n        Py_INCREF(tb);\n        if (!PyTraceBack_Check(tb)) {\n            PyErr_SetString(PyExc_TypeError,\n                \"raise: arg 3 must be a traceback or None\");\n            goto raise_error;\n        }\n    }\n    #if PY_VERSION_HEX < 0x02050000\n    if (PyClass_Check(type)) {\n    #else\n    if (PyType_Check(type)) {\n    #endif\n#if CYTHON_COMPILING_IN_PYPY\n        if (!value) {\n            Py_INCREF(Py_None);\n            value = Py_None;\n        }\n#endif\n        PyErr_NormalizeException(&type, &value, &tb);\n    } else {\n        if (value) {\n            PyErr_SetString(PyExc_TypeError,\n                \"instance exception may not have a separate value\");\n            goto raise_error;\n        }\n        value = type;\n        #if PY_VERSION_HEX < 0x02050000\n        if (PyInstance_Check(type)) {\n            type = (PyObject*) ((PyInstanceObject*)type)->in_class;\n            Py_INCREF(type);\n        } else {\n            type = 0;\n            PyErr_SetString(PyExc_TypeError,\n                \"raise: exception must be an old-style class or instance\");\n            goto raise_error;\n        }\n        #else\n        type = (PyObject*) Py_TYPE(type);\n        Py_INCREF(type);\n        if (!PyType_IsSubtype((PyTypeObject *)type, (PyTypeObject *)PyExc_BaseException)) {\n            PyErr_SetString(PyExc_TypeError,\n                \"raise: exception class must be a subclass of BaseException\");\n            goto raise_error;\n        }\n        #endif\n    }\n    __Pyx_ErrRestore(type, value, tb);\n    return;\nraise_error:\n    Py_XDECREF(value);\n    Py_XDECREF(type);\n    Py_XDECREF(tb);\n    return;\n}\n#else /* Python 3+ */\nstatic void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject *cause) {\n    PyObject* owned_instance = NULL;\n    if (tb == Py_None) {\n        tb = 0;\n    } else if (tb && !PyTraceBack_Check(tb)) {\n        PyErr_SetString(PyExc_TypeError,\n            \"raise: arg 3 must be a traceback or None\");\n        goto bad;\n    }\n    if (value == Py_None)\n        value = 0;\n    if (PyExceptionInstance_Check(type)) {\n        if (value) {\n            PyErr_SetString(PyExc_TypeError,\n                \"instance exception may not have a separate value\");\n            goto bad;\n        }\n        value = type;\n        type = (PyObject*) Py_TYPE(value);\n    } else if (PyExceptionClass_Check(type)) {\n        PyObject *instance_class = NULL;\n        if (value && PyExceptionInstance_Check(value)) {\n            instance_class = (PyObject*) Py_TYPE(value);\n            if (instance_class != type) {\n                if (PyObject_IsSubclass(instance_class, type)) {\n                    type = instance_class;\n                } else {\n                    instance_class = NULL;\n                }\n            }\n        }\n        if (!instance_class) {\n            PyObject *args;\n            if (!value)\n                args = PyTuple_New(0);\n            else if (PyTuple_Check(value)) {\n                Py_INCREF(value);\n                args = value;\n            } else\n                args = PyTuple_Pack(1, value);\n            if (!args)\n                goto bad;\n            owned_instance = PyObject_Call(type, args, NULL);\n            Py_DECREF(args);\n            if (!owned_instance)\n                goto bad;\n            value = owned_instance;\n            if (!PyExceptionInstance_Check(value)) {\n                PyErr_Format(PyExc_TypeError,\n                             \"calling %R should have returned an instance of \"\n                             \"BaseException, not %R\",\n                             type, Py_TYPE(value));\n                goto bad;\n            }\n        }\n    } else {\n        PyErr_SetString(PyExc_TypeError,\n            \"raise: exception class must be a subclass of BaseException\");\n        goto bad;\n    }\n#if PY_VERSION_HEX >= 0x03030000\n    if (cause) {\n#else\n    if (cause && cause != Py_None) {\n#endif\n        PyObject *fixed_cause;\n        if (cause == Py_None) {\n            fixed_cause = NULL;\n        } else if (PyExceptionClass_Check(cause)) {\n            fixed_cause = PyObject_CallObject(cause, NULL);\n            if (fixed_cause == NULL)\n                goto bad;\n        } else if (PyExceptionInstance_Check(cause)) {\n            fixed_cause = cause;\n            Py_INCREF(fixed_cause);\n        } else {\n            PyErr_SetString(PyExc_TypeError,\n                            \"exception causes must derive from \"\n                            \"BaseException\");\n            goto bad;\n        }\n        PyException_SetCause(value, fixed_cause);\n    }\n    PyErr_SetObject(type, value);\n    if (tb) {\n        PyThreadState *tstate = PyThreadState_GET();\n        PyObject* tmp_tb = tstate->curexc_traceback;\n        if (tb != tmp_tb) {\n            Py_INCREF(tb);\n            tstate->curexc_traceback = tb;\n            Py_XDECREF(tmp_tb);\n        }\n    }\nbad:\n    Py_XDECREF(owned_instance);\n    return;\n}\n#endif\n\nstatic CYTHON_INLINE void __Pyx_RaiseTooManyValuesError(Py_ssize_t expected) {\n    PyErr_Format(PyExc_ValueError,\n                 \"too many values to unpack (expected %\" CYTHON_FORMAT_SSIZE_T \"d)\", expected);\n}\n\nstatic CYTHON_INLINE void __Pyx_RaiseNeedMoreValuesError(Py_ssize_t index) {\n    PyErr_Format(PyExc_ValueError,\n                 \"need more than %\" CYTHON_FORMAT_SSIZE_T \"d value%.1s to unpack\",\n                 index, (index == 1) ? \"\" : \"s\");\n}\n\nstatic CYTHON_INLINE void __Pyx_RaiseNoneNotIterableError(void) {\n    PyErr_SetString(PyExc_TypeError, \"'NoneType' object is not iterable\");\n}\n\n#if PY_MAJOR_VERSION < 3\nstatic int __Pyx_GetBuffer(PyObject *obj, Py_buffer *view, int flags) {\n  #if PY_VERSION_HEX >= 0x02060000\n    if (PyObject_CheckBuffer(obj)) return PyObject_GetBuffer(obj, view, flags);\n  #endif\n        if (PyObject_TypeCheck(obj, __pyx_ptype_5numpy_ndarray)) return __pyx_pw_5numpy_7ndarray_1__getbuffer__(obj, view, flags);\n  #if PY_VERSION_HEX < 0x02060000\n    if (obj->ob_type->tp_dict) {\n        PyObject *getbuffer_cobj = PyObject_GetItem(\n            obj->ob_type->tp_dict, __pyx_n_s_pyx_getbuffer);\n        if (getbuffer_cobj) {\n            getbufferproc func = (getbufferproc) PyCObject_AsVoidPtr(getbuffer_cobj);\n            Py_DECREF(getbuffer_cobj);\n            if (!func)\n                goto fail;\n            return func(obj, view, flags);\n        } else {\n            PyErr_Clear();\n        }\n    }\n  #endif\n    PyErr_Format(PyExc_TypeError, \"'%.200s' does not have the buffer interface\", Py_TYPE(obj)->tp_name);\n#if PY_VERSION_HEX < 0x02060000\nfail:\n#endif\n    return -1;\n}\nstatic void __Pyx_ReleaseBuffer(Py_buffer *view) {\n    PyObject *obj = view->obj;\n    if (!obj) return;\n  #if PY_VERSION_HEX >= 0x02060000\n    if (PyObject_CheckBuffer(obj)) {\n        PyBuffer_Release(view);\n        return;\n    }\n  #endif\n        if (PyObject_TypeCheck(obj, __pyx_ptype_5numpy_ndarray)) { __pyx_pw_5numpy_7ndarray_3__releasebuffer__(obj, view); return; }\n  #if PY_VERSION_HEX < 0x02060000\n    if (obj->ob_type->tp_dict) {\n        PyObject *releasebuffer_cobj = PyObject_GetItem(\n            obj->ob_type->tp_dict, __pyx_n_s_pyx_releasebuffer);\n        if (releasebuffer_cobj) {\n            releasebufferproc func = (releasebufferproc) PyCObject_AsVoidPtr(releasebuffer_cobj);\n            Py_DECREF(releasebuffer_cobj);\n            if (!func)\n                goto fail;\n            func(obj, view);\n            return;\n        } else {\n            PyErr_Clear();\n        }\n    }\n  #endif\n    goto nofail;\n#if PY_VERSION_HEX < 0x02060000\nfail:\n#endif\n    PyErr_WriteUnraisable(obj);\nnofail:\n    Py_DECREF(obj);\n    view->obj = NULL;\n}\n#endif /*  PY_MAJOR_VERSION < 3 */\n\n\n        static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list, int level) {\n    PyObject *empty_list = 0;\n    PyObject *module = 0;\n    PyObject *global_dict = 0;\n    PyObject *empty_dict = 0;\n    PyObject *list;\n    #if PY_VERSION_HEX < 0x03030000\n    PyObject *py_import;\n    py_import = __Pyx_PyObject_GetAttrStr(__pyx_b, __pyx_n_s_import);\n    if (!py_import)\n        goto bad;\n    #endif\n    if (from_list)\n        list = from_list;\n    else {\n        empty_list = PyList_New(0);\n        if (!empty_list)\n            goto bad;\n        list = empty_list;\n    }\n    global_dict = PyModule_GetDict(__pyx_m);\n    if (!global_dict)\n        goto bad;\n    empty_dict = PyDict_New();\n    if (!empty_dict)\n        goto bad;\n    #if PY_VERSION_HEX >= 0x02050000\n    {\n        #if PY_MAJOR_VERSION >= 3\n        if (level == -1) {\n            if (strchr(__Pyx_MODULE_NAME, '.')) {\n                #if PY_VERSION_HEX < 0x03030000\n                PyObject *py_level = PyInt_FromLong(1);\n                if (!py_level)\n                    goto bad;\n                module = PyObject_CallFunctionObjArgs(py_import,\n                    name, global_dict, empty_dict, list, py_level, NULL);\n                Py_DECREF(py_level);\n                #else\n                module = PyImport_ImportModuleLevelObject(\n                    name, global_dict, empty_dict, list, 1);\n                #endif\n                if (!module) {\n                    if (!PyErr_ExceptionMatches(PyExc_ImportError))\n                        goto bad;\n                    PyErr_Clear();\n                }\n            }\n            level = 0; /* try absolute import on failure */\n        }\n        #endif\n        if (!module) {\n            #if PY_VERSION_HEX < 0x03030000\n            PyObject *py_level = PyInt_FromLong(level);\n            if (!py_level)\n                goto bad;\n            module = PyObject_CallFunctionObjArgs(py_import,\n                name, global_dict, empty_dict, list, py_level, NULL);\n            Py_DECREF(py_level);\n            #else\n            module = PyImport_ImportModuleLevelObject(\n                name, global_dict, empty_dict, list, level);\n            #endif\n        }\n    }\n    #else\n    if (level>0) {\n        PyErr_SetString(PyExc_RuntimeError, \"Relative import is not supported for Python <=2.4.\");\n        goto bad;\n    }\n    module = PyObject_CallFunctionObjArgs(py_import,\n        name, global_dict, empty_dict, list, NULL);\n    #endif\nbad:\n    #if PY_VERSION_HEX < 0x03030000\n    Py_XDECREF(py_import);\n    #endif\n    Py_XDECREF(empty_list);\n    Py_XDECREF(empty_dict);\n    return module;\n}\n\n#define __PYX_VERIFY_RETURN_INT(target_type, func_type, func)             \\\n    {                                                                     \\\n        func_type value = func(x);                                        \\\n        if (sizeof(target_type) < sizeof(func_type)) {                    \\\n            if (unlikely(value != (func_type) (target_type) value)) {     \\\n                func_type zero = 0;                                       \\\n                PyErr_SetString(PyExc_OverflowError,                      \\\n                    (is_unsigned && unlikely(value < zero)) ?             \\\n                    \"can't convert negative value to \" #target_type :     \\\n                    \"value too large to convert to \" #target_type);       \\\n                return (target_type) -1;                                  \\\n            }                                                             \\\n        }                                                                 \\\n        return (target_type) value;                                       \\\n    }\n\n#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3\n #if CYTHON_USE_PYLONG_INTERNALS\n  #include \"longintrepr.h\"\n #endif\n#endif\nstatic CYTHON_INLINE npy_int32 __Pyx_PyInt_As_npy_int32(PyObject *x) {\n    const npy_int32 neg_one = (npy_int32) -1, const_zero = 0;\n    const int is_unsigned = neg_one > const_zero;\n#if PY_MAJOR_VERSION < 3\n    if (likely(PyInt_Check(x))) {\n        if (sizeof(npy_int32) < sizeof(long)) {\n            __PYX_VERIFY_RETURN_INT(npy_int32, long, PyInt_AS_LONG)\n        } else {\n            long val = PyInt_AS_LONG(x);\n            if (is_unsigned && unlikely(val < 0)) {\n                PyErr_SetString(PyExc_OverflowError,\n                                \"can't convert negative value to npy_int32\");\n                return (npy_int32) -1;\n            }\n            return (npy_int32) val;\n        }\n    } else\n#endif\n    if (likely(PyLong_Check(x))) {\n        if (is_unsigned) {\n#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3\n #if CYTHON_USE_PYLONG_INTERNALS\n            if (sizeof(digit) <= sizeof(npy_int32)) {\n                switch (Py_SIZE(x)) {\n                    case  0: return 0;\n                    case  1: return (npy_int32) ((PyLongObject*)x)->ob_digit[0];\n                }\n            }\n #endif\n#endif\n            if (unlikely(Py_SIZE(x) < 0)) {\n                PyErr_SetString(PyExc_OverflowError,\n                                \"can't convert negative value to npy_int32\");\n                return (npy_int32) -1;\n            }\n            if (sizeof(npy_int32) <= sizeof(unsigned long)) {\n                __PYX_VERIFY_RETURN_INT(npy_int32, unsigned long, PyLong_AsUnsignedLong)\n            } else if (sizeof(npy_int32) <= sizeof(unsigned long long)) {\n                __PYX_VERIFY_RETURN_INT(npy_int32, unsigned long long, PyLong_AsUnsignedLongLong)\n            }\n        } else {\n#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3\n #if CYTHON_USE_PYLONG_INTERNALS\n            if (sizeof(digit) <= sizeof(npy_int32)) {\n                switch (Py_SIZE(x)) {\n                    case  0: return 0;\n                    case  1: return +(npy_int32) ((PyLongObject*)x)->ob_digit[0];\n                    case -1: return -(npy_int32) ((PyLongObject*)x)->ob_digit[0];\n                }\n            }\n #endif\n#endif\n            if (sizeof(npy_int32) <= sizeof(long)) {\n                __PYX_VERIFY_RETURN_INT(npy_int32, long, PyLong_AsLong)\n            } else if (sizeof(npy_int32) <= sizeof(long long)) {\n                __PYX_VERIFY_RETURN_INT(npy_int32, long long, PyLong_AsLongLong)\n            }\n        }\n        {\n#if CYTHON_COMPILING_IN_PYPY && !defined(_PyLong_AsByteArray)\n            PyErr_SetString(PyExc_RuntimeError,\n                            \"_PyLong_AsByteArray() not available in PyPy, cannot convert large numbers\");\n#else\n            npy_int32 val;\n            PyObject *v = __Pyx_PyNumber_Int(x);\n #if PY_MAJOR_VERSION < 3\n            if (likely(v) && !PyLong_Check(v)) {\n                PyObject *tmp = v;\n                v = PyNumber_Long(tmp);\n                Py_DECREF(tmp);\n            }\n #endif\n            if (likely(v)) {\n                int one = 1; int is_little = (int)*(unsigned char *)&one;\n                unsigned char *bytes = (unsigned char *)&val;\n                int ret = _PyLong_AsByteArray((PyLongObject *)v,\n                                              bytes, sizeof(val),\n                                              is_little, !is_unsigned);\n                Py_DECREF(v);\n                if (likely(!ret))\n                    return val;\n            }\n#endif\n            return (npy_int32) -1;\n        }\n    } else {\n        npy_int32 val;\n        PyObject *tmp = __Pyx_PyNumber_Int(x);\n        if (!tmp) return (npy_int32) -1;\n        val = __Pyx_PyInt_As_npy_int32(tmp);\n        Py_DECREF(tmp);\n        return val;\n    }\n}\n\nstatic CYTHON_INLINE PyObject* __Pyx_PyInt_From_int(int value) {\n    const int neg_one = (int) -1, const_zero = 0;\n    const int is_unsigned = neg_one > const_zero;\n    if (is_unsigned) {\n        if (sizeof(int) < sizeof(long)) {\n            return PyInt_FromLong((long) value);\n        } else if (sizeof(int) <= sizeof(unsigned long)) {\n            return PyLong_FromUnsignedLong((unsigned long) value);\n        } else if (sizeof(int) <= sizeof(unsigned long long)) {\n            return PyLong_FromUnsignedLongLong((unsigned long long) value);\n        }\n    } else {\n        if (sizeof(int) <= sizeof(long)) {\n            return PyInt_FromLong((long) value);\n        } else if (sizeof(int) <= sizeof(long long)) {\n            return PyLong_FromLongLong((long long) value);\n        }\n    }\n    {\n        int one = 1; int little = (int)*(unsigned char *)&one;\n        unsigned char *bytes = (unsigned char *)&value;\n        return _PyLong_FromByteArray(bytes, sizeof(int),\n                                     little, !is_unsigned);\n    }\n}\n\n#if CYTHON_CCOMPLEX\n  #ifdef __cplusplus\n    static CYTHON_INLINE __pyx_t_float_complex __pyx_t_float_complex_from_parts(float x, float y) {\n      return ::std::complex< float >(x, y);\n    }\n  #else\n    static CYTHON_INLINE __pyx_t_float_complex __pyx_t_float_complex_from_parts(float x, float y) {\n      return x + y*(__pyx_t_float_complex)_Complex_I;\n    }\n  #endif\n#else\n    static CYTHON_INLINE __pyx_t_float_complex __pyx_t_float_complex_from_parts(float x, float y) {\n      __pyx_t_float_complex z;\n      z.real = x;\n      z.imag = y;\n      return z;\n    }\n#endif\n\n#if CYTHON_CCOMPLEX\n#else\n    static CYTHON_INLINE int __Pyx_c_eqf(__pyx_t_float_complex a, __pyx_t_float_complex b) {\n       return (a.real == b.real) && (a.imag == b.imag);\n    }\n    static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_sumf(__pyx_t_float_complex a, __pyx_t_float_complex b) {\n        __pyx_t_float_complex z;\n        z.real = a.real + b.real;\n        z.imag = a.imag + b.imag;\n        return z;\n    }\n    static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_difff(__pyx_t_float_complex a, __pyx_t_float_complex b) {\n        __pyx_t_float_complex z;\n        z.real = a.real - b.real;\n        z.imag = a.imag - b.imag;\n        return z;\n    }\n    static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_prodf(__pyx_t_float_complex a, __pyx_t_float_complex b) {\n        __pyx_t_float_complex z;\n        z.real = a.real * b.real - a.imag * b.imag;\n        z.imag = a.real * b.imag + a.imag * b.real;\n        return z;\n    }\n    static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_quotf(__pyx_t_float_complex a, __pyx_t_float_complex b) {\n        __pyx_t_float_complex z;\n        float denom = b.real * b.real + b.imag * b.imag;\n        z.real = (a.real * b.real + a.imag * b.imag) / denom;\n        z.imag = (a.imag * b.real - a.real * b.imag) / denom;\n        return z;\n    }\n    static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_negf(__pyx_t_float_complex a) {\n        __pyx_t_float_complex z;\n        z.real = -a.real;\n        z.imag = -a.imag;\n        return z;\n    }\n    static CYTHON_INLINE int __Pyx_c_is_zerof(__pyx_t_float_complex a) {\n       return (a.real == 0) && (a.imag == 0);\n    }\n    static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_conjf(__pyx_t_float_complex a) {\n        __pyx_t_float_complex z;\n        z.real =  a.real;\n        z.imag = -a.imag;\n        return z;\n    }\n    #if 1\n        static CYTHON_INLINE float __Pyx_c_absf(__pyx_t_float_complex z) {\n          #if !defined(HAVE_HYPOT) || defined(_MSC_VER)\n            return sqrtf(z.real*z.real + z.imag*z.imag);\n          #else\n            return hypotf(z.real, z.imag);\n          #endif\n        }\n        static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_powf(__pyx_t_float_complex a, __pyx_t_float_complex b) {\n            __pyx_t_float_complex z;\n            float r, lnr, theta, z_r, z_theta;\n            if (b.imag == 0 && b.real == (int)b.real) {\n                if (b.real < 0) {\n                    float denom = a.real * a.real + a.imag * a.imag;\n                    a.real = a.real / denom;\n                    a.imag = -a.imag / denom;\n                    b.real = -b.real;\n                }\n                switch ((int)b.real) {\n                    case 0:\n                        z.real = 1;\n                        z.imag = 0;\n                        return z;\n                    case 1:\n                        return a;\n                    case 2:\n                        z = __Pyx_c_prodf(a, a);\n                        return __Pyx_c_prodf(a, a);\n                    case 3:\n                        z = __Pyx_c_prodf(a, a);\n                        return __Pyx_c_prodf(z, a);\n                    case 4:\n                        z = __Pyx_c_prodf(a, a);\n                        return __Pyx_c_prodf(z, z);\n                }\n            }\n            if (a.imag == 0) {\n                if (a.real == 0) {\n                    return a;\n                }\n                r = a.real;\n                theta = 0;\n            } else {\n                r = __Pyx_c_absf(a);\n                theta = atan2f(a.imag, a.real);\n            }\n            lnr = logf(r);\n            z_r = expf(lnr * b.real - theta * b.imag);\n            z_theta = theta * b.real + lnr * b.imag;\n            z.real = z_r * cosf(z_theta);\n            z.imag = z_r * sinf(z_theta);\n            return z;\n        }\n    #endif\n#endif\n\n#if CYTHON_CCOMPLEX\n  #ifdef __cplusplus\n    static CYTHON_INLINE __pyx_t_double_complex __pyx_t_double_complex_from_parts(double x, double y) {\n      return ::std::complex< double >(x, y);\n    }\n  #else\n    static CYTHON_INLINE __pyx_t_double_complex __pyx_t_double_complex_from_parts(double x, double y) {\n      return x + y*(__pyx_t_double_complex)_Complex_I;\n    }\n  #endif\n#else\n    static CYTHON_INLINE __pyx_t_double_complex __pyx_t_double_complex_from_parts(double x, double y) {\n      __pyx_t_double_complex z;\n      z.real = x;\n      z.imag = y;\n      return z;\n    }\n#endif\n\n#if CYTHON_CCOMPLEX\n#else\n    static CYTHON_INLINE int __Pyx_c_eq(__pyx_t_double_complex a, __pyx_t_double_complex b) {\n       return (a.real == b.real) && (a.imag == b.imag);\n    }\n    static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_sum(__pyx_t_double_complex a, __pyx_t_double_complex b) {\n        __pyx_t_double_complex z;\n        z.real = a.real + b.real;\n        z.imag = a.imag + b.imag;\n        return z;\n    }\n    static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_diff(__pyx_t_double_complex a, __pyx_t_double_complex b) {\n        __pyx_t_double_complex z;\n        z.real = a.real - b.real;\n        z.imag = a.imag - b.imag;\n        return z;\n    }\n    static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_prod(__pyx_t_double_complex a, __pyx_t_double_complex b) {\n        __pyx_t_double_complex z;\n        z.real = a.real * b.real - a.imag * b.imag;\n        z.imag = a.real * b.imag + a.imag * b.real;\n        return z;\n    }\n    static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_quot(__pyx_t_double_complex a, __pyx_t_double_complex b) {\n        __pyx_t_double_complex z;\n        double denom = b.real * b.real + b.imag * b.imag;\n        z.real = (a.real * b.real + a.imag * b.imag) / denom;\n        z.imag = (a.imag * b.real - a.real * b.imag) / denom;\n        return z;\n    }\n    static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_neg(__pyx_t_double_complex a) {\n        __pyx_t_double_complex z;\n        z.real = -a.real;\n        z.imag = -a.imag;\n        return z;\n    }\n    static CYTHON_INLINE int __Pyx_c_is_zero(__pyx_t_double_complex a) {\n       return (a.real == 0) && (a.imag == 0);\n    }\n    static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_conj(__pyx_t_double_complex a) {\n        __pyx_t_double_complex z;\n        z.real =  a.real;\n        z.imag = -a.imag;\n        return z;\n    }\n    #if 1\n        static CYTHON_INLINE double __Pyx_c_abs(__pyx_t_double_complex z) {\n          #if !defined(HAVE_HYPOT) || defined(_MSC_VER)\n            return sqrt(z.real*z.real + z.imag*z.imag);\n          #else\n            return hypot(z.real, z.imag);\n          #endif\n        }\n        static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_pow(__pyx_t_double_complex a, __pyx_t_double_complex b) {\n            __pyx_t_double_complex z;\n            double r, lnr, theta, z_r, z_theta;\n            if (b.imag == 0 && b.real == (int)b.real) {\n                if (b.real < 0) {\n                    double denom = a.real * a.real + a.imag * a.imag;\n                    a.real = a.real / denom;\n                    a.imag = -a.imag / denom;\n                    b.real = -b.real;\n                }\n                switch ((int)b.real) {\n                    case 0:\n                        z.real = 1;\n                        z.imag = 0;\n                        return z;\n                    case 1:\n                        return a;\n                    case 2:\n                        z = __Pyx_c_prod(a, a);\n                        return __Pyx_c_prod(a, a);\n                    case 3:\n                        z = __Pyx_c_prod(a, a);\n                        return __Pyx_c_prod(z, a);\n                    case 4:\n                        z = __Pyx_c_prod(a, a);\n                        return __Pyx_c_prod(z, z);\n                }\n            }\n            if (a.imag == 0) {\n                if (a.real == 0) {\n                    return a;\n                }\n                r = a.real;\n                theta = 0;\n            } else {\n                r = __Pyx_c_abs(a);\n                theta = atan2(a.imag, a.real);\n            }\n            lnr = log(r);\n            z_r = exp(lnr * b.real - theta * b.imag);\n            z_theta = theta * b.real + lnr * b.imag;\n            z.real = z_r * cos(z_theta);\n            z.imag = z_r * sin(z_theta);\n            return z;\n        }\n    #endif\n#endif\n\n#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3\n #if CYTHON_USE_PYLONG_INTERNALS\n  #include \"longintrepr.h\"\n #endif\n#endif\nstatic CYTHON_INLINE int __Pyx_PyInt_As_int(PyObject *x) {\n    const int neg_one = (int) -1, const_zero = 0;\n    const int is_unsigned = neg_one > const_zero;\n#if PY_MAJOR_VERSION < 3\n    if (likely(PyInt_Check(x))) {\n        if (sizeof(int) < sizeof(long)) {\n            __PYX_VERIFY_RETURN_INT(int, long, PyInt_AS_LONG)\n        } else {\n            long val = PyInt_AS_LONG(x);\n            if (is_unsigned && unlikely(val < 0)) {\n                PyErr_SetString(PyExc_OverflowError,\n                                \"can't convert negative value to int\");\n                return (int) -1;\n            }\n            return (int) val;\n        }\n    } else\n#endif\n    if (likely(PyLong_Check(x))) {\n        if (is_unsigned) {\n#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3\n #if CYTHON_USE_PYLONG_INTERNALS\n            if (sizeof(digit) <= sizeof(int)) {\n                switch (Py_SIZE(x)) {\n                    case  0: return 0;\n                    case  1: return (int) ((PyLongObject*)x)->ob_digit[0];\n                }\n            }\n #endif\n#endif\n            if (unlikely(Py_SIZE(x) < 0)) {\n                PyErr_SetString(PyExc_OverflowError,\n                                \"can't convert negative value to int\");\n                return (int) -1;\n            }\n            if (sizeof(int) <= sizeof(unsigned long)) {\n                __PYX_VERIFY_RETURN_INT(int, unsigned long, PyLong_AsUnsignedLong)\n            } else if (sizeof(int) <= sizeof(unsigned long long)) {\n                __PYX_VERIFY_RETURN_INT(int, unsigned long long, PyLong_AsUnsignedLongLong)\n            }\n        } else {\n#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3\n #if CYTHON_USE_PYLONG_INTERNALS\n            if (sizeof(digit) <= sizeof(int)) {\n                switch (Py_SIZE(x)) {\n                    case  0: return 0;\n                    case  1: return +(int) ((PyLongObject*)x)->ob_digit[0];\n                    case -1: return -(int) ((PyLongObject*)x)->ob_digit[0];\n                }\n            }\n #endif\n#endif\n            if (sizeof(int) <= sizeof(long)) {\n                __PYX_VERIFY_RETURN_INT(int, long, PyLong_AsLong)\n            } else if (sizeof(int) <= sizeof(long long)) {\n                __PYX_VERIFY_RETURN_INT(int, long long, PyLong_AsLongLong)\n            }\n        }\n        {\n#if CYTHON_COMPILING_IN_PYPY && !defined(_PyLong_AsByteArray)\n            PyErr_SetString(PyExc_RuntimeError,\n                            \"_PyLong_AsByteArray() not available in PyPy, cannot convert large numbers\");\n#else\n            int val;\n            PyObject *v = __Pyx_PyNumber_Int(x);\n #if PY_MAJOR_VERSION < 3\n            if (likely(v) && !PyLong_Check(v)) {\n                PyObject *tmp = v;\n                v = PyNumber_Long(tmp);\n                Py_DECREF(tmp);\n            }\n #endif\n            if (likely(v)) {\n                int one = 1; int is_little = (int)*(unsigned char *)&one;\n                unsigned char *bytes = (unsigned char *)&val;\n                int ret = _PyLong_AsByteArray((PyLongObject *)v,\n                                              bytes, sizeof(val),\n                                              is_little, !is_unsigned);\n                Py_DECREF(v);\n                if (likely(!ret))\n                    return val;\n            }\n#endif\n            return (int) -1;\n        }\n    } else {\n        int val;\n        PyObject *tmp = __Pyx_PyNumber_Int(x);\n        if (!tmp) return (int) -1;\n        val = __Pyx_PyInt_As_int(tmp);\n        Py_DECREF(tmp);\n        return val;\n    }\n}\n\nstatic CYTHON_INLINE PyObject* __Pyx_PyInt_From_long(long value) {\n    const long neg_one = (long) -1, const_zero = 0;\n    const int is_unsigned = neg_one > const_zero;\n    if (is_unsigned) {\n        if (sizeof(long) < sizeof(long)) {\n            return PyInt_FromLong((long) value);\n        } else if (sizeof(long) <= sizeof(unsigned long)) {\n            return PyLong_FromUnsignedLong((unsigned long) value);\n        } else if (sizeof(long) <= sizeof(unsigned long long)) {\n            return PyLong_FromUnsignedLongLong((unsigned long long) value);\n        }\n    } else {\n        if (sizeof(long) <= sizeof(long)) {\n            return PyInt_FromLong((long) value);\n        } else if (sizeof(long) <= sizeof(long long)) {\n            return PyLong_FromLongLong((long long) value);\n        }\n    }\n    {\n        int one = 1; int little = (int)*(unsigned char *)&one;\n        unsigned char *bytes = (unsigned char *)&value;\n        return _PyLong_FromByteArray(bytes, sizeof(long),\n                                     little, !is_unsigned);\n    }\n}\n\n#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3\n #if CYTHON_USE_PYLONG_INTERNALS\n  #include \"longintrepr.h\"\n #endif\n#endif\nstatic CYTHON_INLINE long __Pyx_PyInt_As_long(PyObject *x) {\n    const long neg_one = (long) -1, const_zero = 0;\n    const int is_unsigned = neg_one > const_zero;\n#if PY_MAJOR_VERSION < 3\n    if (likely(PyInt_Check(x))) {\n        if (sizeof(long) < sizeof(long)) {\n            __PYX_VERIFY_RETURN_INT(long, long, PyInt_AS_LONG)\n        } else {\n            long val = PyInt_AS_LONG(x);\n            if (is_unsigned && unlikely(val < 0)) {\n                PyErr_SetString(PyExc_OverflowError,\n                                \"can't convert negative value to long\");\n                return (long) -1;\n            }\n            return (long) val;\n        }\n    } else\n#endif\n    if (likely(PyLong_Check(x))) {\n        if (is_unsigned) {\n#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3\n #if CYTHON_USE_PYLONG_INTERNALS\n            if (sizeof(digit) <= sizeof(long)) {\n                switch (Py_SIZE(x)) {\n                    case  0: return 0;\n                    case  1: return (long) ((PyLongObject*)x)->ob_digit[0];\n                }\n            }\n #endif\n#endif\n            if (unlikely(Py_SIZE(x) < 0)) {\n                PyErr_SetString(PyExc_OverflowError,\n                                \"can't convert negative value to long\");\n                return (long) -1;\n            }\n            if (sizeof(long) <= sizeof(unsigned long)) {\n                __PYX_VERIFY_RETURN_INT(long, unsigned long, PyLong_AsUnsignedLong)\n            } else if (sizeof(long) <= sizeof(unsigned long long)) {\n                __PYX_VERIFY_RETURN_INT(long, unsigned long long, PyLong_AsUnsignedLongLong)\n            }\n        } else {\n#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3\n #if CYTHON_USE_PYLONG_INTERNALS\n            if (sizeof(digit) <= sizeof(long)) {\n                switch (Py_SIZE(x)) {\n                    case  0: return 0;\n                    case  1: return +(long) ((PyLongObject*)x)->ob_digit[0];\n                    case -1: return -(long) ((PyLongObject*)x)->ob_digit[0];\n                }\n            }\n #endif\n#endif\n            if (sizeof(long) <= sizeof(long)) {\n                __PYX_VERIFY_RETURN_INT(long, long, PyLong_AsLong)\n            } else if (sizeof(long) <= sizeof(long long)) {\n                __PYX_VERIFY_RETURN_INT(long, long long, PyLong_AsLongLong)\n            }\n        }\n        {\n#if CYTHON_COMPILING_IN_PYPY && !defined(_PyLong_AsByteArray)\n            PyErr_SetString(PyExc_RuntimeError,\n                            \"_PyLong_AsByteArray() not available in PyPy, cannot convert large numbers\");\n#else\n            long val;\n            PyObject *v = __Pyx_PyNumber_Int(x);\n #if PY_MAJOR_VERSION < 3\n            if (likely(v) && !PyLong_Check(v)) {\n                PyObject *tmp = v;\n                v = PyNumber_Long(tmp);\n                Py_DECREF(tmp);\n            }\n #endif\n            if (likely(v)) {\n                int one = 1; int is_little = (int)*(unsigned char *)&one;\n                unsigned char *bytes = (unsigned char *)&val;\n                int ret = _PyLong_AsByteArray((PyLongObject *)v,\n                                              bytes, sizeof(val),\n                                              is_little, !is_unsigned);\n                Py_DECREF(v);\n                if (likely(!ret))\n                    return val;\n            }\n#endif\n            return (long) -1;\n        }\n    } else {\n        long val;\n        PyObject *tmp = __Pyx_PyNumber_Int(x);\n        if (!tmp) return (long) -1;\n        val = __Pyx_PyInt_As_long(tmp);\n        Py_DECREF(tmp);\n        return val;\n    }\n}\n\nstatic int __Pyx_check_binary_version(void) {\n    char ctversion[4], rtversion[4];\n    PyOS_snprintf(ctversion, 4, \"%d.%d\", PY_MAJOR_VERSION, PY_MINOR_VERSION);\n    PyOS_snprintf(rtversion, 4, \"%s\", Py_GetVersion());\n    if (ctversion[0] != rtversion[0] || ctversion[2] != rtversion[2]) {\n        char message[200];\n        PyOS_snprintf(message, sizeof(message),\n                      \"compiletime version %s of module '%.100s' \"\n                      \"does not match runtime version %s\",\n                      ctversion, __Pyx_MODULE_NAME, rtversion);\n        #if PY_VERSION_HEX < 0x02050000\n        return PyErr_Warn(NULL, message);\n        #else\n        return PyErr_WarnEx(NULL, message, 1);\n        #endif\n    }\n    return 0;\n}\n\n#ifndef __PYX_HAVE_RT_ImportModule\n#define __PYX_HAVE_RT_ImportModule\nstatic PyObject *__Pyx_ImportModule(const char *name) {\n    PyObject *py_name = 0;\n    PyObject *py_module = 0;\n    py_name = __Pyx_PyIdentifier_FromString(name);\n    if (!py_name)\n        goto bad;\n    py_module = PyImport_Import(py_name);\n    Py_DECREF(py_name);\n    return py_module;\nbad:\n    Py_XDECREF(py_name);\n    return 0;\n}\n#endif\n\n#ifndef __PYX_HAVE_RT_ImportType\n#define __PYX_HAVE_RT_ImportType\nstatic PyTypeObject *__Pyx_ImportType(const char *module_name, const char *class_name,\n    size_t size, int strict)\n{\n    PyObject *py_module = 0;\n    PyObject *result = 0;\n    PyObject *py_name = 0;\n    char warning[200];\n    Py_ssize_t basicsize;\n#ifdef Py_LIMITED_API\n    PyObject *py_basicsize;\n#endif\n    py_module = __Pyx_ImportModule(module_name);\n    if (!py_module)\n        goto bad;\n    py_name = __Pyx_PyIdentifier_FromString(class_name);\n    if (!py_name)\n        goto bad;\n    result = PyObject_GetAttr(py_module, py_name);\n    Py_DECREF(py_name);\n    py_name = 0;\n    Py_DECREF(py_module);\n    py_module = 0;\n    if (!result)\n        goto bad;\n    if (!PyType_Check(result)) {\n        PyErr_Format(PyExc_TypeError,\n            \"%.200s.%.200s is not a type object\",\n            module_name, class_name);\n        goto bad;\n    }\n#ifndef Py_LIMITED_API\n    basicsize = ((PyTypeObject *)result)->tp_basicsize;\n#else\n    py_basicsize = PyObject_GetAttrString(result, \"__basicsize__\");\n    if (!py_basicsize)\n        goto bad;\n    basicsize = PyLong_AsSsize_t(py_basicsize);\n    Py_DECREF(py_basicsize);\n    py_basicsize = 0;\n    if (basicsize == (Py_ssize_t)-1 && PyErr_Occurred())\n        goto bad;\n#endif\n    if (!strict && (size_t)basicsize > size) {\n        PyOS_snprintf(warning, sizeof(warning),\n            \"%s.%s size changed, may indicate binary incompatibility\",\n            module_name, class_name);\n        #if PY_VERSION_HEX < 0x02050000\n        if (PyErr_Warn(NULL, warning) < 0) goto bad;\n        #else\n        if (PyErr_WarnEx(NULL, warning, 0) < 0) goto bad;\n        #endif\n    }\n    else if ((size_t)basicsize != size) {\n        PyErr_Format(PyExc_ValueError,\n            \"%.200s.%.200s has the wrong size, try recompiling\",\n            module_name, class_name);\n        goto bad;\n    }\n    return (PyTypeObject *)result;\nbad:\n    Py_XDECREF(py_module);\n    Py_XDECREF(result);\n    return NULL;\n}\n#endif\n\nstatic int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line) {\n    int start = 0, mid = 0, end = count - 1;\n    if (end >= 0 && code_line > entries[end].code_line) {\n        return count;\n    }\n    while (start < end) {\n        mid = (start + end) / 2;\n        if (code_line < entries[mid].code_line) {\n            end = mid;\n        } else if (code_line > entries[mid].code_line) {\n             start = mid + 1;\n        } else {\n            return mid;\n        }\n    }\n    if (code_line <= entries[mid].code_line) {\n        return mid;\n    } else {\n        return mid + 1;\n    }\n}\nstatic PyCodeObject *__pyx_find_code_object(int code_line) {\n    PyCodeObject* code_object;\n    int pos;\n    if (unlikely(!code_line) || unlikely(!__pyx_code_cache.entries)) {\n        return NULL;\n    }\n    pos = __pyx_bisect_code_objects(__pyx_code_cache.entries, __pyx_code_cache.count, code_line);\n    if (unlikely(pos >= __pyx_code_cache.count) || unlikely(__pyx_code_cache.entries[pos].code_line != code_line)) {\n        return NULL;\n    }\n    code_object = __pyx_code_cache.entries[pos].code_object;\n    Py_INCREF(code_object);\n    return code_object;\n}\nstatic void __pyx_insert_code_object(int code_line, PyCodeObject* code_object) {\n    int pos, i;\n    __Pyx_CodeObjectCacheEntry* entries = __pyx_code_cache.entries;\n    if (unlikely(!code_line)) {\n        return;\n    }\n    if (unlikely(!entries)) {\n        entries = (__Pyx_CodeObjectCacheEntry*)PyMem_Malloc(64*sizeof(__Pyx_CodeObjectCacheEntry));\n        if (likely(entries)) {\n            __pyx_code_cache.entries = entries;\n            __pyx_code_cache.max_count = 64;\n            __pyx_code_cache.count = 1;\n            entries[0].code_line = code_line;\n            entries[0].code_object = code_object;\n            Py_INCREF(code_object);\n        }\n        return;\n    }\n    pos = __pyx_bisect_code_objects(__pyx_code_cache.entries, __pyx_code_cache.count, code_line);\n    if ((pos < __pyx_code_cache.count) && unlikely(__pyx_code_cache.entries[pos].code_line == code_line)) {\n        PyCodeObject* tmp = entries[pos].code_object;\n        entries[pos].code_object = code_object;\n        Py_DECREF(tmp);\n        return;\n    }\n    if (__pyx_code_cache.count == __pyx_code_cache.max_count) {\n        int new_max = __pyx_code_cache.max_count + 64;\n        entries = (__Pyx_CodeObjectCacheEntry*)PyMem_Realloc(\n            __pyx_code_cache.entries, new_max*sizeof(__Pyx_CodeObjectCacheEntry));\n        if (unlikely(!entries)) {\n            return;\n        }\n        __pyx_code_cache.entries = entries;\n        __pyx_code_cache.max_count = new_max;\n    }\n    for (i=__pyx_code_cache.count; i>pos; i--) {\n        entries[i] = entries[i-1];\n    }\n    entries[pos].code_line = code_line;\n    entries[pos].code_object = code_object;\n    __pyx_code_cache.count++;\n    Py_INCREF(code_object);\n}\n\n#include \"compile.h\"\n#include \"frameobject.h\"\n#include \"traceback.h\"\nstatic PyCodeObject* __Pyx_CreateCodeObjectForTraceback(\n            const char *funcname, int c_line,\n            int py_line, const char *filename) {\n    PyCodeObject *py_code = 0;\n    PyObject *py_srcfile = 0;\n    PyObject *py_funcname = 0;\n    #if PY_MAJOR_VERSION < 3\n    py_srcfile = PyString_FromString(filename);\n    #else\n    py_srcfile = PyUnicode_FromString(filename);\n    #endif\n    if (!py_srcfile) goto bad;\n    if (c_line) {\n        #if PY_MAJOR_VERSION < 3\n        py_funcname = PyString_FromFormat( \"%s (%s:%d)\", funcname, __pyx_cfilenm, c_line);\n        #else\n        py_funcname = PyUnicode_FromFormat( \"%s (%s:%d)\", funcname, __pyx_cfilenm, c_line);\n        #endif\n    }\n    else {\n        #if PY_MAJOR_VERSION < 3\n        py_funcname = PyString_FromString(funcname);\n        #else\n        py_funcname = PyUnicode_FromString(funcname);\n        #endif\n    }\n    if (!py_funcname) goto bad;\n    py_code = __Pyx_PyCode_New(\n        0,            /*int argcount,*/\n        0,            /*int kwonlyargcount,*/\n        0,            /*int nlocals,*/\n        0,            /*int stacksize,*/\n        0,            /*int flags,*/\n        __pyx_empty_bytes, /*PyObject *code,*/\n        __pyx_empty_tuple, /*PyObject *consts,*/\n        __pyx_empty_tuple, /*PyObject *names,*/\n        __pyx_empty_tuple, /*PyObject *varnames,*/\n        __pyx_empty_tuple, /*PyObject *freevars,*/\n        __pyx_empty_tuple, /*PyObject *cellvars,*/\n        py_srcfile,   /*PyObject *filename,*/\n        py_funcname,  /*PyObject *name,*/\n        py_line,      /*int firstlineno,*/\n        __pyx_empty_bytes  /*PyObject *lnotab*/\n    );\n    Py_DECREF(py_srcfile);\n    Py_DECREF(py_funcname);\n    return py_code;\nbad:\n    Py_XDECREF(py_srcfile);\n    Py_XDECREF(py_funcname);\n    return NULL;\n}\nstatic void __Pyx_AddTraceback(const char *funcname, int c_line,\n                               int py_line, const char *filename) {\n    PyCodeObject *py_code = 0;\n    PyObject *py_globals = 0;\n    PyFrameObject *py_frame = 0;\n    py_code = __pyx_find_code_object(c_line ? c_line : py_line);\n    if (!py_code) {\n        py_code = __Pyx_CreateCodeObjectForTraceback(\n            funcname, c_line, py_line, filename);\n        if (!py_code) goto bad;\n        __pyx_insert_code_object(c_line ? c_line : py_line, py_code);\n    }\n    py_globals = PyModule_GetDict(__pyx_m);\n    if (!py_globals) goto bad;\n    py_frame = PyFrame_New(\n        PyThreadState_GET(), /*PyThreadState *tstate,*/\n        py_code,             /*PyCodeObject *code,*/\n        py_globals,          /*PyObject *globals,*/\n        0                    /*PyObject *locals*/\n    );\n    if (!py_frame) goto bad;\n    py_frame->f_lineno = py_line;\n    PyTraceBack_Here(py_frame);\nbad:\n    Py_XDECREF(py_code);\n    Py_XDECREF(py_frame);\n}\n\nstatic int __Pyx_InitStrings(__Pyx_StringTabEntry *t) {\n    while (t->p) {\n        #if PY_MAJOR_VERSION < 3\n        if (t->is_unicode) {\n            *t->p = PyUnicode_DecodeUTF8(t->s, t->n - 1, NULL);\n        } else if (t->intern) {\n            *t->p = PyString_InternFromString(t->s);\n        } else {\n            *t->p = PyString_FromStringAndSize(t->s, t->n - 1);\n        }\n        #else  /* Python 3+ has unicode identifiers */\n        if (t->is_unicode | t->is_str) {\n            if (t->intern) {\n                *t->p = PyUnicode_InternFromString(t->s);\n            } else if (t->encoding) {\n                *t->p = PyUnicode_Decode(t->s, t->n - 1, t->encoding, NULL);\n            } else {\n                *t->p = PyUnicode_FromStringAndSize(t->s, t->n - 1);\n            }\n        } else {\n            *t->p = PyBytes_FromStringAndSize(t->s, t->n - 1);\n        }\n        #endif\n        if (!*t->p)\n            return -1;\n        ++t;\n    }\n    return 0;\n}\n\nstatic CYTHON_INLINE PyObject* __Pyx_PyUnicode_FromString(char* c_str) {\n    return __Pyx_PyUnicode_FromStringAndSize(c_str, strlen(c_str));\n}\nstatic CYTHON_INLINE char* __Pyx_PyObject_AsString(PyObject* o) {\n    Py_ssize_t ignore;\n    return __Pyx_PyObject_AsStringAndSize(o, &ignore);\n}\nstatic CYTHON_INLINE char* __Pyx_PyObject_AsStringAndSize(PyObject* o, Py_ssize_t *length) {\n#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII || __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT\n    if (\n#if PY_MAJOR_VERSION < 3 && __PYX_DEFAULT_STRING_ENCODING_IS_ASCII\n            __Pyx_sys_getdefaultencoding_not_ascii &&\n#endif\n            PyUnicode_Check(o)) {\n#if PY_VERSION_HEX < 0x03030000\n        char* defenc_c;\n        PyObject* defenc = _PyUnicode_AsDefaultEncodedString(o, NULL);\n        if (!defenc) return NULL;\n        defenc_c = PyBytes_AS_STRING(defenc);\n#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII\n        {\n            char* end = defenc_c + PyBytes_GET_SIZE(defenc);\n            char* c;\n            for (c = defenc_c; c < end; c++) {\n                if ((unsigned char) (*c) >= 128) {\n                    PyUnicode_AsASCIIString(o);\n                    return NULL;\n                }\n            }\n        }\n#endif /*__PYX_DEFAULT_STRING_ENCODING_IS_ASCII*/\n        *length = PyBytes_GET_SIZE(defenc);\n        return defenc_c;\n#else /* PY_VERSION_HEX < 0x03030000 */\n        if (PyUnicode_READY(o) == -1) return NULL;\n#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII\n        if (PyUnicode_IS_ASCII(o)) {\n            *length = PyUnicode_GET_DATA_SIZE(o);\n            return PyUnicode_AsUTF8(o);\n        } else {\n            PyUnicode_AsASCIIString(o);\n            return NULL;\n        }\n#else /* __PYX_DEFAULT_STRING_ENCODING_IS_ASCII */\n        return PyUnicode_AsUTF8AndSize(o, length);\n#endif /* __PYX_DEFAULT_STRING_ENCODING_IS_ASCII */\n#endif /* PY_VERSION_HEX < 0x03030000 */\n    } else\n#endif /* __PYX_DEFAULT_STRING_ENCODING_IS_ASCII  || __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT */\n#if !CYTHON_COMPILING_IN_PYPY\n#if PY_VERSION_HEX >= 0x02060000\n    if (PyByteArray_Check(o)) {\n        *length = PyByteArray_GET_SIZE(o);\n        return PyByteArray_AS_STRING(o);\n    } else\n#endif\n#endif\n    {\n        char* result;\n        int r = PyBytes_AsStringAndSize(o, &result, length);\n        if (unlikely(r < 0)) {\n            return NULL;\n        } else {\n            return result;\n        }\n    }\n}\nstatic CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject* x) {\n   int is_true = x == Py_True;\n   if (is_true | (x == Py_False) | (x == Py_None)) return is_true;\n   else return PyObject_IsTrue(x);\n}\nstatic CYTHON_INLINE PyObject* __Pyx_PyNumber_Int(PyObject* x) {\n  PyNumberMethods *m;\n  const char *name = NULL;\n  PyObject *res = NULL;\n#if PY_MAJOR_VERSION < 3\n  if (PyInt_Check(x) || PyLong_Check(x))\n#else\n  if (PyLong_Check(x))\n#endif\n    return Py_INCREF(x), x;\n  m = Py_TYPE(x)->tp_as_number;\n#if PY_MAJOR_VERSION < 3\n  if (m && m->nb_int) {\n    name = \"int\";\n    res = PyNumber_Int(x);\n  }\n  else if (m && m->nb_long) {\n    name = \"long\";\n    res = PyNumber_Long(x);\n  }\n#else\n  if (m && m->nb_int) {\n    name = \"int\";\n    res = PyNumber_Long(x);\n  }\n#endif\n  if (res) {\n#if PY_MAJOR_VERSION < 3\n    if (!PyInt_Check(res) && !PyLong_Check(res)) {\n#else\n    if (!PyLong_Check(res)) {\n#endif\n      PyErr_Format(PyExc_TypeError,\n                   \"__%.4s__ returned non-%.4s (type %.200s)\",\n                   name, name, Py_TYPE(res)->tp_name);\n      Py_DECREF(res);\n      return NULL;\n    }\n  }\n  else if (!PyErr_Occurred()) {\n    PyErr_SetString(PyExc_TypeError,\n                    \"an integer is required\");\n  }\n  return res;\n}\n#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3\n #if CYTHON_USE_PYLONG_INTERNALS\n  #include \"longintrepr.h\"\n #endif\n#endif\nstatic CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject* b) {\n  Py_ssize_t ival;\n  PyObject *x;\n#if PY_MAJOR_VERSION < 3\n  if (likely(PyInt_CheckExact(b)))\n      return PyInt_AS_LONG(b);\n#endif\n  if (likely(PyLong_CheckExact(b))) {\n    #if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3\n     #if CYTHON_USE_PYLONG_INTERNALS\n       switch (Py_SIZE(b)) {\n       case -1: return -(sdigit)((PyLongObject*)b)->ob_digit[0];\n       case  0: return 0;\n       case  1: return ((PyLongObject*)b)->ob_digit[0];\n       }\n     #endif\n    #endif\n  #if PY_VERSION_HEX < 0x02060000\n    return PyInt_AsSsize_t(b);\n  #else\n    return PyLong_AsSsize_t(b);\n  #endif\n  }\n  x = PyNumber_Index(b);\n  if (!x) return -1;\n  ival = PyInt_AsSsize_t(x);\n  Py_DECREF(x);\n  return ival;\n}\nstatic CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t ival) {\n#if PY_VERSION_HEX < 0x02050000\n   if (ival <= LONG_MAX)\n       return PyInt_FromLong((long)ival);\n   else {\n       unsigned char *bytes = (unsigned char *) &ival;\n       int one = 1; int little = (int)*(unsigned char*)&one;\n       return _PyLong_FromByteArray(bytes, sizeof(size_t), little, 0);\n   }\n#else\n   return PyInt_FromSize_t(ival);\n#endif\n}\n\n\n#endif /* Py_PYTHON_H */\n"
  },
  {
    "path": "src/tools/voc_eval_lib/nms/gpu_nms.hpp",
    "content": "void _nms(int* keep_out, int* num_out, const float* boxes_host, int boxes_num,\n          int boxes_dim, float nms_overlap_thresh, int device_id);\n"
  },
  {
    "path": "src/tools/voc_eval_lib/nms/gpu_nms.pyx",
    "content": "# --------------------------------------------------------\n# Faster R-CNN\n# Copyright (c) 2015 Microsoft\n# Licensed under The MIT License [see LICENSE for details]\n# Written by Ross Girshick\n# --------------------------------------------------------\n\nimport numpy as np\ncimport numpy as np\n\nassert sizeof(int) == sizeof(np.int32_t)\n\ncdef extern from \"gpu_nms.hpp\":\n    void _nms(np.int32_t*, int*, np.float32_t*, int, int, float, int)\n\ndef gpu_nms(np.ndarray[np.float32_t, ndim=2] dets, np.float thresh,\n            np.int32_t device_id=0):\n    cdef int boxes_num = dets.shape[0]\n    cdef int boxes_dim = dets.shape[1]\n    cdef int num_out\n    cdef np.ndarray[np.int32_t, ndim=1] \\\n        keep = np.zeros(boxes_num, dtype=np.int32)\n    cdef np.ndarray[np.float32_t, ndim=1] \\\n        scores = dets[:, 4]\n    cdef np.ndarray[np.int_t, ndim=1] \\\n        order = scores.argsort()[::-1]\n    cdef np.ndarray[np.float32_t, ndim=2] \\\n        sorted_dets = dets[order, :]\n    _nms(&keep[0], &num_out, &sorted_dets[0, 0], boxes_num, boxes_dim, thresh, device_id)\n    keep = keep[:num_out]\n    return list(order[keep])\n"
  },
  {
    "path": "src/tools/voc_eval_lib/nms/nms_kernel.cu",
    "content": "// ------------------------------------------------------------------\n// Faster R-CNN\n// Copyright (c) 2015 Microsoft\n// Licensed under The MIT License [see fast-rcnn/LICENSE for details]\n// Written by Shaoqing Ren\n// ------------------------------------------------------------------\n\n#include \"gpu_nms.hpp\"\n#include <vector>\n#include <iostream>\n\n#define CUDA_CHECK(condition) \\\n  /* Code block avoids redefinition of cudaError_t error */ \\\n  do { \\\n    cudaError_t error = condition; \\\n    if (error != cudaSuccess) { \\\n      std::cout << cudaGetErrorString(error) << std::endl; \\\n    } \\\n  } while (0)\n\n#define DIVUP(m,n) ((m) / (n) + ((m) % (n) > 0))\nint const threadsPerBlock = sizeof(unsigned long long) * 8;\n\n__device__ inline float devIoU(float const * const a, float const * const b) {\n  float left = max(a[0], b[0]), right = min(a[2], b[2]);\n  float top = max(a[1], b[1]), bottom = min(a[3], b[3]);\n  float width = max(right - left + 1, 0.f), height = max(bottom - top + 1, 0.f);\n  float interS = width * height;\n  float Sa = (a[2] - a[0] + 1) * (a[3] - a[1] + 1);\n  float Sb = (b[2] - b[0] + 1) * (b[3] - b[1] + 1);\n  return interS / (Sa + Sb - interS);\n}\n\n__global__ void nms_kernel(const int n_boxes, const float nms_overlap_thresh,\n                           const float *dev_boxes, unsigned long long *dev_mask) {\n  const int row_start = blockIdx.y;\n  const int col_start = blockIdx.x;\n\n  // if (row_start > col_start) return;\n\n  const int row_size =\n        min(n_boxes - row_start * threadsPerBlock, threadsPerBlock);\n  const int col_size =\n        min(n_boxes - col_start * threadsPerBlock, threadsPerBlock);\n\n  __shared__ float block_boxes[threadsPerBlock * 5];\n  if (threadIdx.x < col_size) {\n    block_boxes[threadIdx.x * 5 + 0] =\n        dev_boxes[(threadsPerBlock * col_start + threadIdx.x) * 5 + 0];\n    block_boxes[threadIdx.x * 5 + 1] =\n        dev_boxes[(threadsPerBlock * col_start + threadIdx.x) * 5 + 1];\n    block_boxes[threadIdx.x * 5 + 2] =\n        dev_boxes[(threadsPerBlock * col_start + threadIdx.x) * 5 + 2];\n    block_boxes[threadIdx.x * 5 + 3] =\n        dev_boxes[(threadsPerBlock * col_start + threadIdx.x) * 5 + 3];\n    block_boxes[threadIdx.x * 5 + 4] =\n        dev_boxes[(threadsPerBlock * col_start + threadIdx.x) * 5 + 4];\n  }\n  __syncthreads();\n\n  if (threadIdx.x < row_size) {\n    const int cur_box_idx = threadsPerBlock * row_start + threadIdx.x;\n    const float *cur_box = dev_boxes + cur_box_idx * 5;\n    int i = 0;\n    unsigned long long t = 0;\n    int start = 0;\n    if (row_start == col_start) {\n      start = threadIdx.x + 1;\n    }\n    for (i = start; i < col_size; i++) {\n      if (devIoU(cur_box, block_boxes + i * 5) > nms_overlap_thresh) {\n        t |= 1ULL << i;\n      }\n    }\n    const int col_blocks = DIVUP(n_boxes, threadsPerBlock);\n    dev_mask[cur_box_idx * col_blocks + col_start] = t;\n  }\n}\n\nvoid _set_device(int device_id) {\n  int current_device;\n  CUDA_CHECK(cudaGetDevice(&current_device));\n  if (current_device == device_id) {\n    return;\n  }\n  // The call to cudaSetDevice must come before any calls to Get, which\n  // may perform initialization using the GPU.\n  CUDA_CHECK(cudaSetDevice(device_id));\n}\n\nvoid _nms(int* keep_out, int* num_out, const float* boxes_host, int boxes_num,\n          int boxes_dim, float nms_overlap_thresh, int device_id) {\n  _set_device(device_id);\n\n  float* boxes_dev = NULL;\n  unsigned long long* mask_dev = NULL;\n\n  const int col_blocks = DIVUP(boxes_num, threadsPerBlock);\n\n  CUDA_CHECK(cudaMalloc(&boxes_dev,\n                        boxes_num * boxes_dim * sizeof(float)));\n  CUDA_CHECK(cudaMemcpy(boxes_dev,\n                        boxes_host,\n                        boxes_num * boxes_dim * sizeof(float),\n                        cudaMemcpyHostToDevice));\n\n  CUDA_CHECK(cudaMalloc(&mask_dev,\n                        boxes_num * col_blocks * sizeof(unsigned long long)));\n\n  dim3 blocks(DIVUP(boxes_num, threadsPerBlock),\n              DIVUP(boxes_num, threadsPerBlock));\n  dim3 threads(threadsPerBlock);\n  nms_kernel<<<blocks, threads>>>(boxes_num,\n                                  nms_overlap_thresh,\n                                  boxes_dev,\n                                  mask_dev);\n\n  std::vector<unsigned long long> mask_host(boxes_num * col_blocks);\n  CUDA_CHECK(cudaMemcpy(&mask_host[0],\n                        mask_dev,\n                        sizeof(unsigned long long) * boxes_num * col_blocks,\n                        cudaMemcpyDeviceToHost));\n\n  std::vector<unsigned long long> remv(col_blocks);\n  memset(&remv[0], 0, sizeof(unsigned long long) * col_blocks);\n\n  int num_to_keep = 0;\n  for (int i = 0; i < boxes_num; i++) {\n    int nblock = i / threadsPerBlock;\n    int inblock = i % threadsPerBlock;\n\n    if (!(remv[nblock] & (1ULL << inblock))) {\n      keep_out[num_to_keep++] = i;\n      unsigned long long *p = &mask_host[0] + i * col_blocks;\n      for (int j = nblock; j < col_blocks; j++) {\n        remv[j] |= p[j];\n      }\n    }\n  }\n  *num_out = num_to_keep;\n\n  CUDA_CHECK(cudaFree(boxes_dev));\n  CUDA_CHECK(cudaFree(mask_dev));\n}\n"
  },
  {
    "path": "src/tools/voc_eval_lib/nms/py_cpu_nms.py",
    "content": "# --------------------------------------------------------\n# Fast R-CNN\n# Copyright (c) 2015 Microsoft\n# Licensed under The MIT License [see LICENSE for details]\n# Written by Ross Girshick\n# --------------------------------------------------------\n\nimport numpy as np\n\ndef py_cpu_nms(dets, thresh):\n    \"\"\"Pure Python NMS baseline.\"\"\"\n    x1 = dets[:, 0]\n    y1 = dets[:, 1]\n    x2 = dets[:, 2]\n    y2 = dets[:, 3]\n    scores = dets[:, 4]\n\n    areas = (x2 - x1 + 1) * (y2 - y1 + 1)\n    order = scores.argsort()[::-1]\n\n    keep = []\n    while order.size > 0:\n        i = order[0]\n        keep.append(i)\n        xx1 = np.maximum(x1[i], x1[order[1:]])\n        yy1 = np.maximum(y1[i], y1[order[1:]])\n        xx2 = np.minimum(x2[i], x2[order[1:]])\n        yy2 = np.minimum(y2[i], y2[order[1:]])\n\n        w = np.maximum(0.0, xx2 - xx1 + 1)\n        h = np.maximum(0.0, yy2 - yy1 + 1)\n        inter = w * h\n        ovr = inter / (areas[i] + areas[order[1:]] - inter)\n\n        inds = np.where(ovr <= thresh)[0]\n        order = order[inds + 1]\n\n    return keep\n"
  },
  {
    "path": "src/tools/voc_eval_lib/setup.py",
    "content": "# --------------------------------------------------------\n# Fast R-CNN\n# Copyright (c) 2015 Microsoft\n# Licensed under The MIT License [see LICENSE for details]\n# Written by Ross Girshick\n# --------------------------------------------------------\n\nimport os\nfrom os.path import join as pjoin\nimport numpy as np\nfrom distutils.core import setup\nfrom distutils.extension import Extension\nfrom Cython.Distutils import build_ext\n\ndef find_in_path(name, path):\n    \"Find a file in a search path\"\n    #adapted fom http://code.activestate.com/recipes/52224-find-a-file-given-a-search-path/\n    for dir in path.split(os.pathsep):\n        binpath = pjoin(dir, name)\n        if os.path.exists(binpath):\n            return os.path.abspath(binpath)\n    return None\n\ndef locate_cuda():\n    \"\"\"Locate the CUDA environment on the system\n\n    Returns a dict with keys 'home', 'nvcc', 'include', and 'lib64'\n    and values giving the absolute path to each directory.\n\n    Starts by looking for the CUDAHOME env variable. If not found, everything\n    is based on finding 'nvcc' in the PATH.\n    \"\"\"\n\n    # first check if the CUDAHOME env variable is in use\n    if 'CUDAHOME' in os.environ:\n        home = os.environ['CUDAHOME']\n        nvcc = pjoin(home, 'bin', 'nvcc')\n    else:\n        # otherwise, search the PATH for NVCC\n        default_path = pjoin(os.sep, 'usr', 'local', 'cuda', 'bin')\n        nvcc = find_in_path('nvcc', os.environ['PATH'] + os.pathsep + default_path)\n        if nvcc is None:\n            raise EnvironmentError('The nvcc binary could not be '\n                'located in your $PATH. Either add it to your path, or set $CUDAHOME')\n        home = os.path.dirname(os.path.dirname(nvcc))\n\n    cudaconfig = {'home':home, 'nvcc':nvcc,\n                  'include': pjoin(home, 'include'),\n                  'lib64': pjoin(home, 'lib64')}\n    for k, v in cudaconfig.items():\n        if not os.path.exists(v):\n            raise EnvironmentError('The CUDA %s path could not be located in %s' % (k, v))\n\n    return cudaconfig\nCUDA = locate_cuda()\n\n# Obtain the numpy include directory.  This logic works across numpy versions.\ntry:\n    numpy_include = np.get_include()\nexcept AttributeError:\n    numpy_include = np.get_numpy_include()\n\ndef customize_compiler_for_nvcc(self):\n    \"\"\"inject deep into distutils to customize how the dispatch\n    to gcc/nvcc works.\n\n    If you subclass UnixCCompiler, it's not trivial to get your subclass\n    injected in, and still have the right customizations (i.e.\n    distutils.sysconfig.customize_compiler) run on it. So instead of going\n    the OO route, I have this. Note, it's kindof like a wierd functional\n    subclassing going on.\"\"\"\n\n    # tell the compiler it can processes .cu\n    self.src_extensions.append('.cu')\n\n    # save references to the default compiler_so and _comple methods\n    default_compiler_so = self.compiler_so\n    super = self._compile\n\n    # now redefine the _compile method. This gets executed for each\n    # object but distutils doesn't have the ability to change compilers\n    # based on source extension: we add it.\n    def _compile(obj, src, ext, cc_args, extra_postargs, pp_opts):\n        print(extra_postargs)\n        if os.path.splitext(src)[1] == '.cu':\n            # use the cuda for .cu files\n            self.set_executable('compiler_so', CUDA['nvcc'])\n            # use only a subset of the extra_postargs, which are 1-1 translated\n            # from the extra_compile_args in the Extension class\n            postargs = extra_postargs['nvcc']\n        else:\n            postargs = extra_postargs['gcc']\n\n        super(obj, src, ext, cc_args, postargs, pp_opts)\n        # reset the default compiler_so, which we might have changed for cuda\n        self.compiler_so = default_compiler_so\n\n    # inject our redefined _compile method into the class\n    self._compile = _compile\n\n# run the customize_compiler\nclass custom_build_ext(build_ext):\n    def build_extensions(self):\n        customize_compiler_for_nvcc(self.compiler)\n        build_ext.build_extensions(self)\n\next_modules = [\n    Extension(\n        \"utils.cython_bbox\",\n        [\"utils/bbox.pyx\"],\n        extra_compile_args={'gcc': [\"-Wno-cpp\", \"-Wno-unused-function\"]},\n        include_dirs = [numpy_include]\n    ),\n    Extension(\n        \"nms.cpu_nms\",\n        [\"nms/cpu_nms.pyx\"],\n        extra_compile_args={'gcc': [\"-Wno-cpp\", \"-Wno-unused-function\"]},\n        include_dirs = [numpy_include]\n    ),\n    Extension('nms.gpu_nms',\n        ['nms/nms_kernel.cu', 'nms/gpu_nms.pyx'],\n        library_dirs=[CUDA['lib64']],\n        libraries=['cudart'],\n        language='c++',\n        runtime_library_dirs=[CUDA['lib64']],\n        # this syntax is specific to this build system\n        # we're only going to use certain compiler args with nvcc and not with gcc\n        # the implementation of this trick is in customize_compiler() below\n        extra_compile_args={'gcc': [\"-Wno-unused-function\"],\n                            'nvcc': ['-arch=sm_61',\n                                     '--ptxas-options=-v',\n                                     '-c',\n                                     '--compiler-options',\n                                     \"'-fPIC'\"]},\n        include_dirs = [numpy_include, CUDA['include']]\n    )\n]\n\nsetup(\n    name='tf_faster_rcnn',\n    ext_modules=ext_modules,\n    # inject our custom trigger\n    cmdclass={'build_ext': custom_build_ext},\n)\n"
  },
  {
    "path": "src/tools/voc_eval_lib/utils/.gitignore",
    "content": "*.c\n*.cpp\n*.h\n*.hpp\n"
  },
  {
    "path": "src/tools/voc_eval_lib/utils/__init__.py",
    "content": "# --------------------------------------------------------\n# Fast R-CNN\n# Copyright (c) 2015 Microsoft\n# Licensed under The MIT License [see LICENSE for details]\n# Written by Ross Girshick\n# --------------------------------------------------------\n"
  },
  {
    "path": "src/tools/voc_eval_lib/utils/bbox.pyx",
    "content": "# --------------------------------------------------------\n# Fast R-CNN\n# Copyright (c) 2015 Microsoft\n# Licensed under The MIT License [see LICENSE for details]\n# Written by Sergey Karayev\n# --------------------------------------------------------\n\ncimport cython\nimport numpy as np\ncimport numpy as np\n\nDTYPE = np.float\nctypedef np.float_t DTYPE_t\n\ndef bbox_overlaps(\n        np.ndarray[DTYPE_t, ndim=2] boxes,\n        np.ndarray[DTYPE_t, ndim=2] query_boxes):\n    \"\"\"\n    Parameters\n    ----------\n    boxes: (N, 4) ndarray of float\n    query_boxes: (K, 4) ndarray of float\n    Returns\n    -------\n    overlaps: (N, K) ndarray of overlap between boxes and query_boxes\n    \"\"\"\n    cdef unsigned int N = boxes.shape[0]\n    cdef unsigned int K = query_boxes.shape[0]\n    cdef np.ndarray[DTYPE_t, ndim=2] overlaps = np.zeros((N, K), dtype=DTYPE)\n    cdef DTYPE_t iw, ih, box_area\n    cdef DTYPE_t ua\n    cdef unsigned int k, n\n    for k in range(K):\n        box_area = (\n            (query_boxes[k, 2] - query_boxes[k, 0] + 1) *\n            (query_boxes[k, 3] - query_boxes[k, 1] + 1)\n        )\n        for n in range(N):\n            iw = (\n                min(boxes[n, 2], query_boxes[k, 2]) -\n                max(boxes[n, 0], query_boxes[k, 0]) + 1\n            )\n            if iw > 0:\n                ih = (\n                    min(boxes[n, 3], query_boxes[k, 3]) -\n                    max(boxes[n, 1], query_boxes[k, 1]) + 1\n                )\n                if ih > 0:\n                    ua = float(\n                        (boxes[n, 2] - boxes[n, 0] + 1) *\n                        (boxes[n, 3] - boxes[n, 1] + 1) +\n                        box_area - iw * ih\n                    )\n                    overlaps[n, k] = iw * ih / ua\n    return overlaps\n\n"
  },
  {
    "path": "src/tools/voc_eval_lib/utils/blob.py",
    "content": "# --------------------------------------------------------\n# Fast R-CNN\n# Copyright (c) 2015 Microsoft\n# Licensed under The MIT License [see LICENSE for details]\n# Written by Ross Girshick\n# --------------------------------------------------------\n\n\"\"\"Blob helper functions.\"\"\"\nfrom __future__ import absolute_import\nfrom __future__ import division\nfrom __future__ import print_function\n\nimport numpy as np\nimport cv2\n\n\ndef im_list_to_blob(ims):\n  \"\"\"Convert a list of images into a network input.\n\n  Assumes images are already prepared (means subtracted, BGR order, ...).\n  \"\"\"\n  max_shape = np.array([im.shape for im in ims]).max(axis=0)\n  num_images = len(ims)\n  blob = np.zeros((num_images, max_shape[0], max_shape[1], 3),\n                  dtype=np.float32)\n  for i in range(num_images):\n    im = ims[i]\n    blob[i, 0:im.shape[0], 0:im.shape[1], :] = im\n\n  return blob\n\n\ndef prep_im_for_blob(im, pixel_means, target_size, max_size):\n  \"\"\"Mean subtract and scale an image for use in a blob.\"\"\"\n  im = im.astype(np.float32, copy=False)\n  im -= pixel_means\n  im_shape = im.shape\n  im_size_min = np.min(im_shape[0:2])\n  im_size_max = np.max(im_shape[0:2])\n  im_scale = float(target_size) / float(im_size_min)\n  # Prevent the biggest axis from being more than MAX_SIZE\n  if np.round(im_scale * im_size_max) > max_size:\n    im_scale = float(max_size) / float(im_size_max)\n  im = cv2.resize(im, None, None, fx=im_scale, fy=im_scale,\n                  interpolation=cv2.INTER_LINEAR)\n\n  return im, im_scale\n"
  },
  {
    "path": "src/tools/voc_eval_lib/utils/timer.py",
    "content": "# --------------------------------------------------------\n# Fast R-CNN\n# Copyright (c) 2015 Microsoft\n# Licensed under The MIT License [see LICENSE for details]\n# Written by Ross Girshick\n# --------------------------------------------------------\n\nimport time\n\nclass Timer(object):\n    \"\"\"A simple timer.\"\"\"\n    def __init__(self):\n        self.total_time = 0.\n        self.calls = 0\n        self.start_time = 0.\n        self.diff = 0.\n        self.average_time = 0.\n\n    def tic(self):\n        # using time.time instead of time.clock because time time.clock\n        # does not normalize for multithreading\n        self.start_time = time.time()\n\n    def toc(self, average=True):\n        self.diff = time.time() - self.start_time\n        self.total_time += self.diff\n        self.calls += 1\n        self.average_time = self.total_time / self.calls\n        if average:\n            return self.average_time\n        else:\n            return self.diff\n"
  },
  {
    "path": "src/tools/voc_eval_lib/utils/visualization.py",
    "content": "# --------------------------------------------------------\n# Tensorflow Faster R-CNN\n# Licensed under The MIT License [see LICENSE for details]\n# Written by Xinlei Chen\n# --------------------------------------------------------\nfrom __future__ import absolute_import\nfrom __future__ import division\nfrom __future__ import print_function\n\nimport numpy as np\nfrom six.moves import range\nimport PIL.Image as Image\nimport PIL.ImageColor as ImageColor\nimport PIL.ImageDraw as ImageDraw\nimport PIL.ImageFont as ImageFont\n\nSTANDARD_COLORS = [\n    'AliceBlue', 'Chartreuse', 'Aqua', 'Aquamarine', 'Azure', 'Beige', 'Bisque',\n    'BlanchedAlmond', 'BlueViolet', 'BurlyWood', 'CadetBlue', 'AntiqueWhite',\n    'Chocolate', 'Coral', 'CornflowerBlue', 'Cornsilk', 'Crimson', 'Cyan',\n    'DarkCyan', 'DarkGoldenRod', 'DarkGrey', 'DarkKhaki', 'DarkOrange',\n    'DarkOrchid', 'DarkSalmon', 'DarkSeaGreen', 'DarkTurquoise', 'DarkViolet',\n    'DeepPink', 'DeepSkyBlue', 'DodgerBlue', 'FireBrick', 'FloralWhite',\n    'ForestGreen', 'Fuchsia', 'Gainsboro', 'GhostWhite', 'Gold', 'GoldenRod',\n    'Salmon', 'Tan', 'HoneyDew', 'HotPink', 'IndianRed', 'Ivory', 'Khaki',\n    'Lavender', 'LavenderBlush', 'LawnGreen', 'LemonChiffon', 'LightBlue',\n    'LightCoral', 'LightCyan', 'LightGoldenRodYellow', 'LightGray', 'LightGrey',\n    'LightGreen', 'LightPink', 'LightSalmon', 'LightSeaGreen', 'LightSkyBlue',\n    'LightSlateGray', 'LightSlateGrey', 'LightSteelBlue', 'LightYellow', 'Lime',\n    'LimeGreen', 'Linen', 'Magenta', 'MediumAquaMarine', 'MediumOrchid',\n    'MediumPurple', 'MediumSeaGreen', 'MediumSlateBlue', 'MediumSpringGreen',\n    'MediumTurquoise', 'MediumVioletRed', 'MintCream', 'MistyRose', 'Moccasin',\n    'NavajoWhite', 'OldLace', 'Olive', 'OliveDrab', 'Orange', 'OrangeRed',\n    'Orchid', 'PaleGoldenRod', 'PaleGreen', 'PaleTurquoise', 'PaleVioletRed',\n    'PapayaWhip', 'PeachPuff', 'Peru', 'Pink', 'Plum', 'PowderBlue', 'Purple',\n    'Red', 'RosyBrown', 'RoyalBlue', 'SaddleBrown', 'Green', 'SandyBrown',\n    'SeaGreen', 'SeaShell', 'Sienna', 'Silver', 'SkyBlue', 'SlateBlue',\n    'SlateGray', 'SlateGrey', 'Snow', 'SpringGreen', 'SteelBlue', 'GreenYellow',\n    'Teal', 'Thistle', 'Tomato', 'Turquoise', 'Violet', 'Wheat', 'White',\n    'WhiteSmoke', 'Yellow', 'YellowGreen'\n]\n\nNUM_COLORS = len(STANDARD_COLORS)\n\ntry:\n  FONT = ImageFont.truetype('arial.ttf', 24)\nexcept IOError:\n  FONT = ImageFont.load_default()\n\ndef _draw_single_box(image, xmin, ymin, xmax, ymax, display_str, font, color='black', thickness=4):\n  draw = ImageDraw.Draw(image)\n  (left, right, top, bottom) = (xmin, xmax, ymin, ymax)\n  draw.line([(left, top), (left, bottom), (right, bottom),\n             (right, top), (left, top)], width=thickness, fill=color)\n  text_bottom = bottom\n  # Reverse list and print from bottom to top.\n  text_width, text_height = font.getsize(display_str)\n  margin = np.ceil(0.05 * text_height)\n  draw.rectangle(\n      [(left, text_bottom - text_height - 2 * margin), (left + text_width,\n                                                        text_bottom)],\n      fill=color)\n  draw.text(\n      (left + margin, text_bottom - text_height - margin),\n      display_str,\n      fill='black',\n      font=font)\n\n  return image\n\ndef draw_bounding_boxes(image, gt_boxes, im_info):\n  num_boxes = gt_boxes.shape[0]\n  gt_boxes_new = gt_boxes.copy()\n  gt_boxes_new[:,:4] = np.round(gt_boxes_new[:,:4].copy() / im_info[2])\n  disp_image = Image.fromarray(np.uint8(image[0]))\n\n  for i in range(num_boxes):\n    this_class = int(gt_boxes_new[i, 4])\n    disp_image = _draw_single_box(disp_image, \n                                gt_boxes_new[i, 0],\n                                gt_boxes_new[i, 1],\n                                gt_boxes_new[i, 2],\n                                gt_boxes_new[i, 3],\n                                'N%02d-C%02d' % (i, this_class),\n                                FONT,\n                                color=STANDARD_COLORS[this_class % NUM_COLORS])\n\n  image[0, :] = np.array(disp_image)\n  return image\n"
  }
]