private Dictionary <string, bool> Solve(List <RepairableError> errors, SolverType type) { try { List <Clause> clauses = GenerateClauses(errors); return(Solve(clauses, type)); } // the repair exception could be because of not considering all the barriers in the loop // refer CUDA/transitiveclosure as an example catch (RepairException) { bool overapproximated = false; foreach (Error error in errors) { RaceError race = error as RaceError; if (race != null && race.OverapproximatedBarriers.Any()) { overapproximated = true; race.Overapproximated = true; } } // if none of the clauses were overapproximated, return the original result if (!overapproximated) { throw; } List <Clause> clauses = GenerateClauses(errors); return(Solve(clauses, type)); } }
/// <summary> /// Retrieves the race information. /// </summary> /// <param name="example">The counter example.</param> /// <param name="error">The race error.</param> /// <returns>The race errors.</returns> public IEnumerable <RaceError> GetRaceInformation(CallCounterexample example, RaceError error) { string raceName, access1, access2; DetermineNatureOfRace(example, out raceName, out access1, out access2); PopulateModelWithStatesIfNecessary(example); string raceyArrayName = GetArrayName(example.FailingRequires); IEnumerable <SourceLocationInfo> possibleSourcesForFirstAccess = GetPossibleSourceLocationsForFirstAccessInRace( example, raceyArrayName, AccessType.Create(access1), GetStateName(example)); SourceLocationInfo sourceInfoForSecondAccess = new SourceLocationInfo( GetAttributes(example.FailingCall), GetSourceFileName(), example.FailingCall.tok); error.RaceType = raceName; error.Access1 = access1; error.Access2 = access2; List <RaceError> errors = new List <RaceError>(); foreach (SourceLocationInfo possibleSourceForFirstAccess in possibleSourcesForFirstAccess) { RaceError race = new RaceError(error.CounterExample, error.Implementation) { RaceType = raceName, Access1 = access1, Access2 = access2, Start = possibleSourceForFirstAccess, End = sourceInfoForSecondAccess }; errors.Add(race); } if (!errors.Any()) { return new List <RaceError> { error } } ; return(errors); }
/// <summary> /// Generates clauses based on the errors. /// </summary> /// <param name="errors">The errors.</param> /// <returns>The clauses.</returns> private List <Clause> GenerateClauses(List <RepairableError> errors) { List <Clause> clauses = new List <Clause>(); foreach (RepairableError error in errors) { RaceError race = error as RaceError; if (race != null) { IEnumerable <Barrier> barriers = error.Barriers; if (race != null && race.Overapproximated && race.OverapproximatedBarriers.Any()) { // consider the over-approximation barriers for the loop barriers = race.OverapproximatedBarriers; } Clause clause = new Clause(); foreach (string variable in barriers.Select(x => x.Name)) { clause.Add(new Literal(variable, true)); } clauses.Add(clause); } else { foreach (string variable in error.Barriers.Select(x => x.Name)) { Clause clause = new Clause(); clause.Add(new Literal(variable, false)); clauses.Add(clause); } } } return(clauses.Distinct().ToList()); }
/// <summary> /// Generates the errors from the counter example. /// </summary> /// <param name="example">The counter example.</param> /// <param name="implementation">The implementation.</param> /// <returns>The error.</returns> private IEnumerable <Error> GenerateErrors(Counterexample example, Implementation implementation) { List <Error> errors = new List <Error>(); if (example is CallCounterexample) { CallCounterexample callCounterexample = example as CallCounterexample; if (QKeyValue.FindBoolAttribute(callCounterexample.FailingRequires.Attributes, "barrier_divergence")) { DivergenceError divergence = new DivergenceError(example, implementation); ErrorReporter reporter = new ErrorReporter(program, implementation.Name); reporter.PopulateDivergenceInformation(callCounterexample, divergence); IdentifyVariables(divergence); errors.Add(divergence); return(errors); } else if (QKeyValue.FindBoolAttribute(callCounterexample.FailingRequires.Attributes, "race")) { RaceError template = new RaceError(example, implementation); ErrorReporter reporter = new ErrorReporter(program, implementation.Name); IEnumerable <RaceError> races = reporter.GetRaceInformation(callCounterexample, template); foreach (RaceError race in races) { IdentifyVariables(race); } errors.AddRange(races); return(errors); } } errors.Add(new Error(example, implementation)); return(errors); }
/// <summary> /// Populates the barriers based on the source information. /// </summary> /// <param name="barriers">The barriers involved in the trace.</param> /// <param name="race">The race error.</param> private void PopulateRaceBarriers(IEnumerable <Barrier> barriers, RaceError race) { bool inverse = false; List <Barrier> location_barriers; if (race.Start == null && race.End == null) { location_barriers = barriers.ToList(); } else { location_barriers = FilterBarriers(barriers, race.Start, race.End); if (!location_barriers.Any()) { location_barriers = FilterBarriers(race.End, race.Start); inverse = true; } } // get all the other barriers which are in the loop List <Barrier> loop_barriers = GetLoopBarriers(race.Start, race.End); if (inverse) { List <Barrier> inverse_barriers = new List <Barrier>(); foreach (Barrier barrier in loop_barriers) { if (!location_barriers.Contains(barrier)) { inverse_barriers.Add(barrier); } } location_barriers = inverse_barriers; } // check if all the locations are from the loop // needed for cases for one location is inside and the other is outside the loop // refer CUDASamples\6_Advanced_concurrentKernels_sum as an example bool same_loop = !location_barriers.Any(x => !loop_barriers.Contains(x)); List <Barrier> result = new List <Barrier>(); foreach (Barrier barrier in location_barriers) { if (barriers.Contains(barrier)) { AddBarrier(result, barrier); } } List <Barrier> overapproximated_result = new List <Barrier>(); foreach (Barrier barrier in loop_barriers.Union(location_barriers)) { if (barriers.Contains(barrier)) { AddBarrier(overapproximated_result, barrier); } } race.Barriers = same_loop ? result : overapproximated_result; race.OverapproximatedBarriers = overapproximated_result; }