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.
"""

M
minqiyang 已提交
23 24
import six

25 26 27
from .. import core
from ..framework import Program, Variable

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

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,
}

41
DEBUG = False
42 43


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

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

52 53 54 55
    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 已提交
56

57
    Examples:
M
minqiyang 已提交
58

59 60 61 62 63
        >>> 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)
64

65
    """
66

67 68 69 70 71 72 73
    # 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.")
74

75 76
    # Get the var_name list of first block and calculate
    total_memory = 0.0
M
minqiyang 已提交
77
    for var in six.itervalues(program.global_block().vars):
78 79 80 81 82 83 84 85
        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 已提交
86
            print("%s memory usage: %d" % (var.name, var_memory))
87 88
        total_memory += var_memory
    if DEBUG:
M
minqiyang 已提交
89
        print("total memory usage: %.2f" % (total_memory))
90

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

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

104
    return min_total_memory, max_total_memory, unit_str