Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
FORMUS3IC_LAS3
/
embb
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
0
Merge Requests
0
Pipelines
Wiki
Members
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Commit
17341a5c
authored
Mar 31, 2015
by
Tobias Fuchs
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'embb392_partitioner' into development
parents
52a5d250
1b725190
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
174 additions
and
107 deletions
+174
-107
algorithms_cpp/include/embb/algorithms/internal/partition-inl.h
+68
-73
algorithms_cpp/include/embb/algorithms/internal/partition.h
+31
-31
algorithms_cpp/test/partitioner_test.cc
+68
-3
algorithms_cpp/test/partitioner_test.h
+7
-0
No files found.
algorithms_cpp/include/embb/algorithms/internal/partition-inl.h
View file @
17341a5c
...
...
@@ -31,109 +31,104 @@ namespace embb {
namespace
algorithms
{
namespace
internal
{
template
<
typename
ForwardIterator
>
ChunkDescriptor
<
ForwardIterator
>::
ChunkDescriptor
(
ForwardIterator
first
,
ForwardIterator
last
)
:
first
(
first
),
last
(
last
)
{
template
<
typename
RAI
>
ChunkDescriptor
<
RAI
>::
ChunkDescriptor
(
RAI
first
,
RAI
last
)
:
first_
(
first
),
last_
(
last
)
{
}
template
<
typename
ForwardIterator
>
ForwardIterator
ChunkDescriptor
<
ForwardIterator
>::
GetFirst
()
const
{
return
first
;
template
<
typename
RAI
>
RAI
ChunkDescriptor
<
RAI
>::
GetFirst
()
const
{
return
first
_
;
}
template
<
typename
ForwardIterator
>
ForwardIterator
ChunkDescriptor
<
ForwardIterator
>::
GetLast
()
const
{
return
last
;
template
<
typename
RAI
>
RAI
ChunkDescriptor
<
RAI
>::
GetLast
()
const
{
return
last
_
;
}
template
<
typename
ForwardIterator
>
BlockSizePartitioner
<
ForwardIterator
>::
BlockSizePartitioner
(
ForwardIterator
first
,
ForwardIterator
last
,
size_t
chunkSize
)
:
first
(
first
),
last
(
last
),
chunkSize
(
chunkSize
)
{
elements_count
=
static_cast
<
size_t
>
(
std
::
distance
(
first
,
last
));
chunks
=
elements_count
/
chunkSize
;
if
(
elements_count
%
chunkSize
!=
0
)
chunks
++
;
template
<
typename
RAI
>
BlockSizePartitioner
<
RAI
>::
BlockSizePartitioner
(
RAI
first
,
RAI
last
,
size_t
chunkSize
)
:
first_
(
first
),
last_
(
last
),
chunk_size_
(
chunkSize
)
{
elements_count_
=
static_cast
<
size_t
>
(
std
::
distance
(
first_
,
last_
));
chunks_
=
elements_count_
/
chunk_size_
;
if
(
elements_count_
%
chunk_size_
!=
0
)
{
chunks_
++
;
}
}
template
<
typename
ForwardIterator
>
size_t
BlockSizePartitioner
<
ForwardIterator
>::
Size
()
{
return
chunks
;
template
<
typename
RAI
>
size_t
BlockSizePartitioner
<
RAI
>::
Size
()
{
return
chunks
_
;
}
template
<
typename
ForwardIterator
>
const
ChunkDescriptor
<
ForwardIterator
>
BlockSizePartitioner
<
ForwardIterator
>::
operator
[](
size_t
const
&
index
)
const
{
ForwardIterator
first_new
=
first
;
std
::
advance
(
first_new
,
index
*
chunkSize
)
;
ForwardIterator
last_new
=
first_new
;
if
(
index
>=
chunks
-
1
)
{
last_new
=
last
;
template
<
typename
RAI
>
const
ChunkDescriptor
<
RAI
>
BlockSizePartitioner
<
RAI
>::
operator
[](
size_t
const
&
index
)
const
{
typedef
typename
std
::
iterator_traits
<
RAI
>::
difference_type
difference_type
;
RAI
first_new
(
first_
);
first_new
+=
static_cast
<
difference_type
>
(
chunk_size_
*
index
)
;
RAI
last_new
(
first_new
);
if
(
index
>=
chunks
_
-
1
)
{
last_new
=
last
_
;
}
else
{
std
::
advance
(
last_new
,
chunkSize
);
last_new
+=
static_cast
<
difference_type
>
(
chunk_size_
);
}
return
ChunkDescriptor
<
ForwardIterator
>
(
first_new
,
last_new
);
return
ChunkDescriptor
<
RAI
>
(
first_new
,
last_new
);
}
template
<
typename
ForwardIterator
>
size_t
ChunkPartitioner
<
ForwardIterator
>::
Size
()
{
return
size
;
template
<
typename
RAI
>
size_t
ChunkPartitioner
<
RAI
>::
Size
()
{
return
size
_
;
}
template
<
typename
ForwardIterator
>
ChunkPartitioner
<
ForwardIterator
>::
ChunkPartitioner
(
ForwardIterator
first
,
ForwardIterator
last
,
size_t
amountChunks
)
:
first
(
first
),
last
(
last
)
{
template
<
typename
RAI
>
ChunkPartitioner
<
RAI
>::
ChunkPartitioner
(
RAI
first
,
RAI
last
,
size_t
amountChunks
)
:
first_
(
first
),
last_
(
last
)
{
if
(
amountChunks
>
0
)
{
size
=
amountChunks
;
size
_
=
amountChunks
;
}
else
{
// if no concrete chunk size was given, use number of cores
...
// if no concrete chunk size was given, use number of cores
embb
::
tasks
::
Node
&
node
=
embb
::
tasks
::
Node
::
GetInstance
();
size
=
node
.
GetWorkerThreadCount
();
size
_
=
node
.
GetWorkerThreadCount
();
}
elements_count
=
static_cast
<
size_t
>
(
std
::
distance
(
first
,
last
));
if
(
size
>
elements_count
)
{
elements_count_
=
static_cast
<
size_t
>
(
std
::
distance
(
first_
,
last_
));
if
(
size_
>
elements_count_
)
{
// if we want to make more chunks than we have elements, correct
// the number of chunks
size
=
elements_count
;
size
_
=
elements_count_
;
}
standard_chunk_size
=
elements_count
/
size
;
bigger_chunk_count
=
elements_count
%
size
;
standard_chunk_size
_
=
elements_count_
/
size_
;
bigger_chunk_count
_
=
elements_count_
%
size_
;
}
template
<
typename
ForwardIterator
>
const
ChunkDescriptor
<
ForwardIterator
>
ChunkPartitioner
<
ForwardIterator
>::
operator
[](
template
<
typename
RAI
>
const
ChunkDescriptor
<
RAI
>
ChunkPartitioner
<
RAI
>::
operator
[](
size_t
const
&
index
)
const
{
typedef
typename
std
::
iterator_traits
<
ForwardIterator
>::
difference_type
typedef
typename
std
::
iterator_traits
<
RAI
>::
difference_type
difference_type
;
// Number of element preceding elements in the given chunk
size_t
prec_elements_count
=
0
;
if
(
index
<=
bigger_chunk_count
)
{
prec_elements_count
=
index
*
(
standard_chunk_size
+
1
);
if
(
index
<=
bigger_chunk_count_
)
{
prec_elements_count
=
index
*
(
standard_chunk_size_
+
1
);
}
else
{
prec_elements_count
=
(
standard_chunk_size
+
1
)
*
bigger_chunk_count
+
standard_chunk_size
*
(
index
-
bigger_chunk_count
);
prec_elements_count
=
(
standard_chunk_size_
+
1
)
*
bigger_chunk_count_
+
(
standard_chunk_size_
*
(
index
-
bigger_chunk_count_
));
}
size_t
cur_elements_count
=
(
index
<
bigger_chunk_count
)
?
(
standard_chunk_size
+
1
)
:
standard_chunk_size
;
ForwardIterator
first_new
=
first
;
std
::
advance
(
first_new
,
prec_elements_count
);
first_new
=
first
+
static_cast
<
difference_type
>
(
prec_elements_count
);
ForwardIterator
last_new
=
first_new
;
std
::
advance
(
last_new
,
cur_elements_count
);
return
ChunkDescriptor
<
ForwardIterator
>
(
first_new
,
last_new
);
size_t
cur_elements_count
=
(
index
<
bigger_chunk_count_
)
?
(
standard_chunk_size_
+
1
)
:
standard_chunk_size_
;
RAI
first_new
(
first_
);
first_new
+=
static_cast
<
difference_type
>
(
prec_elements_count
);
RAI
last_new
(
first_new
);
last_new
+=
static_cast
<
difference_type
>
(
cur_elements_count
);
return
ChunkDescriptor
<
RAI
>
(
first_new
,
last_new
);
}
}
// namespace internal
...
...
algorithms_cpp/include/embb/algorithms/internal/partition.h
View file @
17341a5c
...
...
@@ -38,14 +38,14 @@ namespace internal {
* Describes a single partition of a 1-dimensional
* partitioning, using first and last iterator.
*
* \tparam
ForwardIterator
Type of the iterator.
* \tparam
RAI
Type of the iterator.
*/
template
<
typename
ForwardIterator
>
template
<
typename
RAI
>
class
ChunkDescriptor
{
private
:
ForwardIterator
first
;
ForwardIterator
last
;
RAI
first_
;
RAI
last_
;
public
:
/**
...
...
@@ -54,7 +54,7 @@ class ChunkDescriptor {
* \param first The first iterator.
* \param last The last iterator
*/
ChunkDescriptor
(
ForwardIterator
first
,
ForwardIterator
last
);
ChunkDescriptor
(
RAI
first
,
RAI
last
);
/**
* Gets the first iterator.
...
...
@@ -63,7 +63,7 @@ class ChunkDescriptor {
*
* \waitfree
*/
ForwardIterator
GetFirst
()
const
;
RAI
GetFirst
()
const
;
/**
* Gets the last iterator.
...
...
@@ -72,7 +72,7 @@ class ChunkDescriptor {
*
* \waitfree
*/
ForwardIterator
GetLast
()
const
;
RAI
GetLast
()
const
;
};
/**
...
...
@@ -80,9 +80,9 @@ class ChunkDescriptor {
*
* Describes the interface for accessing a 1-dimensional partitioning.
*
* \tparam
ForwardIterator
Type of the iterator.
* \tparam
RAI
Type of the iterator.
*/
template
<
typename
ForwardIterator
>
template
<
typename
RAI
>
class
IPartitioner
{
public
:
virtual
~
IPartitioner
()
{}
...
...
@@ -106,7 +106,7 @@ class IPartitioner {
*
* \waitfree
*/
virtual
const
ChunkDescriptor
<
ForwardIterator
>
operator
[](
virtual
const
ChunkDescriptor
<
RAI
>
operator
[](
size_t
const
&
index
)
const
=
0
;
};
...
...
@@ -129,16 +129,16 @@ class IPartitioner {
* 2: [6,7,8,9,10]
* 3: [11,12,13]
*
* \tparam
ForwardIterator
Type of the iterator.
* \tparam
RAI
Type of the iterator.
*/
template
<
typename
ForwardIterator
>
class
BlockSizePartitioner
:
IPartitioner
<
ForwardIterator
>
{
template
<
typename
RAI
>
class
BlockSizePartitioner
:
IPartitioner
<
RAI
>
{
private
:
ForwardIterator
first
;
ForwardIterator
last
;
size_t
chunk
Size
;
size_t
elements_count
;
size_t
chunks
;
RAI
first_
;
RAI
last_
;
size_t
chunk
_size_
;
size_t
elements_count
_
;
size_t
chunks
_
;
public
:
/**
...
...
@@ -150,7 +150,7 @@ class BlockSizePartitioner : IPartitioner < ForwardIterator > {
* \param chunkSize (Optional) size of the chunk.
*/
BlockSizePartitioner
(
ForwardIterator
first
,
ForwardIterator
last
,
size_t
chunkSize
=
1
);
RAI
first
,
RAI
last
,
size_t
chunkSize
=
1
);
/**
* See IPartitioner
...
...
@@ -164,7 +164,7 @@ class BlockSizePartitioner : IPartitioner < ForwardIterator > {
*
* \waitfree
*/
virtual
const
ChunkDescriptor
<
ForwardIterator
>
operator
[](
virtual
const
ChunkDescriptor
<
RAI
>
operator
[](
size_t
const
&
index
)
const
;
};
...
...
@@ -196,17 +196,17 @@ class BlockSizePartitioner : IPartitioner < ForwardIterator > {
* 4: [10,11]
* 5: [12,13]
*
* \tparam
ForwardIterator
Type of the iterator.
* \tparam
RAI
Type of the iterator.
*/
template
<
typename
ForwardIterator
>
class
ChunkPartitioner
:
IPartitioner
<
ForwardIterator
>
{
template
<
typename
RAI
>
class
ChunkPartitioner
:
IPartitioner
<
RAI
>
{
private
:
size_t
size
;
size_t
elements_count
;
ForwardIterator
first
;
ForwardIterator
last
;
size_t
standard_chunk_size
;
size_t
bigger_chunk_count
;
size_t
size
_
;
size_t
elements_count
_
;
RAI
first_
;
RAI
last_
;
size_t
standard_chunk_size
_
;
size_t
bigger_chunk_count
_
;
public
:
/**
...
...
@@ -227,7 +227,7 @@ class ChunkPartitioner : IPartitioner < ForwardIterator > {
* \param last The last.
* \param amountChunks (Optional) the amount chunks.
*/
ChunkPartitioner
(
ForwardIterator
first
,
ForwardIterator
last
,
ChunkPartitioner
(
RAI
first
,
RAI
last
,
size_t
amountChunks
=
0
);
/**
...
...
@@ -235,7 +235,7 @@ class ChunkPartitioner : IPartitioner < ForwardIterator > {
*
* \waitfree
*/
virtual
const
ChunkDescriptor
<
ForwardIterator
>
operator
[](
virtual
const
ChunkDescriptor
<
RAI
>
operator
[](
size_t
const
&
index
)
const
;
};
...
...
algorithms_cpp/test/partitioner_test.cc
View file @
17341a5c
...
...
@@ -33,9 +33,15 @@
#include <vector>
#include <list>
PartitionerTest
::
PartitionerTest
()
{
CreateUnit
(
"algorithms partitioner test"
).
Add
(
&
PartitionerTest
::
TestBasic
,
this
);
PartitionerTest
::
PartitionerTest
()
:
partitioned_array_size_
(
16384
)
{
// Size of array to be partitioned should be power of 2
CreateUnit
(
"TestBasic"
)
.
Add
(
&
PartitionerTest
::
TestBasic
,
this
);
CreateUnit
(
"TestLargeRange"
)
.
Pre
(
&
PartitionerTest
::
TestLargeRangePre
,
this
)
.
Add
(
&
PartitionerTest
::
TestLargeRange
,
this
)
.
Post
(
&
PartitionerTest
::
TestLargeRangePost
,
this
);
}
void
PartitionerTest
::
TestBasic
()
{
...
...
@@ -70,3 +76,62 @@ void PartitionerTest::TestBasic() {
PT_EXPECT_EQ_MSG
(
partitioner2
.
Size
(),
size_t
(
3
),
"Check count of partitions"
);
}
void
PartitionerTest
::
TestLargeRangePre
()
{
partitioned_array_
=
new
int
[
partitioned_array_size_
];
for
(
size_t
i
=
0
;
i
<
partitioned_array_size_
;
++
i
)
{
partitioned_array_
[
i
]
=
static_cast
<
int
>
(
i
);
}
}
void
PartitionerTest
::
TestLargeRangePost
()
{
delete
[]
partitioned_array_
;
}
void
PartitionerTest
::
TestLargeRange
()
{
// Test chunk partitioner with increasing number of chunks:
for
(
size_t
num_chunks
=
2
;
num_chunks
<
partitioned_array_size_
;
num_chunks
*=
2
)
{
embb
::
algorithms
::
internal
::
ChunkPartitioner
<
int
*>
chunk_partitioner
(
partitioned_array_
,
partitioned_array_
+
partitioned_array_size_
,
num_chunks
);
int
last_value_prev
=
-
1
;
PT_EXPECT_EQ
(
num_chunks
,
chunk_partitioner
.
Size
());
// Iterate over chunks in partition:
for
(
size_t
chunk
=
0
;
chunk
<
chunk_partitioner
.
Size
();
++
chunk
)
{
int
first_value
=
*
(
chunk_partitioner
[
chunk
].
GetFirst
());
int
last_value
=
*
(
chunk_partitioner
[
chunk
].
GetLast
()
-
1
);
PT_EXPECT_LT
(
first_value
,
last_value
);
// Test seams between chunks: chunk[i].last + 1 == chunk[i+1].first
PT_EXPECT_EQ
((
last_value_prev
+
1
),
first_value
);
last_value_prev
=
last_value
;
}
}
// Test block size partitioner with increasing chunk size:
for
(
size_t
block_size
=
1
;
block_size
<
partitioned_array_size_
;
block_size
*=
2
)
{
embb
::
algorithms
::
internal
::
BlockSizePartitioner
<
int
*>
chunk_partitioner
(
partitioned_array_
,
partitioned_array_
+
partitioned_array_size_
,
block_size
);
int
last_value_prev
=
-
1
;
// Iterate over chunks in partition:
for
(
size_t
chunk
=
0
;
chunk
<
chunk_partitioner
.
Size
();
++
chunk
)
{
int
first_value
=
*
(
chunk_partitioner
[
chunk
].
GetFirst
());
int
last_value
=
*
(
chunk_partitioner
[
chunk
].
GetLast
()
-
1
);
if
(
block_size
==
1
)
{
PT_EXPECT_EQ
(
first_value
,
last_value
);
}
else
{
PT_EXPECT_LT
(
first_value
,
last_value
);
}
// Test seams between chunks: chunk[i].last + 1 == chunk[i+1].first
PT_EXPECT_EQ
((
last_value_prev
+
1
),
first_value
);
last_value_prev
=
last_value
;
}
}
}
algorithms_cpp/test/partitioner_test.h
View file @
17341a5c
...
...
@@ -35,6 +35,13 @@ class PartitionerTest : public partest::TestCase {
private
:
void
TestBasic
();
void
TestLargeRangePre
();
void
TestLargeRangePost
();
void
TestLargeRange
();
int
*
partitioned_array_
;
size_t
partitioned_array_size_
;
};
#endif // ALGORITHMS_CPP_TEST_PARTITIONER_TEST_H_
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment