Пример #1
0
    def set_params_for_side(self, model, side):
        
        ics = []

        for interval in side.intervals:
            
            # if no interconnect then continue:
            try:
                interval.name['i']
            except KeyError:
                continue

            equationNumber = interval.name['e']
            equation = model.equations[equationNumber].copy()
        
            icRegion = interval.name['i']()

            blockNumber = icRegion.blockNumber
            side_num = icRegion.side_num

            funcName = ("Block" + str(blockNumber)
                        + "Interconnect__Side" + str(side_num)
                        + "_Eqn" + str(equationNumber))

            # generate equation:
            parsedValues = self.parse_equations(equation, model.dimension,
                                                blockNumber, side_num,
                                                icRegion.firstIndex,
                                                icRegion.secondIndex)
            # fill params:
            ic = Params()
            ic.name = "Connection"
            # ic.firstIndex = icRegion.firstIndex
            # ic.secondIndex = icRegion.secondIndex
            ic.side_num = side_num
            # ic.ranges = icRegion.ranges
            # ic.equationNumber = equationNum
            ic.equation = equation
            ic.funcName = funcName
            ic.boundName = determineNameOfBoundary(side_num)
            ic.blockNumber = blockNumber
            ic.parsedValues = parsedValues
            ic.original = [e.sent for e in equation.eqs]

            # for functionMaps:
            interval.name['fm'] = ic

            # for cpp:
            # each block can connect to many other block
            # let other block discribe interconnect in
            # that case
            ics.append(ic)

        return(ics)
Пример #2
0
    def _set_params_for_two_blocks(self, model, block, iconn, ics,
                                   blockNumber, firstIndex):
        '''Only for one block in pair.'''
        # choice side:
        if (iconn.block1 == blockNumber
            and iconn.block2 != blockNumber):
            # case differ 1
            side_num = iconn.block1Side
        elif (iconn.block2 == blockNumber
              and iconn.block1 != blockNumber):
            # case differ 2
            side_num = iconn.block2Side

        # len(ics for block)
        # firstIndex = len(ics)

        # FOR find equation for block
        Range = (side_num == 1) * block.size.sizeX
        coord = lambda region: ((side_num == 0) * region.xfrom
                                + (side_num == 1) * region.xto)
        side_test = lambda eRegion: coord(eRegion) == Range
        equationNum = self.choice_equation_num(side_test, block)

        equation = model.equations[equationNum].copy()
        # END FOR

        funcName = ("Block" + str(blockNumber)
                    + "Interconnect__Side" + str(side_num)
                    + "_Eqn" + str(equationNum))

        # generate equation:
        parsedValues = self.parse_equations(equation, model.dimension,
                                            blockNumber, side_num,
                                            firstIndex, 0)
        # fill params:
        ic = Params()
        ic.name = "Connection"
        ic.firstIndex = firstIndex
        ic.secondIndex = '0'
        ic.side_num = side_num
        ic.ranges = []
        ic.equationNumber = equationNum
        ic.equation = equation
        ic.funcName = funcName
        ic.boundName = determineNameOfBoundary(side_num)
        ic.blockNumber = blockNumber
        ic.parsedValues = parsedValues
        ic.original = [e.sent for e in equation.eqs]
        
        # each block can connect to many other block
        # let other block discribe interconnect in
        # that case
        return(ic)
