Search in sources :

Example 1 with ClawDimension

use of cx2x.translator.language.common.ClawDimension in project claw-compiler by C2SM-RCM.

the class TransformationHelper method duplicateWithDimension.

/**
   * Duplicates the type to update and add extra dimensions to match the base
   * type.
   *
   * @param base       Base type.
   * @param toUpdate   Type to update.
   * @param xcodemlDst Destination XcodeML unit. Duplicate will be created here.
   * @param xcodemlSrc Source XcodeML unit. Contains base dimension.
   * @return The new type hash generated.
   */
public static String duplicateWithDimension(XbasicType base, XbasicType toUpdate, XcodeML xcodemlDst, XcodeML xcodemlSrc, OverPosition overPos, List<ClawDimension> dimensions) throws IllegalTransformationException {
    XbasicType newType = toUpdate.cloneNode();
    String type = xcodemlDst.getTypeTable().generateArrayTypeHash();
    newType.setAttribute(Xattr.TYPE, type);
    if (base.isAllAssumedShape() && toUpdate.isAllAssumedShape()) {
        int additionalDimensions = base.getDimensions() - toUpdate.getDimensions();
        for (int i = 0; i < additionalDimensions; ++i) {
            Xnode index = xcodemlDst.createEmptyAssumedShaped();
            newType.addDimension(index, 0);
        }
    } else if (base.isAllAssumedShape() && !toUpdate.isAllAssumedShape()) {
        switch(overPos) {
            case BEFORE:
                // TODO control and validate the before/after
                for (ClawDimension dim : dimensions) {
                    newType.addDimension(dim.generateIndexRange(xcodemlDst, false), XbasicType.APPEND);
                }
                break;
            case AFTER:
                for (ClawDimension dim : dimensions) {
                    newType.addDimension(dim.generateIndexRange(xcodemlDst, false), 0);
                }
                break;
            case MIDDLE:
                throw new IllegalTransformationException("Not supported yet. " + "Insertion in middle for duplicated array type.", 0);
        }
    } else {
        newType.resetDimension();
        for (int i = 0; i < base.getDimensions(); ++i) {
            Xnode newDim = new Xnode(Xcode.INDEXRANGE, xcodemlDst);
            newType.append(newDim, false);
            Xnode baseDim = base.getDimensions(i);
            Xnode lowerBound = baseDim.matchSeq(Xcode.LOWERBOUND);
            Xnode upperBound = baseDim.matchSeq(Xcode.UPPERBOUND);
            if (lowerBound != null) {
                Xnode newLowerBound = XnodeUtil.duplicateBound(lowerBound, xcodemlDst, xcodemlSrc);
                newDim.append(newLowerBound, false);
            }
            if (upperBound != null) {
                Xnode newUpperBound = XnodeUtil.duplicateBound(upperBound, xcodemlDst, xcodemlSrc);
                newDim.append(newUpperBound, false);
            }
            newType.addDimension(newDim, XbasicType.APPEND);
        }
    }
    xcodemlDst.getTypeTable().add(newType);
    return type;
}
Also used : ClawDimension(cx2x.translator.language.common.ClawDimension) IllegalTransformationException(cx2x.xcodeml.exception.IllegalTransformationException)

Example 2 with ClawDimension

use of cx2x.translator.language.common.ClawDimension in project claw-compiler by C2SM-RCM.

the class TransformationHelper method updateModuleSignature.

/**
   * Update the function signature in the module file to reflects local changes.
   *
   * @param xcodeml     Current XcodeML file unit.
   * @param fctDef      Function definition that has been changed.
   * @param fctType     Function type that has been changed.
   * @param modDef      Module definition holding the function definition.
   * @param claw        Pragma that has triggered the transformation.
   * @param transformer Current transformer object.
   * @throws IllegalTransformationException If the module file or the function
   *                                        cannot be located
   */
