File: base.h

package info (click to toggle)
openmpi 5.0.7-1
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 202,312 kB
  • sloc: ansic: 612,441; makefile: 42,495; sh: 11,230; javascript: 9,244; f90: 7,052; java: 6,404; perl: 5,154; python: 1,856; lex: 740; fortran: 61; cpp: 20; tcl: 12
file content (300 lines) | stat: -rw-r--r-- 9,518 bytes parent folder | download | duplicates (3)
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
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
/*
 * Copyright (c) 2013      Mellanox Technologies, Inc.
 *                         All rights reserved.
 * Copyright (c) 2015 Cisco Systems, Inc.  All rights reserved.
 * $COPYRIGHT$
 *
 * Additional copyrights may follow
 *
 * $HEADER$
 */
/**
 * @file
 */
#ifndef MCA_MEMHEAP_BASE_H
#define MCA_MEMHEAP_BASE_H

#include "oshmem_config.h"
#include "opal/class/opal_list.h"
#include "opal/class/opal_value_array.h"
#include "oshmem/mca/mca.h"

#include "oshmem/mca/memheap/memheap.h"

BEGIN_C_DECLS

/*
 * Global functions for MCA: overall MEMHEAP open and close
 */
OSHMEM_DECLSPEC int mca_memheap_base_select(void);

/*
 * Globals
 */

/* only used within base -- no need to DECLSPEC */
#define MEMHEAP_BASE_MIN_ORDER         3                                /* forces 64 bit alignment */
#define MEMHEAP_BASE_PAGE_ORDER        21
#define MEMHEAP_BASE_PRIVATE_SIZE      (1ULL << MEMHEAP_BASE_PAGE_ORDER) /* should be at least the same as a huge page size */
#define MEMHEAP_BASE_MIN_SIZE          (1ULL << MEMHEAP_BASE_PAGE_ORDER) /* must fit into at least one huge page */

extern int mca_memheap_base_already_opened;
extern int mca_memheap_base_key_exchange;
extern int mca_memheap_num_segments_warn;

#define HEAP_SEG_INDEX              0
#define MCA_MEMHEAP_SEG_COUNT       2

#define MEMHEAP_SEG_INVALID  0xFFFF


typedef struct mca_memheap_base_config {
    long            device_nic_mem_seg_size; /* Used for SHMEM_HINT_DEVICE_NIC_MEM */
} mca_memheap_base_config_t;


typedef struct mca_memheap_map {
    map_segment_t  *mem_segs;
    int             n_segments;
    int             capacity;
    int             num_transports;
} mca_memheap_map_t;

extern mca_memheap_map_t mca_memheap_base_map;
extern mca_memheap_base_config_t mca_memheap_base_config;

int mca_memheap_base_alloc_init(mca_memheap_map_t *, size_t, long, char *);
void mca_memheap_base_alloc_exit(mca_memheap_map_t *);
int mca_memheap_base_static_init(mca_memheap_map_t *);
void mca_memheap_base_static_exit(mca_memheap_map_t *);
int mca_memheap_base_reg(mca_memheap_map_t *);
int mca_memheap_base_dereg(mca_memheap_map_t *);
int memheap_oob_init(mca_memheap_map_t *);
void memheap_oob_destruct(void);
map_segment_t *mca_memheap_base_allocate_segment(mca_memheap_map_t *map);

OSHMEM_DECLSPEC int mca_memheap_base_is_symmetric_addr(const void* va);
OSHMEM_DECLSPEC sshmem_mkey_t *mca_memheap_base_get_mkey(void* va,
                                                           int tr_id);
OSHMEM_DECLSPEC sshmem_mkey_t * mca_memheap_base_get_cached_mkey_slow(shmem_ctx_t ctx,
                                                                      map_segment_t *s,
                                                                      int pe,
                                                                      void* va,
                                                                      int btl_id,
                                                                      void** rva);
