Skip to content

Commit 934ba12

Browse files
committed
Add MCA parameters to define the size of memcpy chunks.
Add support for vector copy, allowing the upper level to define specialized/optimized vector copy functions. Signed-off-by: George Bosilca <bosilca@icl.utk.edu>
1 parent d6cdbdf commit 934ba12

File tree

4 files changed

+152
-58
lines changed

4 files changed

+152
-58
lines changed

opal/datatype/opal_datatype_copy.c

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
* Copyright (c) 2004-2006 The Trustees of Indiana University and Indiana
44
* University Research and Technology
55
* Corporation. All rights reserved.
6-
* Copyright (c) 2004-2013 The University of Tennessee and The University
6+
* Copyright (c) 2004-2019 The University of Tennessee and The University
77
* of Tennessee Research Foundation. All rights
88
* reserved.
99
* Copyright (c) 2004-2006 High Performance Computing Center Stuttgart,
@@ -41,7 +41,15 @@
4141
#define DO_DEBUG(INST)
4242
#endif /* OPAL_ENABLE_DEBUG */
4343

44-
static size_t opal_datatype_memop_block_size = 128 * 1024;
44+
size_t opal_datatype_memop_block_size = 128 * 1024;
45+
size_t opal_datatype_cuda_memop_block_size = SIZE_MAX; /* or (size_t)-1 in pre C99 */
46+
47+
/* The MEM_OP_BLOCK_SIZE_CONST define how a large contiguous memcpy
48+
* should be split. In some cases having a pipeline might allow for
49+
* cache write-backs, but in general (and certainly in the case of
50+
* CUDA devices) this should be set to the largest size_t value.
51+
*/
52+
#define MEM_OP_BLOCK_SIZE_CONST opal_datatype_memop_block_size
4553

4654
/**
4755
* Non overlapping memory regions
@@ -72,6 +80,10 @@ static size_t opal_datatype_memop_block_size = 128 * 1024;
7280
#include "opal_datatype_copy.h"
7381

7482
#if OPAL_CUDA_SUPPORT
83+
84+
#undef MEM_OP_BLOCK_SIZE_CONST
85+
#define MEM_OP_BLOCK_SIZE_CONST opal_datatype_cuda_memop_block_size
86+
7587
#include "opal_datatype_cuda.h"
7688

7789
#undef MEM_OP_NAME
@@ -92,9 +104,12 @@ static size_t opal_datatype_memop_block_size = 128 * 1024;
92104
fct = copy_function; \
93105
} \
94106
} while(0)
95-
#else
107+
108+
#else /* OPAL_CUDA_SUPPORT */
109+
96110
#define SET_CUDA_COPY_FCT(cuda_device_bufs, fct, copy_function)
97-
#endif
111+
112+
#endif /* OPAL_CUDA_SUPPORT */
98113

99114
int32_t opal_datatype_copy_content_same_ddt( const opal_datatype_t* datatype, int32_t count,
100115
char* destination_base, char* source_base )

opal/datatype/opal_datatype_copy.h

