File: btl_uct_device_context.h

package info (click to toggle)
openmpi 5.0.7-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, 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 (174 lines) | stat: -rw-r--r-- 6,011 bytes parent folder | download | duplicates (2)
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
/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */
/*
 * Copyright (c) 2014-2018 Los Alamos National Security, LLC. All rights
 *                         reserved.
 * $COPYRIGHT$
 *
 * Additional copyrights may follow
 *
 * $HEADER$
 */

#if !defined(BTL_UCT_DEVICE_CONTEXT_H)
#    define BTL_UCT_DEVICE_CONTEXT_H

#    include "btl_uct.h"
#    include "btl_uct_frag.h"
#    include "btl_uct_rdma.h"

/**
 * @brief Create a new device context for the given transport
 *
 * @param[in] module     btl uct module
 * @param[in] tl         btl uct tl pointer
 * @param[in] context_id identifier for this context (0..MCA_BTL_UCT_MAX_WORKERS-1)
 */
mca_btl_uct_device_context_t *mca_btl_uct_context_create(mca_btl_uct_module_t *module,
                                                         mca_btl_uct_tl_t *tl, int context_id,
                                                         bool enable_progress);

/**
 * @brief Destroy a device context and release all resources
 *
 * @param[in] context   btl uct device context
 *
 * This call frees a device context and all associated resources. It is not
 * valid to use the device context after this returns.
 */
void mca_btl_uct_context_destroy(mca_btl_uct_device_context_t *context);

static inline bool mca_btl_uct_context_trylock(mca_btl_uct_device_context_t *context)
{
    return OPAL_THREAD_TRYLOCK(&context->mutex);
}

static inline void mca_btl_uct_context_lock(mca_btl_uct_device_context_t *context)
{
    OPAL_THREAD_LOCK(&context->mutex);
}

static inline void mca_btl_uct_context_unlock(mca_btl_uct_device_context_t *context)
{
    OPAL_THREAD_UNLOCK(&context->mutex);
}

#    define MCA_BTL_UCT_CONTEXT_SERIALIZE(context, code) \
        do {                                             \
            mca_btl_uct_context_lock(context);           \
            code;                                        \
            mca_btl_uct_context_unlock(context);         \
        } while (0);

static inline int mca_btl_uct_get_context_index(void)
{
    static opal_atomic_uint32_t next_uct_index = 0;
    int context_id;

#    if OPAL_C_HAVE__THREAD_LOCAL
    if (mca_btl_uct_component.bind_threads_to_contexts) {
        static _Thread_local int uct_index = -1;

        context_id = uct_index;
        if (OPAL_UNLIKELY(-1 == context_id)) {
            context_id = uct_index = opal_atomic_fetch_add_32((opal_atomic_int32_t
                                                                   *) &next_uct_index,
                                                              1)
                                     % mca_btl_uct_component.num_contexts_per_module;
        }
    } else {
#    endif
        /* avoid using atomics in this. i doubt it improves performance to ensure atomicity on the
         * next index in this case. */
        context_id = next_uct_index++ % mca_btl_uct_component.num_contexts_per_module;
#    if OPAL_C_HAVE__THREAD_LOCAL
    }
#    endif

    return context_id;
}

static inline mca_btl_uct_device_context_t *
mca_btl_uct_module_get_tl_context_specific(mca_btl_uct_module_t *module, mca_btl_uct_tl_t *tl,
                                           int context_id)
{
    mca_btl_uct_device_context_t *context = tl->uct_dev_contexts[context_id];

    if (OPAL_UNLIKELY(NULL == context)) {
        OPAL_THREAD_LOCK(&module->lock);
        context = tl->uct_dev_contexts[context_id];
        if (OPAL_UNLIKELY(NULL == context)) {
            context = tl->uct_dev_contexts[context_id] = mca_btl_uct_context_create(module, tl,
                                                                                    context_id,
                                                                                    true);
        }
        OPAL_THREAD_UNLOCK(&module->lock);
    }

    return context;
}

static inline mca_btl_uct_device_context_t *
mca_btl_uct_module_get_rdma_context(mca_btl_uct_module_t *module)
{
    return mca_btl_uct_module_get_tl_context_specific(module, module->rdma_tl,
                                                      mca_btl_uct_get_context_index());
}

static inline mca_btl_uct_device_context_t *
mca_btl_uct_module_get_rdma_context_specific(mca_btl_uct_module_t *module, int context_id)
{
    return mca_btl_uct_module_get_tl_context_specific(module, module->rdma_tl, context_id);
}

static inline mca_btl_uct_device_context_t *
mca_btl_uct_module_get_am_context(mca_btl_uct_module_t *module)
{
    return mca_btl_uct_module_get_tl_context_specific(module, module->am_tl,
                                                      mca_btl_uct_get_context_index());
}

static inline void mca_btl_uct_device_handle_completions(mca_btl_uct_device_context_t *dev_context)
{
    mca_btl_uct_uct_completion_t *comp;

    while (
        NULL
        != (comp = (mca_btl_uct_uct_completion_t *) opal_fifo_pop(&dev_context->completion_fifo))) {
        int rc = UCS_OK == comp->status ? OPAL_SUCCESS : OPAL_ERROR;

        if (comp->frag) {
            /* reset the count */
            comp->uct_comp.count = 1;
            mca_btl_uct_frag_complete(comp->frag, rc);

            continue;
        }

        /* we may be calling the callback before remote completion. this is in violation of the
         * btl interface specification but should not hurt in non-ob1 use cases. if this ever
         * becomes a problem we can look at possible solutions. */
        comp->cbfunc(comp->btl, comp->endpoint, comp->local_address, comp->local_handle,
                     comp->cbcontext, comp->cbdata, rc);
        mca_btl_uct_uct_completion_release(comp);
    }
}

static inline int mca_btl_uct_context_progress(mca_btl_uct_device_context_t *context)
{
    int ret = 0;

    if (!context->uct_worker) {
        return 0;
    }

    if (!mca_btl_uct_context_trylock(context)) {
        ret = uct_worker_progress(context->uct_worker);
        mca_btl_uct_context_unlock(context);

        mca_btl_uct_device_handle_completions(context);
    }

    return ret;
}

#endif /* BTL_UCT_DEVICE_CONTEXT_H */