





'''simple docstring'''






import json
import os
from datetime import date
from pathlib import Path

from tabulate import DataRow, TableFormat, tabulate


__UpperCamelCase					    =	TableFormat(
    lineabove=None,
    linebelowheader=None,
    linebetweenrows=None,
    linebelow=None,
    headerrow=DataRow("", "|", "|"),
    datarow=DataRow("", "|", "|"),
    padding=1,
    with_header_hide=None,
)


__UpperCamelCase					    =	[]
__UpperCamelCase					    =	[]

__UpperCamelCase					    =	{"type": "section", "text": {"type": "plain_text", "text": "No failed tests! 🤗", "emoji": True}}

__UpperCamelCase					    =	[
    {
        "type": "header",
        "text": {
            "type": "plain_text",
            "text": f"""🤗 Accelerate nightly {os.environ.get('TEST_TYPE', '')} test results""",
            "emoji": True,
        },
    }
]

__UpperCamelCase					    =	0
for log in Path().glob("*.log"):
	__UpperCamelCase					    =	0
	with open(log, "r") as f:
		for line in f:
			__UpperCamelCase					    =	json.loads(line)
			if line.get("nodeid", "") != "":
				__UpperCamelCase					    =	line["nodeid"]
				if line.get("duration", None) is not None:
					__UpperCamelCase					    =	f"""{line['duration']:.4f}"""
					if line.get("outcome", "") == "failed":
						section_num_failed += 1
						failed.append([test, duration, log.name.split("_")[0]])
						total_num_failed += 1
	group_info.append([str(log), section_num_failed, failed])
	__UpperCamelCase					    =	[]
	log.unlink()

__UpperCamelCase					    =	""
__UpperCamelCase					    =	[]
if total_num_failed > 0:
	for name, num_failed, failed_tests in group_info:
		if num_failed > 0:
			if num_failed == 1:
				message += f"*{name[1:]}: {num_failed} failed test*\n"
			else:
				message += f"*{name[1:]}: {num_failed} failed tests*\n"
			__UpperCamelCase					    =	[]
			__UpperCamelCase					    =	{}
			for test in failed_tests:
				__UpperCamelCase					    =	test[0].split("::")
				__UpperCamelCase					    =	data[0].split("/")[-1]
				if data[0] not in filesafailed:
					__UpperCamelCase					    =	[data[1:]]
				else:
					filesafailed[data[0]] += [data[1:]]
				failed_table.append(data)

			__UpperCamelCase					    =	[test[0] for test in failed_table]
			__UpperCamelCase					    =	list(set(files))
			# Count number of instances in failed_tests
			__UpperCamelCase					    =	[]
			for file in individual_files:
				table.append([file, len(filesafailed[file])])

			__UpperCamelCase					    =	tabulate(
			    table,
			    headers=["Test Location", "Num Failed"],
			    tablefmt=hf_table_format,
			    stralign="right",
			)
			message += f"\n```\n{failed_table}\n```"
			all_filesafailed.append(filesafailed)
	if len(message) > 3000:
		__UpperCamelCase					    =	"Too many failed tests, please see the full report in the Action results."
		__UpperCamelCase					    =	len(err) + 10
		__UpperCamelCase					    =	message[: 3000 - offset] + f"""\n...\n```\n{err}"""
	print(f"""### {message}""")
else:
	__UpperCamelCase					    =	"No failed tests! 🤗"
	print(f"""## {message}""")
	payload.append(no_error_payload)

if os.environ.get("TEST_TYPE", "") != "":
	from slack_sdk import WebClient

	__UpperCamelCase					    =	WebClient(token=os.environ["SLACK_API_TOKEN"])
	if message != "No failed tests! 🤗":
		__UpperCamelCase					    =	{
		    "type": "section",
		    "text": {
		        "type": "mrkdwn",
		        "text": message,
		    },
		}
		payload.append(md_report)
		__UpperCamelCase					    =	{
		    "type": "section",
		    "text": {
		        "type": "mrkdwn",
		        "text": "*For more details:*",
		    },
		    "accessory": {
		        "type": "button",
		        "text": {
		            "type": "plain_text",
		            "text": "Check Action results",
		            "emoji": True,
		        },
		        "url": f"""https://github.com/{os.environ['GITHUB_REPOSITORY']}/actions/runs/{os.environ['GITHUB_RUN_ID']}""",
		    },
		}
		payload.append(action_button)
		__UpperCamelCase					    =	{
		    "type": "context",
		    "elements": [
		        {
		            "type": "plain_text",
		            "text": f"""Nightly {os.environ.get('TEST_TYPE')} test results for {date.today()}""",
		        }
		    ],
		}
		payload.append(date_report)
	__UpperCamelCase					    =	client.chat_postMessage(channel="#accelerate-ci-daily", text=message, blocks=payload)
	__UpperCamelCase					    =	response.data["ts"]
	for failed_file in all_filesafailed:
		for test_location, test_failures in failed_file.items():
			# Keep only the first instance of the test name
			__UpperCamelCase					    =	""
			for i, row in enumerate(test_failures):
				if row[0] != test_class:
					__UpperCamelCase					    =	row[0]
				else:
					__UpperCamelCase					    =	""

			__UpperCamelCase					    =	{
			    "type": "section",
			    "text": {
			        "type": "mrkdwn",
			        "text": f"""Test location: {test_location}\n```\n{tabulate(test_failures, headers=['Class', 'Test'], tablefmt=hf_table_format, stralign='right')}\n```""",
			    },
			}

			client.chat_postMessage(
			    channel="#accelerate-ci-daily",
			    thread_ts=ts,
			    blocks=[payload],
			)









'''simple docstring'''






import inspect
import unittest

import torch
import torch.nn as nn

from accelerate.hooks import (
    AlignDevicesHook,
    ModelHook,
    SequentialHook,
    add_hook_to_module,
    attach_align_device_hook,
    remove_hook_from_module,
    remove_hook_from_submodules,
)
from accelerate.test_utils import require_multi_gpu




class  _A (					nn.Module		):

		def __init__(   self					:   List[str]			)					->    Optional[Any]:


					"""simple docstring"""

					super().__init__()
					__snake_case					:      List[Any]							      =     nn.Linear(3  ,      4			)
					__snake_case					:      str							      =     nn.BatchNormad(4			)
					__snake_case					:      Optional[Any]							      =     nn.Linear(4  ,      5			)

		def 	lowercase__     (   self					:   str  ,      __magic_name__					:   Dict			)					->    List[str]:


					"""simple docstring"""

					return self.lineara(self.batchnorm(self.lineara(__magic_name__			)			)			)





class  _A (					__lowercase		):

		def 	lowercase__     (   self					:   List[str]  ,      __magic_name__					:   Tuple  ,      *__magic_name__					:   Dict  ,      **__magic_name__					:   Optional[Any]			)					->    Tuple:


					"""simple docstring"""

					return (args[0] + 1,) + args[1:], kwargs





class  _A (					__lowercase		):

		def 	lowercase__     (   self					:   str  ,      __magic_name__					:   Union[str, Any]  ,      __magic_name__					:   Tuple			)					->    Union[str, Any]:


					"""simple docstring"""

					return output + 1





class  _A (					unittest.TestCase		):

		def 	lowercase__     (   self					:   Dict			)					->    Any:


					"""simple docstring"""

					__snake_case					:      int							      =     ModelForTest()
					__snake_case					:      Tuple							      =     ModelHook()

					add_hook_to_module(__magic_name__  ,      __magic_name__			)
					self.assertEqual(test_model._hf_hook  ,      __magic_name__			)
					self.assertTrue(hasattr(__magic_name__  ,      """_old_forward"""			)			)

					# Check adding the hook did not change the name or the signature
					self.assertEqual(test_model.forward.__name__  ,      """forward"""			)
					self.assertListEqual(list(inspect.signature(test_model.forward			).parameters			)  ,      ["""x"""]			)

					remove_hook_from_module(__magic_name__			)
					self.assertFalse(hasattr(__magic_name__  ,      """_hf_hook"""			)			)
					self.assertFalse(hasattr(__magic_name__  ,      """_old_forward"""			)			)

		def 	lowercase__     (   self					:   Tuple			)					->    List[str]:


					"""simple docstring"""

					__snake_case					:      List[Any]							      =     ModelForTest()
					__snake_case					:      Optional[int]							      =     ModelHook()

					add_hook_to_module(__magic_name__  ,      __magic_name__			)
					add_hook_to_module(__magic_name__  ,      __magic_name__  ,      append=__magic_name__			)

					self.assertEqual(isinstance(test_model._hf_hook  ,      __magic_name__			)  ,      __magic_name__			)
					self.assertEqual(len(test_model._hf_hook.hooks			)  ,      2			)
					self.assertTrue(hasattr(__magic_name__  ,      """_old_forward"""			)			)

					# Check adding the hook did not change the name or the signature
					self.assertEqual(test_model.forward.__name__  ,      """forward"""			)
					self.assertListEqual(list(inspect.signature(test_model.forward			).parameters			)  ,      ["""x"""]			)

					remove_hook_from_module(__magic_name__			)
					self.assertFalse(hasattr(__magic_name__  ,      """_hf_hook"""			)			)
					self.assertFalse(hasattr(__magic_name__  ,      """_old_forward"""			)			)

		def 	lowercase__     (   self					:   str			)					->    Union[str, Any]:


					"""simple docstring"""

					__snake_case					:      List[Any]							      =     ModelForTest()
					__snake_case					:      Any							      =     torch.randn(2  ,      3			)
					__snake_case					:      str							      =     test_model(x + 1			)
					__snake_case					:      int							      =     test_model(x + 2			)

					__snake_case					:      Union[str, Any]							      =     PreForwardHook()
					add_hook_to_module(__magic_name__  ,      __magic_name__			)
					__snake_case					:      int							      =     test_model(__magic_name__			)
					self.assertTrue(torch.allclose(__magic_name__  ,      __magic_name__  ,      atol=1E-5			)			)

					# Attaching a hook to a model when it already has one replaces, does not chain
					__snake_case					:      Optional[int]							      =     PreForwardHook()
					add_hook_to_module(__magic_name__  ,      __magic_name__			)
					__snake_case					:      List[Any]							      =     test_model(__magic_name__			)
					self.assertTrue(torch.allclose(__magic_name__  ,      __magic_name__  ,      atol=1E-5			)			)

					# You need to use the sequential hook to chain two or more hooks
					__snake_case					:      Optional[int]							      =     SequentialHook(PreForwardHook()  ,      PreForwardHook()			)
					add_hook_to_module(__magic_name__  ,      __magic_name__			)

					__snake_case					:      List[str]							      =     test_model(__magic_name__			)
					assert torch.allclose(__magic_name__  ,      __magic_name__  ,      atol=1E-5			)

		def 	lowercase__     (   self					:   Union[str, Any]			)					->    List[str]:


					"""simple docstring"""

					__snake_case					:      Union[str, Any]							      =     ModelForTest()
					__snake_case					:      str							      =     torch.randn(2  ,      3			)
					__snake_case					:      Any							      =     test_model(__magic_name__			)

					__snake_case					:      Any							      =     PostForwardHook()
					add_hook_to_module(__magic_name__  ,      __magic_name__			)
					__snake_case					:      Any							      =     test_model(__magic_name__			)
					self.assertTrue(torch.allclose(__magic_name__  ,      output + 1  ,      atol=1E-5			)			)

					# Attaching a hook to a model when it already has one replaces, does not chain
					__snake_case					:      Any							      =     PostForwardHook()
					add_hook_to_module(__magic_name__  ,      __magic_name__			)
					__snake_case					:      Dict							      =     test_model(__magic_name__			)
					self.assertTrue(torch.allclose(__magic_name__  ,      output + 1  ,      atol=1E-5			)			)

					# You need to use the sequential hook to chain two or more hooks
					__snake_case					:      str							      =     SequentialHook(PostForwardHook()  ,      PostForwardHook()			)
					add_hook_to_module(__magic_name__  ,      __magic_name__			)

					__snake_case					:      int							      =     test_model(__magic_name__			)
					assert torch.allclose(__magic_name__  ,      output + 2  ,      atol=1E-5			)

		def 	lowercase__     (   self					:   str			)					->    int:


					"""simple docstring"""

					__snake_case					:      Union[str, Any]							      =     ModelForTest()
					__snake_case					:      int							      =     torch.randn(2  ,      3			)
					__snake_case					:      Any							      =     test_model(__magic_name__			)

					__snake_case					:      Dict							      =     PostForwardHook()
					add_hook_to_module(__magic_name__  ,      __magic_name__			)
					__snake_case					:      List[Any]							      =     test_model(__magic_name__			)
					self.assertTrue(torch.allclose(__magic_name__  ,      output + 1			)			)
					self.assertTrue(outputa.requires_grad			)

					__snake_case					:      Dict							      =     True
					__snake_case					:      int							      =     test_model(__magic_name__			)
					self.assertFalse(outputa.requires_grad			)

		@require_multi_gpu
		def 	lowercase__     (   self					:   Tuple			)					->    List[Any]:


					"""simple docstring"""

					__snake_case					:      Tuple							      =     ModelForTest()
					# Everything is on CPU
					self.assertEqual(model.lineara.weight.device  ,      torch.device("""cpu"""			)			)
					self.assertEqual(model.batchnorm.weight.device  ,      torch.device("""cpu"""			)			)
					self.assertEqual(model.lineara.weight.device  ,      torch.device("""cpu"""			)			)

					# This will move each submodule on different devices
					add_hook_to_module(model.lineara  ,      AlignDevicesHook(execution_device=0			)			)
					add_hook_to_module(model.batchnorm  ,      AlignDevicesHook(execution_device=0			)			)
					add_hook_to_module(model.lineara  ,      AlignDevicesHook(execution_device=1			)			)

					self.assertEqual(model.lineara.weight.device  ,      torch.device(0			)			)
					self.assertEqual(model.batchnorm.weight.device  ,      torch.device(0			)			)
					self.assertEqual(model.batchnorm.running_mean.device  ,      torch.device(0			)			)
					self.assertEqual(model.lineara.weight.device  ,      torch.device(1			)			)

					# We can still make a forward pass. The input does not need to be on any particular device
					__snake_case					:      Tuple							      =     torch.randn(2  ,      3			)
					__snake_case					:      Union[str, Any]							      =     model(__magic_name__			)
					self.assertEqual(output.device  ,      torch.device(1			)			)

					# We can add a general hook to put back output on same device as input.
					add_hook_to_module(__magic_name__  ,      AlignDevicesHook(io_same_device=__magic_name__			)			)
					__snake_case					:      Tuple							      =     torch.randn(2  ,      3			).to(0			)
					__snake_case					:      Any							      =     model(__magic_name__			)
					self.assertEqual(output.device  ,      torch.device(0			)			)

		def 	lowercase__     (   self					:   Union[str, Any]			)					->    str:


					"""simple docstring"""

					__snake_case					:      int							      =     ModelForTest()

					# Everything is on CPU
					self.assertEqual(model.lineara.weight.device  ,      torch.device("""cpu"""			)			)
					self.assertEqual(model.batchnorm.weight.device  ,      torch.device("""cpu"""			)			)
					self.assertEqual(model.lineara.weight.device  ,      torch.device("""cpu"""			)			)

					# This will move each submodule on different devices
					__snake_case					:      List[str]							      =     {"""execution_device""": 0 if torch.cuda.is_available() else """cpu""", """offload""": True}

					add_hook_to_module(model.lineara  ,      AlignDevicesHook(**__magic_name__			)			)
					add_hook_to_module(model.batchnorm  ,      AlignDevicesHook(**__magic_name__			)			)
					add_hook_to_module(model.lineara  ,      AlignDevicesHook(**__magic_name__			)			)

					# Parameters have been offloaded, so on the meta device
					self.assertEqual(model.lineara.weight.device  ,      torch.device("""meta"""			)			)
					self.assertEqual(model.batchnorm.weight.device  ,      torch.device("""meta"""			)			)
					self.assertEqual(model.lineara.weight.device  ,      torch.device("""meta"""			)			)
					# Buffers are not included in the offload by default, so are on the execution device
					__snake_case					:      Any							      =     torch.device(hook_kwargs["""execution_device"""]			)
					self.assertEqual(model.batchnorm.running_mean.device  ,      __magic_name__			)

					__snake_case					:      Dict							      =     torch.randn(2  ,      3			)
					__snake_case					:      Any							      =     model(__magic_name__			)
					self.assertEqual(output.device  ,      __magic_name__			)

					# Removing hooks loads back the weights in the model.
					remove_hook_from_module(model.lineara			)
					remove_hook_from_module(model.batchnorm			)
					remove_hook_from_module(model.lineara			)
					self.assertEqual(model.lineara.weight.device  ,      torch.device("""cpu"""			)			)
					self.assertEqual(model.batchnorm.weight.device  ,      torch.device("""cpu"""			)			)
					self.assertEqual(model.lineara.weight.device  ,      torch.device("""cpu"""			)			)

					# Now test with buffers included in the offload
					__snake_case					:      int							      =     {
					    """execution_device""": 0 if torch.cuda.is_available() else """cpu""",
					    """offload""": True,
					    """offload_buffers""": True,
					}

					add_hook_to_module(model.lineara  ,      AlignDevicesHook(**__magic_name__			)			)
					add_hook_to_module(model.batchnorm  ,      AlignDevicesHook(**__magic_name__			)			)
					add_hook_to_module(model.lineara  ,      AlignDevicesHook(**__magic_name__			)			)

					# Parameters have been offloaded, so on the meta device, buffers included
					self.assertEqual(model.lineara.weight.device  ,      torch.device("""meta"""			)			)
					self.assertEqual(model.batchnorm.weight.device  ,      torch.device("""meta"""			)			)
					self.assertEqual(model.lineara.weight.device  ,      torch.device("""meta"""			)			)
					self.assertEqual(model.batchnorm.running_mean.device  ,      torch.device("""meta"""			)			)

					__snake_case					:      str							      =     torch.randn(2  ,      3			)
					__snake_case					:      str							      =     model(__magic_name__			)
					self.assertEqual(output.device  ,      __magic_name__			)

					# Removing hooks loads back the weights in the model.
					remove_hook_from_module(model.lineara			)
					remove_hook_from_module(model.batchnorm			)
					remove_hook_from_module(model.lineara			)
					self.assertEqual(model.lineara.weight.device  ,      torch.device("""cpu"""			)			)
					self.assertEqual(model.batchnorm.weight.device  ,      torch.device("""cpu"""			)			)
					self.assertEqual(model.lineara.weight.device  ,      torch.device("""cpu"""			)			)

		def 	lowercase__     (   self					:   Dict			)					->    str:


					"""simple docstring"""

					__snake_case					:      Tuple							      =     ModelForTest()

					# Everything is on CPU
					self.assertEqual(model.lineara.weight.device  ,      torch.device("""cpu"""			)			)
					self.assertEqual(model.batchnorm.weight.device  ,      torch.device("""cpu"""			)			)
					self.assertEqual(model.lineara.weight.device  ,      torch.device("""cpu"""			)			)

					# This will move each submodule on different devices
					__snake_case					:      Union[str, Any]							      =     0 if torch.cuda.is_available() else """cpu"""
					attach_align_device_hook(__magic_name__  ,      execution_device=__magic_name__  ,      offload=__magic_name__			)

					# Parameters have been offloaded, so on the meta device
					self.assertEqual(model.lineara.weight.device  ,      torch.device("""meta"""			)			)
					self.assertEqual(model.batchnorm.weight.device  ,      torch.device("""meta"""			)			)
					self.assertEqual(model.lineara.weight.device  ,      torch.device("""meta"""			)			)
					# Buffers are not included in the offload by default, so are on the execution device
					__snake_case					:      Union[str, Any]							      =     torch.device(__magic_name__			)
					self.assertEqual(model.batchnorm.running_mean.device  ,      __magic_name__			)

					__snake_case					:      Optional[int]							      =     torch.randn(2  ,      3			)
					__snake_case					:      Dict							      =     model(__magic_name__			)
					self.assertEqual(output.device  ,      __magic_name__			)

					# Removing hooks loads back the weights in the model.
					remove_hook_from_submodules(__magic_name__			)
					self.assertEqual(model.lineara.weight.device  ,      torch.device("""cpu"""			)			)
					self.assertEqual(model.batchnorm.weight.device  ,      torch.device("""cpu"""			)			)
					self.assertEqual(model.lineara.weight.device  ,      torch.device("""cpu"""			)			)

					# Now test with buffers included in the offload
					attach_align_device_hook(__magic_name__  ,      execution_device=__magic_name__  ,      offload=__magic_name__  ,      offload_buffers=__magic_name__			)

					# Parameters have been offloaded, so on the meta device, buffers included
					self.assertEqual(model.lineara.weight.device  ,      torch.device("""meta"""			)			)
					self.assertEqual(model.batchnorm.weight.device  ,      torch.device("""meta"""			)			)
					self.assertEqual(model.lineara.weight.device  ,      torch.device("""meta"""			)			)
					self.assertEqual(model.batchnorm.running_mean.device  ,      torch.device("""meta"""			)			)

					__snake_case					:      Dict							      =     torch.randn(2  ,      3			)
					__snake_case					:      Optional[int]							      =     model(__magic_name__			)
					self.assertEqual(output.device  ,      __magic_name__			)

					# Removing hooks loads back the weights in the model.
					remove_hook_from_submodules(__magic_name__			)
					self.assertEqual(model.lineara.weight.device  ,      torch.device("""cpu"""			)			)
					self.assertEqual(model.batchnorm.weight.device  ,      torch.device("""cpu"""			)			)
					self.assertEqual(model.lineara.weight.device  ,      torch.device("""cpu"""			)			)

		def 	lowercase__     (   self					:   Any			)					->    Union[str, Any]:


					"""simple docstring"""

					__snake_case					:      Any							      =     ModelForTest()

					# Everything is on CPU
					self.assertEqual(model.lineara.weight.device  ,      torch.device("""cpu"""			)			)
					self.assertEqual(model.batchnorm.weight.device  ,      torch.device("""cpu"""			)			)
					self.assertEqual(model.lineara.weight.device  ,      torch.device("""cpu"""			)			)

					# This will move each submodule on different devices
					__snake_case					:      str							      =     0 if torch.cuda.is_available() else """cpu"""
					attach_align_device_hook(
					    __magic_name__  ,      execution_device=__magic_name__  ,      offload=__magic_name__  ,      weights_map=model.state_dict()			)

					# Parameters have been offloaded, so on the meta device
					self.assertEqual(model.lineara.weight.device  ,      torch.device("""meta"""			)			)
					self.assertEqual(model.batchnorm.weight.device  ,      torch.device("""meta"""			)			)
					self.assertEqual(model.lineara.weight.device  ,      torch.device("""meta"""			)			)
					# Buffers are not included in the offload by default, so are on the execution device
					__snake_case					:      List[str]							      =     torch.device(__magic_name__			)
					self.assertEqual(model.batchnorm.running_mean.device  ,      __magic_name__			)

					__snake_case					:      Tuple							      =     torch.randn(2  ,      3			)
					__snake_case					:      Optional[Any]							      =     model(__magic_name__			)
					self.assertEqual(output.device  ,      __magic_name__			)

					# Removing hooks loads back the weights in the model.
					remove_hook_from_submodules(__magic_name__			)
					self.assertEqual(model.lineara.weight.device  ,      torch.device("""cpu"""			)			)
					self.assertEqual(model.batchnorm.weight.device  ,      torch.device("""cpu"""			)			)
					self.assertEqual(model.lineara.weight.device  ,      torch.device("""cpu"""			)			)

					# Now test with buffers included in the offload
					attach_align_device_hook(
					    __magic_name__  ,      execution_device=__magic_name__  ,      offload=__magic_name__  ,      weights_map=model.state_dict()  ,      offload_buffers=__magic_name__  ,      )

					# Parameters have been offloaded, so on the meta device, buffers included
					self.assertEqual(model.lineara.weight.device  ,      torch.device("""meta"""			)			)
					self.assertEqual(model.batchnorm.weight.device  ,      torch.device("""meta"""			)			)
					self.assertEqual(model.lineara.weight.device  ,      torch.device("""meta"""			)			)
					self.assertEqual(model.batchnorm.running_mean.device  ,      torch.device("""meta"""			)			)

					__snake_case					:      List[str]							      =     torch.randn(2  ,      3			)
					__snake_case					:      Dict							      =     model(__magic_name__			)
					self.assertEqual(output.device  ,      __magic_name__			)

					# Removing hooks loads back the weights in the model.
					remove_hook_from_submodules(__magic_name__			)
					self.assertEqual(model.lineara.weight.device  ,      torch.device("""cpu"""			)			)
					self.assertEqual(model.batchnorm.weight.device  ,      torch.device("""cpu"""			)			)
					self.assertEqual(model.lineara.weight.device  ,      torch.device("""cpu"""			)			)


