Skip to content

SVM optimizations #130

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 99 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
99 commits
Select commit Hold shift + click to select a range
634f871
Add discover constants recursive function
mxprshn Sep 11, 2021
e110c7e
Try to implement persistent union find
mxprshn Sep 11, 2021
b537708
Fix discover constants to use pset
mxprshn Sep 11, 2021
4c01d0b
Try to implement path condition slicing
mxprshn Sep 13, 2021
8a823f5
Implement IndependentWith method for constant sources
mxprshn Oct 1, 2021
e788dd2
Add conditions grouping by source independence
mxprshn Oct 4, 2021
f0a6581
Move independence logic to pathCondition from pathConditionIndependent
mxprshn Oct 4, 2021
e115574
Rename constraintsWithConstants field
mxprshn Oct 7, 2021
3dcfc0b
Make persistent union-find cyclic
mxprshn Oct 8, 2021
d2d6cee
Add subset function to persistent union find
mxprshn Oct 8, 2021
b0f02e9
Add fragments iterator to pathCondition
mxprshn Oct 8, 2021
147a3bc
Add some comments
mxprshn Oct 8, 2021
e7839b4
Add some persistent union find tests
mxprshn Oct 16, 2021
f91a799
Add with independent by function and some sandbox code
mxprshn Oct 19, 2021
cee9447
Merge branch 'master' into constraint-independence
mxprshn Oct 20, 2021
22b44c1
Update commonStatedConditionalExecutionk to use constraint independence
mxprshn Oct 20, 2021
2ca9dbd
Update model in Z3 module instead of creating it
mxprshn Nov 14, 2021
e247715
Implement SubTerms for heapReading
mxprshn Nov 21, 2021
08d1672
Fix subterms for heapReading and add Slice and Union to discoverConst…
mxprshn Nov 25, 2021
e4f9696
Merge branch 'master' into constraint-independence
mxprshn Dec 1, 2021
0b9188d
Prettify code
mxprshn Dec 1, 2021
66756cc
[style] PR comments fixes
mxprshn Dec 3, 2021
4f3a431
[fix] Fix PC check for False
mxprshn Dec 3, 2021
c9dbb4a
[style] Use Option.defaultValue and rename slice args
mxprshn Dec 3, 2021
8abad91
Add StatedLogger and clear cache after model update
mxprshn Dec 24, 2021
7251d4e
Fill model with this and params
mxprshn Dec 24, 2021
99f366d
[fix] Fix namespace conflict
mxprshn Dec 24, 2021
de31156
[style] Check if pc contains cond more prettily
mxprshn Dec 26, 2021
46c76ba
[feat] Add Stopwatch module for method execution time measurement
mxprshn Feb 9, 2022
c5f1e44
[feat] Add execution time writing to csv
mxprshn Feb 14, 2022
c27b432
[feat] Measure total interpretation time
mxprshn Feb 14, 2022
487457d
Disable coverage and clear stopwatch after execution
mxprshn Feb 15, 2022
ceeea20
Merge branch 'stopwatch' into constraint-independence-time
mxprshn Feb 23, 2022
ab925c5
Measure model update and PC operations time
mxprshn Feb 23, 2022
66e517c
Measure union-find operations time
mxprshn Feb 28, 2022
36a600a
Add new mutable PC class
mxprshn Feb 28, 2022
a709a25
[feat] Implement all members of mutable PC
mxprshn Mar 5, 2022
70abd26
[feat] Replace old PC with new
mxprshn Mar 5, 2022
173fcf8
[fix] Fix empty const sequence bug and enable coverage
mxprshn Mar 6, 2022
4370685
[fix] Fix for the case when there are constraints without constants
mxprshn Mar 7, 2022
453775e
[fix] Disable coverage again
mxprshn Mar 7, 2022
b251e88
[fix] Measure time of Add and Fragments
mxprshn Mar 7, 2022
67d77da
Merge branch 'master' into merge-master-into-new-pc
mxprshn Mar 10, 2022
b325b53
[fix] Fix master merge conflicts with
mxprshn Mar 11, 2022
dc2170c
[temp] Some code for testing purposes, fixme
mxprshn Mar 20, 2022
b6906b0
[fix] Fix Slice folding
mxprshn Mar 20, 2022
4db3cc3
[style] Fix pc namings
mxprshn Mar 20, 2022
b8e663d
[fix] Remove unused persistent union find
mxprshn Mar 20, 2022
25af3e9
[style] Remove commented code
mxprshn Mar 20, 2022
6aa02e7
[style] Add comments to utils and PC
mxprshn Mar 20, 2022
747a36c
[feat] Add functional map and union for PC
mxprshn Mar 20, 2022
fbfcf51
[fix] Remove time measurement
mxprshn Mar 20, 2022
c33fa0b
[fix] Remove tagged logging
mxprshn Mar 20, 2022
f5b6252
[style] Format fixes
mxprshn Mar 20, 2022
545e56c
[fix] Remove changes in regex test
mxprshn Mar 20, 2022
62d99e3
[style] One more format fix
mxprshn Mar 20, 2022
7794e7c
Merge branch 'merge-master-into-new-pc' into constraint-independence
mxprshn Mar 20, 2022
e698159
[feat] First incrementality attempt
mxprshn Apr 12, 2022
c2b15d8
[fix] Pass stack trace to test result for debugging
mxprshn Apr 18, 2022
96d1dac
Very dirty attempt to eval model before
mxprshn Apr 30, 2022
58edff0
[fix] Assert new assumptions right before check sat
mxprshn May 6, 2022
73430cf
[fix] Don't forget to assert additional assumptions
mxprshn May 7, 2022
f90e040
[fix] Catch double encoding exceptions
mxprshn May 7, 2022
e9cb57f
[style] Prettify code a bit
mxprshn May 10, 2022
b208155
[feat] Add conjunction splitting
mxprshn May 11, 2022
5698618
[fix] Move assertion and check to one function for efficiency
mxprshn May 12, 2022
220bb8b
[fix] Use ints as names for assumptions
mxprshn May 12, 2022
11e2ea4
Merge branch 'incrementality-with-assumptions' into optimizations
mxprshn May 17, 2022
97afb91
[fix] Fix incrementality and independence merge conflicts
mxprshn May 17, 2022
1ebc138
Add some tests with 'logic bombs'
mxprshn May 16, 2022
01d8c38
[fix] Fix not updated model
mxprshn May 17, 2022
3905341
Merge branch 'eval-model-on-branching' into optimizations
mxprshn May 17, 2022
01a6d34
Revert "Merge branch 'eval-model-on-branching' into optimizations"
mxprshn May 17, 2022
cbadf8c
Very dirty attempt to eval model before
mxprshn May 17, 2022
3291c74
[style] Prettify code a bit
mxprshn May 10, 2022
78cd8c1
[fix] Remove noNewConsts
mxprshn May 17, 2022
35e4756
[fix] Save number of generated unit tests to csv
mxprshn May 17, 2022
40edf31
[fix] Make regex test harder
mxprshn May 17, 2022
defb901
[fix] Set expected coverage for new tests
mxprshn May 17, 2022
fd05f66
[fix] Add PC class without independence
mxprshn May 17, 2022
9a592c2
[feat] Add ability to enable/disable opts with flags
mxprshn May 22, 2022
a9b40c3
[fix] Fix CLI arguments, disable logging and time measurement, style …
mxprshn Jun 2, 2022
2449219
Merge branch 'VSharp-team:master' into opts-master
mxprshn Jul 15, 2022
dd65e89
[style] Style fixes
mxprshn Jul 15, 2022
cef420d
[fix] Fix runtime submodule version
mxprshn Jul 19, 2022
de680e3
[fix] Add API level options class and remove eval condition option
mxprshn Jul 21, 2022
e2fcd66
Merge branch 'master' into opts-master
mxprshn Jul 21, 2022
a8226e1
[fix] Fix conflicts after master merge
mxprshn Jul 22, 2022
23e00c0
Merge branch 'master' into opts-master
mxprshn Jul 22, 2022
49b281c
[fix] Fix FillWithParametersAndThis signature
mxprshn Jul 22, 2022
b66151d
Merge branch 'master' into opts-master
mxprshn Jul 24, 2022
5d624a6
[fix] Fix 'visualize' option conflict
mxprshn Jul 25, 2022
d71e132
[fix] Fix broken import
mxprshn Jul 25, 2022
d077c56
[fix] Bug fixes: incorrect vector time in encoding cache, incorrect I…
mxprshn Aug 1, 2022
814d398
[fix] Fix Z3 builder cache clearing
mxprshn Aug 3, 2022
c0f325f
[style] Remove Stopwatch and TaggedLogger from production
mxprshn Aug 3, 2022
b5a2ebd
[fix] Enable constraint-independence for integration tests
mxprshn Aug 3, 2022
53419b6
[fix] In incremental mode, create solver for each covered method
mxprshn Aug 3, 2022
0ffc829
[fix] CLI options style fixes + remove new solver creation for each m…
mxprshn Aug 3, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
90 changes: 90 additions & 0 deletions VSharp.API/Options.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
using System.IO;
using VSharp.Interpreter.IL;