OSHMEM_DECLSPEC void mca_memheap_modex_recv_all(void);

/* This function is for internal usage only
 * return value:
 * 0 - addr is not symmetric address
 * 1 - addr is part of user memheap
 * 2 - addr is part of private memheap
 * 3 - addr is static variable
 */
typedef enum {
    ADDR_INVALID = 0, ADDR_USER, ADDR_PRIVATE, ADDR_STATIC,
} addr_type_t;

OSHMEM_DECLSPEC int mca_memheap_base_detect_addr_type(void* va);

static inline unsigned memheap_log2(unsigned long long val)
{
    /* add 1 if val is NOT a power of 2 (to do the ceil) */
    unsigned int count = (val & (val - 1) ? 1 : 0);

    while (val > 0) {
        val = val >> 1;
        count++;
    }

    return count > 0 ? count - 1 : 0;
}

static inline void *memheap_down_align_addr(void* addr, unsigned int shift)
{
    return (void*) (((intptr_t) addr) & (~(intptr_t) 0) << shift);
}

static inline void *memheap_up_align_addr(void*addr, unsigned int shift)
{
    return (void*) ((((intptr_t) addr) | ~((~(intptr_t) 0) << shift)));
}

static inline unsigned long long memheap_align(unsigned long top)
{
    return ((top + MEMHEAP_BASE_MIN_SIZE - 1) & ~(MEMHEAP_BASE_MIN_SIZE - 1));
}

/*
 * MCA framework
 */
OSHMEM_DECLSPEC extern mca_base_framework_t oshmem_memheap_base_framework;

/* ******************************************************************** */
#ifdef __BASE_FILE__
#define __SPML_FILE__ __BASE_FILE__
#else
#define __SPML_FILE__ __FILE__
#endif

#ifdef OPAL_ENABLE_DEBUG
#define MEMHEAP_VERBOSE(level, ...) \
    oshmem_output_verbose(level, oshmem_memheap_base_framework.framework_output, \
        "%s:%d - %s()", __SPML_FILE__, __LINE__, __func__, __VA_ARGS__)
#else
#define MEMHEAP_VERBOSE(level, ...)
#endif

#define MEMHEAP_ERROR(...) \
    oshmem_output(oshmem_memheap_base_framework.framework_output, \
        "Error %s:%d - %s()", __SPML_FILE__, __LINE__, __func__, __VA_ARGS__)

#define MEMHEAP_WARN(...) \
    oshmem_output_verbose(0, oshmem_memheap_base_framework.framework_output, \
        "Warning %s:%d - %s()", __SPML_FILE__, __LINE__, __func__, __VA_ARGS__)

extern int mca_memheap_seg_cmp(const void *k, const void *v);

/* Turn ON/OFF debug output from build (default 0) */
#ifndef MEMHEAP_BASE_DEBUG
#define MEMHEAP_BASE_DEBUG    0
#endif
#define MEMHEAP_VERBOSE_FASTPATH(...)

extern mca_memheap_map_t* memheap_map;

static inline int map_segment_is_va_in(map_base_segment_t *s, void *va)
{
    return (va >= s->va_base && va < s->va_end);
}

static inline map_segment_t *memheap_find_seg(int segno)
{
    return &mca_memheap_base_map.mem_segs[segno];
}

static inline int memheap_is_va_in_segment(void *va, int segno) 
{
    return map_segment_is_va_in(&memheap_find_seg(segno)->super, va);
}

static inline int memheap_find_segnum(void *va, int pe)
{
    int i;
    int my_pe = oshmem_my_proc_id();

    if (pe == my_pe) {
        /* Find segment number for local segment using va_base
         * TODO: Merge local and remote segment information in mkeys_cache
         */
        for (i = 0; i < mca_memheap_base_map.n_segments; i++) {
            if (memheap_is_va_in_segment(va, i)) {
                return i;
            }
        }
    } else {
        /* Find segment number for remote segments using va_base */
        for (i = 0; i < mca_memheap_base_map.n_segments; i++) {
            map_segment_t *seg = memheap_find_seg(i);
            if (seg) {
                sshmem_mkey_t **mkeys_cache = seg->mkeys_cache;
                if (mkeys_cache) {
                    if (mkeys_cache[pe]) {
                        if ((va >= mkeys_cache[pe]->va_base) &&
                            ((char*)va < (char*)mkeys_cache[pe]->va_base + mkeys_cache[pe]->len)) {
                            return i;
                        }
                    }
                }
            }
        }
    }
    return MEMHEAP_SEG_INVALID;
}

static inline void* memheap_va2rva(void* va, void* local_base, void* remote_base)
{
    return (void*) (remote_base > local_base ?
            (uintptr_t)va + ((uintptr_t)remote_base - (uintptr_t)local_base) :
            (uintptr_t)va - ((uintptr_t)local_base - (uintptr_t)remote_base));
}

static inline void *map_segment_va2rva(mkey_segment_t *seg, void *va)
{
    return memheap_va2rva(va, seg->super.va_base, seg->rva_base);
}

void mkey_segment_init(mkey_segment_t *seg, sshmem_mkey_t *mkey, uint32_t segno);

static inline map_segment_t *memheap_find_va(void* va)
{
    map_segment_t *s = NULL;
    int i;

    for (i = 0; i < memheap_map->n_segments; i++) {
        if (memheap_is_va_in_segment(va, i)) {
            s = &memheap_map->mem_segs[i];
            break;
        }
    }

#if MEMHEAP_BASE_DEBUG == 1
    if (s) {
        MEMHEAP_VERBOSE(5, "match seg#%02ld: 0x%llX - 0x%llX %llu bytes va=%p",
                s - memheap_map->mem_segs,
                (long long)s->super.va_base,
                (long long)s->super.va_end,
                (long long)(s->super.va_end - s->super.va_base),
                (void *)va);
    }
#endif
    return s;
}

static inline  sshmem_mkey_t *mca_memheap_base_get_cached_mkey(shmem_ctx_t ctx,
                                                               int pe,
                                                                void* va,
                                                                int btl_id,
                                                                void** rva)
{
    map_segment_t *s;
    sshmem_mkey_t *mkey;

    MEMHEAP_VERBOSE_FASTPATH(10, "rkey: pe=%d va=%p", pe, va);
    s = memheap_find_va(va);
    if (OPAL_UNLIKELY(NULL == s))
        return NULL ;

    if (OPAL_UNLIKELY(!MAP_SEGMENT_IS_VALID(s)))
        return NULL ;

    if (OPAL_UNLIKELY(pe == oshmem_my_proc_id())) {
        *rva = va;
        MEMHEAP_VERBOSE_FASTPATH(10, "rkey: pe=%d va=%p -> (local) %lx %p", pe, va, 
                s->mkeys[btl_id].u.key, *rva);
        return &s->mkeys[btl_id];
    }

    if (OPAL_LIKELY(s->mkeys_cache[pe])) {
        mkey = &s->mkeys_cache[pe][btl_id];
        *rva = memheap_va2rva(va, s->super.va_base, mkey->va_base);
        MEMHEAP_VERBOSE_FASTPATH(10, "rkey: pe=%d va=%p -> (cached) %lx %p", pe, (void *)va, mkey->u.key, (void *)*rva);
        return mkey;
    }

    return mca_memheap_base_get_cached_mkey_slow(ctx, s, pe, va, btl_id, rva);
}

static inline int mca_memheap_base_num_transports(void) 
{
    return memheap_map->num_transports;
}

static inline void* mca_memheap_seg2base_va(int seg)
{
    return memheap_map->mem_segs[seg].super.va_base;
}

END_C_DECLS

#endif /* MCA_MEMHEAP_BASE_H */