Пример #3
0
    def _set_params_for_closed_block(self, model, block, iconn,
                                     blockNumber, srcFirstIndex,
                                     distFirstIndex):

        '''srcFirstIndex and distFirstIndex is first indexes of
        two interconects of same block'''

        # FOR finding equations:
        # choice left or right side of block
        # i.e. 0.0 or block.sizeX
        Range1 = (iconn.block1Side == 1) * block.size.sizeX
        Range2 = (iconn.block2Side == 1) * block.size.sizeX

        # return either xfrom or xto for block
        coord1 = lambda region: ((iconn.block1Side == 0)
                                 * region.xfrom
                                 + (iconn.block1Side == 1)
                                 * region.xto)
        coord2 = lambda region: ((iconn.block2Side == 0)
                                 * region.xfrom
                                 + (iconn.block2Side == 1)
                                 * region.xto)

        # find equation
        # for first block (one side of closed block)
        side_test = lambda eRegion: coord1(eRegion) == Range1
        equationNum1 = self.choice_equation_num(side_test, block)

        # find equation
        # for second block (other side of closed block)
        side_test = lambda eRegion: coord2(eRegion) == Range2
        equationNum2 = self.choice_equation_num(side_test, block)

        equation1 = model.equations[equationNum1].copy()
        equation2 = model.equations[equationNum2].copy()
        # END FOR

        funcName1 = ("Block" + str(blockNumber)
                     + "Interconnect__Side"
                     + str(iconn.block1Side)
                     + "_Eqn" + str(equationNum1))
        funcName2 = ("Block" + str(blockNumber)
                     + "Interconnect__Side"
                     + str(iconn.block2Side)
                     + "_Eqn" + str(equationNum2))

        # FOR equatioin cpp:
        # first equation:
        parsedValues_1 = self.parse_equations(equation1, model.dimension,
                                              blockNumber, iconn.block1Side,
                                              1, 0)

        # second equation:
        parsedValues_2 = self.parse_equations(equation2, model.dimension,
                                              blockNumber, iconn.block2Side,
                                              0, 0)
        # END FOR

        # fill params:
        ic1 = Params()
        ic1.name = "Connection"
        ic1.firstIndex = srcFirstIndex
        ic1.secondIndex = '0'
        ic1.side_num = iconn.block1Side
        ic1.ranges = []
        ic1.equationNumber = equationNum1
        ic1.equation = equation1
        ic1.funcName = funcName1
        ic1.parsedValues = parsedValues_1
        ic1.original = [e.sent for e in equation1.eqs]
        ic1.boundName = determineNameOfBoundary(iconn.block1Side)
        ic1.blockNumber = blockNumber
        
        ic2 = Params()
        ic2.name = "Connection"
        ic2.firstIndex = distFirstIndex
        ic2.secondIndex = '0'
        ic2.side_num = iconn.block2Side
        ic2.ranges = []
        ic2.equationNumber = equationNum2
        ic2.equation = equation2
        ic2.funcName = funcName2
        ic2.parsedValues = parsedValues_2
        ic2.original = [e.sent for e in equation2.eqs]
        ic2.boundName = determineNameOfBoundary(iconn.block2Side)
        ic2.blockNumber = blockNumber

        return((ic1, ic2))