namespace VSharp
{
/// <summary>
/// Symbolic virtual machine execution mode.
/// </summary>
public enum ExecutionMode
{
/// <summary>
/// Pure symbolic execution. Cannot cope with external dependencies in code.
/// </summary>
Symbolic,
/// <summary>
/// (Experimental) Concrete and symbolic execution combination. Allows to explore code with external dependencies by
/// instantiating concrete objects.
/// </summary>
Concolic
}

/// <summary>
///
/// </summary>
public enum SearchStrategy
{
DFS,
BFS,
ShortestDistance
}

/// <summary>
/// Parameters of the test generation run.
/// </summary>
/// <param name="OutputDirectory">Directory to place generated <c>*.vst</c> tests. If <c>null</c> or empty, process working directory is used.
/// <c>null</c> by default. </param>
/// <param name="SearchStrategy"></param>
/// <param name="ExecutionMode">Symbolic virtual machine execution mode. <see cref="F:ExecutionMode.Symbolic"/> by default.</param>
/// <param name="GuidedSearch"></param>
/// <param name="RecThreshold"></param>
/// <param name="Timeout">Timeout for code exploration in seconds. Negative value means infinite timeout (up to exhaustive coverage or user interruption).
/// -1 by default</param>
/// <param name="IsConstraintIndependenceEnabled">If true, constraint independence optimization is enabled: independent constraint sets are maintained
/// during symbolic execution. In general, improves execution time. <c>true</c> by default.</param>
/// <param name="IsSolverIncrementalityEnabled">If true, SMT solver works in incremental mode during symbolic execution. May improve execution
/// time in some cases. <c>false</c> by default.</param>
/// <param name="Visualize">If true, symbolic execution process animation is saved in <c>/visualize</c> subdirectory of the <see cref="OutputDirectory"/>.</param>
public readonly record struct CoverOptions(
DirectoryInfo OutputDirectory = null,
SearchStrategy SearchStrategy = SearchStrategy.DFS,
ExecutionMode ExecutionMode = ExecutionMode.Symbolic,
bool GuidedSearch = false,
uint RecThreshold = 0u,
int Timeout = -1,
bool IsConstraintIndependenceEnabled = true,
bool IsSolverIncrementalityEnabled = false,
bool Visualize = false
)
{
internal SiliOptions ToSiliOptions(coverageZone coverageZone)
{
var searchMode = SearchStrategy switch
{
SearchStrategy.DFS => Interpreter.IL.searchMode.DFSMode,
SearchStrategy.BFS => Interpreter.IL.searchMode.BFSMode,
SearchStrategy.ShortestDistance => Interpreter.IL.searchMode.ShortestDistanceBasedMode
};

if (GuidedSearch)
{
searchMode = searchMode.NewGuidedMode(searchMode);
}

var executionMode = ExecutionMode switch
{
ExecutionMode.Symbolic => Interpreter.IL.executionMode.SymbolicMode,
ExecutionMode.Concolic => Interpreter.IL.executionMode.ConcolicMode
};

return new SiliOptions(
explorationMode.NewTestCoverageMode(coverageZone, searchMode),
executionMode,
OutputDirectory,
RecThreshold,
Timeout,
Visualize
);
}
}
}
83 changes: 35 additions & 48 deletions VSharp.API/VSharp.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ internal Statistics(TimeSpan time, DirectoryInfo outputDir, uint tests, uint err
public TimeSpan TestGenerationTime { get; }

/// <summary>
/// Directory where *.vst tests are placed
/// Directory where *.vst tests are placed.
/// </summary>
public DirectoryInfo OutputDir { get; }

Expand Down Expand Up @@ -71,21 +71,16 @@ public void GenerateReport(TextWriter writer)

public static class TestGenerator
{
private static Statistics StartExploration(List<MethodBase> methods, string resultsFolder, string[] mainArguments = null, int timeout = -1)
private static Statistics StartExploration(List<MethodBase> methods, CoverOptions options = new(), string[] mainArguments = null)
{
var recThreshold = 0u;
UnitTests unitTests = new UnitTests(resultsFolder);
var outputDirectory = options.OutputDirectory ?? new DirectoryInfo(Directory.GetCurrentDirectory());
// TODO: customize search strategies via console options
var options =
new SiliOptions(
explorationMode.NewTestCoverageMode(coverageZone.MethodZone, searchMode.DFSMode),
executionMode.SymbolicMode,
unitTests.TestDirectory,
recThreshold,
timeout,
false);
SILI explorer = new SILI(options);
Core.API.ConfigureSolver(SolverPool.mkSolver());
UnitTests unitTests = new UnitTests(outputDirectory.FullName);
SILI explorer = new SILI(options.ToSiliOptions(coverageZone.MethodZone));
// TODO: refresh solver ctx for each method in incremental mode
Core.API.ConfigureSolver(SolverPool.mkSolver(), options.IsSolverIncrementalityEnabled);
Core.API.SetConstraintIndependenceEnabled(options.IsConstraintIndependenceEnabled);

foreach (var method in methods)
{
if (method == method.Module.Assembly.EntryPoint)
Expand Down Expand Up @@ -116,24 +111,22 @@ public static bool Reproduce(DirectoryInfo testDir)
/// Generates test coverage for specified method.
/// </summary>
/// <param name="method">Type to be covered with tests.</param>
/// <param name="timeout">Timeout for code exploration in seconds. Negative value means infinite timeout (up to exhaustive coverage or user interuption).</param>
/// <param name="outputDirectory">Directory to place generated *.vst tests. If null or empty, process working directory is used.</param>
/// <param name="options">Additional parameters of the run.</param>
/// <returns>Summary of tests generation process.</returns>
public static Statistics Cover(MethodBase method, int timeout = -1, string outputDirectory = "")
public static Statistics Cover(MethodBase method, CoverOptions options = new())
{
List<MethodBase> methods = new List<MethodBase> {method};
return StartExploration(methods, outputDirectory, null, timeout);
return StartExploration(methods, options);
}

/// <summary>
/// Generates test coverage for all public methods of specified type.
/// </summary>
/// <param name="type">Type to be covered with tests.</param>
/// <param name="timeout">Timeout for code exploration in seconds. Negative value means infinite timeout (up to exhaustive coverage or user interuption).</param>
/// <param name="outputDirectory">Directory to place generated *.vst tests. If null or empty, process working directory is used.</param>
/// <param name="options">Additional parameters of the run.</param>
/// <returns>Summary of tests generation process.</returns>
/// <exception cref="ArgumentException">Thrown if specified class does not contain public methods.</exception>
public static Statistics Cover(Type type, int timeout = -1, string outputDirectory = "")
public static Statistics Cover(Type type, CoverOptions options = new())
{
List<MethodBase> methods = new List<MethodBase>(type.GetConstructors());

Expand All @@ -146,19 +139,18 @@ public static Statistics Cover(Type type, int timeout = -1, string outputDirecto
throw new ArgumentException("I've not found any public method or constructor of class " + type.FullName);
}

return StartExploration(methods, outputDirectory, null, timeout);
return StartExploration(methods, options);
}

/// <summary>
/// Generates test coverage for all public methods of all public classes in the specified assembly.
/// </summary>
/// <param name="assembly">Assembly to be covered with tests.</param>
/// <param name="timeout">Timeout for code exploration in seconds. Negative value means infinite timeout (up to exhaustive coverage or user interuption).</param>
/// <param name="outputDirectory">Directory to place generated *.vst tests. If null or empty, process working directory is used.</param>
/// <param name="options">Additional parameters of the run.</param>
/// <returns>Summary of tests generation process.</returns>
/// <exception cref="ArgumentException">Thrown if no public methods found in assembly.
/// </exception>
public static Statistics Cover(Assembly assembly, int timeout = -1, string outputDirectory = "")
public static Statistics Cover(Assembly assembly, CoverOptions options = new())
{
List<MethodBase> methods;
BindingFlags bindingFlags = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public |
Expand All @@ -180,20 +172,19 @@ public static Statistics Cover(Assembly assembly, int timeout = -1, string outpu
throw new ArgumentException("I've not found any public method in assembly");
}

return StartExploration(methods, outputDirectory, null, timeout);
return StartExploration(methods, options);
}

/// <summary>
/// Generates test coverage for the entry point of the specified assembly.
/// </summary>
/// <param name="assembly">Assembly to be covered with tests.</param>
/// <param name="args">Command line arguments of entry point</param>
/// <param name="timeout">Timeout for code exploration in seconds. Negative value means infinite timeout (up to exhaustive coverage or user interuption).</param>
/// <param name="outputDirectory">Directory to place generated *.vst tests. If null or empty, process working directory is used.</param>
/// <param name="args">Command line arguments of entry point.</param>
/// <param name="options">Additional parameters of the run.</param>
/// <returns>Summary of tests generation process.</returns>
/// <exception cref="ArgumentException">Thrown if assembly does not contain entry point.
/// </exception>
public static Statistics Cover(Assembly assembly, string[] args, int timeout = -1, string outputDirectory = "")
public static Statistics Cover(Assembly assembly, string[] args, CoverOptions options = new())
{
List<MethodBase> methods;
var entryPoint = assembly.EntryPoint;
Expand All @@ -203,63 +194,59 @@ public static Statistics Cover(Assembly assembly, string[] args, int timeout = -
}
methods = new List<MethodBase> { entryPoint };

return StartExploration(methods, outputDirectory, args, timeout);
return StartExploration(methods, options, args);
}

/// <summary>
/// Generates test coverage for the specified method and runs all tests.
/// </summary>
/// <param name="method">Type to be covered with tests.</param>
/// <param name="timeout">Timeout for code exploration in seconds. Negative value means infinite timeout (up to exhaustive coverage or user interuption).</param>
/// <param name="outputDirectory">Directory to place generated *.vst tests. If null or empty, process working directory is used.</param>
/// <param name="options">Additional parameters of the run.</param>
/// <returns>True if all generated tests have passed.</returns>
public static bool CoverAndRun(MethodBase method, int timeout = -1, string outputDirectory = "")
public static bool CoverAndRun(MethodBase method, CoverOptions options = new())
{
var stats = Cover(method, timeout, outputDirectory);
var stats = Cover(method, options);
return Reproduce(stats.OutputDir);
}

/// <summary>
/// Generates test coverage for the specified type and runs all tests.
/// </summary>
/// <param name="type">Type to be covered with tests.</param>
/// <param name="timeout">Timeout for code exploration in seconds. Negative value means infinite timeout (up to exhaustive coverage or user interuption).</param>
/// <param name="outputDirectory">Directory to place generated *.vst tests. If null or empty, process working directory is used.</param>
/// <param name="options">Additional parameters of the run.</param>
/// <returns>True if all generated tests have passed.</returns>
/// <exception cref="ArgumentException">Thrown if specified class does not contain public methods.</exception>
public static bool CoverAndRun(Type type, int timeout = -1, string outputDirectory = "")
public static bool CoverAndRun(Type type, CoverOptions options = new())
{
var stats = Cover(type, timeout, outputDirectory);
var stats = Cover(type, options);
return Reproduce(stats.OutputDir);
}

/// <summary>
/// Generates test coverage for all public methods of all public classes of the specified assembly and runs all tests.
/// </summary>
/// <param name="assembly">Assembly to be covered with tests.</param>
/// <param name="timeout">Timeout for code exploration in seconds. Negative value means infinite timeout (up to exhaustive coverage or user interuption).</param>
/// <param name="outputDirectory">Directory to place generated *.vst tests. If null or empty, process working directory is used.</param>
/// <param name="options">Additional parameters of the run.</param>
/// <returns>True if all generated tests have passed.</returns>
/// <exception cref="ArgumentException">Thrown if no public methods found in assembly.
/// </exception>
public static bool CoverAndRun(Assembly assembly, int timeout = -1, string outputDirectory = "")
public static bool CoverAndRun(Assembly assembly, CoverOptions options = new())
{
var stats = Cover(assembly, timeout, outputDirectory);
var stats = Cover(assembly, options);
return Reproduce(stats.OutputDir);
}

/// <summary>
/// Generates test coverage for entry point of the specified assembly and runs all tests.
/// </summary>
/// <param name="assembly">Assembly to be covered with tests.</param>
/// <param name="args">Command line arguments of entry point</param>
/// <param name="timeout">Timeout for code exploration in seconds. Negative value means infinite timeout (up to exhaustive coverage or user interuption).</param>
/// <param name="outputDirectory">Directory to place generated *.vst tests. If null or empty, process working directory is used.</param>
/// <param name="args">Command line arguments of entry point.</param>
/// <param name="options">Additional parameters of the run.</param>
/// <returns>True if all generated tests have passed.</returns>
/// <exception cref="ArgumentException">Thrown if assembly does not contain entry point.</exception>
public static bool CoverAndRun(Assembly assembly, string[] args, int timeout = -1, string outputDirectory = "")
public static bool CoverAndRun(Assembly assembly, string[] args, CoverOptions options = new())
{
var stats = Cover(assembly, args, timeout, outputDirectory);
var stats = Cover(assembly, args, options);
return Reproduce(stats.OutputDir);
}

Expand Down
Loading