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
ffa2f18a
authored
Mar 02, 2015
by
Christian Kern
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'development' into embb9_tarball_script
parents
938c3be8
ad71c970
Hide whitespace changes
Inline
Side-by-side
Showing
48 changed files
with
656 additions
and
353 deletions
+656
-353
algorithms_cpp/include/embb/algorithms/internal/count-inl.h
+16
-13
algorithms_cpp/include/embb/algorithms/internal/for_each-inl.h
+55
-33
algorithms_cpp/include/embb/algorithms/internal/merge_sort-inl.h
+151
-64
algorithms_cpp/include/embb/algorithms/internal/partition-inl.h
+3
-3
algorithms_cpp/include/embb/algorithms/internal/quick_sort-inl.h
+29
-9
algorithms_cpp/include/embb/algorithms/internal/reduce-inl.h
+77
-44
algorithms_cpp/include/embb/algorithms/internal/scan-inl.h
+77
-58
algorithms_cpp/include/embb/algorithms/invoke.h
+2
-2
algorithms_cpp/include/embb/algorithms/merge_sort.h
+13
-2
algorithms_cpp/include/embb/algorithms/reduce.h
+3
-3
algorithms_cpp/include/embb/algorithms/scan.h
+3
-3
algorithms_cpp/test/count_test.cc
+2
-4
algorithms_cpp/test/for_each_test.cc
+24
-5
algorithms_cpp/test/merge_sort_test.cc
+48
-29
algorithms_cpp/test/merge_sort_test.h
+1
-1
algorithms_cpp/test/quick_sort_test.cc
+25
-6
algorithms_cpp/test/reduce_test.cc
+25
-2
algorithms_cpp/test/scan_test.cc
+28
-8
base_c/include/embb/base/c/internal/platform.h
+1
-1
base_c/test/alloc_test.h
+1
-1
base_c/test/condition_var_test.h
+1
-1
base_c/test/core_set_test.h
+1
-1
base_c/test/counter_test.h
+1
-1
base_c/test/duration_test.h
+1
-1
base_c/test/thread_index_test.h
+1
-1
base_c/test/thread_specific_storage_test.h
+1
-1
base_c/test/thread_test.h
+1
-1
base_c/test/time_test.h
+1
-1
base_cpp/include/embb/base/core_set.h
+1
-1
base_cpp/include/embb/base/duration.h
+1
-1
base_cpp/include/embb/base/exceptions.h
+1
-11
base_cpp/include/embb/base/internal/duration-inl.h
+1
-1
base_cpp/include/embb/base/internal/mutex-inl.h
+1
-1
base_cpp/include/embb/base/internal/thread-inl.h
+1
-1
base_cpp/include/embb/base/internal/thread_closures.h
+7
-7
base_cpp/include/embb/base/internal/thread_specific_storage-inl.h
+1
-1
base_cpp/include/embb/base/thread.h
+8
-8
base_cpp/include/embb/base/thread_specific_storage.h
+3
-5
base_cpp/include/embb/base/time.h
+1
-1
base_cpp/test/thread_test.h
+1
-2
dataflow_cpp/include/embb/dataflow/internal/inputs.h
+5
-5
mtapi_c/include/embb/mtapi/c/mtapi.h
+1
-1
mtapi_cpp/include/embb/mtapi/action.h
+8
-8
mtapi_cpp/include/embb/mtapi/execution_policy.h
+7
-0
mtapi_cpp/include/embb/mtapi/node.h
+10
-0
mtapi_cpp/src/execution_policy.cc
+5
-0
mtapi_cpp/src/node.cc
+1
-0
partest.tar
+0
-0
No files found.
algorithms_cpp/include/embb/algorithms/internal/count-inl.h
View file @
ffa2f18a
...
@@ -37,42 +37,45 @@ namespace internal {
...
@@ -37,42 +37,45 @@ namespace internal {
template
<
typename
ValueType
>
template
<
typename
ValueType
>
class
ValueComparisonFunction
{
class
ValueComparisonFunction
{
public
:
public
:
explicit
ValueComparisonFunction
(
const
ValueType
&
value
)
explicit
ValueComparisonFunction
(
const
ValueType
&
value
)
:
value_
(
value
)
{}
:
value_
(
value
)
{}
ValueComparisonFunction
(
const
ValueComparisonFunction
&
other
)
ValueComparisonFunction
(
const
ValueComparisonFunction
&
other
)
:
value_
(
other
.
value_
)
{}
:
value_
(
other
.
value_
)
{}
template
<
typename
ElementType
>
template
<
typename
ElementType
>
int
operator
()(
ElementType
element
)
{
int
operator
()(
ElementType
element
)
{
if
(
element
==
value_
)
if
(
element
==
value_
)
{
return
1
;
return
1
;
else
}
else
{
return
0
;
return
0
;
}
}
}
private
:
private
:
const
ValueType
&
value_
;
const
ValueType
&
value_
;
ValueComparisonFunction
&
operator
=
(
const
ValueComparisonFunction
&
other
);
ValueComparisonFunction
&
operator
=
(
const
ValueComparisonFunction
&
other
);
};
};
template
<
typename
Function
>
template
<
typename
Function
>
class
FunctionComparisonFunction
{
class
FunctionComparisonFunction
{
public
:
public
:
explicit
FunctionComparisonFunction
(
Function
function
)
explicit
FunctionComparisonFunction
(
Function
function
)
:
function_
(
function
)
{}
:
function_
(
function
)
{}
FunctionComparisonFunction
(
const
FunctionComparisonFunction
&
other
)
FunctionComparisonFunction
(
const
FunctionComparisonFunction
&
other
)
:
function_
(
other
.
function_
)
{}
:
function_
(
other
.
function_
)
{}
template
<
typename
ElementType
>
template
<
typename
ElementType
>
int
operator
()(
ElementType
element
)
{
int
operator
()(
ElementType
element
)
{
if
(
function_
(
element
))
if
(
function_
(
element
))
{
return
1
;
return
1
;
else
}
else
{
return
0
;
return
0
;
}
}
}
private
:
private
:
Function
function_
;
Function
function_
;
FunctionComparisonFunction
&
operator
=
(
const
FunctionComparisonFunction
&
FunctionComparisonFunction
&
operator
=
(
other
);
const
FunctionComparisonFunction
&
other
);
};
};
}
// namespace internal
}
// namespace internal
...
...
algorithms_cpp/include/embb/algorithms/internal/for_each-inl.h
View file @
ffa2f18a
...
@@ -45,44 +45,54 @@ class ForEachFunctor {
...
@@ -45,44 +45,54 @@ class ForEachFunctor {
/**
/**
* Constructs a for-each functor with arguments.
* Constructs a for-each functor with arguments.
*/
*/
ForEachFunctor
(
RAI
first
,
RAI
last
,
Function
unary
,
ForEachFunctor
(
size_t
chunk_first
,
size_t
chunk_last
,
Function
unary
,
const
embb
::
mtapi
::
ExecutionPolicy
&
policy
,
size_t
block_size
)
const
embb
::
mtapi
::
ExecutionPolicy
&
policy
,
:
first_
(
first
),
last_
(
last
),
unary_
(
unary
),
policy_
(
policy
),
const
BlockSizePartitioner
<
RAI
>&
partitioner
)
block_size_
(
block_size
)
{
:
chunk_first_
(
chunk_first
),
chunk_last_
(
chunk_last
),
unary_
(
unary
),
policy_
(
policy
),
partitioner_
(
partitioner
)
{
}
}
void
Action
(
mtapi
::
TaskContext
&
)
{
void
Action
(
mtapi
::
TaskContext
&
)
{
size_t
distance
=
static_cast
<
size_t
>
(
std
::
distance
(
first_
,
last_
));
if
(
chunk_first_
==
chunk_last_
)
{
if
(
distance
==
0
)
return
;
// Leaf case, recursed to single chunk. Do work on chunk:
if
(
distance
<=
block_size_
)
{
// leaf case -> do work
ChunkDescriptor
<
RAI
>
chunk
=
partitioner_
[
chunk_first_
];
for
(
RAI
curIter
(
first_
);
curIter
!=
last_
;
++
curIter
)
{
RAI
first
=
chunk
.
GetFirst
();
unary_
(
*
curIter
);
RAI
last
=
chunk
.
GetLast
();
for
(
RAI
it
=
first
;
it
!=
last
;
++
it
)
{
unary_
(
*
it
);
}
}
}
else
{
// recurse further
}
else
{
ChunkPartitioner
<
RAI
>
partitioner
(
first_
,
last_
,
2
);
// Recurse further:
ForEachFunctor
<
RAI
,
Function
>
functorL
(
partitioner
[
0
].
GetFirst
(),
size_t
chunk_split_index
=
(
chunk_first_
+
chunk_last_
)
/
2
;
partitioner
[
0
].
GetLast
(),
unary_
,
policy_
,
block_size_
);
// Split chunks into left / right branches:
ForEachFunctor
<
RAI
,
Function
>
functorR
(
partitioner
[
1
].
GetFirst
(),
self_t
functor_l
(
chunk_first_
,
partitioner
[
1
].
GetLast
(),
unary_
,
policy_
,
block_size_
);
chunk_split_index
,
unary_
,
policy_
,
partitioner_
);
mtapi
::
Node
&
node
=
mtapi
::
Node
::
GetInstance
();
self_t
functor_r
(
chunk_split_index
+
1
,
mtapi
::
Task
taskL
=
node
.
Spawn
(
mtapi
::
Action
(
base
::
MakeFunction
(
chunk_last_
,
functorL
,
&
ForEachFunctor
<
RAI
,
Function
>::
Action
),
unary_
,
policy_
,
partitioner_
);
mtapi
::
Task
task_l
=
mtapi
::
Node
::
GetInstance
().
Spawn
(
mtapi
::
Action
(
base
::
MakeFunction
(
functor_l
,
&
self_t
::
Action
),
policy_
));
policy_
));
mtapi
::
Task
taskR
=
node
.
Spawn
(
mtapi
::
Action
(
base
::
MakeFunction
(
mtapi
::
Task
task_r
=
mtapi
::
Node
::
GetInstance
().
Spawn
(
functorR
,
&
ForEachFunctor
<
RAI
,
Function
>::
Action
),
mtapi
::
Action
(
base
::
MakeFunction
(
functor_r
,
&
self_t
::
Action
),
policy_
));
policy_
));
task
L
.
Wait
(
MTAPI_INFINITE
);
task
_l
.
Wait
(
MTAPI_INFINITE
);
task
R
.
Wait
(
MTAPI_INFINITE
);
task
_r
.
Wait
(
MTAPI_INFINITE
);
}
}
}
}
private
:
private
:
RAI
first_
;
typedef
ForEachFunctor
<
RAI
,
Function
>
self_t
;
RAI
last_
;
private
:
size_t
chunk_first_
;
size_t
chunk_last_
;
Function
unary_
;
Function
unary_
;
const
embb
::
mtapi
::
ExecutionPolicy
&
policy_
;
const
embb
::
mtapi
::
ExecutionPolicy
&
policy_
;
size_t
block_size
_
;
const
BlockSizePartitioner
<
RAI
>&
partitioner
_
;
/**
/**
* Disables assignment.
* Disables assignment.
...
@@ -95,21 +105,33 @@ void ForEachRecursive(RAI first, RAI last, Function unary,
...
@@ -95,21 +105,33 @@ void ForEachRecursive(RAI first, RAI last, Function unary,
const
embb
::
mtapi
::
ExecutionPolicy
&
policy
,
size_t
block_size
)
{
const
embb
::
mtapi
::
ExecutionPolicy
&
policy
,
size_t
block_size
)
{
typedef
typename
std
::
iterator_traits
<
RAI
>::
difference_type
difference_type
;
typedef
typename
std
::
iterator_traits
<
RAI
>::
difference_type
difference_type
;
difference_type
distance
=
std
::
distance
(
first
,
last
);
difference_type
distance
=
std
::
distance
(
first
,
last
);
assert
(
distance
>
0
);
if
(
distance
==
0
)
{
return
;
}
else
if
(
distance
<
0
)
{
EMBB_THROW
(
embb
::
base
::
ErrorException
,
"Negative range for ForEach"
);
}
unsigned
int
num_cores
=
policy
.
GetCoreCount
();
if
(
num_cores
==
0
)
{
EMBB_THROW
(
embb
::
base
::
ErrorException
,
"No cores in execution policy"
);
}
mtapi
::
Node
&
node
=
mtapi
::
Node
::
GetInstance
();
mtapi
::
Node
&
node
=
mtapi
::
Node
::
GetInstance
();
// Determine actually used block size
// Determine actually used block size
if
(
block_size
==
0
)
{
if
(
block_size
==
0
)
{
block_size
=
(
static_cast
<
size_t
>
(
distance
)
/
n
ode
.
GetCoreCount
()
);
block_size
=
(
static_cast
<
size_t
>
(
distance
)
/
n
um_cores
);
if
(
block_size
==
0
)
{
if
(
block_size
==
0
)
{
block_size
=
1
;
block_size
=
1
;
}
}
}
}
//
Perform check of
task number sufficiency
//
Check
task number sufficiency
if
(((
distance
/
block_size
)
*
2
)
+
1
>
MTAPI_NODE_MAX_TASKS_DEFAULT
)
{
if
(((
distance
/
block_size
)
*
2
)
+
1
>
MTAPI_NODE_MAX_TASKS_DEFAULT
)
{
EMBB_THROW
(
embb
::
base
::
ErrorException
,
"Not enough MTAPI tasks available "
EMBB_THROW
(
embb
::
base
::
ErrorException
,
"
to perform the parallel foreach loop
"
);
"
Not enough MTAPI tasks available for parallel foreach
"
);
}
}
ForEachFunctor
<
RAI
,
Function
>
functor
(
first
,
last
,
unary
,
policy
,
block_size
);
BlockSizePartitioner
<
RAI
>
partitioner
(
first
,
last
,
block_size
);
ForEachFunctor
<
RAI
,
Function
>
functor
(
0
,
partitioner
.
Size
()
-
1
,
unary
,
policy
,
partitioner
);
mtapi
::
Task
task
=
node
.
Spawn
(
mtapi
::
Action
(
mtapi
::
Task
task
=
node
.
Spawn
(
mtapi
::
Action
(
base
::
MakeFunction
(
functor
,
base
::
MakeFunction
(
functor
,
&
ForEachFunctor
<
RAI
,
Function
>::
Action
),
&
ForEachFunctor
<
RAI
,
Function
>::
Action
),
...
@@ -127,7 +149,7 @@ void ForEachIteratorCheck(RAI first, RAI last, Function unary,
...
@@ -127,7 +149,7 @@ void ForEachIteratorCheck(RAI first, RAI last, Function unary,
}
// namespace internal
}
// namespace internal
template
<
typename
RAI
,
typename
Function
>
template
<
typename
RAI
,
typename
Function
>
void
ForEach
(
RAI
first
,
RAI
last
,
Function
unary
,
void
ForEach
(
RAI
first
,
const
RAI
last
,
Function
unary
,
const
embb
::
mtapi
::
ExecutionPolicy
&
policy
,
size_t
block_size
)
{
const
embb
::
mtapi
::
ExecutionPolicy
&
policy
,
size_t
block_size
)
{
typename
std
::
iterator_traits
<
RAI
>::
iterator_category
category
;
typename
std
::
iterator_traits
<
RAI
>::
iterator_category
category
;
internal
::
ForEachIteratorCheck
(
first
,
last
,
unary
,
policy
,
block_size
,
internal
::
ForEachIteratorCheck
(
first
,
last
,
unary
,
policy
,
block_size
,
...
...
algorithms_cpp/include/embb/algorithms/internal/merge_sort-inl.h
View file @
ffa2f18a
...
@@ -48,58 +48,112 @@ class MergeSortFunctor {
...
@@ -48,58 +48,112 @@ class MergeSortFunctor {
public
:
public
:
typedef
typename
std
::
iterator_traits
<
RAI
>::
value_type
value_type
;
typedef
typename
std
::
iterator_traits
<
RAI
>::
value_type
value_type
;
MergeSortFunctor
(
RAI
first
,
RAI
last
,
RAITemp
temporary_first
,
MergeSortFunctor
(
size_t
chunk_first
,
size_t
chunk_last
,
ComparisonFunction
comparison
,
const
embb
::
mtapi
::
ExecutionPolicy
&
policy
,
RAITemp
temporary_first
,
ComparisonFunction
comparison
,
size_t
block_size
,
const
RAI
&
global_first
,
int
depth
)
const
embb
::
mtapi
::
ExecutionPolicy
&
policy
,
:
first_
(
first
),
last_
(
last
),
temp_first_
(
temporary_first
),
const
BlockSizePartitioner
<
RAI
>&
partitioner
,
comparison_
(
comparison
),
policy_
(
policy
),
block_size_
(
block_size
),
const
RAI
&
global_first
,
int
depth
)
global_first_
(
global_first
),
depth_
(
depth
)
{
:
chunk_first_
(
chunk_first
),
chunk_last_
(
chunk_last
),
temp_first_
(
temporary_first
),
comparison_
(
comparison
),
policy_
(
policy
),
partitioner_
(
partitioner
),
global_first_
(
global_first
),
depth_
(
depth
)
{
}
}
void
Action
(
mtapi
::
TaskContext
&
context
)
{
void
Action
(
mtapi
::
TaskContext
&
)
{
typedef
typename
std
::
iterator_traits
<
RAI
>::
difference_type
difference_type
;
size_t
chunk_split_index
=
(
chunk_first_
+
chunk_last_
)
/
2
;
size_t
distance
=
static_cast
<
size_t
>
(
std
::
distance
(
first_
,
last_
));
if
(
chunk_first_
==
chunk_last_
)
{
if
(
distance
<=
1
)
{
// Leaf case: recurse into a single chunk's elements:
if
(
!
CloneBackToInput
()
&&
distance
!=
0
)
{
ChunkDescriptor
<
RAI
>
chunk
=
partitioner_
[
chunk_first_
];
RAITemp
temp_first
=
temp_first_
;
MergeSortChunk
(
chunk
.
GetFirst
(),
chunk
.
GetLast
(),
depth_
);
temp_first
+=
std
::
distance
(
global_first_
,
first_
);
*
temp_first
=
*
first_
;
}
return
;
}
internal
::
ChunkPartitioner
<
RAI
>
partitioner
(
first_
,
last_
,
2
);
MergeSortFunctor
<
RAI
,
RAITemp
,
ComparisonFunction
>
functorL
(
partitioner
[
0
].
GetFirst
(),
partitioner
[
0
].
GetLast
(),
temp_first_
,
comparison_
,
policy_
,
block_size_
,
global_first_
,
depth_
+
1
);
MergeSortFunctor
<
RAI
,
RAITemp
,
ComparisonFunction
>
functorR
(
partitioner
[
1
].
GetFirst
(),
partitioner
[
1
].
GetLast
(),
temp_first_
,
comparison_
,
policy_
,
block_size_
,
global_first_
,
depth_
+
1
);
if
(
distance
<=
block_size_
)
{
functorL
.
Action
(
context
);
functorR
.
Action
(
context
);
}
else
{
}
else
{
// Recurse further, split chunks:
self_t
functor_l
(
chunk_first_
,
chunk_split_index
,
temp_first_
,
comparison_
,
policy_
,
partitioner_
,
global_first_
,
depth_
+
1
);
self_t
functor_r
(
chunk_split_index
+
1
,
chunk_last_
,
temp_first_
,
comparison_
,
policy_
,
partitioner_
,
global_first_
,
depth_
+
1
);
mtapi
::
Node
&
node
=
mtapi
::
Node
::
GetInstance
();
mtapi
::
Node
&
node
=
mtapi
::
Node
::
GetInstance
();
mtapi
::
Task
taskL
=
node
.
Spawn
(
mtapi
::
Action
(
base
::
MakeFunction
(
functorL
,
mtapi
::
Task
task_l
=
node
.
Spawn
(
&
MergeSortFunctor
<
RAI
,
RAITemp
,
ComparisonFunction
>::
Action
),
mtapi
::
Action
(
base
::
MakeFunction
(
functor_l
,
&
self_t
::
Action
),
policy_
));
policy_
));
mtapi
::
Task
taskR
=
node
.
Spawn
(
mtapi
::
Action
(
base
::
MakeFunction
(
functorR
,
mtapi
::
Task
task_r
=
node
.
Spawn
(
&
MergeSortFunctor
<
RAI
,
RAITemp
,
ComparisonFunction
>::
Action
),
mtapi
::
Action
(
base
::
MakeFunction
(
functor_r
,
&
self_t
::
Action
),
policy_
));
policy_
));
taskL
.
Wait
(
MTAPI_INFINITE
);
task_l
.
Wait
(
MTAPI_INFINITE
);
taskR
.
Wait
(
MTAPI_INFINITE
);
task_r
.
Wait
(
MTAPI_INFINITE
);
ChunkDescriptor
<
RAI
>
ck_f
=
partitioner_
[
chunk_first_
];
ChunkDescriptor
<
RAI
>
ck_m
=
partitioner_
[
chunk_split_index
+
1
];
ChunkDescriptor
<
RAI
>
ck_l
=
partitioner_
[
chunk_last_
];
if
(
CloneBackToInput
(
depth_
))
{
// Merge from temp into input:
difference_type
first
=
std
::
distance
(
global_first_
,
ck_f
.
GetFirst
());
difference_type
mid
=
std
::
distance
(
global_first_
,
ck_m
.
GetFirst
());
difference_type
last
=
std
::
distance
(
global_first_
,
ck_l
.
GetLast
());
SerialMerge
(
temp_first_
+
first
,
temp_first_
+
mid
,
temp_first_
+
last
,
ck_f
.
GetFirst
(),
comparison_
);
}
else
{
// Merge from input into temp:
SerialMerge
(
ck_f
.
GetFirst
(),
ck_m
.
GetFirst
(),
ck_l
.
GetLast
(),
temp_first_
+
std
::
distance
(
global_first_
,
ck_f
.
GetFirst
()),
comparison_
);
}
}
}
}
if
(
CloneBackToInput
())
{
/**
difference_type
first
=
std
::
distance
(
global_first_
,
functorL
.
first_
);
* Serial merge sort of elements within a single chunk.
difference_type
mid
=
std
::
distance
(
global_first_
,
functorR
.
first_
);
*/
difference_type
last
=
std
::
distance
(
global_first_
,
functorR
.
last_
);
void
MergeSortChunk
(
RAI
first
,
SerialMerge
(
temp_first_
+
first
,
temp_first_
+
mid
,
RAI
last
,
temp_first_
+
last
,
functorL
.
first_
,
comparison_
);
int
depth
)
{
size_t
distance
=
static_cast
<
size_t
>
(
std
::
distance
(
first
,
last
));
if
(
distance
<=
1
)
{
// Leaf case:
if
(
!
CloneBackToInput
(
depth
)
&&
distance
!=
0
)
{
RAITemp
temp_first
=
temp_first_
;
std
::
advance
(
temp_first
,
std
::
distance
(
global_first_
,
first
));
*
temp_first
=
*
first
;
}
return
;
}
// Recurse further. Use binary split, ignoring chunk size as this
// recursion is serial and has leaf size 1:
ChunkPartitioner
<
RAI
>
partitioner
(
first
,
last
,
2
);
ChunkDescriptor
<
RAI
>
ck_l
=
partitioner
[
0
];
ChunkDescriptor
<
RAI
>
ck_r
=
partitioner
[
1
];
MergeSortChunk
(
ck_l
.
GetFirst
(),
ck_l
.
GetLast
(),
depth
+
1
);
MergeSortChunk
(
ck_r
.
GetFirst
(),
ck_r
.
GetLast
(),
depth
+
1
);
if
(
CloneBackToInput
(
depth
))
{
// Merge from temp into input:
difference_type
d_first
=
std
::
distance
(
global_first_
,
ck_l
.
GetFirst
());
difference_type
d_mid
=
std
::
distance
(
global_first_
,
ck_r
.
GetFirst
());
difference_type
d_last
=
std
::
distance
(
global_first_
,
ck_r
.
GetLast
());
SerialMerge
(
temp_first_
+
d_first
,
temp_first_
+
d_mid
,
temp_first_
+
d_last
,
ck_l
.
GetFirst
(),
comparison_
);
}
else
{
}
else
{
SerialMerge
(
functorL
.
first_
,
functorR
.
first_
,
functorR
.
last_
,
// Merge from input into temp:
temp_first_
+
std
::
distance
(
global_first_
,
functorL
.
first_
),
SerialMerge
(
comparison_
);
ck_l
.
GetFirst
(),
ck_r
.
GetFirst
(),
ck_r
.
GetLast
(),
temp_first_
+
std
::
distance
(
global_first_
,
ck_l
.
GetFirst
()),
comparison_
);
}
}
}
}
...
@@ -109,17 +163,22 @@ class MergeSortFunctor {
...
@@ -109,17 +163,22 @@ class MergeSortFunctor {
* \return \c true if the temporary data range is input and the array to be
* \return \c true if the temporary data range is input and the array to be
* sorted is output. \c false, if the other way around.
* sorted is output. \c false, if the other way around.
*/
*/
bool
CloneBackToInput
()
{
bool
CloneBackToInput
(
int
depth
)
{
return
depth
_
%
2
==
0
?
true
:
false
;
return
depth
%
2
==
0
?
true
:
false
;
}
}
private
:
private
:
RAI
first_
;
typedef
MergeSortFunctor
<
RAI
,
RAITemp
,
ComparisonFunction
>
self_t
;
RAI
last_
;
typedef
typename
std
::
iterator_traits
<
RAI
>::
difference_type
difference_type
;
private
:
size_t
chunk_first_
;
size_t
chunk_last_
;
RAITemp
temp_first_
;
RAITemp
temp_first_
;
ComparisonFunction
comparison_
;
ComparisonFunction
comparison_
;
const
embb
::
mtapi
::
ExecutionPolicy
&
policy_
;
const
embb
::
mtapi
::
ExecutionPolicy
&
policy_
;
size_t
block_size
_
;
const
BlockSizePartitioner
<
RAI
>&
partitioner
_
;
const
RAI
&
global_first_
;
const
RAI
&
global_first_
;
int
depth_
;
int
depth_
;
...
@@ -154,41 +213,69 @@ class MergeSortFunctor {
...
@@ -154,41 +213,69 @@ class MergeSortFunctor {
}
}
};
};
}
// namespace internal
template
<
typename
RAI
,
typename
RAITemp
,
typename
ComparisonFunction
>
template
<
typename
RAI
,
typename
RAITemp
,
typename
ComparisonFunction
>
void
MergeSort
(
void
MergeSort
IteratorCheck
(
RAI
first
,
RAI
first
,
RAI
last
,
RAI
last
,
RAITemp
temporary_first
,
RAITemp
temporary_first
,
ComparisonFunction
comparison
,
ComparisonFunction
comparison
,
const
embb
::
mtapi
::
ExecutionPolicy
&
policy
,
const
embb
::
mtapi
::
ExecutionPolicy
&
policy
,
size_t
block_size
size_t
block_size
,
std
::
random_access_iterator_tag
)
{
)
{
typedef
typename
std
::
iterator_traits
<
RAI
>::
difference_type
difference_type
;
typedef
typename
std
::
iterator_traits
<
RAI
>::
difference_type
difference_type
;
embb
::
mtapi
::
Node
&
node
=
embb
::
mtapi
::
Node
::
GetInstance
();
typedef
MergeSortFunctor
<
RAI
,
RAITemp
,
ComparisonFunction
>
difference_type
distance
=
last
-
first
;
functor_t
;
assert
(
distance
>=
0
);
difference_type
distance
=
std
::
distance
(
first
,
last
);
if
(
distance
==
0
)
{
return
;
}
else
if
(
distance
<
0
)
{
EMBB_THROW
(
embb
::
base
::
ErrorException
,
"Negative range for MergeSort"
);
}
unsigned
int
num_cores
=
policy
.
GetCoreCount
();
if
(
num_cores
==
0
)
{
EMBB_THROW
(
embb
::
base
::
ErrorException
,
"No cores in execution policy"
);
}
// Determine actually used block size
if
(
block_size
==
0
)
{
if
(
block_size
==
0
)
{
block_size
=
(
static_cast
<
size_t
>
(
distance
)
/
n
ode
.
GetCoreCount
()
);
block_size
=
(
static_cast
<
size_t
>
(
distance
)
/
n
um_cores
);
if
(
block_size
==
0
)
if
(
block_size
==
0
)
block_size
=
1
;
block_size
=
1
;
}
}
if
(((
distance
/
block_size
)
*
2
)
+
1
>
MTAPI_NODE_MAX_TASKS_DEFAULT
)
{
// Check task number sufficiency
if
(((
distance
/
block_size
)
*
2
)
+
1
>
MTAPI_NODE_MAX_TASKS_DEFAULT
)
{
EMBB_THROW
(
embb
::
base
::
ErrorException
,
EMBB_THROW
(
embb
::
base
::
ErrorException
,
"Not enough MTAPI tasks available to perform
the
merge sort"
);
"Not enough MTAPI tasks available to perform merge sort"
);
}
}
internal
::
MergeSortFunctor
<
RAI
,
RAITemp
,
ComparisonFunction
>
functor
(
BlockSizePartitioner
<
RAI
>
partitioner
(
first
,
last
,
block_size
);
first
,
last
,
temporary_first
,
comparison
,
policy
,
block_size
,
first
,
0
);
functor_t
functor
(
0
,
mtapi
::
Task
task
=
node
.
Spawn
(
mtapi
::
Action
(
base
::
MakeFunction
(
functor
,
partitioner
.
Size
()
-
1
,
&
internal
::
MergeSortFunctor
<
RAI
,
RAITemp
,
ComparisonFunction
>::
Action
),
temporary_first
,
policy
));
comparison
,
policy
,
partitioner
,
first
,
0
);
mtapi
::
Task
task
=
embb
::
mtapi
::
Node
::
GetInstance
().
Spawn
(
mtapi
::
Action
(
base
::
MakeFunction
(
functor
,
&
functor_t
::
Action
),
policy
));
task
.
Wait
(
MTAPI_INFINITE
);
task
.
Wait
(
MTAPI_INFINITE
);
}
}
}
// namespace internal
template
<
typename
RAI
,
typename
RAITemp
,
typename
ComparisonFunction
>
void
MergeSort
(
RAI
first
,
RAI
last
,
RAITemp
temporary_first
,
ComparisonFunction
comparison
,
const
embb
::
mtapi
::
ExecutionPolicy
&
policy
,
size_t
block_size
)
{
typedef
typename
std
::
iterator_traits
<
RAI
>::
iterator_category
category
;
internal
::
MergeSortIteratorCheck
(
first
,
last
,
temporary_first
,
comparison
,
policy
,
block_size
,
category
());
}
}
// namespace algorithms
}
// namespace algorithms
}
// namespace embb
}
// namespace embb
...
...
algorithms_cpp/include/embb/algorithms/internal/partition-inl.h
View file @
ffa2f18a
...
@@ -71,8 +71,8 @@ const ChunkDescriptor<ForwardIterator>
...
@@ -71,8 +71,8 @@ const ChunkDescriptor<ForwardIterator>
ForwardIterator
last_new
=
first_new
;
ForwardIterator
last_new
=
first_new
;
if
(
index
==
elements_count
/
chunkSize
)
{
if
(
index
>=
chunks
-
1
)
{
std
::
advance
(
last_new
,
elements_count
%
chunkSize
)
;
last_new
=
last
;
}
else
{
}
else
{
std
::
advance
(
last_new
,
chunkSize
);
std
::
advance
(
last_new
,
chunkSize
);
}
}
...
@@ -94,7 +94,7 @@ ChunkPartitioner<ForwardIterator>::ChunkPartitioner(ForwardIterator first,
...
@@ -94,7 +94,7 @@ ChunkPartitioner<ForwardIterator>::ChunkPartitioner(ForwardIterator first,
}
else
{
}
else
{
// if no concrete chunk size was given, use number of cores...
// if no concrete chunk size was given, use number of cores...
mtapi
::
Node
&
node
=
mtapi
::
Node
::
GetInstance
();
mtapi
::
Node
&
node
=
mtapi
::
Node
::
GetInstance
();
size
=
node
.
Get
Core
Count
();
size
=
node
.
Get
WorkerThread
Count
();
}
}
elements_count
=
static_cast
<
size_t
>
(
std
::
distance
(
first
,
last
));
elements_count
=
static_cast
<
size_t
>
(
std
::
distance
(
first
,
last
));
...
...
algorithms_cpp/include/embb/algorithms/internal/quick_sort-inl.h
View file @
ffa2f18a
...
@@ -186,16 +186,26 @@ class QuickSortFunctor {
...
@@ -186,16 +186,26 @@ class QuickSortFunctor {
QuickSortFunctor
(
const
QuickSortFunctor
&
);
QuickSortFunctor
(
const
QuickSortFunctor
&
);
};
};
}
// namespace internal
template
<
typename
RAI
,
typename
ComparisonFunction
>
template
<
typename
RAI
,
typename
ComparisonFunction
>
void
QuickSort
(
RAI
first
,
RAI
last
,
ComparisonFunction
comparison
,
void
QuickSortIteratorCheck
(
RAI
first
,
RAI
last
,
const
embb
::
mtapi
::
ExecutionPolicy
&
policy
,
size_t
block_size
)
{
ComparisonFunction
comparison
,
const
embb
::
mtapi
::
ExecutionPolicy
&
policy
,
size_t
block_size
,
std
::
random_access_iterator_tag
)
{
embb
::
mtapi
::
Node
&
node
=
embb
::
mtapi
::
Node
::
GetInstance
();
embb
::
mtapi
::
Node
&
node
=
embb
::
mtapi
::
Node
::
GetInstance
();
typename
std
::
iterator_traits
<
RAI
>::
difference_type
distance
=
last
-
first
;
typedef
typename
std
::
iterator_traits
<
RAI
>::
difference_type
difference_type
;
assert
(
distance
>
0
);
difference_type
distance
=
std
::
distance
(
first
,
last
);
if
(
distance
==
0
)
{
return
;
}
else
if
(
distance
<
0
)
{
EMBB_THROW
(
embb
::
base
::
ErrorException
,
"Negative range for QuickSort"
);
}
unsigned
int
num_cores
=
policy
.
GetCoreCount
();
if
(
num_cores
==
0
)
{
EMBB_THROW
(
embb
::
base
::
ErrorException
,
"No cores in execution policy"
);
}
if
(
block_size
==
0
)
{
if
(
block_size
==
0
)
{
block_size
=
(
static_cast
<
size_t
>
(
distance
)
/
n
ode
.
GetCoreCount
()
);
block_size
=
(
static_cast
<
size_t
>
(
distance
)
/
n
um_cores
);
if
(
block_size
==
0
)
if
(
block_size
==
0
)
block_size
=
1
;
block_size
=
1
;
}
}
...
@@ -203,13 +213,23 @@ void QuickSort(RAI first, RAI last, ComparisonFunction comparison,
...
@@ -203,13 +213,23 @@ void QuickSort(RAI first, RAI last, ComparisonFunction comparison,
EMBB_THROW
(
embb
::
base
::
ErrorException
,
EMBB_THROW
(
embb
::
base
::
ErrorException
,
"Not enough MTAPI tasks available for performing quick sort"
);
"Not enough MTAPI tasks available for performing quick sort"
);
}
}
internal
::
QuickSortFunctor
<
RAI
,
ComparisonFunction
>
functor
(
QuickSortFunctor
<
RAI
,
ComparisonFunction
>
functor
(
first
,
last
,
comparison
,
policy
,
block_size
);
first
,
last
,
comparison
,
policy
,
block_size
);
mtapi
::
Task
task
=
node
.
Spawn
(
mtapi
::
Action
(
base
::
MakeFunction
(
mtapi
::
Task
task
=
node
.
Spawn
(
mtapi
::
Action
(
base
::
MakeFunction
(
functor
,
&
internal
::
QuickSortFunctor
<
RAI
,
ComparisonFunction
>::
Action
)));
functor
,
&
QuickSortFunctor
<
RAI
,
ComparisonFunction
>::
Action
)));
task
.
Wait
(
MTAPI_INFINITE
);
task
.
Wait
(
MTAPI_INFINITE
);
}
}
}
// namespace internal
template
<
typename
RAI
,
typename
ComparisonFunction
>
void
QuickSort
(
RAI
first
,
RAI
last
,
ComparisonFunction
comparison
,
const
embb
::
mtapi
::
ExecutionPolicy
&
policy
,
size_t
block_size
)
{
typedef
typename
std
::
iterator_traits
<
RAI
>::
iterator_category
category
;
internal
::
QuickSortIteratorCheck
(
first
,
last
,
comparison
,
policy
,
block_size
,
category
());
}
}
// namespace algorithms
}
// namespace algorithms
}
// namespace embb
}
// namespace embb
...
...
algorithms_cpp/include/embb/algorithms/internal/reduce-inl.h
View file @
ffa2f18a
...
@@ -42,45 +42,55 @@ template<typename RAI, typename ReturnType, typename ReductionFunction,
...
@@ -42,45 +42,55 @@ template<typename RAI, typename ReturnType, typename ReductionFunction,
typename
TransformationFunction
>
typename
TransformationFunction
>
class
ReduceFunctor
{
class
ReduceFunctor
{
public
:
public
:
ReduceFunctor
(
RAI
first
,
RAI
last
,
ReturnType
neutral
,
ReduceFunctor
(
size_t
chunk_first
,
size_t
chunk_last
,
ReturnType
neutral
,
ReductionFunction
reduction
,
ReductionFunction
reduction
,
TransformationFunction
transformation
,
TransformationFunction
transformation
,
const
embb
::
mtapi
::
ExecutionPolicy
&
policy
,
size_t
block_size
,
const
embb
::
mtapi
::
ExecutionPolicy
&
policy
,
const
BlockSizePartitioner
<
RAI
>&
partitioner
,
ReturnType
&
result
)
ReturnType
&
result
)
:
:
chunk_first_
(
chunk_first
),
chunk_last_
(
chunk_last
),
neutral_
(
neutral
),
first_
(
first
),
last_
(
last
),
neutral_
(
neutral
),
reduction_
(
reduction
),
reduction_
(
reduction
),
transformation_
(
transformation
),
policy_
(
policy
),
transformation_
(
transformation
),
policy_
(
policy
),
partitioner_
(
partitioner
),
result_
(
result
)
{
block_size_
(
block_size
),
result_
(
result
)
{
}
}
void
Action
(
mtapi
::
TaskContext
&
)
{
void
Action
(
mtapi
::
TaskContext
&
)
{
if
(
first_
==
last_
)
{
if
(
chunk_first_
==
chunk_
last_
)
{
return
;
// Leaf case, recursed to single chunk. Do work on chunk:
}
ChunkDescriptor
<
RAI
>
chunk
=
partitioner_
[
chunk_first_
];
size_t
distance
=
static_cast
<
size_t
>
(
std
::
distance
(
first_
,
last_
)
);
RAI
first
=
chunk
.
GetFirst
(
);
if
(
distance
<=
block_size_
)
{
// leaf case -> do work
RAI
last
=
chunk
.
GetLast
();
ReturnType
result
(
neutral_
);
ReturnType
result
(
neutral_
);
for
(
RAI
it
er
=
first_
;
iter
!=
last_
;
++
iter
)
{
for
(
RAI
it
=
first
;
it
!=
last
;
++
it
)
{
result
=
reduction_
(
result
,
transformation_
(
*
it
er
));
result
=
reduction_
(
result
,
transformation_
(
*
it
));
}
}
result_
=
result
;
result_
=
result
;
}
else
{
// recurse further
}
else
{
internal
::
ChunkPartitioner
<
RAI
>
partitioner
(
first_
,
last_
,
2
);
// Recurse further:
size_t
chunk_split_index
=
(
chunk_first_
+
chunk_last_
)
/
2
;
// Split chunks into left / right branches:
ReturnType
result_l
(
neutral_
);
ReturnType
result_l
(
neutral_
);
ReturnType
result_r
(
neutral_
);
ReturnType
result_r
(
neutral_
);
ReduceFunctor
functor_l
(
partitioner
[
0
].
GetFirst
(),
self_t
functor_l
(
chunk_first_
,
partitioner
[
0
].
GetLast
(),
chunk_split_index
,
neutral_
,
reduction_
,
transformation_
,
policy_
,
neutral_
,
reduction_
,
transformation_
,
policy_
,
block_size_
,
result_l
);
partitioner_
,
ReduceFunctor
functor_r
(
partitioner
[
1
].
GetFirst
(),
result_l
);
partitioner
[
1
].
GetLast
(),
self_t
functor_r
(
chunk_split_index
+
1
,
neutral_
,
reduction_
,
transformation_
,
policy_
,
chunk_last_
,
block_size_
,
result_r
);
neutral_
,
reduction_
,
transformation_
,
policy_
,
mtapi
::
Node
&
node
=
mtapi
::
Node
::
GetInstance
();
partitioner_
,
mtapi
::
Task
task_l
=
node
.
Spawn
(
mtapi
::
Action
(
base
::
MakeFunction
(
result_r
);
functor_l
,
&
ReduceFunctor
::
Action
),
policy_
));
mtapi
::
Task
task_l
=
mtapi
::
Node
::
GetInstance
().
Spawn
(
mtapi
::
Task
task_r
=
node
.
Spawn
(
mtapi
::
Action
(
base
::
MakeFunction
(
mtapi
::
Action
(
functor_r
,
&
ReduceFunctor
::
Action
),
policy_
));
base
::
MakeFunction
(
functor_l
,
&
self_t
::
Action
),
policy_
));
mtapi
::
Task
task_r
=
mtapi
::
Node
::
GetInstance
().
Spawn
(
mtapi
::
Action
(
base
::
MakeFunction
(
functor_r
,
&
self_t
::
Action
),
policy_
));
task_l
.
Wait
(
MTAPI_INFINITE
);
task_l
.
Wait
(
MTAPI_INFINITE
);
task_r
.
Wait
(
MTAPI_INFINITE
);
task_r
.
Wait
(
MTAPI_INFINITE
);
result_
=
reduction_
(
result_l
,
result_r
);
result_
=
reduction_
(
result_l
,
result_r
);
...
@@ -88,15 +98,23 @@ class ReduceFunctor {
...
@@ -88,15 +98,23 @@ class ReduceFunctor {
}
}
private
:
private
:
RAI
first_
;
typedef
ReduceFunctor
<
RAI
,
ReturnType
,
RAI
last_
;
ReductionFunction
,
TransformationFunction
>
self_t
;
private
:
size_t
chunk_first_
;
size_t
chunk_last_
;
ReturnType
neutral_
;
ReturnType
neutral_
;
ReductionFunction
reduction_
;
ReductionFunction
reduction_
;
TransformationFunction
transformation_
;
TransformationFunction
transformation_
;
const
embb
::
mtapi
::
ExecutionPolicy
&
policy_
;
const
embb
::
mtapi
::
ExecutionPolicy
&
policy_
;
size_t
block_size
_
;
const
BlockSizePartitioner
<
RAI
>&
partitioner
_
;
ReturnType
&
result_
;
ReturnType
&
result_
;
/**
* Disables assignment and copy-construction.
*/
ReduceFunctor
&
operator
=
(
const
ReduceFunctor
&
);
ReduceFunctor
&
operator
=
(
const
ReduceFunctor
&
);
ReduceFunctor
(
const
ReduceFunctor
&
);
ReduceFunctor
(
const
ReduceFunctor
&
);
};
};
...
@@ -110,27 +128,42 @@ ReturnType ReduceRecursive(RAI first, RAI last, ReturnType neutral,
...
@@ -110,27 +128,42 @@ ReturnType ReduceRecursive(RAI first, RAI last, ReturnType neutral,
size_t
block_size
)
{
size_t
block_size
)
{
typedef
typename
std
::
iterator_traits
<
RAI
>::
difference_type
difference_type
;
typedef
typename
std
::
iterator_traits
<
RAI
>::
difference_type
difference_type
;
difference_type
distance
=
std
::
distance
(
first
,
last
);
difference_type
distance
=
std
::
distance
(
first
,
last
);
assert
(
distance
>
0
);
if
(
distance
==
0
)
{
return
neutral
;
}
else
if
(
distance
<
0
)
{
EMBB_THROW
(
embb
::
base
::
ErrorException
,
"Negative range for Reduce"
);
}
unsigned
int
num_cores
=
policy
.
GetCoreCount
();
if
(
num_cores
==
0
)
{
EMBB_THROW
(
embb
::
base
::
ErrorException
,
"No cores in execution policy"
);
}
mtapi
::
Node
&
node
=
mtapi
::
Node
::
GetInstance
();
mtapi
::
Node
&
node
=
mtapi
::
Node
::
GetInstance
();
size_t
used_block_size
=
block_size
;
// Determine actually used block size
if
(
used_block_size
==
0
)
{
if
(
block_size
==
0
)
{
used_block_size
=
static_cast
<
size_t
>
(
distance
)
/
node
.
GetCoreCount
();
block_size
=
(
static_cast
<
size_t
>
(
distance
)
/
num_cores
);
if
(
used_block_size
==
0
)
used_block_size
=
1
;
if
(
block_size
==
0
)
{
block_size
=
1
;
}
}
}
// Perform check of task number sufficiency
if
(((
distance
/
used_
block_size
)
*
2
)
+
1
>
MTAPI_NODE_MAX_TASKS_DEFAULT
)
{
if
(((
distance
/
block_size
)
*
2
)
+
1
>
MTAPI_NODE_MAX_TASKS_DEFAULT
)
{
EMBB_THROW
(
embb
::
base
::
ErrorException
,
EMBB_THROW
(
embb
::
base
::
ErrorException
,
"Number of computation tasks required in reduction would "
"Number of computation tasks required in reduction would "
"exceed MTAPI maximum number of tasks"
);
"exceed MTAPI maximum number of tasks"
);
}
}
ReturnType
result
=
neutral
;
typedef
ReduceFunctor
<
RAI
,
ReturnType
,
ReductionFunction
,
typedef
ReduceFunctor
<
RAI
,
ReturnType
,
ReductionFunction
,
TransformationFunction
>
Functor
;
TransformationFunction
>
Functor
;
Functor
functor
(
first
,
last
,
neutral
,
reduction
,
transformation
,
policy
,
BlockSizePartitioner
<
RAI
>
partitioner
(
first
,
last
,
block_size
);
used_block_size
,
result
);
ReturnType
result
=
neutral
;
mtapi
::
Task
task
=
node
.
Spawn
(
mtapi
::
Action
(
base
::
MakeFunction
(
Functor
functor
(
0
,
partitioner
.
Size
()
-
1
,
neutral
,
reduction
,
transformation
,
policy
,
partitioner
,
result
);
mtapi
::
Task
task
=
node
.
Spawn
(
mtapi
::
Action
(
base
::
MakeFunction
(
functor
,
&
Functor
::
Action
),
policy
));
functor
,
&
Functor
::
Action
),
policy
));
task
.
Wait
(
MTAPI_INFINITE
);
task
.
Wait
(
MTAPI_INFINITE
);
return
result
;
return
result
;
...
...
algorithms_cpp/include/embb/algorithms/internal/scan-inl.h
View file @
ffa2f18a
...
@@ -41,73 +41,79 @@ template<typename RAIIn, typename RAIOut, typename ReturnType,
...
@@ -41,73 +41,79 @@ template<typename RAIIn, typename RAIOut, typename ReturnType,
typename
ScanFunction
,
typename
TransformationFunction
>
typename
ScanFunction
,
typename
TransformationFunction
>
class
ScanFunctor
{
class
ScanFunctor
{
public
:
public
:
ScanFunctor
(
RAIIn
first
,
RAIIn
last
,
RAIOut
output_iterator
,
ScanFunctor
(
size_t
chunk_first
,
size_t
chunk_
last
,
RAIOut
output_iterator
,
ReturnType
neutral
,
ScanFunction
scan
,
ReturnType
neutral
,
ScanFunction
scan
,
TransformationFunction
transformation
,
TransformationFunction
transformation
,
const
embb
::
mtapi
::
ExecutionPolicy
&
policy
,
const
embb
::
mtapi
::
ExecutionPolicy
&
policy
,
size_t
block_size
,
ReturnType
*
tree_values
,
size_t
node_id
,
const
BlockSizePartitioner
<
RAIIn
>&
partitioner
,
ReturnType
*
tree_values
,
size_t
node_id
,
bool
going_down
)
bool
going_down
)
:
policy_
(
policy
),
first_
(
first
),
last_
(
last
),
:
policy_
(
policy
),
chunk_first_
(
chunk_first
),
chunk_last_
(
chunk_
last
),
output_iterator_
(
output_iterator
),
scan_
(
scan
),
output_iterator_
(
output_iterator
),
scan_
(
scan
),
transformation_
(
transformation
),
transformation_
(
transformation
),
neutral_
(
neutral
),
block_size_
(
block_size
),
tree_values_
(
tree_values
),
neutral_
(
neutral
),
partitioner_
(
partitioner
),
tree_values_
(
tree_values
),
node_id_
(
node_id
),
parent_value_
(
neutral
),
is_first_pass_
(
going_down
)
{
node_id_
(
node_id
),
parent_value_
(
neutral
),
is_first_pass_
(
going_down
)
{
}
}
void
Action
(
mtapi
::
TaskContext
&
)
{
void
Action
(
mtapi
::
TaskContext
&
)
{
if
(
first_
==
last_
)
{
if
(
chunk_first_
==
chunk_last_
)
{
return
;
ChunkDescriptor
<
RAIIn
>
chunk
=
partitioner_
[
chunk_first_
];
}
RAIIn
iter_in
=
chunk
.
GetFirst
();
size_t
distance
=
static_cast
<
size_t
>
(
std
::
distance
(
first_
,
last_
));
RAIIn
last_in
=
chunk
.
GetLast
();
if
(
distance
<=
block_size_
)
{
// leaf case -> do work
RAIOut
iter_out
=
output_iterator_
;
// leaf case -> do work
if
(
is_first_pass_
)
{
if
(
is_first_pass_
)
{
RAIIn
iter_in
=
first_
;
ReturnType
result
=
transformation_
(
*
iter_in
);
RAIOut
iter_out
=
output_iterator_
;
ReturnType
result
=
transformation_
(
*
first_
);
*
iter_out
=
result
;
*
iter_out
=
result
;
++
iter_in
;
++
iter_in
;
++
iter_out
;
++
iter_out
;
while
(
iter_in
!=
last_
)
{
for
(;
iter_in
!=
last_in
;
++
iter_in
,
++
iter_out
)
{
result
=
scan_
(
result
,
transformation_
(
*
iter_in
));
result
=
scan_
(
result
,
transformation_
(
*
iter_in
));
*
iter_out
=
result
;
*
iter_out
=
result
;
++
iter_in
;
++
iter_out
;
}
}
SetTreeValue
(
result
);
SetTreeValue
(
result
);
}
else
{
// Second pass
}
else
{
RAIIn
iter_in
=
first_
;
// Second pass
RAIOut
iter_out
=
output_iterator_
;
for
(;
iter_in
!=
last_in
;
++
iter_in
,
++
iter_out
)
{
while
(
iter_in
!=
last_
)
{
*
iter_out
=
scan_
(
parent_value_
,
*
iter_out
);
*
iter_out
=
scan_
(
parent_value_
,
*
iter_out
);
++
iter_in
;
++
iter_out
;
}
}
}
}
}
else
{
}
else
{
internal
::
ChunkPartitioner
<
RAIIn
>
partitioner
(
first_
,
last_
,
2
);
// recurse further
ScanFunctor
functor_l
(
partitioner
[
0
].
GetFirst
(),
partitioner
[
0
].
GetLast
(),
size_t
chunk_split_index
=
(
chunk_first_
+
chunk_last_
)
/
2
;
output_iterator_
,
neutral_
,
scan_
,
transformation_
,
// Split chunks into left / right branches:
policy_
,
block_size_
,
tree_values_
,
node_id_
,
ScanFunctor
functor_l
(
is_first_pass_
);
chunk_first_
,
chunk_split_index
,
ScanFunctor
functor_r
(
partitioner
[
1
].
GetFirst
(),
partitioner
[
1
].
GetLast
(),
output_iterator_
,
neutral_
,
scan_
,
transformation_
,
output_iterator_
,
neutral_
,
scan_
,
transformation_
,
policy_
,
partitioner_
,
tree_values_
,
node_id_
,
policy_
,
block_size_
,
tree_values_
,
node_id_
,
is_first_pass_
);
is_first_pass_
);
ScanFunctor
functor_r
(
functor_l
.
SetID
(
1
);
chunk_split_index
+
1
,
chunk_last_
,
functor_r
.
SetID
(
2
);
output_iterator_
,
neutral_
,
scan_
,
transformation_
,
policy_
,
partitioner_
,
tree_values_
,
node_id_
,
is_first_pass_
);
functor_l
.
SetID
(
LEFT
);
functor_r
.
SetID
(
RIGHT
);
// Advance output iterator of right branch:
ChunkDescriptor
<
RAIIn
>
chunk_left
=
partitioner_
[
chunk_first_
];
ChunkDescriptor
<
RAIIn
>
chunk_right
=
partitioner_
[
chunk_split_index
+
1
];
std
::
advance
(
functor_r
.
output_iterator_
,
std
::
advance
(
functor_r
.
output_iterator_
,
std
::
distance
(
functor_l
.
first_
,
functor_r
.
first_
));
std
::
distance
(
chunk_left
.
GetFirst
(),
chunk_right
.
GetFirst
()
));
if
(
!
is_first_pass_
)
{
if
(
!
is_first_pass_
)
{
functor_l
.
parent_value_
=
parent_value_
;
functor_l
.
parent_value_
=
parent_value_
;
functor_r
.
parent_value_
=
functor_l
.
GetTreeValue
()
+
parent_value_
;
functor_r
.
parent_value_
=
functor_l
.
GetTreeValue
()
+
parent_value_
;
}
}
// Spawn tasks to recurse:
mtapi
::
Node
&
node
=
mtapi
::
Node
::
GetInstance
();
mtapi
::
Node
&
node
=
mtapi
::
Node
::
GetInstance
();
mtapi
::
Task
task_l
=
node
.
Spawn
(
mtapi
::
Action
(
base
::
MakeFunction
(
mtapi
::
Task
task_l
=
node
.
Spawn
(
functor_l
,
&
ScanFunctor
::
Action
),
mtapi
::
Action
(
policy_
));
base
::
MakeFunction
(
functor_l
,
&
ScanFunctor
::
Action
),
mtapi
::
Task
task_r
=
node
.
Spawn
(
mtapi
::
Action
(
base
::
MakeFunction
(
policy_
));
functor_r
,
&
ScanFunctor
::
Action
),
mtapi
::
Task
task_r
=
node
.
Spawn
(
policy_
));
mtapi
::
Action
(
base
::
MakeFunction
(
functor_r
,
&
ScanFunctor
::
Action
),
policy_
));
// Wait for tasks to complete:
task_l
.
Wait
(
MTAPI_INFINITE
);
task_l
.
Wait
(
MTAPI_INFINITE
);
task_r
.
Wait
(
MTAPI_INFINITE
);
task_r
.
Wait
(
MTAPI_INFINITE
);
SetTreeValue
(
scan_
(
functor_l
.
GetTreeValue
(),
functor_r
.
GetTreeValue
()));
SetTreeValue
(
scan_
(
functor_l
.
GetTreeValue
(),
functor_r
.
GetTreeValue
()));
...
@@ -123,23 +129,25 @@ class ScanFunctor {
...
@@ -123,23 +129,25 @@ class ScanFunctor {
}
}
private
:
private
:
static
const
int
LEFT
=
1
;
static
const
int
RIGHT
=
2
;
const
embb
::
mtapi
::
ExecutionPolicy
&
policy_
;
const
embb
::
mtapi
::
ExecutionPolicy
&
policy_
;
RAIIn
first_
;
size_t
chunk_
first_
;
RAIIn
last_
;
size_t
chunk_
last_
;
RAIOut
output_iterator_
;
RAIOut
output_iterator_
;
ScanFunction
scan_
;
ScanFunction
scan_
;
TransformationFunction
transformation_
;
TransformationFunction
transformation_
;
ReturnType
neutral_
;
ReturnType
neutral_
;
size_t
block_size
_
;
const
BlockSizePartitioner
<
RAIIn
>&
partitioner
_
;
ReturnType
*
tree_values_
;
ReturnType
*
tree_values_
;
size_t
node_id_
;
size_t
node_id_
;
ReturnType
parent_value_
;
ReturnType
parent_value_
;
bool
is_first_pass_
;
bool
is_first_pass_
;
void
SetID
(
int
is_left
)
{
void
SetID
(
int
branch
)
{
if
(
is_left
==
1
)
{
if
(
branch
==
LEFT
)
{
node_id_
=
2
*
node_id_
+
1
;
node_id_
=
2
*
node_id_
+
1
;
}
else
if
(
is_left
==
2
)
{
}
else
if
(
branch
==
RIGHT
)
{
node_id_
=
2
*
node_id_
+
2
;
node_id_
=
2
*
node_id_
+
2
;
}
}
}
}
...
@@ -165,37 +173,48 @@ void ScanIteratorCheck(RAIIn first, RAIIn last, RAIOut output_iterator,
...
@@ -165,37 +173,48 @@ void ScanIteratorCheck(RAIIn first, RAIIn last, RAIOut output_iterator,
std
::
random_access_iterator_tag
)
{
std
::
random_access_iterator_tag
)
{
typedef
typename
std
::
iterator_traits
<
RAIIn
>::
difference_type
difference_type
;
typedef
typename
std
::
iterator_traits
<
RAIIn
>::
difference_type
difference_type
;
difference_type
distance
=
std
::
distance
(
first
,
last
);
difference_type
distance
=
std
::
distance
(
first
,
last
);
if
(
distance
<
=
0
)
{
if
(
distance
=
=
0
)
{
return
;
return
;
}
else
if
(
distance
<
0
)
{
EMBB_THROW
(
embb
::
base
::
ErrorException
,
"Negative range for Scan"
);
}
}
mtapi
::
Node
&
node
=
mtapi
::
Node
::
GetInstance
();
unsigned
int
num_cores
=
policy
.
GetCoreCount
();
if
(
num_cores
==
0
)
{
EMBB_THROW
(
embb
::
base
::
ErrorException
,
"No cores in execution policy"
);
}
ReturnType
values
[
MTAPI_NODE_MAX_TASKS_DEFAULT
];
ReturnType
values
[
MTAPI_NODE_MAX_TASKS_DEFAULT
];
size_t
used_block_size
=
block_size
;
if
(
block_size
==
0
)
{
if
(
block_size
==
0
)
{
used_block_size
=
static_cast
<
size_t
>
(
distance
)
/
node
.
GetCoreCount
();
block_size
=
static_cast
<
size_t
>
(
distance
)
/
num_cores
;
if
(
used_block_size
==
0
)
used_block_size
=
1
;
if
(
block_size
==
0
)
{
block_size
=
1
;
}
}
}
if
(((
distance
/
used_
block_size
)
*
2
)
+
1
>
MTAPI_NODE_MAX_TASKS_DEFAULT
)
{
if
(((
distance
/
block_size
)
*
2
)
+
1
>
MTAPI_NODE_MAX_TASKS_DEFAULT
)
{
EMBB_THROW
(
embb
::
base
::
ErrorException
,
EMBB_THROW
(
embb
::
base
::
ErrorException
,
"Number of computation tasks required in scan "
"Not enough MTAPI tasks available for parallel scan"
);
"exceeds MTAPI maximum number of tasks"
);
}
}
// first pass. Calculates prefix sums for leaves and when recursion returns
// first pass. Calculates prefix sums for leaves and when recursion returns
// it creates the tree.
// it creates the tree.
typedef
ScanFunctor
<
RAIIn
,
RAIOut
,
ReturnType
,
ScanFunction
,
typedef
ScanFunctor
<
RAIIn
,
RAIOut
,
ReturnType
,
ScanFunction
,
TransformationFunction
>
Functor
;
TransformationFunction
>
Functor
;
Functor
functor_down
(
first
,
last
,
output_iterator
,
neutral
,
scan
,
mtapi
::
Node
&
node
=
mtapi
::
Node
::
GetInstance
();
transformation
,
policy
,
used_block_size
,
values
,
0
,
true
);
BlockSizePartitioner
<
RAIIn
>
partitioner_down
(
first
,
last
,
block_size
);
Functor
functor_down
(
0
,
partitioner_down
.
Size
()
-
1
,
output_iterator
,
neutral
,
scan
,
transformation
,
policy
,
partitioner_down
,
values
,
0
,
true
);
mtapi
::
Task
task_down
=
node
.
Spawn
(
mtapi
::
Action
(
base
::
MakeFunction
(
mtapi
::
Task
task_down
=
node
.
Spawn
(
mtapi
::
Action
(
base
::
MakeFunction
(
functor_down
,
&
Functor
::
Action
),
functor_down
,
&
Functor
::
Action
),
policy
));
policy
));
task_down
.
Wait
(
MTAPI_INFINITE
);
task_down
.
Wait
(
MTAPI_INFINITE
);
// Second pass. Gives to each leaf the part of the prefix missing
// Second pass. Gives to each leaf the part of the prefix missing
Functor
functor_up
(
first
,
last
,
output_iterator
,
neutral
,
scan
,
BlockSizePartitioner
<
RAIIn
>
partitioner_up
(
first
,
last
,
block_size
);
transformation
,
policy
,
used_block_size
,
values
,
0
,
false
);
Functor
functor_up
(
0
,
partitioner_up
.
Size
()
-
1
,
output_iterator
,
neutral
,
scan
,
transformation
,
policy
,
partitioner_up
,
values
,
0
,
false
);
mtapi
::
Task
task_up
=
node
.
Spawn
(
mtapi
::
Action
(
base
::
MakeFunction
(
mtapi
::
Task
task_up
=
node
.
Spawn
(
mtapi
::
Action
(
base
::
MakeFunction
(
functor_up
,
&
Functor
::
Action
),
functor_up
,
&
Functor
::
Action
),
policy
));
policy
));
...
...
algorithms_cpp/include/embb/algorithms/invoke.h
View file @
ffa2f18a
...
@@ -58,7 +58,7 @@ typedef embb::base::Function<void> InvokeFunctionType;
...
@@ -58,7 +58,7 @@ typedef embb::base::Function<void> InvokeFunctionType;
template
<
typename
Function1
,
...
>
template
<
typename
Function1
,
...
>
void
Invoke
(
void
Invoke
(
Function1
func1
,
Function1
func1
,
/**< [in] First function to invoke */
/**< [in] First function
object
to invoke */
...);
...);
/**
/**
...
@@ -72,7 +72,7 @@ void Invoke(
...
@@ -72,7 +72,7 @@ void Invoke(
template
<
typename
Function1
,
...
>
template
<
typename
Function1
,
...
>
void
Invoke
(
void
Invoke
(
Function1
func1
,
Function1
func1
,
/**< [in] Function to invoke */
/**< [in] Function
object
to invoke */
...,
...,
const
embb
::
mtapi
::
ExecutionPolicy
&
policy
const
embb
::
mtapi
::
ExecutionPolicy
&
policy
/**< [in] embb::mtapi::ExecutionPolicy to use */
/**< [in] embb::mtapi::ExecutionPolicy to use */
...
...
algorithms_cpp/include/embb/algorithms/merge_sort.h
View file @
ffa2f18a
...
@@ -167,9 +167,20 @@ void MergeSortAllocate(
...
@@ -167,9 +167,20 @@ void MergeSortAllocate(
typedef
base
::
Allocation
Alloc
;
typedef
base
::
Allocation
Alloc
;
typename
std
::
iterator_traits
<
RAI
>::
difference_type
distance
=
last
-
first
;
typename
std
::
iterator_traits
<
RAI
>::
difference_type
distance
=
last
-
first
;
typedef
typename
std
::
iterator_traits
<
RAI
>::
value_type
value_type
;
typedef
typename
std
::
iterator_traits
<
RAI
>::
value_type
value_type
;
if
(
distance
==
0
)
{
return
;
}
else
if
(
distance
<
0
)
{
EMBB_THROW
(
embb
::
base
::
ErrorException
,
"Negative range for MergeSort"
);
}
value_type
*
temporary
=
static_cast
<
value_type
*>
(
value_type
*
temporary
=
static_cast
<
value_type
*>
(
Alloc
::
Allocate
(
distance
*
sizeof
(
value_type
)));
Alloc
::
Allocate
(
distance
*
sizeof
(
value_type
)));
MergeSort
(
first
,
last
,
temporary
,
comparison
,
policy
,
block_size
);
EMBB_TRY
{
MergeSort
(
first
,
last
,
temporary
,
comparison
,
policy
,
block_size
);
}
EMBB_CATCH
(
embb
::
base
::
ErrorException
&
e
)
{
// embb exception handling does not support catch(...) and rethrow yet.
Alloc
::
Free
(
temporary
);
EMBB_THROW
(
embb
::
base
::
ErrorException
,
e
.
what
());
}
Alloc
::
Free
(
temporary
);
Alloc
::
Free
(
temporary
);
}
}
...
...
algorithms_cpp/include/embb/algorithms/reduce.h
View file @
ffa2f18a
...
@@ -68,10 +68,10 @@ namespace algorithms {
...
@@ -68,10 +68,10 @@ namespace algorithms {
* \tparam RAI Random access iterator
* \tparam RAI Random access iterator
* \tparam ReturnType Type of result of reduction operation, deduced from
* \tparam ReturnType Type of result of reduction operation, deduced from
* \c neutral
* \c neutral
* \tparam ReductionFunction Binary reduction function with signature
* \tparam ReductionFunction Binary reduction function
object
with signature
* <tt>ReturnType ReductionFunction(ReturnType, ReturnType)</tt>.
* <tt>ReturnType ReductionFunction(ReturnType, ReturnType)</tt>.
* \tparam TransformationFunction Unary transformation function
with signature
* \tparam TransformationFunction Unary transformation function
object with
* <tt>ReturnType TransformationFunction(typename
*
signature
<tt>ReturnType TransformationFunction(typename
* std::iterator_traits<RAI>::value_type)</tt>
* std::iterator_traits<RAI>::value_type)</tt>
*/
*/
template
<
typename
RAI
,
typename
ReturnType
,
typename
ReductionFunction
,
template
<
typename
RAI
,
typename
ReturnType
,
typename
ReductionFunction
,
...
...
algorithms_cpp/include/embb/algorithms/scan.h
View file @
ffa2f18a
...
@@ -71,10 +71,10 @@ namespace algorithms {
...
@@ -71,10 +71,10 @@ namespace algorithms {
* \tparam RAIOut Random access iterator type of output range
* \tparam RAIOut Random access iterator type of output range
* \tparam ReturnType Type of output elements of scan operation, deduced from
* \tparam ReturnType Type of output elements of scan operation, deduced from
* \c neutral
* \c neutral
* \tparam ScanFunction Binary scan function with signature
* \tparam ScanFunction Binary scan function
object
with signature
* <tt>ReturnType ScanFunction(ReturnType, ReturnType)</tt>
* <tt>ReturnType ScanFunction(ReturnType, ReturnType)</tt>
* \tparam TransformationFunction Unary transformation function
with signature
* \tparam TransformationFunction Unary transformation function
object with
* <tt>ReturnType TransformationFunction(typename
*
signature
<tt>ReturnType TransformationFunction(typename
* std::iterator_traits<RAIIn>::value_type)</tt>.
* std::iterator_traits<RAIIn>::value_type)</tt>.
*/
*/
template
<
typename
RAIIn
,
typename
RAIOut
,
typename
ReturnType
,
template
<
typename
RAIIn
,
typename
RAIOut
,
typename
ReturnType
,
...
...
algorithms_cpp/test/count_test.cc
View file @
ffa2f18a
...
@@ -60,7 +60,7 @@ CountTest::CountTest() {
...
@@ -60,7 +60,7 @@ CountTest::CountTest() {
void
CountTest
::
TestDataStructures
()
{
void
CountTest
::
TestDataStructures
()
{
using
embb
::
algorithms
::
Count
;
using
embb
::
algorithms
::
Count
;
const
int
size
=
10
;
const
int
size
=
10
;
int
array
[]
=
{
10
,
20
,
30
,
30
,
20
,
10
,
10
,
20
,
20
,
20
};
int
array
[]
=
{
10
,
20
,
30
,
30
,
20
,
10
,
10
,
20
,
20
,
20
};
std
::
vector
<
int
>
vector
(
array
,
array
+
size
);
std
::
vector
<
int
>
vector
(
array
,
array
+
size
);
std
::
deque
<
int
>
deque
(
array
,
array
+
size
);
std
::
deque
<
int
>
deque
(
array
,
array
+
size
);
const
std
::
vector
<
int
>
const_vector
(
array
,
array
+
size
);
const
std
::
vector
<
int
>
const_vector
(
array
,
array
+
size
);
...
@@ -74,7 +74,7 @@ void CountTest::TestDataStructures() {
...
@@ -74,7 +74,7 @@ void CountTest::TestDataStructures() {
void
CountTest
::
TestCountIf
()
{
void
CountTest
::
TestCountIf
()
{
using
embb
::
algorithms
::
CountIf
;
using
embb
::
algorithms
::
CountIf
;
const
int
size
=
10
;
const
int
size
=
10
;
int
array
[]
=
{
10
,
21
,
30
,
31
,
20
,
11
,
10
,
21
,
20
,
20
};
int
array
[]
=
{
10
,
21
,
30
,
31
,
20
,
11
,
10
,
21
,
20
,
20
};
PT_EXPECT_EQ
(
CountIf
(
array
,
array
+
size
,
IsEven
()),
6
);
PT_EXPECT_EQ
(
CountIf
(
array
,
array
+
size
,
IsEven
()),
6
);
PT_EXPECT_EQ
(
CountIf
(
array
,
array
+
size
,
&
IsEvenFunction
),
6
);
PT_EXPECT_EQ
(
CountIf
(
array
,
array
+
size
,
&
IsEvenFunction
),
6
);
}
}
...
@@ -128,8 +128,6 @@ void CountTest::TestPolicy() {
...
@@ -128,8 +128,6 @@ void CountTest::TestPolicy() {
PT_EXPECT_EQ
(
Count
(
vector
.
begin
(),
vector
.
end
(),
10
,
ExecutionPolicy
()),
3
);
PT_EXPECT_EQ
(
Count
(
vector
.
begin
(),
vector
.
end
(),
10
,
ExecutionPolicy
()),
3
);
PT_EXPECT_EQ
(
Count
(
vector
.
begin
(),
vector
.
end
(),
10
,
ExecutionPolicy
(
true
)),
PT_EXPECT_EQ
(
Count
(
vector
.
begin
(),
vector
.
end
(),
10
,
ExecutionPolicy
(
true
)),
3
);
3
);
PT_EXPECT_EQ
(
Count
(
vector
.
begin
(),
vector
.
end
(),
10
,
ExecutionPolicy
(
false
)),
3
);
PT_EXPECT_EQ
(
Count
(
vector
.
begin
(),
vector
.
end
(),
10
,
PT_EXPECT_EQ
(
Count
(
vector
.
begin
(),
vector
.
end
(),
10
,
ExecutionPolicy
(
true
,
1
)),
3
);
ExecutionPolicy
(
true
,
1
)),
3
);
}
}
...
...
algorithms_cpp/test/for_each_test.cc
View file @
ffa2f18a
...
@@ -207,16 +207,35 @@ void ForEachTest::TestPolicy() {
...
@@ -207,16 +207,35 @@ void ForEachTest::TestPolicy() {
}
}
vector
=
init
;
vector
=
init
;
ForEach
(
vector
.
begin
(),
vector
.
end
(),
Square
(),
ExecutionPolicy
(
false
));
ForEach
(
vector
.
begin
(),
vector
.
end
(),
Square
(),
ExecutionPolicy
(
true
,
1
));
for
(
size_t
i
=
0
;
i
<
count
;
i
++
)
{
for
(
size_t
i
=
0
;
i
<
count
;
i
++
)
{
PT_EXPECT_EQ
(
vector
[
i
],
init
[
i
]
*
init
[
i
]);
PT_EXPECT_EQ
(
vector
[
i
],
init
[
i
]
*
init
[
i
]);
}
}
vector
=
init
;
// ForEach on empty list should not throw:
ForEach
(
vector
.
begin
(),
vector
.
end
(),
Square
(),
ExecutionPolicy
(
true
,
1
));
ForEach
(
vector
.
begin
(),
vector
.
begin
(),
Square
());
for
(
size_t
i
=
0
;
i
<
count
;
i
++
)
{
PT_EXPECT_EQ
(
vector
[
i
],
init
[
i
]
*
init
[
i
]);
#ifdef EMBB_USE_EXCEPTIONS
bool
empty_core_set_thrown
=
false
;
try
{
ForEach
(
vector
.
begin
(),
vector
.
end
(),
Square
(),
ExecutionPolicy
(
false
));
}
catch
(
embb
::
base
::
ErrorException
&
)
{
empty_core_set_thrown
=
true
;
}
PT_EXPECT_MSG
(
empty_core_set_thrown
,
"Empty core set should throw ErrorException"
);
bool
negative_range_thrown
=
false
;
try
{
std
::
vector
<
int
>::
iterator
second
=
vector
.
begin
()
+
1
;
ForEach
(
second
,
vector
.
begin
(),
Square
());
}
catch
(
embb
::
base
::
ErrorException
&
)
{
negative_range_thrown
=
true
;
}
}
PT_EXPECT_MSG
(
negative_range_thrown
,
"Negative range should throw ErrorException"
);
#endif
}
}
void
ForEachTest
::
StressTest
()
{
void
ForEachTest
::
StressTest
()
{
...
...
algorithms_cpp/test/merge_sort_test.cc
View file @
ffa2f18a
...
@@ -156,28 +156,28 @@ void MergeSortTest::TestRanges() {
...
@@ -156,28 +156,28 @@ void MergeSortTest::TestRanges() {
}
}
}
}
//
void MergeSortTest::TestBlockSizes() {
void
MergeSortTest
::
TestBlockSizes
()
{
//
using embb::algorithms::MergeSortAllocate;
using
embb
::
algorithms
::
MergeSortAllocate
;
// using embb::algorithms
::ExecutionPolicy;
using
embb
::
mtapi
::
ExecutionPolicy
;
//
size_t count = 4;
size_t
count
=
4
;
//
std::vector<int> init(count);
std
::
vector
<
int
>
init
(
count
);
//
std::vector<int> vector(count);
std
::
vector
<
int
>
vector
(
count
);
//
std::vector<int> vector_copy(count);
std
::
vector
<
int
>
vector_copy
(
count
);
//
for (size_t i = count - 1; i > 0; i--) {
for
(
size_t
i
=
count
-
1
;
i
>
0
;
i
--
)
{
//
init[i] = static_cast<int>(i+2);
init
[
i
]
=
static_cast
<
int
>
(
i
+
2
);
//
}
}
//
vector_copy = init;
vector_copy
=
init
;
//
std::sort(vector_copy.begin(), vector_copy.end());
std
::
sort
(
vector_copy
.
begin
(),
vector_copy
.
end
());
//
//
for (size_t block_size = 1; block_size < count + 2; block_size++) {
for
(
size_t
block_size
=
1
;
block_size
<
count
+
2
;
block_size
++
)
{
//
vector = init;
vector
=
init
;
//
MergeSortAllocate(vector.begin(), vector.end(), std::less<int>(),
MergeSortAllocate
(
vector
.
begin
(),
vector
.
end
(),
std
::
less
<
int
>
(),
//
ExecutionPolicy(), block_size);
ExecutionPolicy
(),
block_size
);
//
for (size_t i = 0; i < count; i++) {
for
(
size_t
i
=
0
;
i
<
count
;
i
++
)
{
//
PT_EXPECT_EQ(vector[i], vector_copy[i]);
PT_EXPECT_EQ
(
vector
[
i
],
vector_copy
[
i
]);
//
}
}
//
}
}
//
}
}
void
MergeSortTest
::
TestPolicy
()
{
void
MergeSortTest
::
TestPolicy
()
{
using
embb
::
algorithms
::
MergeSortAllocate
;
using
embb
::
algorithms
::
MergeSortAllocate
;
...
@@ -201,24 +201,43 @@ void MergeSortTest::TestPolicy() {
...
@@ -201,24 +201,43 @@ void MergeSortTest::TestPolicy() {
vector
=
init
;
vector
=
init
;
MergeSortAllocate
(
vector
.
begin
(),
vector
.
end
(),
std
::
less
<
int
>
(),
MergeSortAllocate
(
vector
.
begin
(),
vector
.
end
(),
std
::
less
<
int
>
(),
ExecutionPolicy
(
true
));
ExecutionPolicy
(
true
));
for
(
size_t
i
=
0
;
i
<
count
;
i
++
)
{
for
(
size_t
i
=
0
;
i
<
count
;
i
++
)
{
PT_EXPECT_EQ
(
vector_copy
[
i
],
vector
[
i
]);
PT_EXPECT_EQ
(
vector_copy
[
i
],
vector
[
i
]);
}
}
vector
=
init
;
vector
=
init
;
MergeSortAllocate
(
vector
.
begin
(),
vector
.
end
(),
std
::
less
<
int
>
(),
MergeSortAllocate
(
vector
.
begin
(),
vector
.
end
(),
std
::
less
<
int
>
(),
ExecutionPolicy
(
false
));
ExecutionPolicy
(
true
,
1
));
for
(
size_t
i
=
0
;
i
<
count
;
i
++
)
{
for
(
size_t
i
=
0
;
i
<
count
;
i
++
)
{
PT_EXPECT_EQ
(
vector_copy
[
i
],
vector
[
i
]);
PT_EXPECT_EQ
(
vector_copy
[
i
],
vector
[
i
]);
}
}
vector
=
init
;
// MergeSort on empty list should not throw:
MergeSortAllocate
(
vector
.
begin
(),
vector
.
end
(),
std
::
less
<
int
>
(),
MergeSortAllocate
(
vector
.
begin
(),
vector
.
begin
(),
std
::
less
<
int
>
());
ExecutionPolicy
(
true
,
1
));
for
(
size_t
i
=
0
;
i
<
count
;
i
++
)
{
#ifdef EMBB_USE_EXCEPTIONS
PT_EXPECT_EQ
(
vector_copy
[
i
],
vector
[
i
]);
bool
empty_core_set_thrown
=
false
;
try
{
MergeSortAllocate
(
vector
.
begin
(),
vector
.
end
(),
std
::
less
<
int
>
(),
ExecutionPolicy
(
false
));
}
catch
(
embb
::
base
::
ErrorException
&
)
{
empty_core_set_thrown
=
true
;
}
PT_EXPECT_MSG
(
empty_core_set_thrown
,
"Empty core set should throw ErrorException"
);
bool
negative_range_thrown
=
false
;
try
{
std
::
vector
<
int
>::
iterator
second
=
vector
.
begin
()
+
1
;
MergeSortAllocate
(
second
,
vector
.
begin
(),
std
::
less
<
int
>
());
}
catch
(
embb
::
base
::
ErrorException
&
)
{
negative_range_thrown
=
true
;
}
}
PT_EXPECT_MSG
(
negative_range_thrown
,
"Negative range should throw ErrorException"
);
#endif
}
}
void
MergeSortTest
::
StressTest
()
{
void
MergeSortTest
::
StressTest
()
{
...
...
algorithms_cpp/test/merge_sort_test.h
View file @
ffa2f18a
...
@@ -58,7 +58,7 @@ class MergeSortTest : public partest::TestCase {
...
@@ -58,7 +58,7 @@ class MergeSortTest : public partest::TestCase {
/**
/**
* Tests various block sizes for the workers.
* Tests various block sizes for the workers.
*/
*/
//
void TestBlockSizes();
void
TestBlockSizes
();
/**
/**
* Tests setting policies (without checking their actual execution).
* Tests setting policies (without checking their actual execution).
...
...
algorithms_cpp/test/quick_sort_test.cc
View file @
ffa2f18a
...
@@ -214,17 +214,36 @@ void QuickSortTest::TestPolicy() {
...
@@ -214,17 +214,36 @@ void QuickSortTest::TestPolicy() {
vector
=
init
;
vector
=
init
;
QuickSort
(
vector
.
begin
(),
vector
.
end
(),
std
::
greater
<
int
>
(),
QuickSort
(
vector
.
begin
(),
vector
.
end
(),
std
::
greater
<
int
>
(),
ExecutionPolicy
(
false
));
ExecutionPolicy
(
true
,
1
));
for
(
size_t
i
=
0
;
i
<
count
;
i
++
)
{
for
(
size_t
i
=
0
;
i
<
count
;
i
++
)
{
PT_EXPECT_EQ
(
vector_copy
[
i
],
vector
[
i
]);
PT_EXPECT_EQ
(
vector_copy
[
i
],
vector
[
i
]);
}
}
vector
=
init
;
// MergeSort on empty list should not throw:
QuickSort
(
vector
.
begin
(),
vector
.
end
(),
std
::
greater
<
int
>
(),
QuickSort
(
vector
.
begin
(),
vector
.
begin
(),
std
::
less
<
int
>
());
ExecutionPolicy
(
true
,
1
));
for
(
size_t
i
=
0
;
i
<
count
;
i
++
)
{
#ifdef EMBB_USE_EXCEPTIONS
PT_EXPECT_EQ
(
vector_copy
[
i
],
vector
[
i
]);
bool
empty_core_set_thrown
=
false
;
try
{
QuickSort
(
vector
.
begin
(),
vector
.
end
(),
std
::
less
<
int
>
(),
ExecutionPolicy
(
false
));
}
catch
(
embb
::
base
::
ErrorException
&
)
{
empty_core_set_thrown
=
true
;
}
PT_EXPECT_MSG
(
empty_core_set_thrown
,
"Empty core set should throw ErrorException"
);
bool
negative_range_thrown
=
false
;
try
{
std
::
vector
<
int
>::
iterator
second
=
vector
.
begin
()
+
1
;
QuickSort
(
second
,
vector
.
begin
(),
std
::
less
<
int
>
());
}
catch
(
embb
::
base
::
ErrorException
&
)
{
negative_range_thrown
=
true
;
}
}
PT_EXPECT_MSG
(
negative_range_thrown
,
"Negative range should throw ErrorException"
);
#endif
}
}
void
QuickSortTest
::
StressTest
()
{
void
QuickSortTest
::
StressTest
()
{
...
...
algorithms_cpp/test/reduce_test.cc
View file @
ffa2f18a
...
@@ -179,10 +179,33 @@ void ReduceTest::TestPolicy() {
...
@@ -179,10 +179,33 @@ void ReduceTest::TestPolicy() {
Identity
(),
ExecutionPolicy
()),
sum
);
Identity
(),
ExecutionPolicy
()),
sum
);
PT_EXPECT_EQ
(
Reduce
(
vector
.
begin
(),
vector
.
end
(),
0
,
std
::
plus
<
int
>
(),
PT_EXPECT_EQ
(
Reduce
(
vector
.
begin
(),
vector
.
end
(),
0
,
std
::
plus
<
int
>
(),
Identity
(),
ExecutionPolicy
(
true
)),
sum
);
Identity
(),
ExecutionPolicy
(
true
)),
sum
);
PT_EXPECT_EQ
(
Reduce
(
vector
.
begin
(),
vector
.
end
(),
0
,
std
::
plus
<
int
>
(),
Identity
(),
ExecutionPolicy
(
false
)),
sum
);
PT_EXPECT_EQ
(
Reduce
(
vector
.
begin
(),
vector
.
end
(),
0
,
std
::
plus
<
int
>
(),
PT_EXPECT_EQ
(
Reduce
(
vector
.
begin
(),
vector
.
end
(),
0
,
std
::
plus
<
int
>
(),
Identity
(),
ExecutionPolicy
(
true
,
1
)),
sum
);
Identity
(),
ExecutionPolicy
(
true
,
1
)),
sum
);
// Empty list should return neutral element:
PT_EXPECT_EQ
(
Reduce
(
vector
.
begin
(),
vector
.
begin
(),
41
,
std
::
plus
<
int
>
(),
Identity
(),
ExecutionPolicy
(
true
,
1
)),
41
);
#ifdef EMBB_USE_EXCEPTIONS
bool
empty_core_set_thrown
=
false
;
try
{
Reduce
(
vector
.
begin
(),
vector
.
end
(),
0
,
std
::
plus
<
int
>
(),
Identity
(),
ExecutionPolicy
(
false
));
}
catch
(
embb
::
base
::
ErrorException
&
)
{
empty_core_set_thrown
=
true
;
}
PT_EXPECT_MSG
(
empty_core_set_thrown
,
"Empty core set should throw ErrorException"
);
bool
negative_range_thrown
=
false
;
try
{
std
::
vector
<
int
>::
iterator
second
=
vector
.
begin
()
+
1
;
Reduce
(
second
,
vector
.
begin
(),
0
,
std
::
plus
<
int
>
());
}
catch
(
embb
::
base
::
ErrorException
&
)
{
negative_range_thrown
=
true
;
}
PT_EXPECT_MSG
(
negative_range_thrown
,
"Negative range should throw ErrorException"
);
#endif
}
}
void
ReduceTest
::
StressTest
()
{
void
ReduceTest
::
StressTest
()
{
...
...
algorithms_cpp/test/scan_test.cc
View file @
ffa2f18a
...
@@ -284,21 +284,41 @@ void ScanTest::TestPolicy() {
...
@@ -284,21 +284,41 @@ void ScanTest::TestPolicy() {
outputVector
=
init
;
outputVector
=
init
;
Scan
(
vector
.
begin
(),
vector
.
end
(),
outputVector
.
begin
(),
0
,
std
::
plus
<
int
>
(),
Scan
(
vector
.
begin
(),
vector
.
end
(),
outputVector
.
begin
(),
0
,
std
::
plus
<
int
>
(),
Identity
(),
ExecutionPolicy
(
false
));
Identity
(),
ExecutionPolicy
(
true
,
1
));
expected
=
0
;
expected
=
0
;
for
(
size_t
i
=
0
;
i
<
count
;
i
++
)
{
for
(
size_t
i
=
0
;
i
<
count
;
i
++
)
{
expected
+=
vector
[
i
];
expected
+=
vector
[
i
];
PT_EXPECT_EQ
(
expected
,
outputVector
[
i
]);
PT_EXPECT_EQ
(
expected
,
outputVector
[
i
]);
}
}
// Empty list should not throw and not change output:
outputVector
=
init
;
outputVector
=
init
;
Scan
(
vector
.
begin
(),
vector
.
end
(),
outputVector
.
begin
(),
0
,
std
::
plus
<
int
>
(),
std
::
vector
<
int
>::
iterator
out_it
=
outputVector
.
begin
();
Identity
(),
ExecutionPolicy
(
true
,
1
));
Scan
(
vector
.
begin
(),
vector
.
begin
(),
out_it
,
0
,
std
::
plus
<
int
>
());
expected
=
0
;
PT_EXPECT
(
out_it
==
outputVector
.
begin
());
for
(
size_t
i
=
0
;
i
<
count
;
i
++
)
{
expected
+=
vector
[
i
];
#ifdef EMBB_USE_EXCEPTIONS
PT_EXPECT_EQ
(
expected
,
outputVector
[
i
]);
bool
empty_core_set_thrown
=
false
;
try
{
Scan
(
vector
.
begin
(),
vector
.
end
(),
outputVector
.
begin
(),
0
,
std
::
plus
<
int
>
(),
Identity
(),
ExecutionPolicy
(
false
));
}
catch
(
embb
::
base
::
ErrorException
&
)
{
empty_core_set_thrown
=
true
;
}
PT_EXPECT_MSG
(
empty_core_set_thrown
,
"Empty core set should throw ErrorException"
);
bool
negative_range_thrown
=
false
;
try
{
std
::
vector
<
int
>::
iterator
second
=
vector
.
begin
()
+
1
;
Scan
(
second
,
vector
.
begin
(),
outputVector
.
begin
(),
0
,
std
::
plus
<
int
>
());
}
catch
(
embb
::
base
::
ErrorException
&
)
{
negative_range_thrown
=
true
;
}
}
PT_EXPECT_MSG
(
negative_range_thrown
,
"Negative range should throw ErrorException"
);
#endif
}
}
void
ScanTest
::
StressTest
()
{
void
ScanTest
::
StressTest
()
{
...
...
base_c/include/embb/base/c/internal/platform.h
View file @
ffa2f18a
...
@@ -105,4 +105,4 @@ typedef pthread_cond_t embb_condition_t;
...
@@ -105,4 +105,4 @@ typedef pthread_cond_t embb_condition_t;
}
/* Close extern "C" { */
}
/* Close extern "C" { */
#endif
#endif
#endif // EMBB_BASE_C_INTERNAL_PLATFORM_H_
#endif
// EMBB_BASE_C_INTERNAL_PLATFORM_H_
base_c/test/alloc_test.h
View file @
ffa2f18a
...
@@ -81,4 +81,4 @@ class AllocTest : public partest::TestCase {
...
@@ -81,4 +81,4 @@ class AllocTest : public partest::TestCase {
}
// namespace base
}
// namespace base
}
// namespace embb
}
// namespace embb
#endif // BASE_C_TEST_ALLOC_TEST_H_
#endif
// BASE_C_TEST_ALLOC_TEST_H_
base_c/test/condition_var_test.h
View file @
ffa2f18a
...
@@ -65,4 +65,4 @@ class ConditionVarTest : public partest::TestCase {
...
@@ -65,4 +65,4 @@ class ConditionVarTest : public partest::TestCase {
}
// namespace base
}
// namespace base
}
// namespace embb
}
// namespace embb
#endif // BASE_C_TEST_CONDITION_VAR_TEST_H_
#endif
// BASE_C_TEST_CONDITION_VAR_TEST_H_
base_c/test/core_set_test.h
View file @
ffa2f18a
...
@@ -51,4 +51,4 @@ class CoreSetTest : public partest::TestCase {
...
@@ -51,4 +51,4 @@ class CoreSetTest : public partest::TestCase {
}
// namespace base
}
// namespace base
}
// namespace embb
}
// namespace embb
#endif // BASE_C_TEST_CORE_SET_TEST_H_
#endif
// BASE_C_TEST_CORE_SET_TEST_H_
base_c/test/counter_test.h
View file @
ffa2f18a
...
@@ -97,4 +97,4 @@ class CounterTest : public partest::TestCase {
...
@@ -97,4 +97,4 @@ class CounterTest : public partest::TestCase {
}
// namespace base
}
// namespace base
}
// namespace embb
}
// namespace embb
#endif // BASE_C_TEST_COUNTER_TEST_H_
#endif
// BASE_C_TEST_COUNTER_TEST_H_
base_c/test/duration_test.h
View file @
ffa2f18a
...
@@ -73,4 +73,4 @@ class DurationTest : public partest::TestCase {
...
@@ -73,4 +73,4 @@ class DurationTest : public partest::TestCase {
}
// namespace base
}
// namespace base
}
// namespace embb
}
// namespace embb
#endif // BASE_C_TEST_DURATION_TEST_H_
#endif
// BASE_C_TEST_DURATION_TEST_H_
base_c/test/thread_index_test.h
View file @
ffa2f18a
...
@@ -78,4 +78,4 @@ int ThreadStart(void* arg);
...
@@ -78,4 +78,4 @@ int ThreadStart(void* arg);
#endif // BASE_C_TEST_THREAD_INDEX_TEST_H_
#endif
// BASE_C_TEST_THREAD_INDEX_TEST_H_
base_c/test/thread_specific_storage_test.h
View file @
ffa2f18a
...
@@ -61,4 +61,4 @@ class ThreadSpecificStorageTest : public partest::TestCase {
...
@@ -61,4 +61,4 @@ class ThreadSpecificStorageTest : public partest::TestCase {
#endif // BASE_C_TEST_THREAD_SPECIFIC_STORAGE_TEST_H_
#endif
// BASE_C_TEST_THREAD_SPECIFIC_STORAGE_TEST_H_
base_c/test/thread_test.h
View file @
ffa2f18a
...
@@ -66,4 +66,4 @@ int ThreadStartFunction(void* arg);
...
@@ -66,4 +66,4 @@ int ThreadStartFunction(void* arg);
}
// namespace base
}
// namespace base
}
// namespace embb
}
// namespace embb
#endif // BASE_C_TEST_THREAD_TEST_H_
#endif
// BASE_C_TEST_THREAD_TEST_H_
base_c/test/time_test.h
View file @
ffa2f18a
...
@@ -53,4 +53,4 @@ class TimeTest : public partest::TestCase {
...
@@ -53,4 +53,4 @@ class TimeTest : public partest::TestCase {
#endif // BASE_C_TEST_TIME_TEST_H_
#endif
// BASE_C_TEST_TIME_TEST_H_
base_cpp/include/embb/base/core_set.h
View file @
ffa2f18a
...
@@ -201,4 +201,4 @@ class CoreSet {
...
@@ -201,4 +201,4 @@ class CoreSet {
#endif // EMBB_BASE_CORE_SET_H_
#endif
// EMBB_BASE_CORE_SET_H_
base_cpp/include/embb/base/duration.h
View file @
ffa2f18a
...
@@ -522,4 +522,4 @@ class Nanoseconds : public Tick {
...
@@ -522,4 +522,4 @@ class Nanoseconds : public Tick {
#include <embb/base/internal/duration-inl.h>
#include <embb/base/internal/duration-inl.h>
#endif // EMBB_BASE_DURATION_H_
#endif
// EMBB_BASE_DURATION_H_
base_cpp/include/embb/base/exceptions.h
View file @
ffa2f18a
...
@@ -175,16 +175,6 @@ class Exception : public std::exception {
...
@@ -175,16 +175,6 @@ class Exception : public std::exception {
}
}
/**
/**
* Returns the error message.
* This is here for compatibility with std::exception.
*
* \return Pointer to error message
*/
virtual
const
char
*
what
()
const
throw
()
{
return
What
();
}
/**
* Returns an integer code representing the exception.
* Returns an integer code representing the exception.
*
*
* \return %Exception code
* \return %Exception code
...
@@ -286,4 +276,4 @@ class ErrorException : public Exception {
...
@@ -286,4 +276,4 @@ class ErrorException : public Exception {
}
// namespace base
}
// namespace base
}
// namespace embb
}
// namespace embb
#endif // EMBB_BASE_EXCEPTIONS_H_
#endif
// EMBB_BASE_EXCEPTIONS_H_
base_cpp/include/embb/base/internal/duration-inl.h
View file @
ffa2f18a
...
@@ -112,4 +112,4 @@ Duration<Tick>::Duration(const embb_duration_t& duration) : rep_() {
...
@@ -112,4 +112,4 @@ Duration<Tick>::Duration(const embb_duration_t& duration) : rep_() {
}
// namespace base
}
// namespace base
}
// namespace embb
}
// namespace embb
#endif // EMBB_BASE_INTERNAL_DURATION_INL_H_
#endif
// EMBB_BASE_INTERNAL_DURATION_INL_H_
base_cpp/include/embb/base/internal/mutex-inl.h
View file @
ffa2f18a
...
@@ -116,4 +116,4 @@ bool UniqueLock<Mutex>::OwnsLock() const {
...
@@ -116,4 +116,4 @@ bool UniqueLock<Mutex>::OwnsLock() const {
}
// namespace base
}
// namespace base
}
// namespace embb
}
// namespace embb
#endif // EMBB_BASE_INTERNAL_MUTEX_INL_H_
#endif
// EMBB_BASE_INTERNAL_MUTEX_INL_H_
base_cpp/include/embb/base/internal/thread-inl.h
View file @
ffa2f18a
...
@@ -107,4 +107,4 @@ std::basic_ostream<CharT, Traits>&
...
@@ -107,4 +107,4 @@ std::basic_ostream<CharT, Traits>&
}
// namespace base
}
// namespace base
}
// namespace embb
}
// namespace embb
#endif // EMBB_BASE_INTERNAL_THREAD_INL_H_
#endif
// EMBB_BASE_INTERNAL_THREAD_INL_H_
base_cpp/include/embb/base/internal/thread_closures.h
View file @
ffa2f18a
...
@@ -36,8 +36,8 @@ namespace internal {
...
@@ -36,8 +36,8 @@ namespace internal {
/**
/**
* Thread closure for thread start function with no arguments.
* Thread closure for thread start function with no arguments.
*
*
* Provides a thread start function
calling a callable entity such as a function
* Provides a thread start function
from which a priorly stored function object
*
pointer or functor
.
*
is called
.
*/
*/
template
<
typename
Function
>
template
<
typename
Function
>
struct
ThreadClosure
{
struct
ThreadClosure
{
...
@@ -56,8 +56,8 @@ struct ThreadClosure {
...
@@ -56,8 +56,8 @@ struct ThreadClosure {
/**
/**
* Thread closure for thread start function with one argument.
* Thread closure for thread start function with one argument.
*
*
* Provides a thread start function
calling a callable entity such as a function
* Provides a thread start function
from which a priorly stored function object
*
pointer or functor
.
*
is called
.
*/
*/
template
<
typename
Function
,
typename
Arg1
>
template
<
typename
Function
,
typename
Arg1
>
struct
ThreadClosureArg1
{
struct
ThreadClosureArg1
{
...
@@ -78,8 +78,8 @@ struct ThreadClosureArg1 {
...
@@ -78,8 +78,8 @@ struct ThreadClosureArg1 {
/**
/**
* Thread closure for thread start function with two arguments.
* Thread closure for thread start function with two arguments.
*
*
* Provides a thread start function
calling a callable entity such as a function
* Provides a thread start function
from which a priorly stored function object
*
pointer or functor
.
*
is called
.
*/
*/
template
<
typename
Function
,
typename
Arg1
,
typename
Arg2
>
template
<
typename
Function
,
typename
Arg1
,
typename
Arg2
>
struct
ThreadClosureArg2
{
struct
ThreadClosureArg2
{
...
@@ -103,4 +103,4 @@ struct ThreadClosureArg2 {
...
@@ -103,4 +103,4 @@ struct ThreadClosureArg2 {
}
// namespace base
}
// namespace base
}
// namespace embb
}
// namespace embb
#endif // EMBB_BASE_INTERNAL_THREAD_CLOSURES_H_
#endif
// EMBB_BASE_INTERNAL_THREAD_CLOSURES_H_
base_cpp/include/embb/base/internal/thread_specific_storage-inl.h
View file @
ffa2f18a
...
@@ -149,4 +149,4 @@ void ThreadSpecificStorage<Type>::Prepare() {
...
@@ -149,4 +149,4 @@ void ThreadSpecificStorage<Type>::Prepare() {
}
// namespace base
}
// namespace base
}
// namespace embb
}
// namespace embb
#endif // EMBB_BASE_INTERNAL_THREAD_SPECIFIC_STORAGE_INL_H_
#endif
// EMBB_BASE_INTERNAL_THREAD_SPECIFIC_STORAGE_INL_H_
base_cpp/include/embb/base/thread.h
View file @
ffa2f18a
...
@@ -154,12 +154,12 @@ class Thread {
...
@@ -154,12 +154,12 @@ class Thread {
* \memory A small constant amount of memory to store the function. This
* \memory A small constant amount of memory to store the function. This
* memory is freed the thread is joined.
* memory is freed the thread is joined.
* \notthreadsafe
* \notthreadsafe
* \tparam Function
Type of callabl
e
* \tparam Function
Function object typ
e
*/
*/
template
<
typename
Function
>
template
<
typename
Function
>
explicit
Thread
(
explicit
Thread
(
Function
function
Function
function
/**< [IN] C
allable (without arguments, must be copyable)
*/
/**< [IN] C
opyable function object, callable without arguments
*/
);
);
/**
/**
...
@@ -174,14 +174,14 @@ class Thread {
...
@@ -174,14 +174,14 @@ class Thread {
* \memory A small constant amount of memory to store the function. This
* \memory A small constant amount of memory to store the function. This
* memory is freed the thread is joined.
* memory is freed the thread is joined.
* \notthreadsafe
* \notthreadsafe
* \tparam Function
Type of callabl
e
* \tparam Function
Function object typ
e
*/
*/
template
<
typename
Function
>
template
<
typename
Function
>
explicit
Thread
(
explicit
Thread
(
CoreSet
&
core_set
,
CoreSet
&
core_set
,
/**< [IN] Set of cores on which the thread shall be executed. */
/**< [IN] Set of cores on which the thread shall be executed. */
Function
function
Function
function
/**< [IN] C
allable (without arguments, must be copyable)
*/
/**< [IN] C
opyable function object, callable without arguments
*/
);
);
/**
/**
...
@@ -196,13 +196,13 @@ class Thread {
...
@@ -196,13 +196,13 @@ class Thread {
* \memory A small constant amount of memory to store the function. This
* \memory A small constant amount of memory to store the function. This
* memory is freed the thread is joined.
* memory is freed the thread is joined.
* \notthreadsafe
* \notthreadsafe
* \tparam Function
Type of callabl
e
* \tparam Function
Function object typ
e
* \tparam Argument Type of argument
* \tparam Argument Type of argument
*/
*/
template
<
typename
Function
,
typename
Arg
>
template
<
typename
Function
,
typename
Arg
>
Thread
(
Thread
(
Function
function
,
Function
function
,
/**< [IN] C
allable (with one argument, must be copyable)
*/
/**< [IN] C
opyable function object, callable with one argument
*/
Arg
arg
Arg
arg
/**< [IN] Argument for function (must be copyable) */
/**< [IN] Argument for function (must be copyable) */
);
);
...
@@ -219,14 +219,14 @@ class Thread {
...
@@ -219,14 +219,14 @@ class Thread {
* \memory A small constant amount of memory to store the function. This
* \memory A small constant amount of memory to store the function. This
* memory is freed the thread is joined.
* memory is freed the thread is joined.
* \notthreadsafe
* \notthreadsafe
* \tparam Function
Type of callabl
e
* \tparam Function
Function object typ
e
* \tparam Arg1 Type of first argument
* \tparam Arg1 Type of first argument
* \tparam Arg2 Type of second argument
* \tparam Arg2 Type of second argument
*/
*/
template
<
typename
Function
,
typename
Arg1
,
typename
Arg2
>
template
<
typename
Function
,
typename
Arg1
,
typename
Arg2
>
Thread
(
Thread
(
Function
function
,
Function
function
,
/**< [IN] C
allable (with two arguments, must be copyable)
*/
/**< [IN] C
opyable function object, callable with two arguments
*/
Arg1
arg1
,
Arg1
arg1
,
/**< [IN] First argument for function (must be copyable) */
/**< [IN] First argument for function (must be copyable) */
Arg2
arg2
Arg2
arg2
...
...
base_cpp/include/embb/base/thread_specific_storage.h
View file @
ffa2f18a
...
@@ -35,12 +35,10 @@ namespace embb {
...
@@ -35,12 +35,10 @@ namespace embb {
namespace
base
{
namespace
base
{
namespace
test
{
namespace
test
{
/**
/**
* Forward declaration for friending.
* Forward declaration for friending.
*/
*/
class
ThreadSpecificStorageTest
;
class
ThreadSpecificStorageTest
;
}
}
/**
/**
...
@@ -178,4 +176,4 @@ class ThreadSpecificStorage {
...
@@ -178,4 +176,4 @@ class ThreadSpecificStorage {
#include <embb/base/internal/thread_specific_storage-inl.h>
#include <embb/base/internal/thread_specific_storage-inl.h>
#endif // EMBB_BASE_THREAD_SPECIFIC_STORAGE_H_
#endif
// EMBB_BASE_THREAD_SPECIFIC_STORAGE_H_
base_cpp/include/embb/base/time.h
View file @
ffa2f18a
...
@@ -78,4 +78,4 @@ class Time {
...
@@ -78,4 +78,4 @@ class Time {
}
// namespace base
}
// namespace base
}
// namespace embb
}
// namespace embb
#endif // EMBB_BASE_TIME_H_
#endif
// EMBB_BASE_TIME_H_
base_cpp/test/thread_test.h
View file @
ffa2f18a
...
@@ -43,8 +43,7 @@ class ThreadTest : public partest::TestCase {
...
@@ -43,8 +43,7 @@ class ThreadTest : public partest::TestCase {
/**
/**
* Adds test methods.
* Adds test methods.
*/
*/
ThreadTest
();
/**<
ThreadTest
();
number of threads concurrently running test methods */
private
:
private
:
/**
/**
...
...
dataflow_cpp/include/embb/dataflow/internal/inputs.h
View file @
ffa2f18a
...
@@ -89,7 +89,7 @@ class Inputs<Slices, T1, embb::base::internal::Nil, embb::base::internal::Nil,
...
@@ -89,7 +89,7 @@ class Inputs<Slices, T1, embb::base::internal::Nil, embb::base::internal::Nil,
const
int
idx
=
clock
%
Slices
;
const
int
idx
=
clock
%
Slices
;
if
(
count_
[
idx
]
==
0
)
{
if
(
count_
[
idx
]
==
0
)
{
EMBB_THROW
(
embb
::
base
::
ErrorException
,
EMBB_THROW
(
embb
::
base
::
ErrorException
,
"All inputs already fired for this clock."
)
"All inputs already fired for this clock."
)
;
}
}
if
(
--
count_
[
idx
]
==
0
)
{
if
(
--
count_
[
idx
]
==
0
)
{
count_
[
idx
]
=
1
;
count_
[
idx
]
=
1
;
...
@@ -135,7 +135,7 @@ class Inputs<Slices, T1, T2, embb::base::internal::Nil,
...
@@ -135,7 +135,7 @@ class Inputs<Slices, T1, T2, embb::base::internal::Nil,
const
int
idx
=
clock
%
Slices
;
const
int
idx
=
clock
%
Slices
;
if
(
count_
[
idx
]
==
0
)
{
if
(
count_
[
idx
]
==
0
)
{
EMBB_THROW
(
embb
::
base
::
ErrorException
,
EMBB_THROW
(
embb
::
base
::
ErrorException
,
"All inputs already fired for this clock."
)
"All inputs already fired for this clock."
)
;
}
}
if
(
--
count_
[
idx
]
==
0
)
{
if
(
--
count_
[
idx
]
==
0
)
{
count_
[
idx
]
=
2
;
count_
[
idx
]
=
2
;
...
@@ -185,7 +185,7 @@ class Inputs<Slices, T1, T2, T3, embb::base::internal::Nil,
...
@@ -185,7 +185,7 @@ class Inputs<Slices, T1, T2, T3, embb::base::internal::Nil,
const
int
idx
=
clock
%
Slices
;
const
int
idx
=
clock
%
Slices
;
if
(
count_
[
idx
]
==
0
)
{
if
(
count_
[
idx
]
==
0
)
{
EMBB_THROW
(
embb
::
base
::
ErrorException
,
EMBB_THROW
(
embb
::
base
::
ErrorException
,
"All inputs already fired for this clock."
)
"All inputs already fired for this clock."
)
;
}
}
if
(
--
count_
[
idx
]
==
0
)
{
if
(
--
count_
[
idx
]
==
0
)
{
count_
[
idx
]
=
3
;
count_
[
idx
]
=
3
;
...
@@ -238,7 +238,7 @@ class Inputs<Slices, T1, T2, T3, T4, embb::base::internal::Nil>
...
@@ -238,7 +238,7 @@ class Inputs<Slices, T1, T2, T3, T4, embb::base::internal::Nil>
const
int
idx
=
clock
%
Slices
;
const
int
idx
=
clock
%
Slices
;
if
(
count_
[
idx
]
==
0
)
{
if
(
count_
[
idx
]
==
0
)
{
EMBB_THROW
(
embb
::
base
::
ErrorException
,
EMBB_THROW
(
embb
::
base
::
ErrorException
,
"All inputs already fired for this clock."
)
"All inputs already fired for this clock."
)
;
}
}
if
(
--
count_
[
idx
]
==
0
)
{
if
(
--
count_
[
idx
]
==
0
)
{
count_
[
idx
]
=
4
;
count_
[
idx
]
=
4
;
...
@@ -296,7 +296,7 @@ class Inputs
...
@@ -296,7 +296,7 @@ class Inputs
const
int
idx
=
clock
%
Slices
;
const
int
idx
=
clock
%
Slices
;
if
(
count_
[
idx
]
==
0
)
{
if
(
count_
[
idx
]
==
0
)
{
EMBB_THROW
(
embb
::
base
::
ErrorException
,
EMBB_THROW
(
embb
::
base
::
ErrorException
,
"All inputs already fired for this clock."
)
"All inputs already fired for this clock."
)
;
}
}
if
(
--
count_
[
idx
]
==
0
)
{
if
(
--
count_
[
idx
]
==
0
)
{
count_
[
idx
]
=
5
;
count_
[
idx
]
=
5
;
...
...
mtapi_c/include/embb/mtapi/c/mtapi.h
View file @
ffa2f18a
...
@@ -68,7 +68,7 @@
...
@@ -68,7 +68,7 @@
* </tr>
* </tr>
* <tr>
* <tr>
* <td>Action Function</td>
* <td>Action Function</td>
* <td>The
callable, an
executable function of an action, invoked by the
* <td>The executable function of an action, invoked by the
* MTAPI runtime when a task is started.</td>
* MTAPI runtime when a task is started.</td>
* </tr>
* </tr>
* <tr>
* <tr>
...
...
mtapi_cpp/include/embb/mtapi/action.h
View file @
ffa2f18a
...
@@ -51,13 +51,13 @@ class Action {
...
@@ -51,13 +51,13 @@ class Action {
}
}
/**
/**
* Constructs an Action from any entity that provides an
* Constructs an Action from a function object.
* operator() (TaskContext &).
*
* \tparam Function Function object
*/
*/
template
<
typename
Function
>
template
<
typename
Function
>
Action
(
Action
(
Function
func
/**< [in] Anything that provides an
Function
func
/**< [in] Function object */
operator() (TaskContext &). */
)
)
:
function_
(
func
)
:
function_
(
func
)
,
execution_policy_
()
{
,
execution_policy_
()
{
...
@@ -65,13 +65,13 @@ class Action {
...
@@ -65,13 +65,13 @@ class Action {
}
}
/**
/**
* Constructs an Action from any entity that provides an
* Constructs an Action from a function object and an Affinity.
* operator() (TaskContext &) and an Affinity.
*
* \tparam Function Function object
*/
*/
template
<
typename
Function
>
template
<
typename
Function
>
Action
(
Action
(
Function
func
,
/**< [in] Anything that provides an
Function
func
,
/**< [in] Function object */
operator() (TaskContext &). */
ExecutionPolicy
execution_policy
/**< [in] Execution policy */
ExecutionPolicy
execution_policy
/**< [in] Execution policy */
)
)
:
function_
(
func
)
:
function_
(
func
)
...
...
mtapi_cpp/include/embb/mtapi/execution_policy.h
View file @
ffa2f18a
...
@@ -106,6 +106,13 @@ class ExecutionPolicy{
...
@@ -106,6 +106,13 @@ class ExecutionPolicy{
);
);
/**
/**
* Returns the number of cores the policy is affine to.
*
* \return the number of cores
*/
unsigned
int
GetCoreCount
()
const
;
/**
* Returns the affinity
* Returns the affinity
*
*
* \return the affinity
* \return the affinity
...
...
mtapi_cpp/include/embb/mtapi/node.h
View file @
ffa2f18a
...
@@ -129,6 +129,15 @@ class Node {
...
@@ -129,6 +129,15 @@ class Node {
}
}
/**
/**
* Returns the number of worker threads.
* \return The number of worker threads.
* \waitfree
*/
mtapi_uint_t
GetWorkerThreadCount
()
const
{
return
worker_thread_count_
;
}
/**
* Creates a Group to launch \link Task Tasks \endlink in.
* Creates a Group to launch \link Task Tasks \endlink in.
* \return A reference to the created Group
* \return A reference to the created Group
* \throws ErrorException if the Group object could not be constructed.
* \throws ErrorException if the Group object could not be constructed.
...
@@ -210,6 +219,7 @@ class Node {
...
@@ -210,6 +219,7 @@ class Node {
mtapi_task_context_t
*
context
);
mtapi_task_context_t
*
context
);
mtapi_uint_t
core_count_
;
mtapi_uint_t
core_count_
;
mtapi_uint_t
worker_thread_count_
;
mtapi_action_hndl_t
action_handle_
;
mtapi_action_hndl_t
action_handle_
;
std
::
list
<
Queue
*>
queues_
;
std
::
list
<
Queue
*>
queues_
;
std
::
list
<
Group
*>
groups_
;
std
::
list
<
Group
*>
groups_
;
...
...
mtapi_cpp/src/execution_policy.cc
View file @
ffa2f18a
...
@@ -27,6 +27,7 @@
...
@@ -27,6 +27,7 @@
#include <embb/mtapi/execution_policy.h>
#include <embb/mtapi/execution_policy.h>
#include <embb/mtapi/mtapi.h>
#include <embb/mtapi/mtapi.h>
#include <embb/base/exceptions.h>
#include <embb/base/exceptions.h>
#include <embb/base/c/internal/bitset.h>
#include <cassert>
#include <cassert>
namespace
embb
{
namespace
embb
{
...
@@ -105,6 +106,10 @@ bool ExecutionPolicy::IsSetWorker(mtapi_uint_t worker) {
...
@@ -105,6 +106,10 @@ bool ExecutionPolicy::IsSetWorker(mtapi_uint_t worker) {
return
MTAPI_TRUE
==
aff
;
return
MTAPI_TRUE
==
aff
;
}
}
unsigned
int
ExecutionPolicy
::
GetCoreCount
()
const
{
return
embb_bitset_count
(
&
affinity_
);
}
const
mtapi_affinity_t
&
ExecutionPolicy
::
GetAffinity
()
const
{
const
mtapi_affinity_t
&
ExecutionPolicy
::
GetAffinity
()
const
{
return
affinity_
;
return
affinity_
;
}
}
...
...
mtapi_cpp/src/node.cc
View file @
ffa2f18a
...
@@ -75,6 +75,7 @@ Node::Node(
...
@@ -75,6 +75,7 @@ Node::Node(
"mtapi::Node could not initialize mtapi"
);
"mtapi::Node could not initialize mtapi"
);
}
}
core_count_
=
info
.
hardware_concurrency
;
core_count_
=
info
.
hardware_concurrency
;
worker_thread_count_
=
embb_core_set_count
(
&
attr
->
core_affinity
);
action_handle_
=
mtapi_action_create
(
MTAPI_CPP_TASK_JOB
,
action_func
,
action_handle_
=
mtapi_action_create
(
MTAPI_CPP_TASK_JOB
,
action_func
,
MTAPI_NULL
,
0
,
MTAPI_NULL
,
&
status
);
MTAPI_NULL
,
0
,
MTAPI_NULL
,
&
status
);
if
(
MTAPI_SUCCESS
!=
status
)
{
if
(
MTAPI_SUCCESS
!=
status
)
{
...
...
partest.tar
100644 → 100755
View file @
ffa2f18a
No preview for this file type
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