Пример #4
0
    def make_region(self, mainBlockSide, mainBlock, secondBlock,
                    region_num, firstIndex):
        
        '''Make some data for each block in ic.
        
        First it's find side and intervals, in which
        ic to be used. For interval it used ``Interval``
        object with bound and equation numbers set to
        ``None`` (i.e. ``name={'b': None, 'e': None}``).

        Change ``side.intervals`` to add ic intervals
        to it (i.e. first split ic interval at bouds/eq
        regions, then split all ``side.intervals`` at
        that ic_interval).

        Also It create ranges that is rectangle
        ``[xfrom, xto, yfrom, yto]`` where all in cell sizes.

        interval, xfrom, xto, yfrom, yto, lenOfConnection,
        beforeStartLen, ranges is all inteconnect data,
        relative to mainBlock.
        
        It also add first index of current inteconnect
        for created region and increase it global value
        (stored in ``model._ics_firstIndex``)

        It create ``secondIndex`` which is index to be
        used by ``mainBlock`` in order to get according
        ``ics`` data for according side coordinate.

        (ex (what ``secondIndex`` used for):
        
           secondIndex: ic[firstIndex][secondIndex] for mainBlock
              where ic is inteconnects array,
                 firstIndex is index of ic mainBlock and secondBlock
                 secondIndex according mainBlock side (see ex below))

        (ex (how ``secondIndex`` created for side 2 or 3):

           secondIndex = idxX - to_cell(lenBSBSSC)
              where lenBSBSSC is len between start of block side
                 and start of connection)

        Tests:

        >>> from envs.hs.model.model_main import ModelNet as Model
        >>> m = Model()
        >>> m.io.loadFromFile('problems/2dTests/tests_2d_two_blocks0')
        >>> ic = m.interconnects[0]
        >>> icr = ic.regions[1]
        >>> icr.ranges
        [0, 301, 0, 1]

        >>> icr = ic.regions[2]
        >>> icr.ranges
        [150, 451, 700, 701]
        '''

        grid = self.net.model.grid
        den = mainBlock.defaultEquation

        if mainBlockSide == 0:

            xfrom = 0  # mainBlock.size.offsetX
            xto = 0  # mainBlock.size.offsetX
            yfrom = (max([secondBlock.size.offsetY, mainBlock.size.offsetY])
                     - mainBlock.size.offsetY)
            yto = (min([mainBlock.size.offsetY + mainBlock.size.sizeY,
                        secondBlock.size.offsetY + secondBlock.size.sizeY])
                   - mainBlock.size.offsetY)
            interval = Interval([yfrom, yto])

            beforeStartLen = yfrom
            lenOfConnection = yto - yfrom
            sideIndex = 'idxY'
            stepAlongSide = grid.gridStepY

        elif mainBlockSide == 1:

            xfrom = mainBlock.size.sizeX  # + mainBlock.size.offsetX
            xto = mainBlock.size.sizeX  # + mainBlock.size.offsetX
            yfrom = (max([secondBlock.size.offsetY, mainBlock.size.offsetY])
                     - mainBlock.size.offsetY)
            yto = (min([mainBlock.size.offsetY + mainBlock.size.sizeY,
                        secondBlock.size.offsetY + secondBlock.size.sizeY])
                   - mainBlock.size.offsetY)
            interval = Interval([yfrom, yto])

            beforeStartLen = yfrom
            lenOfConnection = yto - yfrom
            sideIndex = 'idxY'
            stepAlongSide = grid.gridStepY

        elif mainBlockSide == 2:

            xfrom = (max([mainBlock.size.offsetX, secondBlock.size.offsetX])
                     - mainBlock.size.offsetX)
            xto = (min([mainBlock.size.offsetX + mainBlock.size.sizeX,
                        secondBlock.size.offsetX + secondBlock.size.sizeX])
                   - mainBlock.size.offsetX)
            yfrom = 0  # mainBlock.size.offsetY
            yto = 0  # mainBlock.size.offsetY
            interval = Interval([xfrom, xto])

            beforeStartLen = xfrom
            lenOfConnection = xto - xfrom
            sideIndex = 'idxX'
            stepAlongSide = grid.gridStepX

        else:

            xfrom = (max([mainBlock.size.offsetX, secondBlock.size.offsetX])
                     - mainBlock.size.offsetX)
            xto = (min([mainBlock.size.offsetX + mainBlock.size.sizeX,
                        secondBlock.size.offsetX + secondBlock.size.sizeX])
                   - mainBlock.size.offsetX)
            yfrom = mainBlock.size.sizeY  # + mainBlock.size.offsetY
            yto = mainBlock.size.sizeY  # + mainBlock.size.offsetY
            interval = Interval([xfrom, xto])

            beforeStartLen = xfrom
            lenOfConnection = xto - xfrom
            sideIndex = 'idxX'
            stepAlongSide = grid.gridStepX

        # FOR collect data:
        out = Params()

        out.firstIndex = firstIndex
        # out.firstIndex = self.net.model._ics_firstIndex
        # self.net.model._ics_firstIndex += 1

        out.side_num = mainBlockSide
        # out.stepAlongSide = stepAlongSide
        # out.beforeStartLen = beforeStartLen
        
        # map: block side index -> second index of ic
        # (ex: idxX -> secondIndex where secondIndex: ic[][secondIndex]):
        startCellIndex = determineCISC2D(beforeStartLen, stepAlongSide)
        out.secondIndex = ('(' + sideIndex + ' - ' + str(startCellIndex)
                           + ') * Block' + str(mainBlock.blockNumber)
                           + 'CELLSIZE')

        out.icLen = lenOfConnection

        side = mainBlock.sides[mainBlockSide]
        logger.debug("side.intervals:")
        logger.debug(side.intervals)
        logger.debug("icr.intervals:")
        logger.debug(interval)

        # add default name:
        interval.name = {'b': None, 'e': den,
                         'i': (lambda _self=self, _region_num=region_num:
                               _self[_region_num])}
        # region_num - is global name
        # while _region_num is local name in lambda
        # that used because otherwise all regions
        # would have same region_num.
        
        # split at equation and bounds regions:
        out.intervals = interval.split_all([copy(interval)
                                            for interval in side.intervals],
                                           [])

        # add ic info into block.side:
        side.intervals = sum([i.split_all(out.intervals, [])
                              for i in side.intervals], [])
        # reset vertexs:
        mainBlock.editor.set_vertexs()

        out.xfrom = xfrom
        out.xto = xto
        out.yfrom = yfrom
        out.yto = yto
        '''
        ranges = getRangesInClosedInterval([xfrom, xto, grid.gridStepX],
                                           [yfrom, yto, grid.gridStepY])
        out.ranges = ranges
        '''
        out.blockNumber = mainBlock.blockNumber
        out.ic = self.net
        out.ic_regions = self
        # END FOR

        return(out)
Пример #5
0
    def make_bound_param(self, model, vertex):
        '''Fill this parameters for block bound border
        (vertex in case of 1d)::

        Collect this parameters for template:

             - ``bParams.dim``
             - ``bParams.values`` -- border_values
             - ``bParams.btype``
             - ``bParams.side_num``
             - ``bParams.boundNumber``
             - ``bParams.equationNumber``
             - ``bParams.equation`` -- system of equations
             - ``bParams.funcName``
             - ``bParams.block``
             - ``bParams.blockNumber``
             - ``bParams.boundName`` -- for comment
             - ``bParams.parsedValues``
             - ``bParams.original`` -- for comment

        This parameters also collected for dom:
    
             - ``bound.side``
             - ``bound.blockNumber``
             - ``bParams.funcName``
        '''
        block = vertex.block
        blockNumber = vertex.block.blockNumber

        # for 1d there is only one side:
        side_num = vertex.sides_nums[0]

        # find equation number for side or use default
        equationNum = vertex.equationNumber
        '''
        regsEqNums = [eqReg.equationNumber
                      for eqReg in block.equationRegions
                      if self.test(block, eqReg, side_num)]
        equationNum = (regsEqNums[0] if len(regsEqNums) > 0
                       else block.defaultEquation)
        '''
        eSystem = model.equations[equationNum].copy()

        # find bound region for side or use default
        boundNumber = vertex.boundNumber
        '''
        regionsForSide = [bRegion
                          for k in block.boundRegions
                          for bRegion in block.boundRegions[k]
                          if bRegion.side_num == side_num]
        '''

        # if exist special region for that side
        # if len(regionsForSide) > 0:
        if boundNumber is not None:
            # region = block.boundsRegions[boundNumber]
            # region = regionsForSide[0]
            # boundNumber = region.boundNumber

            bound = model.bounds[boundNumber]

            args = (model, blockNumber, side_num, boundNumber, equationNum)

            # for Dirichlet bound
            if bound.btype == 0:
                func = self.get_func_for_dirichlet(*args)

            # for Neumann bound
            elif bound.btype == 1:
                func = self.get_func_for_neumann(*args)

            funcName = func[0]
            border_values = list(func[1])
            btype = bound.btype
        else:
            # if not, use default

            args = (eSystem, blockNumber, side_num, equationNum)
            func = self.get_func_default(*args)

            funcName = func[0]
            border_values = func[1]
            btype = 1
            boundNumber = -1

        args = (eSystem, model, blockNumber, btype, side_num, border_values)
        parsed = self.parse_equations(*args)
        # print("bound bug debug:")
        # print(parsed)

        # FOR collect template data:
        bParams = Params()
        bParams.dim = model.dimension
        bParams.values = border_values
        bParams.btype = btype
        bParams.side_num = side_num
        bParams.boundNumber = boundNumber
        bParams.equationNumber = equationNum
        bParams.equation = eSystem
        bParams.funcName = funcName
        bParams.block = block
        bParams.blockNumber = blockNumber
        logger.debug("bParams.funcName")
        logger.debug(bParams.funcName)
        logger.debug("bParams.side_num")
        logger.debug(bParams.side_num)
        # in comment
        bParams.boundName = determineNameOfBoundary(side_num)
        bParams.parsedValues = parsed[0]
        bParams.border_values_parsed = parsed[1]
        bParams.original = [e.sent for e in eSystem.eqs]
        # END FOR

        vertex.fm = bParams
        return (bParams)
