Search in sources :

Example 26 with IllegalTransformationException

use of claw.tatsu.xcodeml.exception.IllegalTransformationException in project claw-compiler by C2SM-RCM.

the class ScaGPU method transformElemental.

/**
 * Apply transformation on ELEMENTAL function/subroutine.
 *
 * @param xcodeml    Current translation unit.
 * @param translator Current translator.
 * @throws IllegalTransformationException If transformation fails.
 */
private void transformElemental(XcodeProgram xcodeml, ClawTranslator translator) throws Exception {
    /*
         * SCA in ELEMENTAL function. Only flag the function and leave the actual
         * transformation until having information on the calling site from another
         * translation unit.
         */
    if (_fctType.isElemental()) {
        _fctType.setBooleanAttribute(Xattr.WAS_ELEMENTAL, true);
        if (_fctType.isFunction() && !_fctType.hasAttribute(Xattr.RESULT_NAME)) {
            _arrayFieldsInOut.add(_fctDef.getName());
        }
        if (translator.cfg().getBooleanParameter(Configuration.SCA_ELEMENTAL_PROMOTION_ASSUMED)) {
            forceAssumedShapedArrayPromotion = _fctType.isSubroutine() || !(_arrayFieldsInOut.contains(_fctType.getResultName()) || _arrayFieldsInOut.contains(_fctDef.getName()));
        }
        // SCA ELEMENTAL
        FmoduleDefinition modDef = _fctDef.findParentModule();
        if (modDef == null) {
            throw new IllegalTransformationException("SCA in ELEMENTAL function " + "transformation requires module encapsulation.");
        }
        transformReturnStatement(xcodeml);
        // Apply the common transformation
        super.transform(xcodeml, translator, null);
        // Remove ELEMENTAL and PURE attributes if present.
        removeAttributesWithWaring(xcodeml, _fctType, Xattr.IS_ELEMENTAL);
        removeAttributesWithWaring(xcodeml, _fctType, Xattr.IS_PURE);
        // Apply specific steps for GPU
        applySpecificTransformation(translator.cfg(), xcodeml);
        // Finalize the common steps
        super.finalizeTransformation(xcodeml);
    }
}
Also used : IllegalTransformationException(claw.tatsu.xcodeml.exception.IllegalTransformationException) FmoduleDefinition(claw.tatsu.xcodeml.xnode.fortran.FmoduleDefinition)

Example 27 with IllegalTransformationException

use of claw.tatsu.xcodeml.exception.IllegalTransformationException in project claw-compiler by C2SM-RCM.

the class LoopExtraction method transform.

/**
 * Apply the transformation. A loop extraction is applied in the following
 * steps: 1) Duplicate the function targeted by the transformation 2) Extract
 * the loop body in the duplicated function and remove the loop. 3) Adapt
 * function call and demote array references in the duplicated function body. 4)
 * Optional: Add a LoopFusion transformation to the transformations' queue.
 *
 * @param xcodeml        The XcodeML on which the transformations are applied.
 * @param translator     The translator used to applied the transformations.
 * @param transformation Only for dependent transformation. The other
 *                       transformation part of the transformation.
 * @throws IllegalTransformationException if the transformation cannot be
 *                                        applied.
 */
@Override
public void transform(XcodeProgram xcodeml, Translator translator, Transformation transformation) throws Exception {
    ClawTranslator ct = (ClawTranslator) translator;
    final Context context = ct.context();
    /*
         * DUPLICATE THE FUNCTION
         */
    // Duplicate function definition
    FfunctionDefinition clonedFctDef = _fctDefToExtract.cloneNode();
    String newFctTypeHash = xcodeml.getTypeTable().generateHash(FortranType.FUNCTION);
    String newFctName = clonedFctDef.getName() + ClawConstant.EXTRACTION_SUFFIX + translator.getNextTransformationCounter();
    clonedFctDef.name().setValue(newFctName);
    clonedFctDef.name().setType(newFctTypeHash);
    // Update the symbol table in the fct definition
    Xid fctId = clonedFctDef.getSymbolTable().get(_fctDefToExtract.getName());
    fctId.setType(newFctTypeHash);
    fctId.setName(newFctName);
    // Get the fctType in typeTable
    FfunctionType fctType = xcodeml.getTypeTable().getFunctionType(_fctDefToExtract);
    FfunctionType newFctType = fctType.cloneNode();
    newFctType.setType(newFctTypeHash);
    xcodeml.getTypeTable().add(newFctType);
    // Get the id from the global symbols table
    Xid globalFctId = xcodeml.getGlobalSymbolsTable().get(_fctDefToExtract.getName());
    // If the fct is define in the global symbol table, duplicate it
    if (globalFctId != null) {
        Xid newFctId = globalFctId.cloneNode();
        newFctId.setType(newFctTypeHash);
        newFctId.setName(newFctName);
        xcodeml.getGlobalSymbolsTable().add(newFctId);
    }
    // Insert the duplicated function declaration
    _fctDefToExtract.insertAfter(clonedFctDef);
    // Find the loop that will be extracted
    Xnode loopInClonedFct = locateDoStatement(clonedFctDef);
    Message.debug(context, "loop-extract transformation: " + _claw.getPragma().value());
    Message.debug(context, "  created subroutine: " + clonedFctDef.getName());
    /*
         * REMOVE BODY FROM THE LOOP AND DELETE THE LOOP
         */
    // 1. append body into fct body after loop
    Loop.extractBody(loopInClonedFct);
    // 2. delete loop
    loopInClonedFct.delete();
    /*
         * ADAPT FUNCTION CALL AND DEMOTE ARRAY REFERENCES IN THE BODY OF THE FUNCTION
         */
    // Wrap function call with loop
    Xnode extractedLoop = wrapCallWithLoop(xcodeml, _extractedLoop);
    Message.debug(context, "  call wrapped with loop: " + _fctCall.matchDirectDescendant(Xcode.NAME).value() + " --> " + clonedFctDef.getName());
    // Change called fct name
    _fctCall.matchDirectDescendant(Xcode.NAME).setValue(newFctName);
    _fctCall.matchDirectDescendant(Xcode.NAME).setType(newFctTypeHash);
    // Adapt function call parameters and function declaration
    XdeclTable fctDeclarations = clonedFctDef.getDeclarationTable();
    XsymbolTable fctSymbols = clonedFctDef.getSymbolTable();
    Message.debug(context, "  Start to apply mapping: " + _claw.getMappings().size());
    for (ClawMapping mapping : _claw.getMappings()) {
        Message.debug(context, "Apply mapping (" + mapping.getMappedDimensions() + ") ");
        for (ClawMappingVar var : mapping.getMappedVariables()) {
            Message.debug(context, "  Var: " + var);
            Optional<Xnode> argument = _fctCall.findArg(var.getArgMapping());
            if (!argument.isPresent()) {
                continue;
            }
            /*
                 * Case 1: Var --> ArrayRef Var --> ArrayRef transformation 1. Check that the
                 * variable used as array index exists in the current scope (XdeclTable). If so,
                 * get its type value. Create a Var element for the arrayIndex. Create the
                 * arrayIndex element with Var as child.
                 *
                 * 2. Get the reference type of the base variable. 2.1 Create the varRef element
                 * with the type of base variable 2.2 insert clone of base variable in varRef 3.
                 * Create arrayRef element with varRef + arrayIndex
                 */
            if (argument.get().is(Xcode.VAR)) {
                FbasicType type = xcodeml.getTypeTable().getBasicType(argument.get());
                // Demotion cannot be applied as type dimension is smaller
                if (type.getDimensions() < mapping.getMappedDimensions()) {
                    throw new IllegalTransformationException("mapping dimensions too big. Mapping " + mapping.toString() + " is wrong ...", _claw.getPragma().lineNo());
                }
                Xnode newArg = xcodeml.createNode(Xcode.F_ARRAY_REF);
                newArg.setType(type.getRef());
                Xnode varRef = xcodeml.createNode(Xcode.VAR_REF);
                varRef.setType(argument.get().getType());
                varRef.append(argument.get(), true);
                newArg.append(varRef);
                // create arrayIndex
                for (ClawMappingVar mappingVar : mapping.getMappingVariables()) {
                    Xnode arrayIndex = xcodeml.createNode(Xcode.ARRAY_INDEX);
                    // Find the mapping var in the local table (fct scope)
                    Xnode mappingVarDecl = _fctDef.getDeclarationTable().get(mappingVar.getArgMapping());
                    // Add to arrayIndex
                    Xnode newMappingVar = xcodeml.createVar(mappingVarDecl.getType(), mappingVarDecl.matchSeq(Xcode.NAME).value(), Xscope.LOCAL);
                    arrayIndex.append(newMappingVar);
                    newArg.append(arrayIndex);
                }
                argument.get().insertAfter(newArg);
                argument.get().delete();
            }
            // Case 2: ArrayRef (n arrayIndex) --> ArrayRef (n+m arrayIndex)
            // Change variable declaration in extracted fct
            Xnode varDecl = fctDeclarations.get(var.getFctMapping());
            Xid id = fctSymbols.get(var.getFctMapping());
            FbasicType varDeclType = xcodeml.getTypeTable().getBasicType(varDecl);
            // Case 1: variable is demoted to scalar then take the ref type
            if (varDeclType.getDimensions() == mapping.getMappedDimensions()) {
                Xnode newVarDecl = xcodeml.createNode(Xcode.VAR_DECL);
                newVarDecl.append(xcodeml.createName(var.getFctMapping(), varDeclType.getRef()));
                fctDeclarations.replace(newVarDecl, var.getFctMapping());
                id.setType(varDeclType.getRef());
            }
        }
    // Loop mapped variables
    }
    // Loop over mapping clauses
    // Adapt array reference in function body
    List<Xnode> arrayReferences = clonedFctDef.body().matchAll(Xcode.F_ARRAY_REF);
    for (Xnode ref : arrayReferences) {
        if (!Xnode.isOfCode(ref.matchSeq(Xcode.VAR_REF).child(0), Xcode.VAR)) {
            continue;
        }
        String mappedVar = ref.matchSeq(Xcode.VAR_REF, Xcode.VAR).value();
        if (_fctMappingMap.containsKey(mappedVar)) {
            ClawMapping mapping = _fctMappingMap.get(mappedVar);
            boolean changeRef = true;
            int mappingIndex = 0;
            for (Xnode e : ref.children()) {
                if (e.is(Xcode.ARRAY_INDEX)) {
                    List<Xnode> children = e.children();
                    if (!children.isEmpty() && Xnode.isOfCode(children.get(0), Xcode.VAR)) {
                        String varName = e.matchSeq(Xcode.VAR).value();
                        if (varName.equals(mapping.getMappingVariables().get(mappingIndex).getFctMapping())) {
                            ++mappingIndex;
                        } else {
                            changeRef = false;
                        }
                    }
                }
            }
            if (changeRef) {
                // TODO Var ref should be extracted only if the reference can be
                // totally demoted
                ref.insertBefore(ref.matchSeq(Xcode.VAR_REF, Xcode.VAR).cloneNode());
                ref.delete();
            }
        }
    }
    // Generate directive pragmas if needed
    Xnode grip = null;
    if (_claw.hasClause(ClawClause.ACC)) {
        /*
             * TODO see TODO in ExpandNotation OpenACC and OpenMP loop construct are pretty
             * different ... have to look how to do that properly. See issue #22
             */
        grip = Directive.generateAcceleratorClause(xcodeml, extractedLoop, _claw.value(ClawClause.ACC));
    }
    if (_claw.hasClause(ClawClause.PARALLEL)) {
        Directive.generateParallelRegion(xcodeml, (grip == null) ? extractedLoop : grip, extractedLoop);
    }
    // TODO must be triggered by a clause
    // Directive.generateRoutineDirectives(_claw, xcodeml, clonedFctDef);
    // Add any additional transformation defined in the directive clauses
    ct.generateAdditionalTransformation(_claw, xcodeml, extractedLoop);
    removePragma();
    transformed();
}
Also used : Context(claw.tatsu.common.Context) FfunctionType(claw.tatsu.xcodeml.xnode.fortran.FfunctionType) ClawMappingVar(claw.wani.language.ClawMappingVar) FbasicType(claw.tatsu.xcodeml.xnode.fortran.FbasicType) Xnode(claw.tatsu.xcodeml.xnode.common.Xnode) Xid(claw.tatsu.xcodeml.xnode.common.Xid) FfunctionDefinition(claw.tatsu.xcodeml.xnode.fortran.FfunctionDefinition) IllegalTransformationException(claw.tatsu.xcodeml.exception.IllegalTransformationException) XsymbolTable(claw.tatsu.xcodeml.xnode.common.XsymbolTable) ClawTranslator(claw.wani.x2t.translator.ClawTranslator) ClawMapping(claw.wani.language.ClawMapping) XdeclTable(claw.tatsu.xcodeml.xnode.common.XdeclTable)

