-
Notifications
You must be signed in to change notification settings - Fork 314
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
SCF To Calyx Support Float Add and Float SeqMemory Read/Write #6953
Conversation
I'd like to hear more about what the story for floating point types is. There's a reason nothing in CIRCT handles them--hardware IRs work very naturally for bitvectors modeled as (signless) integer types. But floating point is a whole beast with very different hardware circuits. How does Calyx handle floats? |
Sure! Calyx plans to introduce floating point adders and multipliers as primitives using HardFloat
Suppose Calyx can do floating point manipulations, then the crux lies in lowering Calyx to HW dialect. Can we convert the floating point number to the corresponding bitvector based on IEEE754 and the problem is then solved? Am I oversimplifying the prblem? |
Thanks for the pointer. Yes, I think the crux of the problem is how Calyx floating points convert to bitvectors in the HW dialect. I don't think anyone in CIRCT has modeled IEEE754 floats, but if you are fine modeling them as a bitvector of the appropriate width, the core CIRCT dialects should support that. |
Sounds good! I'm super excited to try this out! |
54039cd
to
22b3ddc
Compare
22b3ddc
to
9daf0cf
Compare
…memory to write/read floating point data
9daf0cf
to
9552293
Compare
…ing point) op to pass in write_data
9552293
to
3c375e3
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is looking good.
I would suggest to break it up into smaller changes if possible. It seems there are a few things that can be added in separate PRs:
- Addition of the constant op
- Addition of the floating point add op
- Addition of the memory handling
Also, please include both happy path and failure tests, as applicable.
@@ -2911,7 +2989,53 @@ LogicalResult SliceLibOp::verify() { | |||
DictionaryAttr::get(getContext())}; \ | |||
} | |||
|
|||
#define ImplBinFloatingPointOpCellInterface(OpType) \ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We generally discourage macros. Could this be templated on OpType
instead?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1, I see ImplBinPipeOpCellInterface
is doing something similar and I'm not sure why
upon a quick glance. It might be OK to refactor both in a follow-up PR, or open an issue to do so and add a TODO.
AnySignlessInteger:$execptionalFlags, I1:$done); | ||
} | ||
|
||
def AddFNOp : ArithBinaryFloatingPointLibraryOp<"addFN"> {} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is the addFN
name? "Add floating number" or something like that? I don't usually nitpick on the mnemonics, but it is worth thinking through. I get the impression this aligns with Calyx native IR, so if that's the case, addFN
sounds good to me.
// Equivalent generic form | ||
%1 = "calyx.constant"() {value = 42 : i32} : () -> i32 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: I don't this is necessary; it is just a detail of LLVM.
@@ -2911,7 +2989,53 @@ LogicalResult SliceLibOp::verify() { | |||
DictionaryAttr::get(getContext())}; \ | |||
} | |||
|
|||
#define ImplBinFloatingPointOpCellInterface(OpType) \ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1, I see ImplBinPipeOpCellInterface
is doing something similar and I'm not sure why
upon a quick glance. It might be OK to refactor both in a follow-up PR, or open an issue to do so and add a TODO.
unsigned bitWidth = | ||
cell.getOutputPorts()[0].getType().getIntOrFloatBitWidth(); | ||
unsigned expWidth, sigWidth; | ||
if (bitWidth == 16) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't this be expWidth, sigWidth, and signBit?
void Emitter::emitLibraryFloatingPoint(Operation *op) { | ||
auto cell = cast<CellInterface>(op); | ||
unsigned bitWidth = | ||
cell.getOutputPorts()[0].getType().getIntOrFloatBitWidth(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we assert this has length > 0?
unsigned bitWidth = | ||
cell.getOutputPorts()[0].getType().getIntOrFloatBitWidth(); | ||
unsigned expWidth, sigWidth; | ||
if (bitWidth == 16) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I know this is the default size for Half, but there are other 16-bit values. Maybe comment saying this is for Half-float?
bool MemoryInterface::isSeqMem() { | ||
if (auto *memOp = std::get_if<calyx::SeqMemoryOp>(&impl); memOp) { | ||
return true; | ||
} | ||
return false; | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
bool MemoryInterface::isSeqMem() { | |
if (auto *memOp = std::get_if<calyx::SeqMemoryOp>(&impl); memOp) { | |
return true; | |
} | |
return false; | |
} | |
bool MemoryInterface::isSeqMem() { | |
return std::holds_alternative<calyx::SeqMemoryOp>(&impl); | |
} |
@@ -730,7 +737,8 @@ BuildBasicBlockRegs::partiallyLowerFuncToComp(mlir::func::FuncOp funcOp, | |||
|
|||
for (auto arg : enumerate(block->getArguments())) { | |||
Type argType = arg.value().getType(); | |||
assert(isa<IntegerType>(argType) && "unsupported block argument type"); | |||
assert((isa<IntegerType>(argType) || isa<FloatType>(argType)) && |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
assert((isa<IntegerType>(argType) || isa<FloatType>(argType)) && | |
assert(isa<IntegerType, FloatType>(argType) && |
(I think this should work)
@@ -753,11 +761,11 @@ BuildReturnRegs::partiallyLowerFuncToComp(mlir::func::FuncOp funcOp, | |||
|
|||
for (auto argType : enumerate(funcOp.getResultTypes())) { | |||
auto convArgType = calyx::convIndexType(rewriter, argType.value()); | |||
assert(isa<IntegerType>(convArgType) && "unsupported return type"); | |||
unsigned width = convArgType.getIntOrFloatBitWidth(); | |||
assert((isa<IntegerType>(convArgType) || isa<FloatType>(convArgType)) && |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(Similar case for here)
(Hi sorry, I'm just seeing this is in draft mode. Feel free to ignore my comments.) |
This is the second patch stacking on #6952
This patch tries to legalize
AddFOp
and support floating pointSeqMemory
read/write in SCFToCalyx.