1
1

MTL_OFI: Generation of specialized functions at build time

-> Added new targets in Makefile.am to call a new build script
   generate-opt-funcs.pl to generate specialized functions for
   each *.pm file.

-> Added new perl module *.pm files for send,isend,irecv,iprobe,improbe
   which are loaded by generate-opt-funcs.pl to create new source files
   that correspond to the name of the .pm file to be used as part of
   MTL OFI.

-> Added mtl_ofi_opt.pm.template and updated README with details on the
   specialization features and how to add additional specialization
   support.

-> Added new opt_common/mtl_ofi_opt_common.pm containing common
   functions for generating the specialized functions used by
   all other *.pm modules.

-> Added new mtl_ofi.h which includes the definitions for the
   function symbol table for storing the specialized functions along
   with the definitions for the initialization functions for the
   corresponding function pointers.

-> Based off the OFI provider capabilities the specialized function
   pointers are assigned at mtl_ofi_component_init to the corresponding
   MTL OFI function.

-> mca_mtl_ofi_module_t has been updated with the symbol table
   struct which is assigned at component init.

Signed-off-by: Spruit, Neil R <neil.r.spruit@intel.com>
Этот коммит содержится в:
Spruit, Neil R 2018-10-17 07:13:55 -07:00
родитель 1cd1f4acfd
Коммит bef5f50a42
15 изменённых файлов: 933 добавлений и 29 удалений

Просмотреть файл

@ -12,12 +12,30 @@
# $HEADER$
#
EXTRA_DIST = post_configure.sh
EXTRA_DIST = post_configure.sh \
$(generated_source_modules)
MAINTAINERCLEANFILES = \
$(generated_sources)
AM_CPPFLAGS = $(ompi_mtl_ofi_CPPFLAGS) $(opal_common_ofi_CPPFLAGS)
dist_ompidata_DATA = help-mtl-ofi.txt
generated_source_modules = \
mtl_ofi_send_opt.pm \
mtl_ofi_isend_opt.pm \
mtl_ofi_irecv_opt.pm \
mtl_ofi_iprobe_opt.pm \
mtl_ofi_improbe_opt.pm
generated_sources = \
mtl_ofi_send_opt.c \
mtl_ofi_isend_opt.c \
mtl_ofi_irecv_opt.c \
mtl_ofi_iprobe_opt.c \
mtl_ofi_improbe_opt.c
mtl_ofi_sources = \
mtl_ofi.h \
mtl_ofi.c \
@ -26,7 +44,18 @@ mtl_ofi_sources = \
mtl_ofi_endpoint.h \
mtl_ofi_endpoint.c \
mtl_ofi_request.h \
mtl_ofi_types.h
mtl_ofi_types.h \
mtl_ofi_opt.h \
$(generated_sources)
# A number of files are generated from macro expansion to minimize
# branches in the critical path. These files have perl modules with the suffix
# .pm that generate the corresponding .c file with all possible branches as
# their own function and symbol. Additional input
# files should be added to generated_source_modules, as well as adding
# their .c variants to generated_sources.
%.c : %.pm;
$(PERL) generate-opt-funcs.pl $@
# Make the output library in this directory, and name it either
# mca_<type>_<name>.la (for DSO builds) or libmca_<type>_<name>.la

Просмотреть файл

