Returns a relaxed (possibly reshaped/upcast-ed) version of value,
        to be loaded to the given variable.

        Args:
            value (ndarray): an numpy array to be loaded to var
            var (tf.Variable):

        Returns:
            ndarray: a possibly reshaped or casted version of value

def relaxed_value_for_var(value, var):
        """
        Returns a relaxed (possibly reshaped/upcast-ed) version of value,
        to be loaded to the given variable.

        Args:
            value (ndarray): an numpy array to be loaded to var
            var (tf.Variable):

        Returns:
            ndarray: a possibly reshaped or casted version of value
        """
        assert isinstance(var, tf.Variable)
        name = var.op.name

        # check incompatible shape
        varshape = tuple(var.get_shape().as_list())
        if varshape != value.shape:
            # TODO only allow reshape when shape different by empty axis
            if np.prod(varshape) != np.prod(value.shape):
                raise ValueError(
                    "Trying to load a tensor of shape {} into the variable '{}' whose shape is {}.".format(
                        value.shape, name, varshape))
            logger.warn("The tensor is reshaped from {} to {} when assigned to '{}'".format(
                value.shape, varshape, name))
            value = value.reshape(varshape)

        # fix some common type incompatibility problems, but not all
        def upcast(vartype, valtype):
            # vartype: a tf dtype
            # valtype: a numpy dtype
            # allow up-casting
            if vartype == tf.float64 and valtype == np.float32:
                return np.float64
            if vartype in [tf.int64, tf.int32] and valtype in [np.int32, np.int16, np.int8]:
                return np.int64 if vartype == tf.int64 else np.int32
            return None

        if hasattr(value, 'dtype'):
            vartype = var.dtype.as_numpy_dtype
            if vartype != value.dtype:
                msg = "Variable {} has dtype {} but was given a value of dtype {}.".format(name, vartype, value.dtype)
                newtype = upcast(var.dtype.base_dtype, value.dtype)
                if newtype is not None:
                    value = newtype(value)
                    logger.warn(msg + " Load it after casting!")
                else:
                    assert vartype == value.dtype, msg
        return value