public static void updateModuleSignature(XcodeProgram xcodeml, XfunctionDefinition fctDef, XfunctionType fctType, XmoduleDefinition modDef, ClawLanguage claw, cx2x.xcodeml.transformation.Transformer transformer, boolean importFctType) throws IllegalTransformationException {
    Xmod mod;
    if (transformer.getModCache().isModuleLoaded(modDef.getName())) {
        mod = transformer.getModCache().get(modDef.getName());
    } else {
        mod = fctDef.findContainingModule();
        if (mod == null) {
            throw new IllegalTransformationException("Unable to locate module file for: " + modDef.getName(), claw.getPragma().lineNo());
        }
        transformer.getModCache().add(modDef.getName(), mod);
    }
    XfunctionType fctTypeMod;
    if (importFctType) {
        Node rawNode = mod.getDocument().importNode(fctType.element(), true);
        mod.getTypeTable().element().appendChild(rawNode);
        XfunctionType importedFctType = new XfunctionType((Element) rawNode);
        Xid importedFctTypeId = mod.createId(importedFctType.getType(), Xname.SCLASS_F_FUNC, fctDef.getName().value());
        mod.getIdentifiers().add(importedFctTypeId);
        // check if params need to be imported as well
        if (importedFctType.getParameterNb() > 0) {
            for (Xnode param : importedFctType.getParams().getAll()) {
                mod.importType(xcodeml, param.getAttribute(Xattr.TYPE));
            }
        }
        return;
    } else {
        fctTypeMod = (XfunctionType) mod.getTypeTable().get(fctDef.getName().getAttribute(Xattr.TYPE));
    }
    if (fctTypeMod == null) {
        /* Workaround for a bug in OMNI Compiler. Look at test case
       * claw/abstraction12. In this test case, the XcodeML/F intermediate
       * representation for the function call points to a FfunctionType element
       * with no parameters. Thus, we have to matchSeq the correct FfunctionType
       * for the same function/subroutine with the same name in the module
       * symbol table. */
        String errorMsg = "Unable to locate fct " + fctDef.getName().value() + " in module " + modDef.getName();
        int lineNo = claw.getPragma().lineNo();
        // If not, try to matchSeq the correct FfunctionType in the module definitions
        Xid id = mod.getIdentifiers().get(fctDef.getName().value());
        if (id == null) {
            throw new IllegalTransformationException(errorMsg, lineNo);
        }
        fctTypeMod = (XfunctionType) mod.getTypeTable().get(id.getType());
        if (fctTypeMod == null) {
            throw new IllegalTransformationException(errorMsg, lineNo);
        }
    }
    XbasicType modIntTypeIntentIn = mod.createBasicType(mod.getTypeTable().generateIntegerTypeHash(), Xname.TYPE_F_INT, Xintent.IN);
    mod.getTypeTable().add(modIntTypeIntentIn);
    List<Xnode> paramsLocal = fctType.getParams().getAll();
    List<Xnode> paramsMod = fctTypeMod.getParams().getAll();
    if (paramsLocal.size() < paramsMod.size()) {
        throw new IllegalTransformationException("Local function has more parameters than module counterpart.", claw.getPragma().lineNo());
    }
    for (int i = 0; i < paramsLocal.size(); ++i) {
        Xnode pLocal = paramsLocal.get(i);
        // Number of parameters in the module function as been
        if (pLocal.getBooleanAttribute(ClawAttr.IS_CLAW.toString())) {
            // new parameter
            Xnode param = mod.createAndAddParamIfNotExists(pLocal.value(), modIntTypeIntentIn.getType(), fctTypeMod);
            if (param != null) {
                param.setAttribute(ClawAttr.IS_CLAW.toString(), Xname.TRUE);
            }
        } else {
            Xnode pMod = paramsMod.get(i);
            String localType = pLocal.getAttribute(Xattr.TYPE);
            String modType = pMod.getAttribute(Xattr.TYPE);
            if (!localType.equals(modType)) {
                // Param has been update so have to replicate the change to mod file
                XbasicType lType = (XbasicType) xcodeml.getTypeTable().get(localType);
                XbasicType crtType = (XbasicType) mod.getTypeTable().get(modType);
                List<ClawDimension> dimensions = TransformationHelper.findDimensions(fctType);
                OverPosition overPos = OverPosition.fromString(pLocal.getAttribute(ClawAttr.OVER.toString()));
                if (lType.isArray()) {
                    String newType = TransformationHelper.duplicateWithDimension(lType, crtType, mod, xcodeml, overPos, dimensions);
                    pMod.setAttribute(Xattr.TYPE, newType);
                }
            }
            // Propagate the over attribute
            copyAttribute(pLocal, pMod, ClawAttr.OVER);
        }
    }
}
Also used : OverPosition(cx2x.translator.language.common.OverPosition) Node(org.w3c.dom.Node) ClawDimension(cx2x.translator.language.common.ClawDimension) IllegalTransformationException(cx2x.xcodeml.exception.IllegalTransformationException)