@ -143,3 +143,152 @@ Command-line syntax to set the MCA variable:
variable "mtl_ofi_thread_grouping" set to 1, the MTL will use multiple
contexts, but the benefits may be negligible as only one thread is driving
progress.
SPECIALIZED FUNCTIONS:
-------------------
To improve performance when calling message passing APIs in the OFI mtl
specialized functions are generated at compile time that eliminate all the
if conditionals that can be determined at init and don't need to be
queried again during the critical path. These functions are generated by
perl scripts during make which generate functions and symbols for every
combination of flags for each function.
1. ADDING NEW FLAGS FOR SPECIALIZATION OF EXISTING FUNCTION:
To add a new flag to an existing specialized function for handling cases
where different OFI providers may or may not support a particular feature,
then you must follow these steps:
1) Update the "_generic" function in mtl_ofi.h with the new flag and
the if conditionals to read the new value.
2) Update the *.pm file corresponding to the function with the new flag in:
gen_funcs(), gen_*_function(), & gen_*_sym_init()
3) Update mtl_ofi_opt.h with:
The new flag as #define NEW_FLAG_TYPES #NUMBER_OF_STATES
example: #define OFI_CQ_DATA 2 (only has TRUE/FALSE states)
Update the function's types with:
#define OMPI_MTL_OFI_FUNCTION_TYPES [NEW_FLAG_TYPES]
2. ADDING A NEW FUNCTION FOR SPECIALIZATION:
To add a new function to be specialized you must
follow these steps:
1) Create a new mtl_ofi_"function_name"_opt.pm based off opt_common/mtl_ofi_opt.pm.template
2) Add new .pm file to generated_source_modules in Makefile.am
3) Add .c file to generated_sources in Makefile.am named the same as the corresponding .pm file
4) Update existing or create function in mtl_ofi.h to _generic with new flags.
5) Update mtl_ofi_opt.h with:
a) New function types: #define OMPI_MTL_OFI_FUNCTION_TYPES [FLAG_TYPES]
b) Add new function to the struct ompi_mtl_ofi_symtable:
struct ompi_mtl_ofi_symtable {
...
int (*ompi_mtl_ofi_FUNCTION OMPI_MTL_OFI_FUNCTION_TYPES )
}
c) Add new symbol table init function definition:
void ompi_mtl_ofi_FUNCTION_symtable_init(struct ompi_mtl_ofi_symtable* sym_table);
6) Add calls to init the new function in the symbol table and assign the function
pointer to be used based off the flags in mtl_ofi_component.c:
ompi_mtl_ofi_FUNCTION_symtable_init(&ompi_mtl_ofi.sym_table);
ompi_mtl_ofi.base.mtl_FUNCTION =
ompi_mtl_ofi.sym_table.ompi_mtl_ofi_FUNCTION[ompi_mtl_ofi.flag];
3. EXAMPLE SPECIALIZED FILE:
The code below is an example of what is generated by the specialization
scripts for use in the OFI mtl. This code specializes the blocking
send functionality based on FI_REMOTE_CQ_DATA & OFI Scalable Endpoint support
provided by an OFI Provider. Only one function and symbol is used during
runtime based on if FI_REMOTE_CQ_DATA is supported and/or if OFI Scalable
Endpoint support is enabled.
/*
* Copyright (c) 2013-2018 Intel, Inc. All rights reserved
*
* $COPYRIGHT$
*
* Additional copyrights may follow
*
* $HEADER$
*/
#include "mtl_ofi.h"
__opal_attribute_always_inline__ static inline int
ompi_mtl_ofi_send_false_false(struct mca_mtl_base_module_t *mtl,
struct ompi_communicator_t *comm,
int dest,
int tag,
struct opal_convertor_t *convertor,
mca_pml_base_send_mode_t mode)
{
const bool OFI_CQ_DATA = false;
const bool OFI_SCEP_EPS = false;
return ompi_mtl_ofi_send_generic(mtl, comm, dest, tag,
convertor, mode,
OFI_CQ_DATA, OFI_SCEP_EPS);
}
__opal_attribute_always_inline__ static inline int
ompi_mtl_ofi_send_false_true(struct mca_mtl_base_module_t *mtl,
struct ompi_communicator_t *comm,
int dest,
int tag,
struct opal_convertor_t *convertor,
mca_pml_base_send_mode_t mode)
{
const bool OFI_CQ_DATA = false;
const bool OFI_SCEP_EPS = true;
return ompi_mtl_ofi_send_generic(mtl, comm, dest, tag,
convertor, mode,
OFI_CQ_DATA, OFI_SCEP_EPS);
}
__opal_attribute_always_inline__ static inline int
ompi_mtl_ofi_send_true_false(struct mca_mtl_base_module_t *mtl,
struct ompi_communicator_t *comm,
int dest,
int tag,
struct opal_convertor_t *convertor,
mca_pml_base_send_mode_t mode)
{
const bool OFI_CQ_DATA = true;
const bool OFI_SCEP_EPS = false;
return ompi_mtl_ofi_send_generic(mtl, comm, dest, tag,
convertor, mode,
OFI_CQ_DATA, OFI_SCEP_EPS);
}
__opal_attribute_always_inline__ static inline int
ompi_mtl_ofi_send_true_true(struct mca_mtl_base_module_t *mtl,
struct ompi_communicator_t *comm,
int dest,
int tag,
struct opal_convertor_t *convertor,
mca_pml_base_send_mode_t mode)
{
const bool OFI_CQ_DATA = true;
const bool OFI_SCEP_EPS = true;
return ompi_mtl_ofi_send_generic(mtl, comm, dest, tag,
convertor, mode,
OFI_CQ_DATA, OFI_SCEP_EPS);
}
void ompi_mtl_ofi_send_symtable_init(struct ompi_mtl_ofi_symtable* sym_table)
{
sym_table->ompi_mtl_ofi_send[false][false]
= ompi_mtl_ofi_send_false_false;
sym_table->ompi_mtl_ofi_send[false][true]
= ompi_mtl_ofi_send_false_true;
sym_table->ompi_mtl_ofi_send[true][false]
= ompi_mtl_ofi_send_true_false;
sym_table->ompi_mtl_ofi_send[true][true]
= ompi_mtl_ofi_send_true_true;
}
###

62
ompi/mca/mtl/ofi/generate-opt-funcs.pl Обычный файл
Просмотреть файл

@ -0,0 +1,62 @@
#!/usr/bin/env perl
#
# Copyright (c) 2013-2018 Intel, Inc. All rights reserved
#
# $COPYRIGHT$
#
# Additional copyrights may follow
#
# $HEADER$
#
use strict;
use warnings;
use mtl_ofi_send_opt;
use mtl_ofi_isend_opt;
use mtl_ofi_irecv_opt;
use mtl_ofi_iprobe_opt;
use mtl_ofi_improbe_opt;
use opt_common::mtl_ofi_opt_common;
my $MTL_OFI_HEADER =
'/*
* Copyright (c) 2013-2018 Intel, Inc. All rights reserved
*
* $COPYRIGHT$
*
* Additional copyrights may follow
*
* $HEADER$
*/
#include "mtl_ofi.h"';
my $specialization_file = $ARGV[0];
my $specialization_type = $specialization_file;
$specialization_type =~ s{\.[^.]+$}{};
my $sym_table_type = $specialization_type;
$sym_table_type =~ s/_opt//g;
open my $gen_file, ">", $specialization_file;
#
# Generate the Specialized functions & symbol table for the specified file.
#
print $gen_file "$MTL_OFI_HEADER\n\n";
my $GEN_FUNC = $specialization_type . "::gen_funcs\(\$gen_file, \"FUNC\"\)";
my $GEN_SYM = $specialization_type . "::gen_funcs\(\$gen_file, \"SYM\"\)";
my $SYM_TABLE = "ompi_" . $sym_table_type . "_symtable";
eval $GEN_FUNC;
my $SYM_FUNC_HEADER = opt_common::mtl_ofi_opt_common::gen_sym_function_header($SYM_TABLE);
print $gen_file "$SYM_FUNC_HEADER\n";
eval $GEN_SYM;
my $SYM_FUNC_FOOTER = opt_common::mtl_ofi_opt_common::gen_sym_function_footer();
print $gen_file "$SYM_FUNC_FOOTER\n\n";
close($gen_file);
exit(0);
###

Просмотреть файл

