Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
170 commits
Select commit Hold shift + click to select a range
5ae18e5
Define runtime transport layer interface for backline backends
josephleekl Jul 20, 2026
5e76333
update changelog
josephleekl Jul 20, 2026
279a2b4
comments
josephleekl Jul 20, 2026
a319b39
update changelog
josephleekl Jul 20, 2026
0bb4b19
Merge branch 'main' into josephleekl/transport-layer
josephleekl Jul 20, 2026
c523f67
Transport Layer Loader is added
rniczh Jul 20, 2026
2b88bd4
Merge branch 'main' into josephleekl/transport-layer
josephleekl Jul 20, 2026
8dccc62
update interface
rniczh Jul 20, 2026
fc399e9
Merge branch 'josephleekl/transport-layer' into rniczh/tranport-layer…
rniczh Jul 20, 2026
cdee60b
coprocessor backend interface is added
rniczh Jul 20, 2026
da41e92
chagne type
rniczh Jul 20, 2026
2b6c1e9
Merge branch 'josephleekl/transport-layer' into rniczh/tranport-layer…
rniczh Jul 20, 2026
6e942a9
remove redundancy
rniczh Jul 20, 2026
4408322
add start
rniczh Jul 20, 2026
5282f5a
update comment
rniczh Jul 20, 2026
2b36a11
Merge branch 'josephleekl/transport-layer' into rniczh/tranport-layer…
rniczh Jul 20, 2026
32fc6f2
update changelog
rniczh Jul 20, 2026
2fc50c3
update
rniczh Jul 20, 2026
4d211ce
update
rniczh Jul 20, 2026
060458b
remove redundancy
rniczh Jul 20, 2026
246a4b7
number of collection is always 1
rniczh Jul 20, 2026
22cd621
update interface
rniczh Jul 20, 2026
5b57ef4
Merge branch 'josephleekl/transport-layer' into rniczh/tranport-layer…
rniczh Jul 20, 2026
18c2684
Add transport dialect
mehrdad2m Jul 21, 2026
6984afa
Add transport-to-llvm pass
mehrdad2m Jul 21, 2026
7630570
Update runtime/include/Transport.hpp
rniczh Jul 21, 2026
da12f30
Apply suggestion from @mehrdad2m
rniczh Jul 21, 2026
5490f08
Apply suggestion from @mehrdad2m
rniczh Jul 21, 2026
5d639c5
Apply suggestion from @mehrdad2m
rniczh Jul 21, 2026
30ebdf0
Merge branch 'josephleekl/transport-layer' into rniczh/tranport-layer…
rniczh Jul 21, 2026
8979bfc
Merge branch 'main' into transport-dialect
mehrdad2m Jul 21, 2026
2d8991e
Merge branch 'transport-dialect' into transport-to-llvm-pass
mehrdad2m Jul 21, 2026
e04d7b2
Merge branch 'transport-to-llvm-pass' into rniczh/tranport-layer-loader
mehrdad2m Jul 21, 2026
fd17906
update
mehrdad2m Jul 22, 2026
9cd39b5
update
mehrdad2m Jul 22, 2026
c2c1c73
Merge branch 'transport-dialect' into transport-to-llvm-pass
mehrdad2m Jul 22, 2026
7b3ff71
update
mehrdad2m Jul 22, 2026
b09fcc5
Merge branch 'transport-to-llvm-pass' into rniczh/tranport-layer-loader
mehrdad2m Jul 22, 2026
bdfab4c
format
mehrdad2m Jul 22, 2026
b911d91
Merge branch 'transport-dialect' into transport-to-llvm-pass
mehrdad2m Jul 22, 2026
a515020
format
mehrdad2m Jul 22, 2026
6b84b8c
Merge branch 'transport-to-llvm-pass' into rniczh/tranport-layer-loader
mehrdad2m Jul 22, 2026
7e86066
Merge branch 'main' into transport-dialect
mehrdad2m Jul 22, 2026
e4a779b
add include to lsp
mehrdad2m Jul 23, 2026
44e0d6a
add changelog
mehrdad2m Jul 23, 2026
0340a86
initial copy
josephleekl Jul 23, 2026
e34c06a
Refine transport dialect: string data_path, get_session, typed round …
mehrdad2m Jul 24, 2026
ed2a082
add tests
mehrdad2m Jul 24, 2026
a6493b2
fix
mehrdad2m Jul 24, 2026
56259d3
Merge branch 'transport-dialect' into transport-to-llvm-pass
mehrdad2m Jul 24, 2026
1c2ea7a
update get_session
mehrdad2m Jul 24, 2026
8887466
add changelog
mehrdad2m Jul 24, 2026
f6d1426
refine the CAPI
mehrdad2m Jul 24, 2026
266d3d9
Add tests
mehrdad2m Jul 24, 2026
61d3a0b
format
mehrdad2m Jul 24, 2026
a14e1fd
add tests
mehrdad2m Jul 24, 2026
747c0ed
format
mehrdad2m Jul 24, 2026
8f801e6
Merge branch 'transport-to-llvm-pass' into rniczh/tranport-layer-loader
mehrdad2m Jul 24, 2026
fb3c784
update namespace and test
josephleekl Jul 24, 2026
3937c94
Merge remote-tracking branch 'origin/rniczh/tranport-layer-loader' in…
josephleekl Jul 24, 2026
d45f158
format
josephleekl Jul 24, 2026
ff83df8
Update runtime/lib/transport/common/QueuePair.cpp
josephleekl Jul 24, 2026
853df0b
Update runtime/tests/CMakeLists.txt
josephleekl Jul 24, 2026
1767ee1
add comment for CPU controller commit work item
josephleekl Jul 24, 2026
036171b
add gpu device
josephleekl Jul 25, 2026
ae3bd4f
format
josephleekl Jul 25, 2026
718eedb
Merge branch 'main' into transport-dialect
mehrdad2m Jul 25, 2026
676c117
Merge branch 'transport-dialect' into transport-to-llvm-pass
mehrdad2m Jul 25, 2026
cb83699
Merge branch 'transport-to-llvm-pass' into rniczh/tranport-layer-loader
mehrdad2m Jul 25, 2026
ff8a253
format
mehrdad2m Jul 25, 2026
844eef2
Merge branch 'transport-dialect' into transport-to-llvm-pass
mehrdad2m Jul 25, 2026
cbb2c7a
Merge branch 'transport-to-llvm-pass' into rniczh/tranport-layer-loader
mehrdad2m Jul 25, 2026
0b0d0c0
format
mehrdad2m Jul 25, 2026
05195ab
Merge branch 'transport-to-llvm-pass' into rniczh/tranport-layer-loader
mehrdad2m Jul 25, 2026
a53549c
apply ne w catalyst-dev changes
mehrdad2m Jul 25, 2026
245af10
Merge branch 'transport-to-llvm-pass' into rniczh/tranport-layer-loader
mehrdad2m Jul 25, 2026
b01d828
Add ENABLE_TRANSPORT
mehrdad2m Jul 27, 2026
7a25f72
Merge branch 'rniczh/tranport-layer-loader' into josephleekl/transpor…
josephleekl Jul 27, 2026
2487663
Merge branch 'josephleekl/transport-cpu-device-common' into josephlee…
josephleekl Jul 27, 2026
ff68604
Update runtime/lib/transport/gpu_verbs/coprocessor/coprocessor_functi…
josephleekl Jul 27, 2026
6ea613d
Apply suggestions from code review
josephleekl Jul 27, 2026
5d5ad87
Update runtime/lib/transport/gpu_verbs/coprocessor/coprocessor_functi…
josephleekl Jul 27, 2026
a151300
Update runtime/lib/transport/gpu_verbs/coprocessor/coprocessor_functi…
josephleekl Jul 27, 2026
6232f25
Update runtime/tests/CMakeLists.txt
josephleekl Jul 27, 2026
55ec769
Key transport string globals on their contents.
mehrdad2m Jul 27, 2026
bc198e6
add linking flag
mehrdad2m Jul 28, 2026
e4d9f5f
Merge branch 'rniczh/tranport-layer-loader' into josephleekl/transpor…
josephleekl Jul 29, 2026
cbd398e
comments
josephleekl Jul 29, 2026
efb0806
comments
josephleekl Jul 29, 2026
d19b8f1
comments
josephleekl Jul 29, 2026
377e253
comments
josephleekl Jul 29, 2026
62e72d4
comments
josephleekl Jul 29, 2026
884b763
update
josephleekl Jul 29, 2026
c8200b7
Update runtime/lib/transport/common/BackendConfig.hpp
josephleekl Jul 29, 2026
400ce51
Merge branch 'josephleekl/transport-cpu-device-common' into josephlee…
josephleekl Jul 29, 2026
ef12413
format
josephleekl Jul 29, 2026
2be00bb
Merge branch 'josephleekl/transport-cpu-device-common' into josephlee…
josephleekl Jul 29, 2026
7fac616
Merge branch 'main' into transport-to-llvm-pass
mehrdad2m Jul 29, 2026
c323c7a
Merge branch 'transport-to-llvm-pass' into rniczh/tranport-layer-loader
mehrdad2m Jul 29, 2026
10f84d9
comments
josephleekl Jul 29, 2026
5d479bf
comments
josephleekl Jul 29, 2026
bcd67a5
comments
josephleekl Jul 29, 2026
143b63e
comments
josephleekl Jul 30, 2026
1689712
Update mlir/lib/Transport/Transforms/TransportToLLVM.cpp
mehrdad2m Jul 30, 2026
68149c3
guard last_rtt_ns
rniczh Jul 30, 2026
b5fd401
formatted
rniczh Jul 30, 2026
dc1f98c
comments
josephleekl Jul 30, 2026
45ffdd8
replace with isAlnum
mehrdad2m Jul 30, 2026
bbebcd2
drain pending tokens at destory
rniczh Jul 30, 2026
43a16e9
format
mehrdad2m Jul 30, 2026
7d5c424
resolve coprocessor lib
rniczh Jul 30, 2026
793d8bf
add warning
rniczh Jul 30, 2026
f59cd15
add test for draining pending tokens
rniczh Jul 30, 2026
5063573
cerr
rniczh Jul 30, 2026
f54830a
formatted
rniczh Jul 30, 2026
ee0b3bf
Merge branch 'transport-to-llvm-pass' into rniczh/tranport-layer-loader
mehrdad2m Jul 30, 2026
8b46a2e
fix makefile
mehrdad2m Jul 30, 2026
df00468
unify set coprocessor fn
josephleekl Jul 30, 2026
2f0cb81
remove impl
josephleekl Jul 30, 2026
adf290e
Merge branch 'josephleekl/transport-cpu-device-common' into josephlee…
josephleekl Jul 30, 2026
1651037
restore _fn name in CAPI
josephleekl Jul 30, 2026
be4b871
Merge branch 'main' into rniczh/tranport-layer-loader
rniczh Jul 30, 2026
dbbf9e2
Merge branch 'rniczh/tranport-layer-loader' into josephleekl/transpor…
rniczh Jul 30, 2026
6dd28b8
Merge remote-tracking branch 'origin/josephleekl/transport-cpu-device…
josephleekl Jul 30, 2026
392cbdd
Add todo
rniczh Jul 30, 2026
4c635d7
rename as_controller
mehrdad2m Jul 30, 2026
b0e8b22
remove constexprs
mehrdad2m Jul 30, 2026
fa7b893
rename
josephleekl Jul 30, 2026
f52777d
format
mehrdad2m Jul 30, 2026
20dd4ed
Merge branch 'rniczh/tranport-layer-loader' into josephleekl/transpor…
rniczh Jul 30, 2026
61154f8
Merge branch 'josephleekl/transport-cpu-device-common' into josephlee…
rniczh Jul 30, 2026
1ae1c0a
Fix decoder return convention and payload size plumbing
josephleekl Jul 30, 2026
3d0d27d
Merge remote-tracking branch 'origin/main' into josephleekl/transport…
josephleekl Jul 30, 2026
20fa8ef
changelog
josephleekl Jul 30, 2026
0dfc5b9
Merge branch 'josephleekl/transport-cpu-device-common' into josephlee…
josephleekl Jul 30, 2026
a0b1a54
changelog
josephleekl Jul 30, 2026
f308b98
pack steane code table mapping into a constant
josephleekl Jul 31, 2026
5bf70d9
Update runtime/lib/transport/common/BackendConfig.hpp
josephleekl Jul 31, 2026
ad0cd11
Apply suggestions from code review
josephleekl Jul 31, 2026
b7518f4
Update runtime/lib/transport/common/MemoryRegion.cpp
josephleekl Jul 31, 2026
ffee9ab
Apply suggestions from code review
josephleekl Jul 31, 2026
634a96f
Update runtime/lib/transport/common/QueuePair.cpp
josephleekl Jul 31, 2026
b48002b
Update runtime/lib/transport/cpu_verbs/controller/CpuControllerSessio…
josephleekl Jul 31, 2026
f313798
Update runtime/lib/transport/cpu_verbs/coprocessor/CpuCoprocessorSess…
josephleekl Jul 31, 2026
f79abcc
Update runtime/lib/transport/cpu_verbs/coprocessor/CpuCoprocessorSess…
josephleekl Jul 31, 2026
1dd7156
Merge branch 'josephleekl/transport-cpu-device-common' into josephlee…
josephleekl Jul 31, 2026
69d809a
Update mlir/include/Transport/IR/TransportOps.td
josephleekl Jul 31, 2026
98975b7
Update runtime/lib/transport/gpu_verbs/coprocessor/GpuRuntime.hip
josephleekl Jul 31, 2026
ee097af
Update runtime/tests/Test_Transport.cpp
josephleekl Jul 31, 2026
82df327
Update runtime/tests/Test_Transport.cpp
josephleekl Jul 31, 2026
9fbdaf5
Update runtime/lib/transport/gpu_verbs/coprocessor/GpuRuntime.hip
josephleekl Jul 31, 2026
617b1f8
Merge branch 'main' into josephleekl/transport-cpu-device-common
josephleekl Aug 3, 2026
8e25340
Merge branch 'josephleekl/transport-cpu-device-common' into josephlee…
josephleekl Aug 3, 2026
5d87e75
format
josephleekl Aug 3, 2026
8bdea6e
Merge branch 'josephleekl/transport-cpu-device-common' into josephlee…
josephleekl Aug 3, 2026
1090d2b
use runtime call for write to dataslot
josephleekl Aug 3, 2026
535cb1d
Add reply slot api
rniczh Aug 3, 2026
6aa96f4
Apply suggestions from code review
josephleekl Aug 3, 2026
a9b44f8
separate X/Z coprocessor decoder
josephleekl Aug 3, 2026
c74ac0f
Apply suggestions from code review
josephleekl Aug 3, 2026
a941d8e
Apply suggestions from code review
josephleekl Aug 3, 2026
9072963
Merge branch 'josephleekl/transport-gpu-device' into josephleekl/tran…
josephleekl Aug 3, 2026
3d90881
mehrdad comments
josephleekl Aug 3, 2026
5df3f44
Merge branch 'josephleekl/transport-gpu-device' into josephleekl/tran…
josephleekl Aug 3, 2026
4936abd
remove coprocessor fn convention from MLIR
josephleekl Aug 3, 2026
4ce5ec2
Merge branch 'josephleekl/transport-gpu-device' into josephleekl/tran…
josephleekl Aug 3, 2026
417f47b
update comment
josephleekl Aug 3, 2026
5fbfa11
Merge main into transport-XZ-decode
josephleekl Aug 4, 2026
499ffbe
Merge branch 'main' into josephleekl/transport-XZ-decode
josephleekl Aug 5, 2026
5acd685
format
josephleekl Aug 5, 2026
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
7 changes: 6 additions & 1 deletion doc/releases/changelog-dev.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,10 +49,15 @@
* A `BufferizableOpInterface` implementation is added for the `Transport` dialect ops.
[(#3064)](https://github.com/PennyLaneAI/catalyst/pull/3064)

* A `lower-decode-to-transport` pass is added, which replaces each qecp.decode_esm_css with
* A `lower-decode-to-transport` pass is added, which replaces each qecp.decode_esm_css with
a transport kick/collect round over its buffers.
[(#3066)](https://github.com/PennyLaneAI/catalyst/pull/3066)

* An X/Z syndrome decode can now be routed to its own decoder in a backline coprocessor.
`qecp.decode_esm_css` carries an optional `check_type` attribute recording which check family a
syndrome came from, which `lower-decode-to-transport` maps to a `decoder_id` on `transport.kick`.
[(#3092)](https://github.com/PennyLaneAI/catalyst/pull/3092)

* A new remote/local executor infrastructure has been added to Catalyst, enabling qnode kernels to
be dispatched to a separate executor process.

Expand Down
6 changes: 6 additions & 0 deletions frontend/catalyst/python_interface/dialects/qecp.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
IndexType,
IntegerAttr,
IntegerType,
StringAttr,
TensorType,
UnitAttr,
i1,
Expand All @@ -52,6 +53,7 @@
AtLeast,
BaseAttr,
IRDLOperation,
ParsePropInAttrDict,
TypeAttributeInvT,
VarConstraint,
base,
Expand Down Expand Up @@ -859,6 +861,10 @@ class DecodeEsmCssOp(IRDLOperation):

err_idx = opt_result_def(TensorConstraint(element_type=IndexType(), rank=1))

check_type = opt_prop_def(StringAttr)

irdl_options = (ParsePropInAttrDict(),)

def __init__(
self,
tanner_graph: TannerGraphSSAValue | Operation,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
ArrayAttr,
DenseArrayBase,
IndexType,
StringAttr,
SymbolRefAttr,
TensorType,
i1,
Expand Down Expand Up @@ -1322,6 +1323,7 @@ def _qec_cycle_css_pattern(
esm=pack_mres_tensor_op.result,
err_idx_type=TensorType(IndexType(), shape=(num_correctable_errors,)),
)
decode_esm_op.properties["check_type"] = StringAttr(check_type.value.lower())

# Apply correction(s)
err_indices = cast(OpResult[TensorType[IndexType]], decode_esm_op.err_idx)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -531,7 +531,7 @@ def test_single_qec_cycle_Steane(self, run_filecheck, qecl_to_qecp_steane_pipeli
// CHECK: qecp.dealloc_aux {{.*}} : !qecp.qubit<aux>
// CHECK: qecp.dealloc_aux {{.*}} : !qecp.qubit<aux>
// CHECK: [[esm:%.+]] = tensor.from_elements [[m0]], [[m1]], [[m2]] : tensor<3xi1>
// CHECK: [[idx_t:%.+]] = qecp.decode_esm_css([[tanner_x]] : !qecp.tanner_graph<24, 11, i32>) [[esm]] : tensor<3xi1> -> tensor<1xindex>
// CHECK: [[idx_t:%.+]] = qecp.decode_esm_css([[tanner_x]] : !qecp.tanner_graph<24, 11, i32>) [[esm]] {check_type = "x"} : tensor<3xi1> -> tensor<1xindex>
// CHECK: [[lb:%.+]] = arith.constant 0 : index
// CHECK: [[ub:%.+]] = arith.constant 1 : index
// CHECK: [[st:%.+]] = arith.constant 1 : index
Expand Down Expand Up @@ -568,7 +568,7 @@ def test_single_qec_cycle_Steane(self, run_filecheck, qecl_to_qecp_steane_pipeli
// CHECK: qecp.dealloc_aux {{.*}} : !qecp.qubit<aux>
// CHECK: qecp.dealloc_aux {{.*}} : !qecp.qubit<aux>
// CHECK: [[esm:%.+]] = tensor.from_elements [[m0]], [[m1]], [[m2]] : tensor<3xi1>
// CHECK: [[idx_t:%.+]] = qecp.decode_esm_css([[tanner_z]] : !qecp.tanner_graph<24, 11, i32>) [[esm]] : tensor<3xi1> -> tensor<1xindex>
// CHECK: [[idx_t:%.+]] = qecp.decode_esm_css([[tanner_z]] : !qecp.tanner_graph<24, 11, i32>) [[esm]] {check_type = "z"} : tensor<3xi1> -> tensor<1xindex>
// CHECK: [[lb:%.+]] = arith.constant 0 : index
// CHECK: [[ub:%.+]] = arith.constant 1 : index
// CHECK: [[st:%.+]] = arith.constant 1 : index
Expand Down Expand Up @@ -1796,7 +1796,7 @@ def test_qec_cycle_shor(self, run_filecheck):
// CHECK: qecp.dealloc_aux {{.*}} : !qecp.qubit<aux>
// CHECK: qecp.dealloc_aux {{.*}} : !qecp.qubit<aux>
// CHECK: [[esm:%.+]] = tensor.from_elements [[m0]], [[m1]] : tensor<2xi1>
// CHECK: [[idx_t:%.+]] = qecp.decode_esm_css([[tanner_x]] : !qecp.tanner_graph<24, 12, i32>) [[esm]] : tensor<2xi1> -> tensor<1xindex>
// CHECK: [[idx_t:%.+]] = qecp.decode_esm_css([[tanner_x]] : !qecp.tanner_graph<24, 12, i32>) [[esm]] {check_type = "x"} : tensor<2xi1> -> tensor<1xindex>
// CHECK: [[lb:%.+]] = arith.constant 0 : index
// CHECK: [[ub:%.+]] = arith.constant 1 : index
// CHECK: [[st:%.+]] = arith.constant 1 : index
Expand Down Expand Up @@ -1842,7 +1842,7 @@ def test_qec_cycle_shor(self, run_filecheck):
// CHECK: qecp.dealloc_aux {{.*}} : !qecp.qubit<aux>
// CHECK: qecp.dealloc_aux {{.*}} : !qecp.qubit<aux>
// CHECK: [[esm:%.+]] = tensor.from_elements [[m0]], [[m1]], [[m2]], [[m3]], [[m4]], [[m5]] : tensor<6xi1>
// CHECK: [[idx_t:%.+]] = qecp.decode_esm_css([[tanner_z]] : !qecp.tanner_graph<24, 16, i32>) [[esm]] : tensor<6xi1> -> tensor<1xindex>
// CHECK: [[idx_t:%.+]] = qecp.decode_esm_css([[tanner_z]] : !qecp.tanner_graph<24, 16, i32>) [[esm]] {check_type = "z"} : tensor<6xi1> -> tensor<1xindex>
// CHECK: [[lb:%.+]] = arith.constant 0 : index
// CHECK: [[ub:%.+]] = arith.constant 1 : index
// CHECK: [[st:%.+]] = arith.constant 1 : index
Expand Down
7 changes: 6 additions & 1 deletion mlir/include/QecPhysical/IR/QecPhysicalOps.td
Original file line number Diff line number Diff line change
Expand Up @@ -396,6 +396,10 @@ def DecodeEsmCssOp : QecPhysical_Op<"decode_esm_css"> {
and Z checks. It is therefore up to the user of this operation to determine what type(s) of
correction(s) to apply given the Tanner graph that was supplied.

The optional `check_type` attribute records which check family this syndrome came from
("x" or "z"), so a consumer picking a decoder per parity-check matrix need not recover it by
tracing the Tanner graph operand.

If no correctable error was detected, this operation returns an index value of -1.

#### Example
Expand All @@ -422,7 +426,8 @@ def DecodeEsmCssOp : QecPhysical_Op<"decode_esm_css"> {
let arguments = (ins
AnyTypeOf<[1DTensorOf<[I1]>, MemRefRankOf<[I1], [1]>]>:$esm,
TannerGraphType:$tanner_graph,
Optional<MemRefRankOf<[Index], [1]>>:$err_idx_in
Optional<MemRefRankOf<[Index], [1]>>:$err_idx_in,
OptionalAttr<StrAttr>:$check_type
);

let results = (outs
Expand Down
3 changes: 2 additions & 1 deletion mlir/include/Transport/IR/TransportOps.td
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,8 @@ def Transport_StartOp : Transport_Op<"start"> {
def Transport_KickOp : Transport_Op<"kick"> {
let summary = "Send a payload as one round's request (controller).";
let arguments = (ins Transport_ControllerSession:$session, Transport_AnyBuffer:$payload,
I32Attr:$work_item_idx);
I32Attr:$work_item_idx,
DefaultValuedOptionalAttr<I32Attr, "0">:$decoder_id);
let assemblyFormat = "$session `,` $payload attr-dict `:` qualified(type($session)) `,` type($payload)";
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,8 @@ struct DecodeEsmCssOpInterface
Value errIdxBuffer = memref::AllocOp::create(rewriter, loc, errIdxMemRefType);

DecodeEsmCssOp::create(rewriter, loc, TypeRange{}, esmToBufferOp.getResult(),
decodeEsmCssOp.getTannerGraph(), errIdxBuffer);
decodeEsmCssOp.getTannerGraph(), errIdxBuffer,
decodeEsmCssOp.getCheckTypeAttr());

bufferization::replaceOpWithBufferizedValues(rewriter, op, errIdxBuffer);
return success();
Expand Down
12 changes: 10 additions & 2 deletions mlir/lib/Transport/Transforms/LowerDecodeToTransport.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@

#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringSwitch.h"
#include "mlir/IR/Builders.h"
#include "mlir/IR/BuiltinAttributes.h"
#include "mlir/Pass/Pass.h"
Expand Down Expand Up @@ -68,11 +69,18 @@ struct LowerDecodeToTransportPass
MLIRContext *ctx = &getContext();
auto ctrlTy = SessionType::get(ctx, Role::Controller);

auto emitRound = [&](Operation *anchor, Value syndrome, Value correction, StringRef key) {
auto emitRound = [&](qecp::DecodeEsmCssOp anchor, Value syndrome, Value correction,
StringRef key) {
OpBuilder b(anchor);
Value s = GetSessionOp::create(b, anchor->getLoc(), ctrlTy, b.getStringAttr(key))
.getSession();
KickOp::create(b, anchor->getLoc(), s, syndrome, b.getI32IntegerAttr(0));
const std::int32_t decoderSlot =
llvm::StringSwitch<std::int32_t>(anchor.getCheckType().value_or(""))
.Case("x", 0)
.Case("z", 1)
.Default(0);
KickOp::create(b, anchor->getLoc(), s, syndrome, b.getI32IntegerAttr(0),
b.getI32IntegerAttr(decoderSlot));
CollectOp::create(b, anchor->getLoc(), TypeRange{}, ValueRange{s, correction});
anchor->erase();
};
Expand Down
5 changes: 3 additions & 2 deletions mlir/lib/Transport/Transforms/TransportToLLVM.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -248,9 +248,10 @@ struct KickLowering : public OpConversionPattern<KickOp> {
}
auto [srcPtr, bytes] =
memrefPtrAndBytes(rewriter, op.getLoc(), adaptor.getPayload(), memTy);
Value decoderId = constInt(rewriter, op.getLoc(), i32Ty(ctx), op.getDecoderId());
emitCall(rewriter, op.getLoc(), mod, "__catalyst__transport__write_data_slot",
{ptrTy(ctx), ptrTy(ctx), i64Ty(ctx)}, i32Ty(ctx),
{adaptor.getSession(), srcPtr, bytes});
{ptrTy(ctx), ptrTy(ctx), i64Ty(ctx), i32Ty(ctx)}, i32Ty(ctx),
{adaptor.getSession(), srcPtr, bytes, decoderId});
Value idx = constInt(rewriter, op.getLoc(), i32Ty(ctx), op.getWorkItemIdx());
emitCall(rewriter, op.getLoc(), mod, "__catalyst__transport__kick",
{ptrTy(ctx), i32Ty(ctx)}, i32Ty(ctx), {adaptor.getSession(), idx});
Expand Down
2 changes: 1 addition & 1 deletion mlir/test/Transport/ConvertTransportToLLVM.mlir
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
// CHECK-DAG: llvm.func @__catalyst__transport__exchange_keys(!llvm.ptr) -> i32
// CHECK-DAG: llvm.func @__catalyst__transport__establish_channel(!llvm.ptr, !llvm.ptr) -> i32
// CHECK-DAG: llvm.func @__catalyst__transport__commit_work_item(!llvm.ptr, i32, i64, i64) -> i32
// CHECK-DAG: llvm.func @__catalyst__transport__write_data_slot(!llvm.ptr, !llvm.ptr, i64) -> i32
// CHECK-DAG: llvm.func @__catalyst__transport__write_data_slot(!llvm.ptr, !llvm.ptr, i64, i32) -> i32
// CHECK-DAG: llvm.func @__catalyst__transport__kick(!llvm.ptr, i32) -> i32
// CHECK-DAG: llvm.func @__catalyst__transport__collect(!llvm.ptr, !llvm.ptr, i64) -> i32
// CHECK-DAG: llvm.func @__catalyst__transport__start(!llvm.ptr)
Expand Down
39 changes: 39 additions & 0 deletions mlir/test/Transport/LowerDecodeToTransport.mlir
Original file line number Diff line number Diff line change
Expand Up @@ -96,3 +96,42 @@ module attributes {catalyst.backline = #transport.backline<transport = "net",
return
}
}

// -----

// Check decode check_type mapping to decoder_id

// CHECK-LABEL: func.func @qec_cycle_css
// CHECK: %[[SX:.*]] = transport.get_session {key = "cop0"} : !transport.session<controller>
// CHECK: transport.kick %[[SX]], %{{.*}} {work_item_idx = 0 : i32}
// CHECK: %[[SZ:.*]] = transport.get_session {key = "cop0"} : !transport.session<controller>
// CHECK: transport.kick %[[SZ]], %{{.*}} {decoder_id = 1 : i32, work_item_idx = 0 : i32}
module attributes {catalyst.backline = #transport.backline<transport = "net",
controller = #transport.node<backend_lib = "x", config = "c">,
coprocessors = [#transport.node<backend_lib = "x", config = "c", name = "cop0", peer = "10.0.0.1", symbol = "decode">]>} {
func.func @qec_cycle_css(%tannerX: !qecp.tanner_graph<8, 6, i32>,
%tannerZ: !qecp.tanner_graph<8, 6, i32>,
%esmX: memref<?xi1>, %iX: memref<?xindex>,
%esmZ: memref<?xi1>, %iZ: memref<?xindex>) {
qecp.decode_esm_css(%tannerX : !qecp.tanner_graph<8, 6, i32>) %esmX in (%iX : memref<?xindex>) {check_type = "x"} : memref<?xi1>
qecp.decode_esm_css(%tannerZ : !qecp.tanner_graph<8, 6, i32>) %esmZ in (%iZ : memref<?xindex>) {check_type = "z"} : memref<?xi1>
return
}
}

// -----

// A decode that declares no check family takes decoder 0, so IR from before the attribute
// existed lowers unchanged.

// CHECK-LABEL: func.func @untagged
// CHECK: transport.kick %{{.*}} {work_item_idx = 0 : i32}
// CHECK-NOT: decoder_id
module attributes {catalyst.backline = #transport.backline<transport = "net",
controller = #transport.node<backend_lib = "x", config = "c">,
coprocessors = [#transport.node<backend_lib = "x", config = "c", name = "cop0", peer = "10.0.0.1", symbol = "decode">]>} {
func.func @untagged(%tanner: !qecp.tanner_graph<8, 6, i32>, %esm: memref<?xi1>, %erridx: memref<?xindex>) {
qecp.decode_esm_css(%tanner : !qecp.tanner_graph<8, 6, i32>) %esm in (%erridx : memref<?xindex>) : memref<?xi1>
return
}
}
10 changes: 6 additions & 4 deletions runtime/include/Transport.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -167,8 +167,9 @@ class ControllerSession : public TransportSession {

// Copy `bytes` of payload into the current round's outbound slot, ready for kick().
// Throws if `bytes` exceeds what the round was committed to carry, so an oversized
// payload will fail.
virtual void write_data_slot(const void *src, std::uint64_t bytes) = 0;
// payload will fail. `decoder_id` picks the coprocessor-side decoder for this round.
virtual void write_data_slot(const void *src, std::uint64_t bytes,
std::uint32_t decoder_id) = 0;

// Current round's reply slot in the transport-owned reply ring.
virtual void *reply_slot() { return nullptr; }
Expand Down Expand Up @@ -228,8 +229,9 @@ class CoprocessorSession : public TransportSession {
/**
* @brief Bind a per-message coprocessor function (CPU-style).
*
* Call before start(). `fn` is invoked once per received message; `ctx` is
* passed back on every invocation and may be null.
* Call before start(). `fn` is invoked once per received message, receiving the
* message's decoder_id so it can dispatch internally; `ctx` is passed back on
* every invocation and may be null.
Comment thread
josephleekl marked this conversation as resolved.
*/
virtual void set_coprocessor_fn(CoprocessorFn /*fn*/, void * /*ctx*/) {
throw std::logic_error(
Expand Down
2 changes: 1 addition & 1 deletion runtime/include/TransportCAPI.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ void *__catalyst__transport__data_slot(CatalystTransportSession *s);
// Copy `bytes` into the round's outbound slot. Fails if `bytes` exceeds what
// commit_work_item committed.
int __catalyst__transport__write_data_slot(CatalystTransportSession *s, const void *src,
uint64_t bytes);
uint64_t bytes, uint32_t decoder_id);
void *__catalyst__transport__reply_slot(CatalystTransportSession *s);
int __catalyst__transport__kick(CatalystTransportSession *s, uint32_t work_item_idx);

Expand Down
4 changes: 2 additions & 2 deletions runtime/lib/transport/TransportCAPI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -349,13 +349,13 @@ void *__catalyst__transport__data_slot(CatalystTransportSession *s) {
}

int __catalyst__transport__write_data_slot(CatalystTransportSession *s, const void *src,
std::uint64_t bytes) {
std::uint64_t bytes, std::uint32_t decoder_id) {
auto *c = cast_to_controller(s);
if (!c) {
return CATALYST_TRANSPORT_ERR;
}
return guard([&] {
c->write_data_slot(src, bytes);
c->write_data_slot(src, bytes, decoder_id);
return 0;
});
}
Expand Down
9 changes: 7 additions & 2 deletions runtime/lib/transport/common/WireProtocol.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,16 @@ inline constexpr std::uint64_t DEMO_SYNDROME = 0x0123456789ABCDEFull;
#pragma pack(push, 1)
struct Payload {
Comment thread
josephleekl marked this conversation as resolved.
std::uint64_t value;
std::uint32_t seq_num;
std::uint32_t pad;
std::uint32_t decoder_id; // selects which decoder handles this message
std::uint32_t seq_num; // arrival flag
Comment thread
josephleekl marked this conversation as resolved.
};
#pragma pack(pop)
static_assert(sizeof(Payload) == 16, "Payload must be exactly 16 B");
static_assert(offsetof(Payload, seq_num) + sizeof(Payload::seq_num) == sizeof(Payload),
"seq_num must be the last field in Payload");
static_assert(offsetof(Payload, value) == 0,
"value must be first so a decoder can read the data from the frame's start");
static_assert(offsetof(Payload, decoder_id) == 8, "decoder_id is at byte offset 8");

/**
* @brief Bytes of a Payload the caller and the coprocessor function may use.
Expand Down
1 change: 0 additions & 1 deletion runtime/lib/transport/cpu_verbs/base/CpuSessionBase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,6 @@ void CpuSessionBase<Role>::post_write(ibv_qp *qp, std::uint64_t cursor, bool inl
bool signaled) {
auto *send = send_payload(); // value already written by the caller
send->seq_num = static_cast<std::uint32_t>(cursor + 1);
send->pad = 0;
ibv_sge sge{
.addr = reinterpret_cast<std::uint64_t>(send),
.length = sizeof(Payload), // 16 B on the wire, into slot's first 16 B
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,12 +64,14 @@ void *CpuControllerSession::data_slot() {
return &send_payload()->value;
}

void CpuControllerSession::write_data_slot(const void *src, std::uint64_t bytes) {
void CpuControllerSession::write_data_slot(const void *src, std::uint64_t bytes,
std::uint32_t decoder_id) {
RDMA_CHECK(bytes <= in_bytes_, "payload (%zu B) exceeds the %zu B committed for this round",
static_cast<std::size_t>(bytes), static_cast<std::size_t>(in_bytes_));
Payload *send = send_payload();
send->value = 0;
std::memcpy(&send->value, src, bytes);
send->decoder_id = decoder_id;
}

int CpuControllerSession::kick(std::uint32_t /*work_item_idx*/) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ class CpuControllerSession : public CpuSessionBase<ControllerSession> {
std::uint64_t out_bytes) override;
int kick(std::uint32_t work_item_idx = 0) override;
void *data_slot() override;
void write_data_slot(const void *src, std::uint64_t bytes) override;
void write_data_slot(const void *src, std::uint64_t bytes, std::uint32_t decoder_id) override;

protected:
bool oob_listens() const override { return false; }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,10 +98,11 @@ void CpuCoprocessorSession::run(std::stop_token st) {
last_word_.store(r->value, std::memory_order_relaxed);
completed_.fetch_add(1, std::memory_order_release);
Payload *send = send_payload();
send->value = 0; // deterministic high bytes when the result is shorter
send->value = 0;
send->decoder_id = r->decoder_id;
if (coproc_fn_) {
const std::size_t nb = coproc_fn_(&r->value, PAYLOAD_DATA_BYTES, &send->value,
PAYLOAD_DATA_BYTES, coproc_ctx_);
const std::size_t nb =
coproc_fn_(r, sizeof(Payload), &send->value, PAYLOAD_DATA_BYTES, coproc_ctx_);
RDMA_CHECK(nb > 0 && nb <= PAYLOAD_DATA_BYTES,
"coprocessor function wrote %zu bytes, expected 1..%zu", nb,
PAYLOAD_DATA_BYTES);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,10 @@

namespace catalyst::transport::cpu_verbs {

// Coprocessor role: receives messages, runs the coprocessor function, and
// returns the result. The function is bound via set_coprocessor_fn; nullptr
// selects the built-in echo.
// Coprocessor role: receives messages, runs the coprocessor function, and returns
// the result. The function is bound via set_coprocessor_fn; nullptr selects the
// built-in echo. Each message's decoder_id is handed to the function, which may
// serve several codes and dispatch on it, or ignore it if it serves only one.
class CpuCoprocessorSession : public CpuSessionBase<CoprocessorSession> {
using Base = CpuSessionBase<CoprocessorSession>;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,10 @@ constexpr std::int64_t STEANE_SYNDROME_TO_QUBIT[1u << STEANE_CHECKS] = {-1, 6, 4
* the wire does not carry; a decoder therefore has to know its own code's check
* count.
*/
// `in` is the request frame; its leading bytes are the syndrome. The frame's
// decoder_id (a uint32 at byte offset 8) is not read: the [[7,1,3]] Steane code has
// Hx == Hz, so one table serves both the X and Z checks. A code whose matrices differ
// would read that field and switch on it here.
extern "C" std::size_t steane_coprocessor(const void *in, std::size_t in_len, void *out,
std::size_t out_cap, void * /*ctx*/) {
if (in == nullptr || out == nullptr || in_len < STEANE_CHECKS ||
Expand Down
Loading
Loading