Example 3 with ClawDimension

use of cx2x.translator.language.common.ClawDimension in project claw-compiler by C2SM-RCM.

the class TransformationHelper method promoteField.

/**
   * Promote a field with the information stored in the defined dimensions.
   *
   * @param fieldId   Id of the field as defined in the symbol table.
   * @param update    If true, update current type otherwise, create a type from
   *                  scratch.
   * @param assumed   If true, generate assumed dimension range, otherwise, use
   *                  the information in the defined dimension.
   * @param overIndex Over clause to be used for promotion.
   * @param xcodeml   Current XcodeML program unit in which the element will be
   *                  created.
   * @param overPos   Force behavior as if over clause is present.
   * @throws IllegalTransformationException If type cannot be found.
   */
public static PromotionInfo promoteField(String fieldId, boolean update, boolean assumed, int overIndex, int overDimensions, XfunctionDefinition fctDef, XfunctionType fctType, List<ClawDimension> dimensions, ClawLanguage claw, XcodeProgram xcodeml, OverPosition overPos) throws IllegalTransformationException {
    Xid id = fctDef.getSymbolTable().get(fieldId);
    Xdecl decl = fctDef.getDeclarationTable().get(fieldId);
    String type = xcodeml.getTypeTable().generateArrayTypeHash();
    XbasicType newType;
    if (update) {
        if (XnodeUtil.isBuiltInType(id.getType())) {
            newType = xcodeml.createBasicType(type, id.getType(), Xintent.NONE);
        } else {
            XbasicType old = (XbasicType) xcodeml.getTypeTable().get(id.getType());
            if (old == null) {
                throw new IllegalTransformationException("Cannot matchSeq type for " + fieldId, claw.getPragma().lineNo());
            } else {
                newType = old.cloneNode();
                newType.setType(type);
            }
        }
    } else {
        newType = xcodeml.createBasicType(type, id.getType(), Xintent.NONE);
    }
    PromotionInfo proInfo = new PromotionInfo(fieldId, newType.getDimensions(), newType.getDimensions() + dimensions.size(), type);
    if (assumed) {
        if (newType.isAllAssumedShape() && (fctType.hasParam(fieldId) || newType.isPointer())) {
            for (int i = 0; i < overDimensions; ++i) {
                Xnode index = xcodeml.createEmptyAssumedShaped();
                newType.addDimension(index, 0);
            }
        } else {
            if (claw.hasOverClause() || overPos != null) {
                /* If the directive has an over clause, there is three possibility to
           * insert the newly defined dimensions.
           * 1. Insert the dimensions in the middle on currently existing ones.
           * 2. Insert the dimensions before currently existing ones.
           * 3. Insert the dimensions after currently existing ones. */
                if (overPos == null) {
                    overPos = getOverPosition(claw.getOverClauseValues().get(overIndex));
                }
                if (overPos == OverPosition.MIDDLE) {
                    // Insert new dimension in middle (case 1)
                    int startIdx = 1;
                    for (ClawDimension dim : dimensions) {
                        Xnode index = dim.generateIndexRange(xcodeml, false);
                        newType.addDimension(index, startIdx++);
                    }
                } else if (overPos == OverPosition.AFTER) {
                    // Insert new dimensions at the end (case 3)
                    for (ClawDimension dim : dimensions) {
                        Xnode index = dim.generateIndexRange(xcodeml, false);
                        newType.addDimension(index, XbasicType.APPEND);
                    }
                } else {
                    // Insert new dimension at the beginning (case 2)
                    for (ClawDimension dim : dimensions) {
                        Xnode index = dim.generateIndexRange(xcodeml, false);
                        newType.addDimension(index, 0);
                    }
                }
            } else {
                for (ClawDimension dim : dimensions) {
                    Xnode index = dim.generateIndexRange(xcodeml, false);
                    newType.addDimension(index, 0);
                }
            }
        }
    } else {
        for (ClawDimension dim : dimensions) {
            Xnode index = dim.generateIndexRange(xcodeml, false);
            newType.addDimension(index, XbasicType.APPEND);
        }
    }
    id.setType(type);
    decl.matchSeq(Xcode.NAME).setAttribute(Xattr.TYPE, type);
    xcodeml.getTypeTable().add(newType);
    // Update params in function type
    for (Xnode param : fctType.getParams().getAll()) {
        if (param.value().equals(fieldId)) {
            // Update type with new promoted type
            param.setAttribute(Xattr.TYPE, type);
            // Save the over clause for parallelize forward transformation
            if (claw.hasOverClause()) {
                param.setAttribute(ClawAttr.OVER.toString(), getOverPosition(claw.getOverClauseValues().get(overIndex)).toString());
            }
        }
    }
    if (fctType.hasAttribute(Xattr.RESULT_NAME) && fctType.getAttribute(Xattr.RESULT_NAME).equals(fieldId)) {
        if (claw.hasOverClause()) {
            fctType.setAttribute(ClawAttr.OVER.toString(), getOverPosition(claw.getOverClauseValues().get(overIndex)).toString());
        }
    }
    return proInfo;
}
Also used : ClawDimension(cx2x.translator.language.common.ClawDimension) IllegalTransformationException(cx2x.xcodeml.exception.IllegalTransformationException) PromotionInfo(cx2x.translator.transformation.claw.parallelize.PromotionInfo)

Example 4 with ClawDimension

use of cx2x.translator.language.common.ClawDimension in project claw-compiler by C2SM-RCM.

the class Parallelize method insertVariableToIterateOverDimension.

/**
   * Insert the declaration of the different variables needed to iterate over
   * the additional dimensions.
   *
   * @param xcodeml Current XcodeML program unit in which element are
   *                created.
   */
private void insertVariableToIterateOverDimension(XcodeProgram xcodeml) {
    // Create type and declaration for iterations over the new dimensions
    XbasicType intTypeIntentIn = xcodeml.createBasicType(xcodeml.getTypeTable().generateIntegerTypeHash(), Xname.TYPE_F_INT, Xintent.IN);
    xcodeml.getTypeTable().add(intTypeIntentIn);
    // For each dimension defined in the directive
    for (ClawDimension dimension : _claw.getDimensionValues()) {
        // Create the parameter for the lower bound
        if (dimension.lowerBoundIsVar()) {
            xcodeml.createIdAndDecl(dimension.getLowerBoundId(), intTypeIntentIn.getType(), Xname.SCLASS_F_PARAM, _fctDef);
            // Add parameter to the local type table
            Xnode param = xcodeml.createAndAddParam(dimension.getLowerBoundId(), intTypeIntentIn.getType(), _fctType);
            param.setAttribute(ClawAttr.IS_CLAW.toString(), Xname.TRUE);
        }
        // Create parameter for the upper bound
        if (dimension.upperBoundIsVar()) {
            xcodeml.createIdAndDecl(dimension.getUpperBoundId(), intTypeIntentIn.getType(), Xname.SCLASS_F_PARAM, _fctDef);
            // Add parameter to the local type table
            Xnode param = xcodeml.createAndAddParam(dimension.getUpperBoundId(), intTypeIntentIn.getType(), _fctType);
            param.setAttribute(ClawAttr.IS_CLAW.toString(), Xname.TRUE);
        }
        // Create induction variable declaration
        xcodeml.createIdAndDecl(dimension.getIdentifier(), Xname.TYPE_F_INT, Xname.SCLASS_F_LOCAL, _fctDef);
    }
}
Also used : ClawDimension(cx2x.translator.language.common.ClawDimension)

Example 5 with ClawDimension

use of cx2x.translator.language.common.ClawDimension in project claw-compiler by C2SM-RCM.

the class Parallelize method transformForCPU.

