Exemplo n.º 1
0
 def _print_IndexedElement(self, expr):
     if isinstance(expr.base, IndexedVariable):
         base = expr.base.internal_variable
     else:
         base = expr.base
     inds = list(expr.indices)
     inds = inds[::-1]
     base_shape = base.shape
     allow_negative_indexes = (isinstance(expr.base, IndexedVariable) and \
             base.allows_negative_indexes)
     for i, ind in enumerate(inds):
         if isinstance(ind, PyccelUnarySub) and isinstance(
                 ind.args[0], LiteralInteger):
             inds[i] = PyccelMinus(base_shape[i], ind.args[0])
         else:
             #indices of indexedElement of len==1 shouldn't be a Tuple
             if isinstance(ind, Tuple) and len(ind) == 1:
                 inds[i].args = ind[0]
             if allow_negative_indexes and \
                     not isinstance(ind, LiteralInteger) and not isinstance(ind, Slice):
                 inds[i] = PyccelMod(ind, base_shape[i])
     #set dtype to the C struct types
     dtype = self._print(expr.dtype)
     dtype = self.find_in_ndarray_type_registry(dtype, expr.precision)
     base_name = self._print(base.name)
     if base.is_ndarray:
         if expr.rank > 0:
             #managing the Slice input
             for i, ind in enumerate(inds):
                 if isinstance(ind, Slice):
                     #setting the slice start and end to their correct value if none is provided
                     start = ind.start
                     #handling the negative indexes for a slice object
                     if isinstance(start, PyccelUnarySub) and \
                             isinstance(start.args[0], LiteralInteger):
                         start = PyccelMinus(base_shape[i], start.args[0])
                     end = ind.end
                     if isinstance(end, PyccelUnarySub) and \
                             isinstance(end.args[0], LiteralInteger):
                         end = PyccelMinus(base_shape[i], end.args[0])
                     if ind.start is None:
                         start = 0
                     if ind.end is None:
                         end = base.shape[i]
                     inds[i] = Slice(start, end)
                 else:
                     #setting the Slice start and end to their correct value when try to get a view with scalar index
                     inds[i] = Slice(ind, ind + 1)
             inds = [self._print(i) for i in inds]
             return "array_slicing(%s, %s)" % (base_name, ", ".join(inds))
         inds = [self._print(i) for i in inds]
     else:
         raise NotImplementedError(expr)
     return "%s.%s[get_index(%s, %s)]" % (base_name, dtype, base_name,
                                          ", ".join(inds))
Exemplo n.º 2
0
    def _visit_Slice(self, stmt):

        upper = self._visit(stmt.upper) if stmt.upper is not None else None
        lower = self._visit(stmt.lower) if stmt.lower is not None else None
        step = self._visit(stmt.step) if stmt.step is not None else None

        return Slice(lower, upper, step)
Exemplo n.º 3
0
def get_results_shape(func):
    """returns a dictionary that contains for each result, its shape. When using
    the decorator @shapes, the shape value may be computed"""

    # ...
    arguments = list(func.arguments)
    arguments_inout = list(func.arguments_inout)
    results = list(func.results)

    inouts = [x for x, flag in zip(arguments, arguments_inout) if flag]
    # ...

    # ...
    d_args = {}
    for a in arguments:
        d_args[a.name] = a
    # ...

#    print('results = ', results)
#    print('inouts   = ', inouts)

    d_shapes = {}
    if 'shapes' in func.decorators.keys():
        d = func.decorators['shapes']
        for valued in d:
            # ...
            r = [r for r in results + inouts if r.name == valued.name]
            if not r:
                raise ValueError('Could not find {}'.format(r))

            assert (len(r) == 1)
            r = r[0]
            # ...

            # ...
            rhs = valued.value
            if isinstance(rhs, String):
                rhs = rhs.arg.replace("'", '')

            else:
                raise NotImplementedError('')
            # ...

            # ...
            rhs = sympify(rhs, locals=d_args)
            # ...

            # TODO improve
            # this must always be a list of slices
            d_shapes[r.name] = [Slice(None, rhs)]

    # TODO treate the case when shapes is not given => add some checks
