KhronosGroup / KhronosGroup/SYCL-Docs

`vec::convert` is underspecified

Open
#492 1 comment 3 reactions 1 assignee Claimed by @nliber View on GitHub
clarification
Dominant language
JavaScript
Stars
158
Forks
80
Avg merge
7d 6h
Merged PRs (30d)
5

Description

[Table 142](https://registry.khronos.org/SYCL/specs/sycl-2020/html/sycl-2020.html#table.members.vec) of the SYCL 2020 specification defines `vec::convert` as follows:

> Converts this SYCL `vec` to a SYCL `vec` of a different element type specified by `ConvertT` using the rounding mode specified by `RoundingMode`. The new SYCL `vec` type must have the same number of elements as this SYCL `vec`. The different rounding modes are described in [Table 144](https://registry.khronos.org/SYCL/specs/sycl-2020/html/sycl-2020.html#table.vec.roundingmodes).

Which raises a number of questions:

There are no restrictions about using different rounding modes even for integer to integer conversions. What is the meaning of them in that case? Note that there are cases when source value is not representable in destination type, like narrowing conversion, signed to unsigned conversion for negative values. Should rounding modes affect the result in those cases?

How "converts" is defined, exactly? Does it follow C++ standard or some other rules? If it follows C++, then which one?
The latest C++ spec draft defines integer conversions in [conv.integral.3](https://eel.is/c++draft/conv.integral#3) as:

> the result is the unique value of the destination type that is congruent to the source integer modulo `2^N`
, where `N` is the width of the destination type.

However, if you take a look at [C++17 draft (document N4713)](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/n4713.pdf) 7.8 Integer conversions, you will find the following:

> If the destination type is unsigned, the resulting value is the least unsigned integer congruent to the source integer (modulo `2^n` where `n` is the number of bits used to represent the unsigned type). [ Note: In a two’s complement representation, this conversion is conceptual and there is no change in the bit pattern (if there is no truncation). — end note ]
> **If the destination type is signed, the value is unchanged if it can be represented in the destination type; otherwise, the value is implementation-defined**

SYCL-CTS is using C-style cast to compute reference value for integer conversions: [`tests/common/common_vec.h:132`](https://github.com/KhronosGroup/SYCL-CTS/blob/dd0283b147ac6d98399cba218a9af584fc7d4cbf/tests/common/common_vec.h#L132), which means that reference selected in CTS is technically implementation-defined if it is compiled with C++17-based toolchain and it is well-defined it it is compiled with C++20-based toolchain, which doesn't sound right.

Note: signed-to-unsigned (and vice-versa) conversions defined in SPIR-V do not follow C++20 rules: they clamp input value to a nearest representable value in the destination type instead of doing modulo arithmetic, see [`OpSatConvertSToU`](https://registry.khronos.org/SPIR-V/specs/unified1/SPIRV.html#OpSatConvertSToU) for example.

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.