blob: 996ede416f0aecff71fbc36c29d64cf7d41b0d26 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
|
// SPDX-License-Identifier: Apache-2.0
package firrtlTests
import firrtl.FileUtils
import firrtl.{ChirrtlForm, CircuitState}
import firrtl.testutils._
import scala.concurrent.duration.Duration
import scala.concurrent.{Await, ExecutionContext, Future}
class MultiThreadingSpec extends FirrtlPropSpec {
// TODO Test with annotations and source locator
property("The FIRRTL compiler should be thread safe") {
// Run the compiler we're testing
def runCompiler(input: Seq[String], compiler: firrtl.Compiler): String = {
val parsedInput = firrtl.Parser.parse(input)
val res = compiler.compileAndEmit(CircuitState(parsedInput, ChirrtlForm))
res.getEmittedCircuit.value
}
// The parameters we're testing with
val compilers = Seq(
new firrtl.HighFirrtlCompiler,
new firrtl.MiddleFirrtlCompiler,
new firrtl.LowFirrtlCompiler,
new firrtl.VerilogCompiler
)
val inputFilePath = s"/integration/GCDTester.fir" // arbitrary
val numThreads = 64 // arbitrary
// Begin the actual test
val inputStrings = FileUtils.getLinesResource(inputFilePath).toSeq
import ExecutionContext.Implicits.global
try { // Use try-catch because error can manifest in many ways
// Execute for each compiler
val compilerResults = compilers.map { compiler =>
// Run compiler serially once
val serialResult = runCompiler(inputStrings, compiler)
Future {
val threadFutures = (0 until numThreads).map { i =>
Future {
runCompiler(inputStrings, compiler) == serialResult
}
}
Await.result(Future.sequence(threadFutures), Duration.Inf)
}
}
val results = Await.result(Future.sequence(compilerResults), Duration.Inf)
assert(results.flatten.reduce(_ && _)) // check all true (ie. success)
} catch {
case _: Throwable => fail("The Compiler is not thread safe")
}
}
}
|