Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
las3_pub
/
predictable_parallel_patterns
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
6d262a62
authored
Jul 29, 2019
by
FritzFlorian
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add unversioned files.
parent
6ce5e247
Pipeline
#1285
passed with stages
in 3 minutes 54 seconds
Changes
2
Pipelines
1
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
216 additions
and
0 deletions
+216
-0
lib/pls/include/pls/dataflow/internal/function_node_impl.h
+85
-0
lib/pls/include/pls/dataflow/internal/graph_impl.h
+131
-0
No files found.
lib/pls/include/pls/dataflow/internal/function_node_impl.h
0 → 100644
View file @
6d262a62
#ifndef PLS_DATAFLOW_INTERNAL_FUNCTION_NODE_IMPL_H_
#define PLS_DATAFLOW_INTERNAL_FUNCTION_NODE_IMPL_H_
namespace
pls
{
namespace
dataflow
{
namespace
internal
{
template
<
typename
I0
,
typename
...
I
,
typename
O0
,
typename
...
O
,
typename
F
>
template
<
int
POS
,
typename
T
>
void
function_node
<
pls
::
dataflow
::
inputs
<
I0
,
I
...
>
,
pls
::
dataflow
::
outputs
<
O0
,
O
...
>
,
F
>::
token_pushed
(
token
<
T
>
token
)
{
auto
current_memory
=
get_invocation
<
invocation_memory
>
(
token
.
invocation
());
std
::
get
<
POS
>
(
current_memory
->
input_buffer_
)
=
token
;
auto
remaining_inputs
=
--
(
current_memory
->
inputs_missing_
);
if
(
remaining_inputs
==
0
)
{
execute_function
(
current_memory
,
token
.
invocation
());
current_memory
->
inputs_missing_
=
num_in_ports
;
}
}
//////////////////////////////////////////////////////////////////
// Helpers for actually calling the work lambda
//////////////////////////////////////////////////////////////////
template
<
typename
I0
,
typename
...
I
,
typename
O0
,
typename
...
O
,
typename
F
>
void
function_node
<
pls
::
dataflow
::
inputs
<
I0
,
I
...
>
,
pls
::
dataflow
::
outputs
<
O0
,
O
...
>
,
F
>::
execute_function
(
invocation_memory
*
invocation_memory
,
invocation_info
invocation_info
)
{
auto
lambda
=
[
&
]()
{
input_tuple
&
inputs
=
invocation_memory
->
input_buffer_
;
output_tuple
outputs
{};
execute_function_internal
(
inputs
,
typename
sequence_gen
<
1
+
sizeof
...(
I
)
>::
type
(),
outputs
,
typename
sequence_gen
<
1
+
sizeof
...(
O
)
>::
type
(),
invocation_info
);
};
// TODO: maybe replace this with 'continuation' style invocation
pls
::
scheduler
::
spawn_child_and_wait
<
pls
::
lambda_task_by_reference
<
decltype
(
lambda
)
>>
(
lambda
);
}
template
<
typename
I0
,
typename
...
I
,
typename
O0
,
typename
...
O
,
typename
F
>
template
<
int
N
,
typename
...
OT
>
struct
function_node
<
pls
::
dataflow
::
inputs
<
I0
,
I
...
>
,
pls
::
dataflow
::
outputs
<
O0
,
O
...
>
,
F
>::
propagate_output
{
propagate_output
(
multi_out_port_type
&
,
output_tuple
&
)
{}
void
propagate
()
{}
};
template
<
typename
I0
,
typename
...
I
,
typename
O0
,
typename
...
O
,
typename
F
>
template
<
int
N
,
typename
OT1
,
typename
...
OT
>
struct
function_node
<
pls
::
dataflow
::
inputs
<
I0
,
I
...
>
,
pls
::
dataflow
::
outputs
<
O0
,
O
...
>
,
F
>::
propagate_output
<
N
,
OT1
,
OT
...
>
{
multi_out_port_type
&
out_port_
;
output_tuple
&
output_tuple_
;
propagate_output
(
multi_out_port_type
&
out_port
,
output_tuple
&
output_tuple
)
:
out_port_
{
out_port
},
output_tuple_
{
output_tuple
}
{}
void
propagate
()
{
out_port_
.
template
get
<
N
>
().
push_token
(
std
::
get
<
N
>
(
output_tuple_
));
propagate_output
<
N
+
1
,
OT
...
>
{
out_port_
,
output_tuple_
}.
propagate
();
}
};
template
<
typename
I0
,
typename
...
I
,
typename
O0
,
typename
...
O
,
typename
F
>
template
<
typename
T
>
void
function_node
<
pls
::
dataflow
::
inputs
<
I0
,
I
...
>
,
pls
::
dataflow
::
outputs
<
O0
,
O
...
>
,
F
>::
set_invocation_info
(
token
<
T
>
&
token
,
invocation_info
invocation_info
)
{
token
.
set_invocation
(
invocation_info
);
}
template
<
typename
I0
,
typename
...
I
,
typename
O0
,
typename
...
O
,
typename
F
>
template
<
int
...
IS
,
int
...
OS
>
void
function_node
<
pls
::
dataflow
::
inputs
<
I0
,
I
...
>
,
pls
::
dataflow
::
outputs
<
O0
,
O
...
>
,
F
>::
execute_function_internal
(
input_tuple
&
inputs
,
sequence
<
IS
...
>
,
output_tuple
&
outputs
,
sequence
<
OS
...
>
,
invocation_info
invocation_info
)
{
set_invocation_info
(
std
::
get
<
OS
>
(
outputs
)...,
invocation_info
);
function_
(
std
::
get
<
IS
>
(
inputs
).
value
()...,
std
::
get
<
OS
>
(
outputs
).
value
()...);
propagate_output
<
0
,
O0
,
O
...
>
{
out_port_
,
outputs
}.
propagate
();
}
}
}
}
#endif //PLS_DATAFLOW_INTERNAL_FUNCTION_NODE_IMPL_H_
lib/pls/include/pls/dataflow/internal/graph_impl.h
0 → 100644
View file @
6d262a62
#ifndef PLS_DATAFLOW_INTERNAL_GRAPH_IMPL_H_
#define PLS_DATAFLOW_INTERNAL_GRAPH_IMPL_H_
namespace
pls
{
namespace
dataflow
{
namespace
internal
{
template
<
typename
I0
,
typename
...
I
,
typename
O0
,
typename
...
O
>
template
<
int
POS
,
typename
T
>
void
graph
<
pls
::
dataflow
::
inputs
<
I0
,
I
...
>
,
pls
::
dataflow
::
outputs
<
O0
,
O
...
>>::
token_pushed
(
token
<
T
>
token
)
{
auto
invocation
=
get_invocation
<
invocation_memory
>
(
token
.
invocation
());
std
::
get
<
POS
>
(
*
invocation
->
output_buffer_
)
=
token
.
value
();
}
template
<
typename
I0
,
typename
...
I
,
typename
O0
,
typename
...
O
>
void
graph
<
pls
::
dataflow
::
inputs
<
I0
,
I
...
>
,
pls
::
dataflow
::
outputs
<
O0
,
O
...
>>::
build
()
{
PLS_ASSERT
(
build_state_
==
build_state
::
fresh
,
"Must only build a dataflow graph once!"
)
PLS_ASSERT
(
is_fully_connected
(),
"Must fully connect all inputs/outputs inside a dataflow graph!"
)
build_state_
=
build_state
::
building
;
node_list_start_
=
node_list_current_
=
this
;
memory_index_
=
0
;
num_nodes_
=
1
;
for
(
int
i
=
0
;
i
<
num_in_ports
;
i
++
)
{
build_recursive
(
inputs_
.
next_node_at
(
i
));
}
build_state_
=
build_state
::
built
;
}
template
<
typename
I0
,
typename
...
I
,
typename
O0
,
typename
...
O
>
void
graph
<
pls
::
dataflow
::
inputs
<
I0
,
I
...
>
,
pls
::
dataflow
::
outputs
<
O0
,
O
...
>>::
build_recursive
(
node
*
node
)
{
if
(
node
->
build_state_
!=
build_state
::
fresh
)
{
return
;
// Already visited
}
node
->
build_state_
=
build_state
::
building
;
PLS_ASSERT
(
node
->
is_fully_connected
(),
"Must fully connect dataflow graph nodes!"
)
add_node
(
node
);
for
(
int
i
=
0
;
i
<
node
->
num_successors
();
i
++
)
{
build_recursive
(
node
->
successor_at
(
i
));
}
node
->
build_state_
=
build_state
::
built
;
}
template
<
typename
I0
,
typename
...
I
,
typename
O0
,
typename
...
O
>
void
graph
<
pls
::
dataflow
::
inputs
<
I0
,
I
...
>
,
pls
::
dataflow
::
outputs
<
O0
,
O
...
>>::
add_node
(
node
*
new_node
)
{
new_node
->
memory_index_
=
num_nodes_
++
;
if
(
node_list_current_
==
nullptr
)
{
node_list_current_
=
new_node
;
node_list_start_
=
new_node
;
}
else
{
node_list_current_
->
direct_successor_
=
new_node
;
node_list_current_
=
new_node
;
}
}
template
<
typename
I0
,
typename
...
I
,
typename
O0
,
typename
...
O
>
template
<
int
N
,
typename
...
IT
>
struct
graph
<
pls
::
dataflow
::
inputs
<
I0
,
I
...
>
,
pls
::
dataflow
::
outputs
<
O0
,
O
...
>>::
feed_inputs
{
feed_inputs
(
inputs_type
&
,
value_input_tuple
&
,
invocation_info
&
)
{}
void
run
()
{}
};
template
<
typename
I0
,
typename
...
I
,
typename
O0
,
typename
...
O
>
template
<
int
N
,
typename
IT1
,
typename
...
IT
>
struct
graph
<
pls
::
dataflow
::
inputs
<
I0
,
I
...
>
,
pls
::
dataflow
::
outputs
<
O0
,
O
...
>>::
feed_inputs
<
N
,
IT1
,
IT
...
>
{
inputs_type
&
inputs_
;
value_input_tuple
&
input_values_
;
invocation_info
&
invocation_
;
feed_inputs
(
inputs_type
&
inputs
,
value_input_tuple
&
input_values
,
invocation_info
&
invocation
)
:
inputs_
{
inputs
},
input_values_
{
input_values
},
invocation_
{
invocation
}
{}
void
run
()
{
inputs_
.
template
get
<
N
>
().
push_token
(
token
<
IT1
>
{
std
::
get
<
N
>
(
input_values_
),
invocation_
});
feed_inputs
<
N
+
1
,
IT
...
>
{
inputs_
,
input_values_
,
invocation_
}.
run
();
}
};
template
<
typename
I0
,
typename
...
I
,
typename
O0
,
typename
...
O
>
class
graph
<
pls
::
dataflow
::
inputs
<
I0
,
I
...
>
,
pls
::
dataflow
::
outputs
<
O0
,
O
...
>>::
run_graph_task
:
public
pls
::
task
{
graph
*
self_
;
value_input_tuple
input_
;
value_output_tuple
*
output_
;
// Buffers for actual execution
invocation_info
invocation_
;
public
:
run_graph_task
(
graph
*
self
,
value_input_tuple
&
input
,
value_output_tuple
*
output
)
:
self_
{
self
},
input_
{
input
},
output_
{
output
},
invocation_
{
nullptr
}
{
void
**
buffers
;
buffers
=
reinterpret_cast
<
void
**>
(
allocate_memory
(
self_
->
num_nodes_
*
sizeof
(
void
*
)));
node
*
iterator
=
self_
->
node_list_start_
;
for
(
int
i
=
0
;
i
<
self_
->
num_nodes_
;
i
++
)
{
auto
required_size
=
iterator
->
instance_buffer_size
();
buffers
[
i
]
=
allocate_memory
(
required_size
);
iterator
->
init_instance_buffer
(
buffers
[
i
]);
iterator
=
iterator
->
direct_successor_
;
}
invocation_
=
invocation_info
{
buffers
};
self_
->
get_invocation
<
invocation_memory
>
(
invocation_
)
->
output_buffer_
=
output
;
}
void
execute_internal
()
override
{
feed_inputs
<
0
,
I0
,
I
...
>
{
self_
->
inputs_
,
input_
,
invocation_
}.
run
();
}
};
}
}
}
#endif //PLS_DATAFLOW_INTERNAL_GRAPH_IMPL_H_
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment