Skip to content

Commit 5061cb5

Browse files
Added VectBitSet class wrapping sycl::vec, and implementing large bitset semantics.
1 parent 525a14f commit 5061cb5

File tree

3 files changed

+156
-0
lines changed

3 files changed

+156
-0
lines changed

models/starComplexity.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,11 @@ constexpr unsigned maxNodes=22, maxStars=2*maxNodes-1;
55

66
#include "netcomplexity.h"
77

8+
#ifdef SYCL_LANGUAGE_VERSION
9+
10+
11+
12+
813
class linkRep
914
{
1015
public:

models/testVecBitSet.cc

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
#include "vecBitSet.h"
2+
#include <iostream>
3+
using namespace std;
4+
5+
// TODO - convert this to a unit test
6+
7+
void print(VecBitSet<unsigned,4> x)
8+
{
9+
for (unsigned i=0; i<x.size(); ++i)
10+
cout<<hex<<x[i]<<" ";
11+
cout<<endl;
12+
}
13+
14+
int main()
15+
{
16+
VecBitSet<unsigned,4> v(sycl::vec<unsigned,4>(1,3,7,15));
17+
auto x=v<<5;
18+
print(x);
19+
print(v<<40);
20+
print(v>>5);
21+
print(v>>40);
22+
}

models/vecBitSet.h

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
// a type of high bitcount objects suitable for SYCL
2+
3+
#ifndef ECOLAB_VECBITSET_H
4+
#define ECOLAB_VECBITSET_H
5+
6+
#ifdef SYCL_LANGUAGE_VERSION
7+
#include <sycl/sycl.hpp>
8+
9+
// constructs a swizzle permutation (From...V::size(), 0...From-1)
10+
// initialise with To=V::size(), NumItems=0 and N=
11+
// NumItems tracks the numer of items in the parameter pack \a N
12+
template <class V, unsigned From, unsigned To, unsigned NumItems, unsigned... N>
13+
V swizzleFrom(const V& x) {
14+
if constexpr (From<To) {
15+
return swizzleFrom<V,From+1,To, NumItems+1, N...,From>(x);
16+
} else if constexpr (NumItems<V::size()) { // fill in remainder of permutation
17+
return swizzleFrom<V,0,V::size()-NumItems,NumItems,N...>(x);
18+
} else {
19+
return x.template swizzle<N...>();
20+
}
21+
}
22+
23+
template <class V, unsigned From>
24+
V swizzleFrom(const V& x) {return swizzleFrom<V,From,unsigned(V::size()),0>(x);}
25+
26+
/// assign the value \a t to all elements [From..To)
27+
template <class V, class T, unsigned From, unsigned To, unsigned... N>
28+
void swizzleAsg(V& x, const T& t) {
29+
if constexpr (From<To) {
30+
swizzleAsg<V,T,From+1,To, N...,From>(x,t);
31+
} else {
32+
x.template swizzle<N...>()=t;
33+
}
34+
}
35+
36+
// a type of high bitcount objects
37+
template <class T, unsigned N>
38+
class VecBitSet: public sycl::vec<T,N>
39+
{
40+
// shift vector by n positions using a swizzle
41+
template <unsigned n> VecBitSet shiftLeft() const {
42+
if constexpr (n<N) {
43+
VecBitSet r=swizzleFrom<const VecBitSet,N-n>(*this);
44+
swizzleAsg<VecBitSet,T,0,n>(r,0);
45+
return r;
46+
}
47+
return sycl::vec<T,N>(0);
48+
}
49+
50+
// shift vector by n positions using a swizzle
51+
template <unsigned n> VecBitSet shiftRight() const {
52+
if constexpr (n<N) {
53+
VecBitSet r=swizzleFrom<const VecBitSet,n>(*this);
54+
swizzleAsg<VecBitSet,T,N-n,N>(r,0);
55+
return r;
56+
}
57+
return sycl::vec<T,N>(0);
58+
}
59+
60+
// returns result of bitshifting to the left
61+
// @param r = original vector shifted one extra posiution to the left
62+
// @param l = original vector
63+
VecBitSet bitShiftLeft(sycl::vec<T,N> r, const sycl::vec<T,N>& l, unsigned remainder) const {
64+
r>>=(8*sizeof(T)-remainder);
65+
r|=l<<remainder;
66+
return r;
67+
}
68+
69+
#ifdef CLASSDESC_ACCESS
70+
CLASSDESC_ACCESS(VecBitSet);
71+
#endif
72+
public:
73+
VecBitSet()=default;
74+
template <class U>
75+
VecBitSet(const U& x): sycl::vec<T,N>(x) {}
76+
template <class U>
77+
VecBitSet& operator=(const U& x) {sycl::vec<T,N>::operator=(x); return *this;}
78+
// only need to fix up bit shift operations
79+
VecBitSet operator<<(unsigned n) const {
80+
auto d=div(int(n),8*sizeof(T));
81+
switch (d.quot) {
82+
case 0: return bitShiftLeft(shiftLeft<1>(), *this, d.rem);
83+
case 1: return bitShiftLeft(shiftLeft<2>(), shiftLeft<1>(), d.rem);
84+
case 2: return bitShiftLeft(shiftLeft<3>(), shiftLeft<2>(), d.rem);
85+
case 3: return bitShiftLeft(shiftLeft<4>(), shiftLeft<3>(), d.rem);
86+
case 4: return bitShiftLeft(shiftLeft<5>(), shiftLeft<4>(), d.rem);
87+
case 5: return bitShiftLeft(shiftLeft<6>(), shiftLeft<5>(), d.rem);
88+
case 6: return bitShiftLeft(shiftLeft<7>(), shiftLeft<6>(), d.rem);
89+
case 7: return bitShiftLeft(shiftLeft<8>(), shiftLeft<7>(), d.rem);
90+
case 8: return bitShiftLeft(shiftLeft<9>(), shiftLeft<8>(), d.rem);
91+
case 9: return bitShiftLeft(shiftLeft<10>(), shiftLeft<9>(), d.rem);
92+
case 10: return bitShiftLeft(shiftLeft<11>(), shiftLeft<10>(), d.rem);
93+
case 11: return bitShiftLeft(shiftLeft<12>(), shiftLeft<11>(), d.rem);
94+
case 12: return bitShiftLeft(shiftLeft<13>(), shiftLeft<12>(), d.rem);
95+
case 13: return bitShiftLeft(shiftLeft<14>(), shiftLeft<13>(), d.rem);
96+
case 14: return bitShiftLeft(shiftLeft<15>(), shiftLeft<14>(), d.rem);
97+
case 15: return shiftLeft<15>() >> (8*sizeof(T)-d.rem);
98+
default: return sycl::vec<T,N>(0); // SYCL defines a maximum of 16 elements in a vec.
99+
}
100+
}
101+
VecBitSet operator>>(unsigned n) const {
102+
auto d=div(int(n),8*sizeof(T));
103+
d.rem=(8*sizeof(T)-d.rem)%(8*sizeof(T)); // shift the other way
104+
switch (d.quot) {
105+
case 0: return bitShiftLeft(*this, shiftRight<1>(), d.rem);
106+
case 1: return bitShiftLeft(shiftRight<1>(), shiftRight<2>(), d.rem);
107+
case 2: return bitShiftLeft(shiftRight<2>(), shiftRight<3>(), d.rem);
108+
case 3: return bitShiftLeft(shiftRight<3>(), shiftRight<4>(), d.rem);
109+
case 4: return bitShiftLeft(shiftRight<4>(), shiftRight<5>(), d.rem);
110+
case 5: return bitShiftLeft(shiftRight<5>(), shiftRight<6>(), d.rem);
111+
case 6: return bitShiftLeft(shiftRight<6>(), shiftRight<7>(), d.rem);
112+
case 7: return bitShiftLeft(shiftRight<7>(), shiftRight<8>(), d.rem);
113+
case 8: return bitShiftLeft(shiftRight<8>(), shiftRight<9>(), d.rem);
114+
case 9: return bitShiftLeft(shiftRight<9>(), shiftRight<10>(), d.rem);
115+
case 10: return bitShiftLeft(shiftRight<10>(), shiftRight<11>(), d.rem);
116+
case 11: return bitShiftLeft(shiftRight<11>(), shiftRight<12>(), d.rem);
117+
case 12: return bitShiftLeft(shiftRight<12>(), shiftRight<13>(), d.rem);
118+
case 13: return bitShiftLeft(shiftRight<13>(), shiftRight<14>(), d.rem);
119+
case 14: return bitShiftLeft(shiftRight<14>(), shiftRight<15>(), d.rem);
120+
case 15: return shiftRight<15>() >> (8*sizeof(T)-d.rem);
121+
default: return sycl::vec<T,N>(0); // SYCL defines a maximum of 16 elements in a vec.
122+
}
123+
}
124+
};
125+
126+
127+
128+
#endif
129+
#endif

0 commit comments

Comments
 (0)