Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
T
thallium
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
2
Issues
2
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
sds
thallium
Commits
02c51546
Commit
02c51546
authored
Nov 27, 2017
by
Matthieu Dorier
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
done integrating serialization
parent
f1f532cf
Changes
9
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
229 additions
and
70 deletions
+229
-70
include/thallium/callable_remote_procedure.hpp
include/thallium/callable_remote_procedure.hpp
+11
-4
include/thallium/engine.hpp
include/thallium/engine.hpp
+37
-6
include/thallium/packed_response.hpp
include/thallium/packed_response.hpp
+50
-0
include/thallium/request.hpp
include/thallium/request.hpp
+10
-5
include/thallium/serialization/buffer_input_archive.hpp
include/thallium/serialization/buffer_input_archive.hpp
+7
-7
include/thallium/serialization/buffer_output_archive.hpp
include/thallium/serialization/buffer_output_archive.hpp
+7
-7
include/thallium/serialization/serialize.hpp
include/thallium/serialization/serialize.hpp
+20
-19
include/thallium/tuple_util.hpp
include/thallium/tuple_util.hpp
+57
-0
test/TestHelloWorld.cpp
test/TestHelloWorld.cpp
+30
-22
No files found.
include/thallium/callable_remote_procedure.hpp
View file @
02c51546
...
...
@@ -6,6 +6,8 @@
#include <utility>
#include <margo.h>
#include <thallium/buffer.hpp>
#include <thallium/packed_response.hpp>
#include <thallium/serialization/serialize.hpp>
#include <thallium/serialization/stl/vector.hpp>
#include <thallium/serialization/buffer_output_archive.hpp>
...
...
@@ -28,10 +30,10 @@ private:
auto
forward
(
const
buffer
&
buf
)
const
{
margo_forward
(
m_handle
,
const_cast
<
void
*>
(
static_cast
<
const
void
*>
(
&
buf
)));
buffer
output
;
if
(
m_ignore_response
)
return
output
;
if
(
m_ignore_response
)
return
packed_response
(
std
::
move
(
output
))
;
margo_get_output
(
m_handle
,
&
output
);
margo_free_output
(
m_handle
,
&
output
);
// won't do anything on a buffer type
return
output
;
return
packed_response
(
std
::
move
(
output
))
;
}
public:
...
...
@@ -83,10 +85,15 @@ public:
template
<
typename
...
T
>
auto
operator
()(
T
&&
...
t
)
const
{
buffer
b
;
buffer_output_archive
arch
(
b
);
serialize_many
(
arch
,
std
::
forward
<
T
>
(
t
)...);
buffer_output_archive
arch
(
b
);
serialize_many
(
arch
,
std
::
forward
<
T
>
(
t
)...);
return
forward
(
b
);
}
auto
operator
()()
const
{
buffer
b
;
return
forward
(
b
);
}
};
}
...
...
include/thallium/engine.hpp
View file @
02c51546
...
...
@@ -6,6 +6,7 @@
#include <functional>
#include <unordered_map>
#include <margo.h>
#include <thallium/tuple_util.hpp>
#include <thallium/function_cast.hpp>
#include <thallium/buffer.hpp>
#include <thallium/request.hpp>
...
...
@@ -23,8 +24,11 @@ class engine {
private:
using
rpc_t
=
std
::
function
<
void
(
const
request
&
,
const
buffer
&
)
>
;
margo_instance_id
m_mid
;
bool
m_is_server
;
std
::
unordered_map
<
hg_id_t
,
rpc_t
>
m_rpcs
;
template
<
typename
F
,
bool
disable_response
>
static
void
rpc_handler_ult
(
hg_handle_t
handle
)
{
...
...
@@ -97,8 +101,12 @@ public:
remote_procedure
define
(
const
std
::
string
&
name
);
template
<
typename
F
>
remote_procedure
define
(
const
std
::
string
&
name
,
F
&&
fun
);
template
<
typename
...
Args
>
remote_procedure
define
(
const
std
::
string
&
name
,
const
std
::
function
<
void
(
const
request
&
,
Args
...)
>&
fun
);
template
<
typename
...
Args
>
remote_procedure
define
(
const
std
::
string
&
name
,
void
(
*
f
)(
const
request
&
,
Args
...));
endpoint
lookup
(
const
std
::
string
&
address
)
const
;
...
...
@@ -109,21 +117,44 @@ public:
#include <thallium/remote_procedure.hpp>
#include <thallium/proc_buffer.hpp>
#include <thallium/serialization/stl/tuple.hpp>
#include <thallium/serialization/buffer_input_archive.hpp>
#include <thallium/serialization/buffer_output_archive.hpp>
namespace
thallium
{
template
<
typename
F
>
remote_procedure
engine
::
define
(
const
std
::
string
&
name
,
F
&&
fun
)
{
template
<
typename
...
Args
>
remote_procedure
engine
::
define
(
const
std
::
string
&
name
,
const
std
::
function
<
void
(
const
request
&
,
Args
...)
>&
fun
)
{
// TODO throw an exception if the following call fails
hg_id_t
id
=
margo_register_name
(
m_mid
,
name
.
c_str
(),
process_buffer
,
process_buffer
,
rpc_callback
<
decltype
(
fun
),
false
>
);
margo_register_data
(
m_mid
,
id
,
void_cast
(
&
fun
),
nullptr
);
rpc_callback
<
rpc_t
,
false
>
);
m_rpcs
[
id
]
=
[
fun
](
const
request
&
r
,
const
buffer
&
b
)
{
std
::
function
<
void
(
Args
...)
>
l
=
[
&
fun
,
&
r
](
Args
&&
...
args
)
{
fun
(
r
,
std
::
forward
<
Args
>
(
args
)...);
};
std
::
tuple
<
std
::
decay_t
<
Args
>
...
>
iargs
;
if
(
sizeof
...(
Args
)
>
0
)
{
buffer_input_archive
iarch
(
b
);
iarch
&
iargs
;
}
apply_function_to_tuple
(
l
,
iargs
);
};
margo_register_data
(
m_mid
,
id
,
void_cast
(
&
m_rpcs
[
id
]),
nullptr
);
return
remote_procedure
(
*
this
,
id
);
}
template
<
typename
...
Args
>
remote_procedure
engine
::
define
(
const
std
::
string
&
name
,
void
(
*
f
)(
const
request
&
,
Args
...))
{
return
define
(
name
,
std
::
function
<
void
(
const
request
&
,
Args
...)
>
(
f
));
}
}
#endif
include/thallium/packed_response.hpp
0 → 100644
View file @
02c51546
#ifndef __THALLIUM_PACKED_RESPONSE_HPP
#define __THALLIUM_PACKED_RESPONSE_HPP
#include <thallium/buffer.hpp>
#include <thallium/serialization/serialize.hpp>
#include <thallium/serialization/buffer_input_archive.hpp>
namespace
thallium
{
class
callable_remote_procedure
;
class
packed_response
{
friend
class
callable_remote_procedure
;
private:
buffer
m_buffer
;
packed_response
(
buffer
&&
b
)
:
m_buffer
(
std
::
move
(
b
))
{}
public:
template
<
typename
T
>
T
as
()
const
{
T
t
;
buffer_input_archive
iarch
(
m_buffer
);
iarch
&
t
;
return
t
;
}
template
<
typename
T1
,
typename
T2
,
typename
...
Tn
>
auto
as
()
const
{
std
::
tuple
<
std
::
decay_t
<
T1
>
,
std
::
decay_t
<
T2
>
,
std
::
decay_t
<
Tn
>
...
>
t
;
buffer_input_archive
iarch
(
m_buffer
);
iarch
&
t
;
return
t
;
}
template
<
typename
T
>
operator
T
()
const
{
return
as
<
T
>
();
}
};
}
#endif
include/thallium/request.hpp
View file @
02c51546
...
...
@@ -2,6 +2,8 @@
#define __THALLIUM_REQUEST_HPP
#include <margo.h>
#include <thallium/serialization/serialize.hpp>
#include <thallium/serialization/buffer_output_archive.hpp>
namespace
thallium
{
...
...
@@ -53,15 +55,17 @@ public:
margo_destroy
(
m_handle
);
}
template
<
typename
T
>
void
respond
(
T
&&
t
)
const
{
template
<
typename
...
T
>
void
respond
(
T
&&
...
t
)
const
{
if
(
m_disable_response
)
return
;
// XXX throwing an exception?
// TODO serialize
if
(
m_handle
!=
HG_HANDLE_NULL
)
{
margo_respond
(
m_handle
,
nullptr
);
buffer
b
;
buffer_output_archive
arch
(
b
);
serialize_many
(
arch
,
std
::
forward
<
T
>
(
t
)...);
margo_respond
(
m_handle
,
&
b
);
}
}
/*
void respond(const buffer& output) const {
if(m_disable_response) return; // XXX throwing an exception?
if(m_handle != HG_HANDLE_NULL) {
...
...
@@ -76,6 +80,7 @@ public:
void respond(buffer&& output) const {
respond((const buffer&)output);
}
*/
};
}
...
...
include/thallium/serialization/buffer_input_archive.hpp
View file @
02c51546
...
...
@@ -24,12 +24,12 @@ private:
std
::
size_t
pos
;
template
<
typename
T
,
bool
b
>
inline
void
read_impl
(
T
&
t
,
const
std
::
integral_constant
<
bool
,
b
>&
)
{
load
(
*
this
,
t
);
inline
void
read_impl
(
T
&
&
t
,
const
std
::
integral_constant
<
bool
,
b
>&
)
{
load
(
*
this
,
std
::
forward
<
T
>
(
t
)
);
}
template
<
typename
T
>
inline
void
read_impl
(
T
&
t
,
const
std
::
true_type
&
)
{
inline
void
read_impl
(
T
&
&
t
,
const
std
::
true_type
&
)
{
read
(
&
t
);
}
...
...
@@ -54,8 +54,8 @@ public:
* a load member function has been provided.
*/
template
<
typename
T
>
buffer_input_archive
&
operator
&
(
T
&
obj
)
{
read_impl
(
obj
,
std
::
is_arithmetic
<
T
>
());
buffer_input_archive
&
operator
&
(
T
&
&
obj
)
{
read_impl
(
std
::
forward
<
T
>
(
obj
),
std
::
is_arithmetic
<
std
::
decay_t
<
T
>
>
());
return
*
this
;
}
...
...
@@ -64,8 +64,8 @@ public:
* \see operator&
*/
template
<
typename
T
>
buffer_input_archive
&
operator
>>
(
T
&
obj
)
{
return
(
*
this
)
&
obj
;
buffer_input_archive
&
operator
>>
(
T
&
&
obj
)
{
return
(
*
this
)
&
std
::
forward
<
T
>
(
obj
)
;
}
/**
...
...
include/thallium/serialization/buffer_output_archive.hpp
View file @
02c51546
...
...
@@ -22,12 +22,12 @@ private:
std
::
size_t
pos
;
template
<
typename
T
,
bool
b
>
inline
void
write_impl
(
T
&
t
,
const
std
::
integral_constant
<
bool
,
b
>&
)
{
save
(
*
this
,
t
);
inline
void
write_impl
(
T
&
&
t
,
const
std
::
integral_constant
<
bool
,
b
>&
)
{
save
(
*
this
,
std
::
forward
<
T
>
(
t
)
);
}
template
<
typename
T
>
inline
void
write_impl
(
T
&
t
,
const
std
::
true_type
&
)
{
inline
void
write_impl
(
T
&
&
t
,
const
std
::
true_type
&
)
{
write
((
char
*
)
&
t
,
sizeof
(
T
));
}
...
...
@@ -54,8 +54,8 @@ public:
* a load member function has been provided.
*/
template
<
typename
T
>
buffer_output_archive
&
operator
&
(
T
&
obj
)
{
write_impl
(
obj
,
std
::
is_arithmetic
<
T
>
());
buffer_output_archive
&
operator
&
(
T
&
&
obj
)
{
write_impl
(
std
::
forward
<
T
>
(
obj
),
std
::
is_arithmetic
<
std
::
decay_t
<
T
>
>
());
return
*
this
;
}
...
...
@@ -64,8 +64,8 @@ public:
* \see operator&
*/
template
<
typename
T
>
buffer_output_archive
&
operator
<<
(
T
&
obj
)
{
return
(
*
this
)
&
obj
;
buffer_output_archive
&
operator
<<
(
T
&
&
obj
)
{
return
(
*
this
)
&
std
::
forward
<
T
>
(
obj
)
;
}
/**
...
...
include/thallium/serialization/serialize.hpp
View file @
02c51546
#ifndef SERIALIZE_H
#define SERIALIZE_H
#include <utility>
#include <type_traits>
namespace
thallium
{
...
...
@@ -97,14 +98,14 @@ struct serializer;
template
<
class
A
,
typename
T
>
struct
serializer
<
A
,
T
,
true
>
{
static
void
apply
(
A
&
ar
,
T
&
t
)
{
static
void
apply
(
A
&
ar
,
T
&
&
t
)
{
t
.
serialize
(
ar
);
}
};
template
<
class
A
,
typename
T
>
struct
serializer
<
A
,
T
,
false
>
{
static
void
apply
(
A
&
ar
,
T
&
t
)
{
static
void
apply
(
A
&
ar
,
T
&
&
t
)
{
static_assert
(
has_serialize_method
<
A
,
T
>::
value
,
"Undefined
\"
serialize
\"
member function"
);
}
...
...
@@ -114,8 +115,8 @@ struct serializer<A,T,false> {
* Generic serialize method calling apply on a serializer.
*/
template
<
class
A
,
typename
T
>
void
serialize
(
A
&
ar
,
T
&
t
)
{
serializer
<
A
,
T
,
has_serialize_method
<
A
,
T
>::
value
>::
apply
(
ar
,
t
);
void
serialize
(
A
&
ar
,
T
&
&
t
)
{
serializer
<
A
,
T
,
has_serialize_method
<
A
,
T
>::
value
>::
apply
(
ar
,
std
::
forward
<
T
>
(
t
)
);
}
/**
...
...
@@ -127,15 +128,15 @@ struct saver;
template
<
class
A
,
typename
T
>
struct
saver
<
A
,
T
,
true
>
{
static
void
apply
(
A
&
ar
,
T
&
t
)
{
static
void
apply
(
A
&
ar
,
T
&
&
t
)
{
t
.
save
(
ar
);
}
};
template
<
class
A
,
typename
T
>
struct
saver
<
A
,
T
,
false
>
{
static
void
apply
(
A
&
ar
,
T
&
t
)
{
serialize
(
ar
,
t
);
static
void
apply
(
A
&
ar
,
T
&
&
t
)
{
serialize
(
ar
,
std
::
forward
<
T
>
(
t
)
);
}
};
...
...
@@ -143,8 +144,8 @@ struct saver<A,T,false> {
* Generic save method calling apply on a saver.
*/
template
<
class
A
,
typename
T
>
inline
void
save
(
A
&
ar
,
T
&
t
)
{
saver
<
A
,
T
,
has_save_method
<
A
,
T
>::
value
>::
apply
(
ar
,
t
);
inline
void
save
(
A
&
ar
,
T
&
&
t
)
{
saver
<
A
,
T
,
has_save_method
<
A
,
T
>::
value
>::
apply
(
ar
,
std
::
forward
<
T
>
(
t
)
);
}
/**
...
...
@@ -156,15 +157,15 @@ struct loader;
template
<
class
A
,
typename
T
>
struct
loader
<
A
,
T
,
true
>
{
static
void
apply
(
A
&
ar
,
T
&
t
)
{
static
void
apply
(
A
&
ar
,
T
&
&
t
)
{
t
.
load
(
ar
);
}
};
template
<
class
A
,
typename
T
>
struct
loader
<
A
,
T
,
false
>
{
static
void
apply
(
A
&
ar
,
T
&
t
)
{
serialize
(
ar
,
t
);
static
void
apply
(
A
&
ar
,
T
&
&
t
)
{
serialize
(
ar
,
std
::
forward
<
T
>
(
t
)
);
}
};
...
...
@@ -172,8 +173,8 @@ struct loader<A,T,false> {
* Generic load method calling allpy on a loader.
*/
template
<
class
A
,
typename
T
>
inline
void
load
(
A
&
ar
,
T
&
t
)
{
loader
<
A
,
T
,
has_load_method
<
A
,
T
>::
value
>::
apply
(
ar
,
t
);
inline
void
load
(
A
&
ar
,
T
&
&
t
)
{
loader
<
A
,
T
,
has_load_method
<
A
,
T
>::
value
>::
apply
(
ar
,
std
::
forward
<
T
>
(
t
)
);
}
/**
...
...
@@ -181,14 +182,14 @@ inline void load(A& ar, T& t) {
* objects passed as arguments.
*/
template
<
class
A
,
typename
T1
,
typename
...
Tn
>
void
serialize_many
(
A
&
ar
,
T1
&
t1
,
Tn
&
...
rest
)
{
ar
&
t1
;
serialize_many
(
ar
,
rest
...);
void
serialize_many
(
A
&
ar
,
T1
&
&
t1
,
Tn
&
&
...
rest
)
{
ar
&
std
::
forward
<
T1
>
(
t1
)
;
serialize_many
(
ar
,
std
::
forward
<
Tn
>
(
rest
)
...);
}
template
<
class
A
,
typename
T
>
void
serialize_many
(
A
&
ar
,
T
&
t
)
{
ar
&
t
;
void
serialize_many
(
A
&
ar
,
T
&
&
t
)
{
ar
&
std
::
forward
<
T
>
(
t
)
;
}
}
...
...
include/thallium/tuple_util.hpp
0 → 100644
View file @
02c51546
#ifndef __THALLIUM_TUPLE_UTIL_HPP
#define __THALLIUM_TUPLE_UTIL_HPP
#include <tuple>
namespace
thallium
{
namespace
detail
{
template
<
size_t
N
>
struct
apply_f_to_t_impl
{
template
<
typename
R
,
typename
...
ArgsF
,
typename
...
ArgsT
,
typename
...
Args
>
static
R
apply
(
const
std
::
function
<
R
(
ArgsF
...)
>&
f
,
std
::
tuple
<
ArgsT
...
>
const
&
t
,
Args
...
args
)
{
return
apply_f_to_t_impl
<
N
-
1
>::
apply
(
f
,
t
,
std
::
get
<
N
-
1
>
(
t
),
args
...);
}
};
template
<
>
struct
apply_f_to_t_impl
<
0
>
{
template
<
typename
R
,
typename
...
ArgsF
,
typename
...
ArgsT
,
typename
...
Args
>
static
R
apply
(
const
std
::
function
<
R
(
ArgsF
...)
>&
f
,
std
::
tuple
<
ArgsT
...
>
const
&
t
,
Args
...
args
)
{
return
f
(
args
...);
}
};
}
/**
* Applies a function with arbitrary arguments to a tuple holding the same types of arguments.
*
* \param f : function to call on the tuple.
* \param t : tupe of arguments.
* \return the value returned by f.
*/
template
<
typename
R
,
typename
...
ArgsF
,
typename
...
ArgsT
>
R
apply_function_to_tuple
(
const
std
::
function
<
R
(
ArgsF
...)
>&
f
,
std
::
tuple
<
ArgsT
...
>
const
&
t
)
{
return
detail
::
apply_f_to_t_impl
<
sizeof
...(
ArgsT
)
>::
apply
(
f
,
t
);
}
/**
* Applies a function with arbitrary arguments to a tuple holding the same types of arguments.
*
* \param f : function to call on the tuple.
* \param t : tupe of arguments.
* \return the value returned by f.
*/
template
<
typename
R
,
typename
...
ArgsF
,
typename
...
ArgsT
>
R
apply_function_to_tuple
(
R
(
*
f
)(
ArgsF
...),
std
::
tuple
<
ArgsT
...
>
const
&
t
)
{
std
::
function
<
R
(
ArgsF
...)
>
fun
(
f
);
return
apply_function_to_tuple
(
fun
,
t
);
}
}
#endif
test/TestHelloWorld.cpp
View file @
02c51546
...
...
@@ -5,27 +5,33 @@
#include <unistd.h>
#include <iostream>
#include <thallium.hpp>
#include <thallium/serialization/stl/string.hpp>
namespace
tl
=
thallium
;
void
hello
(
const
tl
::
request
&
req
,
const
tl
::
buffer
&
input
)
{
std
::
cout
<<
"(1) Hello World "
;
for
(
auto
c
:
input
)
std
::
cout
<<
c
;
std
::
cout
<<
std
::
endl
;
tl
::
buffer
ret
(
6
,
'c'
);
req
.
respond
(
ret
);
void
hello
(
const
tl
::
request
&
req
,
const
std
::
string
&
name
)
{
std
::
cout
<<
"Hello "
<<
name
<<
std
::
endl
;
}
int
server
()
{
tl
::
engine
margo
(
"bmi+tcp://127.0.0.1:1234"
,
MARGO_SERVER_MODE
);
margo
.
define
(
"hello1"
,
hello
);
margo
.
define
(
"hello2"
,
[
&
margo
](
const
tl
::
request
&
req
,
const
tl
::
buffer
&
input
)
{
std
::
cout
<<
"(2) Hello World "
;
for
(
auto
c
:
input
)
std
::
cout
<<
c
;
std
::
cout
<<
std
::
endl
;
margo
.
finalize
();
}
).
ignore_response
();
margo
.
define
(
"hello"
,
hello
).
ignore_response
();
std
::
function
<
void
(
const
tl
::
request
&
,
int
,
int
)
>
f
=
[](
const
tl
::
request
&
req
,
int
x
,
int
y
)
{
std
::
cout
<<
x
<<
"+"
<<
y
<<
" = "
<<
(
x
+
y
)
<<
std
::
endl
;
req
.
respond
(
x
+
y
);
};
margo
.
define
(
"sum"
,
f
);
std
::
function
<
void
(
const
tl
::
request
&
)
>
g
=
[
&
margo
](
const
tl
::
request
&
req
)
{
std
::
cout
<<
"Stopping server"
<<
std
::
endl
;
margo
.
finalize
();
};
margo
.
define
(
"stop"
,
g
);
std
::
string
addr
=
margo
.
self
();
std
::
cout
<<
"Server running at address "
<<
addr
<<
std
::
endl
;
...
...
@@ -35,22 +41,24 @@ int server() {
int
client
()
{
tl
::
engine
margo
(
"bmi+tcp"
,
MARGO_CLIENT_MODE
);
auto
remote_hello1
=
margo
.
define
(
"hello1"
);
auto
remote_hello2
=
margo
.
define
(
"hello2"
).
ignore_response
();
auto
remote_hello
=
margo
.
define
(
"hello"
).
ignore_response
();
auto
remote_sum
=
margo
.
define
(
"sum"
);
auto
remote_stop
=
margo
.
define
(
"stop"
).
ignore_response
();
std
::
string
server_addr
=
"bmi+tcp://127.0.0.1:1234"
;
sleep
(
1
);
auto
server_endpoint
=
margo
.
lookup
(
server_addr
);
std
::
cout
<<
"Lookup done for endpoint "
<<
(
std
::
string
)
server_endpoint
<<
std
::
endl
;
tl
::
buffer
b
(
16
,
'a'
);
auto
ret
=
remote_hello1
.
on
(
server_endpoint
)(
b
);
std
::
cout
<<
"Response from hello1: "
;
for
(
auto
c
:
ret
)
std
::
cout
<<
c
;
std
::
cout
<<
std
::
endl
;
std
::
string
name
(
"Matthieu"
);
remote_hello
.
on
(
server_endpoint
)(
name
);
remote_hello2
.
on
(
server_endpoint
)(
b
);
int
ret
=
remote_sum
.
on
(
server_endpoint
)(
23
,
67
);
std
::
cout
<<
"Server returned "
<<
ret
<<
std
::
endl
;
remote_stop
.
on
(
server_endpoint
)();
return
0
;
}
...
...
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