Skip to content
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

Draft
wants to merge 4 commits into
base: main
Choose a base branch
from

Conversation

jiahanxie353
Copy link

This is the second patch stacking on #6952

This patch tries to legalize AddFOp and support floating point SeqMemory read/write in SCFToCalyx.

@mikeurbach
Copy link
Contributor

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?

@jiahanxie353
Copy link
Author

jiahanxie353 commented Apr 26, 2024

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

hardware IRs work very naturally for bitvectors modeled as (signless) integer types

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?

@mikeurbach
Copy link
Contributor

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.

@jiahanxie353
Copy link
Author

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!

Copy link
Contributor

@mikeurbach mikeurbach left a 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) \
Copy link
Contributor

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?

Copy link
Member

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"> {}
Copy link
Contributor

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.

Comment on lines +39 to +40
// Equivalent generic form
%1 = "calyx.constant"() {value = 42 : i32} : () -> i32
Copy link
Member

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) \
Copy link
Member

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) {
Copy link
Member

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();
Copy link
Member

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) {
Copy link
Member

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?

Comment on lines +172 to +178
bool MemoryInterface::isSeqMem() {
if (auto *memOp = std::get_if<calyx::SeqMemoryOp>(&impl); memOp) {
return true;
}
return false;
}

Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
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)) &&
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
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)) &&
Copy link
Member

Choose a reason for hiding this comment

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

(Similar case for here)

@cgyurgyik
Copy link
Member

(Hi sorry, I'm just seeing this is in draft mode. Feel free to ignore my comments.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants