-
Notifications
You must be signed in to change notification settings - Fork 5
Slice and Subtensor
A slice object is used to specify how to slice extents. You can specify where to start the slicing, and where to end. You can also specify the step. My implementation contains two types of slice, one is static and another one is dynamic. The static one is a compiled time object which is decreases runtime cost compared to the dynamic slice.
A subtensor object is used to create new tensor without copying or moving old tensor data which needs new memory space and increases runtime cost. For example, you need to do some tensor operation inside a loop by creating a new tensor again and again by copying the tensor which inturns increase the runtime. If we use subtensor runtime cost decreases drastically.
Subtensor reduces this runtime cost by taking the pointer to the tensor data, which is cheap to copy.
I took the slice implementation from Cem Bassoy's previous year's implementation of span and created the improved one from the ground up and added the concept of a static slice and a dynamic slice.
- I have combined both stridden and sliced slice as the previous one used the tag to identify them.
- Added static and dynamic concept and there is no such concept in the previous one.
- Removed two functions which were not begin used (
operator[]
for getting the position andoperator()
for getting new slice after passing old slice ) - No concept of
ran
function
- Reverse iterating when step is < 0
using namespace boost::numeric::ublas;
// can be both static or dynamic based the situation but by default, it's treated as dynamic
auto s1 = span::slice<>{};
// dynamic slice ( start: 0, end: 10, step: 1 )
auto s2 = span::slice<>{0,10};
// dynamic slice ( start: 0, end: 10, step: 4 )
auto s3 = span::slice<>{0,10,4};
// dynamic slice ( start: 0, end: ( extent - 2 ), step: 4 )
auto s4 = span::slice<>{0,-2,4};
// dynamic slice ( start: ( extent - 7 ), end: ( extent - 2 ), step: 4 )
// caution: if both numbers are negative then start must be less than end ( -7 < -3 or start < end )
auto s5 = span::slice<>{-7,-2,4};
// dynamic slice ( start: 3, end: 3, step: 1 )
auto s6 = span::slice<>{3};
// dynamic slice ( start: ( extent - 3 ), end: ( extent - 3 ), step: 1 )
auto s7 = span::slice<>{-3};
// dynamic slice ( start: ( extent - 3 ), end: 8, step: 1 )
// caution: (extent - 3) < 8
auto s8 = span::slice<>{-3, 8};
// static slice ( start: 0, end: 10, step: 1 )
auto s9 = span::slice<0,10>{};
// static slice ( start: 0, end: 10, step: 4 )
auto s10 = span::slice<0,10,4>{};
// static slice ( start: 0, end: ( extent - 2 ), step: 4 )
auto s11 = span::slice<0,-2,4>{};
// static slice ( start: ( extent - 7 ), end: ( extent - 2 ), step: 4 )
// caution: if both numbers are negative then start must be less than end ( -7 < -3 or start < end )
auto s12 = span::slice<-7,-2,4>{};
// static slice ( start: 3, end: 3, step: 1 )
auto s13 = span::slice<3>{};
// static slice ( start: ( extent - 3 ), end: ( extent - 3 ), step: 1 )
auto s14 = span::slice<-3>{};
// static slice ( start: ( extent - 3 ), end: 8, step: 1 )
// caution: (extent - 3) < 8
auto s15 = span::slice<-3, 8>{};
boost::numeric::ublas::span::slice<>
is type alias for boost::numeric::ublas::basic_slice<ptrdiff_t,Args...>
so for some reason you want to use different type for slice.
template<ptrdiff_t,... Args>
using my_slice = boost::numeric::ublas::basic_slice<size_t,Args...>;
auto s1 = my_slice<0,6,3>{};
Similar to slice I took the implementation from subtensor and added the support for both the static slice and the dynamic slice.
I also modified the subtensor helper functions which needed to be modified for the static slice and dynamic slice. Now if tensor has static extents and static slice, the type of subtensor will be static subtensor and other this condition subtensor is dynamic subtensor.
- It is missing a few functions such as
data
,rank
, etc - Better support for the tensor operation
using namespace boost::numeric::ublas;
auto t1 = tensor{static_extents<10,10>{},1.f};
auto t2 = tensor{dynamic_extents<>{10,10},1.f};
//static subtensor
auto s1 = t1(span::slice<2,3>{}, span::slice<>{}};
//dynamic subtensor
auto s2 = t1(span::slice<>{2,3}, span::slice<>{}};
//dynamic subtensor
auto s3 = t2(span::slice<>{2,3}, span::slice<>{}};
/-----------other ways to create subtensor---------------/
// static subtensor
auto s4 = subtensor<decltype(t1),span::slice<0,5>,span::slice<4>>{ t1 };
// dynamic subtensor
auto s5 = subtensor{ t1, ,span::slice<>{0,5},span::slice<>{4} };
I will try to mitigate all the problems which are discussed above, after mitigating I will implement reverse iterating when step < 0 and I am thinking of adding python like slice using string. This slice using string will reduce writing slice again and again as it will follow DRY( Do not Repeat Yourself ).
We both would like to thank our mentor Cem for his constant support and help in achieving our goals. We always find him helpful and he was always easy to reach for help or discussion regarding the work. We would also like to thank Google for the Google Summer of Code Programme, without which all these wouldn't be possible. Lastly, we express our gratitude to our parents for helping and providing us with all the indirect or direct needs for carrying out our work nicely in our homes.
- Home
- Project Proposal
- Milestones and Tasks
- Implementation
- Documentation
- Discussions
- Examples
- Experimental features
- Project Proposal
- Milestones and Tasks
- Implementation
- Documentation
- Discussions
- Example Code