jvm - Firrtl 在输入较大时耗尽堆内存

标签 jvm out-of-memory chisel

我尝试在 110MB Firrtl 文件上运行 verilog 编译器传递,尽管给它提供了宽敞的 12G 堆空间来使用,但我始终遇到内存不足错误。看来问题出在解析器上,特别是 ANTLR,生成了太多的 ArrayList。对于 Firrtl 电路定义来说 110MB 是否太大了?

该文件是通过 Firrtl 使用 Chisel 和 --compiler=high 生成的。我的 Firrtl 版本是 1.2-SNAPSHOT(本地构建),Chisel 是 3.2-SNAPSHOT(也是本地构建)。

$ JAVA_OPTS="-Xms8G -Xmx12G" ../firrtl/utils/bin/firrtl -i mnist_cnn_v4.fir -o mnist_cnn_v4.v -X verilog --no-check-comb-loops --no-dce --info-mode=ignore -ll Trace
> Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
    at java.base/java.util.Arrays.copyOf(Arrays.java:3688)
    at java.base/java.util.ArrayList.grow(ArrayList.java:236)
    at java.base/java.util.ArrayList.grow(ArrayList.java:241)
    at java.base/java.util.ArrayList.add(ArrayList.java:466)
    at java.base/java.util.ArrayList.add(ArrayList.java:479)
    at org.antlr.v4.runtime.ParserRuleContext.addAnyChild(ParserRuleContext.java:134)
    at org.antlr.v4.runtime.ParserRuleContext.addChild(ParserRuleContext.java:145)
    at org.antlr.v4.runtime.Parser.consume(Parser.java:584)
    at firrtl.antlr.FIRRTLParser.intLit(FIRRTLParser.java:2870)
    at firrtl.antlr.FIRRTLParser.type(FIRRTLParser.java:600)
    at firrtl.antlr.FIRRTLParser.field(FIRRTLParser.java:740)
    at firrtl.antlr.FIRRTLParser.type(FIRRTLParser.java:647)
    at firrtl.antlr.FIRRTLParser.field(FIRRTLParser.java:740)
    at firrtl.antlr.FIRRTLParser.type(FIRRTLParser.java:647)
    at firrtl.antlr.FIRRTLParser.field(FIRRTLParser.java:740)
    at firrtl.antlr.FIRRTLParser.type(FIRRTLParser.java:647)
    at firrtl.antlr.FIRRTLParser.port(FIRRTLParser.java:418)
    at firrtl.antlr.FIRRTLParser.module(FIRRTLParser.java:287)
    at firrtl.antlr.FIRRTLParser.circuit(FIRRTLParser.java:189)
    at firrtl.Parser$.$anonfun$parseCharStream$1(Parser.scala:42)
    at firrtl.Parser$$$Lambda$94/1642030774.apply(Unknown Source)
    at firrtl.Utils$.time(Utils.scala:186)
    at firrtl.Parser$.parseCharStream(Parser.scala:33)
    at firrtl.Parser$.parseFile(Parser.scala:25)
    at firrtl.Driver$.$anonfun$getCircuit$5(Driver.scala:200)
    at firrtl.Driver$$$Lambda$93/1571967156.apply(Unknown Source)
    at scala.Option.getOrElse(Option.scala:121)
    at firrtl.Driver$.$anonfun$getCircuit$3(Driver.scala:183)
    at firrtl.Driver$$$Lambda$91/802600647.apply(Unknown Source)
    at scala.Option.getOrElse(Option.scala:121)
    at firrtl.Driver$.$anonfun$getCircuit$1(Driver.scala:183)
    at firrtl.Driver$$$Lambda$88/2041416495.apply(Unknown Source)

最佳答案

这是解析器的已知限制,有两种解决方法,如 Jack 所建议。在 this comment :

  1. 使用protobuf作为 Chisel 和 FIRRTL 之间的接口(interface)。使用 chisel3.Driver.dumpProto,而不是使用 chisel3.Driver.dumpFirrtl。 FIRRTL 命令行实用程序将自动将 .pb 文件推断为 protobuf,并使用适当的反序列化器而不是 ANTLR 解析器。

  2. 使用chisel3.Driver直接调用FIRRTL,而不是使用FIRRTL命令行实用程序。这仍然会导致发出 FIRRTL 供您检查,但在内部,Chisel 表示形式会直接转换为 FIRRTL,而不经过解析。尝试:

val args = Array("-o", "mnist_cnn_v4.v",
                 "-X", "verilog",
                 "--no-check-comb-loops",
                 "--no-dce",
                 "--info-mode=ignore",
                 "-ll Trace")

chisel3.Driver.execute(args, () => new Foo) /* change Foo to your top module */

后一个内存中转换已添加到Chisel3#829中并在 FIRRTL#832 中添加了 protobuf 支持。 jack 在那里引用了一些实验 reading a 420MB FIRRTL file using different methods 。总之,如果您有大的 FIRRTL 文件,请尽量避免使用解析器。

关于jvm - Firrtl 在输入较大时耗尽堆内存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53245026/

相关文章:

chisel - 如何将已弃用的低 Firrtl 转换转换为依赖项 API

scala - 解决大型 Chisel 文件所触发的 JVM 代码大小限制的任何方法

java - 使用 Nailgun 与 netcat 为 Java 应用程序提供快速 CLI 的优缺点是什么?

java - Volatile 关键字和线程本地内存

clojure - 内存不足错误: GC overhead limit exceeded Criterium

android - 从家回来后应用程序崩溃

chisel - 如何软重置凿子计数器

java - java类加载器是否验证方法体?

java - 然而Eclipse错误: Incompatible JVM,,无法更新JVM

php - 确定 PHP 在 OOM 终止期间正在做什么?