Пример #6
0
    def make_bounds_for_edges(self, model, side):
        '''
        DESCRIPTION:

        Collect this parameters for template:
        
        - ``bParams.name``
        - ``bParams.side_num``
        - ``bParams.blockNumber``
        - ``bParams.boundNumber``
        - ``bParams.equationNumber``
        
        - ``bParams.funcName`` -- func name in cpp
        - ``bParams.btype`` -- Dirichlet 0, Neumann 1
        - ``bParams.equation`` -- system of equations
        SysNet object
        - ``bParams.parsedValues``
        - ``bParams.original`` -- original for comment
        - ``bParams.boundName`` -- bound name for comment

        This parameters also collected for dom:
        
        - ``bParams.blockNumber``
        - ``bParams.side_num``
        - ``bParams.funcName`` -- for defining func index in
        namesAndNumbers dict.
        - ``bParams.region``
        
        Inputs:

        - ``side`` -- is ``Side`` object::

        side:

         - ``side_num``,

         - ``block.blockNumber``,

         - ``interval`` -- of type oIntervals

           where oIntervals =
                 [Interval([x, y], name={'b': bval, 'e', eval})]
        '''
        bounds = []
        for interval in side.intervals:

            # if interconnect then continue:
            try:
                interval.name['i']
                continue
            except KeyError:
                pass

            bParams = Params()
            bParams.name = 'sides bound'
            bParams.side_num = side.side_num
            bParams.blockNumber = side.block.blockNumber
            bParams.boundNumber = interval.name['b']
            bParams.equationNumber = interval.name['e']
            bParams.interval = interval

            eSystem = model.equations[bParams.equationNumber].copy()

            if bParams.boundNumber is not None:

                # FOR set up funcName and border values:
                args = (model, bParams.blockNumber, bParams.side_num,
                        bParams.boundNumber, bParams.equationNumber)

                btype = model.bounds[bParams.boundNumber].btype

                # for Dirichlet bound
                if btype == 0:
                    func = self.get_func_for_dirichlet(*args)

                # for Neumann bound
                elif btype == 1:
                    func = self.get_func_for_neumann(*args)

                funcName = func[0]
                border_values = list(func[1])

            else:

                btype = 0
                args = (eSystem, bParams.blockNumber, bParams.side_num,
                        bParams.equationNumber)
                func = self.get_func_default(*args)

                funcName = func[0]
                border_values = func[1]

            args = (eSystem, model, bParams.blockNumber, btype,
                    bParams.side_num, border_values)
            parsed, bv_parsed = self.parse_equations(*args)

            bParams.funcName = funcName
            bParams.btype = btype
            bParams.equation = eSystem
            bParams.parsedValues = parsed
            bParams.border_values_parsed = bv_parsed
            bParams.original = [e.sent for e in eSystem.eqs]

            # for comment
            bParams.boundName = determineNameOfBoundary(bParams.side_num)

            # collect for functionMaps:
            interval.name['fm'] = bParams

            bounds.append(bParams)
        return (bounds)