85int main(
int argc,
char **argv) {
86 llvm::sys::PrintStackTraceOnErrorSignal(llvm::StringRef());
87 llvm::setBugReportMsg(
89 " and include the crash backtrace, relevant LLZK files, and associated run script(s).\n"
92 llvm::cl::ParseCommandLineOptions(
94 "llzk-witgen: execute LLZK compute semantics and emit JSON public outputs.\n"
95 "Note: llzk-witgen v1 ignores constrain() and traps on bool.assert.\n"
98 DialectRegistry registry;
100 mlir::func::registerInlinerExtension(registry);
102 mlir::arith::ArithDialect, mlir::cf::ControlFlowDialect, mlir::func::FuncDialect,
103 mlir::memref::MemRefDialect, mlir::scf::SCFDialect>();
105 context.appendDialectRegistry(registry);
106 context.loadAllAvailableDialects();
108 mlir::arith::ArithDialect, mlir::cf::ControlFlowDialect, mlir::func::FuncDialect,
109 mlir::memref::MemRefDialect, mlir::scf::SCFDialect>();
114 auto sourceBuffer = llvm::MemoryBuffer::getFileOrSTDIN(InputFilename);
116 llvm::errs() << sourceBuffer.getError().message() <<
'\n';
120 ParserConfig parserConfig(&context);
121 OwningOpRef<ModuleOp> moduleOp =
122 parseSourceString<ModuleOp>(sourceBuffer.get()->getBuffer(), parserConfig, InputFilename);
127 auto buffer = llvm::MemoryBuffer::getFileOrSTDIN(InputsFilename);
129 llvm::errs() << buffer.getError().message() <<
'\n';
133 auto parsed = llvm::json::parse(buffer.get()->getBuffer());
135 llvm::errs() <<
"failed to parse JSON input: " << llvm::toString(parsed.takeError()) <<
'\n';
140 if (BackendName ==
"execution-engine") {
142 }
else if (BackendName ==
"interpreter") {
145 llvm::errs() <<
"unknown backend: " << BackendName <<
'\n';
148 if (OutputScopeName ==
"full-witness") {
150 }
else if (OutputScopeName ==
"public") {
153 llvm::errs() <<
"unknown output scope: " << OutputScopeName <<
'\n';
156 if (UninitializedBehaviorName ==
"zero") {
158 }
else if (UninitializedBehaviorName ==
"random") {
160 }
else if (UninitializedBehaviorName ==
"fail") {
163 llvm::errs() <<
"unknown uninitialized behavior: " << UninitializedBehaviorName <<
'\n';
166 if (UninitializedSeed.getNumOccurrences() > 0) {
172 if (WtnsOutputFilename.getNumOccurrences() > 0) {
173 if (WtnsOutputFilename ==
"-") {
174 llvm::errs() <<
"--output-wtns does not support stdout; specify an output file\n";
177 if (OutputScopeName.getNumOccurrences() > 0 && OutputScopeName !=
"full-witness") {
178 llvm::errs() <<
"--output-wtns conflicts with --output-scope=" << OutputScopeName
179 <<
"; use --output-scope=full-witness\n";
188 llvm::errs() <<
"llzk-witgen error: " << llvm::toString(result.takeError()) <<
'\n';
192 if (WtnsOutputFilename.getNumOccurrences() > 0) {
198 llvm::errs() <<
"llzk-witgen error: .wtns output requires exactly one field\n";
201 const llzk::Field &field = (*fields.begin()).get();
203 llvm::errs() <<
"llzk-witgen error: " << llvm::toString(std::move(error)) <<
'\n';
208 if (CheckOutputFilename.getNumOccurrences() > 0) {
209 auto expectedBuffer = llvm::MemoryBuffer::getFileOrSTDIN(CheckOutputFilename);
210 if (!expectedBuffer) {
211 llvm::errs() << expectedBuffer.getError().message() <<
'\n';
215 auto expected = llvm::json::parse(expectedBuffer.get()->getBuffer());
217 llvm::errs() <<
"failed to parse expected JSON output: "
218 << llvm::toString(expected.takeError()) <<
'\n';
222 llvm::SmallVector<llzk::witgen::JSONMismatch> mismatches;
224 if (!mismatches.empty()) {
225 llvm::errs() <<
"llzk-witgen output mismatch:\n";
230 llvm::outs() <<
"output matched expected JSON\n";
234 llvm::outs() << llvm::formatv(
"{0:2}", *result) <<
'\n';
void diffJSON(const llvm::json::Value &expected, const llvm::json::Value &actual, llvm::SmallVectorImpl< JSONMismatch > &out, llvm::StringRef path)
Compare two JSON values structurally and append any mismatches to out.
llvm::Expected< llvm::json::Value > runWitgen(ModuleOp moduleOp, const llvm::json::Value &input, const WitgenOptions &options)
Run include preprocessing, field validation, and backend execution.