# Path: detectron/utils/io.py
# def save_object(obj, file_name, pickle_format=2):
#     """Save a Python object by pickling it.
# 
# Unless specifically overridden, we want to save it in Pickle format=2 since this
# will allow other Python2 executables to load the resulting Pickle. When we want
# to completely remove Python2 backward-compatibility, we can bump it up to 3. We
# should never use pickle.HIGHEST_PROTOCOL as far as possible if the resulting
# file is manifested or used, external to the system.
#     """
#     file_name = os.path.abspath(file_name)
#     # Avoid filesystem race conditions (particularly on network filesystems)
#     # by saving to a random tmp file on the same filesystem, and then
#     # atomically rename to the target filename.
#     tmp_file_name = file_name + ".tmp." + uuid4().hex
#     try:
#         with open(tmp_file_name, 'wb') as f:
#             pickle.dump(obj, f, pickle_format)
#             f.flush()  # make sure it's written to disk
#             os.fsync(f.fileno())
#         os.rename(tmp_file_name, file_name)
#     finally:
#         # Clean up the temp file on failure. Rather than using os.path.exists(),
#         # which can be unreliable on network filesystems, attempt to delete and
#         # ignore os errors.
#         try:
#             os.remove(tmp_file_name)
#         except EnvironmentError as e:  # parent class of IOError, OSError
#             if getattr(e, 'errno', None) != errno.ENOENT:  # We expect ENOENT
#                 logger.info("Could not delete temp file %r",
#                     tmp_file_name, exc_info=True)
#                 # pass through since we don't want the job to crash


import argparse
import numpy as np
import os
import sys
from caffe.proto import caffe_pb2
from caffe2.proto import caffe2_pb2
from caffe2.python import caffe_translator
from caffe2.python import utils
from google.protobuf import text_format
from detectron.utils.io import save_object

    if len(sys.argv) == 1:
        parser.print_help()
        sys.exit(1)

    args = parser.parse_args()
    return args


def normalize_resnet_name(name):
    if name.find('res') == 0 and name.find('res_') == -1:
        # E.g.,
        #  res4b11_branch2c -> res4_11_branch2c
        #  res2a_branch1 -> res2_0_branch1
        chunk = name[len('res'):name.find('_')]
        name = (
            'res' + chunk[0] + '_' + str(
                int(chunk[2:]) if len(chunk) > 2  # e.g., "b1" -> 1
                else ord(chunk[1]) - ord('a')
            ) +  # e.g., "a" -> 0
            name[name.find('_'):]
        )
    return name


def pickle_weights(out_file_name, weights):
    blobs = {
        normalize_resnet_name(blob.name): utils.Caffe2TensorToNumpyArray(blob)
        for blob in weights.protos
    }

# Path: detectron/utils/io.py
# def save_object(obj, file_name, pickle_format=2):
#     """Save a Python object by pickling it.
# 
# Unless specifically overridden, we want to save it in Pickle format=2 since this
# will allow other Python2 executables to load the resulting Pickle. When we want
# to completely remove Python2 backward-compatibility, we can bump it up to 3. We
# should never use pickle.HIGHEST_PROTOCOL as far as possible if the resulting
# file is manifested or used, external to the system.
#     """
#     file_name = os.path.abspath(file_name)
#     # Avoid filesystem race conditions (particularly on network filesystems)
#     # by saving to a random tmp file on the same filesystem, and then
#     # atomically rename to the target filename.
#     tmp_file_name = file_name + ".tmp." + uuid4().hex
#     try:
#         with open(tmp_file_name, 'wb') as f:
#             pickle.dump(obj, f, pickle_format)
#             f.flush()  # make sure it's written to disk
#             os.fsync(f.fileno())
#         os.rename(tmp_file_name, file_name)
#     finally:
#         # Clean up the temp file on failure. Rather than using os.path.exists(),
#         # which can be unreliable on network filesystems, attempt to delete and
#         # ignore os errors.
#         try:
#             os.remove(tmp_file_name)
#         except EnvironmentError as e:  # parent class of IOError, OSError
#             if getattr(e, 'errno', None) != errno.ENOENT:  # We expect ENOENT
#                 logger.info("Could not delete temp file %r",
#                     tmp_file_name, exc_info=True)
#                 # pass through since we don't want the job to crash


# Path: tools/pickle_caffe_blobs.py
import argparse
import numpy as np
import os
import sys
from caffe.proto import caffe_pb2
from caffe2.proto import caffe2_pb2
from caffe2.python import caffe_translator
from caffe2.python import utils
from google.protobuf import text_format
from detectron.utils.io import save_object


    if len(sys.argv) == 1:
        parser.print_help()
        sys.exit(1)

    args = parser.parse_args()
    return args


def normalize_resnet_name(name):
    if name.find('res') == 0 and name.find('res_') == -1:
        # E.g.,
        #  res4b11_branch2c -> res4_11_branch2c
        #  res2a_branch1 -> res2_0_branch1
        chunk = name[len('res'):name.find('_')]
        name = (
            'res' + chunk[0] + '_' + str(
                int(chunk[2:]) if len(chunk) > 2  # e.g., "b1" -> 1
                else ord(chunk[1]) - ord('a')
            ) +  # e.g., "a" -> 0
            name[name.find('_'):]
        )
    return name


def pickle_weights(out_file_name, weights):
    blobs = {
        normalize_resnet_name(blob.name): utils.Caffe2TensorToNumpyArray(blob)
        for blob in weights.protos
    }

    save_object(blobs, out_file_name)