1 /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */
2 /*
3 * Copyright (c) 2013 Mellanox Technologies, Inc.
4 * All rights reserved.
5 * Copyright (c) 2015 Los Alamos National Security, LLC. All rights
6 * reserved.
7 * $COPYRIGHT$
8 *
9 * Additional copyrights may follow
10 *
11 * $HEADER$
12 */
13
14 /**
15 * @file
16 *
17 * Atomic Operations Interface
18 *
19 */
20
21 #ifndef OSHMEM_MCA_ATOMIC_H
22 #define OSHMEM_MCA_ATOMIC_H
23
24 #include "oshmem_config.h"
25 #include "oshmem/types.h"
26 #include "oshmem/constants.h"
27
28 #include "opal/util/output.h"
29 #include "mpi.h"
30 #include "oshmem/mca/mca.h"
31 #include "opal/mca/base/base.h"
32 #include "oshmem/mca/atomic/base/base.h"
33
34 BEGIN_C_DECLS
35
36 #define OSHMEM_ATOMIC_PTR_2_INT(ptr, size) ((size) == 8 ? *(uint64_t*)(ptr) : *(uint32_t*)(ptr))
37
38 #define DO_SHMEM_TYPE_OP(ctx, type_name, type, op, target, value, pe) do { \
39 int rc = OSHMEM_SUCCESS; \
40 size_t size = 0; \
41 \
42 RUNTIME_CHECK_INIT(); \
43 RUNTIME_CHECK_PE(pe); \
44 RUNTIME_CHECK_ADDR(target); \
45 \
46 size = sizeof(value); \
47 rc = MCA_ATOMIC_CALL(op( \
48 ctx, \
49 (void*)target, \
50 value, \
51 size, \
52 pe)); \
53 RUNTIME_CHECK_RC(rc); \
54 \
55 return; \
56 } while (0)
57
58 #define OSHMEM_TYPE_OP(type_name, type, prefix, op) \
59 void prefix##_##type_name##_atomic_##op(type *target, type value, int pe) \
60 { \
61 DO_SHMEM_TYPE_OP(oshmem_ctx_default, type_name, type, op, \
62 target, value, pe); \
63 }
64
65 #define OSHMEM_CTX_TYPE_OP(type_name, type, prefix, op) \
66 void prefix##_ctx_##type_name##_atomic_##op(shmem_ctx_t ctx, type *target, type value, int pe) \
67 { \
68 DO_SHMEM_TYPE_OP(ctx, type_name, type, op, \
69 target, value, pe); \
70 }
71
72 #define DO_OSHMEM_TYPE_FOP(ctx, type_name, type, op, target, value, pe) do { \
73 int rc = OSHMEM_SUCCESS; \
74 size_t size = 0; \
75 type out_value; \
76 \
77 RUNTIME_CHECK_INIT(); \
78 RUNTIME_CHECK_PE(pe); \
79 RUNTIME_CHECK_ADDR(target); \
80 \
81 size = sizeof(out_value); \
82 rc = MCA_ATOMIC_CALL(f##op( \
83 ctx, \
84 (void*)target, \
85 (void*)&out_value, \
86 value, \
87 size, \
88 pe)); \
89 RUNTIME_CHECK_RC(rc); \
90 \
91 return out_value; \
92 } while (0)
93
94 #define OSHMEM_TYPE_FOP(type_name, type, prefix, op) \
95 type prefix##_##type_name##_atomic_fetch_##op(type *target, type value, int pe) \
96 { \
97 DO_OSHMEM_TYPE_FOP(oshmem_ctx_default, type_name, type, op, \
98 target, value, pe); \
99 }
100
101 #define OSHMEM_CTX_TYPE_FOP(type_name, type, prefix, op) \
102 type prefix##_ctx_##type_name##_atomic_fetch_##op(shmem_ctx_t ctx, type *target, type value, int pe) \
103 { \
104 DO_OSHMEM_TYPE_FOP(ctx, type_name, type, op, \
105 target, value, pe); \
106 }
107
108 /* ******************************************************************** */
109
110 struct oshmem_op_t;
111
112 /* ******************************************************************** */
113
114 typedef int (*mca_atomic_base_component_init_fn_t)(bool enable_progress_threads,
115 bool enable_threads);
116
117 typedef int (*mca_atomic_base_component_finalize_fn_t)(void);
118
119 typedef struct mca_atomic_base_module_1_0_0_t* (*mca_atomic_base_component_query_fn_t)(int *priority);
120
121 /* ******************************************************************** */
122
123 /**
124 * Atomic component interface
125 *
126 * Component interface for the atomic framework. A public
127 * instance of this structure, called
128 * mca_atomic_[component_name]_component, must exist in any atomic
129 * component.
130 */
131 struct mca_atomic_base_component_1_0_0_t {
132 /** Base component description */
133 mca_base_component_t atomic_version;
134 /** Base component data block */
135 mca_base_component_data_t atomic_data;
136
137 /** Component initialization function */
138 mca_atomic_base_component_init_fn_t atomic_startup;
139 mca_atomic_base_component_finalize_fn_t atomic_finalize;
140 mca_atomic_base_component_query_fn_t atomic_query;
141
142 /* priority for component */
143 int priority;
144 };
145 typedef struct mca_atomic_base_component_1_0_0_t mca_atomic_base_component_1_0_0_t;
146
147 /** Per guidence in mca.h, use the unversioned struct name if you just
148 want to always keep up with the most recent version of the
149 interace. */
150 typedef struct mca_atomic_base_component_1_0_0_t mca_atomic_base_component_t;
151
152 /**
153 * Atomic module interface
154 *
155 */
156 struct mca_atomic_base_module_1_0_0_t {
157 /** Collective modules all inherit from opal_object */
158 opal_object_t super;
159
160 /* Collective function pointers */
161 int (*atomic_add)(shmem_ctx_t ctx,
162 void *target,
163 uint64_t value,
164 size_t size,
165 int pe);
166 int (*atomic_and)(shmem_ctx_t ctx,
167 void *target,
168 uint64_t value,
169 size_t size,
170 int pe);
171 int (*atomic_or)(shmem_ctx_t ctx,
172 void *target,
173 uint64_t value,
174 size_t size,
175 int pe);
176 int (*atomic_xor)(shmem_ctx_t ctx,
177 void *target,
178 uint64_t value,
179 size_t size,
180 int pe);
181 int (*atomic_fadd)(shmem_ctx_t ctx,
182 void *target,
183 void *prev,
184 uint64_t value,
185 size_t size,
186 int pe);
187 int (*atomic_fand)(shmem_ctx_t ctx,
188 void *target,
189 void *prev,
190 uint64_t value,
191 size_t size,
192 int pe);
193 int (*atomic_for)(shmem_ctx_t ctx,
194 void *target,
195 void *prev,
196 uint64_t value,
197 size_t size,
198 int pe);
199 int (*atomic_fxor)(shmem_ctx_t ctx,
200 void *target,
201 void *prev,
202 uint64_t value,
203 size_t size,
204 int pe);
205 int (*atomic_swap)(shmem_ctx_t ctx,
206 void *target,
207 void *prev,
208 uint64_t value,
209 size_t size,
210 int pe);
211 int (*atomic_cswap)(shmem_ctx_t ctx,
212 void *target,
213 uint64_t *prev, /* prev is used internally by wrapper, we may
214 always use 64-bit value */
215 uint64_t cond,
216 uint64_t value,
217 size_t size,
218 int pe);
219 };
220 typedef struct mca_atomic_base_module_1_0_0_t mca_atomic_base_module_1_0_0_t;
221
222 /** Per guidence in mca.h, use the unversioned struct name if you just
223 want to always keep up with the most recent version of the
224 interace. */
225 typedef struct mca_atomic_base_module_1_0_0_t mca_atomic_base_module_t;
226 OSHMEM_DECLSPEC OBJ_CLASS_DECLARATION(mca_atomic_base_module_t);
227
228 /* ******************************************************************** */
229
230 /*
231 * Macro for use in components
232 */
233 #define MCA_ATOMIC_BASE_VERSION_2_0_0 \
234 OSHMEM_MCA_BASE_VERSION_2_1_0("atomic", 1, 0, 0)
235
236 /* ******************************************************************** */
237
238 OSHMEM_DECLSPEC extern mca_atomic_base_component_t mca_atomic_base_selected_component;
239 OSHMEM_DECLSPEC extern mca_atomic_base_module_t mca_atomic;
240 #define MCA_ATOMIC_CALL(a) mca_atomic.atomic_ ## a
241
242 END_C_DECLS
243
244 #endif /* OSHMEM_MCA_ATOMIC_H */