-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathCopyChannel.hpp
144 lines (131 loc) · 4.46 KB
/
CopyChannel.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
/**
* @file CopyChannel.hpp
* @brief Copy channel header
*/
#ifndef INTERDEVCOPY_COPY_CHANNEL_HPP_INCLUDE_
#define INTERDEVCOPY_COPY_CHANNEL_HPP_INCLUDE_
#include "Common.hpp"
#include <functional>
#include <typeinfo>
#include <typeindex>
#include <tuple>
namespace interdevcopy {
class DeviceMemoryRegion;
/**
* the type of copy function
*/
using CopyFuncType = std::function<ssize_t(size_t, size_t, size_t, void *)>;
/**
* the type of copy function getter
*/
using CopyFuncGetterType = std::function<CopyFuncType(
DeviceMemoryRegion *, DeviceMemoryRegion *, void *)>;
/**
* Copy Channel
*/
class CopyChannel: public util::Object {
private:
/// source device memory region
DeviceMemoryRegion *source;
/// destination device memory region
DeviceMemoryRegion *destination;
CopyFuncType copyfunc;
public:
CopyChannel(DeviceMemoryRegion *, DeviceMemoryRegion *, void *);
~CopyChannel();
ssize_t doCopy(size_t dstoff, size_t srcoff, size_t size, void *option);
};
void _registerCopyFuncGetterMapEntry_(std::type_index, std::type_index,
CopyFuncGetterType);
/**
* @brief template class for registering CopyFuncGetter type
* @tparam FuncGetter class to define CopyFuncGetter
*
* The template class _CopyFuncGetterMapEntryInitializer registers
* a CopyFuncGetter on initialization.
*
* CopyFuncGetter is a class with the definitions of two alias types
* and operator() function:
* - srctype, the type of source device memory region,
* - dsttype, the type of destination device memory region, and
* - operator() to return copy function, a function object of
* CopyFuncType, with the source and destination device memory region
* being bound.
*
* This template structure is intended to be created as a global object
* in the REGISTER_COPY_HANDLER_IF macro.
*/
template <class FuncGetter> struct _CopyFuncGetterMapEntryInitializer {
FuncGetter getter_;
/**
* @brief constructor to run a routine on initialization
* @param cond condition expression
*
* Register CopyFuncGetter if the condition cond is true.
*/
_CopyFuncGetterMapEntryInitializer(std::function<bool()> &&cond) {
if (cond()) {
_registerCopyFuncGetterMapEntry_(
typeid(typename FuncGetter::desttype),
typeid(typename FuncGetter::srctype), this->getter_);
}
}
};
/**
* @brief a utility function to downcast and bind device memory regions
* @tparam DstDevMemType destination device memory region type
* @tparam SrcDevMemType source device memory region type
* @param fp function pointer to copy data
* @param d_ destination device memory region
* @param s_ source device memory region
*
* The template function wrapCopyFuncWithDownCastAndBind() binds
* source and destination device memory regions to a function to copy data
* and return the lambda object with CopyFunc type.
* This template function is used for convenience of implementation of
* CopyFunctions (for interdevcopy) using simple memcpy-like copy functions.
*/
template <class DstDevMemType, class SrcDevMemType>
CopyFuncType wrapCopyFuncWithDownCastAndBind(
ssize_t(*fp)(DstDevMemType *, SrcDevMemType *, size_t, size_t, size_t,
void *), DeviceMemoryRegion *d_, DeviceMemoryRegion *s_) {
INTERDEVCOPY_ASSERT(typeid(*d_) == typeid(DstDevMemType));
INTERDEVCOPY_ASSERT(typeid(*s_) == typeid(SrcDevMemType));
auto d_impl = dynamic_cast<DstDevMemType *>(d_);
auto s_impl = dynamic_cast<SrcDevMemType *>(s_);
return [fp, d_impl, s_impl](size_t d_off, size_t s_off, size_t size,
void *opt) {
return (*fp)(d_impl, s_impl, d_off, s_off, size, opt);
};
}
} // namespace interdevcopy
/**
* @ingroup API
* @brief copy channel (exported data type as part of API)
* @see interdevcopy_create_channel
*/
struct interdevcopy_channel {
interdevcopy::CopyChannel impl;
};
/**
* @var interdevcopy_channel::impl
* @brief created copy channel
*/
/**
* @brief register a CopyFuncGetter under a condition
* @param FuncGetterType_ type name of CopyFuncGetter class
* @param condexpr_ a condition expression
*/
#define REGISTER_COPY_HANDLER_IF(FuncGetterType_, condexpr_) \
namespace { \
interdevcopy::_CopyFuncGetterMapEntryInitializer<FuncGetterType_> \
_INTERDEVCOPY_UNIQUE_SYMBOL__(_copy_func_getter_init_)( \
[](){return (condexpr_);}); \
}
/**
* @brief register a CopyFuncGetter always
* @param FuncGetterType_ type name of CopyFuncGetter class
*/
#define REGISTER_COPY_HANDLER(FuncGetterType_) \
REGISTER_COPY_HANDLER_IF(FuncGetterType_, true)
#endif