code: def fast_group_adder(wires_to_add, reducer=wallace_reducer, final_adder=kogge_stone):
      
      import math
      longest_wire_len = max(len(w) for w in wires_to_add)
      result_bitwidth = longest_wire_len + int(math.ceil(math.log(len(wires_to_add), 2)))
  
      bits = [[] for i in range(longest_wire_len)]
  
      for wire in wires_to_add:
          for bit_loc, bit in enumerate(wire):
              bits[bit_loc].append(bit)
  
      return reducer(bits, result_bitwidth, final_adder)
docs: A generalization of the carry save adder, this is designed to add many numbers
      together in a both area and time efficient manner. Uses a tree reducer
      to achieve this performance
  
  
      :param [WireVector] wires_to_add: an array of wirevectors to add
      :param reducer: the tree reducer to use
      :param final_adder: The two value adder to use at the end
      :return: a wirevector with the result of the addition
        The length of the result is:
        max(len(w) for w in wires_to_add) + ceil(len(wires_to_add))