{'fraction_non_alphanumeric': 0.02972092678954771, 'fraction_numerical': 0.012510178399585462, 'mean_word_length': 4.606764888981116, 'pattern_counts': {'":': 0, '<': 2, '<?xml version=': 0, '>': 2, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
Reproducible Efficient Parallel SAT Solving

In this paper, we propose a new reproducible and efficient parallel SAT solving algorithm. Unlike sequential SAT solvers, most parallel solvers do not guarantee reproducible behavior due to maximizing the performance. The unstable and non-deterministic behavior of parallel SAT solvers hinders a wider adoption of parallel solvers to the practical applications. In order to achieve robust and efficient parallel SAT solving, we propose two techniques to significantly reduce idle time in deterministic parallel SAT solving: delayed clause exchange and accurate estimation of execution time of clause exchange interval between solvers. The experimental results show that our reproducible parallel SAT solver has comparable performance to non-deterministic parallel SAT solvers even in a many-core environment.


Introduction
Most modern computers have multiple cores, and the number of cores is increasing. To exploit the performance of multi-core systems, parallel processing software which efficiently utilizes each core is required. The same applies to SAT solvers, and parallel SAT solving is an active area of research. The parallel track of the SAT Competition is continuously held since 2011 1 .
There are mainly two approaches of parallel SAT solving: portfolio and divide-and-conquer approaches. The former approach launches multiple SAT solvers with different search strategies in parallel, and each solver tries to solve the same SAT instance competitively [1,2,4]. The latter approach divide a given SAT instance in an attempt to distribute the total workload among computing units, and then solve them in parallel [5][6][7]10,12,13]. In both approaches, clause exchange techniques are combined into parallel systems in order to share the pruning information of the search space between solvers [1,2,4,11,12].
Most of parallel SAT solvers do not provide reproducible behavior in both runtime and found solutions due to maximizing the performance. Even for the same instance and computational environment, the execution time often varies for each run, and found models or unsatisfiability proofs may also differ. This is because there is no specific order in clause exchange between computing units. The timing of sending and receiving clauses can change due to system workload, cache misses and/or communication delays. The non-deterministic behavior of parallel SAT solvers causes various difficulties. In model checking, one may find different bugs (corresponding to satisfiable assignments) for each run. In the case of scheduling, even if a good solution is found, it may not be reproduced next time. If a bug occurs in software with an embedded non-deterministic SAT solver, the bug may not be reproduced. Researchers of parallel SAT solvers should have a number of experiments for stable evaluation of solvers. In contrast, most sequential SAT solvers guarantee reproducible behavior. The above-mentioned issues can be avoided if we use sequential SAT solvers. Reproducibility is thus an important property that directly affects the usability of SAT solvers as tools.
ManySAT 2.0 [3] is the first parallel SAT solver that supports reproducible behavior 2 . It is a portfolio parallel SAT solver for shared memory multi-core systems. To achieve deterministic behavior, it periodically synchronizes all threads, each of which executes a SAT solver, before and after the clause exchange. After the former synchronization, each solver exchanges clauses according to a specific order of threads until the latter synchronization. In ManySAT, all threads need to be synchronized periodically. Hence, waiting threads frequently occur as the number of CPU cores increases. As a result, there is a performance gap between deterministic and non-deterministic modes of ManySAT.
In this paper, we present two techniques to reduce the waiting time of threads: (1) delayed clause exchange and (2) refining the interval of clause exchange. The former suppresses the fluctuation of intervals between clause exchange, and the latter enables accurate prediction of exchange timing. We demonstrate that our approach significantly reduces the waiting time of threads and achieves the comparable performance with non-deterministic parallel SAT solvers even in a many-core environment 3 .
The outline of this paper is as follows. The next section experimentally demonstrates the non-deterministic and unstable behavior of parallel SAT solvers. Section 3 describes the mechanism of ManySAT to realize the reproducibility and shows the experimental evaluation of the performance. In Sects. 4 and 5, we present two techniques in order to reduce the waiting time: delayed clause exchange and refining the interval of clause exchange, respectively. Experimental results are presented in Sect. 6. We conclude in Sect. 7.

Non-deterministic Behavior in Parallel SAT Solvers
In this section, we reexamine the unreproducible behavior of existing parallel SAT solvers. Here we consider ManySAT and Glucose-syrup as such parallel solvers developed for shared memory multi-core systems. ManySAT is the first portfolio parallel SAT solver [4] developed as a non-deterministic parallel solver, Table 1. Solved instances on SAT Competition 2018 and SAT Race 2019 (800 instances in total). "X (Y + Z)" denotes the number of solved instances (X), solved satisfiable instances (Y) and solved unsatisfiable instances (Z), respectively. Non-deterministic solvers (ManySAT with non-det and Glucose-syrup) were run three times, and the first and last lines of the results denote the best and worst results, respectively.   Table 1. In this work, we conducted all experiments on the following two computing environments: (1) a cluster equipped with 4-core Intel Core i5-6600 (3.3 GHz) machines using a memory limit of 8 GB, and (2) a cluster equipped with 68-core Intel Xeon Phi KNL (1.4 GHz) machines using a memory limit of 96 GB 4 . The time limit was set to 5000 s. We ran each solver with 4 threads on the first environment and 64 threads on the second. "ManySAT 2.0 with non-det" denotes the non-deterministic mode of ManySAT, and "det-static" and "det-dynamic" mean the two deterministic modes described in the next section.
The results of non-deterministic solvers show that different runs yield different numbers of solved instances. For Glucose-syrup, the difference between the best and worst results is 7 and 9 instances on the 4 and 64 threads environments, respectively. Figure 1 gives scatter plots comparing the runtimes for each instance in which we compared the best and worst results of Glucose-syrup. The runtimes of satisfiable instances vary greatly with runs. Unsatisfiable instances have more stable results but there are some instances solved by either one. Such behavior is typically encountered when using parallel SAT solvers.
Clause exchange is a cooperative and fundamental mechanism in parallel SAT solvers in order to share the pruning information of the search space between computing units. Typically, the timing of sending and receiving clauses is affected by system workload, cache misses, and/or communication delays. However, most of parallel SAT solvers do not have synchronization mechanism of the timing in order to avoid the communication overhead and to maximize the performance. This is the cause of unreproducible behavior of parallel SAT solvers.

A Deterministic Parallel SAT Solver
In this section, we describe the algorithm called deterministic parallel DPLL ((DP) 2 LL in short) proposed by [3] which is implemented in the first deterministic parallel SAT solver ManySAT 2.0. The pseudo code is shown in Algorithm 1. Let n be the number of solvers to be executed in parallel. Firstly, n threads are launched to execute the function search() (lines 2 and 4). Each thread is identified by an ID number t ∈ {1, . . . , n}. After all threads have finished (line 5), the algorithm outputs the solution obtained by the thread with the lowest thread ID among all the threads which succeeded to decide the satisfiability of the instance (line 6). The reason for choosing the lowest ID is to avoid non-deterministic behavior if two or more threads find solutions at the same time.
The function search() (lines 8-25) is the same as usual CDCL solvers, except for sending and receiving clauses. Each thread periodically receives clauses from the other threads. We call the reception interval a period. The function endOfPeriod () decides whether the current period has ended (line 10). In ManySAT, it returns true when the number of conflicts in the period exceeds a certain threshold. In that case, all threads are synchronized before and after clause exchange by "< barrier >" instruction 5 (lines 11 and 14). The former barrier is necessary for each thread to start importing clauses simultaneously. Suppose that a thread starts importing clauses at the end of period x. The latter barrier prevents the thread importing a clause which is exported from another thread at the next period x + 1. In order to avoid deadlocks, when a thread finds foreach i ∈ 1, · · · , t − 1, t + 1, · · · , n do 28 import clauses from thread i; a solution (lines 18 and 25), it needs to go to the first barrier on line 11 instead of exiting immediately. This is because other threads that have not found a solution are waiting there. After synchronization, each thread t exits with its own status ans t , if any thread finds a solution (line 12). The function importExtraClauses() receives learnt clauses acquired by the other threads according to a fixed order of the threads (line 27), because different ordering of clauses will trigger off different ordering of unit propagations and consequently different behavior. The rest of the search function follows CDCL algorithm. The propagate() function (line 15) applies unit propagation (or Boolean constraint propagation) and returns false if a conflict occurs, and true otherwise. In the former case, if the conflict occurs without any decision (line 16), it means the unsatisfiability is proved. Otherwise, a cause of the conflict is analyzed (line 19) and a clause is learnt to prevent occurring the same conflict. If the learnt clause is eligible for export (for example, the length is short), it is marked to export. These exported clauses are periodically imported by the function importExtraClauses(). In the latter case, the function decide() chooses an unassigned variable as the next  decision and assigns it true or false (line 23). Otherwise it returns false as all the variable are assigned, that is, a model is found. This (DP) 2 LL algorithm periodically requires synchronization with all threads. Runtime variation of periods on each thread causes idle time for each synchronization, that is, each thread should wait the slowest threads. A simple way to suppress the variation is to measure the execution time of threads and synchronize based on the elapsed time. However, the measurement of CPU or real time usually contains errors, so this approach is hard to hold reproducibility. In ManySAT, the length of a period is defined as the number of conflicts. There are two kinds of definitions of the period: static and dynamic. The static period is simply defined as a fixed number c of conflicts (c = 700 in default). The dynamic period is intended to provide a better approximation of progression speed of each solver. Let L k t denote the length of the k-th period of a thread t, defined as is the ratio of the number of learnt clauses held by the thread t to the maximum number of learnt clauses among all threads at the (k − 1)-th period. In this modeling, a thread with a large (or small) number of learnt clauses (the ratio tending to 1 (or 0)) is considered to be slow (or fast) and the length of period becomes shorter (or longer).
In Table 1, "det-static" and "det-dynamic" denote the results of the static and dynamic periods, respectively. There is a performance gap between deterministic and non-deterministic solvers. The cause is high waiting time ratio to the running time. Figure 2 shows the waiting time ratio of ManySAT for each instance, and the ratio on all instances is shown in Table 2. In our experiments, the waiting time ratio of the static period is lower than dynamic, but it reaches 23% for 4 threads and 40% for 64 threads environments. These results indicate that it is difficult to realize efficient solving by synchronizing all threads in a many-core environment.

Delayed Clause Exchange
In order to reduce the idle time in deterministic parallel SAT solvers, we propose a new clause exchange schema called delayed clause exchange (DCE). Figure 3 shows the runtime distribution of the static periods in ManySAT for two instances. These results indicate that the execution time of periods fluctuates very frequently, but in the long term it seems to be stable (roughly, 0.005 s for (a), 0.05 s for (b)). Other instances have a similar tendency. In order to take advantage of this property and absorb frequent fluctuations, we consider allowing clause reception to be delayed for a certain number of periods. Let n be the number of threads, T = {1, . . . , n} the set of thread IDs, p t the current period ID of a thread t ∈ T (p t ≥ 1), E p t a set of clauses exported by a thread t at a period p and m an admissible delay, called margin, is denoted by the number of periods (m ≥ 0). Algorithm 2 shows the pseudo code of (DP) 2 LL with DCE. There are two differences from Algorithm 1. The first point is clause reception. For each thread t, when the current period p t ends, then the thread increments the current period ID (line 14) and imports clauses from the other threads (line 15). If another thread i has not yet finished the period p t − m (that is, p i < p t − m), then the thread t should wait for it to complete (line 25). After that, the thread t imports E pt−m i . The second point concerns termination conditions. When multiple threads find solutions in DCE, to keep reproducibility, the algorithm select a thread that found at the earliest period. In case of a tie, the thread with the lowest ID is selected (line 7). Running threads that have Note that when m = 0, (DP) 2 LL with DCE is same as (DP) 2 LL. DCE can reduce the total waiting time of threads. Firstly, we consider the best case of DCE. At some point, if for any two threads i, j ∈ T (i = j) the difference p i − p j is less than or equal to m, then any thread can import clauses immediately without waiting for other threads at the point. This is because a set of clauses to be imported had already been exported by other threads. Secondly, the worst case is that only one thread is extremely slow and all other threads are ahead by m periods. In this case, the fast |T | − 1 threads must wait the slowest thread until the difference less than or equal to m. In other cases, if there exists two threads i, j ∈ T such that p i − p j > m, then the preceding thread i should wait the postdating thread j until the difference less than or equal to m. The execution time of periods fluctuates frequently, but if the total execution time of m consecutive periods is almost the same for each thread, the DCE can be expected to reduce the waiting time. The disadvantage of DCE is that the clause reception is always delayed by m periods, even if there is no difference in the period of each thread.

Refining Periods
In ManySAT, the length of a period is defined as the number of conflicts. The generation speed of conflicts is affected by the number and length of clauses. The number of clauses varies during search by learning and reduction of clauses, and the length of learnt clauses also changes sometimes significantly. As the result, runtime of a period fluctuates frequently as shown in Fig. 3. Accurate estimation of period execution time is important to reduce the waiting time. In this section, we introduce two new definitions of a period based on reproducible properties.

Refinement Based on Literal Accesses
Most of the memory used by SAT solvers is occupied by literals in clauses. Accessing literals in memory is a fundamental operation and occurs very frequently in unit propagation, conflict analysis, and so on. We consider defining the length of a period as the number of accesses to literals. The speed of accessing literals can be considered to be more stable than the generation speed of conflicts since it is almost independent of the number and length of clauses. With this definition, the function endOfPeriod () (line 12 in Algorithm 2) returns true if the number of literal accesses in the period exceeds a certain threshold. In our implementation, we count the number of accesses to literals in unit propagation, conflict analysis and removal of clauses that are satisfied without any decision.

Refinement Based on Block Executions
In order to estimate the runtime of a period more accurately, we consider measuring not only the number of literal accesses, but also the number of executions of various operations performed by a SAT solver. It is similar to profiling a program which measures the number of calls and runtime of each function to detect performance bottlenecks. As a finer granularity than functions, we focus on compound statements called blocks (statements enclosed in curly braces in C ++ ) and measure the number of the executions of each block during the search. For example, the runtime of one call of propagate() (line 16 in Algorithm 2) depends obviously on a given instance (proportional to the number of clauses). Whereas propagate() has a loop block that checks the value of each literal in a clause to determine whether the clause is unit or falsified. The time to execute the block once can be considered almost constant. We apply linear regression analysis to estimate the time required for one execution of each block.
Let n be the number of blocks to be measured, x i,j k the number of executions of a block k of a thread j in an instance i, d k the runtime to be required for one execution of a block k, and y i,j the execution time of a thread j in an instance i without waiting time. Each d k is non-negative. Hence, if a block k has a nested block l, d k indicates the execution time of k excluding l. Then, y i,j can be expressed as: With this definition, the function endOfPeriod () returns true if the value of (1) in a period exceeds a certain threshold.
Our developed deterministic parallel SAT solver (introduced in the next section) counts the number of executions for 71 blocks that almost cover the whole of operations performed by the solver. We used the application instances of SAT Competition 2016 and 2017 (300 and 350 instances, respectively) as training instances to estimate each d k . The evaluation was performed on the 64 threads environment with a time limit of 600 s. To avoid overfitting, we manually selected 29 out of 71 blocks, which are mainly contained in unit propagation, conflict analysis and search loop (corresponding to search() function in Algorithm 2). Then, we estimated the regression coefficients d k from the results using the Elastic Nets method [14]. The coefficient of determination (R 2 ) was 0.94. Figure 4 shows the results of prediction of thread execution time on SAT Competition 2018 as testing instances. Most of estimated results are close to the observed one. Some points are far from observations, but such points of the same color are often equidistant from observations. This means that the difference between the predicted and the observed time is approximately the same for each thread that solves the same instance, and in such cases, synchronization between threads can be expected to have less idle time.

Experimental Results
We have developed a new deterministic parallel SAT solver called ManyGlucose based on Glucose-syrup 4.1, which implements the delayed clause exchange and three types of periods (one is conflict based period used in ManySAT and the others are described in the previous section). In this work, we set the margin to a fixed value of 20 and adjust the length of the three types of periods. Suppose that p conf , p accs and p exec denote the length of a period based on the number of Table 3. Results of three types of periods. In this evaluation, we executed ManyGlucose with margin 20 for 400 instances used in SAT Competition 2018 for the 4 threads environment. The best result of each column in (a) is typeset in boldface. conflicts, literal accesses and block executions (corresponding to the threshold in the function endOfPeriod ()). We determine the appropriate length of each period by preliminary experiments. Table 3 shows the results of three types of periods. As the length of period becomes longer, the waiting time is reduced since the number of clause exchanges is diminished, but the number of solved instances also tends to decreases. There is a trade-off between the number of clause exchanges and solved instances. From these results, we determined the appropriate length for each period type to be p conf = 100, p accs = 2M , and p exec = 0.5. Table 3 (b) denotes that the period based on the block executions has the smallest waiting time ratio. The average runtime of periods when p exec = 0.5 is 0.109 s. Hence, with this setting, time delay to receive learnt clauses acquired by other threads is about 2 s (0.109 * 20). Figure 5 shows the runtime distribution of periods based on these thresholds for some instances. These are results of unsolved instances by ManyGlucose without DCE within a 1000 s time limit (that is, the right end of x-axis corresponds to 1000 s). The execution time per period is normalized by the z-score to compare three period types. These graphs show that the period based on conflicts has large amplitude, and the block executions has small amplitude. For most instances, the block executions shows the best results, but Fig. 5 (c) is an example in which the literal access shows the best results.
We ran ManyGlucose configured with three types of periods and with and without DCE for the application instances used in SAT Competition 2018 and SAT Race 2019 in the 4 and 64 threads environments using the parameters obtained in the preliminary experiment (that is, p conf = 100, p accs = 2M , and p exec = 0.5). ManyGlucose with DCE and block executions were run three times to show the robustness of our deterministic parallel SAT solver. Table 4 shows the number of solved instances and waiting time ratio for each solver and  For the ratio of waiting time, DCE reduces approximately 24%, 32% and 35% in conflict, literal access and block execution based periods than without DCE, respectively. The ratio of waiting time in 64 threads is greater than in 4 threads. When using block execution based period, it increases about 3.5 times without DCE (12.5% to 44.0%), but 1.5 times with DCE (5.7% to 8.8%). This means DCE is more effective in many-core systems. The regression coefficients of block execution based period are estimated in the 64 threads environment. Figure 7(a) shows that it is effective for reducing the waiting time even in the different environment. The difference of average runtime per period between 4 and 64 threads denotes the performance gap of sequential computation of each system. The 64 threads environment has a large number of CPU cores, although the sequential computing performance is not high. In the 64 threads environment, time delay to receive learnt clauses acquired by other threads is about 8 to 12 s.
Compared with Glucose-syrup, ManyGlucose shows the stable results due to its determinism. In the results of running ManyGlucose with DCE and block execution based period three times, the difference between the best and worst Table 4. Results of (a) solved instances and (b) waiting time ratio on SAT Competition 2018 and SAT Race 2019. Results of Glucose-syrup are same as Table 1. The best result of each column in (a) is typeset in boldface. "confs", "lit accs" and "blk execs" mean the period type based on conflicts, literal accesses and block executions, respectively. results is 2 instances in the 4 threads and no difference in the 64 threads environment. We have confirmed that ManyGlucose can find the same model for each run for satisfiable instances. Our 4 threads environment is a cluster built on educational PCs and cannot be used exclusively, and the results fluctuate slightly. In contrast, the results of 64 threads are very stable due to the exclusive use of the system. Figure 8 shows comparisons of runtime of each instance in the best and worst results. The results for 4 threads vary slightly over time, while the results for 64 threads are almost completely distributed on the diagonal. In contrast to    The number of solved instances in the best case of ManyGlucose exceeds the worst case of Glucose-syrup. This indicates that DCE and accurate period estimation can achieve performance comparable to non-deterministic solvers while holding deterministic behavior. Figure 9 shows the time ratio required for clause exchange, which is very small ratio compared to the solving and waiting time. In DCE, for each thread t and each period p, there is a database E p t that stores clauses exported by the thread t at the period p. If the current period of the thread t is greater than p, then write access to E p t no longer exists, so any thread can read it without mutual exclusive control. In contrast, shared clause databases in non-deterministic parallel SAT solvers usually have a mixture of write access to add clauses and read access to get clauses. Hence, the mutual exclusive control is required to access the clause database. One of the advantages of DCE is that it does not require the cost of mutual exclusive control to access clause databases.

Conclusion
The non-deterministic behavior of parallel SAT solvers is one of the obstacles to the promotion of application and research of parallel SAT solvers. In this paper, we have presented techniques to realize efficient and reproducible parallel SAT solving. The main technique is the delayed clause exchange (DCE), which absorbs fluctuations of intervals between clause exchanges. In order to enhance the effect of DCE, it is important to estimate exchange intervals accurately based on reproducible criterion. In this work, we presented two methods based on the number of literal accesses and block executions. The experimental results show that the combination of these techniques can achieve comparable performance to non-deterministic parallel SAT solvers even in many-core environments. Our approach can be applicable to deterministic parallel MaxSAT solving [9] which is based on the synchronization mechanism used in ManySAT. As future work it would be interesting to consider a general framework for building deterministic parallel SAT solvers (like PaInleSS [8] for non-deterministic parallel SAT solvers) in which state-of-the-art sequential solvers can easily participate.