text: # Copyright (C) 2020  GreenWaves Technologies, SAS
  
  # This program is free software: you can redistribute it and/or modify
  # it under the terms of the GNU Affero General Public License as
  # published by the Free Software Foundation, either version 3 of the
  # License, or (at your option) any later version.
  
  # This program is distributed in the hope that it will be useful,
  # but WITHOUT ANY WARRANTY; without even the implied warranty of
  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  # GNU Affero General Public License for more details.
  
  # You should have received a copy of the GNU Affero General Public License
  # along with this program.  If not, see <https://www.gnu.org/licenses/>.
  
  import numpy as np
  from graph.types import GatherParameters, NNEdge
  from graph.types.input_output import ConstantInputParameters
  from importer.common.constant_mixin import ConstantMixin
  from importer.common.provisional_dim import ProvisionalDim
  from importer.onnx.common import logger
  
  from ..backend_handler import BackendHandler
  from ..handler import onnx_op
  
  
  @onnx_op("Gather")
  class Gather(ConstantMixin, BackendHandler):
  
      @classmethod
      def _common(cls, node, **kwargs):
          all_nodes = kwargs['all_nodes']
          G = kwargs['G']
          valid_name = kwargs['valid_name']
          inputs = [all_nodes[inp] for inp in node.input]
          x = inputs[0]
          x_shape = x[2].shape
          y = inputs[1]
          indices = cls.get_constant(y)
          axis = node.attrs.get('axis', 0)
  
          pshape = ProvisionalDim(x_shape[:axis:] + list(indices.shape) + x_shape[axis + 1:])
          if cls.is_constant(x):
              x_val = cls.get_constant(x)
              logger.info(f"reducing {valid_name} to a constant {cls.print_small(x_val)}")
              params = ConstantInputParameters(valid_name, value=np.take(x_val, indices, axis=axis),
                                               constant_store=G.constant_store)
          else:
              axis = cls._trim_axis(axis, x_shape)
              params = GatherParameters(valid_name, axis=axis, indices=indices)
              G.add_edge(NNEdge(from_node=x[0], to_node=params, from_idx=x[1], to_idx=0))
          all_nodes[node.output[0]] = (params, 0, pshape)
          return params
  
      @classmethod
      def version_1(cls, node, **kwargs):
          return cls._common(node, **kwargs)
  
      @classmethod
      def version_11(cls, node, **kwargs):
          return cls._common(node, **kwargs)
  