Beispiel #1
0
        /// <summary>
        /// Inserts conditions into the schedule given by the operations list at their earliest possible position
        /// todo: set/map operations are potentially expensive, they shouldn't be insertes asap, but depending an weight,
        /// derived from statistics over set/map size for graph elements, quiet well known for anonymous rule sets
        /// </summary>
        private static void InsertConditionsIntoSchedule(PatternCondition[] conditions, List <SearchOperation> operations, bool lazyNegativeIndependentConditionEvaluation)
        {
            // get needed (in order to evaluate it) elements of each condition
            Dictionary <String, object>[] neededElements = new Dictionary <String, object> [conditions.Length];
            for (int i = 0; i < conditions.Length; ++i)
            {
                neededElements[i] = new Dictionary <string, object>();
                for (int j = 0; j < conditions[i].NeededNodeNames.Length; ++j)
                {
                    String      neededNodeName = conditions[i].NeededNodeNames[j];
                    PatternNode neededNode     = conditions[i].NeededNodes[j];
                    neededElements[i][neededNodeName] = neededNode;
                }
                for (int j = 0; j < conditions[i].NeededEdgeNames.Length; ++j)
                {
                    String      neededEdgeName = conditions[i].NeededEdgeNames[j];
                    PatternEdge neededEdge     = conditions[i].NeededEdges[j];
                    neededElements[i][neededEdgeName] = neededEdge;
                }
                for (int j = 0; j < conditions[i].NeededVariableNames.Length; ++j)
                {
                    String          neededVariableName = conditions[i].NeededVariableNames[j];
                    PatternVariable neededVariable     = conditions[i].NeededVariables[j];
                    neededElements[i][neededVariableName] = neededVariable;
                }
            }

            // iterate over all conditions
            for (int i = 0; i < conditions.Length; ++i)
            {
                int   j;
                float costToEnd = 0;

                // find leftmost place in scheduled search plan for current condition
                // by search from end of schedule forward until the first element the condition is dependent on is found
                for (j = operations.Count - 1; j >= 0; --j)
                {
                    SearchOperation op = operations[j];
                    if (op.Type == SearchOperationType.Condition ||
                        op.Type == SearchOperationType.NegativePattern ||
                        op.Type == SearchOperationType.IndependentPattern ||
                        op.Type == SearchOperationType.DefToBeYieldedTo)
                    {
                        continue;
                    }

                    if (lazyNegativeIndependentConditionEvaluation)
                    {
                        break;
                    }

                    if (op.Type == SearchOperationType.AssignVar)
                    {
                        if (neededElements[i].ContainsKey(((PatternVariable)op.Element).Name))
                        {
                            costToEnd = op.CostToEnd;
                            break;
                        }
                        continue;
                    }

                    if (neededElements[i].ContainsKey(((SearchPlanNode)op.Element).PatternElement.Name))
                    {
                        costToEnd = op.CostToEnd;
                        break;
                    }
                }

                operations.Insert(j + 1, new SearchOperation(SearchOperationType.Condition,
                                                             conditions[i], null, costToEnd));
            }
        }
Beispiel #2
0
        /// <summary>
        /// Inserts inlined variable assignments into the schedule given by the operations list at their earliest possible position
        /// </summary>
        private static void InsertInlinedVariableAssignmentsIntoSchedule(PatternGraph patternGraph, List <SearchOperation> operations)
        {
            // compute the number of inlined parameter variables
            int numInlinedParameterVariables = 0;

            foreach (PatternVariable var in patternGraph.variablesPlusInlined)
            {
                if (var.AssignmentSource != null && patternGraph.WasInlinedHere(var.originalSubpatternEmbedding))
                {
                    ++numInlinedParameterVariables;
                }
            }

            if (numInlinedParameterVariables == 0)
            {
                return;
            }

            // get the inlined parameter variables and the elements needed in order to compute their defining expression
            Dictionary <String, PatternElement>[] neededElements = new Dictionary <String, PatternElement> [numInlinedParameterVariables];
            PatternVariable[] inlinedParameterVariables          = new PatternVariable[numInlinedParameterVariables];
            int curInlParamVar = 0;

            foreach (PatternVariable var in patternGraph.variablesPlusInlined)
            {
                if (var.AssignmentSource == null)
                {
                    continue;
                }
                if (!patternGraph.WasInlinedHere(var.originalSubpatternEmbedding))
                {
                    continue;
                }

                neededElements[curInlParamVar] = new Dictionary <string, PatternElement>();
                for (int i = 0; i < var.AssignmentDependencies.neededNodeNames.Length; ++i)
                {
                    String      neededNodeName = var.AssignmentDependencies.neededNodeNames[i];
                    PatternNode neededNode     = var.AssignmentDependencies.neededNodes[i];
                    neededElements[curInlParamVar][neededNodeName] = neededNode;
                }
                for (int i = 0; i < var.AssignmentDependencies.neededEdgeNames.Length; ++i)
                {
                    String      neededEdgeName = var.AssignmentDependencies.neededEdgeNames[i];
                    PatternEdge neededEdge     = var.AssignmentDependencies.neededEdges[i];
                    neededElements[curInlParamVar][neededEdgeName] = neededEdge;
                }
                inlinedParameterVariables[curInlParamVar] = var;

                ++curInlParamVar;
            }

            // iterate over all inlined parameter variables
            for (int i = 0; i < inlinedParameterVariables.Length; ++i)
            {
                int   j;
                float costToEnd = 0;

                // find leftmost place in scheduled search plan for current assignment
                // by search from end of schedule forward until the first element the expression assigned is dependent on is found
                for (j = operations.Count - 1; j >= 0; --j)
                {
                    SearchOperation op = operations[j];
                    if (op.Type == SearchOperationType.Condition ||
                        op.Type == SearchOperationType.Assign ||
                        op.Type == SearchOperationType.AssignVar ||
                        op.Type == SearchOperationType.NegativePattern ||
                        op.Type == SearchOperationType.IndependentPattern ||
                        op.Type == SearchOperationType.DefToBeYieldedTo)
                    {
                        continue;
                    }

                    if (neededElements[i].ContainsKey(((SearchPlanNode)op.Element).PatternElement.Name))
                    {
                        costToEnd = op.CostToEnd;
                        break;
                    }
                }

                SearchOperation so = new SearchOperation(SearchOperationType.AssignVar,
                                                         inlinedParameterVariables[i], null, costToEnd);
                so.Expression = inlinedParameterVariables[i].AssignmentSource;
                operations.Insert(j + 1, so);
            }
        }
Beispiel #3
0
        /// <summary>
        /// Parallelize the scheduled search plan to the branching factor,
        /// splitting it at the first loop into a header part and a body part
        /// </summary>
        public static void ParallelizeHeadBody(LGSPRulePattern rulePattern)
        {
            Debug.Assert(rulePattern.patternGraph.schedulesIncludingNegativesAndIndependents.Length == 1);
            ScheduledSearchPlan ssp = rulePattern.patternGraph.schedulesIncludingNegativesAndIndependents[0];

            int indexToSplitAt = 0;

            for (int i = 0; i < ssp.Operations.Length; ++i)
            {
                SearchOperation so = ssp.Operations[i];
                if (so.Type == SearchOperationType.Lookup || so.Type == SearchOperationType.Incident ||
                    so.Type == SearchOperationType.Incoming || so.Type == SearchOperationType.Outgoing ||
                    so.Type == SearchOperationType.PickFromStorage || so.Type == SearchOperationType.PickFromStorageDependent ||
                    so.Type == SearchOperationType.PickFromIndex || so.Type == SearchOperationType.PickFromIndexDependent)
                {
                    indexToSplitAt = i;
                    break;
                }
            }

            rulePattern.patternGraph.parallelizedSchedule = new ScheduledSearchPlan[2];
            List <SearchOperation> headOperations = new List <SearchOperation>();
            List <SearchOperation> bodyOperations = new List <SearchOperation>();

            for (int i = 0; i < rulePattern.Inputs.Length; ++i)
            {
                if (rulePattern.Inputs[i] is VarType) // those don't appear in the schedule, they are only extracted into the search program
                {
                    VarType         varType = (VarType)rulePattern.Inputs[i];
                    String          varName = rulePattern.InputNames[i];
                    PatternVariable dummy   = new PatternVariable(varType, varName, varName, i, false, null);
                    headOperations.Add(new SearchOperation(SearchOperationType.WriteParallelPresetVar,
                                                           dummy, null, 0));
                    bodyOperations.Add(new SearchOperation(SearchOperationType.ParallelPresetVar,
                                                           dummy, null, 0));
                }
            }
            for (int i = 0; i < ssp.Operations.Length; ++i)
            {
                SearchOperation so = ssp.Operations[i];
                if (i < indexToSplitAt)
                {
                    SearchOperation clone = (SearchOperation)so.Clone();
                    clone.Isomorphy.Parallel          = true;
                    clone.Isomorphy.LockForAllThreads = true;
                    headOperations.Add(clone);
                    switch (so.Type)
                    {
                    // the target binding looping operations can't appear in the header, so we don't treat them here
                    // the non-target binding operations are completely handled by just adding them, happended already above
                    // the target binding non-looping operations are handled below,
                    // by parallel preset writing in the header and reading in the body
                    // with exception of def, its declaration and initializion is just re-executed in the body
                    // some presets can't appear in an action header, they are thus not taken care of
                    case SearchOperationType.ActionPreset:
                    case SearchOperationType.MapWithStorage:
                    case SearchOperationType.MapWithStorageDependent:
                    case SearchOperationType.Cast:
                    case SearchOperationType.Assign:
                    case SearchOperationType.Identity:
                    case SearchOperationType.ImplicitSource:
                    case SearchOperationType.ImplicitTarget:
                    case SearchOperationType.Implicit:
                        headOperations.Add(new SearchOperation(SearchOperationType.WriteParallelPreset,
                                                               (SearchPlanNode)so.Element, so.SourceSPNode, 0));
                        bodyOperations.Add(new SearchOperation(SearchOperationType.ParallelPreset,
                                                               (SearchPlanNode)so.Element, so.SourceSPNode, 0));
                        break;

                    case SearchOperationType.AssignVar:
                        headOperations.Add(new SearchOperation(SearchOperationType.WriteParallelPresetVar,
                                                               (PatternVariable)so.Element, so.SourceSPNode, 0));
                        bodyOperations.Add(new SearchOperation(SearchOperationType.ParallelPresetVar,
                                                               (PatternVariable)so.Element, so.SourceSPNode, 0));
                        break;

                    case SearchOperationType.DefToBeYieldedTo:
                        bodyOperations.Add((SearchOperation)so.Clone());
                        break;
                    }
                }
                else if (i == indexToSplitAt)
                {
                    SearchOperation cloneHead;
                    SearchOperation cloneBody;
                    switch (so.Type)
                    {
                    case SearchOperationType.Lookup:
                        cloneHead = (SearchOperation)so.Clone(SearchOperationType.SetupParallelLookup);
                        cloneBody = (SearchOperation)so.Clone(SearchOperationType.ParallelLookup);
                        break;

                    case SearchOperationType.Incident:
                        cloneHead = (SearchOperation)so.Clone(SearchOperationType.SetupParallelIncident);
                        cloneBody = (SearchOperation)so.Clone(SearchOperationType.ParallelIncident);
                        break;

                    case SearchOperationType.Incoming:
                        cloneHead = (SearchOperation)so.Clone(SearchOperationType.SetupParallelIncoming);
                        cloneBody = (SearchOperation)so.Clone(SearchOperationType.ParallelIncoming);
                        break;

                    case SearchOperationType.Outgoing:
                        cloneHead = (SearchOperation)so.Clone(SearchOperationType.SetupParallelOutgoing);
                        cloneBody = (SearchOperation)so.Clone(SearchOperationType.ParallelOutgoing);
                        break;

                    case SearchOperationType.PickFromStorage:
                        cloneHead = (SearchOperation)so.Clone(SearchOperationType.SetupParallelPickFromStorage);
                        cloneBody = (SearchOperation)so.Clone(SearchOperationType.ParallelPickFromStorage);
                        break;

                    case SearchOperationType.PickFromStorageDependent:
                        cloneHead = (SearchOperation)so.Clone(SearchOperationType.SetupParallelPickFromStorageDependent);
                        cloneBody = (SearchOperation)so.Clone(SearchOperationType.ParallelPickFromStorageDependent);
                        break;

                    case SearchOperationType.PickFromIndex:
                        cloneHead = (SearchOperation)so.Clone(SearchOperationType.SetupParallelPickFromIndex);
                        cloneBody = (SearchOperation)so.Clone(SearchOperationType.ParallelPickFromIndex);
                        break;

                    case SearchOperationType.PickFromIndexDependent:
                        cloneHead = (SearchOperation)so.Clone(SearchOperationType.SetupParallelPickFromIndexDependent);
                        cloneBody = (SearchOperation)so.Clone(SearchOperationType.ParallelPickFromIndexDependent);
                        break;

                    default: // failure, operation at this index cannot be parallelized/parallelization not supported
                        cloneHead = null;
                        cloneBody = null;
                        break;
                    }
                    headOperations.Add(cloneHead);
                    cloneBody.Isomorphy.Parallel = true;
                    bodyOperations.Add(cloneBody);
                }
                else
                {
                    SearchOperation clone = (SearchOperation)so.Clone();
                    clone.Isomorphy.Parallel = true;
                    bodyOperations.Add(clone);
                    if (clone.Element is PatternCondition)
                    {
                        SetNeedForParallelizedVersion((clone.Element as PatternCondition).ConditionExpression);
                    }
                }
            }
            ScheduledSearchPlan headSsp = new ScheduledSearchPlan(
                rulePattern.patternGraph, headOperations.ToArray(), headOperations.Count > 0 ? headOperations[0].CostToEnd : 0);

            rulePattern.patternGraph.parallelizedSchedule[0] = headSsp;
            ScheduledSearchPlan bodySsp = new ScheduledSearchPlan(
                rulePattern.patternGraph, bodyOperations.ToArray(), bodyOperations.Count > 0 ? bodyOperations[0].CostToEnd : 0);

            rulePattern.patternGraph.parallelizedSchedule[1] = bodySsp;
            ParallelizeNegativeIndependent(bodySsp);
            ParallelizeAlternativeIterated(rulePattern.patternGraph);
            ParallelizeYielding(rulePattern.patternGraph);
        }