Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
50 commits
Select commit Hold shift + click to select a range
3a25ebf
[SYCL] add new fp8 data types and unit tests
dklochkov-emb Feb 18, 2026
9490498
[SYCL] update fp8 to check constraints
dklochkov-emb Feb 18, 2026
a24ac3b
[SYCL] apply new updates from docs and e5m3 data type
dklochkov-emb Feb 19, 2026
2573ebe
[SYCL] remove extra types
dklochkov-emb Feb 19, 2026
bb0cc94
[SYCL][FP8] implement stochastic rounding
dklochkov-emb Feb 20, 2026
6e0a2e4
[SYCL] update fp8 implemetation
dklochkov-emb Mar 19, 2026
1715062
Merge remote-tracking branch 'upstream/sycl' into sycl-ext-one-api-fp…
dklochkov-emb Mar 19, 2026
6d03f08
[SYCL] fix formatting
dklochkov-emb Mar 19, 2026
c938642
[SYCL] do not use extra rounding modes
dklochkov-emb Mar 19, 2026
a55e275
[SYCL][FP8] use saturation
dklochkov-emb Mar 24, 2026
28565bc
Revert "[SYCL][FP8] use saturation"
dklochkov-emb Mar 24, 2026
9712f34
[SYCL] update list of builtins used in fp8 types
dklochkov-emb Mar 24, 2026
046affd
[SYCL] add more tests of builtin calls
dklochkov-emb Mar 24, 2026
a697eb8
[SYCL] fix PR issues
dklochkov-emb Apr 1, 2026
1f0808a
[SYCL] do not use extra check for e8m0
dklochkov-emb Apr 1, 2026
ef5f670
[SYCL] fix formatting
dklochkov-emb Apr 1, 2026
865d909
Merge remote-tracking branch 'upstream/sycl' into sycl-ext-one-api-fp…
dklochkov-emb Apr 1, 2026
8d9cc9f
[SYCL] remove unused variable
dklochkov-emb Apr 1, 2026
e5fd6c4
[SYCL] remove unused variable
dklochkov-emb Apr 3, 2026
f9a044f
Merge remote-tracking branch 'upstream/sycl' into sycl-ext-one-api-fp…
dklochkov-emb Apr 3, 2026
ae426a9
[SYCL] fix formatting
dklochkov-emb Apr 3, 2026
5b6da23
[SYCL] do not construct fp8 with mixture of parameters in pack
dklochkov-emb Apr 7, 2026
b8cf8b0
[SYCL] limit operators with SFINAE, do not use asserts
dklochkov-emb Apr 8, 2026
a772591
[SYCL] do not cast to float
dklochkov-emb Apr 8, 2026
2d57fd0
[SYCL] rework fp8 to avoid casts to float
dklochkov-emb Apr 8, 2026
479f011
[SYCL] remove extra check from assert
dklochkov-emb Apr 8, 2026
181d92c
[SYCL] do not cast to half during convertion
dklochkov-emb Apr 8, 2026
e4051c6
[SYCL] do not use extra checks of saturation and rounding for e5m2 an…
dklochkov-emb Apr 8, 2026
f8aa6fb
[SYCL] replace exceptions with asserts
dklochkov-emb Apr 8, 2026
a92fff8
[SYCL] remove unused functions
dklochkov-emb Apr 9, 2026
d99b83f
[SYCL] add tests to check rouning constraints
dklochkov-emb Apr 9, 2026
97d4c9e
Merge remote-tracking branch 'upstream/sycl' into sycl-ext-one-api-fp…
dklochkov-emb Apr 9, 2026
aa7c776
[SYCL] fix formatting
dklochkov-emb Apr 9, 2026
8fbe460
[SYCL] do not cast seed
dklochkov-emb Apr 9, 2026
f4945f0
[SYCL] remove unused variable
dklochkov-emb Apr 9, 2026
bcbe8d7
[SYCL] use memcpy to convert to e8m0 instead of std library
dklochkov-emb Apr 15, 2026
956f22b
[SYCL] convert bytes before fp8
dklochkov-emb Apr 16, 2026
c5e6d91
[SYCL] remove unused function
dklochkov-emb Apr 16, 2026
726294a
[SYCL] rename functions and traits
dklochkov-emb Apr 16, 2026
ddb260d
[SYCL] remove unused functions
dklochkov-emb Apr 17, 2026
05175ef
Merge remote-tracking branch 'upstream/sycl' into sycl-ext-one-api-fp…
dklochkov-emb Apr 17, 2026
b596110
[SYCL] rework fp8 types to avoid copy-paste
dklochkov-emb Apr 20, 2026
edbb6fd
[SYCL] add separate trait for variadic constructors
dklochkov-emb Apr 20, 2026
cfd3a3a
[SYCL] pass references in test
dklochkov-emb Apr 20, 2026
b743896
Merge remote-tracking branch 'upstream/sycl' into sycl-ext-one-api-fp…
dklochkov-emb Apr 20, 2026
ad9b49f
Revert "[SYCL] pass references in test"
dklochkov-emb Apr 21, 2026
e1ec70d
Revert "[SYCL] add separate trait for variadic constructors"
dklochkov-emb Apr 21, 2026
0843e6b
Revert "[SYCL] rework fp8 types to avoid copy-paste"
dklochkov-emb Apr 21, 2026
bce6894
[SYCL] remove stochastic float constructors
dklochkov-emb Apr 21, 2026
dec9931
[SYCL] add tests to check decay
dklochkov-emb Apr 21, 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
1,979 changes: 1,979 additions & 0 deletions sycl/include/sycl/ext/oneapi/experimental/float_8bit/types.hpp

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions sycl/unittests/Extensions/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,4 @@ add_subdirectory(FreeFunctionCommands)
add_subdirectory(KernelQueries)
add_subdirectory(InterProcessCommunication)
add_subdirectory(DeviceIndex)
add_subdirectory(fp8)
6 changes: 6 additions & 0 deletions sycl/unittests/Extensions/fp8/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
add_sycl_unittest(FP8TypesTests OBJECT
fp8_e4m3.cpp
fp8_e5m2.cpp
fp8_e8m0.cpp
builtin_call_tests.cpp
)
247 changes: 247 additions & 0 deletions sycl/unittests/Extensions/fp8/builtin_call_tests.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,247 @@
#include "builtin_mocks.hpp"
#include <gtest/gtest.h>
#include <sycl/ext/oneapi/experimental/float_8bit/types.hpp>