#    else:
#        raise NotImplementedError('')

    return d_shapes
Exemplo n.º 4
0
    def _visit_Slice(self, stmt):

        upper = self._visit(stmt.upper)
        lower = self._visit(stmt.lower)

        if stmt.step is not None:
            raise NotImplementedError("Steps in slices are not implemented")

        if not isinstance(upper, Nil) and not isinstance(lower, Nil):

            return Slice(lower, upper)
        elif not isinstance(lower, Nil):

            return Slice(lower, None)
        elif not isinstance(upper, Nil):

            return Slice(None, upper)
        else:

            return Slice(None, None)
Exemplo n.º 5
0
    def _visit_Map(self, stmt):
        func = stmt.func
        args = stmt.target

        # ...
        if isinstance(func, BasicMap):
            raise TypeError("'map' object is not callable")
        # ...

        # ... get the codomain type
        type_codomain = self.main_type
        type_domain = self.d_domain_types[type_codomain]
        # ...

        # ... construct the generator
        target = [self._visit(i) for i in args]

        if len(target) == 1:
            target = target[0]
            assert (isinstance(target, Variable))

            generator = VariableGenerator(target)

        else:
            generator = ZipGenerator(*target)
        # ...

        # ... construct the results
        results = self._visit(type_codomain)

        # compute depth of the type list
        # TODO do we still need this?
        depth_out = len(list(type_codomain.atoms(TypeList)))
        # ...

        # ...
        index = generator.index
        iterator = generator.iterator
        # ...

        # ... list of all statements
        stmts = []
        # ...

        # ... we set the generator after we treat map/tmap
        self.set_generator(results, generator)
        # ...

        # ... apply the function to arguments
        rhs = Call(func, iterator)
        # ...

        #        print('PAR ICI')
        #        print(func)
        #        print(func.name)
        ##        import sys; sys.exit(0)

        # ... create lhs
        lhs = generator.iterator
        # TODO check this
        if isinstance(lhs, Tuple) and len(lhs) == 1:
            lhs = lhs[0]
        # ...

        # ... create lhs for storing the result
        if isinstance(results, Variable):
            results = [results]

        else:
            msg = '{} not available'.format(type(results))
            raise NotImplementedError(msg)

        if not isinstance(index, Tuple):
            index = [index]

        else:
            index = list([i for i in index])

        lhs = []
        for r in results:
            m = r.rank - depth_out
            ind = index + [Slice(None, None)] * m
            if len(ind) == 1:
                ind = ind[0]

            lhs.append(IndexedBase(r.name)[ind])

        lhs = Tuple(*lhs)
        if len(lhs) == 1:
            lhs = lhs[0]
        # ...

        # ... create core statement
        stmts += [Assign(lhs, rhs)]
        # ...

        # TODO USE THIS
        #                expr = self.get_expr_from_type()

        # return the associated for loops
        return GeneratorBlock(generator,
                              stmts,
                              accelerator=self.accelerator,
                              nowait=self.nowait,
                              schedule=self.schedule,
                              chunk=self.chunk)
