memory_usage_calc.py 3.3 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
#   Copyright (c) 2018 PaddlePaddle Authors. All Rights Reserve.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""
This module privides a memory usage calculate function for user.
The purpose of this API is to allow users to estimate memory usage of
M
minqiyang 已提交
17 18
a program under a special batch size, then user can set appropriate
batch size to fully utilize a GPU.
19 20 21 22

This API is still under active development and may change drastically.
"""

23 24
from __future__ import print_function

M
minqiyang 已提交
25 26
import six

27 28 29
from .. import core
from ..framework import Program, Variable

30
__all__ = ['memory_usage']
31 32 33 34 35 36 37 38 39 40 41 42

dtype_to_size = {
    core.VarDesc.VarType.FP16: 2,
    core.VarDesc.VarType.FP32: 4,
    core.VarDesc.VarType.FP64: 8,
    core.VarDesc.VarType.INT16: 2,
    core.VarDesc.VarType.INT32: 4,
    core.VarDesc.VarType.INT64: 8,
    core.VarDesc.VarType.BOOL: 1,
    core.VarDesc.VarType.UINT8: 1,
}

43
DEBUG = False
44 45


46 47 48
def memory_usage(program, batch_size):
    """
    Get the estimate memory usage of program with input batch size.
49

50 51
    Args:
        program(Program): The current Program.
M
minqiyang 已提交
52 53
        batch_size(int): The current input data batch_size.

54 55 56 57
    Returns:
        min_total_memory(float): the estimate memory usage lower bound.
        max_total_memory(float): the estimate memory usage upper bound.
        unit_str(string): the unit of estimate usage result.
M
minqiyang 已提交
58

59
    Examples:
M
minqiyang 已提交
60

61 62 63 64 65
        >>> import paddle.fluid as fluid
        >>> lower_usage, upper_usage, unit = fluid.contrib.memory_usage(
                fluid.default_main_program(), batch_size=10)
        >>> print "memory usage is about %.3f - %.3f %s" % \
                (lower_usage, upper_usage, unit)
66

67
    """
68

69 70 71 72 73 74 75
    # Parameters check
    if not isinstance(program, Program):
        raise TypeError(
            "Calculating Memory Usage requires Program as its Parameter."
            "But you passed in %s" % (type(prgram)))
    if batch_size <= 0:
        raise ValueError("The batch size need to be positive.")
76

77 78
    # Get the var_name list of first block and calculate
    total_memory = 0.0
M
minqiyang 已提交
79
    for var in six.itervalues(program.global_block().vars):
80 81 82 83 84 85 86 87
        data_count = 1
        for x in var.shape:
            if x == -1:
                data_count *= batch_size
            else:
                data_count *= x
        var_memory = data_count * dtype_to_size[var.dtype]
        if DEBUG:
M
minqiyang 已提交
88
            print("%s memory usage: %d" % (var.name, var_memory))
89 90
        total_memory += var_memory
    if DEBUG:
M
minqiyang 已提交
91
        print("total memory usage: %.2f" % (total_memory))
92

93 94 95 96 97
    # Convert appropriate unit
    unit_str = "B"
    if total_memory > 1024:
        total_memory /= 1024
        unit_str = "KB"
98 99
        if total_memory > 1024:
            total_memory /= 1024
100
            unit_str = "MB"
101

102 103 104
    # Append extra memory consumption (5% - 10%)
    min_total_memory = total_memory * 1.05
    max_total_memory = total_memory * 1.1
105

106
    return min_total_memory, max_total_memory, unit_str