#ifndef PIM_DIALECT_H #define PIM_DIALECT_H include "mlir/IR/OpBase.td" include "mlir/IR/AttrTypeBase.td" include "mlir/Dialect/MemRef/IR/MemRefBase.td" include "mlir/Interfaces/SideEffectInterfaces.td" include "mlir/Interfaces/DestinationStyleOpInterface.td" include "mlir/Dialect/Bufferization/IR/BufferViewFlowOpInterface.td" def PimDialect : Dialect { let name = "pim"; let summary = "A low-level dialect for the PIM coprocessors on ReRAM crossbars"; let cppNamespace = "::onnx_mlir::pim"; } class PimOp traits = []> : Op; def PimTensor : AnyTypeOf<[AnyMemRef, AnyRankedTensor], "", "::mlir::ShapedType">; //===----------------------------------------------------------------------===// // Execution //===----------------------------------------------------------------------===// def PimCoreOp : PimOp<"core", [SingleBlock]> { let summary = "Execute a block on a PIM core"; let regions = (region SizedRegion<1>:$body); let arguments = (ins Variadic:$weights, I32Attr:$coreId ); let assemblyFormat = [{ `(` $weights `)` attr-dict regions `:` type($weights) `->` `(` `)` }]; } def PimHaltOp : PimOp<"halt", [Terminator]> { let summary = "Halt execution of the core"; let assemblyFormat = [{ attr-dict }]; } //===----------------------------------------------------------------------===// // Communication //===----------------------------------------------------------------------===// def PimSendOp : PimOp<"send", []> { let summary = "Send a tensor to another core"; let arguments = (ins PimTensor:$input, I32Attr:$size, I32Attr:$targetCoreId ); let assemblyFormat = [{ `(` $input `)` attr-dict `:` type($input) `->` `(` `)` }]; } def PimReceiveOp : PimOp<"receive", [DestinationStyleOpInterface]> { let summary = "Receive a tensor from another core"; let arguments = (ins PimTensor:$outputBuffer, I32Attr:$size, I32Attr:$sourceCoreId ); let results = (outs PimTensor:$output ); let extraClassDeclaration = [{ mlir::MutableOperandRange getDpsInitsMutable() { return getOutputBufferMutable(); } }]; let assemblyFormat = [{ `(` $outputBuffer `)` attr-dict `:` type($outputBuffer) `->` type($output) }]; } def PimMemCopyHostToDevOp : PimOp<"memcp_hd", [DestinationStyleOpInterface]> { let summary = "Copy a memory region from host memory into device memory"; let arguments = (ins PimTensor:$deviceTarget, PimTensor:$hostSource, I32Attr:$deviceTargetOffset, I32Attr:$hostSourceOffset, I32Attr:$size ); let results = (outs PimTensor:$output ); let extraClassDeclaration = [{ mlir::MutableOperandRange getDpsInitsMutable() { return getDeviceTargetMutable(); } }]; let assemblyFormat = [{ `(` $deviceTarget `,` $hostSource `)` attr-dict `:` `(` type($deviceTarget) `,` type($hostSource) `)` `->` type($output) }]; } def PimMemCopyDevToHostOp : PimOp<"memcp_dh", [DestinationStyleOpInterface]> { let summary = "Copy a memory region from device memory into host memory"; let arguments = (ins PimTensor:$hostTarget, PimTensor:$deviceSource, I32Attr:$hostTargetOffset, I32Attr:$deviceSourceOffset, I32Attr:$size ); let results = (outs PimTensor:$output ); let extraClassDeclaration = [{ mlir::MutableOperandRange getDpsInitsMutable() { return getHostTargetMutable(); } }]; let assemblyFormat = [{ `(` $hostTarget `,` $deviceSource `)` attr-dict `:` `(` type($hostTarget) `,` type($deviceSource) `)` `->` type($output) }]; } def PimMemCopyOp : PimOp<"memcp", [DestinationStyleOpInterface]> { let summary = "Copy a memory region within the same memory space"; let arguments = (ins PimTensor:$target, PimTensor:$source, I32Attr:$targetOffset, I32Attr:$sourceOffset, I32Attr:$size ); let results = (outs PimTensor:$output ); let extraClassDeclaration = [{ mlir::MutableOperandRange getDpsInitsMutable() { return getTargetMutable(); } }]; let assemblyFormat = [{ `(` $target `,` $source `)` attr-dict `:` `(` type($target) `,` type($source) `)` `->` type($output) }]; } //===----------------------------------------------------------------------===// // Math //===----------------------------------------------------------------------===// def PimTransposeOp : PimOp<"transpose", [DestinationStyleOpInterface]> { let summary = "Transpose a matrix"; let arguments = (ins PimTensor:$input, I64ArrayAttr:$permutation, PimTensor:$outputBuffer ); let results = (outs PimTensor:$output ); let extraClassDeclaration = [{ mlir::MutableOperandRange getDpsInitsMutable() { return getOutputBufferMutable(); } }]; let assemblyFormat = [{ `(` $input `,` $outputBuffer `)` attr-dict `:` `(` type($input) `,` type($outputBuffer) `)` `->` type($output) }]; } def PimVMMOp : PimOp<"vmm", [DestinationStyleOpInterface]> { let summary = "Vector-matrix multiplication: c = a * b"; let arguments = (ins I32Attr:$weightIndex, PimTensor:$input, PimTensor:$outputBuffer ); let results = (outs PimTensor:$output ); let extraClassDeclaration = [{ mlir::MutableOperandRange getDpsInitsMutable() { return getOutputBufferMutable(); } }]; let assemblyFormat = [{ `(` $input `,` $outputBuffer `)` attr-dict `:` `(` type($input) `,` type($outputBuffer) `)` `->` type($output) }]; } def PimMVMOp : PimOp<"mvm", [DestinationStyleOpInterface]> { let summary = "Matrix-vector multiplication: c = a * b"; let arguments = (ins I32Attr:$weightIndex, PimTensor:$input, PimTensor:$outputBuffer ); let results = (outs PimTensor:$output ); let extraClassDeclaration = [{ mlir::MutableOperandRange getDpsInitsMutable() { return getOutputBufferMutable(); } }]; let assemblyFormat = [{ `(` $input `,` $outputBuffer `)` attr-dict `:` `(` type($input) `,` type($outputBuffer) `)` `->` type($output) }]; } def PimVVAddOp : PimOp<"vvadd", [DestinationStyleOpInterface]> { let summary = "Element-wise addition: c = a + b"; let arguments = (ins PimTensor:$lhs, PimTensor:$rhs, PimTensor:$outputBuffer ); let results = (outs PimTensor:$output ); let extraClassDeclaration = [{ mlir::MutableOperandRange getDpsInitsMutable() { return getOutputBufferMutable(); } }]; let assemblyFormat = [{ `(` $lhs `,` $rhs `,` $outputBuffer `)` attr-dict `:` `(` type($lhs) `,` type($rhs) `,` type($outputBuffer) `)` `->` type($output) }]; } def PimVVSubOp : PimOp<"vvsub", [DestinationStyleOpInterface]> { let summary = "Element-wise subtraction: c = a - b"; let arguments = (ins PimTensor:$lhs, PimTensor:$rhs, PimTensor:$outputBuffer ); let results = (outs PimTensor:$output ); let extraClassDeclaration = [{ mlir::MutableOperandRange getDpsInitsMutable() { return getOutputBufferMutable(); } }]; let assemblyFormat = [{ `(` $lhs `,` $rhs `,` $outputBuffer `)` attr-dict `:` `(` type($lhs) `,` type($rhs) `,` type($outputBuffer) `)` `->` type($output) }]; } def PimVVMulOp : PimOp<"vvmul", [DestinationStyleOpInterface]> { let summary = "Element-wise multiplication: c = a * b"; let arguments = (ins PimTensor:$lhs, PimTensor:$rhs, PimTensor:$outputBuffer ); let results = (outs PimTensor:$output ); let extraClassDeclaration = [{ mlir::MutableOperandRange getDpsInitsMutable() { return getOutputBufferMutable(); } }]; let assemblyFormat = [{ `(` $lhs `,` $rhs `,` $outputBuffer `)` attr-dict `:` `(` type($lhs) `,` type($rhs) `,` type($outputBuffer) `)` `->` type($output) }]; } def PimVVMaxOp : PimOp<"vvmax", [DestinationStyleOpInterface]> { let summary = "Element-wise max: c = max(a, b)"; let arguments = (ins PimTensor:$lhs, PimTensor:$rhs, PimTensor:$outputBuffer ); let results = (outs PimTensor:$output ); let extraClassDeclaration = [{ mlir::MutableOperandRange getDpsInitsMutable() { return getOutputBufferMutable(); } }]; let assemblyFormat = [{ `(` $lhs `,` $rhs `,` $outputBuffer `)` attr-dict `:` `(` type($lhs) `,` type($rhs) `,` type($outputBuffer) `)` `->` type($output) }]; } def PimVVDMulOp : PimOp<"vvdmul", [DestinationStyleOpInterface]> { let summary = "Dot product: c = dot(a, b)"; let arguments = (ins PimTensor:$lhs, PimTensor:$rhs, PimTensor:$outputBuffer ); let results = (outs PimTensor:$output ); let extraClassDeclaration = [{ mlir::MutableOperandRange getDpsInitsMutable() { return getOutputBufferMutable(); } }]; let assemblyFormat = [{ `(` $lhs `,` $rhs `,` $outputBuffer `)` attr-dict `:` `(` type($lhs) `,` type($rhs) `,` type($outputBuffer) `)` `->` type($output) }]; } def PimSumOp : PimOp<"sum", [DestinationStyleOpInterface]> { let summary = "Reduce all elements to a single value"; let arguments = (ins PimTensor:$input, PimTensor:$outputBuffer ); let results = (outs PimTensor:$output ); let extraClassDeclaration = [{ mlir::MutableOperandRange getDpsInitsMutable() { return getOutputBufferMutable(); } }]; let assemblyFormat = [{ `(` $input `,` $outputBuffer `)` attr-dict `:` `(` type($input) `,` type($outputBuffer) `)` `->` type($output) }]; } def PimVAvgOp : PimOp<"vavg", [DestinationStyleOpInterface]> { let summary = "Average all elements into a single value"; let arguments = (ins PimTensor:$input, PimTensor:$outputBuffer ); let results = (outs PimTensor:$output ); let extraClassDeclaration = [{ mlir::MutableOperandRange getDpsInitsMutable() { return getOutputBufferMutable(); } }]; let assemblyFormat = [{ `(` $input `,` $outputBuffer `)` attr-dict `:` `(` type($input) `,` type($outputBuffer) `)` `->` type($output) }]; } def PimVReluOp : PimOp<"vrelu", [DestinationStyleOpInterface]> { let summary = "Element-wise ReLU: c = max(a, 0)"; let arguments = (ins PimTensor:$input, PimTensor:$outputBuffer ); let results = (outs PimTensor:$output ); let extraClassDeclaration = [{ mlir::MutableOperandRange getDpsInitsMutable() { return getOutputBufferMutable(); } }]; let assemblyFormat = [{ `(` $input `,` $outputBuffer `)` attr-dict `:` `(` type($input) `,` type($outputBuffer) `)` `->` type($output) }]; } def PimVTanhOp : PimOp<"vtanh", [DestinationStyleOpInterface]> { let summary = "Element-wise tanh activation"; let arguments = (ins PimTensor:$input, PimTensor:$outputBuffer ); let results = (outs PimTensor:$output ); let extraClassDeclaration = [{ mlir::MutableOperandRange getDpsInitsMutable() { return getOutputBufferMutable(); } }]; let assemblyFormat = [{ `(` $input `,` $outputBuffer `)` attr-dict `:` `(` type($input) `,` type($outputBuffer) `)` `->` type($output) }]; } def PimVSigmOp : PimOp<"vsigm", [DestinationStyleOpInterface]> { let summary = "Element-wise sigmoid activation"; let arguments = (ins PimTensor:$input, PimTensor:$outputBuffer ); let results = (outs PimTensor:$output ); let extraClassDeclaration = [{ mlir::MutableOperandRange getDpsInitsMutable() { return getOutputBufferMutable(); } }]; let assemblyFormat = [{ `(` $input `,` $outputBuffer `)` attr-dict `:` `(` type($input) `,` type($outputBuffer) `)` `->` type($output) }]; } #endif // PIM_DIALECT_H