namespace {

using namespace sycl::ext::oneapi::experimental;

class Fp8BuiltinCallTest : public ::testing::Test {
protected:
void SetUp() override { fp8_builtin_mock::resetCounters(); }
};

TEST_F(Fp8BuiltinCallTest, E4M3CtorFromHalfCallsClampConvertFP16ToE4M3) {
fp8_e4m3 Value(static_cast<sycl::half>(1.25f));
(void)Value;
EXPECT_EQ(fp8_builtin_mock::getCounters().ClampConvertFP16ToE4M3INTEL, 1);
}

TEST_F(Fp8BuiltinCallTest, E4M3CtorFromBf16CallsClampConvertBF16ToE4M3) {
fp8_e4m3 Value(static_cast<sycl::ext::oneapi::bfloat16>(1.25f));
(void)Value;
EXPECT_EQ(fp8_builtin_mock::getCounters().ClampConvertBF16ToE4M3INTEL, 1);
}

TEST_F(Fp8BuiltinCallTest, E4M3ArrayCtorFromFloatCallsClampConvertFP16ToE4M3) {
float Input[2] = {1.25f, 2.5f};

fp8_e4m3_x2 Value(Input);
(void)Value;

EXPECT_EQ(fp8_builtin_mock::getCounters().ClampConvertFP16ToE4M3INTEL, 2);
}

TEST_F(Fp8BuiltinCallTest, E4M3MarrayCtorFromBf16CallsClampConvertBF16ToE4M3) {
sycl::marray<sycl::ext::oneapi::bfloat16, 2> Input = {
static_cast<sycl::ext::oneapi::bfloat16>(1.25f),
static_cast<sycl::ext::oneapi::bfloat16>(2.5f)};

fp8_e4m3_x2 Value(Input);
(void)Value;

EXPECT_EQ(fp8_builtin_mock::getCounters().ClampConvertBF16ToE4M3INTEL, 2);
}

TEST_F(Fp8BuiltinCallTest, E4M3CastToHalfCallsClampConvertE4M3ToFP16) {
fp8_e4m3 Value(static_cast<sycl::half>(1.0f));
fp8_builtin_mock::resetCounters();
(void)static_cast<sycl::half>(Value);
EXPECT_EQ(fp8_builtin_mock::getCounters().ConvertE4M3ToFP16EXT, 1);
}

TEST_F(Fp8BuiltinCallTest, E4M3CastToBf16CallsConvertE4M3ToBF16) {
fp8_e4m3 Value(static_cast<sycl::half>(1.0f));
fp8_builtin_mock::resetCounters();
(void)static_cast<sycl::ext::oneapi::bfloat16>(Value);
EXPECT_EQ(fp8_builtin_mock::getCounters().ConvertE4M3ToBF16EXT, 1);
}

TEST_F(Fp8BuiltinCallTest, E4M3CastToBoolCallsConvertE4M3ToFP16) {
fp8_e4m3 Value(static_cast<sycl::half>(1.0f));
fp8_builtin_mock::resetCounters();
(void)static_cast<bool>(Value);
EXPECT_EQ(fp8_builtin_mock::getCounters().ConvertE4M3ToFP16EXT, 1);
}

TEST_F(Fp8BuiltinCallTest, E4M3MarrayCastToHalfCallsConvertE4M3ToFP16) {
sycl::half Input[2] = {static_cast<sycl::half>(1.0f),
static_cast<sycl::half>(2.0f)};
fp8_e4m3_x2 Value(Input);

fp8_builtin_mock::resetCounters();
(void)static_cast<sycl::marray<sycl::half, 2>>(Value);

EXPECT_EQ(fp8_builtin_mock::getCounters().ConvertE4M3ToFP16EXT, 2);
}

TEST_F(Fp8BuiltinCallTest, E4M3MarrayCastToBf16CallsConvertE4M3ToBF16) {
sycl::half Input[2] = {static_cast<sycl::half>(1.0f),
static_cast<sycl::half>(2.0f)};
fp8_e4m3_x2 Value(Input);

fp8_builtin_mock::resetCounters();
(void)static_cast<sycl::marray<sycl::ext::oneapi::bfloat16, 2>>(Value);

EXPECT_EQ(fp8_builtin_mock::getCounters().ConvertE4M3ToBF16EXT, 2);
}

TEST_F(Fp8BuiltinCallTest, E4M3AssignmentFromFloatCallsClampConvertFP16ToE4M3) {
fp8_e4m3 Value(static_cast<sycl::half>(1.0f));

fp8_builtin_mock::resetCounters();
Value = 1.25f;

EXPECT_EQ(fp8_builtin_mock::getCounters().ClampConvertFP16ToE4M3INTEL, 1);
}

TEST_F(Fp8BuiltinCallTest, E5M2CtorFromHalfCallsClampConvertFP16ToE5M2) {
fp8_e5m2 Value(static_cast<sycl::half>(2.0f));
(void)Value;
EXPECT_EQ(fp8_builtin_mock::getCounters().ClampConvertFP16ToE5M2INTEL, 1);
}

TEST_F(Fp8BuiltinCallTest, E5M2CtorFromBf16CallsClampConvertBF16ToE5M2) {
fp8_e5m2 Value(static_cast<sycl::ext::oneapi::bfloat16>(2.0f));
(void)Value;
EXPECT_EQ(fp8_builtin_mock::getCounters().ClampConvertBF16ToE5M2INTEL, 1);
}

TEST_F(Fp8BuiltinCallTest,
E5M2ArrayCtorFromFloatFiniteCallsClampConvertFP16ToE5M2) {
float Input[2] = {2.0f, 4.0f};

fp8_e5m2_x2 Value(Input, rounding::to_even, saturation::finite);
(void)Value;

EXPECT_EQ(fp8_builtin_mock::getCounters().ClampConvertFP16ToE5M2INTEL, 2);
}

TEST_F(Fp8BuiltinCallTest, E5M2MarrayCtorFromBf16NoneCallsConvertBF16ToE5M2) {
sycl::marray<sycl::ext::oneapi::bfloat16, 2> Input = {
static_cast<sycl::ext::oneapi::bfloat16>(2.0f),
static_cast<sycl::ext::oneapi::bfloat16>(4.0f)};

fp8_e5m2_x2 Value(Input, rounding::to_even, saturation::none);
(void)Value;

EXPECT_EQ(fp8_builtin_mock::getCounters().ConvertBF16ToE5M2EXT, 2);
}

TEST_F(Fp8BuiltinCallTest, E5M2CastToHalfCallsConvertE5M2ToFP16) {
fp8_e5m2 Value(static_cast<sycl::half>(2.0f));
fp8_builtin_mock::resetCounters();
(void)static_cast<sycl::half>(Value);
EXPECT_EQ(fp8_builtin_mock::getCounters().ConvertE5M2ToFP16EXT, 1);
}

TEST_F(Fp8BuiltinCallTest, E5M2CastToBf16CallsConvertE5M2ToBF16) {
fp8_e5m2 Value(static_cast<sycl::half>(2.0f));
fp8_builtin_mock::resetCounters();
(void)static_cast<sycl::ext::oneapi::bfloat16>(Value);
EXPECT_EQ(fp8_builtin_mock::getCounters().ConvertE5M2ToBF16EXT, 1);
}

TEST_F(Fp8BuiltinCallTest, E5M2MarrayCastToHalfCallsConvertE5M2ToFP16) {
sycl::half Input[2] = {static_cast<sycl::half>(2.0f),
static_cast<sycl::half>(4.0f)};
fp8_e5m2_x2 Value(Input);

fp8_builtin_mock::resetCounters();
(void)static_cast<sycl::marray<sycl::half, 2>>(Value);

EXPECT_EQ(fp8_builtin_mock::getCounters().ConvertE5M2ToFP16EXT, 2);
}

TEST_F(Fp8BuiltinCallTest, E5M2MarrayCastToBf16CallsConvertE5M2ToBF16) {
sycl::half Input[2] = {static_cast<sycl::half>(2.0f),
static_cast<sycl::half>(4.0f)};
fp8_e5m2_x2 Value(Input);

fp8_builtin_mock::resetCounters();
(void)static_cast<sycl::marray<sycl::ext::oneapi::bfloat16, 2>>(Value);

EXPECT_EQ(fp8_builtin_mock::getCounters().ConvertE5M2ToBF16EXT, 2);
}

TEST_F(Fp8BuiltinCallTest, E5M2AssignmentFromFloatCallsClampConvertFP16ToE5M2) {
fp8_e5m2 Value(static_cast<sycl::half>(2.0f));

fp8_builtin_mock::resetCounters();
Value = 4.0f;

EXPECT_EQ(fp8_builtin_mock::getCounters().ClampConvertFP16ToE5M2INTEL, 1);
}

TEST_F(Fp8BuiltinCallTest,
E5M2CtorFromHalfWithNoSaturationCallsConvertFP16ToE5M2) {
sycl::half Input[1] = {static_cast<sycl::half>(2.0f)};

fp8_e5m2 Value(Input, rounding::to_even, saturation::none);
(void)Value;

EXPECT_EQ(fp8_builtin_mock::getCounters().ConvertFP16ToE5M2EXT, 1);
}

TEST_F(Fp8BuiltinCallTest,
E5M2CtorFromBf16WithNoSaturationCallsConvertBF16ToE5M2) {
sycl::ext::oneapi::bfloat16 Input[1] = {
static_cast<sycl::ext::oneapi::bfloat16>(2.0f)};

fp8_e5m2 Value(Input, rounding::to_even, saturation::none);
(void)Value;

EXPECT_EQ(fp8_builtin_mock::getCounters().ConvertBF16ToE5M2EXT, 1);
}

TEST_F(Fp8BuiltinCallTest, E5M2StochasticHalfFiniteCallsClampStochastic) {
sycl::half Input[1] = {static_cast<sycl::half>(3.0f)};
uint32_t SeedValue = 10;
stochastic_seed Seed(&SeedValue);

fp8_e5m2 Value(Input, Seed, saturation::finite);
(void)Value;

EXPECT_EQ(fp8_builtin_mock::getCounters().ClampStochasticRoundFP16ToE5M2INTEL,
1);
EXPECT_EQ(SeedValue, 11u);
}

TEST_F(Fp8BuiltinCallTest, E5M2StochasticHalfNoneCallsNonClampStochastic) {
sycl::half Input[1] = {static_cast<sycl::half>(3.0f)};
uint32_t SeedValue = 20;
stochastic_seed Seed(&SeedValue);

fp8_e5m2 Value(Input, Seed, saturation::none);
(void)Value;

EXPECT_EQ(fp8_builtin_mock::getCounters().StochasticRoundFP16ToE5M2INTEL, 1);
EXPECT_EQ(SeedValue, 21u);
}

TEST_F(Fp8BuiltinCallTest, E5M2StochasticBf16FiniteCallsClampStochastic) {
sycl::ext::oneapi::bfloat16 Input[1] = {
static_cast<sycl::ext::oneapi::bfloat16>(3.0f)};
uint32_t SeedValue = 30;
stochastic_seed Seed(&SeedValue);

fp8_e5m2 Value(Input, Seed, saturation::finite);
(void)Value;

EXPECT_EQ(fp8_builtin_mock::getCounters().ClampStochasticRoundBF16ToE5M2INTEL,
1);
}

TEST_F(Fp8BuiltinCallTest, E5M2StochasticBf16NoneCallsNonClampStochastic) {
sycl::ext::oneapi::bfloat16 Input[1] = {
static_cast<sycl::ext::oneapi::bfloat16>(3.0f)};
uint32_t SeedValue = 40;
stochastic_seed Seed(&SeedValue);

fp8_e5m2 Value(Input, Seed, saturation::none);
(void)Value;

EXPECT_EQ(fp8_builtin_mock::getCounters().StochasticRoundBF16ToE5M2INTEL, 1);
}

} // namespace
Loading
Loading