Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Running profiler multiple times increases number of operations, includes fix #6

Open
majdiabdulsamad opened this issue Oct 5, 2021 · 0 comments

Comments

@majdiabdulsamad
Copy link

majdiabdulsamad commented Oct 5, 2021

Hello,

First of all, thank you for the profiling tools, it's been very helpful.

As the title mentions, the output for the number of operations increased every time I ran the profile function, because I'm using this in a notebook and I'm running it multiple times in debugging. I found out that it's because the hooks are being registered and added every time. I managed to fix this by creating a list of handles, and appending the handles for all of the hooks. When the profile function is done counting, I simply iterate over the handles and remove them. I don't know if this is efficient or scales up well for larger models, but for my specific case I did not notice an increase (very small model).

Edit: Another solution would be to check if hooks already exist (i.e. check handle list is not None) and then skipping the count which is more efficient, but I can't figure out how to do that right now.

Here's the code I used:

def profile(model, input_size, custom_ops = {}):

    model.eval()
    #create list of handles to keep track of the hooks to remove them later
    handle = []
    def add_hooks(m):
        if len(list(m.children())) > 0: return
        m.register_buffer('total_ops', torch.zeros(1))
        m.register_buffer('total_params', torch.zeros(1))
        
        for p in m.parameters():
            m.total_params += torch.Tensor([p.numel()])
        
        if isinstance(m, torch.nn.Conv2d):
            handle.append(m.register_forward_hook(count_conv2d))
        elif isinstance(m, torch.nn.BatchNorm2d):
            handle.append(m.register_forward_hook(count_bn2d))
        elif isinstance(m, torch.nn.ReLU):
            handle.append(m.register_forward_hook(count_relu))
        elif isinstance(m, (torch.nn.MaxPool1d, torch.nn.MaxPool2d, torch.nn.MaxPool3d)):
            handle.append(m.register_forward_hook(count_maxpool))
        elif isinstance(m, (torch.nn.AvgPool1d, torch.nn.AvgPool2d, torch.nn.AvgPool3d)):
            handle.append(m.register_forward_hook(count_avgpool))
        elif isinstance(m, torch.nn.Linear):
            handle.append(m.register_forward_hook(count_linear))
        elif isinstance(m, (torch.nn.Dropout, torch.nn.Dropout2d, torch.nn.Dropout3d)):
            pass
        else:
            print("Not implemented for ", m)
    model.apply(add_hooks)
    x = torch.zeros(input_size)
    model(x)
    # if(isinstace(m)):
    total_ops = 0
    total_params = 0
    for m in model.modules():
        if len(list(m.children())) > 0: continue
        total_ops += m.total_ops
        total_params += m.total_params
    total_ops = total_ops
    total_params = total_params
    #Delete the handles to maintain same number of ops
    for i in handle:
        i.remove()
    return total_ops, total_params
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant