internal HashSet <Variable> FindWrittenGroupSharedArrays(GPUVerifier verifier) { // We add any group-shared array that may be written to or accessed atomically // in the region. // // We also add any group-shared array that may be written to by an asynchronous // memory copy somewhere in the kernel. This is because asynchronous copies can // cross barriers. Currently we are very conservative about this. HashSet <Variable> result = new HashSet <Variable>(); foreach (var v in verifier.KernelArrayInfo.GetGroupSharedArrays(false)) { if (verifier.ArraysAccessedByAsyncWorkGroupCopy[AccessType.WRITE].Contains(v.Name)) { result.Add(v); } } foreach (var m in Blocks.Select(Item => Item.Cmds).SelectMany(Item => Item).OfType <CallCmd>() .Select(Item => Item.Proc.Modifies).SelectMany(Item => Item)) { // m is a variable modified by a call in the barrier interval Variable v; if (verifier.TryGetArrayFromAccessHasOccurred(GVUtil.StripThreadIdentifier(m.Name), AccessType.WRITE, out v) || verifier.TryGetArrayFromAccessHasOccurred(GVUtil.StripThreadIdentifier(m.Name), AccessType.ATOMIC, out v)) { if (verifier.KernelArrayInfo.GetGroupSharedArrays(false).Contains(v)) { result.Add(v); } } } return(result); }
private static bool IsDisjunctionOfPredicates(Expr guard) { if (!(guard is NAryExpr)) { return(false); } NAryExpr nary = (NAryExpr)guard; if (nary.Args.Count() != 2) { return(false); } if (!(nary.Fun is BinaryOperator)) { return(false); } BinaryOperator binOp = (BinaryOperator)nary.Fun; if (binOp.Op != BinaryOperator.Opcode.Or) { return(false); } if (!(nary.Args[0] is IdentifierExpr && nary.Args[1] is IdentifierExpr)) { return(false); } return(GPUVerifier.IsPredicate(GVUtil.StripThreadIdentifier( ((IdentifierExpr)nary.Args[0]).Name)) && GPUVerifier.IsPredicate(GVUtil.StripThreadIdentifier( ((IdentifierExpr)nary.Args[1]).Name))); }
private Dictionary <string, int> GetAssignmentCounts(Implementation impl) { Dictionary <string, int> result = new Dictionary <string, int>(); foreach (var c in verifier.RootRegion(impl).Cmds()) { if (c is AssignCmd) { var aCmd = (AssignCmd)c; HashSet <string> alreadySeenInThisAssignment = new HashSet <string>(); foreach (var a in aCmd.Lhss) { if (a is SimpleAssignLhs) { var v = GVUtil.StripThreadIdentifier( ((SimpleAssignLhs)a).AssignedVariable.Name); if (!alreadySeenInThisAssignment.Contains(v)) { if (result.ContainsKey(v)) { result[v]++; } else { result[v] = 1; } alreadySeenInThisAssignment.Add(v); } } } } } return(result); }
private bool BarrierHasNonUniformArgument(Procedure BarrierProcedure) { foreach (var v in BarrierProcedure.InParams) { if (!verifier.uniformityAnalyser.IsUniform(BarrierProcedure.Name, GVUtil.StripThreadIdentifier(v.Name))) { return(true); } } return(false); }
private string CleanOriginalProgramVariable(string Name, out int Id) { string StrippedName = GVUtil.StripThreadIdentifier(Name, out Id); if (globalArraySourceNames.ContainsKey(StrippedName)) { return(globalArraySourceNames[StrippedName]); } else { return(StrippedName.TrimStart(new char[] { '$' }).Split(new char[] { '.' })[0]); } }
public override Expr VisitIdentifierExpr(IdentifierExpr expr) { int id; var varName = GVUtil.StripThreadIdentifier(expr.Name, out id); if (!defs.ContainsKey(varName)) { // The variable never assigned to in the procedure return(base.VisitIdentifierExpr(expr)); } else if (defs[varName] == null) { // The variable has been assigned to, but we do not know what was assigned. freeVars.Add(varName); return(base.VisitIdentifierExpr(expr)); } else { return(verifier.MaybeDualise(VisitExpr(defs[varName]), id, procName)); } }
public ModStrideConstraint GetStrideConstraint(string variable, object regionId) { if (!strideConstraintMap.ContainsKey(regionId)) { return(null); } else { int id; var strippedVariable = GVUtil.StripThreadIdentifier(variable, out id); ModStrideConstraint msc; if (strideConstraintMap[regionId].TryGetValue(strippedVariable, out msc)) { return(new ModStrideConstraint(verifier.MaybeDualise(msc.mod, id, impl.Name), verifier.MaybeDualise(msc.modEq, id, impl.Name))); } else { return(null); } } }
private void AddBarrierDivergenceCandidates(HashSet <Variable> LocalVars, Implementation Impl, IRegion region) { if (!verifier.ContainsBarrierCall(region) && !GPUVerifyVCGenCommandLineOptions.WarpSync) { return; } Expr guard = region.Guard(); if (guard != null && verifier.uniformityAnalyser.IsUniform(Impl.Name, guard)) { return; } if (IsDisjunctionOfPredicates(guard)) { string LoopPredicate = ((guard as NAryExpr).Args[0] as IdentifierExpr).Name; LoopPredicate = LoopPredicate.Substring(0, LoopPredicate.IndexOf('$')); var uniformEnabledPredicate = Expr.Eq( // Int type used here, but it doesn't matter as we will print and then re-parse the program new IdentifierExpr(Token.NoToken, new LocalVariable(Token.NoToken, new TypedIdent(Token.NoToken, LoopPredicate + "$1", Microsoft.Boogie.Type.Int))), new IdentifierExpr(Token.NoToken, new LocalVariable(Token.NoToken, new TypedIdent(Token.NoToken, LoopPredicate + "$2", Microsoft.Boogie.Type.Int))) ); verifier.AddCandidateInvariant(region, uniformEnabledPredicate, "loopPredicateEquality"); verifier.AddCandidateInvariant(region, Expr.Imp(GPUVerifier.ThreadsInSameGroup(), uniformEnabledPredicate), "loopPredicateEquality"); Dictionary <string, int> assignmentCounts = GetAssignmentCounts(Impl); HashSet <string> alreadyConsidered = new HashSet <string>(); foreach (var v in LocalVars) { string lv = GVUtil.StripThreadIdentifier(v.Name); if (alreadyConsidered.Contains(lv)) { continue; } alreadyConsidered.Add(lv); if (verifier.uniformityAnalyser.IsUniform(Impl.Name, v.Name)) { continue; } if (GPUVerifier.IsPredicate(lv)) { continue; } if (!assignmentCounts.ContainsKey(lv) || assignmentCounts[lv] <= 1) { continue; } if (!verifier.ContainsNamedVariable( GetModifiedVariables(region), lv)) { continue; } AddPredicatedEqualityCandidateInvariant(region, LoopPredicate, new LocalVariable(Token.NoToken, new TypedIdent(Token.NoToken, lv, Type.Int))); } } }