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
9e2febab
authored
Mar 30, 2015
by
Tobias Fuchs
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
algorithms_cpp: restricted partitioners to RAI, added unit tests for partitioners on large ranges
parent
791943da
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
173 additions
and
107 deletions
+173
-107
algorithms_cpp/include/embb/algorithms/internal/partition-inl.h
+67
-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 @
9e2febab
...
@@ -31,109 +31,103 @@ namespace embb {
...
@@ -31,109 +31,103 @@ namespace embb {
namespace
algorithms
{
namespace
algorithms
{
namespace
internal
{
namespace
internal
{
template
<
typename
ForwardIterator
>
template
<
typename
RAI
>
ChunkDescriptor
<
ForwardIterator
>::
ChunkDescriptor
(
ForwardIterator
first
,
ChunkDescriptor
<
RAI
>::
ChunkDescriptor
(
ForwardIterator
last
)
:
RAI
first
,
RAI
last
)
:
first
(
first
),
last
(
last
)
{
first_
(
first
),
last_
(
last
)
{
}
}
template
<
typename
ForwardIterator
>
template
<
typename
RAI
>
ForwardIterator
ChunkDescriptor
<
ForwardIterator
>::
GetFirst
()
const
{
RAI
ChunkDescriptor
<
RAI
>::
GetFirst
()
const
{
return
first
;
return
first
_
;
}
}
template
<
typename
ForwardIterator
>
template
<
typename
RAI
>
ForwardIterator
ChunkDescriptor
<
ForwardIterator
>::
GetLast
()
const
{
RAI
ChunkDescriptor
<
RAI
>::
GetLast
()
const
{
return
last
;
return
last
_
;
}
}
template
<
typename
ForwardIterator
>
template
<
typename
RAI
>
BlockSizePartitioner
<
ForwardIterator
>::
BlockSizePartitioner
(
BlockSizePartitioner
<
RAI
>::
BlockSizePartitioner
(
ForwardIterator
first
,
ForwardIterator
last
,
size_t
chunkSize
)
:
RAI
first
,
RAI
last
,
size_t
chunkSize
)
:
first
(
first
),
last
(
last
),
chunkSize
(
chunkSize
)
{
first_
(
first
),
last_
(
last
),
chunk_size_
(
chunkSize
)
{
elements_count
=
static_cast
<
size_t
>
(
std
::
distance
(
first
,
last
));
elements_count_
=
static_cast
<
size_t
>
(
std
::
distance
(
first_
,
last_
));
chunks
=
elements_count
/
chunkSize
;
chunks_
=
elements_count_
/
chunk_size_
;
if
(
elements_count
%
chunkSize
!=
0
)
if
(
elements_count_
%
chunk_size_
!=
0
)
{
chunks
++
;
chunks_
++
;
}
}
}
template
<
typename
ForwardIterator
>
template
<
typename
RAI
>
size_t
BlockSizePartitioner
<
ForwardIterator
>::
Size
()
{
size_t
BlockSizePartitioner
<
RAI
>::
Size
()
{
return
chunks
;
return
chunks
_
;
}
}
template
<
typename
ForwardIterator
>
template
<
typename
RAI
>
const
ChunkDescriptor
<
ForwardIterator
>
const
ChunkDescriptor
<
RAI
>
BlockSizePartitioner
<
ForwardIterator
>::
operator
[](
BlockSizePartitioner
<
RAI
>::
operator
[](
size_t
const
&
index
)
const
{
size_t
const
&
index
)
const
{
ForwardIterator
first_new
=
first
;
typedef
std
::
iterator_traits
<
RAI
>::
difference_type
difference_type
;
std
::
advance
(
first_new
,
index
*
chunkSize
);
RAI
first_new
(
first_
);
first_new
+=
static_cast
<
difference_type
>
(
chunk_size_
*
index
);
ForwardIterator
last_new
=
first_new
;
RAI
last_new
(
first_new
);
if
(
index
>=
chunks_
-
1
)
{
if
(
index
>=
chunks
-
1
)
{
last_new
=
last_
;
last_new
=
last
;
}
else
{
}
else
{
std
::
advance
(
last_new
,
chunkSize
);
last_new
+=
static_cast
<
difference_type
>
(
chunk_size_
);
}
}
return
ChunkDescriptor
<
RAI
>
(
first_new
,
last_new
);
return
ChunkDescriptor
<
ForwardIterator
>
(
first_new
,
last_new
);
}
}
template
<
typename
ForwardIterator
>
template
<
typename
RAI
>
size_t
ChunkPartitioner
<
ForwardIterator
>::
Size
()
{
size_t
ChunkPartitioner
<
RAI
>::
Size
()
{
return
size
;
return
size
_
;
}
}
template
<
typename
ForwardIterator
>
template
<
typename
RAI
>
ChunkPartitioner
<
ForwardIterator
>::
ChunkPartitioner
(
ForwardIterator
first
,
ChunkPartitioner
<
RAI
>::
ChunkPartitioner
(
ForwardIterator
last
,
size_t
amountChunks
)
:
RAI
first
,
RAI
last
,
size_t
amountChunks
)
:
first
(
first
),
last
(
last
)
{
first_
(
first
),
last_
(
last
)
{
if
(
amountChunks
>
0
)
{
if
(
amountChunks
>
0
)
{
size
=
amountChunks
;
size
_
=
amountChunks
;
}
else
{
}
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
();
embb
::
tasks
::
Node
&
node
=
embb
::
tasks
::
Node
::
GetInstance
();
size
=
node
.
GetWorkerThreadCount
();
size
_
=
node
.
GetWorkerThreadCount
();
}
}
elements_count_
=
static_cast
<
size_t
>
(
std
::
distance
(
first_
,
last_
));
elements_count
=
static_cast
<
size_t
>
(
std
::
distance
(
first
,
last
));
if
(
size_
>
elements_count_
)
{
if
(
size
>
elements_count
)
{
// if we want to make more chunks than we have elements, correct
// if we want to make more chunks than we have elements, correct
// the number of chunks
// the number of chunks
size
=
elements_count
;
size
_
=
elements_count_
;
}
}
standard_chunk_size
=
elements_count
/
size
;
standard_chunk_size
_
=
elements_count_
/
size_
;
bigger_chunk_count
=
elements_count
%
size
;
bigger_chunk_count
_
=
elements_count_
%
size_
;
}
}
template
<
typename
ForwardIterator
>
template
<
typename
RAI
>
const
ChunkDescriptor
<
ForwardIterator
>
const
ChunkDescriptor
<
RAI
>
ChunkPartitioner
<
ForwardIterator
>::
operator
[](
ChunkPartitioner
<
RAI
>::
operator
[](
size_t
const
&
index
)
const
{
size_t
const
&
index
)
const
{
typedef
typename
std
::
iterator_traits
<
ForwardIterator
>::
difference_type
typedef
typename
std
::
iterator_traits
<
RAI
>::
difference_type
difference_type
;
difference_type
;
// Number of element preceding elements in the given chunk
size_t
prec_elements_count
=
0
;
size_t
prec_elements_count
=
0
;
if
(
index
<=
bigger_chunk_count_
)
{
if
(
index
<=
bigger_chunk_count
)
{
prec_elements_count
=
index
*
(
standard_chunk_size_
+
1
);
prec_elements_count
=
index
*
(
standard_chunk_size
+
1
);
}
else
{
}
else
{
prec_elements_count
=
(
standard_chunk_size
+
1
)
*
bigger_chunk_count
prec_elements_count
=
+
standard_chunk_size
*
(
index
-
bigger_chunk_count
);
(
standard_chunk_size_
+
1
)
*
bigger_chunk_count_
+
(
standard_chunk_size_
*
(
index
-
bigger_chunk_count_
));
}
}
size_t
cur_elements_count
=
(
index
<
bigger_chunk_count_
)
size_t
cur_elements_count
=
?
(
standard_chunk_size_
+
1
)
(
index
<
bigger_chunk_count
)
?
:
standard_chunk_size_
;
(
standard_chunk_size
+
1
)
:
standard_chunk_size
;
RAI
first_new
(
first_
);
first_new
+=
static_cast
<
difference_type
>
(
prec_elements_count
);
ForwardIterator
first_new
=
first
;
RAI
last_new
(
first_new
);
std
::
advance
(
first_new
,
prec_elements_count
);
last_new
+=
static_cast
<
difference_type
>
(
cur_elements_count
);
return
ChunkDescriptor
<
RAI
>
(
first_new
,
last_new
);
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
);
}
}
}
// namespace internal
}
// namespace internal
...
...
algorithms_cpp/include/embb/algorithms/internal/partition.h
View file @
9e2febab
...
@@ -38,14 +38,14 @@ namespace internal {
...
@@ -38,14 +38,14 @@ namespace internal {
* Describes a single partition of a 1-dimensional
* Describes a single partition of a 1-dimensional
* partitioning, using first and last iterator.
* 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
{
class
ChunkDescriptor
{
private
:
private
:
ForwardIterator
first
;
RAI
first_
;
ForwardIterator
last
;
RAI
last_
;
public
:
public
:
/**
/**
...
@@ -54,7 +54,7 @@ class ChunkDescriptor {
...
@@ -54,7 +54,7 @@ class ChunkDescriptor {
* \param first The first iterator.
* \param first The first iterator.
* \param last The last iterator
* \param last The last iterator
*/
*/
ChunkDescriptor
(
ForwardIterator
first
,
ForwardIterator
last
);
ChunkDescriptor
(
RAI
first
,
RAI
last
);
/**
/**
* Gets the first iterator.
* Gets the first iterator.
...
@@ -63,7 +63,7 @@ class ChunkDescriptor {
...
@@ -63,7 +63,7 @@ class ChunkDescriptor {
*
*
* \waitfree
* \waitfree
*/
*/
ForwardIterator
GetFirst
()
const
;
RAI
GetFirst
()
const
;
/**
/**
* Gets the last iterator.
* Gets the last iterator.
...
@@ -72,7 +72,7 @@ class ChunkDescriptor {
...
@@ -72,7 +72,7 @@ class ChunkDescriptor {
*
*
* \waitfree
* \waitfree
*/
*/
ForwardIterator
GetLast
()
const
;
RAI
GetLast
()
const
;
};
};
/**
/**
...
@@ -80,9 +80,9 @@ class ChunkDescriptor {
...
@@ -80,9 +80,9 @@ class ChunkDescriptor {
*
*
* Describes the interface for accessing a 1-dimensional partitioning.
* 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
{
class
IPartitioner
{
public
:
public
:
virtual
~
IPartitioner
()
{}
virtual
~
IPartitioner
()
{}
...
@@ -106,7 +106,7 @@ class IPartitioner {
...
@@ -106,7 +106,7 @@ class IPartitioner {
*
*
* \waitfree
* \waitfree
*/
*/
virtual
const
ChunkDescriptor
<
ForwardIterator
>
operator
[](
virtual
const
ChunkDescriptor
<
RAI
>
operator
[](
size_t
const
&
index
)
const
=
0
;
size_t
const
&
index
)
const
=
0
;
};
};
...
@@ -129,16 +129,16 @@ class IPartitioner {
...
@@ -129,16 +129,16 @@ class IPartitioner {
* 2: [6,7,8,9,10]
* 2: [6,7,8,9,10]
* 3: [11,12,13]
* 3: [11,12,13]
*
*
* \tparam
ForwardIterator
Type of the iterator.
* \tparam
RAI
Type of the iterator.
*/
*/
template
<
typename
ForwardIterator
>
template
<
typename
RAI
>
class
BlockSizePartitioner
:
IPartitioner
<
ForwardIterator
>
{
class
BlockSizePartitioner
:
IPartitioner
<
RAI
>
{
private
:
private
:
ForwardIterator
first
;
RAI
first_
;
ForwardIterator
last
;
RAI
last_
;
size_t
chunk
Size
;
size_t
chunk
_size_
;
size_t
elements_count
;
size_t
elements_count
_
;
size_t
chunks
;
size_t
chunks
_
;
public
:
public
:
/**
/**
...
@@ -150,7 +150,7 @@ class BlockSizePartitioner : IPartitioner < ForwardIterator > {
...
@@ -150,7 +150,7 @@ class BlockSizePartitioner : IPartitioner < ForwardIterator > {
* \param chunkSize (Optional) size of the chunk.
* \param chunkSize (Optional) size of the chunk.
*/
*/
BlockSizePartitioner
(
BlockSizePartitioner
(
ForwardIterator
first
,
ForwardIterator
last
,
size_t
chunkSize
=
1
);
RAI
first
,
RAI
last
,
size_t
chunkSize
=
1
);
/**
/**
* See IPartitioner
* See IPartitioner
...
@@ -164,7 +164,7 @@ class BlockSizePartitioner : IPartitioner < ForwardIterator > {
...
@@ -164,7 +164,7 @@ class BlockSizePartitioner : IPartitioner < ForwardIterator > {
*
*
* \waitfree
* \waitfree
*/
*/
virtual
const
ChunkDescriptor
<
ForwardIterator
>
operator
[](
virtual
const
ChunkDescriptor
<
RAI
>
operator
[](
size_t
const
&
index
)
const
;
size_t
const
&
index
)
const
;
};
};
...
@@ -196,17 +196,17 @@ class BlockSizePartitioner : IPartitioner < ForwardIterator > {
...
@@ -196,17 +196,17 @@ class BlockSizePartitioner : IPartitioner < ForwardIterator > {
* 4: [10,11]
* 4: [10,11]
* 5: [12,13]
* 5: [12,13]
*
*
* \tparam
ForwardIterator
Type of the iterator.
* \tparam
RAI
Type of the iterator.
*/
*/
template
<
typename
ForwardIterator
>
template
<
typename
RAI
>
class
ChunkPartitioner
:
IPartitioner
<
ForwardIterator
>
{
class
ChunkPartitioner
:
IPartitioner
<
RAI
>
{
private
:
private
:
size_t
size
;
size_t
size
_
;
size_t
elements_count
;
size_t
elements_count
_
;
ForwardIterator
first
;
RAI
first_
;
ForwardIterator
last
;
RAI
last_
;
size_t
standard_chunk_size
;
size_t
standard_chunk_size
_
;
size_t
bigger_chunk_count
;
size_t
bigger_chunk_count
_
;
public
:
public
:
/**
/**
...
@@ -227,7 +227,7 @@ class ChunkPartitioner : IPartitioner < ForwardIterator > {
...
@@ -227,7 +227,7 @@ class ChunkPartitioner : IPartitioner < ForwardIterator > {
* \param last The last.
* \param last The last.
* \param amountChunks (Optional) the amount chunks.
* \param amountChunks (Optional) the amount chunks.
*/
*/
ChunkPartitioner
(
ForwardIterator
first
,
ForwardIterator
last
,
ChunkPartitioner
(
RAI
first
,
RAI
last
,
size_t
amountChunks
=
0
);
size_t
amountChunks
=
0
);
/**
/**
...
@@ -235,7 +235,7 @@ class ChunkPartitioner : IPartitioner < ForwardIterator > {
...
@@ -235,7 +235,7 @@ class ChunkPartitioner : IPartitioner < ForwardIterator > {
*
*
* \waitfree
* \waitfree
*/
*/
virtual
const
ChunkDescriptor
<
ForwardIterator
>
operator
[](
virtual
const
ChunkDescriptor
<
RAI
>
operator
[](
size_t
const
&
index
)
const
;
size_t
const
&
index
)
const
;
};
};
...
...
algorithms_cpp/test/partitioner_test.cc
View file @
9e2febab
...
@@ -33,9 +33,15 @@
...
@@ -33,9 +33,15 @@
#include <vector>
#include <vector>
#include <list>
#include <list>
PartitionerTest
::
PartitionerTest
()
{
PartitionerTest
::
PartitionerTest
()
CreateUnit
(
"algorithms partitioner test"
).
:
partitioned_array_size_
(
16384
)
{
Add
(
&
PartitionerTest
::
TestBasic
,
this
);
// 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
()
{
void
PartitionerTest
::
TestBasic
()
{
...
@@ -70,3 +76,61 @@ void PartitionerTest::TestBasic() {
...
@@ -70,3 +76,61 @@ void PartitionerTest::TestBasic() {
PT_EXPECT_EQ_MSG
(
partitioner2
.
Size
(),
size_t
(
3
),
"Check count of partitions"
);
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
;
}
}
}
\ No newline at end of file
algorithms_cpp/test/partitioner_test.h
View file @
9e2febab
...
@@ -35,6 +35,13 @@ class PartitionerTest : public partest::TestCase {
...
@@ -35,6 +35,13 @@ class PartitionerTest : public partest::TestCase {
private
:
private
:
void
TestBasic
();
void
TestBasic
();
void
TestLargeRangePre
();
void
TestLargeRangePost
();
void
TestLargeRange
();
int
*
partitioned_array_
;
size_t
partitioned_array_size_
;
};
};
#endif // ALGORITHMS_CPP_TEST_PARTITIONER_TEST_H_
#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