




'''simple docstring'''







import torch

from accelerate import PartialState
from accelerate.utils.operations import broadcast, gather, gather_object, pad_across_processes, reduce





def 						snake_case_							(_a	:							str     ):
    return (torch.arange(state.num_processes     ) + 1.0 + (state.num_processes * state.process_index)).to(state.device     )





def 						snake_case_							(_a	:							str     ):
    UpperCAmelCase			       =		create_tensor(_a     )
    UpperCAmelCase			       =		gather(_a     )
    assert gathered_tensor.tolist() == list(range(1    ,   state.num_processes**2 + 1     )     )





def 						snake_case_							(_a	:							int     ):
    UpperCAmelCase			       =		[state.process_index]
    UpperCAmelCase			       =		gather_object(_a     )
    assert len(_a     ) == state.num_processes, F"{gathered_obj}, {len(_a     )} != {state.num_processes}"
    assert gathered_obj == list(range(state.num_processes     )     ), F"{gathered_obj} != {list(range(state.num_processes     )     )}"





def 						snake_case_							(_a	:							int     ):
    UpperCAmelCase			       =		create_tensor(_a     )
    UpperCAmelCase			       =		broadcast(_a     )
    assert broadcasted_tensor.shape == torch.Size([state.num_processes]     )
    assert broadcasted_tensor.tolist() == list(range(1    ,   state.num_processes + 1     )     )





def 						snake_case_							(_a	:							Dict     ):
    # We need to pad the tensor with one more element if we are the main process
    # to ensure that we can pad
    if state.is_main_process:
        UpperCAmelCase			       =		torch.arange(state.num_processes + 1     ).to(state.device     )
    else:
        UpperCAmelCase			       =		torch.arange(state.num_processes     ).to(state.device     )
    UpperCAmelCase			       =		pad_across_processes(_a     )
    assert padded_tensor.shape == torch.Size([state.num_processes + 1]     )
    if not state.is_main_process:
        assert padded_tensor.tolist() == list(range(0    ,   state.num_processes     )     ) + [0]





def 						snake_case_							(_a	:							Tuple     ):
    # For now runs on only two processes
    if state.num_processes != 2:
        return
    UpperCAmelCase			       =		create_tensor(_a     )
    UpperCAmelCase			       =		reduce(_a    ,   '''sum'''     )
    UpperCAmelCase			       =		torch.tensor([4.0, 6]     ).to(state.device     )
    assert torch.allclose(_a    ,   _a     ), F"{reduced_tensor} != {truth_tensor}"





def 						snake_case_							(_a	:							Optional[int]     ):
    # For now runs on only two processes
    if state.num_processes != 2:
        return
    UpperCAmelCase			       =		create_tensor(_a     )
    UpperCAmelCase			       =		reduce(_a    ,   '''mean'''     )
    UpperCAmelCase			       =		torch.tensor([2.0, 3]     ).to(state.device     )
    assert torch.allclose(_a    ,   _a     ), F"{reduced_tensor} != {truth_tensor}"





def 						snake_case_							(_a	:							int     ):
    # For xla_spawn (TPUs)
    main()





def 						snake_case_							():
    UpperCAmelCase			       =		PartialState()
    state.print(F"State: {state}"     )
    state.print('''testing gather'''     )
    test_gather(_a     )
    state.print('''testing gather_object'''     )
    test_gather_object(_a     )
    state.print('''testing broadcast'''     )
    test_broadcast(_a     )
    state.print('''testing pad_across_processes'''     )
    test_pad_across_processes(_a     )
    state.print('''testing reduce_sum'''     )
    test_reduce_sum(_a     )
    state.print('''testing reduce_mean'''     )
    test_reduce_mean(_a     )


if __name__ == "__main__":
   main()





"""simple docstring"""






import os

import numpy
import onnx



def   a_						(					lowerCamelCase					,			lowerCamelCase       ):
				UpperCAmelCase__             =							a.name
				UpperCAmelCase__             =							b.name

				UpperCAmelCase__             =							''
				UpperCAmelCase__             =							''

				UpperCAmelCase__             =							a == b

				UpperCAmelCase__             =							name_a
				UpperCAmelCase__             =							name_b

				return res



