This is a test plan for the APIs described in sycl_ext_oneapi_sub_group_mask
All of the tests described below are performed only on the default device that is selected on the CTS command line.
Part of the extension feature is available from revision 1 of the extension and
tests for it should use #if SYCL_EXT_ONEAPI_SUB_GROUP_MASK >= 1
and can be
skipped if the feature is not supported. That part is described in paragraph
Section 2.3.
The other part of the feature is available from revision 2 of the extension and
tests for it should use #if SYCL_EXT_ONEAPI_SUB_GROUP_MASK >= 2
and can be
skipped if the feature is not supported. That part is described in paragraph
Section 2.2.
All of the following tests have these initial steps performed in defferent .cpp files :
-
Create a
queue
from the tested device and callqueue::submit()
. -
Submit a kernel via
handler::parallel_for()
with parameterssycl::nd_range<1>(range<1>(32), range<1>(32))
and lambda finction with parametersycl::nd_item<1>
. -
Lambda function should be decorated with attribute
reqd_sub_group_size(N)
withN
values =[8,16,32]
. If device does not supportsub_group
sizeN
, test for sizeN
can be skipped.device.get_info<sycl::info::device::sub_group_sizes>()
should be used to check supportedsub_group
sizes. -
In lambda function use
nd_item::get_sub_group()
to getsycl::sub_group
instance. -
Use accessor to buffer for type
bool
to save results. -
For regular test run check is performed only for leader work-item.
-
For full conformance test run check is performed for all work-items.
Features described in this paragraph are available from revision 2 of the extension.
-
Construct
sub_group_mask
instances
with sub_group_mask()
ctor. -
Check that
s.none() == true
.
Run the following test with VALUE
= item.get_local_linear_id()
and with VALUE
= 0b1010…
:
size_t val = VALUE;
sub_group_mask mask{val};
for ( size_t i = 0; i < mask.size(); ++i ) {
if (mask[id(i)] != ((val >> i) & 1)) {
/* test fails */
}
}
Run the following test with all combinations of:
-
TYPE:
char
,signed char
,unsigned char
,short int
,unsigned short int
,int
,unsigned int
,long int
,unsigned long int
,long long int
,unsigned long long int
-
DIM:
2
,5
,10
-
VALUE:
item.get_local_linear_id()
,0b101010…
marray<TYPE, DIM> ma;
size_t val = VALUE;
if (sizeof(ma) < sizeof(val)) {
int N = CHAR_BIT * sizeof(ma);
/* set first N bits of "ma" to first N bits of "val" */
} else {
int N = CHAR_BIT * sizeof(val);
/* set first N bits of "ma" to first N bits of "val" */
}
sub_group_mask mask{ma};
for (size_t i = 0; i < mask.size(); ++i) {
if (mask[id(i)] != ((val >> i) & 1)) {
/* test fails */
}
}
-
Construct
sub_group_mask
instances
with every test case described in Section 2.2.1 Section 2.2.2 and Section 2.2.3. -
Construct
sub_group_mask
instancecopy
withsub_group_mask(s)
copy ctor. -
Apply checks for
copy
as described in the corresponding paragraph.
-
Construct
sub_group_mask
instances
with every test case described in Section 2.2.1 Section 2.2.2 and Section 2.2.3.. -
Construct
sub_group_mask
instanceother
with the same size as s. -
Use
other = s
to assignother
instance with copy ofs
. -
Apply checks for
other
as described in the corresponding paragraph.
Features described in this paragraph are available from revision 1 of the extension.
Member functions from Table are checked with following steps:
-
Use
sub_group_ballot
to getsub_group_mask
instance with predicate suitable for test. -
Check return type.
-
Check that Expression returns Exprected value.
Function | Predicate | Return type | Expression | Expected value |
---|---|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
-
Use non-const instance of
sub_group_mask
. -
Use Predicate
sub_group.get_local_id().size_t()%2 == 0
. -
Check that return type is
sub_group_mask::reference
. -
Check that
sub_group_mask[id(N)]
forN = 0…sub_group_mask.size() - 1
refers to value equal toN%2 == 0
To check sub_group_mask::reference
functionality:
-
If
N%5 == 0
try to assign opposite value tosub_group_mask[id(N)]
and then check thatsub_group_mask.test(id(N))
equalsN%2 =! 0
. -
If
N%5 == 1
try to assignsub_group_mask[id(N+1)]
tosub_group_mask[id(N)]
and then check thatsub_group_mask.test(id(N))
equals(N+1)%2 == 0
. -
If
N%5 == 2
check that~sub_group_mask[id(N)]
equalsN%2 != 0
. -
If
N%5 == 3
check that(bool)sub_group_mask[id(N)]
equalsN%2 == 0
. -
If
N%5 == 4
try to usesub_group_mask[id(N)].flip()
, check that return type issub_group_mask::reference&
, check thatsub_group_mask.test(id(N))
equalsN%2 =! 0
.
For T equals to integral types below:
-
char
-
signed char
-
unsigned char
-
short int
-
unsigned short int
-
int
-
unsigned int
-
long int
-
unsigned long int
-
long long int
-
unsigned long long int
And marray<T, dim>
where T is the integral type above
and dim
is 2
, 5
, and 10
.
For N = 0…sub_group_mask.size() - 1
:
-
Use non-const instance of
sub_group_mask
. -
Use Predicate
sub_group.get_local_id().size_t()%3 == 0
. -
Check that return type is
void
. -
Use insert_bits(bits, id(N)) with
bits = 0b1010…
-
For
K = 0 … N - 1
check thatsub_group_mask.test(id(K))
equalsK%3 == 0
-
For
K = N … N + CHAR_BIT * sizeof(T) - 1
check thatsub_group_mask.test(id(K))
equals(N-K)%2 == 1
-
If
N + CHAR_BIT * sizeof(T) < sub_group_mask.size()
forK = N + CHAR_BIT * sizeof(T) … sub_group_mask.size() - 1
check thatsub_group_mask.test(id(K))
equalsK%3 == 0
For T equals to integral types below:
-
char
-
signed char
-
unsigned char
-
short int
-
unsigned short int
-
int
-
unsigned int
-
long int
-
unsigned long int
-
long long int
-
unsigned long long int
And marray<T, dim>
where T is the integral type above
and dim
is 2
, 5
, and 10
.
For N = 0…sub_group_mask.size() - 1
:
-
Use const instance of
sub_group_mask
. -
Use Predicate
sub_group.get_local_id().size_t()%2 != 0
. -
Check that return type is
void
. -
Use extract_bits(id(N))
-
If
N + CHAR_BIT * sizeof(T) < sub_group_mask.size()
check that out is0b1010…
-
Otherwise check that out’s first
sub_group_mask.size() - N
bits are10..
and the rest is zero.
-
Use non-const instance of
sub_group_mask
. -
Use Predicate
sub_group.get_local_id().size_t()%2 == 0
. -
Check that return type is
void
. -
Use set().
-
Check that
sub_group_mask.test(id(N))
forN = 0…sub_group_mask.size() - 1
equalstrue
.
-
Use non-const instance of
sub_group_mask
. -
Use Predicate
sub_group.get_local_id().size_t()%2 == 0
. -
Check that return type is
void
. -
for
N = 0…sub_group_mask.size() - 1
use set(id(N), true) ifN%3 == 0
and set(id(N), false) ifN%3 == 1
-
Check that
sub_group_mask.test(id(N))
forN = 0…sub_group_mask.size() - 1
equalstrue
ifN%3 == 0
,false
if N%3 == 1 andN%2 == 0
ifN%3 == 2
-
Use non-const instance of
sub_group_mask
. -
Use Predicate
sub_group.get_local_id().size_t()%2 == 0
. -
Check that return type is
void
. -
Use reset().
-
Check that
sub_group_mask.test(id(N))
forN = 0…sub_group_mask.size() - 1
equalsfalse
.
-
Use non-const instance of
sub_group_mask
. -
Use Predicate
sub_group.get_local_id().size_t()%2 == 0
. -
Check that return type is
void
. -
for
N = 0…sub_group_mask.size() - 1
use reset(id(N)) ifN%3 == 0
. -
Check that
sub_group_mask.test(id(N))
forN = 0…sub_group_mask.size() - 1
equalsfalse
ifN%3 == 0
, and equalsN%2 == 0
otherwise.
-
Use non-const instance of
sub_group_mask
. -
Use Predicate
sub_group.get_local_id().size_t() > sub_group.get_local_range().size_t()/2
. -
Check that return type is
void
. -
Save result for low = find_low().
-
Use reset_low().
-
Check that sub_group_mask[low] refers to
false
. -
Check that
sub_group_mask.test(id(N))
forN = 0…sub_group_mask.size() - 1
equalsfalse
ifN > sub_group.get_local_range().size_t()/2 + 1
andtrue
otherwise.
-
Use non-const instance of
sub_group_mask
. -
Use Predicate
sub_group.get_local_id().size_t() < sub_group.get_local_range().size_t()/2
. -
Check that return type is
void
. -
Save result for high = find_high().
-
Use reset_high().
-
Check that sub_group_mask[high] refers to
false
. -
Check that
sub_group_mask.test(id(N))
forN = 0…sub_group_mask.size() - 1
equalstrue
ifN < sub_group.get_local_range().size_t()/2 - 1
andfalse
otherwise.
-
Use non-const instance of
sub_group_mask
. -
Use Predicate
sub_group.get_local_id().size_t()%2 == 0
. -
Check that return type is
void
. -
Use flip().
-
Check that
sub_group_mask.test(id(N))
forN = 0…sub_group_mask.size() - 1
equalsN%2 =! 0
.
-
Use non-const instance of
sub_group_mask
. -
Use Predicate
sub_group.get_local_id().size_t()%2 == 0
. -
Check that return type is
void
. -
Use flip(sub_group.get_local_id()).
-
Check that
sub_group_mask.test(id(N))
forN = 0…sub_group_mask.size() - 1
equalsN%2 == 0
if id(N) != sub_group.get_local_id(). -
Check that
sub_group_mask.test(sub_group.get_local_id())
equalssub_group.get_local_id().size_t()%2 != 0
-
Use const instance of
sub_group_mask
. -
Use Predicate
sub_group.get_local_id().size_t()%2 == 0
. -
For const rhs sub_group_mask use Predicate
sub_group.get_local_id().size_t()%2 == 0
. -
Check that return type is
bool
. -
Check that result is
true
. -
Use const instance of
sub_group_mask
. -
Use Predicate
sub_group.get_local_id().size_t()%2 == 0
. -
For rhs sub_group_mask use Predicate
sub_group.get_local_id().size_t()%2 != 0
. -
Check that return type is
bool
. -
Check that result is
false
.
-
Use const instance of
sub_group_mask
. -
Use Predicate
sub_group.get_local_id().size_t()%2 == 0
. -
For const rhs sub_group_mask use Predicate
sub_group.get_local_id().size_t()%2 == 0
. -
Check that return type is
bool
. -
Check that result is
false
. -
Use const instance of
sub_group_mask
. -
Use Predicate
sub_group.get_local_id().size_t()%2 == 0
. -
For const rhs sub_group_mask use Predicate
sub_group.get_local_id().size_t()%2 != 0
. -
Check that return type is
bool
. -
Check that result is
true
.
-
Use non-const instance of
sub_group_mask
. -
Use Predicate
sub_group.get_local_id().size_t()%2 == 0
. -
For const rhs sub_group_mask use Predicate
true
. -
Use operator &=(rhs).
-
Check that
sub_group_mask.test(id(N))
forN = 0…sub_group_mask.size() - 1
equalsN%2 == 0
. -
Use non-const instance of
sub_group_mask
. -
Use Predicate
sub_group.get_local_id().size_t()%2 == 0
. -
For const rhs sub_group_mask use Predicate
false
. -
Use operator &=(rhs)
-
Check that
sub_group_mask.test(id(N))
forN = 0…sub_group_mask.size() - 1
equalsfalse
.
-
Use non-const instance of
sub_group_mask
. -
Use Predicate
sub_group.get_local_id().size_t()%2 == 0
. -
For const rhs sub_group_mask use Predicate
true
. -
Use operator |=(rhs)
-
Check that
sub_group_mask.test(id(N))
forN = 0…sub_group_mask.size() - 1
equalstrue
. -
Use non-const instance of
sub_group_mask
. -
Use Predicate
sub_group.get_local_id().size_t()%2 == 0
. -
For const rhs sub_group_mask use Predicate
false
. -
Use operator |=(rhs)
-
Check that
sub_group_mask.test(id(N))
forN = 0…sub_group_mask.size() - 1
equalsN%2 == 0
.
-
Use non-const instance of
sub_group_mask
. -
Use Predicate
sub_group.get_local_id().size_t()%2 == 0
. -
For const rhs sub_group_mask use Predicate
true
. -
Use operator ^=(rhs)
-
Check that
sub_group_mask.test(id(N))
forN = 0…sub_group_mask.size() - 1
equalsN%2 != 0
. -
Use non-const instance of
sub_group_mask
. -
Use Predicate
sub_group.get_local_id().size_t()%2 == 0
. -
For const rhs sub_group_mask use Predicate
false
. -
Use operator ^=(rhs)
-
Check that
sub_group_mask.test(id(N))
forN = 0…sub_group_mask.size() - 1
equalsN%2 == 0
.
For shift = 0…sub_group_mask.size() - 1
:
-
Use const instance of
sub_group_mask
. -
Use Predicate
sub_group.get_local_id().size_t()%3 == 0
. -
Use operator <<=(shift)
-
Check that
sub_group_mask.test(id(N))
forN = shift…sub_group_mask.size() - 1
equals(N - shift)%3 == 0
. -
Check that
sub_group_mask.test(id(N))
forN = 0…shift - 1
equalsfalse
.
For shift = 0…sub_group_mask.size() - 1
:
-
Use const instance of
sub_group_mask
. -
Use Predicate
sub_group.get_local_id().size_t()%3 == 0
. -
Use operator >>=(shift)
-
Check that
sub_group_mask.test(id(N))
forN = sub_group_mask.size() - shift…sub_group_mask.size() - 1
equalsfalse
. -
Check that
sub_group_mask.test(id(N))
forN = 0…sub_group_mask.size() - shift - 1
equals(N + shift)%3 == 0
.
-
Use const instance of
sub_group_mask
. -
Use Predicate
sub_group.get_local_id().size_t()%2 == 0
. -
Check that return type is
sub_group_mask
. -
Get new
sub_group_mask
with operator ~() -
Check that for new
sub_group_mask
sub_group_mask.test(id(N))
forN = 0…sub_group_mask.size() - 1
equalsN%2 != 0
.
For shift = 0…sub_group_mask.size() - 1
:
-
Use non-const instance of
sub_group_mask
. -
Use Predicate
sub_group.get_local_id().size_t()%3 == 0
. -
Get new
sub_group_mask
with operator <<(shift) -
Check that for new
sub_group_mask
sub_group_mask.test(id(N))
forN = shift…sub_group_mask.size() - 1
equals(N - shift)%3 != 0
. -
Check that for new
sub_group_mask
sub_group_mask.test(id(N))
forN = 0…shift - 1
equalsfalse
.
For shift = 0…sub_group_mask.size() - 1
:
-
Use non-const instance of
sub_group_mask
. -
Use Predicate
sub_group.get_local_id().size_t()%3 == 0
. -
Get new
sub_group_mask
with operator >>(shift) -
Check that for new
sub_group_mask
sub_group_mask.test(id(N))
forN = sub_group_mask.size() - shift…sub_group_mask.size() - 1
equalsfalse
. -
Check that for new
sub_group_mask
sub_group_mask.test(id(N))
forN = 0…sub_group_mask.size() - shift - 1
equals(N + shift)%3 != 0
.
-
Use const instances of
sub_group_mask
. -
For lhs sub_group_mask use Predicate
sub_group.get_local_id().size_t()%2 == 0
. -
For rhs sub_group_mask use Predicate
true
. -
Use operator &(const sub_group_mask& lhs, const sub_group_mask& rhs).
-
Check that return type is
sub_group_mask
-
Check that for resulting
sub_group_mask
sub_group_mask.test(id(N))
forN = 0…sub_group_mask.size() - 1
equalsN%2 == 0
. -
Use const instances of
sub_group_mask
. -
For lhs sub_group_mask use Predicate
sub_group.get_local_id().size_t()%2 == 0
. -
For rhs sub_group_mask use Predicate
false
. -
Use operator &(const sub_group_mask& lhs, const sub_group_mask& rhs).
-
Check that for resulting
sub_group_mask
sub_group_mask.test(id(N))
forN = 0…sub_group_mask.size() - 1
equalsfalse
.
-
Use const instances of
sub_group_mask
. -
For lhs sub_group_mask use Predicate
sub_group.get_local_id().size_t()%2 == 0
. -
For rhs sub_group_mask use Predicate
true
. -
Use operator |=(rhs)
-
Check that return type is
sub_group_mask
-
Check that for resulting
sub_group_mask
sub_group_mask.test(id(N))
forN = 0…sub_group_mask.size() - 1
equalstrue
. -
Use const instances of
sub_group_mask
. -
For lhs sub_group_mask use Predicate
sub_group.get_local_id().size_t()%2 == 0
. -
For rhs sub_group_mask use Predicate
false
. -
Use operator |=(rhs)
-
Check that for resulting
sub_group_mask
sub_group_mask.test(id(N))
forN = 0…sub_group_mask.size() - 1
equalsN%2 == 0
.
-
Use const instances of
sub_group_mask
. -
For lhs sub_group_mask use Predicate
sub_group.get_local_id().size_t()%2 == 0
. -
For rhs sub_group_mask use Predicate
true
. -
Use operator ^=(rhs)
-
Check that for resulting
sub_group_mask
sub_group_mask.test(id(N))
forN = 0…sub_group_mask.size() - 1
equalsN%2 != 0
. -
Use const instances of
sub_group_mask
. -
For lhs sub_group_mask use Predicate
sub_group.get_local_id().size_t()%2 == 0
. -
For rhs sub_group_mask use Predicate
false
. -
Use operator ^=(rhs)
-
Check that return type is
sub_group_mask
-
Check that for resulting
sub_group_mask
sub_group_mask.test(id(N))
forN = 0…sub_group_mask.size() - 1
equalsN%2 == 0
.