@@ -143,3 +143,152 @@ Command-line syntax to set the MCA variable:
143143 variable "mtl_ofi_thread_grouping" set to 1, the MTL will use multiple
144144 contexts, but the benefits may be negligible as only one thread is driving
145145 progress.
146+
147+ SPECIALIZED FUNCTIONS:
148+ -------------------
149+ To improve performance when calling message passing APIs in the OFI mtl
150+ specialized functions are generated at compile time that eliminate all the
151+ if conditionals that can be determined at init and don't need to be
152+ queried again during the critical path. These functions are generated by
153+ perl scripts during make which generate functions and symbols for every
154+ combination of flags for each function.
155+
156+ 1. ADDING NEW FLAGS FOR SPECIALIZATION OF EXISTING FUNCTION:
157+ To add a new flag to an existing specialized function for handling cases
158+ where different OFI providers may or may not support a particular feature,
159+ then you must follow these steps:
160+ 1) Update the "_generic" function in mtl_ofi.h with the new flag and
161+ the if conditionals to read the new value.
162+ 2) Update the *.pm file corresponding to the function with the new flag in:
163+ gen_funcs(), gen_*_function(), & gen_*_sym_init()
164+ 3) Update mtl_ofi_opt.h with:
165+ The new flag as #define NEW_FLAG_TYPES #NUMBER_OF_STATES
166+ example: #define OFI_CQ_DATA 2 (only has TRUE/FALSE states)
167+ Update the function's types with:
168+ #define OMPI_MTL_OFI_FUNCTION_TYPES [NEW_FLAG_TYPES]
169+
170+ 2. ADDING A NEW FUNCTION FOR SPECIALIZATION:
171+ To add a new function to be specialized you must
172+ follow these steps:
173+ 1) Create a new mtl_ofi_"function_name"_opt.pm based off opt_common/mtl_ofi_opt.pm.template
174+ 2) Add new .pm file to generated_source_modules in Makefile.am
175+ 3) Add .c file to generated_sources in Makefile.am named the same as the corresponding .pm file
176+ 4) Update existing or create function in mtl_ofi.h to _generic with new flags.
177+ 5) Update mtl_ofi_opt.h with:
178+ a) New function types: #define OMPI_MTL_OFI_FUNCTION_TYPES [FLAG_TYPES]
179+ b) Add new function to the struct ompi_mtl_ofi_symtable:
180+ struct ompi_mtl_ofi_symtable {
181+ ...
182+ int (*ompi_mtl_ofi_FUNCTION OMPI_MTL_OFI_FUNCTION_TYPES )
183+ }
184+ c) Add new symbol table init function definition:
185+ void ompi_mtl_ofi_FUNCTION_symtable_init(struct ompi_mtl_ofi_symtable* sym_table);
186+ 6) Add calls to init the new function in the symbol table and assign the function
187+ pointer to be used based off the flags in mtl_ofi_component.c:
188+ ompi_mtl_ofi_FUNCTION_symtable_init(&ompi_mtl_ofi.sym_table);
189+ ompi_mtl_ofi.base.mtl_FUNCTION =
190+ ompi_mtl_ofi.sym_table.ompi_mtl_ofi_FUNCTION[ompi_mtl_ofi.flag];
191+
192+ 3. EXAMPLE SPECIALIZED FILE:
193+ The code below is an example of what is generated by the specialization
194+ scripts for use in the OFI mtl. This code specializes the blocking
195+ send functionality based on FI_REMOTE_CQ_DATA & OFI Scalable Endpoint support
196+ provided by an OFI Provider. Only one function and symbol is used during
197+ runtime based on if FI_REMOTE_CQ_DATA is supported and/or if OFI Scalable
198+ Endpoint support is enabled.
199+ /*
200+ * Copyright (c) 2013-2018 Intel, Inc. All rights reserved
201+ *
202+ * $COPYRIGHT$
203+ *
204+ * Additional copyrights may follow
205+ *
206+ * $HEADER$
207+ */
208+
209+ #include "mtl_ofi.h"
210+
211+ __opal_attribute_always_inline__ static inline int
212+ ompi_mtl_ofi_send_false_false(struct mca_mtl_base_module_t *mtl,
213+ struct ompi_communicator_t *comm,
214+ int dest,
215+ int tag,
216+ struct opal_convertor_t *convertor,
217+ mca_pml_base_send_mode_t mode)
218+ {
219+ const bool OFI_CQ_DATA = false;
220+ const bool OFI_SCEP_EPS = false;
221+
222+ return ompi_mtl_ofi_send_generic(mtl, comm, dest, tag,
223+ convertor, mode,
224+ OFI_CQ_DATA, OFI_SCEP_EPS);
225+ }
226+
227+ __opal_attribute_always_inline__ static inline int
228+ ompi_mtl_ofi_send_false_true(struct mca_mtl_base_module_t *mtl,
229+ struct ompi_communicator_t *comm,
230+ int dest,
231+ int tag,
232+ struct opal_convertor_t *convertor,
233+ mca_pml_base_send_mode_t mode)
234+ {
235+ const bool OFI_CQ_DATA = false;
236+ const bool OFI_SCEP_EPS = true;
237+
238+ return ompi_mtl_ofi_send_generic(mtl, comm, dest, tag,
239+ convertor, mode,
240+ OFI_CQ_DATA, OFI_SCEP_EPS);
241+ }
242+
243+ __opal_attribute_always_inline__ static inline int
244+ ompi_mtl_ofi_send_true_false(struct mca_mtl_base_module_t *mtl,
245+ struct ompi_communicator_t *comm,
246+ int dest,
247+ int tag,
248+ struct opal_convertor_t *convertor,
249+ mca_pml_base_send_mode_t mode)
250+ {
251+ const bool OFI_CQ_DATA = true;
252+ const bool OFI_SCEP_EPS = false;
253+
254+ return ompi_mtl_ofi_send_generic(mtl, comm, dest, tag,
255+ convertor, mode,
256+ OFI_CQ_DATA, OFI_SCEP_EPS);
257+ }
258+
259+ __opal_attribute_always_inline__ static inline int
260+ ompi_mtl_ofi_send_true_true(struct mca_mtl_base_module_t *mtl,
261+ struct ompi_communicator_t *comm,
262+ int dest,
263+ int tag,
264+ struct opal_convertor_t *convertor,
265+ mca_pml_base_send_mode_t mode)
266+ {
267+ const bool OFI_CQ_DATA = true;
268+ const bool OFI_SCEP_EPS = true;
269+
270+ return ompi_mtl_ofi_send_generic(mtl, comm, dest, tag,
271+ convertor, mode,
272+ OFI_CQ_DATA, OFI_SCEP_EPS);
273+ }
274+
275+ void ompi_mtl_ofi_send_symtable_init(struct ompi_mtl_ofi_symtable* sym_table)
276+ {
277+
278+ sym_table->ompi_mtl_ofi_send[false][false]
279+ = ompi_mtl_ofi_send_false_false;
280+
281+
282+ sym_table->ompi_mtl_ofi_send[false][true]
283+ = ompi_mtl_ofi_send_false_true;
284+
285+
286+ sym_table->ompi_mtl_ofi_send[true][false]
287+ = ompi_mtl_ofi_send_true_false;
288+
289+
290+ sym_table->ompi_mtl_ofi_send[true][true]
291+ = ompi_mtl_ofi_send_true_true;
292+
293+ }
294+ ###
0 commit comments