def conv_output_length(input_size, conv_size, stride, pad):
    """
    calculates the output size along a single axis for a conv operation
    """
    if input_size is None:
        return None
    without_stride = input_size + 2 * pad - conv_size + 1
    # equivalent to np.ceil(without_stride / stride)
    output_size = (without_stride + stride - 1) // stride
    return output_size