Skip to content
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
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
4 changes: 4 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,7 @@
path = test/benchmark/CGRA-Bench
url = https://github.com/tancheng/CGRA-Bench.git
ignore = all
[submodule "test-benchmark-zeonica-testbench"]
path = test/benchmark/Zeonica_Testbench
url = https://github.com/sarchlab/Zeonica_Testbench.git
ignore = all
12 changes: 12 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,3 +56,15 @@ Build LLVM & Neura
$ /workspace/llvm-project/build/bin/llvm-lit test.mlir -v
```

Sync `test/e2e` outputs into Zeonica_Testbench (submodule)
--------------------------------------------------------
This repo vendors [`sarchlab/Zeonica_Testbench`](https://github.com/sarchlab/Zeonica_Testbench.git) as a git submodule at `test/benchmark/Zeonica_Testbench`.

After running e2e compilation/tests, you can sync the generated artifacts into the testbench repo:
```sh
$ ./tools/sync_e2e_outputs_to_zeonica_testbench.sh
```

Mapping (per kernel `K`):
- `test/e2e/K/tmp-generated-dfg.{dot,yaml}` -> `test/benchmark/Zeonica_Testbench/kernel/K/K-dfg.{dot,yaml}`
- `test/e2e/K/tmp-generated-instructions.{asm,yaml}` -> `test/benchmark/Zeonica_Testbench/kernel/K/K-instructions.{asm,yaml}`
142 changes: 71 additions & 71 deletions lib/NeuraDialect/Transforms/GenerateCodePass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -595,8 +595,8 @@ struct GenerateCodePass
setUniqueDestination(pi, producer_direction.str());
else if (!regs.empty())
setUniqueDestination(pi, "$" + std::to_string(regs.back().regId));
}
}
}

// Egress: on source tile at first_link_ts, move [$src_reg] -> [out_dir].
void placeSrcEgress(const Topology &topology, int src_tile_id, int time_step,
Expand Down Expand Up @@ -706,8 +706,8 @@ struct GenerateCodePass
const bool should_rewire_to_register =
IsCtrl || (consumer_placement.time_step > deposit_time_step);
if (should_rewire_to_register) {
setConsumerSourceExact(consumer_operation, value_at_consumer, "$" + std::to_string(register_id));
return true;
setConsumerSourceExact(consumer_operation, value_at_consumer, "$" + std::to_string(register_id));
return true;
Copy link

Copilot AI Jan 17, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Incorrect indentation: these lines are part of the conditional block starting at line 708 but are not properly indented. They should be indented one level deeper to reflect their scope within the if statement.

Suggested change
setConsumerSourceExact(consumer_operation, value_at_consumer, "$" + std::to_string(register_id));
return true;
setConsumerSourceExact(consumer_operation, value_at_consumer, "$" + std::to_string(register_id));
return true;

Copilot uses AI. Check for mistakes.
}
}
} else {
Expand Down Expand Up @@ -804,7 +804,7 @@ struct GenerateCodePass
} else {
return collectDataMovConsumers(forwarder);
}
}
}

template<bool IsCtrl>
void rewriteMovConsumers(Operation *forwarder,
Expand Down Expand Up @@ -1403,18 +1403,18 @@ struct GenerateCodePass
const std::unordered_set<int> &materialized_ids;

void run() {
DfgNodeMap nodes;
DfgEdgeList edges;
DfgNodeMap nodes;
DfgEdgeList edges;
Copy link

Copilot AI Jan 17, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Incorrect indentation: these variable declarations should be indented one level deeper as they are within the run() method body, not at class level.

Copilot uses AI. Check for mistakes.

DenseMap<Value, SmallVector<Operation *, 2>> reserve_to_ctrl_movs;
DenseMap<Value, SmallVector<Operation *, 2>> reserve_to_ctrl_movs;
Copy link

Copilot AI Jan 17, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Incorrect indentation: this variable declaration should be indented one level deeper to align with the other local variables in the run() method.

Copilot uses AI. Check for mistakes.
pass.collectCtrlMovReserves(func, reserve_to_ctrl_movs);

pass.buildSsaNodesAndEdges(func, reserve_to_ctrl_movs, nodes, edges);

std::vector<std::pair<int,int>> original_edges = edges;
edges.clear();
llvm::SmallDenseSet<std::pair<int,int>, 32> edges_to_skip;
std::vector<HopRewriteInfo> hop_rewrites;
std::vector<std::pair<int,int>> original_edges = edges;
edges.clear();
llvm::SmallDenseSet<std::pair<int,int>, 32> edges_to_skip;
std::vector<HopRewriteInfo> hop_rewrites;
Copy link

Copilot AI Jan 17, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Incorrect indentation: these variable declarations should be indented one level deeper as they are local variables within the run() method body.

Copilot uses AI. Check for mistakes.

pass.collectHopRewrites(func, topology, nodes, original_edges, edges, edges_to_skip, hop_rewrites);

Expand All @@ -1428,9 +1428,9 @@ struct GenerateCodePass
pass.emitDotOutput(nodes, edges);
pass.emitYamlOutput(nodes, edges);

llvm::outs() << "[generate-code] DFG (SSA-based) emitted: nodes=" << nodes.size()
<< ", edges=" << edges.size()
<< " -> tmp-generated-dfg.dot, tmp-generated-dfg.yaml\n";
llvm::outs() << "[generate-code] DFG (SSA-based) emitted: nodes=" << nodes.size()
<< ", edges=" << edges.size()
<< " -> tmp-generated-dfg.dot, tmp-generated-dfg.yaml\n";
Copy link

Copilot AI Jan 17, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Incorrect indentation: this logging statement should be indented one level deeper as it is within the run() method body, not at class level.

Copilot uses AI. Check for mistakes.
}
};

Expand Down Expand Up @@ -1478,40 +1478,40 @@ struct GenerateCodePass
void emitYamlForTile(llvm::raw_fd_ostream &yaml_out, const Tile &tile) {
yaml_out << " - column: " << tile.col_idx << "\n row: " << tile.row_idx
<< "\n core_id: \"" << tile.core_id << "\"\n entries:\n";

// Groups instructions by index_per_ii.
// Groups instructions by index_per_ii.
Copy link

Copilot AI Jan 17, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Incorrect indentation: this comment and the following code block should be indented one level deeper to reflect being within the method body.

Copilot uses AI. Check for mistakes.
IndexGroups index_groups = groupByIndexPerIi(tile.entry.instructions);

yaml_out << " - entry_id: \"entry0\"\n instructions:\n";
for (const auto &index_pair : index_groups) {
int index_per_ii = index_pair.first;
auto operations = index_pair.second;
std::stable_sort(operations.begin(), operations.end(),
[](const Instruction *a, const Instruction *b) {
return a->time_step < b->time_step;
});

yaml_out << " - index_per_ii: " << index_per_ii << "\n operations:\n";
for (const Instruction *inst : operations) {
yaml_out << " - opcode: \"" << inst->opcode << "\"\n";
if (inst->id >= 0)
yaml_out << " id: " << inst->id << "\n";
yaml_out << " time_step: " << inst->time_step << "\n"
<< " invalid_iterations: " << inst->invalid_iterations << "\n";
// sources.
if (!inst->src_operands.empty()) {
yaml_out << " src_operands:\n";
for (const Operand &opnd : inst->src_operands)
yaml_out << " - operand: \"" << opnd.operand << "\"\n color: \"" << opnd.color << "\"\n";
}
// destinations.
if (!inst->dst_operands.empty()) {
yaml_out << " dst_operands:\n";
for (const Operand &opnd : inst->dst_operands)
yaml_out << " - operand: \"" << opnd.operand << "\"\n color: \"" << opnd.color << "\"\n";

yaml_out << " - entry_id: \"entry0\"\n instructions:\n";
for (const auto &index_pair : index_groups) {
Copy link

Copilot AI Jan 17, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Incorrect indentation: these lines should be indented one level deeper as they are within the method body, not at class level.

Copilot uses AI. Check for mistakes.
int index_per_ii = index_pair.first;
auto operations = index_pair.second;
std::stable_sort(operations.begin(), operations.end(),
[](const Instruction *a, const Instruction *b) {
return a->time_step < b->time_step;
});

yaml_out << " - index_per_ii: " << index_per_ii << "\n operations:\n";
for (const Instruction *inst : operations) {
yaml_out << " - opcode: \"" << inst->opcode << "\"\n";
if (inst->id >= 0)
yaml_out << " id: " << inst->id << "\n";
yaml_out << " time_step: " << inst->time_step << "\n"
<< " invalid_iterations: " << inst->invalid_iterations << "\n";
// sources.
if (!inst->src_operands.empty()) {
yaml_out << " src_operands:\n";
for (const Operand &opnd : inst->src_operands)
yaml_out << " - operand: \"" << opnd.operand << "\"\n color: \"" << opnd.color << "\"\n";
}
// destinations.
if (!inst->dst_operands.empty()) {
yaml_out << " dst_operands:\n";
for (const Operand &opnd : inst->dst_operands)
yaml_out << " - operand: \"" << opnd.operand << "\"\n color: \"" << opnd.color << "\"\n";
}
}
}
}
}

void writeYAMLOutput(const ArrayConfig &config) {
Expand Down Expand Up @@ -1561,36 +1561,36 @@ struct GenerateCodePass

void emitAsmForTile(llvm::raw_fd_ostream &asm_out, const Tile &tile) {
asm_out << "PE(" << tile.col_idx << "," << tile.row_idx << "):\n";

// Groups instructions by index_per_ii.
// Groups instructions by index_per_ii.
Copy link

Copilot AI Jan 17, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Incorrect indentation: this comment and the following code block should be indented one level deeper to reflect being within the method body.

Copilot uses AI. Check for mistakes.
IndexGroups index_groups = groupByIndexPerIi(tile.entry.instructions);

for (const auto &index_pair : index_groups) {
int index_per_ii = index_pair.first;
auto instructions = index_pair.second;
std::stable_sort(instructions.begin(), instructions.end(),
[](const Instruction *a, const Instruction *b) {
return a->time_step < b->time_step;
});

asm_out << "{\n";
for (size_t i = 0; i < instructions.size(); ++i) {
const Instruction *inst = instructions[i];
asm_out << " " << inst->opcode;
for (const Operand &operand : inst->src_operands) asm_out << ", " << formatOperand(operand);
if (!inst->dst_operands.empty()) {
asm_out << " -> ";
for (size_t j = 0; j < inst->dst_operands.size(); ++j) {
if (j > 0) asm_out << ", ";
asm_out << formatOperand(inst->dst_operands[j]);

for (const auto &index_pair : index_groups) {
Copy link

Copilot AI Jan 17, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Incorrect indentation: this loop and its body should be indented one level deeper as they are within the method body, not at class level.

Copilot uses AI. Check for mistakes.
int index_per_ii = index_pair.first;
auto instructions = index_pair.second;
std::stable_sort(instructions.begin(), instructions.end(),
[](const Instruction *a, const Instruction *b) {
return a->time_step < b->time_step;
});

asm_out << "{\n";
for (size_t i = 0; i < instructions.size(); ++i) {
const Instruction *inst = instructions[i];
asm_out << " " << inst->opcode;
for (const Operand &operand : inst->src_operands) asm_out << ", " << formatOperand(operand);
if (!inst->dst_operands.empty()) {
asm_out << " -> ";
for (size_t j = 0; j < inst->dst_operands.size(); ++j) {
if (j > 0) asm_out << ", ";
asm_out << formatOperand(inst->dst_operands[j]);
}
}
asm_out << " (t=" << inst->time_step
<< ", inv_iters=" << inst->invalid_iterations << ")\n";
}
asm_out << " (t=" << inst->time_step
<< ", inv_iters=" << inst->invalid_iterations << ")\n";
asm_out << "} (idx_per_ii=" << index_per_ii << ")\n";
}
asm_out << "} (idx_per_ii=" << index_per_ii << ")\n";
}
asm_out << "\n";
asm_out << "\n";
}

void writeAsmOutput(const ArrayConfig &config) {
Expand Down
1 change: 1 addition & 0 deletions test/benchmark/Zeonica_Testbench
Submodule Zeonica_Testbench added at 45e85e
17 changes: 17 additions & 0 deletions test/benchmark/axpy/axpy_int.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// Keep the function name matching "kernel" so llvm-extract --rfunc=".*kernel.*" can find it.
extern "C" void kernel_axpy_int(int n, int a, const int *x, int *y) {
for (int i = 0; i < n; ++i) {
y[i] = a * x[i] + y[i];
}
}

// Provide a tiny main so clang emits a complete TU; tests extract only the kernel anyway.
int main() {
const int N = 16;
static int x[N];
static int y[N];
kernel_axpy_int(N, /*a=*/3, x, y);
return 0;
}


22 changes: 22 additions & 0 deletions test/benchmark/gemv/gemv_int.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// A simple int GEMV: y = A*x + y.
// Use fixed small sizes to keep the generated IR stable-ish.
extern "C" void kernel_gemv_int(const int *A, const int *x, int *y) {
const int N = 4;
for (int i = 0; i < N; ++i) {
int acc = 0;
for (int j = 0; j < N; ++j) {
acc += A[i * N + j] * x[j];
}
y[i] = acc;
}
}

int main() {
static int A[16];
static int x[4];
static int y[4];
kernel_gemv_int(A, x, y);
return 0;
}


Loading
Loading