Exemplo n.º 6
0
    def _visit_Reduce(self, stmt, op=None):
        target = stmt.target

        # ... get the codomain type
        type_codomain = self.main_type
        type_domain = self.d_domain_types[type_codomain]
        # ...

        # ... construct the results
        results = self._visit(type_codomain)

        # compute depth of the type list
        # TODO do we still need this?
        depth_out = 0
        # ...

        # ... construct the generator
        block = self._visit(target)
        assert (isinstance(block, GeneratorBlock))

        generator = block.generator
        if isinstance(generator, Variable):
            generator = VariableGenerator(generator)

        assert (isinstance(generator, BasicGenerator))
        # ...

        # ...
        index = generator.index
        iterator = generator.iterator
        # ...

        # ... list of all statements
        stmts = []
        # ...

        # ... we set the generator after we treat map/tmap
        self.set_generator(results, generator)
        # ...

        # ... create lhs
        lhs = generator.iterator
        # TODO check this
        if isinstance(lhs, Tuple) and len(lhs) == 1:
            lhs = lhs[0]
        # ...

        # ... create lhs for storing the result
        if isinstance(results, Variable):
            results = [results]

        else:
            msg = '{} not available'.format(type(results))
            raise NotImplementedError(msg)

        if not isinstance(index, Tuple):
            index = [index]

        else:
            index = list([i for i in index])

        lhs = []
        for r in results:
            m = r.rank - depth_out
            ind = [Slice(None, None)] * m
            if ind:
                if len(ind) == 1:
                    ind = ind[0]

                lhs.append(IndexedBase(r.name)[ind])

            else:
                lhs.append(Symbol(r.name))

        lhs = Tuple(*lhs)
        if len(lhs) == 1:
            lhs = lhs[0]
        # ...

        # ... add reduction
        reduction = Reduction(op, results)
        # ...

        # TODO USE THIS
        #                expr = self.get_expr_from_type()

        # return the associated for loops
        return ReductionGeneratorBlock(block,
                                       reduction,
                                       lhs,
                                       accelerator=self.accelerator)
Exemplo n.º 7
0
    def _visit_ProductMap(self, stmt):
        func = stmt.func
        args = stmt.target

        # ...
        if isinstance(func, BasicMap):
            raise TypeError("'map' object is not callable")
        # ...

        # ... get the codomain type
        type_codomain = self.main_type
        type_domain = self.d_domain_types[type_codomain]
        # ...

        # ... construct the generator
        target = [self._visit(i) for i in args]

        generator = ProductGenerator(*target)
        # ...

        # ... construct the results
        results = self._visit(type_codomain)

        # compute depth of the type list
        # TODO do we still need this?
        depth_out = len(list(type_codomain.atoms(TypeList)))
        # ...

        # ...
        index = generator.index
        iterator = generator.iterator
        # ...

        # ... list of all statements
        stmts = []
        # ...

        # ... use a multi index in the case of zip
        length = generator.length
        multi_index = generator.multi_index
        generator.set_as_list()

        # TODO check formula
        value = index[0]
        for ix, nx in zip(index[1:], length[::-1][:-1]):
            value = nx * value + ix

        stmts += [Assign(multi_index, value)]

        # update index to use multi index
        index = multi_index
        # ...

        # ... we set the generator after we treat map/tmap
        self.set_generator(results, generator)
        # ...

        # ... apply the function to arguments
        rhs = Call(func, iterator)
        # ...

        # ... create lhs
        lhs = generator.iterator
        # TODO check this
        if isinstance(lhs, Tuple) and len(lhs) == 1:
            lhs = lhs[0]
        # ...

        # ... create lhs for storing the result
        if isinstance(results, Variable):
            results = [results]

        else:
            msg = '{} not available'.format(type(results))
            raise NotImplementedError(msg)

        if not isinstance(index, Tuple):
            index = [index]

        else:
            index = list([i for i in index])

        lhs = []
        for r in results:
            m = r.rank - depth_out
            ind = index + [Slice(None, None)] * m
            if len(ind) == 1:
                ind = ind[0]

            lhs.append(IndexedBase(r.name)[ind])

        lhs = Tuple(*lhs)
        if len(lhs) == 1:
            lhs = lhs[0]
        # ...

        # ... create core statement
        stmts += [Assign(lhs, rhs)]
        # ...

        # TODO USE THIS
        #                expr = self.get_expr_from_type()

        # return the associated for loops
        return GeneratorBlock(generator,
                              stmts,
                              accelerator=self.accelerator,
                              nowait=self.nowait,
                              schedule=self.schedule,
                              chunk=self.chunk)