Example 28 with IllegalTransformationException

use of claw.tatsu.xcodeml.exception.IllegalTransformationException in project claw-compiler by C2SM-RCM.

the class LoopHoist method transform.

/**
 * @see Transformation#transform(XcodeProgram, Translator, Transformation)
 */
@Override
public void transform(XcodeProgram xcodeml, Translator translator, Transformation transformation) throws Exception {
    ClawTranslator ct = (ClawTranslator) translator;
    HoistedNestedDoStatement hoisted = Loop.hoist(_hoistedGroups, _clawStart.getPragma(), _clawEnd.getPragma(), xcodeml);
    // Generate dynamic transformation (interchange)
    ct.generateAdditionalTransformation(_clawStart, xcodeml, hoisted.getOuterStatement());
    // Apply cleanup clause
    if (_clawStart.hasClause(ClawClause.CLEANUP)) {
        Pragma.remove(_clawStart.getCleanupClauseValue(), _clawStart.getPragma(), _clawEnd.getPragma());
    }
    // Apply reshape clause
    if (_clawStart.hasClause(ClawClause.RESHAPE)) {
        FfunctionDefinition fctDef = _clawStart.getPragma().findParentFunction();
        if (fctDef == null) {
            throw new IllegalTransformationException("Cannot apply reshape clause." + "Parent function definition not found.", _clawStart.getPragma().lineNo());
        }
        for (ReshapeInfo reshapeInfo : _clawStart.getReshapeClauseValues()) {
            Field.reshape(fctDef, reshapeInfo, xcodeml);
        }
    }
    removePragma();
}
Also used : FfunctionDefinition(claw.tatsu.xcodeml.xnode.fortran.FfunctionDefinition) IllegalTransformationException(claw.tatsu.xcodeml.exception.IllegalTransformationException) ClawTranslator(claw.wani.x2t.translator.ClawTranslator) HoistedNestedDoStatement(claw.tatsu.xcodeml.abstraction.HoistedNestedDoStatement) ReshapeInfo(claw.tatsu.xcodeml.abstraction.ReshapeInfo)

Example 29 with IllegalTransformationException

use of claw.tatsu.xcodeml.exception.IllegalTransformationException in project claw-compiler by C2SM-RCM.

the class ScaForward method propagatePromotion.

/**
 * Propagate possible promotion in assignments statements in the parent
 * subroutine of the function call.
 *
 * @param xcodeml    Current XcodeML program unit.
 * @param translator Current translator to store information between
 *                   transformation.
 */
private void propagatePromotion(XcodeProgram xcodeml, ClawTranslator translator) throws IllegalTransformationException {
    // Get all the assignment statements in the function definition
    FfunctionDefinition parentFctDef = _fCall.findParentFunction();
    // Retrieve information of previous forward transformation in the same fct
    List<String> previouslyPromoted = Utility.convertToList(translator.hasElement(parentFctDef));
    List<Xnode> assignments = parentFctDef.matchAll(Xcode.F_ASSIGN_STATEMENT);
    // Find promotion info that can be used.
    // TODO define how default promotion is encoded in xmod file. For the
    // TODO moment using the first information found in fctType.
    PromotionInfo defaultInfo = Function.readPromotionInfo(_fctType, InsertionPosition.BEFORE);
    for (Xnode assignment : assignments) {
        Xnode lhs = assignment.child(0);
        Xnode rhs = assignment.child(1);
        List<Xnode> varsInRhs = rhs.matchAll(Xcode.VAR);
        for (Xnode var : varsInRhs) {
            // Check if the assignment statement uses a promoted variable
            if (_promotedVar.contains(var.value()) && var.matchAncestor(Xcode.FUNCTION_CALL) == null && Xnode.isOfCode(lhs, Xcode.F_ARRAY_REF)) {
                Xnode varInLhs = lhs.matchDescendant(Xcode.VAR);
                if (varInLhs == null) {
                    throw new IllegalTransformationException("Unable to propagate " + "promotion. Internal error.", _claw.getPragma().lineNo());
                }
                // Declare the induction variable if they are not present
                for (DimensionDefinition dim : defaultInfo.getDimensions()) {
                    if (parentFctDef.getDeclarationTable().get(dim.getIdentifier()) == null) {
                        xcodeml.createIdAndDecl(dim.getIdentifier(), FortranType.INTEGER, XstorageClass.F_LOCAL, parentFctDef, DeclarationPosition.LAST);
                    }
                }
                // Generate the do statements and move the assignment statement in
                NestedDoStatement doStmt = new NestedDoStatement(defaultInfo.getDimensions(), xcodeml);
                assignment.insertAfter(doStmt.getOuterStatement());
                doStmt.getInnerStatement().body().append(assignment);
                PromotionInfo promotionInfo;
                if (!previouslyPromoted.contains(varInLhs.value())) {
                    // Perform the promotion on the variable
                    promotionInfo = new PromotionInfo(varInLhs.value(), defaultInfo.getDimensions());
                    Field.promote(promotionInfo, parentFctDef, xcodeml);
                    _promotions.put(promotionInfo.getIdentifier(), promotionInfo);
                } else {
                    promotionInfo = _promotions.get(varInLhs.value());
                }
                _promotedVar.add(varInLhs.value());
                // Adapt the reference in the assignment statement
                for (String id : _promotedVar) {
                    _promotions.get(id).resetFlags();
                    Field.adaptArrayRef(_promotions.get(id), assignment, false, xcodeml);
                }
                // If the array is a target, check if we have to promote a pointer
                if (!previouslyPromoted.contains(varInLhs.value())) {
                    Field.adaptPointer(xcodeml, parentFctDef, _promotions, promotionInfo);
                    previouslyPromoted.add(varInLhs.value());
                }
                break;
            /*
                     * if one var in the rhs of the assignment statement was promoted it's enough
                     * and we can switch to the next assignment statement.
                     */
            }
        }
    }
    translator.storeElement(parentFctDef, previouslyPromoted);
}
Also used : Xnode(claw.tatsu.xcodeml.xnode.common.Xnode) FfunctionDefinition(claw.tatsu.xcodeml.xnode.fortran.FfunctionDefinition) IllegalTransformationException(claw.tatsu.xcodeml.exception.IllegalTransformationException) PromotionInfo(claw.tatsu.xcodeml.abstraction.PromotionInfo) NestedDoStatement(claw.tatsu.xcodeml.abstraction.NestedDoStatement) DimensionDefinition(claw.tatsu.xcodeml.abstraction.DimensionDefinition)

Example 30 with IllegalTransformationException

use of claw.tatsu.xcodeml.exception.IllegalTransformationException in project claw-compiler by C2SM-RCM.

the class FieldTest method performAndAssertPromotion.

/**
 * Perform the promotion transformation and assert its result.
 *
 * @param id         Identifier of the field to be promoted.
 * @param dims       Dimension definitions to use.
 * @param fctDef     Function definition in which the promotion is performed.
 * @param xcodeml    Current XcodeML translation unit.
 * @param base       Number of dimension before the promotion.
 * @param target     Number of dimension after the promotion.
 * @param dimensions Expected dimensions after promotion.
 */
private void performAndAssertPromotion(String id, List<DimensionDefinition> dims, FfunctionDefinition fctDef, XcodeProgram xcodeml, int base, int target, int[] dimensions) {
    try {
        int diff = target - base;
        PromotionInfo promotionInfo = new PromotionInfo(id);
        promotionInfo.setDimensions(dims);
        Xnode decl = fctDef.getDeclarationTable().get(id);
        assertNotNull(decl);
        FbasicType bt;
        if (base != 0) {
            bt = xcodeml.getTypeTable().getBasicType(decl);
            assertNotNull(bt);
            assertTrue(bt.isArray());
            assertEquals(base, bt.getDimensions());
        } else {
            assertEquals(FortranType.REAL, FortranType.fromString(decl.getType()));
        }
        // Perform the promotion
        Field.promote(promotionInfo, fctDef, xcodeml);
        decl = fctDef.getDeclarationTable().get(id);
        assertNotNull(decl);
        bt = xcodeml.getTypeTable().getBasicType(decl);
        assertNotNull(bt);
        assertTrue(bt.isArray());
        assertEquals(target, bt.getDimensions());
        assertEquals(target, dimensions.length / 2);
        assertEquals(target, promotionInfo.getTargetDimension());
        assertEquals(base, promotionInfo.getBaseDimension());
        assertEquals(diff, promotionInfo.diffDimension());
        assertEquals(bt.getType(), promotionInfo.getTargetType().getType());
        if (base > 0) {
            assertEquals(PromotionInfo.PromotionType.ARRAY_TO_ARRAY, promotionInfo.getPromotionType());
        } else {
            assertEquals(PromotionInfo.PromotionType.SCALAR_TO_ARRAY, promotionInfo.getPromotionType());
        }
        for (int i = 0; i < dimensions.length / 2; ++i) {
            assertDimension(bt.getDimensions(i), dimensions[i * 2], dimensions[(i * 2) + 1]);
        }
    } catch (IllegalTransformationException itex) {
        System.err.println(itex.getMessage());
        fail();
    }
}
Also used : Xnode(claw.tatsu.xcodeml.xnode.common.Xnode) IllegalTransformationException(claw.tatsu.xcodeml.exception.IllegalTransformationException) PromotionInfo(claw.tatsu.xcodeml.abstraction.PromotionInfo) FbasicType(claw.tatsu.xcodeml.xnode.fortran.FbasicType)

Aggregations

IllegalTransformationException (claw.tatsu.xcodeml.exception.IllegalTransformationException)33 Xnode (claw.tatsu.xcodeml.xnode.common.Xnode)23 FfunctionDefinition (claw.tatsu.xcodeml.xnode.fortran.FfunctionDefinition)11 Context (claw.tatsu.common.Context)10 FbasicType (claw.tatsu.xcodeml.xnode.fortran.FbasicType)7 PromotionInfo (claw.tatsu.xcodeml.abstraction.PromotionInfo)6 ClawTranslator (claw.wani.x2t.translator.ClawTranslator)6 DimensionDefinition (claw.tatsu.xcodeml.abstraction.DimensionDefinition)4 Xblock (claw.tatsu.xcodeml.abstraction.Xblock)4 Xid (claw.tatsu.xcodeml.xnode.common.Xid)4 TestContext (helper.Utils.TestContext)4 Test (org.junit.Test)4 XcodeProgram (claw.tatsu.xcodeml.xnode.common.XcodeProgram)3 FfunctionType (claw.tatsu.xcodeml.xnode.fortran.FfunctionType)3 Configuration (claw.wani.x2t.configuration.Configuration)3 ArrayList (java.util.ArrayList)3 FunctionCall (claw.tatsu.xcodeml.abstraction.FunctionCall)2 NestedDoStatement (claw.tatsu.xcodeml.abstraction.NestedDoStatement)2 IllegalDirectiveException (claw.tatsu.xcodeml.exception.IllegalDirectiveException)2 Xattr (claw.tatsu.xcodeml.xnode.common.Xattr)2