Lines changed: 89 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/* -*- Mode: C; c-basic-offset:4 ; -*- */
22
/*
3-
* Copyright (c) 2004-2017 The University of Tennessee and The University
3+
* Copyright (c) 2004-2019 The University of Tennessee and The University
44
* of Tennessee Research Foundation. All rights
55
* reserved.
66
* Copyright (c) 2009 Oak Ridge National Labs. All rights reserved.
@@ -35,18 +35,61 @@
3535
#endif
3636

3737

38-
#define _predefined_data DT_CONCAT(MEM_OP_NAME,_predefined_data)
39-
#define _contiguous_loop DT_CONCAT(MEM_OP_NAME,_contiguous_loop)
4038
#define _copy_content_same_ddt DT_CONCAT(MEM_OP_NAME,_copy_content_same_ddt)
4139

42-
static inline void _predefined_data( const dt_elem_desc_t* ELEM,
43-
const opal_datatype_t* DATATYPE,
44-
unsigned char* SOURCE_BASE,
45-
size_t TOTAL_COUNT,
46-
size_t COUNT,
47-
unsigned char* SOURCE,
48-
unsigned char* DESTINATION,
49-
size_t* SPACE )
40+
#if !defined(MEM_OP_BLOCK_SIZE_CONST)
41+
#error
42+
#endif
43+
44+
#if !defined(_memcpy_vector)
45+
46+
#define _memcpy_vector DT_CONCAT(MEM_OP_NAME,_memcpy_vector)
47+
#define __OPAL_DATATYPE_DEFINE__memcpy_vector
48+
49+
static inline size_t
50+
_memcpy_vector( unsigned char* dest, /* destination pointer of the copy */
51+
unsigned char* source, /* source pointer of the copy */
52+
size_t blength, /* size in bytes of each block */
53+
size_t count, /* the number of blocks */
54+
ptrdiff_t dstride, /* the stride at the destination of each block */
55+
ptrdiff_t sstride ) /* the stride at the source of each block */
56+
{
57+
size_t _length = 0;
58+
if( (blength == (size_t)(sstride)) && (sstride == dstride) ) {
59+
_length = count * blength;
60+
/* the extent and the size of the basic datatype are equals */
61+
DO_DEBUG( opal_output( 0, "vector copy [*] %s( %p, %p, %" PRIsize_t " )\n",
62+
STRINGIFY(MEM_OP_NAME), (void*)dest, (void*)source, _length ); );
63+
MEM_OP( dest, source, _length );
64+
} else {
65+
for(size_t _i = 0; _i < count; _i++ ) {
66+
/* the extent and the size of the basic datatype are equals */
67+
DO_DEBUG( opal_output( 0, "vector copy [%" PRIsize_t "] %s( %p, %p, %" PRIsize_t " )\n",
68+
_i, STRINGIFY(MEM_OP_NAME), (void*)dest, (void*)source, blength ); );
69+
MEM_OP( dest, source, blength );
70+
_length += blength;
71+
source += sstride;
72+
dest += dstride;
73+
}
74+
}
75+
return _length;
76+
}
77+
#endif /* !defined(_memcpy_vector) */
78+
79+
#if !defined(_predefined_data)
80+
81+
#define _predefined_data DT_CONCAT(MEM_OP_NAME,_predefined_data)
82+
#define __OPAL_DATATYPE_DEFINE__predefined_data
83+
84+
static inline
85+
void _predefined_data( const dt_elem_desc_t* ELEM,
86+
const opal_datatype_t* DATATYPE,
87+
unsigned char* SOURCE_BASE,
88+
size_t TOTAL_COUNT,
89+
size_t COUNT,
90+
unsigned char* SOURCE,
91+
unsigned char* DESTINATION,
92+
size_t* SPACE )
5093
{
5194
size_t _copy_count = (COUNT);
5295
size_t _copy_blength;
@@ -57,38 +100,34 @@ static inline void _predefined_data( const dt_elem_desc_t* ELEM,
57100
_copy_blength = opal_datatype_basicDatatypes[_elem->common.type]->size;
58101

59102
if( _copy_blength == (size_t)_elem->extent ) {
60-
_copy_blength *= _copy_count;
61103
OPAL_DATATYPE_SAFEGUARD_POINTER( _source, _copy_blength, (SOURCE_BASE),
62104
(DATATYPE), (TOTAL_COUNT) );
63-
/* the extent and the size of the basic datatype are equals */
64-
DO_DEBUG( opal_output( 0, "copy 1. %s( %p, %p, %" PRIsize_t " ) => space %" PRIsize_t "\n",
65-
STRINGIFY(MEM_OP_NAME), (void*)_destination, (void*)_source, _copy_blength, *(SPACE) ); );
66-
MEM_OP( _destination, _source, _copy_blength );
67-
_source += _copy_blength;
68-
_destination += _copy_blength;
69105
} else {
70106
for(size_t _i = 0; _i < _copy_count; _i++ ) {
71107
OPAL_DATATYPE_SAFEGUARD_POINTER( _source, _copy_blength, (SOURCE_BASE),
72108
(DATATYPE), (TOTAL_COUNT) );
73-
DO_DEBUG( opal_output( 0, "copy 2. %s( %p, %p, %lu ) => space %lu\n",
74-
STRINGIFY(MEM_OP_NAME), (void*)_destination, (void*)_source, (unsigned long)_copy_blength, (unsigned long)(*(SPACE) - (_i * _copy_blength)) ); );
75-
MEM_OP( _destination, _source, _copy_blength );
76-
_source += _elem->extent;
77-
_destination += _elem->extent;
78109
}
79-
_copy_blength *= _copy_count;
80110
}
81-
*(SPACE) -= _copy_blength;
111+
_copy_blength = _memcpy_vector( _destination, _source,
112+
_copy_blength, _copy_count,
113+
_elem->extent, _elem->extent );
114+
*(SPACE) -= _copy_blength;
82115
}
116+
#endif /* !defined(_predefined_data) */
83117

84-
static inline void _contiguous_loop( const dt_elem_desc_t* ELEM,
85-
const opal_datatype_t* DATATYPE,
86-
unsigned char* SOURCE_BASE,
87-
size_t TOTAL_COUNT,
88-
size_t COUNT,
89-
unsigned char* SOURCE,
90-
unsigned char* DESTINATION,
91-
size_t* SPACE )
118+
#if !defined(_contiguous_loop)
119+
#define _contiguous_loop DT_CONCAT(MEM_OP_NAME,_contiguous_loop)
120+
#define __OPAL_DATATYPE_DEFINE__contiguous_loop
121+
122+
static inline
123+
void _contiguous_loop( const dt_elem_desc_t* ELEM,
124+
const opal_datatype_t* DATATYPE,
125+
unsigned char* SOURCE_BASE,
126+
size_t TOTAL_COUNT,
127+
size_t COUNT,
128+
unsigned char* SOURCE,
129+
unsigned char* DESTINATION,
130+
size_t* SPACE )
92131
{
93132
ddt_loop_desc_t *_loop = (ddt_loop_desc_t*)(ELEM);
94133
ddt_endloop_desc_t* _end_loop = (ddt_endloop_desc_t*)((ELEM) + _loop->items);
@@ -115,6 +154,7 @@ static inline void _contiguous_loop( const dt_elem_desc_t* ELEM,
115154
}
116155
*(SPACE) -= _copy_loops;
117156
}
157+
#endif /* !defined(_contiguous_loop) */
118158

119159
static inline int32_t _copy_content_same_ddt( const opal_datatype_t* datatype, int32_t count,
120160
char* destination_base, char* source_base )
@@ -146,7 +186,7 @@ static inline int32_t _copy_content_same_ddt( const opal_datatype_t* datatype, i
146186
source += datatype->true_lb;
147187
if( (ptrdiff_t)datatype->size == extent ) { /* all contiguous == no gaps around */
148188
size_t total_length = iov_len_local;
149-
size_t memop_chunk = opal_datatype_memop_block_size;
189+
size_t memop_chunk = MEM_OP_BLOCK_SIZE_CONST;
150190
while( total_length > 0 ) {
151191
if( memop_chunk > total_length ) memop_chunk = total_length;
152192
OPAL_DATATYPE_SAFEGUARD_POINTER( destination, memop_chunk,
@@ -251,3 +291,18 @@ static inline int32_t _copy_content_same_ddt( const opal_datatype_t* datatype, i
251291
}
252292
}
253293
}
294+
295+
#if defined(__OPAL_DATATYPE_DEFINE__memcpy_vector)
296+
#undef __OPAL_DATATYPE_DEFINE__memcpy_vector
297+
#undef _memcpy_vector
298+
#endif /* defined(__OPAL_DATATYPE_DEFINE__memcpy_vector) */
299+
300+
#if defined(__OPAL_DATATYPE_DEFINE__predefined_data)
301+
#undef __OPAL_DATATYPE_DEFINE__predefined_data
302+
#undef _predefined_data
303+
#endif /* defined(__OPAL_DATATYPE_DEFINE__predefined_data) */
304+
305+
#if defined(__OPAL_DATATYPE_DEFINE__contiguous_loop)
306+
#undef __OPAL_DATATYPE_DEFINE__contiguous_loop
307+
#undef _contiguous_loop
308+
#endif /* defined(__OPAL_DATATYPE_DEFINE__contiguous_loop) */

opal/datatype/opal_datatype_internal.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
* Copyright (c) 2004-2006 The Trustees of Indiana University and Indiana
44
* University Research and Technology
55
* Corporation. All rights reserved.
6-
* Copyright (c) 2004-2018 The University of Tennessee and The University
6+
* Copyright (c) 2004-2019 The University of Tennessee and The University
77
* of Tennessee Research Foundation. All rights
88
* reserved.
99
* Copyright (c) 2004-2006 High Performance Computing Center Stuttgart,
@@ -515,5 +515,8 @@ extern bool opal_position_debug;
515515
extern bool opal_copy_debug;
516516
#endif /* OPAL_ENABLE_DEBUG */
517517

518+
extern size_t opal_datatype_memop_block_size;
519+
extern size_t opal_datatype_cuda_memop_block_size;
520+
518521
END_C_DECLS
519522
#endif /* OPAL_DATATYPE_INTERNAL_H_HAS_BEEN_INCLUDED */

opal/datatype/opal_datatype_module.c

Lines changed: 40 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
* Copyright (c) 2004-2006 The Trustees of Indiana University and Indiana
44
* University Research and Technology
55
* Corporation. All rights reserved.
6-
* Copyright (c) 2004-2018 The University of Tennessee and The University
6+
* Copyright (c) 2004-2019 The University of Tennessee and The University
77
* of Tennessee Research Foundation. All rights
88
* reserved.
99
* Copyright (c) 2004-2006 High Performance Computing Center Stuttgart,
@@ -157,39 +157,39 @@ OPAL_DECLSPEC const opal_datatype_t* opal_datatype_basicDatatypes[OPAL_DATATYPE_
157157

158158
int opal_datatype_register_params(void)
159159
{
160-
#if OPAL_ENABLE_DEBUG
161160
int ret;
161+
#if OPAL_ENABLE_DEBUG
162162

163163
ret = mca_base_var_register ("opal", "mpi", NULL, "ddt_unpack_debug",
164-
"Whether to output debugging information in the ddt unpack functions (nonzero = enabled)",
165-
MCA_BASE_VAR_TYPE_BOOL, NULL, 0, MCA_BASE_VAR_FLAG_SETTABLE, OPAL_INFO_LVL_3,
166-
MCA_BASE_VAR_SCOPE_LOCAL, &opal_unpack_debug);
164+
"Whether to output debugging information in the ddt unpack functions (nonzero = enabled)",
165+
MCA_BASE_VAR_TYPE_BOOL, NULL, 0, MCA_BASE_VAR_FLAG_SETTABLE, OPAL_INFO_LVL_3,
166+
MCA_BASE_VAR_SCOPE_LOCAL, &opal_unpack_debug);
167167
if (0 > ret) {
168-
return ret;
168+
return ret;
169169
}
170170

171171
ret = mca_base_var_register ("opal", "mpi", NULL, "ddt_pack_debug",
172-
"Whether to output debugging information in the ddt pack functions (nonzero = enabled)",
173-
MCA_BASE_VAR_TYPE_BOOL, NULL, 0, MCA_BASE_VAR_FLAG_SETTABLE, OPAL_INFO_LVL_3,
174-
MCA_BASE_VAR_SCOPE_LOCAL, &opal_pack_debug);
172+
"Whether to output debugging information in the ddt pack functions (nonzero = enabled)",
173+
MCA_BASE_VAR_TYPE_BOOL, NULL, 0, MCA_BASE_VAR_FLAG_SETTABLE, OPAL_INFO_LVL_3,
174+
MCA_BASE_VAR_SCOPE_LOCAL, &opal_pack_debug);
175175
if (0 > ret) {
176-
return ret;
176+
return ret;
177177
}
178178

179179
ret = mca_base_var_register ("opal", "mpi", NULL, "ddt_position_debug",
180-
"Non zero lead to output generated by the datatype position functions",
181-
MCA_BASE_VAR_TYPE_BOOL, NULL, 0, MCA_BASE_VAR_FLAG_SETTABLE, OPAL_INFO_LVL_3,
182-
MCA_BASE_VAR_SCOPE_LOCAL, &opal_position_debug);
180+
"Non zero lead to output generated by the datatype position functions",
181+
MCA_BASE_VAR_TYPE_BOOL, NULL, 0, MCA_BASE_VAR_FLAG_SETTABLE, OPAL_INFO_LVL_3,
182+
MCA_BASE_VAR_SCOPE_LOCAL, &opal_position_debug);
183183
if (0 > ret) {
184-
return ret;
184+
return ret;
185185
}
186186

187187
ret = mca_base_var_register ("opal", "mpi", NULL, "ddt_copy_debug",
188-
"Whether to output debugging information in the ddt copy functions (nonzero = enabled)",
189-
MCA_BASE_VAR_TYPE_BOOL, NULL, 0, MCA_BASE_VAR_FLAG_SETTABLE, OPAL_INFO_LVL_3,
190-
MCA_BASE_VAR_SCOPE_LOCAL, &opal_copy_debug);
188+
"Whether to output debugging information in the ddt copy functions (nonzero = enabled)",
189+
MCA_BASE_VAR_TYPE_BOOL, NULL, 0, MCA_BASE_VAR_FLAG_SETTABLE, OPAL_INFO_LVL_3,
190+
MCA_BASE_VAR_SCOPE_LOCAL, &opal_copy_debug);
191191
if (0 > ret) {
192-
return ret;
192+
return ret;
193193
}
194194

195195
ret = mca_base_var_register ("opal", "opal", NULL, "ddt_verbose",
@@ -208,12 +208,33 @@ int opal_datatype_register_params(void)
208208
OPAL_INFO_LVL_8, MCA_BASE_VAR_SCOPE_LOCAL,
209209
&opal_cuda_verbose);
210210
if (0 > ret) {
211-
return ret;
211+
return ret;
212212
}
213213
#endif
214214

215215
#endif /* OPAL_ENABLE_DEBUG */
216216

217+
/* Define the segment size for the data copy operations */
218+
ret = mca_base_var_register ("opal", "opal", NULL, "datatype_memcpy_block_size",
219+
"Split all memory copies handled by the datatype engine",
220+
MCA_BASE_VAR_TYPE_SIZE_T, NULL, 0, MCA_BASE_VAR_FLAG_SETTABLE,
221+
OPAL_INFO_LVL_5, MCA_BASE_VAR_SCOPE_LOCAL,
222+
&opal_datatype_memop_block_size);
223+
if (0 > ret) {
224+
return ret;
225+
}
226+
227+
#if OPAL_CUDA_SUPPORT
228+
ret = mca_base_var_register ("opal", "opal", NULL, "datatype_cuda_memcpy_block_size",
229+
"Split all CUDA memory copies handled by the datatype engine",
230+
MCA_BASE_VAR_TYPE_SIZE_T, NULL, 0, MCA_BASE_VAR_FLAG_SETTABLE,
231+
OPAL_INFO_LVL_5, MCA_BASE_VAR_SCOPE_LOCAL,
232+
&opal_datatype_cuda_memop_block_size);
233+
if (0 > ret) {
234+
return ret;
235+
}
236+
#endif
237+
217238
return OPAL_SUCCESS;
218239
}
219240

0 commit comments

Comments
 (0)