@ -23,12 +23,12 @@ mca_mtl_ofi_module_t ompi_mtl_ofi = {
ompi_mtl_ofi_del_procs,
ompi_mtl_ofi_finalize,
ompi_mtl_ofi_send,
ompi_mtl_ofi_isend,
ompi_mtl_ofi_irecv,
ompi_mtl_ofi_iprobe,
ompi_mtl_ofi_imrecv,
ompi_mtl_ofi_improbe,
NULL,
NULL,
NULL,
NULL,
ompi_mtl_ofi_imrecv,
NULL,
ompi_mtl_ofi_cancel,
ompi_mtl_ofi_add_comm,

Просмотреть файл

@ -37,6 +37,7 @@
#include "ompi/mca/mtl/base/mtl_base_datatype.h"
#include "ompi/message/message.h"
#include "mtl_ofi_opt.h"
#include "mtl_ofi_types.h"
#include "mtl_ofi_request.h"
#include "mtl_ofi_endpoint.h"
@ -384,12 +385,13 @@ ompi_mtl_ofi_ssend_recv(ompi_mtl_ofi_request_t *ack_req,
}
__opal_attribute_always_inline__ static inline int
ompi_mtl_ofi_send(struct mca_mtl_base_module_t *mtl,
ompi_mtl_ofi_send_generic(struct mca_mtl_base_module_t *mtl,
struct ompi_communicator_t *comm,
int dest,
int tag,
struct opal_convertor_t *convertor,
mca_pml_base_send_mode_t mode)
mca_pml_base_send_mode_t mode,
bool ofi_cq_data)
{
ssize_t ret = OMPI_SUCCESS;
ompi_mtl_ofi_request_t ofi_req;
@ -427,7 +429,7 @@ ompi_mtl_ofi_send(struct mca_mtl_base_module_t *mtl,
ofi_req.status.MPI_ERROR = OMPI_SUCCESS;
ofi_req.completion_count = 0;
if (ompi_mtl_ofi.fi_cq_data) {
if (ofi_cq_data) {
match_bits = mtl_ofi_create_send_tag_CQD(comm->c_contextid, tag);
src_addr = sep_peer_fiaddr;
} else {
@ -445,7 +447,7 @@ ompi_mtl_ofi_send(struct mca_mtl_base_module_t *mtl,
}
if (ompi_mtl_ofi.max_inject_size >= length) {
if (ompi_mtl_ofi.fi_cq_data) {
if (ofi_cq_data) {
MTL_OFI_RETRY_UNTIL_DONE(fi_tinjectdata(ompi_mtl_ofi.ofi_ctxt[ctxt_id].tx_ep,
start,
length,
@ -461,7 +463,7 @@ ompi_mtl_ofi_send(struct mca_mtl_base_module_t *mtl,
}
if (OPAL_UNLIKELY(0 > ret)) {
MTL_OFI_LOG_FI_ERR(ret,
ompi_mtl_ofi.fi_cq_data ? "fi_tinjectdata failed"
ofi_cq_data ? "fi_tinjectdata failed"
: "fi_tinject failed");
if (ack_req) {
fi_cancel((fid_t)ompi_mtl_ofi.ofi_ctxt[ctxt_id].tx_ep, &ack_req->ctx);
@ -473,7 +475,7 @@ ompi_mtl_ofi_send(struct mca_mtl_base_module_t *mtl,
}
} else {
ofi_req.completion_count += 1;
if (ompi_mtl_ofi.fi_cq_data) {
if (ofi_cq_data) {
MTL_OFI_RETRY_UNTIL_DONE(fi_tsenddata(ompi_mtl_ofi.ofi_ctxt[ctxt_id].tx_ep,
start,
length,
@ -493,7 +495,7 @@ ompi_mtl_ofi_send(struct mca_mtl_base_module_t *mtl,
}
if (OPAL_UNLIKELY(0 > ret)) {
MTL_OFI_LOG_FI_ERR(ret,
ompi_mtl_ofi.fi_cq_data ? "fi_tsenddata failed"
ofi_cq_data ? "fi_tsenddata failed"
: "fi_tsend failed");
ofi_req.status.MPI_ERROR = ompi_mtl_ofi_get_error(ret);
goto free_request_buffer;
@ -517,14 +519,15 @@ free_request_buffer:
}
__opal_attribute_always_inline__ static inline int
ompi_mtl_ofi_isend(struct mca_mtl_base_module_t *mtl,
ompi_mtl_ofi_isend_generic(struct mca_mtl_base_module_t *mtl,
struct ompi_communicator_t *comm,
int dest,
int tag,
struct opal_convertor_t *convertor,
mca_pml_base_send_mode_t mode,
bool blocking,
mca_mtl_request_t *mtl_request)
mca_mtl_request_t *mtl_request,
bool ofi_cq_data)
{
ssize_t ret = OMPI_SUCCESS;
ompi_mtl_ofi_request_t *ofi_req = (ompi_mtl_ofi_request_t *) mtl_request;
@ -558,7 +561,7 @@ ompi_mtl_ofi_isend(struct mca_mtl_base_module_t *mtl,
ofi_req->status.MPI_ERROR = OMPI_SUCCESS;
ofi_req->completion_count = 1;
if (ompi_mtl_ofi.fi_cq_data) {
if (ofi_cq_data) {
match_bits = mtl_ofi_create_send_tag_CQD(comm->c_contextid, tag);
} else {
match_bits = mtl_ofi_create_send_tag(comm->c_contextid,
@ -574,7 +577,7 @@ ompi_mtl_ofi_isend(struct mca_mtl_base_module_t *mtl,
goto free_request_buffer;
}
if (ompi_mtl_ofi.fi_cq_data) {
if (ofi_cq_data) {
MTL_OFI_RETRY_UNTIL_DONE(fi_tsenddata(ompi_mtl_ofi.ofi_ctxt[ctxt_id].tx_ep,
start,
length,
@ -594,7 +597,7 @@ ompi_mtl_ofi_isend(struct mca_mtl_base_module_t *mtl,
}
if (OPAL_UNLIKELY(0 > ret)) {
MTL_OFI_LOG_FI_ERR(ret,
ompi_mtl_ofi.fi_cq_data ? "fi_tsenddata failed"
ofi_cq_data ? "fi_tsenddata failed"
: "fi_tsend failed");
ofi_req->status.MPI_ERROR = ompi_mtl_ofi_get_error(ret);
}
@ -745,12 +748,13 @@ ompi_mtl_ofi_recv_error_callback(struct fi_cq_err_entry *error,
}
__opal_attribute_always_inline__ static inline int
ompi_mtl_ofi_irecv(struct mca_mtl_base_module_t *mtl,
ompi_mtl_ofi_irecv_generic(struct mca_mtl_base_module_t *mtl,
struct ompi_communicator_t *comm,
int src,
int tag,
struct opal_convertor_t *convertor,
mca_mtl_request_t *mtl_request)
mca_mtl_request_t *mtl_request,
bool ofi_cq_data)
{
int ompi_ret = OMPI_SUCCESS, ctxt_id = 0;
ssize_t ret;
@ -766,7 +770,7 @@ ompi_mtl_ofi_irecv(struct mca_mtl_base_module_t *mtl,
MTL_OFI_MAP_COMM_TO_CONTEXT(comm->c_contextid, ctxt_id);
set_thread_context(ctxt_id);
if (ompi_mtl_ofi.fi_cq_data) {
if (ofi_cq_data) {
if (MPI_ANY_SOURCE != src) {
ompi_proc = ompi_comm_peer_lookup(comm, src);
endpoint = ompi_mtl_ofi_get_endpoint(mtl, ompi_proc);
@ -964,12 +968,13 @@ ompi_mtl_ofi_probe_error_callback(struct fi_cq_err_entry *error,
}
__opal_attribute_always_inline__ static inline int
ompi_mtl_ofi_iprobe(struct mca_mtl_base_module_t *mtl,
ompi_mtl_ofi_iprobe_generic(struct mca_mtl_base_module_t *mtl,
struct ompi_communicator_t *comm,
int src,
int tag,
int *flag,
struct ompi_status_public_t *status)
struct ompi_status_public_t *status,
bool ofi_cq_data)
{
struct ompi_mtl_ofi_request_t ofi_req;
ompi_proc_t *ompi_proc = NULL;
@ -984,7 +989,7 @@ ompi_mtl_ofi_iprobe(struct mca_mtl_base_module_t *mtl,
MTL_OFI_MAP_COMM_TO_CONTEXT(comm->c_contextid, ctxt_id);
set_thread_context(ctxt_id);
if (ompi_mtl_ofi.fi_cq_data) {
if (ofi_cq_data) {
/* If the source is known, use its peer_fiaddr. */
if (MPI_ANY_SOURCE != src) {
ompi_proc = ompi_comm_peer_lookup( comm, src );
@ -1051,13 +1056,14 @@ ompi_mtl_ofi_iprobe(struct mca_mtl_base_module_t *mtl,
}
__opal_attribute_always_inline__ static inline int
ompi_mtl_ofi_improbe(struct mca_mtl_base_module_t *mtl,
ompi_mtl_ofi_improbe_generic(struct mca_mtl_base_module_t *mtl,
struct ompi_communicator_t *comm,
int src,
int tag,
int *matched,
struct ompi_message_t **message,
struct ompi_status_public_t *status)
struct ompi_status_public_t *status,
bool ofi_cq_data)
{
struct ompi_mtl_ofi_request_t *ofi_req;
ompi_proc_t *ompi_proc = NULL;
@ -1081,7 +1087,7 @@ ompi_mtl_ofi_improbe(struct mca_mtl_base_module_t *mtl,
* If the source is known, use its peer_fiaddr.
*/
if (ompi_mtl_ofi.fi_cq_data) {
if (ofi_cq_data) {
if (MPI_ANY_SOURCE != src) {
ompi_proc = ompi_comm_peer_lookup( comm, src );
endpoint = ompi_mtl_ofi_get_endpoint(mtl, ompi_proc);
@ -1437,6 +1443,77 @@ ompi_mtl_ofi_del_comm(struct mca_mtl_base_module_t *mtl,
return ret;
}
#ifdef MCA_ompi_mtl_DIRECT_CALL
__opal_attribute_always_inline__ static inline int
ompi_mtl_ofi_send(struct mca_mtl_base_module_t *mtl,
struct ompi_communicator_t *comm,
int dest,
int tag,
struct opal_convertor_t *convertor,
mca_pml_base_send_mode_t mode)
{
return ompi_mtl_ofi_send_generic(mtl, comm, dest, tag,
convertor, mode,
ompi_mtl_ofi.fi_cq_data);
}
__opal_attribute_always_inline__ static inline int
ompi_mtl_ofi_isend(struct mca_mtl_base_module_t *mtl,
struct ompi_communicator_t *comm,
int dest,
int tag,
struct opal_convertor_t *convertor,
mca_pml_base_send_mode_t mode,
bool blocking,
mca_mtl_request_t *mtl_request)
{
return ompi_mtl_ofi_isend_generic(mtl, comm, dest, tag,
convertor, mode, blocking, mtl_request,
ompi_mtl_ofi.fi_cq_data);
}
__opal_attribute_always_inline__ static inline int
ompi_mtl_ofi_irecv(struct mca_mtl_base_module_t *mtl,
struct ompi_communicator_t *comm,
int src,
int tag,
struct opal_convertor_t *convertor,
mca_mtl_request_t *mtl_request)
{
return ompi_mtl_ofi_irecv_generic(mtl, comm, src, tag,
convertor, mtl_request,
ompi_mtl_ofi.fi_cq_data);
}
__opal_attribute_always_inline__ static inline int
ompi_mtl_ofi_iprobe(struct mca_mtl_base_module_t *mtl,
struct ompi_communicator_t *comm,
int src,
int tag,
int *flag,
struct ompi_status_public_t *status)
{
return ompi_mtl_ofi_iprobe_generic(mtl, comm, src, tag,
flag, status,
ompi_mtl_ofi.fi_cq_data);
}
__opal_attribute_always_inline__ static inline int
ompi_mtl_ofi_improbe(struct mca_mtl_base_module_t *mtl,
struct ompi_communicator_t *comm,
int src,
int tag,
int *matched,
struct ompi_message_t **message,
struct ompi_status_public_t *status)
{
return ompi_mtl_ofi_improbe_generic(mtl, comm, src, tag,
matched, message, status,
ompi_mtl_ofi.fi_cq_data);
}
#endif
END_C_DECLS
#endif /* MTL_OFI_H_HAS_BEEN_INCLUDED */

Просмотреть файл

@ -740,6 +740,31 @@ ompi_mtl_ofi_component_init(bool enable_progress_threads,
ompi_mtl_ofi_define_tag_mode(ofi_tag_mode, &ofi_tag_bits_for_cid);
}
/**
* Initialize the MTL OFI Symbol Tables & function pointers
* for specialized functions.
*/
ompi_mtl_ofi_send_symtable_init(&ompi_mtl_ofi.sym_table);
ompi_mtl_ofi.base.mtl_send =
ompi_mtl_ofi.sym_table.ompi_mtl_ofi_send[ompi_mtl_ofi.fi_cq_data];
ompi_mtl_ofi_isend_symtable_init(&ompi_mtl_ofi.sym_table);
ompi_mtl_ofi.base.mtl_isend =
ompi_mtl_ofi.sym_table.ompi_mtl_ofi_isend[ompi_mtl_ofi.fi_cq_data];
ompi_mtl_ofi_irecv_symtable_init(&ompi_mtl_ofi.sym_table);
ompi_mtl_ofi.base.mtl_irecv =
ompi_mtl_ofi.sym_table.ompi_mtl_ofi_irecv[ompi_mtl_ofi.fi_cq_data];
ompi_mtl_ofi_iprobe_symtable_init(&ompi_mtl_ofi.sym_table);
ompi_mtl_ofi.base.mtl_iprobe =
ompi_mtl_ofi.sym_table.ompi_mtl_ofi_iprobe[ompi_mtl_ofi.fi_cq_data];
ompi_mtl_ofi_improbe_symtable_init(&ompi_mtl_ofi.sym_table);
ompi_mtl_ofi.base.mtl_improbe =
ompi_mtl_ofi.sym_table.ompi_mtl_ofi_improbe[ompi_mtl_ofi.fi_cq_data];
/**
* Check for potential bits in the OFI tag that providers may be reserving
* for internal usage (see mem_tag_format in fi_endpoint man page).

73
ompi/mca/mtl/ofi/mtl_ofi_improbe_opt.pm Обычный файл
Просмотреть файл

@ -0,0 +1,73 @@
#!/usr/bin/env perl
#
# Copyright (c) 2013-2018 Intel, Inc. All rights reserved
#
# $COPYRIGHT$
#
# Additional copyrights may follow
#
# $HEADER$
#
use strict;
use warnings;
use opt_common::mtl_ofi_opt_common;
package mtl_ofi_improbe_opt;
my @true_false = ("false", "true");
sub gen_funcs {
my $gen_file = $_[0];
my $gen_type = $_[1];
my $OFI_CQ_DATA_EN = "false";
foreach $OFI_CQ_DATA_EN (@true_false) {
my @flags = ($OFI_CQ_DATA_EN);
if (($gen_type cmp "FUNC") == 0) {
my $FUNC = gen_improbe_function(\@flags);
print $gen_file "$FUNC\n\n";
}
if (($gen_type cmp "SYM") == 0) {
my $SYM = gen_improbe_sym_init(\@flags);
print $gen_file "$SYM\n";
}
}
}
sub gen_improbe_function {
my @op_flags = @{$_[0]};
my $MTL_OFI_NAME_EXT = opt_common::mtl_ofi_opt_common::gen_flags_ext(\@op_flags);
my $OFI_CQ_DATA_EN = $op_flags[0];
my $IMPROBE_FUNCTION =
"__opal_attribute_always_inline__ static inline int
ompi_mtl_ofi_improbe_" . $MTL_OFI_NAME_EXT . "(struct mca_mtl_base_module_t *mtl,
struct ompi_communicator_t *comm,
int src,
int tag,
int *matched,
struct ompi_message_t **message,
struct ompi_status_public_t *status)
{
const bool OFI_CQ_DATA = " . $OFI_CQ_DATA_EN . ";
return ompi_mtl_ofi_improbe_generic(mtl, comm, src, tag,
matched, message, status,
OFI_CQ_DATA);
}";
return $IMPROBE_FUNCTION;
}
sub gen_improbe_sym_init {
my @op_flags = @{$_[0]};
my $MTL_OFI_FUNC_NAME = "ompi_mtl_ofi_improbe_" . opt_common::mtl_ofi_opt_common::gen_flags_ext(\@op_flags) . "";
my $OFI_CQ_DATA_EN = $op_flags[0];
my $symbol_init =
"
sym_table->ompi_mtl_ofi_improbe[".$OFI_CQ_DATA_EN."]
= ".$MTL_OFI_FUNC_NAME.";
";
return $symbol_init;
}
1;

72
ompi/mca/mtl/ofi/mtl_ofi_iprobe_opt.pm Обычный файл
Просмотреть файл

@ -0,0 +1,72 @@
#!/usr/bin/env perl
#
# Copyright (c) 2013-2018 Intel, Inc. All rights reserved
#
# $COPYRIGHT$
#
# Additional copyrights may follow
#
# $HEADER$
#
use strict;
use warnings;
use opt_common::mtl_ofi_opt_common;
package mtl_ofi_iprobe_opt;
my @true_false = ("false", "true");
sub gen_funcs {
my $gen_file = $_[0];
my $gen_type = $_[1];
my $OFI_CQ_DATA_EN = "false";
foreach $OFI_CQ_DATA_EN (@true_false) {
my @flags = ($OFI_CQ_DATA_EN);
if (($gen_type cmp "FUNC") == 0) {
my $FUNC = gen_iprobe_function(\@flags);
print $gen_file "$FUNC\n\n";
}
if (($gen_type cmp "SYM") == 0) {
my $SYM = gen_iprobe_sym_init(\@flags);
print $gen_file "$SYM\n";
}
}
}
sub gen_iprobe_function {
my @op_flags = @{$_[0]};
my $MTL_OFI_NAME_EXT = opt_common::mtl_ofi_opt_common::gen_flags_ext(\@op_flags);
my $OFI_CQ_DATA_EN = $op_flags[0];
my $IPROBE_FUNCTION =
"__opal_attribute_always_inline__ static inline int
ompi_mtl_ofi_iprobe_" . $MTL_OFI_NAME_EXT . "(struct mca_mtl_base_module_t *mtl,
struct ompi_communicator_t *comm,
int src,
int tag,
int *flag,
struct ompi_status_public_t *status)
{
const bool OFI_CQ_DATA = " . $OFI_CQ_DATA_EN . ";
return ompi_mtl_ofi_iprobe_generic(mtl, comm, src, tag,
flag, status,
OFI_CQ_DATA);
}";
return $IPROBE_FUNCTION;
}
sub gen_iprobe_sym_init {
my @op_flags = @{$_[0]};
my $MTL_OFI_FUNC_NAME = "ompi_mtl_ofi_iprobe_" . opt_common::mtl_ofi_opt_common::gen_flags_ext(\@op_flags) . "";
my $OFI_CQ_DATA_EN = $op_flags[0];
my $symbol_init =
"
sym_table->ompi_mtl_ofi_iprobe[".$OFI_CQ_DATA_EN."]
= ".$MTL_OFI_FUNC_NAME.";
";
return $symbol_init;
}
1;

72
ompi/mca/mtl/ofi/mtl_ofi_irecv_opt.pm Обычный файл
Просмотреть файл

@ -0,0 +1,72 @@
#!/usr/bin/env perl
#
# Copyright (c) 2013-2018 Intel, Inc. All rights reserved
#
# $COPYRIGHT$
#
# Additional copyrights may follow
#
# $HEADER$
#
use strict;
use warnings;
use opt_common::mtl_ofi_opt_common;
package mtl_ofi_irecv_opt;
my @true_false = ("false", "true");
sub gen_funcs {
my $gen_file = $_[0];
my $gen_type = $_[1];
my $OFI_CQ_DATA_EN = "false";
foreach $OFI_CQ_DATA_EN (@true_false) {
my @flags = ($OFI_CQ_DATA_EN);
if (($gen_type cmp "FUNC") == 0) {
my $FUNC = gen_irecv_function(\@flags);
print $gen_file "$FUNC\n\n";
}
if (($gen_type cmp "SYM") == 0) {
my $SYM = gen_irecv_sym_init(\@flags);
print $gen_file "$SYM\n";
}
}
}
sub gen_irecv_function {
my @op_flags = @{$_[0]};
my $MTL_OFI_NAME_EXT = opt_common::mtl_ofi_opt_common::gen_flags_ext(\@op_flags);
my $OFI_CQ_DATA_EN = $op_flags[0];
my $IRECV_FUNCTION =
"__opal_attribute_always_inline__ static inline int
ompi_mtl_ofi_irecv_" . $MTL_OFI_NAME_EXT . "(struct mca_mtl_base_module_t *mtl,
struct ompi_communicator_t *comm,
int src,
int tag,
struct opal_convertor_t *convertor,
mca_mtl_request_t *mtl_request)
{
const bool OFI_CQ_DATA = " . $OFI_CQ_DATA_EN . ";
return ompi_mtl_ofi_irecv_generic(mtl, comm, src, tag,
convertor, mtl_request,
OFI_CQ_DATA);
}";
return $IRECV_FUNCTION;
}
sub gen_irecv_sym_init {
my @op_flags = @{$_[0]};
my $MTL_OFI_FUNC_NAME = "ompi_mtl_ofi_irecv_" . opt_common::mtl_ofi_opt_common::gen_flags_ext(\@op_flags) . "";
my $OFI_CQ_DATA_EN = $op_flags[0];
my $symbol_init =
"
sym_table->ompi_mtl_ofi_irecv[".$OFI_CQ_DATA_EN."]
= ".$MTL_OFI_FUNC_NAME.";
";
return $symbol_init;
}
1;

74
ompi/mca/mtl/ofi/mtl_ofi_isend_opt.pm Обычный файл
Просмотреть файл

@ -0,0 +1,74 @@
#!/usr/bin/env perl
#
# Copyright (c) 2013-2018 Intel, Inc. All rights reserved
#
# $COPYRIGHT$
#
# Additional copyrights may follow
#
# $HEADER$
#
use strict;
use warnings;
use opt_common::mtl_ofi_opt_common;
package mtl_ofi_isend_opt;
my @true_false = ("false", "true");
sub gen_funcs {
my $gen_file = $_[0];
my $gen_type = $_[1];
my $OFI_CQ_DATA_EN = "false";
foreach $OFI_CQ_DATA_EN (@true_false) {
my @flags = ($OFI_CQ_DATA_EN);
if (($gen_type cmp "FUNC") == 0) {
my $FUNC = gen_isend_function(\@flags);
print $gen_file "$FUNC\n\n";
}
if (($gen_type cmp "SYM") == 0) {
my $SYM = gen_isend_sym_init(\@flags);
print $gen_file "$SYM\n";
}
}
}
sub gen_isend_function {
my @op_flags = @{$_[0]};
my $MTL_OFI_NAME_EXT = opt_common::mtl_ofi_opt_common::gen_flags_ext(\@op_flags);
my $OFI_CQ_DATA_EN = $op_flags[0];
my $ISEND_FUNCTION =
"__opal_attribute_always_inline__ static inline int
ompi_mtl_ofi_isend_" . $MTL_OFI_NAME_EXT . "(struct mca_mtl_base_module_t *mtl,
struct ompi_communicator_t *comm,
int dest,
int tag,
struct opal_convertor_t *convertor,
mca_pml_base_send_mode_t mode,
bool blocking,
mca_mtl_request_t *mtl_request)
{
const bool OFI_CQ_DATA = " . $OFI_CQ_DATA_EN . ";
return ompi_mtl_ofi_isend_generic(mtl, comm, dest, tag,
convertor, mode, blocking,
mtl_request, OFI_CQ_DATA);
}";
return $ISEND_FUNCTION;
}
sub gen_isend_sym_init {
my @op_flags = @{$_[0]};
my $MTL_OFI_FUNC_NAME = "ompi_mtl_ofi_isend_" . opt_common::mtl_ofi_opt_common::gen_flags_ext(\@op_flags) . "";
my $OFI_CQ_DATA_EN = $op_flags[0];
my $symbol_init =
"
sym_table->ompi_mtl_ofi_isend[".$OFI_CQ_DATA_EN."]
= ".$MTL_OFI_FUNC_NAME.";
";
return $symbol_init;
}
1;

77
ompi/mca/mtl/ofi/mtl_ofi_opt.h Обычный файл
Просмотреть файл

@ -0,0 +1,77 @@
/*
* Copyright (c) 2013-2018 Intel, Inc. All rights reserved
*
* $COPYRIGHT$
*
* Additional copyrights may follow
*
* $HEADER$
*/
#ifndef MTL_OFI_OPT_H
#define MTL_OFI_OPT_H
#include "mtl_ofi.h"
BEGIN_C_DECLS
#define CQ_DATA_TYPES 2
#define OMPI_MTL_OFI_SEND_TYPES [CQ_DATA_TYPES]
#define OMPI_MTL_OFI_ISEND_TYPES [CQ_DATA_TYPES]
#define OMPI_MTL_OFI_IRECV_TYPES [CQ_DATA_TYPES]
#define OMPI_MTL_OFI_IPROBE_TYPES [CQ_DATA_TYPES]
#define OMPI_MTL_OFI_IMPROBE_TYPES [CQ_DATA_TYPES]
struct ompi_mtl_ofi_symtable {
int (*ompi_mtl_ofi_send OMPI_MTL_OFI_SEND_TYPES )
(struct mca_mtl_base_module_t *mtl,
struct ompi_communicator_t *comm,
int dest,
int tag,
struct opal_convertor_t *convertor,
mca_pml_base_send_mode_t mode);
int (*ompi_mtl_ofi_isend OMPI_MTL_OFI_ISEND_TYPES )
(struct mca_mtl_base_module_t *mtl,
struct ompi_communicator_t *comm,
int dest,
int tag,
struct opal_convertor_t *convertor,
mca_pml_base_send_mode_t mode,
bool blocking,
mca_mtl_request_t *mtl_request);
int (*ompi_mtl_ofi_irecv OMPI_MTL_OFI_IRECV_TYPES )
(struct mca_mtl_base_module_t *mtl,
struct ompi_communicator_t *comm,
int src,
int tag,
struct opal_convertor_t *convertor,
mca_mtl_request_t *mtl_request);
int (*ompi_mtl_ofi_iprobe OMPI_MTL_OFI_IPROBE_TYPES )
(struct mca_mtl_base_module_t *mtl,
struct ompi_communicator_t *comm,
int src,
int tag,
int *flag,
struct ompi_status_public_t *status);
int (*ompi_mtl_ofi_improbe OMPI_MTL_OFI_IMPROBE_TYPES )
(struct mca_mtl_base_module_t *mtl,
struct ompi_communicator_t *comm,
int src,
int tag,
int *matched,
struct ompi_message_t **message,
struct ompi_status_public_t *status);
};
/**
* MTL OFI specialization function symbol table init
*/
void ompi_mtl_ofi_send_symtable_init(struct ompi_mtl_ofi_symtable* sym_table);
void ompi_mtl_ofi_isend_symtable_init(struct ompi_mtl_ofi_symtable* sym_table);
void ompi_mtl_ofi_irecv_symtable_init(struct ompi_mtl_ofi_symtable* sym_table);
void ompi_mtl_ofi_iprobe_symtable_init(struct ompi_mtl_ofi_symtable* sym_table);
void ompi_mtl_ofi_improbe_symtable_init(struct ompi_mtl_ofi_symtable* sym_table);
END_C_DECLS
#endif /* MTL_OFI_OPT_H */

71
ompi/mca/mtl/ofi/mtl_ofi_send_opt.pm Обычный файл
Просмотреть файл

@ -0,0 +1,71 @@
#!/usr/bin/env perl
#
# Copyright (c) 2013-2018 Intel, Inc. All rights reserved
#
# $COPYRIGHT$
#
# Additional copyrights may follow
#
# $HEADER$
#
use strict;
use warnings;
use opt_common::mtl_ofi_opt_common;
package mtl_ofi_send_opt;
my @true_false = ("false", "true");
sub gen_funcs {
my $gen_file = $_[0];
my $gen_type = $_[1];
my $OFI_CQ_DATA_EN = "false";
foreach $OFI_CQ_DATA_EN (@true_false) {
my @flags = ($OFI_CQ_DATA_EN);
if (($gen_type cmp "FUNC") == 0) {
my $FUNC = gen_send_function(\@flags);
print $gen_file "$FUNC\n\n";
}
if (($gen_type cmp "SYM") == 0) {
my $SYM = gen_send_sym_init(\@flags);
print $gen_file "$SYM\n";
}
}
}
sub gen_send_function {
my @op_flags = @{$_[0]};
my $MTL_OFI_NAME_EXT = opt_common::mtl_ofi_opt_common::gen_flags_ext(\@op_flags);
my $OFI_CQ_DATA_EN = $op_flags[0];
my $SEND_FUNCTION =
"__opal_attribute_always_inline__ static inline int
ompi_mtl_ofi_send_" . $MTL_OFI_NAME_EXT . "(struct mca_mtl_base_module_t *mtl,
struct ompi_communicator_t *comm,
int dest,
int tag,
struct opal_convertor_t *convertor,
mca_pml_base_send_mode_t mode)
{
const bool OFI_CQ_DATA = " . $OFI_CQ_DATA_EN . ";
return ompi_mtl_ofi_send_generic(mtl, comm, dest, tag,
convertor, mode,
OFI_CQ_DATA);
}";
return $SEND_FUNCTION;
}
sub gen_send_sym_init {
my @op_flags = @{$_[0]};
my $MTL_OFI_FUNC_NAME = "ompi_mtl_ofi_send_" . opt_common::mtl_ofi_opt_common::gen_flags_ext(\@op_flags) . "";
my $OFI_CQ_DATA_EN = $op_flags[0];
my $symbol_init =
"
sym_table->ompi_mtl_ofi_send[".$OFI_CQ_DATA_EN."]
= ".$MTL_OFI_FUNC_NAME.";
";
return $symbol_init;
}
1;

Просмотреть файл

@ -108,6 +108,9 @@ typedef struct mca_mtl_ofi_module_t {
unsigned long long sync_send_ack;
unsigned long long sync_proto_mask;
/** Optimized function Symbol Tables **/
struct ompi_mtl_ofi_symtable sym_table;
} mca_mtl_ofi_module_t;
extern mca_mtl_ofi_module_t ompi_mtl_ofi;

Просмотреть файл

@ -0,0 +1,66 @@
#!/usr/bin/env perl
#
# Copyright (c) 2013-2018 Intel, Inc. All rights reserved
#
# $COPYRIGHT$
#
# Additional copyrights may follow
#
# $HEADER$
#
use strict;
use warnings;
use opt_common::mtl_ofi_opt_common;
package mtl_ofi_#INSERT FUNCTION NAME HERE#_opt;
my @en_dis = (0, 1);
sub gen_funcs {
my $gen_file = $_[0];
my $gen_type = $_[1];
my $#INSERT FLAG NAME HERE# = 0;
foreach $#INSERT FLAG NAME HERE# (@en_dis) {
my @flags = ($#INSERT FLAG NAME HERE#);
if (($gen_type cmp "FUNC") == 0) {
my $FUNC = gen_#INSERT FUNCTION NAME HERE#_function(\@flags);
print $gen_file "$FUNC\n\n";
}
if (($gen_type cmp "SYM") == 0) {
my $SYM = gen_#INSERT FUNCTION NAME HERE#_sym_init(\@flags);
print $gen_file "$SYM\n";
}
}
}
sub gen_#INSERT FUNCTION NAME HERE#_function {
my @op_flags = @{$_[0]};
my $MTL_OFI_NAME_EXT = opt_common::mtl_ofi_opt_common::gen_flags_ext(\@op_flags);
my $#INSERT FLAG NAME HERE#_EN = $op_flags[0];
my $FUNCTION =
"__opal_attribute_always_inline__ static inline int
ompi_mtl_ofi_#INSERT FUNCTION NAME HERE#_" . $MTL_OFI_NAME_EXT . "(#INSERT FUNCTION ARGS HERE#)
{
const int $#INSERT FLAG NAME HERE# = " . $#INSERT FLAG NAME HERE#_EN . ";
return ompi_mtl_ofi_#INSERT FUNCTION NAME HERE#_generic(#INSERT FUNCTION ARGS HERE#,
#INSERT FLAG NAME HERE#);
}";
return $FUNCTION;
}
sub gen_#INSERT FUNCTION NAME HERE#_sym_init {
my @op_flags = @{$_[0]};
my $MTL_OFI_FUNC_NAME = "ompi_mtl_ofi_#INSERT FUNCTION NAME HERE#_" . opt_common::mtl_ofi_opt_common::gen_flags_ext(\@op_flags) . "";
my $#INSERT FLAG NAME HERE#_EN = $op_flags[0];
my $symbol_init =
"
sym_table->ompi_mtl_ofi_#INSERT FUNCTION NAME HERE#[".$#INSERT FLAG NAME HERE#_EN."]
= ".$MTL_OFI_FUNC_NAME.";
";
return $symbol_init;
}
1;

Просмотреть файл

@ -0,0 +1,54 @@
#!/usr/bin/env perl
#
# Copyright (c) 2013-2018 Intel, Inc. All rights reserved
#
# $COPYRIGHT$
#
# Additional copyrights may follow
#
# $HEADER$
#
use strict;
use warnings;
package opt_common::mtl_ofi_opt_common;
#
# Generate the extension for functions and symbols based off the flags.
#
sub gen_flags_ext {
my $OP_FLAGS = "";
my @name_flags = @{$_[0]};
my $num_flags = $#name_flags;
for my $flag (@name_flags) {
$OP_FLAGS = $OP_FLAGS . $flag;
if ($num_flags--) {
$OP_FLAGS = $OP_FLAGS . '_';
}
}
return $OP_FLAGS;
}
#
# Generate the header for the specialized symbol table init function.
#
sub gen_sym_function_header {
my $MTL_OFI_SYM_TYPE = $_[0];
my $header =
"void ".$MTL_OFI_SYM_TYPE."_init(struct ompi_mtl_ofi_symtable *sym_table)
{";
return $header;
}
###
#
# Generate the footer for the specialized symbol table init function.
#
sub gen_sym_function_footer {
my $footer =
"}";
return $footer;
}
###
1;