Skip to content

Conversation

@GinShio
Copy link

@GinShio GinShio commented Oct 19, 2025

This PR implements the bfloat16_t type for slang and emit it to SPIR-V. The literal suffix is bf. According to spir-v specification, it can be used in cooperative matrix and instruction dot.

bfloat16_t bfVal = 1.bf; // bfloat16 literal 
let bfVec = vector<bfloat16_t, 2>(1.bf, bfloat16_t(0.125hf));
using namespace linalg;
let bfCoopMat = CoopMat<bfloat16_t, MemoryScope.Subgroup, 16, 16, CoopMatMatrixUse::MatrixA>(1.bf);
dot(bfVec, vector<bfloat16_t, 2>(2.bf, 4.bf));

Since spir-v doesn't allows arithmetic ops for bfloat16, it will emit invalid spir-v code, but slang has no restrictions. Also not support type reflection.

@slangbot
Copy link
Contributor

slangbot commented Oct 19, 2025

⚠️ IR Instruction Files Changed

This PR modifies IR instruction definition files. Please review if you need to update the following constants in source/slang/slang-ir.h:

  • k_minSupportedModuleVersion: Should be incremented if you're removing instructions or making breaking changes
  • k_maxSupportedModuleVersion: Should be incremented when adding new instructions

These version numbers help ensure compatibility between different versions of compiled modules.

@GinShio GinShio force-pushed the bfloat16 branch 2 times, most recently from 0f2abeb to 60e1b36 Compare October 21, 2025 05:07
Copy link
Collaborator

@jkwak-work jkwak-work left a comment

Choose a reason for hiding this comment

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

I have a few comments but it looks very good to me.

Although it looks very reasonable to me, I am not sure if we like to use "bf" as its suffix yet.


INT_MASK = SINT_MASK | UINT_MASK,
ARITHMETIC_MASK = INT_MASK | FLOAT_MASK,
ARITHMETIC_MASK = INT_MASK | FLOAT_MASK | BFLOAT_MASK,
Copy link
Collaborator

Choose a reason for hiding this comment

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

Correct me if I have misunderstanding, but as far as I understand, bfloat16_t is only for Cooperative-vector/matrix.
I don't think we should treat it as a regular arithmetic type.

I also see the following statement from GL_EXT_bfloat16:

Arithmetic operators are not supported on bfloat16_t, or vectors of that type, or cooperative matrices of that type.

Copy link
Author

Choose a reason for hiding this comment

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

This is also where I'm confused. Both CoopMat and CoopVec require the component type to be arithmetic type. My understanding is that we must implement some functions to make bfloat16 as arithmetic type. However, SPIR-V / glslang does not support these functions...

https://docs.shader-slang.org/en/latest/external/core-module-reference/interfaces/iarithmetic-01/index.html

Therefore, I wrote in the description:

Since spir-v doesn't allows arithmetic ops for bfloat16, it will emit invalid spir-v code, but slang has no restrictions.

Copy link
Collaborator

Choose a reason for hiding this comment

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

I see why you added it.

Currently the CoopVec uses __BuiltinArithmeticType:

struct CoopVec<T : __BuiltinArithmeticType, let N : int> : IArray<T>, IArithmetic

I think there are two options here: a) add a new type just for CoopVec operation or b) use __BuiltinType and add a few static_assert to cause errors when unsupported types are used for CoopVec such as bool and double.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Hmm.. I tried a bit and it turned to be not trivial to use either way.
Probably the current implementation is good enough.

Copy link
Collaborator

Choose a reason for hiding this comment

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

@csyonghe suggested that we should have a new type just for CoopVec, ICoopVecElement.
Because bfloat16 isn't IArithmetic type.

Similarly texture uses ITexelElement.
You can check it out of how a new type like that can be added.

Copy link
Author

Choose a reason for hiding this comment

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

@csyonghe suggested that we should have a new type just for CoopVec, ICoopVecElement.

Thanks, it looks better. I think we need a IMLElement or other interface. CoopMat also requires it. I will implement IMLElement first, please let me know if we have a better interface name.

Copy link
Collaborator

Choose a reason for hiding this comment

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

We had a bit more discussion about the naming,

IMLElement is too broad and we prefer it to be ICoopVecElement.
If we want to have a general ML operators in the future, we will regret giving a broad name to this specific narrow scope.

But we are still open to suggestions for a better naming at the moment.

Also at the same topic, this PR will not be able to have default implementation after switching to whatever the new interface name becomes.
Because the idea is that the new interface is not IArithmetic and we cannot simply provide a default implementation anymore.
As an example, a simple addition operation like CoopVec<float,5> + CoopVec<float,5> cannot have a default implementation.
That means this PR will be a backward compatibility breaking change.

I will add a "breaking change" label, when the change is reviewed again.

Copy link
Author

Choose a reason for hiding this comment

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

I agree with most of the points.

IMLElement is too broad and we prefer it to be ICoopVecElement.

My understanding is CoopMat requires this, and CoopVec is only one of these usages. So I'd like to call it MLElement, OTOW does not bundle CoopVec. For example, CoopMat<bfloat16_t, Subgroup, 16, 16, UseA> is valid type in the real world.

As an example, a simple addition operation like CoopVec<float,5> + CoopVec<float,5> cannot have a default implementation.

Yes.
Perhaps we can try to allow operator+ if component is arithmetic types, otherwise not. (Maybe in the future)

Copy link
Collaborator

@jkwak-work jkwak-work left a comment

Choose a reason for hiding this comment

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

I noticed that there isn't any tests with CoopVec, which is the main reason of having bfloat16_t.
Can you add some tests with CoopVec; and possibly with CoopMat as well?

@GinShio GinShio changed the title Implement bfloat16_t Implement builtin type bfloat16_t Oct 22, 2025
Copy link
Author

@GinShio GinShio left a comment

Choose a reason for hiding this comment

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

Although it looks very reasonable to me, I am not sure if we like to use "bf" as its suffix yet.

I'd like to add bf16, that's same as C++23 or glsl. But seems to hard add number suffix.

Can you add some tests with CoopVec; and possibly with CoopMat as well?

This seems to be a bit harder for CoopVec using bfloat16 matrix/bias. Added a simple coopvec test.


INT_MASK = SINT_MASK | UINT_MASK,
ARITHMETIC_MASK = INT_MASK | FLOAT_MASK,
ARITHMETIC_MASK = INT_MASK | FLOAT_MASK | BFLOAT_MASK,
Copy link
Author

Choose a reason for hiding this comment

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

This is also where I'm confused. Both CoopMat and CoopVec require the component type to be arithmetic type. My understanding is that we must implement some functions to make bfloat16 as arithmetic type. However, SPIR-V / glslang does not support these functions...

https://docs.shader-slang.org/en/latest/external/core-module-reference/interfaces/iarithmetic-01/index.html

Therefore, I wrote in the description:

Since spir-v doesn't allows arithmetic ops for bfloat16, it will emit invalid spir-v code, but slang has no restrictions.

@jhelferty-nv
Copy link
Contributor

@GinShio Does this need review? I see that there is a branch conflict with hlsl.meta.slang currently. (If you're working on it and not looking for an immediate review, please mark as draft)

@jkwak-work
Copy link
Collaborator

I am changing the status to "draft" because the current PR has a conflict to the current files at ToT.
The PR needs an update.

@jkwak-work jkwak-work marked this pull request as draft November 25, 2025 21:40
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.

4 participants