utils.py 5.1 KB
Newer Older
C
chenjian 已提交
1
# Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved.
C
chenjian 已提交
2
#
C
chenjian 已提交
3 4 5
# 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
C
chenjian 已提交
6
#
C
chenjian 已提交
7
#     http://www.apache.org/licenses/LICENSE-2.0
C
chenjian 已提交
8
#
C
chenjian 已提交
9 10 11 12 13 14 15 16 17 18 19
# 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.

from typing import Any
from warnings import warn
import functools
from contextlib import ContextDecorator

C
chenjian 已提交
20 21 22
from paddle.fluid.core import (_RecordEvent, TracerEventType)
import paddle.fluid.core as core

C
chenjian 已提交
23 24 25 26 27 28 29 30 31 32 33 34 35
_AllowedEventTypeList = [
    TracerEventType.Dataloader, TracerEventType.ProfileStep,
    TracerEventType.UserDefined, TracerEventType.Forward,
    TracerEventType.Backward, TracerEventType.Optimization,
    TracerEventType.PythonOp, TracerEventType.PythonUserDefined
]


class RecordEvent(ContextDecorator):
    r"""
    Interface for recording a time range.

    Parameters:
C
chenjian 已提交
36
        name(str): Name of the record event
C
chenjian 已提交
37 38 39

    Examples:
        .. code-block:: python
C
chenjian 已提交
40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57

            import paddle
            import paddle.profiler as profiler
            # method1: using context manager
            with profiler.RecordEvent("record_add"):
                data1 = paddle.randn(shape=[3])
                data2 = paddle.randn(shape=[3])
                result = data1 + data2
            # method2: call begin() and end()
            record_event = profiler.RecordEvent("record_add")
            record_event.begin()
            data1 = paddle.randn(shape=[3])
            data2 = paddle.randn(shape=[3])
            result = data1 + data2
            record_event.end()

    Note:
        RecordEvent will take effect only when profiler is on and at the state of RECORD.
C
chenjian 已提交
58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74
    """

    def __init__(self,
                 name: str,
                 event_type: TracerEventType=TracerEventType.UserDefined):
        self.name = name
        self.event_type = event_type
        self.event = None

    def __enter__(self):
        self.begin()
        return self

    def __exit__(self, exc_type: Any, exc_value: Any, traceback: Any):
        self.end()

    def begin(self):
C
chenjian 已提交
75 76 77 78 79 80 81 82 83 84 85 86 87 88
        r"""
        Record the time of begining.

        .. code-block:: python

            import paddle
            import paddle.profiler as profiler
            record_event = profiler.RecordEvent("record_sub")
            record_event.begin()
            data1 = paddle.randn(shape=[3])
            data2 = paddle.randn(shape=[3])
            result = data1 - data2
            record_event.end()
        """
C
chenjian 已提交
89 90 91 92 93 94 95 96 97 98
        if self.event_type not in _AllowedEventTypeList:
            warn("Only TracerEvent Type in [{}, {}, {}, {}, {}, {},{}]\
                  can be recorded.".format(*_AllowedEventTypeList))
            self.event = None
        else:
            if self.event_type == TracerEventType.UserDefined:
                self.event_type == TracerEventType.PythonUserDefined
            self.event = _RecordEvent(self.name, self.event_type)

    def end(self):
C
chenjian 已提交
99 100 101 102 103 104 105 106 107 108 109 110 111 112
        r'''
        Record the time of ending.

        .. code-block:: python

            import paddle
            import paddle.profiler as profiler
            record_event = profiler.RecordEvent("record_mul")
            record_event.begin()
            data1 = paddle.randn(shape=[3])
            data2 = paddle.randn(shape=[3])
            result = data1 * data2
            record_event.end()
        '''
C
chenjian 已提交
113 114 115 116
        if self.event:
            self.event.end()


C
chenjian 已提交
117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143
def load_profiler_result(filename: str):
    r"""
    Load dumped profiler data back to memory.

    Parameters:
        filename(str): Name of the exported protobuf file of profiler data.

    Returns:
        ProfilerResult object.

    Examples:
        .. code-block:: python

            # required: gpu
            import paddle.profiler as profiler
            with profiler.Profiler(
                    targets=[profiler.ProfilerTarget.CPU, profiler.ProfilerTarget.GPU],
                    scheduler = (3, 10)) as p:
                for iter in range(10):
                    #train()
                    p.step()
            p.export('test_export_protobuf.pb', format='pb')
            profiler_result = profiler.load_profiler_result('test_export_protobuf.pb')
    """
    return core.load_profiler_result(filename)


C
chenjian 已提交
144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160
def wrap_optimizers():
    def optimizer_warpper(func):
        @functools.wraps(func)
        def warpper(*args, **kwargs):
            with RecordEvent(
                    'Optimization Step',
                    event_type=TracerEventType.Optimization):
                return func(*args, **kwargs)

        return warpper

    import paddle.optimizer as optimizer
    for classname in optimizer.__all__:
        if classname != 'Optimizer':
            classobject = getattr(optimizer, classname)
            if getattr(classobject, 'step', None) != None:
                classobject.step = optimizer_warpper(classobject.step)