def   a_						(					lowerCamelCase					,			lowerCamelCase					,			lowerCamelCase       ):
				for i, input_name in enumerate(node_proto.input       ):
								if input_name == name:
												node_proto.input.insert(lowerCamelCase					,			lowerCamelCase       )
												node_proto.input.pop(i + 1       )

				if node_proto.op_type == "If":
								_graph_replace_input_with(node_proto.attribute[0].g					,			lowerCamelCase					,			lowerCamelCase       )
								_graph_replace_input_with(node_proto.attribute[1].g					,			lowerCamelCase					,			lowerCamelCase       )
				if node_proto.op_type == "Loop":
								_graph_replace_input_with(node_proto.attribute[0].g					,			lowerCamelCase					,			lowerCamelCase       )



def   a_						(					lowerCamelCase					,			lowerCamelCase					,			lowerCamelCase       ):
				for n in graph_proto.node:
								_node_replace_input_with(lowerCamelCase					,			lowerCamelCase					,			lowerCamelCase       )



def   a_						(					lowerCamelCase					,			lowerCamelCase					,			lowerCamelCase       ):
				UpperCAmelCase__             =							list(model.graph.initializer       )
				UpperCAmelCase__             =							list(model_without_ext.graph.initializer       )
				for i, ref_i in ind_to_replace:
								assert inits_with_data[i].name == inits[i].name
								assert inits_with_data[ref_i].name == inits[ref_i].name
								assert i > ref_i

								UpperCAmelCase__             =							inits[i].name
								UpperCAmelCase__             =							inits[ref_i].name

								model_without_ext.graph.initializer.remove(inits[i]       )

								# for n in model.graph.node:
								_graph_replace_input_with(model_without_ext.graph					,			lowerCamelCase					,			lowerCamelCase       )







def   a_						(					lowerCamelCase       ):
				UpperCAmelCase__             =							os.path.dirname(lowerCamelCase       )
				UpperCAmelCase__             =							os.path.basename(lowerCamelCase       )

				UpperCAmelCase__             =							onnx.load(os.path.join(lowerCamelCase					,			lowerCamelCase       )       )

				UpperCAmelCase__             =							list(model.graph.initializer       )

				UpperCAmelCase__             =							set()
				UpperCAmelCase__             =							{}
				UpperCAmelCase__             =							[]

				UpperCAmelCase__             =							0

				for i in range(len(lowerCamelCase       )       ):
								if i in dup_set:
												continue

								for j in range(i + 1					,			len(lowerCamelCase       )       ):
												if j in dup_set:
																continue
												if _is_equal_tensor_proto(inits[i]					,			inits[j]       ):
																dup_set.add(lowerCamelCase       )
																dup_set.add(lowerCamelCase       )

																UpperCAmelCase__             =							inits[j].data_type
																UpperCAmelCase__             =							numpy.prod(inits[j].dims       )
																if dtype == 1:
																				mem_size *= 4
																elif dtype == 6:
																				mem_size *= 4
																elif dtype == 7 or dtype == 1_1:
																				mem_size *= 8
																else:
																				print('unexpected data type: '					,			lowerCamelCase       )
																total_reduced_size += mem_size

																UpperCAmelCase__             =							inits[i].name
																UpperCAmelCase__             =							inits[j].name

																if name_i in dup_map:
																				dup_map[name_i].append(lowerCamelCase       )
																else:
																				UpperCAmelCase__             =							[name_j]
																ind_to_replace.append((j, i)       )

				print('total reduced size: '					,			total_reduced_size / 1_0_2_4 / 1_0_2_4 / 1_0_2_4					,			'GB'       )

				UpperCAmelCase__             =							sorted(lowerCamelCase       )
				_remove_dup_initializers_from_model(lowerCamelCase					,			lowerCamelCase					,			lowerCamelCase       )

				UpperCAmelCase__             =							'optimized_' + model_file_name
				UpperCAmelCase__             =							os.path.join(lowerCamelCase					,			lowerCamelCase       )
				onnx.save(lowerCamelCase					,			lowerCamelCase       )

				return new_model