/**
   * Apply CPU based transformations.
   *
   * @param xcodeml Current XcodeML program unit.
   * @throws IllegalTransformationException If promotion of arrays fails.
   */
private void transformForCPU(XcodeProgram xcodeml) throws IllegalTransformationException {
    /* Create a group of nested loop with the newly defined dimension and wrap
     * every assignment statement in the column loop or including data with it.
     * This is for the moment a really naive transformation idea but it is our
     * start point.
     * Use the first over clause to do it. */
    List<ClawDimension> order = getOrderedDimensionsFromDefinition(0);
    List<Xnode> assignStatements = _fctDef.body().matchAll(Xcode.FASSIGNSTATEMENT);
    for (Xnode assign : assignStatements) {
        Xnode lhs = assign.child(Xnode.LHS);
        String lhsName = (lhs.opcode() == Xcode.VAR) ? lhs.value() : lhs.matchSeq(Xcode.VARREF, Xcode.VAR).value();
        NestedDoStatement loops = null;
        if (lhs.opcode() == Xcode.FARRAYREF && _arrayFieldsInOut.contains(lhsName)) {
            loops = new NestedDoStatement(order, xcodeml);
            assign.insertAfter(loops.getOuterStatement());
            loops.getInnerStatement().body().append(assign, true);
            assign.delete();
        } else if (lhs.opcode() == Xcode.VAR || lhs.opcode() == Xcode.FARRAYREF && _scalarFields.contains(lhsName)) {
            /* If the assignment is in the column loop and is composed with some
         * promoted variables, the field must be promoted and the var reference
         * switch to an array reference */
            if (shouldBePromoted(assign)) {
                if (!_arrayFieldsInOut.contains(lhsName)) {
                    _arrayFieldsInOut.add(lhsName);
                    PromotionInfo promotionInfo;
                    if (lhs.opcode() == Xcode.VAR) {
                        // Scalar to array
                        promotionInfo = TransformationHelper.promoteField(lhsName, false, false, DEFAULT_OVER, _overDimensions, _fctDef, _fctType, _claw.getDimensionValues(), _claw, xcodeml, null);
                    } else {
                        // Array to array
                        promotionInfo = TransformationHelper.promoteField(lhsName, true, true, DEFAULT_OVER, _overDimensions, _fctDef, _fctType, _claw.getDimensionValues(), _claw, xcodeml, null);
                    }
                    _promotions.put(lhsName, promotionInfo);
                }
                if (lhs.opcode() == Xcode.VAR) {
                    adaptScalarRefToArrayReferences(xcodeml, Collections.singletonList(lhsName), DEFAULT_OVER);
                } else {
                    TransformationHelper.adaptArrayReferences(Collections.singletonList(lhsName), DEFAULT_OVER, _fctDef.body(), _promotions, _beforeCrt, _inMiddle, _afterCrt, xcodeml);
                }
                loops = new NestedDoStatement(order, xcodeml);
                assign.insertAfter(loops.getOuterStatement());
                loops.getInnerStatement().body().append(assign, true);
                assign.delete();
            }
        }
        if (loops != null) {
            // Generate the corresponding directive around the loop
            AcceleratorHelper.generateLoopDirectives(_claw, xcodeml, loops.getOuterStatement(), loops.getOuterStatement(), AcceleratorHelper.NO_COLLAPSE);
        }
    }
    // Generate the parallel region
    AcceleratorHelper.generateParallelClause(_claw, xcodeml, _fctDef.body().firstChild(), _fctDef.body().lastChild());
}
Also used : ClawDimension(cx2x.translator.language.common.ClawDimension) NestedDoStatement(cx2x.translator.common.NestedDoStatement)

Aggregations

ClawDimension (cx2x.translator.language.common.ClawDimension)10 IllegalTransformationException (cx2x.xcodeml.exception.IllegalTransformationException)6 OverPosition (cx2x.translator.language.common.OverPosition)3 NestedDoStatement (cx2x.translator.common.NestedDoStatement)2 PromotionInfo (cx2x.translator.transformation.claw.parallelize.PromotionInfo)1 List (java.util.List)1 Test (org.junit.Test)1 Node (org.w3c.dom.Node)1