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
41613a67
authored
Mar 31, 2015
by
Christian Kern
Browse files
Options
Browse Files
Download
Plain Diff
Merge remote-tracking branch 'origin/development' into embb445_opencl_plugin_example_fails
parents
78957f33
6276d2c2
Show whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
239 additions
and
127 deletions
+239
-127
CMakeLists.txt
+1
-1
README.md
+14
-11
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
containers_cpp/include/embb/containers/internal/wait_free_spsc_queue-inl.h
+12
-4
containers_cpp/include/embb/containers/wait_free_spsc_queue.h
+9
-3
containers_cpp/test/queue_test-inl.h
+27
-0
mtapi_opencl_c/src/CL/cl_gl_ext.h
+2
-1
No files found.
CMakeLists.txt
View file @
41613a67
...
@@ -28,7 +28,7 @@ cmake_minimum_required (VERSION 2.8.9)
...
@@ -28,7 +28,7 @@ cmake_minimum_required (VERSION 2.8.9)
# Version number
# Version number
set
(
EMBB_BASE_VERSION_MAJOR 0
)
set
(
EMBB_BASE_VERSION_MAJOR 0
)
set
(
EMBB_BASE_VERSION_MINOR 2
)
set
(
EMBB_BASE_VERSION_MINOR 2
)
set
(
EMBB_BASE_VERSION_PATCH
3
)
set
(
EMBB_BASE_VERSION_PATCH
4
)
# Fix compilation for CMake versions >= 3.1
# Fix compilation for CMake versions >= 3.1
#
#
...
...
README.md
View file @
41613a67
...
@@ -92,13 +92,14 @@ contact us: embb-dev@googlegroups.com.
...
@@ -92,13 +92,14 @@ contact us: embb-dev@googlegroups.com.
Directory Structure
Directory Structure
-------------------
-------------------
EMB²
is a technology stack consisting of various building blocks. For some of
EMB²
consists of various building blocks. For some of them, there exist C and
them, there exist C and C++ versions, others are only implemented in C++. Th
e
C++ versions, others are only implemented in C++. The directory names ar
e
directory names are postfixed with either "_cpp" or "_c" for the C++ and C
postfixed with either "_cpp" or "_c" for the C++ and C versions, respectively.
versions, respectively.
Currently, EMB² contains the following components:
Currently, EMB² contains the following components:
-
base: base_c, base_cpp
-
base: base_c, base_cpp
-
mtapi: mtapi_c, mtapi_cpp
-
mtapi: mtapi_c, mtapi_network_c, mtapi_opencl_c, mtapi_cpp
-
tasks: tasks_cpp
-
algorithms: algorithms_cpp
-
algorithms: algorithms_cpp
-
dataflow: dataflow_cpp
-
dataflow: dataflow_cpp
-
containers: containers_cpp
-
containers: containers_cpp
...
@@ -109,12 +110,14 @@ the header files, source files, and unit tests, respectively.
...
@@ -109,12 +110,14 @@ the header files, source files, and unit tests, respectively.
Component base_c contains abstractions for threading, synchronization, atomic
Component base_c contains abstractions for threading, synchronization, atomic
operations, and other functionalities. As the name indicates, the code is
operations, and other functionalities. As the name indicates, the code is
implemented in C. Component base_cpp is mainly a C++ wrapper around the base_c
implemented in C. Component base_cpp is mainly a C++ wrapper around the base_c
functionalities. Component mtapi_c is a task scheduler written in C and
functions. Component mtapi_c is a task scheduler written in C and mtapi_cpp a
mtapi_cpp a C++ wrapper for the scheduler. Component algorithms_cpp provides
C++ wrapper for the scheduler (mtapi_network_c and mtapi_opencl_c are scheduler
high-level constructs for typical parallelization task in C++, and
plugins for distributed and OpenCL-based heterogeneous systems, respectively).
dataflow_cpp generic skeletons for the development of parallel stream-based
To simplify programming of homogeneous systems, tasks_cpp contains abstractions
applications. Finally, component containers_cpp provides containers, i.e.,
to the MTAPI interfaces. Component algorithms_cpp provides high-level constructs
data structures for storing object in an organized and thread-safe way.
for typical parallelization tasks in C++, and dataflow_cpp generic skeletons for
the development of parallel stream-based applications. Finally, containers_cpp
provides data structures for storing objects in a thread-safe way.
Build and Installation
Build and Installation
...
...
algorithms_cpp/include/embb/algorithms/internal/partition-inl.h
View file @
41613a67
...
@@ -31,109 +31,104 @@ namespace embb {
...
@@ -31,109 +31,104 @@ 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
typename
std
::
iterator_traits
<
RAI
>::
difference_type
std
::
advance
(
first_new
,
index
*
chunkSize
)
;
difference_type
;
RAI
first_new
(
first_
);
ForwardIterator
last_new
=
first_new
;
first_new
+=
static_cast
<
difference_type
>
(
chunk_size_
*
index
)
;
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 @
41613a67
...
@@ -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 @
41613a67
...
@@ -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,62 @@ void PartitionerTest::TestBasic() {
...
@@ -70,3 +76,62 @@ 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
;
}
}
}
algorithms_cpp/test/partitioner_test.h
View file @
41613a67
...
@@ -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_
containers_cpp/include/embb/containers/internal/wait_free_spsc_queue-inl.h
View file @
41613a67
...
@@ -37,11 +37,19 @@
...
@@ -37,11 +37,19 @@
namespace
embb
{
namespace
embb
{
namespace
containers
{
namespace
containers
{
template
<
typename
Type
,
class
Allocator
>
template
<
typename
Type
,
class
Allocator
>
WaitFreeSPSCQueue
<
Type
,
Allocator
>::
WaitFreeSPSCQueue
(
size_t
capacity
)
:
size_t
WaitFreeSPSCQueue
<
Type
,
Allocator
>::
capacity
(
capacity
),
AlignCapacityToPowerOfTwo
(
size_t
capacity
)
{
size_t
result
=
1
;
while
(
result
<
capacity
)
result
<<=
1
;
return
result
;
}
template
<
typename
Type
,
class
Allocator
>
WaitFreeSPSCQueue
<
Type
,
Allocator
>::
WaitFreeSPSCQueue
(
size_t
capacity
)
:
capacity
(
AlignCapacityToPowerOfTwo
(
capacity
)),
head_index
(
0
),
head_index
(
0
),
tail_index
(
0
)
{
tail_index
(
0
)
{
queue_array
=
allocator
.
allocate
(
capacity
);
queue_array
=
allocator
.
allocate
(
this
->
capacity
);
}
}
template
<
typename
Type
,
class
Allocator
>
template
<
typename
Type
,
class
Allocator
>
...
@@ -51,7 +59,7 @@ size_t WaitFreeSPSCQueue<Type, Allocator>::GetCapacity() {
...
@@ -51,7 +59,7 @@ size_t WaitFreeSPSCQueue<Type, Allocator>::GetCapacity() {
template
<
typename
Type
,
class
Allocator
>
template
<
typename
Type
,
class
Allocator
>
bool
WaitFreeSPSCQueue
<
Type
,
Allocator
>::
TryEnqueue
(
Type
const
&
element
)
{
bool
WaitFreeSPSCQueue
<
Type
,
Allocator
>::
TryEnqueue
(
Type
const
&
element
)
{
if
(
head_index
-
tail
_index
==
capacity
)
if
(
tail_index
-
head
_index
==
capacity
)
return
false
;
return
false
;
queue_array
[
tail_index
%
capacity
]
=
element
;
queue_array
[
tail_index
%
capacity
]
=
element
;
...
...
containers_cpp/include/embb/containers/wait_free_spsc_queue.h
View file @
41613a67
...
@@ -68,7 +68,7 @@
...
@@ -68,7 +68,7 @@
* <td>\code{.cpp} Queue<Type>(capacity) \endcode</td>
* <td>\code{.cpp} Queue<Type>(capacity) \endcode</td>
* <td>Nothing</td>
* <td>Nothing</td>
* <td>
* <td>
* Constructs a queue with capacity \c capacity that holds elements of
* Constructs a queue with
minimal
capacity \c capacity that holds elements of
* type \c T.
* type \c T.
* </td>
* </td>
* </tr>
* </tr>
...
@@ -145,11 +145,17 @@ class WaitFreeSPSCQueue {
...
@@ -145,11 +145,17 @@ class WaitFreeSPSCQueue {
*/
*/
embb
::
base
::
Atomic
<
size_t
>
tail_index
;
embb
::
base
::
Atomic
<
size_t
>
tail_index
;
/**
* Align capacity to the next smallest power of two
*/
static
size_t
AlignCapacityToPowerOfTwo
(
size_t
capacity
);
public
:
public
:
/**
/**
* Creates a queue with the specified capacity.
* Creates a queue with
at least
the specified capacity.
*
*
* \memory Allocates \c capacity elements of type \c Type.
* \memory Allocates \c 2^k elements of type \c Type, where \k is the
* smallest number such that <tt>capacity <= 2^k</tt> holds.
*
*
* \notthreadsafe
* \notthreadsafe
*
*
...
...
containers_cpp/test/queue_test-inl.h
View file @
41613a67
...
@@ -276,16 +276,43 @@ QueueTestSingleProducerSingleConsumer_ThreadMethod() {
...
@@ -276,16 +276,43 @@ QueueTestSingleProducerSingleConsumer_ThreadMethod() {
template
<
typename
Queue_t
,
bool
MultipleProducers
,
bool
MultipleConsumers
>
template
<
typename
Queue_t
,
bool
MultipleProducers
,
bool
MultipleConsumers
>
void
QueueTest
<
Queue_t
,
MultipleProducers
,
MultipleConsumers
>::
void
QueueTest
<
Queue_t
,
MultipleProducers
,
MultipleConsumers
>::
QueueTestSingleThreadEnqueueDequeue_ThreadMethod
()
{
QueueTestSingleThreadEnqueueDequeue_ThreadMethod
()
{
// Enqueue the expected amount of elements
for
(
int
i
=
0
;
i
!=
n_queue_size
;
++
i
)
{
for
(
int
i
=
0
;
i
!=
n_queue_size
;
++
i
)
{
bool
success
=
queue
->
TryEnqueue
(
element_t
(
0
,
i
*
133
));
bool
success
=
queue
->
TryEnqueue
(
element_t
(
0
,
i
*
133
));
PT_ASSERT
(
success
==
true
);
PT_ASSERT
(
success
==
true
);
}
}
// Some queues may allow enqueueing more elements than their capacity
// permits, so try to enqueue additional elements until the queue is full
int
oversized_count
=
n_queue_size
;
while
(
queue
->
TryEnqueue
(
element_t
(
0
,
oversized_count
*
133
))
)
{
++
oversized_count
;
}
// Oversized amount should not be larger than the original capacity
PT_ASSERT_LT
(
oversized_count
,
2
*
n_queue_size
);
// Dequeue the expected amount of elements
for
(
int
i
=
0
;
i
!=
n_queue_size
;
++
i
)
{
for
(
int
i
=
0
;
i
!=
n_queue_size
;
++
i
)
{
element_t
dequ
(
0
,
-
1
);
element_t
dequ
(
0
,
-
1
);
bool
success
=
queue
->
TryDequeue
(
dequ
);
bool
success
=
queue
->
TryDequeue
(
dequ
);
PT_ASSERT
(
success
==
true
);
PT_ASSERT
(
success
==
true
);
PT_ASSERT
(
dequ
.
second
==
i
*
133
);
PT_ASSERT
(
dequ
.
second
==
i
*
133
);
}
}
// Dequeue any elements enqueued above the original capacity
for
(
int
i
=
n_queue_size
;
i
!=
oversized_count
;
++
i
)
{
element_t
dequ
(
0
,
-
1
);
bool
success
=
queue
->
TryDequeue
(
dequ
);
PT_ASSERT
(
success
==
true
);
PT_ASSERT
(
dequ
.
second
==
i
*
133
);
}
// Ensure the queue is now empty
{
element_t
dequ
;
bool
success
=
queue
->
TryDequeue
(
dequ
);
PT_ASSERT
(
success
==
false
);
}
}
}
template
<
typename
Queue_t
,
bool
MultipleProducers
,
bool
MultipleConsumers
>
template
<
typename
Queue_t
,
bool
MultipleProducers
,
bool
MultipleConsumers
>
...
...
mtapi_opencl_c/src/CL/cl_gl_ext.h
View file @
41613a67
...
@@ -41,7 +41,8 @@ extern "C" {
...
@@ -41,7 +41,8 @@ extern "C" {
/*
/*
* For each extension, follow this template
* For each extension, follow this template
* /* cl_VEN_extname extension */
* // cl_VEN_extname extension
*/
/* #define cl_VEN_extname 1
/* #define cl_VEN_extname 1
* ... define new types, if any
* ... define new types, if any
* ... define new tokens, if any
* ... define new tokens, if any
...
...
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