From 3a9ad137d256becdb39414ac4bf3b07ebf52fc21 Mon Sep 17 00:00:00 2001 From: Tomasz Gromadzki Date: Thu, 15 Dec 2022 11:52:18 +0100 Subject: [PATCH 1/8] prov/sharp: Sharp provider TODO list TODO.md files defines next development steps. The list is ordered by priority. Signed-off-by: Tomasz Gromadzki --- prov/sharp/TODO.md | 49 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 prov/sharp/TODO.md diff --git a/prov/sharp/TODO.md b/prov/sharp/TODO.md new file mode 100644 index 00000000000..c936f5ff669 --- /dev/null +++ b/prov/sharp/TODO.md @@ -0,0 +1,49 @@ +# TODO List + +## Items to be completed by ww02'23 + +1. `sharp_domain2()` with sharp_coll API + * oob functions definition with dummy implemntation + * `sharp_coll_init_spec` allocation and definition + * `sharp_coll_init()` (MOCK) allocate `sharp_coll_context` + * `sharp_domain_close()` with sharp_coll API + * `sharp_coll_finalize()` (MOCK) deallocate `sharp_coll_context` + +2. make with/without mocks + + * extend build system for easy compilation with/without mock + * test sharp_domain2 with mocks + * test sharp_domain2 without mocks (option) + +## Next item to be done after ww02'23 + +1. `fi_av_open(domain, **av)` – not sure if needed at all. If yes, to be reused from utill_coll provider. Or coll_av coverted to public ofi_coll_av. There are API calls like `coll_find_local_rank()` that use `coll_av` +2. `fi_av_set(av, **set)` - to be partially reused from `util_coll` provider. Common implementation is required for partially common implementation of `util_coll_mc` and `sharp_mc` +3. fi_join_collective() – the biggest item as it includes cooperation with the util_coll provider and conversion of the synchronous API of SHARP driver to the asynchronous mechanism used by libfabric + * `struct sharp_mc` final implementation. Relation between `util_coll_mc` and `sharp_mc` to be defined. + * thread to creat, as the SHARP driver uses libfabric services (oob) synchronously + * sharp_oob_bcast() implementation based on fi_bcast(..., FI_PEER_TRANSFER,...) + * sharp_oob_barrie() implementation based on fi_barrier(..., FI_PEER_TRANSFER,...) + * sharp_oob_gather() implementation based on fi_gather(..., FI_PEER_TRANSFER,...) + * `sharp_mc` to handle `sharp_coll_comm` context + * `sharp_coll_comm_init()` (MOCK) with sharp_oob_barrier() (THREAD?) + * xref_completion implementation + * `fi_close(mc)` + * `sharp_coll_comm_destroy()` + +4. fi_barrier(mc) + * `sharp_coll_do_barrier_nb()` + * `sharp_ep_progress()` to use `sharp_coll_progress()` + * `sharp_ep_progress()` to use `sharp_coll_req_test()` + * support for `oob_progress()` (???) +5. fi_mr_reg(domain, **mr) + * support for `FI_COLL_SHARP_SCARTCH_SIZE` and `FI_COLL_SHARP_MR_CACHE` + * sharp_coll_do_mr() + * `fi_close(*mr)` +6. `fi_allreduce()` + * `sharp_coll_do_reduce_nb()` + * `sharp_ep_progress()` to use `sharp_coll_progress()` + * `sharp_ep_progress()` to use `sharp_coll_req_test()` + +7. fi_query_collective() + * `sharp_coll_caps_query()` From 648d846b71b2d3ef4d943b945e39a2bdd779f130 Mon Sep 17 00:00:00 2001 From: Tomasz Gromadzki Date: Mon, 28 Nov 2022 22:17:45 +0100 Subject: [PATCH 2/8] prov/rxm: collective offload capabilities reported if offload provider is available * FOR TEST PURPOSE ONLY - TEMPORARY SOLUTION * To let all collective tests pass let's force rxm to provide only offload collective domain capabilities. THIS IS ONLY FOR TEST PPURPOSE. In the future, tests for offload provider shall be executed with OFI_OFFLOAD_PROV_ONLY flag set in fi_query_collective() call. Signed-off-by: Tomasz Gromadzki --- prov/rxm/src/rxm_domain.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/prov/rxm/src/rxm_domain.c b/prov/rxm/src/rxm_domain.c index c0fe0a9dfef..78c6791e304 100644 --- a/prov/rxm/src/rxm_domain.c +++ b/prov/rxm/src/rxm_domain.c @@ -323,6 +323,9 @@ static int rxm_query_collective(struct fid_domain *domain, if (!rxm_domain->util_coll_domain) return -FI_ENOSYS; + if (rxm_domain->offload_coll_domain) + return fi_query_collective(rxm_domain->offload_coll_domain, + coll, attr, flags); if (rxm_domain->offload_coll_domain) ret = fi_query_collective(rxm_domain->offload_coll_domain, From 3136f394fdab7ef27fb0a92c06efd1e356bbc1e2 Mon Sep 17 00:00:00 2001 From: Tomasz Gromadzki Date: Fri, 25 Nov 2022 13:15:59 +0100 Subject: [PATCH 3/8] prov/sharp: SHARP provider scaffolding Signed-off-by: Tomasz Gromadzki --- .travis.yml | 1 + Makefile.am | 3 +- README.md | 9 ++ configure.ac | 1 + include/ofi_prov.h | 11 ++ include/ofi_sharp.h | 70 ++++++++++ man/fi_sharp.7.md | 65 +++++++++ man/man7/fi_sharp.7 | 68 +++++++++ prov/sharp/Makefile.include | 30 ++++ prov/sharp/configure.m4 | 15 ++ prov/sharp/src/sharp.h | 195 ++++++++++++++++++++++++++ prov/sharp/src/sharp_attr.c | 105 ++++++++++++++ prov/sharp/src/sharp_coll.c | 184 ++++++++++++++++++++++++ prov/sharp/src/sharp_cq.c | 120 ++++++++++++++++ prov/sharp/src/sharp_domain.c | 232 +++++++++++++++++++++++++++++++ prov/sharp/src/sharp_ep.c | 238 ++++++++++++++++++++++++++++++++ prov/sharp/src/sharp_eq.c | 103 ++++++++++++++ prov/sharp/src/sharp_fabric.c | 112 +++++++++++++++ prov/sharp/src/sharp_init.c | 97 +++++++++++++ prov/sharp/src/sharp_progress.c | 41 ++++++ src/fabric.c | 3 +- src/fi_tostr.c | 1 + util/info.c | 10 +- 23 files changed, 1710 insertions(+), 4 deletions(-) create mode 100644 include/ofi_sharp.h create mode 100644 man/fi_sharp.7.md create mode 100644 man/man7/fi_sharp.7 create mode 100644 prov/sharp/Makefile.include create mode 100644 prov/sharp/configure.m4 create mode 100644 prov/sharp/src/sharp.h create mode 100644 prov/sharp/src/sharp_attr.c create mode 100644 prov/sharp/src/sharp_coll.c create mode 100644 prov/sharp/src/sharp_cq.c create mode 100644 prov/sharp/src/sharp_domain.c create mode 100644 prov/sharp/src/sharp_ep.c create mode 100644 prov/sharp/src/sharp_eq.c create mode 100644 prov/sharp/src/sharp_fabric.c create mode 100644 prov/sharp/src/sharp_init.c create mode 100644 prov/sharp/src/sharp_progress.c diff --git a/.travis.yml b/.travis.yml index ed7308431ac..6d9e2204c5c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -104,6 +104,7 @@ install: --disable-udp --disable-usnic --disable-verbs + --disable-sharp - make -j2 $MAKE_FLAGS - make install - make test diff --git a/Makefile.am b/Makefile.am index ec71968c98d..817b8939abb 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,6 +1,6 @@ # # Copyright (c) 2016 Cisco Systems, Inc. All rights reserved. -# Copyright (c) 2017-2018 Intel Corporation, Inc. All right reserved. +# Copyright (c) 2017-2022 Intel Corporation, Inc. All right reserved. # Copyright (c) 2018 Amazon.com, Inc. or its affiliates. All rights reserved. # (C) Copyright 2020 Hewlett Packard Enterprise Development LP # @@ -454,6 +454,7 @@ include prov/rxd/Makefile.include include prov/bgq/Makefile.include include prov/opx/Makefile.include include prov/shm/Makefile.include +include prov/sharp/Makefile.include include prov/tcp/Makefile.include include prov/net/Makefile.include include prov/rstream/Makefile.include diff --git a/README.md b/README.md index a1e6ea1681d..b4c1d325ace 100644 --- a/README.md +++ b/README.md @@ -211,6 +211,15 @@ over MSG endpoints of a core provider. See [`fi_rxm`(7)](https://ofiwg.github.io/libfabric/main/man/fi_rxm.7.html) for more information. +### sharp + +*** + +The `off_sharp` provider is an utility provider that supports collective endpoints utilizing +SHARP protocol for the barier and the allreduce operations. + +See [`fi_sharp`(7)](https://ofiwg.github.io/libfabric/main/man/fi_sharp.7.html) for more information. + ### sockets *** diff --git a/configure.ac b/configure.ac index ab8f97e9450..6b76d38162f 100644 --- a/configure.ac +++ b/configure.ac @@ -926,6 +926,7 @@ FI_PROVIDER_SETUP([hook_debug]) FI_PROVIDER_SETUP([hook_hmem]) FI_PROVIDER_SETUP([dmabuf_peer_mem]) FI_PROVIDER_SETUP([opx]) +FI_PROVIDER_SETUP([sharp]) FI_PROVIDER_FINI dnl Configure the .pc file FI_PROVIDER_SETUP_PC diff --git a/include/ofi_prov.h b/include/ofi_prov.h index f7545f7a184..be949834163 100644 --- a/include/ofi_prov.h +++ b/include/ofi_prov.h @@ -334,4 +334,15 @@ OPX_INI ; #define COLL_INIT fi_coll_ini() COLL_INI ; +#if (HAVE_SHARP) && (HAVE_SHARP_DL) +# define SHARP_INI FI_EXT_INI +# define SHARP_INIT NULL +#elif (HAVE_SHARP) +# define SHARP_INI INI_SIG(fi_sharp_ini) +# define SHARP_INIT fi_sharp_ini() +SHARP_INI ; +#else +# define SHARP_INIT NULL +#endif + #endif /* _OFI_PROV_H_ */ diff --git a/include/ofi_sharp.h b/include/ofi_sharp.h new file mode 100644 index 00000000000..b044ee9c5c6 --- /dev/null +++ b/include/ofi_sharp.h @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2022 Intel Corporation. All rights reserved. + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL) Version 2, available from the file + * COPYING in the main directory of this source tree, or the + * BSD license below: + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef _OFI_SHARP_H_ +#define _OFI_SHARP_H_ + +#include "config.h" + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +#include "ofi_coll.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define SHARP_VERSION 1 + + +#if ENABLE_DEBUG +#define SHARP_FLAG_DEBUG (1 << 1) +#else +#define SHARP_FLAG_DEBUG (0 << 1) +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* _OFI_SHARP_H_ */ diff --git a/man/fi_sharp.7.md b/man/fi_sharp.7.md new file mode 100644 index 00000000000..6b1c857b772 --- /dev/null +++ b/man/fi_sharp.7.md @@ -0,0 +1,65 @@ +--- +layout: page +title: fi_sharp(7) +tagline: Libfabric Programmer's Manual +--- +{% include JB/setup %} + +# NAME + +fi_sharp \- The SHARP Fabric Provider + +# OVERVIEW + +The SHARP provider is a collectives offload provider that can be used on Linux +systems supporting the SHARP protocol. + +# SUPPORTED FEATURES + +This release contains an initial implementation of the SHARP provider that +offers the following support: + +*Endpoint types* +: The provider supports only the *FI_EP_RDM* endpoint type. + +*Endpoint capabilities* +: Endpoint supports only the fi_barrier and the fi_allreduce operations. + +*Modes* +: The provider does not require the use of any mode bits. + +*Progress* +: The SHARP provider supports *FI_PROGRESS_MANUAL*. + +*Address Format* +: TBD + +*Msg flags* + The provider does not support messaging. + +*MR registration mode* + The provider implements the FI_MR_VIRT_ADDR memory mode. + +*Atomic operations* + The provider does not support any atomic operation. + +# LIMITATIONS + +The SHARP provider has hard-coded maximums for supported queue sizes and data +transfers. These values are reflected in the related fabric attribute +structures. + +No support for counters. + +# RUNTIME PARAMETERS + +The SHARP provider checks for the following environment variables: + +*FI_SHARP_IB_PORT* +: Default: 1 + +# SEE ALSO + +[`fabric`(7)](fabric.7.html), +[`fi_provider`(7)](fi_provider.7.html), +[`fi_getinfo`(3)](fi_getinfo.3.html) diff --git a/man/man7/fi_sharp.7 b/man/man7/fi_sharp.7 new file mode 100644 index 00000000000..98a66094654 --- /dev/null +++ b/man/man7/fi_sharp.7 @@ -0,0 +1,68 @@ +.\" Automatically generated by Pandoc 2.0.6 +.\" +.TH "fi_sharp" "7" "2022\-12\-14" "Libfabric Programmer's Manual" "#VERSION#" +.hy +.SH NAME +.PP +fi_sharp \- The SHARP Fabric Provider +.SH OVERVIEW +.PP +The SHARP provider is a collectives offload provider that can be used on +Linux systems supporting the SHARP protocol. +.SH SUPPORTED FEATURES +.PP +This release contains an initial implementation of the SHARP provider +that offers the following support: +.TP +.B \f[I]Endpoint types\f[] +The provider supports only the \f[I]FI_EP_RDM\f[] endpoint type. +.RS +.RE +.TP +.B \f[I]Endpoint capabilities\f[] +Endpoint supports only the fi_barrier and the fi_allreduce operations. +.RS +.RE +.TP +.B \f[I]Modes\f[] +The provider does not require the use of any mode bits. +.RS +.RE +.TP +.B \f[I]Progress\f[] +The SHARP provider supports \f[I]FI_PROGRESS_MANUAL\f[]. +.RS +.RE +.TP +.B \f[I]Address Format\f[] +TBD +.RS +.RE +.PP +\f[I]Msg flags\f[] The provider does not support messaging. +.PP +\f[I]MR registration mode\f[] The provider implements the +FI_MR_VIRT_ADDR memory mode. +.PP +\f[I]Atomic operations\f[] The provider does not support any atomic +operation. +.SH LIMITATIONS +.PP +The SHARP provider has hard\-coded maximums for supported queue sizes +and data transfers. +These values are reflected in the related fabric attribute structures. +.PP +No support for counters. +.SH RUNTIME PARAMETERS +.PP +The SHARP provider checks for the following environment variables: +.TP +.B \f[I]FI_SHARP_IB_PORT\f[] +Default: 1 +.RS +.RE +.SH SEE ALSO +.PP +\f[C]fabric\f[](7), \f[C]fi_provider\f[](7), \f[C]fi_getinfo\f[](3) +.SH AUTHORS +OpenFabrics. diff --git a/prov/sharp/Makefile.include b/prov/sharp/Makefile.include new file mode 100644 index 00000000000..b8a9e3b3c02 --- /dev/null +++ b/prov/sharp/Makefile.include @@ -0,0 +1,30 @@ +if HAVE_SHARP +_sharp_files = \ + include/ofi_sharp.h \ + prov/sharp/src/sharp.h \ + prov/sharp/src/sharp_attr.c \ + prov/sharp/src/sharp_init.c \ + prov/sharp/src/sharp_fabric.c \ + prov/sharp/src/sharp_domain.c \ + prov/sharp/src/sharp_eq.c \ + prov/sharp/src/sharp_ep.c \ + prov/sharp/src/sharp_cq.c \ + prov/sharp/src/sharp_coll.c \ + prov/sharp/src/sharp_progress.c + +if HAVE_SHARP_DL +pkglib_LTLIBRARIES += libsharp-fi.la +libsharp_fi_la_SOURCES = $(_sharp_files) $(common_srcs) +libsharp_fi_la_LIBADD = $(linkback) $(sharp_LIBS) +libsharp_fi_la_LDFLAGS = -module -avoid-version -shared -export-dynamic +libsharp_fi_la_DEPENDENCIES = $(linkback) +else !HAVE_SHARP_DL +src_libfabric_la_SOURCES += $(_sharp_files) +src_libfabric_la_LIBADD += $(sharp_LIBS) +endif !HAVE_SHARP_DL + +prov_install_man_pages += man/man7/fi_sharp.7 + +endif HAVE_SHARP + +prov_dist_man_pages += man/man7/fi_sharp.7 diff --git a/prov/sharp/configure.m4 b/prov/sharp/configure.m4 new file mode 100644 index 00000000000..539ba929d9d --- /dev/null +++ b/prov/sharp/configure.m4 @@ -0,0 +1,15 @@ +dnl Configury specific to the libfabric sharp provider + +dnl Called to configure this provider +dnl +dnl Arguments: +dnl +dnl $1: action if configured successfully +dnl $2: action if not configured successfully +dnl +AC_DEFUN([FI_SHARP_CONFIGURE],[ + # Determine if we can support the sharp provider + sharp_happy=0 + AS_IF([test x"$enable_sharp" != x"no"], [sharp_happy=1]) + AS_IF([test $sharp_happy -eq 1], [$1], [$2]) +]) diff --git a/prov/sharp/src/sharp.h b/prov/sharp/src/sharp.h new file mode 100644 index 00000000000..a08b0615d78 --- /dev/null +++ b/prov/sharp/src/sharp.h @@ -0,0 +1,195 @@ +/* + * Copyright (c) 2022 Intel Corporation. All rights reserved. + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL) Version 2, available from the file + * COPYING in the main directory of this source tree, or the + * BSD license below: + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef _SHARP_H_ +#define _SHARP_H_ + +#if HAVE_CONFIG_H +# include +#endif /* HAVE_CONFIG_H */ + +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#define SHARP_IOV_LIMIT 1 +#define SHARP_TX_OP_FLAGS (0) +#define SHARP_RX_OP_FLAGS (0) +#define SHARP_DOMAIN_CAPS (FI_COLLECTIVE | FI_LOCAL_COMM | FI_REMOTE_COMM) +enum { + SHARP_RX_SIZE = 65536, + SHARP_TX_SIZE = 16384, +}; + + +struct sharp_env { + size_t ib_port; +}; + +extern struct sharp_env sharp_env; + +/* +XXX temporary solution +*/ +#ifdef sharp_coll_context +#define sharp_coll_context_t struct sharp_coll_context +#else +#define sharp_coll_context_t void +#endif + +struct sharp_domain { + struct util_domain util_domain; + struct fid_domain *peer_domain; + sharp_coll_context_t *sharp_context; + ofi_atomic32_t ref; /* mr count XXX - to be handled in mr create and del */ + ofi_spin_t lock; +}; + +struct sharp_fabric { + struct util_fabric util_fabric; +}; + +#if 0 +struct sharp_eq { + struct util_eq util_eq; + struct fid_eq *peer_eq; +}; +#endif + +struct sharp_ep { + struct util_ep util_ep; + struct fi_info *sharp_info; + + /* + * Peer ep from the main provider. + * Used for oob communications that SHARP uses during setup. + */ + struct fid_ep *peer_ep; + struct fi_info *peer_info; + + ofi_atomic32_t ref; /* mc count XXX to be added to mc handling*/ + ofi_spin_t lock; +}; + +/* +XXX to be reused from coll provider +*/ +struct sharp_av { + struct util_av util_av; + struct fid_peer_av *peer_av; +}; + +/* +XXX temporary solution +*/ +#ifdef sharp_coll_comm +#define sharp_coll_comm_t struct sharp_coll_comm +#else +#define sharp_coll_comm_t void +#endif +struct sharp_mc { + struct fid_mc mc_fid; + struct util_av_set *av_set; + uint64_t local_rank; + uint16_t group_id; + uint16_t seq; + ofi_atomic32_t ref; + struct fid_mc *peer_mc; +/* same as util_coll_mc until this point */ + struct sharp_ep *ep; + sharp_coll_comm_t *sharp_context; +}; + +extern struct fi_fabric_attr sharp_fabric_attr; +extern struct fi_provider sharp_prov; +extern struct util_prov sharp_util_prov; +extern struct fi_info sharp_info; + +int sharp_fabric(struct fi_fabric_attr *attr, struct fid_fabric **fabric, + void *context); + +int sharp_domain2(struct fid_fabric *fabric, struct fi_info *info, + struct fid_domain **dom, uint64_t flags, void *context); + +int sharp_query_collective(struct fid_domain *domain, + enum fi_collective_op coll, struct fi_collective_attr *attr, + uint64_t flags); + + +int sharp_endpoint(struct fid_domain *domain, struct fi_info *info, + struct fid_ep **ep, void *context); + +void sharp_ep_progress(struct util_ep *util_ep); + +int sharp_join_collective(struct fid_ep *ep, const void *addr, + uint64_t flags, struct fid_mc **mc, void *context); + +#if 0 +int sharp_cq_open(struct fid_domain *domain, struct fi_cq_attr *attr, + struct fid_cq **cq_fid, void *context); + +int sharp_eq_open(struct fid_fabric *fabric, struct fi_eq_attr *attr, + struct fid_eq **eq_fid, void *context); +#endif + +void sharp_collective_comp(struct util_coll_operation *coll_op); + +ssize_t sharp_ep_barrier(struct fid_ep *ep, fi_addr_t coll_addr, void *context); + +ssize_t sharp_ep_barrier2(struct fid_ep *ep, fi_addr_t coll_addr, uint64_t flags, + void *context); + +ssize_t sharp_ep_allreduce(struct fid_ep *ep, const void *buf, size_t count, + void *desc, void *result, void *result_desc, + fi_addr_t coll_addr, enum fi_datatype datatype, + enum fi_op op, uint64_t flags, void *context); + +#endif diff --git a/prov/sharp/src/sharp_attr.c b/prov/sharp/src/sharp_attr.c new file mode 100644 index 00000000000..4f524f99d29 --- /dev/null +++ b/prov/sharp/src/sharp_attr.c @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2022 Intel Corporation. All rights reserved. + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL) Version 2, available from the file + * COPYING in the main directory of this source tree, or the + * BSD license below: + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "sharp.h" + +#define SHARP_TX_CAPS (FI_COLLECTIVE) +#define SHARP_RX_CAPS (FI_COLLECTIVE) + + +struct fi_tx_attr sharp_tx_attr = { + .caps = SHARP_TX_CAPS, + .op_flags = SHARP_TX_OP_FLAGS, + .comp_order = FI_ORDER_NONE, + .msg_order = ~0x0ULL, + .size = SHARP_TX_SIZE, + .iov_limit = SHARP_IOV_LIMIT, + .rma_iov_limit = SHARP_IOV_LIMIT +}; + +struct fi_rx_attr sharp_rx_attr = { + .caps = SHARP_RX_CAPS, + .op_flags = SHARP_RX_OP_FLAGS, + .comp_order = FI_ORDER_NONE, + .msg_order = ~0x0ULL, + .size = SHARP_RX_SIZE, + .iov_limit = SHARP_IOV_LIMIT +}; + +struct fi_ep_attr sharp_ep_attr = { + .type = FI_EP_RDM, + .protocol = FI_PROTO_COLL, + .protocol_version = 1, + .max_msg_size = SIZE_MAX, + .max_order_raw_size = SIZE_MAX, + .max_order_waw_size = SIZE_MAX, + .max_order_war_size = SIZE_MAX, + .mem_tag_format = FI_TAG_GENERIC >> 1, + .tx_ctx_cnt = 1, + .rx_ctx_cnt = 1 +}; + +struct fi_domain_attr sharp_domain_attr = { + .name = "sharp", + .caps = SHARP_DOMAIN_CAPS, + .threading = FI_THREAD_SAFE, + .control_progress = FI_PROGRESS_AUTO, + .data_progress = FI_PROGRESS_AUTO, + .resource_mgmt = FI_RM_ENABLED, + .av_type = FI_AV_UNSPEC, + .mr_mode = 0, + .mr_key_size = sizeof_field(struct fi_rma_iov, key), /* XXX */ + .cq_data_size = sizeof_field(struct ofi_op_hdr, data), + .cq_cnt = 1024, + .ep_cnt = 1, + .tx_ctx_cnt = 1, + .rx_ctx_cnt = 1, + .max_ep_tx_ctx = 1, + .max_ep_rx_ctx = 1, + .mr_iov_limit = SHARP_IOV_LIMIT, +}; + +struct fi_fabric_attr sharp_fabric_attr = { + .name = "sharp", + .prov_version = OFI_VERSION_DEF_PROV +}; + +struct fi_info sharp_info = { + .caps = SHARP_TX_CAPS | SHARP_RX_CAPS | SHARP_DOMAIN_CAPS | FI_COLLECTIVE, + .mode = FI_PEER_TRANSFER, + .addr_format = FI_ADDR_STR, + .tx_attr = &sharp_tx_attr, + .rx_attr = &sharp_rx_attr, + .ep_attr = &sharp_ep_attr, + .domain_attr = &sharp_domain_attr, + .fabric_attr = &sharp_fabric_attr +}; diff --git a/prov/sharp/src/sharp_coll.c b/prov/sharp/src/sharp_coll.c new file mode 100644 index 00000000000..eb23b6145ce --- /dev/null +++ b/prov/sharp/src/sharp_coll.c @@ -0,0 +1,184 @@ +/* + * Copyright (c) 2022 Intel Corporation. All rights reserved. + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL) Version 2, available from the file + * COPYING in the main directory of this source tree, or the + * BSD license below: + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include + +#include "ofi_coll.h" +#include "../../coll/src/coll.h" // coll_ep, coll_eq + +#include "sharp.h" + +int sharp_query_collective(struct fid_domain *domain, + enum fi_collective_op coll, struct fi_collective_attr *attr, + uint64_t flags) +{ + if (!attr || attr->mode != 0) + return -FI_EINVAL; + + switch (coll) { + case FI_BARRIER: + return FI_SUCCESS; /* XXX to be integrated w/ sharp_query */ + case FI_ALLREDUCE: + return FI_SUCCESS; /* XXX to be integrated w/ sharp_query */ + case FI_ALLGATHER: + case FI_SCATTER: + case FI_BROADCAST: + case FI_ALLTOALL: + case FI_REDUCE_SCATTER: + case FI_REDUCE: + case FI_GATHER: + default: + return -FI_ENOSYS; + } + + return -FI_ENOSYS; +} + +static int sharp_mc_close(struct fid *fid) +{ + struct sharp_mc *mc; + + mc = container_of(fid, struct sharp_mc, mc_fid.fid); +#if 0 + /* XXX to be enabled with real implementation of fi_join */ + ofi_atomic_dec32(&mc->av_set->ref); +#endif + free(mc); + return 0; +} + +static struct fi_ops sharp_mc_fid_ops = { + .size = sizeof(struct fi_ops), + .close = sharp_mc_close, + .bind = fi_no_bind, + .control = fi_no_control, + .ops_open = fi_no_ops_open, +}; + + +int sharp_join_collective(struct fid_ep *fid, const void *addr, uint64_t flags, + struct fid_mc **mc_fid, void *context) +{ + struct fi_peer_mc_context *peer_context; + struct sharp_mc *mc; + + if (!(flags & FI_COLLECTIVE)) + return -FI_ENOSYS; + + if ((flags & FI_PEER)) { + peer_context = context; + context = peer_context->mc_fid; + } + + mc = calloc(1, sizeof(*mc)); + if (!mc) + return -FI_ENOMEM; + + *mc_fid = &mc->mc_fid; + (*mc_fid)->fid.ops = &sharp_mc_fid_ops; + if ((flags & FI_PEER)) + mc->peer_mc = context; + + /* XXX Dummy implementation */ + struct fi_eq_entry entry; + struct sharp_ep *ep; + struct ofi_coll_eq *eq; + int ret; + + ep = container_of(fid, struct sharp_ep, util_ep.ep_fid); + eq = container_of(ep->util_ep.eq, struct ofi_coll_eq, util_eq.eq_fid); + /* write to the eq */ + memset(&entry, 0, sizeof(entry)); + entry.fid = &((*mc_fid)->fid); + entry.context = context; + + flags = FI_COLLECTIVE; + if (mc->peer_mc) + flags |= FI_PEER; + ret = fi_eq_write(eq->peer_eq, FI_JOIN_COMPLETE, &entry, + sizeof(struct fi_eq_entry), flags); + if (ret <= 0) { + FI_WARN(ep->util_ep.domain->fabric->prov, FI_LOG_EQ, + "join collective - fi_eq_write() failed\n"); + return ret; + } + return FI_SUCCESS; +} + +ssize_t sharp_ep_barrier2(struct fid_ep *fid, fi_addr_t coll_addr, + uint64_t flags, void *context) +{ + + /* XXX Dummy implementation */ + + struct sharp_ep *ep; + struct ofi_coll_cq *cq; + ep = container_of(fid, struct sharp_ep, util_ep.ep_fid); + cq = container_of(ep->util_ep.tx_cq, struct ofi_coll_cq, util_cq); + ssize_t ret; + ret = cq->peer_cq->owner_ops->write(cq->peer_cq, context, FI_COLLECTIVE, + 0, 0, 0, 0, 0); + if (ret) + FI_WARN(ep->util_ep.domain->fabric->prov, FI_LOG_CQ, + "barrier2 - cq write failed\n"); + + return ret; +} + +ssize_t sharp_ep_barrier(struct fid_ep *ep, fi_addr_t coll_addr, void *context) +{ + return sharp_ep_barrier2(ep, coll_addr, 0, context); +} + + +ssize_t sharp_ep_allreduce(struct fid_ep *fid, const void *buf, size_t count, + void *desc, void *result, void *result_desc, + fi_addr_t coll_addr, enum fi_datatype datatype, + enum fi_op op, uint64_t flags, void *context) +{ + + /* XXX Dummy implementation */ + + memcpy(result,buf,count*ofi_datatype_size(datatype)); + struct sharp_ep *ep; + struct ofi_coll_cq *cq; + ep = container_of(fid, struct sharp_ep, util_ep.ep_fid); + cq = container_of(ep->util_ep.tx_cq, struct ofi_coll_cq, util_cq); + ssize_t ret; + ret = cq->peer_cq->owner_ops->write(cq->peer_cq, context, FI_COLLECTIVE, + 0, 0, 0, 0, 0); + if (ret) + FI_WARN(ep->util_ep.domain->fabric->prov, FI_LOG_CQ, + "allreduce - cq write failed\n"); + memcpy(result,buf,count*ofi_datatype_size(datatype)); + return ret; +} diff --git a/prov/sharp/src/sharp_cq.c b/prov/sharp/src/sharp_cq.c new file mode 100644 index 00000000000..8a739783c9e --- /dev/null +++ b/prov/sharp/src/sharp_cq.c @@ -0,0 +1,120 @@ +/* + * Copyright (c) 2022 Intel Corporation. All rights reserved. + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL) Version 2, available from the file + * COPYING in the main directory of this source tree, or the + * BSD license below: + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#if 0 +#include "sharp.h" +#include "ofi_coll.h" /* for coll_cq_init */ + +static int sharp_cq_close(struct fid *fid) +{ + struct ofi_coll_cq *cq; + int ret; + + cq = container_of(fid, struct ofi_coll_cq, util_cq.cq_fid.fid); + + ret = ofi_cq_cleanup(&cq->util_cq); + if (ret) + return ret; + + free(cq); + return 0; +} + +static struct fi_ops coll_cq_fi_ops = { + .size = sizeof(struct fi_ops), + .close = sharp_cq_close, + .bind = fi_no_bind, + .control = fi_no_control, + .ops_open = fi_no_ops_open, +}; + +static struct fi_ops_cq coll_cq_ops = { + .size = sizeof(struct fi_ops_cq), + .read = fi_no_cq_read, + .readfrom = fi_no_cq_readfrom, + .readerr = fi_no_cq_readerr, + .sread = fi_no_cq_sread, + .sreadfrom = fi_no_cq_sreadfrom, + .signal = fi_no_cq_signal, + .strerror = fi_no_cq_strerror, +}; + +int sharp_cq_init(struct fid_domain *domain, + struct fi_cq_attr *attr, struct fid_cq **cq_fid, + ofi_cq_progress_func progress, void *context) +{ + struct ofi_coll_cq *cq; + struct fi_peer_cq_context *peer_context = context; + int ret; + + const struct sharp_domain *coll_domain; + const struct fi_provider* provider; + + coll_domain = container_of(domain, struct sharp_domain, util_domain.domain_fid.fid); + provider = coll_domain->util_domain.fabric->prov; + + if (!attr || !(attr->flags & FI_PEER)) { + FI_WARN(provider, FI_LOG_CORE, "FI_PEER flag required\n"); + return -FI_EINVAL; + } + + if (!peer_context || peer_context->size < sizeof(*peer_context)) { + FI_WARN(provider, FI_LOG_CORE, "invalid peer CQ context\n"); + return -FI_EINVAL; + } + + cq = calloc(1, sizeof(*cq)); + if (!cq) + return -FI_ENOMEM; + + cq->peer_cq = peer_context->cq; + + ret = ofi_cq_init(provider, domain, attr, &cq->util_cq, progress, context); + if (ret) + goto err; + + *cq_fid = &cq->util_cq.cq_fid; + (*cq_fid)->fid.ops = &coll_cq_fi_ops; + (*cq_fid)->ops = &coll_cq_ops; + return 0; + +err: + free(cq); + return ret; +} + +int sharp_cq_open(struct fid_domain *domain, struct fi_cq_attr *attr, + struct fid_cq **cq_fid, void *context) +{ + return sharp_cq_init(domain, attr, cq_fid, &ofi_cq_progress, context); +} +#endif \ No newline at end of file diff --git a/prov/sharp/src/sharp_domain.c b/prov/sharp/src/sharp_domain.c new file mode 100644 index 00000000000..a787af38abc --- /dev/null +++ b/prov/sharp/src/sharp_domain.c @@ -0,0 +1,232 @@ +/* + * Copyright (c) 2022 Intel Corporation. All rights reserved. + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL) Version 2, available from the file + * COPYING in the main directory of this source tree, or the + * BSD license below: + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include +#include + +#include "sharp.h" + +#include "../../coll/src/coll.h" /* for coll_av_open */ + +struct sharp_mr { + struct fid_mr mr_fid; + void *mr_handle; /* obtained from sharp_coll_reg_mr */ + struct sharp_domain *domain; +}; + +static int sharp_mr_close(fid_t fid) +{ +#if 0 +/* XXX to be replaced with SHARP implementation */ + struct fid_mr mr_fid; + struct sharp_mr *sharp_mr = container_of(fid, struct sharp_mr, mr_fid.fid); +#endif + return 0; +} +static struct fi_ops sharp_mr_fi_ops = { + .size = sizeof(struct fi_ops), + .close = sharp_mr_close, + .bind = fi_no_bind, + .control = fi_no_control, + .ops_open = fi_no_ops_open, +}; + + +static int sharp_mr_reg(struct fid *fid, const void *buf, size_t len, + uint64_t access, uint64_t offset, uint64_t requested_key, + uint64_t flags, struct fid_mr **mr, void *context) +{ + struct sharp_mr *sharp_mr; +#if 0 + struct sharp_domain *sharp_domain = container_of(fid, + struct sharp_domain, util_domain.domain_fid.fid); +#endif + + sharp_mr = calloc(1, sizeof(*sharp_mr)); + if (!sharp_mr) + return -FI_ENOMEM; + + void *sharp_coll_mr = NULL; + /* + XXX to be maped to sharp_coll_reg_mr + Only one outstanding registration supported. no registration cache. + */ + + sharp_mr->mr_fid.fid.fclass = FI_CLASS_MR; + sharp_mr->mr_fid.fid.context = context; + sharp_mr->mr_fid.fid.ops = &sharp_mr_fi_ops; + sharp_mr->mr_fid.mem_desc = sharp_coll_mr; + sharp_mr->mr_fid.key = FI_KEY_NOTAVAIL; + *mr = &sharp_mr->mr_fid; + + /* + XXX do we need to track mrs inside domain + */ + return 0; +} + +static struct fi_ops_mr sharp_domain_mr_ops = { + .size = sizeof(struct fi_ops_mr), + .reg = sharp_mr_reg, + .regv = fi_no_mr_regv, + .regattr = fi_no_mr_regattr, +}; + +static struct fi_ops_domain sharp_domain_ops = { + .size = sizeof(struct fi_ops_domain), + .av_open = coll_av_open, + .cq_open = ofi_coll_cq_open, + .endpoint = sharp_endpoint, + .scalable_ep = fi_no_scalable_ep, + .cntr_open = fi_no_cntr_open, + .poll_open = fi_poll_create, + .stx_ctx = fi_no_stx_context, + .srx_ctx = fi_no_srx_context, + .query_atomic = fi_no_query_atomic, + .query_collective = sharp_query_collective, + .endpoint2 = fi_no_endpoint2 +}; + +static int sharp_domain_close(fid_t fid) +{ + struct sharp_domain *domain; + const struct fi_provider *prov; + int ret; + + domain = container_of(fid, struct sharp_domain, + util_domain.domain_fid.fid); + prov = domain->util_domain.fabric->prov; + /* + XXX to be mapped to: + int sharp_coll_finalize(struct sharp_coll_context *context); + */ + ret = ofi_domain_close(&domain->util_domain); + + free(domain); + if (ret) + FI_WARN(prov, FI_LOG_DOMAIN, "Unable to close domain\n"); + return ret; +} + +static struct fi_ops sharp_domain_fi_ops = { + .size = sizeof(struct fi_ops), + .close = sharp_domain_close, + .bind = fi_no_bind, + .control = fi_no_control, + .ops_open = fi_no_ops_open, +}; + +static inline void +fid_domain_init(struct fid_domain **domain_fid, + struct util_domain *util_domain, struct fi_ops *fid_ops, + struct fi_ops_domain *ops, struct fi_ops_mr *mr) +{ + *domain_fid = &util_domain->domain_fid; + (*domain_fid)->fid.ops = fid_ops; + (*domain_fid)->ops = ops; + (*domain_fid)->mr = mr; +} + +int sharp_domain2(struct fid_fabric *fabric, struct fi_info *info, + struct fid_domain **domain_fid, uint64_t flags, void *context) +{ + int ret; + struct sharp_domain *domain; + struct fi_peer_domain_context *peer_context = context; + + if (!(flags & FI_PEER)) { + FI_WARN(&sharp_prov, FI_LOG_CORE, + "FI_PEER flag required\n"); + return -FI_EINVAL; + } + + if (!peer_context || peer_context->size < sizeof(*peer_context)) { + FI_WARN(&sharp_prov, FI_LOG_CORE, + "Invalid peer domain context\n"); + return -FI_EINVAL; + } + + ret = ofi_prov_check_info(&sharp_util_prov, fabric->api_version, info); + if (ret) + return ret; + + domain = calloc(1, sizeof(*domain)); + if (!domain) + return -FI_ENOMEM; + + ret = ofi_domain_init(fabric, info, &domain->util_domain, context, + OFI_LOCK_MUTEX); + + + if (ret) { + free(domain); + return ret; + } + + ofi_atomic_initialize32(&domain->ref, 0); + domain->util_domain.threading = FI_THREAD_UNSPEC; + +#if 0 + /* + XXX + *domain_fid = &domain->util_domain.domain_fid; + (*domain_fid)->fid.ops = &sharp_domain_fi_ops; + (*domain_fid)->ops = &sharp_domain_ops; + (*domain_fid)->mr = &sharp_domain_mr_ops; + */ +#endif + fid_domain_init(domain_fid, &domain->util_domain, &sharp_domain_fi_ops, + &sharp_domain_ops, &sharp_domain_mr_ops); + + +/* +XXX maped to +int sharp_coll_init(struct sharp_coll_init_spec *sharp_coll_spec, + struct sharp_coll_context **sharp_coll_context); +*/ +#if 0 +struct sharp_coll_init_spec { + uint64_t job_id; /**< Job unique ID */ + int world_rank; /**< Global unique process id. */ + int world_size; /**< Num of processes in the job. */ + int (*progress_func)(void); /**< External progress function. */ + int group_channel_idx; /**< local group channel index(0 .. (max - 1))*/ + struct sharp_coll_config config; /**< @ref sharp_coll_config "SHARP COLL Configuration". */ + struct sharp_coll_out_of_band_colls oob_colls; /**< @ref sharp_coll_out_of_band_colls "List of OOB collectives". */ + int world_local_rank; /**< relative rank of this process on this node within its job. */ + int enable_thread_support; /**< enable multi threaded support. */ + void *oob_ctx; /**< context for OOB functions in sharp_coll_init */ + int reserved[4]; /**< Reserved */ +}; +#endif + return 0; +} diff --git a/prov/sharp/src/sharp_ep.c b/prov/sharp/src/sharp_ep.c new file mode 100644 index 00000000000..a12a049351f --- /dev/null +++ b/prov/sharp/src/sharp_ep.c @@ -0,0 +1,238 @@ +/* + * Copyright (c) 2022 Intel Corporation. All rights reserved + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL) Version 2, available from the file + * COPYING in the main directory of this source tree, or the + * BSD license below: + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include +#include +#include +#include + +#include "ofi_iov.h" +#include "ofi_mr.h" + +#include "sharp.h" + +static int sharp_getname(fid_t fid, void *addr, size_t *addrlen) +{ + int ret; + struct sharp_ep *ep; + char *name = addr; + + ep = container_of(fid, struct sharp_ep, util_ep.ep_fid.fid); + + if (!name || *addrlen == 0 || + snprintf(name, *addrlen, "sharp ") >= *addrlen) + return -FI_ETOOSMALL; + + *addrlen -= 6; + name +=6; + ret = fi_getname(&ep->peer_ep->fid, name, addrlen); + + if (!ret) + *addrlen -= 6; + + return ret; +} + +static struct fi_ops_cm sharp_ep_cm_ops = { + .size = sizeof(struct fi_ops_cm), + .setname = fi_no_setname, + .getname = sharp_getname, + .getpeer = fi_no_getpeer, + .connect = fi_no_connect, /* XXX */ + .listen = fi_no_listen, + .accept = fi_no_accept, + .reject = fi_no_reject, + .shutdown = fi_no_shutdown, + .join = sharp_join_collective, +}; + +static int sharp_ep_close(struct fid *fid) +{ + struct sharp_ep *ep; + + ep = container_of(fid, struct sharp_ep, util_ep.ep_fid.fid); + + ofi_endpoint_close(&ep->util_ep); + ofi_spin_destroy(&ep->lock); + + fi_freeinfo(ep->peer_info); + fi_freeinfo(ep->sharp_info); + + free(ep); + return 0; +} + +static int sharp_ep_bind(struct fid *ep_fid, struct fid *bfid, uint64_t flags) +{ + switch (bfid->fclass) { + case FI_CLASS_AV: + case FI_CLASS_CQ: + return ofi_ep_fid_bind(ep_fid, bfid, flags); + case FI_CLASS_EQ: + case FI_CLASS_CNTR: + case FI_CLASS_SRX_CTX: + default: + FI_WARN(&sharp_prov, FI_LOG_EP_CTRL, + "invalid fid class\n"); + return -FI_EINVAL; + } + return -FI_EINVAL; +} + +static int sharp_ep_ctrl(struct fid *fid, int command, void *arg) +{ + if (command == FI_ENABLE) + return 0; + + return -FI_ENOSYS; +} + +static struct fi_ops sharp_ep_fid_ops = { + .size = sizeof(struct fi_ops), + .close = sharp_ep_close, + .bind = sharp_ep_bind, + .control = sharp_ep_ctrl, + .ops_open = fi_no_ops_open, +}; + +static struct fi_ops_collective sharp_ep_collective_ops = { + .size = sizeof(struct fi_ops_collective), + .barrier = sharp_ep_barrier, + .broadcast = fi_coll_no_broadcast, + .alltoall = fi_coll_no_alltoall, + .allreduce = sharp_ep_allreduce, + .allgather = fi_coll_no_allgather, + .reduce_scatter = fi_coll_no_reduce_scatter, + .reduce = fi_coll_no_reduce, + .scatter = fi_coll_no_scatter, + .gather = fi_coll_no_gather, + .msg = fi_coll_no_msg, + .barrier2 = sharp_ep_barrier2, +}; +static struct fi_ops_ep sharp_ep_ops = { + .size = sizeof(struct fi_ops_ep), + .cancel = fi_no_cancel, /* XXX */ + .getopt = fi_no_getopt, + .setopt = fi_no_setopt, + .tx_ctx = fi_no_tx_ctx, + .rx_ctx = fi_no_rx_ctx, + .rx_size_left = fi_no_rx_size_left, + .tx_size_left = fi_no_tx_size_left, +}; + +inline static void +fid_ep_init(struct fid_ep **ep_fid, + struct util_ep *util_ep, struct fi_ops *fid_ops, + struct fi_ops_ep *ops, struct fi_ops_cm *cm, + struct fi_ops_msg *msg, struct fi_ops_rma *rma, + struct fi_ops_tagged *tagged, struct fi_ops_atomic *atomic, + struct fi_ops_collective *collective) +{ + *ep_fid = &util_ep->ep_fid; + (*ep_fid)->fid.ops = fid_ops; + (*ep_fid)->ops = ops; + (*ep_fid)->cm = cm; + (*ep_fid)->msg = msg; + (*ep_fid)->rma = rma; + (*ep_fid)->tagged = tagged; + (*ep_fid)->atomic = atomic; + (*ep_fid)->collective = collective; +} +void sharp_ep_progress(struct util_ep *util_ep) +{ + ; +} + +int sharp_endpoint(struct fid_domain *domain, struct fi_info *info, + struct fid_ep **ep_fid, void *context) +{ + struct sharp_ep *ep; + struct fi_peer_transfer_context *peer_context = context; + int ret; + + if (!info || !(info->mode & FI_PEER_TRANSFER)) { + FI_WARN(&sharp_prov, FI_LOG_CORE, + "FI_PEER_TRANSFER mode required\n"); + return -FI_EINVAL; + } + + if (!peer_context || peer_context->size < sizeof(*peer_context)) { + FI_WARN(&sharp_prov, FI_LOG_CORE, + "Invalid peer transfer context\n"); + return -FI_EINVAL; + } + + ep = calloc(1, sizeof(*ep)); + if (!ep) + return -FI_ENOMEM; + + ep->sharp_info = fi_dupinfo(info); + if (!ep->sharp_info) { + ret = -FI_ENOMEM; + goto err; + } + + ep->peer_info = fi_dupinfo(peer_context->info); + if (!ep->peer_info) { + ret = -FI_ENOMEM; + goto err; + } + + ep->peer_ep = peer_context->ep; + + ret = ofi_endpoint_init(domain, &sharp_util_prov, info, &ep->util_ep, context, + sharp_ep_progress); + + if (ret) + goto err; + + ofi_atomic_initialize32(&ep->ref, 0); + + ret = ofi_spin_init(&ep->lock); + if (ret) { + ofi_spin_destroy(&ep->lock); + goto err; + } + + fid_ep_init(ep_fid, &ep->util_ep, &sharp_ep_fid_ops, &sharp_ep_ops, + &sharp_ep_cm_ops, NULL, NULL, NULL, NULL, &sharp_ep_collective_ops); + + return 0; + +err: + fi_freeinfo(ep->peer_info); + fi_freeinfo(ep->sharp_info); + free(ep); + return ret; +} + + diff --git a/prov/sharp/src/sharp_eq.c b/prov/sharp/src/sharp_eq.c new file mode 100644 index 00000000000..490b62b3998 --- /dev/null +++ b/prov/sharp/src/sharp_eq.c @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2022 Intel Corporation. All rights reserved. + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL) Version 2, available from the file + * COPYING in the main directory of this source tree, or the + * BSD license below: + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "sharp.h" +#if 0 +static int sharp_eq_close(struct fid *fid) +{ + struct sharp_eq *eq; + int ret; + + eq = container_of(fid, struct sharp_eq, util_eq.eq_fid.fid); + + ret = ofi_eq_cleanup(fid); + if (ret) + return ret; + + free(eq); + return 0; +} + +static struct fi_ops sharp_eq_fi_ops = { + .size = sizeof(struct fi_ops), + .close = sharp_eq_close, + .bind = fi_no_bind, + .control = fi_no_control, + .ops_open = fi_no_ops_open, +}; + +static struct fi_ops_eq sharp_eq_ops = { + .size = sizeof(struct fi_ops_cq), + .read = fi_no_eq_read, + .readerr = fi_no_eq_readerr, + .write = fi_no_eq_write, + .sread = fi_no_eq_sread, + .strerror = fi_no_eq_strerror, +}; + +int sharp_eq_open(struct fid_fabric *fabric, struct fi_eq_attr *attr, + struct fid_eq **eq_fid, void *context) +{ + struct sharp_eq *eq; + struct fi_peer_eq_context *peer_context = context; + int ret; + + if (!attr || !(attr->flags & FI_PEER)) { + FI_WARN(&sharp_prov, FI_LOG_CORE, "FI_PEER flag required\n"); + return -FI_EINVAL; + } + + if (!peer_context || peer_context->size < sizeof(*peer_context)) { + FI_WARN(&sharp_prov, FI_LOG_CORE, "invalid peer EQ context\n"); + return -FI_EINVAL; + } + + eq = calloc(1, sizeof(*eq)); + if (!eq) + return -FI_ENOMEM; + + eq->peer_eq = peer_context->eq; + + ret = ofi_eq_init(fabric, attr, &eq->util_eq.eq_fid, context); + if (ret) + goto err; + + *eq_fid = &eq->util_eq.eq_fid; + (*eq_fid)->fid.ops = &sharp_eq_fi_ops; + (*eq_fid)->ops = &sharp_eq_ops; + return 0; + +err: + free(eq); + return ret; +} +#endif \ No newline at end of file diff --git a/prov/sharp/src/sharp_fabric.c b/prov/sharp/src/sharp_fabric.c new file mode 100644 index 00000000000..023f9d8eab5 --- /dev/null +++ b/prov/sharp/src/sharp_fabric.c @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2022 Intel Corporation. All rights reserved. + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL) Version 2, available from the file + * COPYING in the main directory of this source tree, or the + * BSD license below: + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include +#include + +#include "sharp.h" + +static struct fi_ops_fabric sharp_fabric_ops = { + .size = sizeof(struct fi_ops_fabric), + .domain = fi_no_domain, + .passive_ep = fi_no_passive_ep, + .eq_open = ofi_coll_eq_open, + .wait_open = fi_no_wait_open, + .trywait = ofi_trywait, + .domain2 = sharp_domain2 +}; + +static int sharp_fabric_close(fid_t fid) +{ + int ret; + struct util_fabric *fabric; + + fabric = container_of(fid, struct util_fabric, fabric_fid.fid); + + ret = ofi_fabric_close(fabric); + if (ret) + return ret; + + free(fabric); + return 0; +} + +static struct fi_ops sharp_fabric_fi_ops = { + .size = sizeof(struct fi_ops), + .close = sharp_fabric_close, + .bind = fi_no_bind, + .control = fi_no_control, + .ops_open = fi_no_ops_open, +}; + +/* +XXX to be added to fabric.h later +*/ +static inline void +fid_fabric_init(struct fid_fabric **fabric_fid, + struct util_fabric *util_fabric, struct fi_ops *fid_ops, + struct fi_ops_fabric *ops) +{ + *fabric_fid = &util_fabric->fabric_fid; + (*fabric_fid)->fid.ops = fid_ops; + (*fabric_fid)->ops = ops; +} + +int sharp_fabric(struct fi_fabric_attr *attr, struct fid_fabric **fabric_fid, + void *context) +{ + int ret; + struct sharp_fabric *fabric; + + fabric = calloc(1, sizeof(*fabric)); + if (!fabric) + return -FI_ENOMEM; + + ret = ofi_fabric_init(&sharp_prov, &sharp_fabric_attr, attr, + &fabric->util_fabric, context); + if (ret) + goto err; + +#if 0 + /* XXX to be removed later */ + *fabric_fid = &fabric->util_fabric.fabric_fid; + (*fabric_fid)->fid.ops = &sharp_fabric_fi_ops; + (*fabric_fid)->ops = &sharp_fabric_ops; +#endif + fid_fabric_init(fabric_fid, &fabric->util_fabric, &sharp_fabric_fi_ops, + &sharp_fabric_ops); + return 0; + +err: + free(fabric); + return ret; +} diff --git a/prov/sharp/src/sharp_init.c b/prov/sharp/src/sharp_init.c new file mode 100644 index 00000000000..523719eda7c --- /dev/null +++ b/prov/sharp/src/sharp_init.c @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2022 Intel Corporation. All rights reserved. + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL) Version 2, available from the file + * COPYING in the main directory of this source tree, or the + * BSD license below: + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include + +#include +#include "sharp.h" + +struct sharp_env sharp_env = { + .ib_port = 1, +}; + +static void sharp_init_env(void) +{ + fi_param_get_size_t(&sharp_prov, "ib_port", &sharp_env.ib_port); +} + +static int sharp_getinfo(uint32_t version, const char *node, const char *service, + uint64_t flags, const struct fi_info *hints, + struct fi_info **info) +{ + int ret; + + ret = util_getinfo(&sharp_util_prov, version, node, service, flags, + hints, info); + if (ret) + return ret; + + return 0; +} + +static void sharp_fini(void) +{ +#if HAVE_SHARP_DL + ofi_hmem_cleanup(); +#endif +} + +struct fi_provider sharp_prov = { + .name = OFI_OFFLOAD_PREFIX "sharp", + .version = OFI_VERSION_DEF_PROV, + .fi_version = OFI_VERSION_LATEST, + .getinfo = sharp_getinfo, + .fabric = sharp_fabric, + .cleanup = sharp_fini +}; + +/* +XXX to be moved to sharp_attr.c +*/ +struct util_prov sharp_util_prov = { + .prov = &sharp_prov, + .info = &sharp_info, + .flags = 0 +}; + +SHARP_INI +{ +#if HAVE_SHARP_DL + ofi_hmem_init(); +#endif + fi_param_define(&sharp_prov, "ib_port", FI_PARAM_INT, + "IB device port used by SHARP \ + Default: 1"); + + sharp_init_env(); + return &sharp_prov; +} diff --git a/prov/sharp/src/sharp_progress.c b/prov/sharp/src/sharp_progress.c new file mode 100644 index 00000000000..1a54550b014 --- /dev/null +++ b/prov/sharp/src/sharp_progress.c @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2022 Intel Corporation. All rights reserved + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL) Version 2, available from the file + * COPYING in the main directory of this source tree, or the + * BSD license below: + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include +#include +#include + +#include "ofi_iov.h" +#include "ofi_hmem.h" +#include "ofi_atom.h" +#include "ofi_mr.h" +#include "sharp.h" diff --git a/src/fabric.c b/src/fabric.c index 7f764317212..3bc80a638eb 100644 --- a/src/fabric.c +++ b/src/fabric.c @@ -425,7 +425,7 @@ static void ofi_ordered_provs_init(void) "ofi_hook_noop", "ofi_hook_hmem", "ofi_hook_dmabuf_peer_mem", /* So do the offload providers. */ - "off_coll", + "off_coll", "off_sharp", }; struct ofi_prov *prov; int num_provs, i; @@ -873,6 +873,7 @@ void fi_ini(void) ofi_register_provider(HOOK_NOOP_INIT, NULL); ofi_register_provider(COLL_INIT, NULL); + ofi_register_provider(SHARP_INIT, NULL); ofi_init = 1; diff --git a/src/fi_tostr.c b/src/fi_tostr.c index a4ef1cc9585..5e6ee84cb88 100644 --- a/src/fi_tostr.c +++ b/src/fi_tostr.c @@ -276,6 +276,7 @@ static void ofi_tostr_protocol(char *buf, size_t len, uint32_t protocol) CASEENUMSTRN(FI_PROTO_OPX, len); CASEENUMSTRN(FI_PROTO_CXI, len); CASEENUMSTRN(FI_PROTO_XNET, len); + CASEENUMSTRN(FI_PROTO_COLL, len); default: if (protocol & FI_PROV_SPECIFIC) ofi_strncatf(buf, len, "Provider specific"); diff --git a/util/info.c b/util/info.c index 9f375a77719..cfa45b915e8 100644 --- a/util/info.c +++ b/util/info.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2020 Intel Corporation. All rights reserved. + * Copyright (c) 2013-2020, 2022 Intel Corporation. All rights reserved. * Copyright (c) 2016 Cisco Systems, Inc. All rights reserved. * * This software is available to you under the BSD license below: @@ -35,6 +35,7 @@ #include #include +#include #include #include @@ -68,6 +69,7 @@ static const struct option longopts[] = { {"list", no_argument, NULL, 'l'}, {"verbose", no_argument, NULL, 'v'}, {"version", no_argument, &ver, 1}, + {"offload", no_argument, NULL, 'o'}, {0,0,0,0} }; @@ -89,6 +91,7 @@ static const char *help_strings[][2] = { {"", "\t\tlist available libfabric providers"}, {"", "\t\tverbose output"}, {"", "\t\tprint version info and exit"}, + {"", "\t\tshow only offload providers (experimental)"}, {"", ""} }; @@ -355,7 +358,7 @@ int main(int argc, char **argv) hints->domain_attr->mode = ~0; hints->domain_attr->mr_mode = ~(FI_MR_BASIC | FI_MR_SCALABLE); - while ((op = getopt_long(argc, argv, "s:n:P:c:m:t:a:p:d:f:eg:i:lhv", longopts, + while ((op = getopt_long(argc, argv, "s:n:P:c:m:t:a:p:d:f:eg:i:lhv:o", longopts, &option_index)) != -1) { switch (op) { case 0: @@ -436,6 +439,9 @@ int main(int argc, char **argv) case 'v': verbose = 1; break; + case 'o': + flags |= OFI_OFFLOAD_PROV_ONLY; + break; case 'h': default: print_help: From 7df23f72dc27bd9cf2db352c2b762cda32ec958d Mon Sep 17 00:00:00 2001 From: Tomasz Gromadzki Date: Wed, 14 Dec 2022 09:41:22 +0100 Subject: [PATCH 4/8] prov/sharp: Dummy implementation of fi_barrier() and fi_allreduce() Both collective operation implemented ba colling peer collective operation and transparently passing completion back to peer CQ Signed-off-by: Tomasz Gromadzki --- prov/sharp/src/sharp.h | 6 ++++ prov/sharp/src/sharp_coll.c | 68 +++++++++++++++++++++++++++++++++++-- prov/sharp/src/sharp_ep.c | 8 +++++ 3 files changed, 79 insertions(+), 3 deletions(-) diff --git a/prov/sharp/src/sharp.h b/prov/sharp/src/sharp.h index a08b0615d78..53f7f2a15a0 100644 --- a/prov/sharp/src/sharp.h +++ b/prov/sharp/src/sharp.h @@ -192,4 +192,10 @@ ssize_t sharp_ep_allreduce(struct fid_ep *ep, const void *buf, size_t count, fi_addr_t coll_addr, enum fi_datatype datatype, enum fi_op op, uint64_t flags, void *context); +ssize_t sharp_peer_xfer_complete(struct fid_ep *ep, + struct fi_cq_tagged_entry *cqe, + fi_addr_t src_addr); + +ssize_t sharp_peer_xfer_error(struct fid_ep *ep, struct fi_cq_err_entry *cqerr); + #endif diff --git a/prov/sharp/src/sharp_coll.c b/prov/sharp/src/sharp_coll.c index eb23b6145ce..82b1a6701e6 100644 --- a/prov/sharp/src/sharp_coll.c +++ b/prov/sharp/src/sharp_coll.c @@ -86,7 +86,7 @@ static struct fi_ops sharp_mc_fid_ops = { int sharp_join_collective(struct fid_ep *fid, const void *addr, uint64_t flags, - struct fid_mc **mc_fid, void *context) + struct fid_mc **mc_fid, void *context) { struct fi_peer_mc_context *peer_context; struct sharp_mc *mc; @@ -107,6 +107,7 @@ int sharp_join_collective(struct fid_ep *fid, const void *addr, uint64_t flags, (*mc_fid)->fid.ops = &sharp_mc_fid_ops; if ((flags & FI_PEER)) mc->peer_mc = context; + mc->mc_fid.fi_addr = (uintptr_t)mc; /* XXX Dummy implementation */ struct fi_eq_entry entry; @@ -137,21 +138,35 @@ int sharp_join_collective(struct fid_ep *fid, const void *addr, uint64_t flags, ssize_t sharp_ep_barrier2(struct fid_ep *fid, fi_addr_t coll_addr, uint64_t flags, void *context) { +#if 1 + /* XXX Dummy implementation based on peer:fi_barrier() */ + struct sharp_ep *ep; + struct sharp_mc *sharp_mc; + ep = container_of(fid, struct sharp_ep, util_ep.ep_fid); + sharp_mc = (struct sharp_mc *) ((uintptr_t) coll_addr); + + coll_addr = fi_mc_addr(sharp_mc->peer_mc); + flags |= FI_PEER_TRANSFER; + return fi_barrier2(ep->peer_ep, coll_addr, flags, context); +#else /* XXX Dummy implementation */ struct sharp_ep *ep; struct ofi_coll_cq *cq; + ssize_t ret; + ep = container_of(fid, struct sharp_ep, util_ep.ep_fid); cq = container_of(ep->util_ep.tx_cq, struct ofi_coll_cq, util_cq); - ssize_t ret; ret = cq->peer_cq->owner_ops->write(cq->peer_cq, context, FI_COLLECTIVE, 0, 0, 0, 0, 0); + if (ret) FI_WARN(ep->util_ep.domain->fabric->prov, FI_LOG_CQ, "barrier2 - cq write failed\n"); return ret; +#endif } ssize_t sharp_ep_barrier(struct fid_ep *ep, fi_addr_t coll_addr, void *context) @@ -165,15 +180,30 @@ ssize_t sharp_ep_allreduce(struct fid_ep *fid, const void *buf, size_t count, fi_addr_t coll_addr, enum fi_datatype datatype, enum fi_op op, uint64_t flags, void *context) { +#if 1 + /* XXX Dummy implementation based on peer:fi_allreduce() */ + struct sharp_ep *ep; + struct sharp_mc *sharp_mc; + ep = container_of(fid, struct sharp_ep, util_ep.ep_fid); + sharp_mc = (struct sharp_mc *) ((uintptr_t) coll_addr); + + coll_addr = fi_mc_addr(sharp_mc->peer_mc); + flags |= FI_PEER_TRANSFER; + return fi_allreduce(ep->peer_ep, buf, count, desc, result, + result_desc, coll_addr, datatype, op, flags, context); +#else /* XXX Dummy implementation */ + struct ofi_coll_cq *cq; + ssize_t ret; memcpy(result,buf,count*ofi_datatype_size(datatype)); struct sharp_ep *ep; struct ofi_coll_cq *cq; + ssize_t ret; + ep = container_of(fid, struct sharp_ep, util_ep.ep_fid); cq = container_of(ep->util_ep.tx_cq, struct ofi_coll_cq, util_cq); - ssize_t ret; ret = cq->peer_cq->owner_ops->write(cq->peer_cq, context, FI_COLLECTIVE, 0, 0, 0, 0, 0); if (ret) @@ -181,4 +211,36 @@ ssize_t sharp_ep_allreduce(struct fid_ep *fid, const void *buf, size_t count, "allreduce - cq write failed\n"); memcpy(result,buf,count*ofi_datatype_size(datatype)); return ret; +#endif } + +ssize_t sharp_peer_xfer_complete(struct fid_ep *ep_fid, + struct fi_cq_tagged_entry *cqe, + fi_addr_t src_addr) +{ + struct sharp_ep *ep; + struct ofi_coll_cq *cq; + + ep = container_of(ep_fid, struct sharp_ep, util_ep.ep_fid); + cq = container_of(ep->util_ep.tx_cq, struct ofi_coll_cq, util_cq); + + if (cq->peer_cq->owner_ops->write(cq->peer_cq, cqe->op_context, + FI_COLLECTIVE, 0, 0, 0, 0, 0)) + FI_WARN(ep->util_ep.domain->fabric->prov, FI_LOG_DOMAIN, + "collective - cq write failed\n"); + return 0; +} + +ssize_t sharp_peer_xfer_error(struct fid_ep *ep_fid, struct fi_cq_err_entry *cqerr) +{ + struct sharp_ep *ep; + struct ofi_coll_cq *cq; + + ep = container_of(ep_fid, struct sharp_ep, util_ep.ep_fid); + cq = container_of(ep->util_ep.tx_cq, struct ofi_coll_cq, util_cq); + + if (cq->peer_cq->owner_ops->writeerr(cq->peer_cq, cqerr)) + FI_WARN(ep->util_ep.domain->fabric->prov, FI_LOG_DOMAIN, + "collective - cq write failed\n"); + return 0; +} \ No newline at end of file diff --git a/prov/sharp/src/sharp_ep.c b/prov/sharp/src/sharp_ep.c index a12a049351f..910ee214b70 100644 --- a/prov/sharp/src/sharp_ep.c +++ b/prov/sharp/src/sharp_ep.c @@ -172,6 +172,12 @@ void sharp_ep_progress(struct util_ep *util_ep) ; } +static struct fi_ops_transfer_peer sharp_ep_peer_xfer_ops = { + .size = sizeof(struct fi_ops_transfer_peer), + .complete = sharp_peer_xfer_complete, + .comperr = sharp_peer_xfer_error, +}; + int sharp_endpoint(struct fid_domain *domain, struct fi_info *info, struct fid_ep **ep_fid, void *context) { @@ -191,6 +197,8 @@ int sharp_endpoint(struct fid_domain *domain, struct fi_info *info, return -FI_EINVAL; } + peer_context->peer_ops = &sharp_ep_peer_xfer_ops; + ep = calloc(1, sizeof(*ep)); if (!ep) return -FI_ENOMEM; From f1357ba04bc8dfff30ea9304f25baa5c3b034fef Mon Sep 17 00:00:00 2001 From: Tomasz Gromadzki Date: Tue, 27 Dec 2022 20:31:35 +0100 Subject: [PATCH 5/8] prov/sharp: Dummy implementation of fi_join_collective() fi_join_collective implementation with usage of coll_op's state machine Signed-off-by: Tomasz Gromadzki --- prov/coll/src/coll_coll.c | 3 +- prov/sharp/src/sharp_coll.c | 311 +++++++++++++++++++++++++++++++++++- prov/sharp/src/sharp_ep.c | 4 - 3 files changed, 311 insertions(+), 7 deletions(-) diff --git a/prov/coll/src/coll_coll.c b/prov/coll/src/coll_coll.c index b76ed5960c7..4ec9c81bc30 100644 --- a/prov/coll/src/coll_coll.c +++ b/prov/coll/src/coll_coll.c @@ -665,8 +665,7 @@ static struct fi_ops util_coll_fi_ops = { .ops_open = fi_no_ops_open, }; -static int coll_find_local_rank(struct fid_ep *ep, - struct util_coll_mc *coll_mc) +int coll_find_local_rank(struct fid_ep *ep, struct util_coll_mc *coll_mc) { struct coll_av *av = container_of(coll_mc->av_set->av, struct coll_av, util_av.av_fid); diff --git a/prov/sharp/src/sharp_coll.c b/prov/sharp/src/sharp_coll.c index 82b1a6701e6..cbfb1c54e58 100644 --- a/prov/sharp/src/sharp_coll.c +++ b/prov/sharp/src/sharp_coll.c @@ -33,7 +33,6 @@ #include #include "ofi_coll.h" -#include "../../coll/src/coll.h" // coll_ep, coll_eq #include "sharp.h" @@ -68,6 +67,7 @@ static int sharp_mc_close(struct fid *fid) struct sharp_mc *mc; mc = container_of(fid, struct sharp_mc, mc_fid.fid); + ofi_atomic_dec32(&mc->av_set->ref); #if 0 /* XXX to be enabled with real implementation of fi_join */ ofi_atomic_dec32(&mc->av_set->ref); @@ -84,7 +84,315 @@ static struct fi_ops sharp_mc_fid_ops = { .ops_open = fi_no_ops_open, }; +struct sharp_coll_mc { + struct fid_mc mc_fid; + struct util_av_set *av_set; + uint64_t local_rank; + uint16_t group_id; + uint16_t seq; + ofi_atomic32_t ref; + struct fid_mc *peer_mc; + void *context; /* SHARP COLL context */ +}; + +static struct sharp_coll_mc *sharp_create_mc(struct util_av_set *av_set, + void *context) +{ + struct sharp_coll_mc *coll_mc; + + coll_mc = calloc(1, sizeof(*coll_mc)); + if (!coll_mc) + return NULL; + + coll_mc->mc_fid.fid.fclass = FI_CLASS_MC; + coll_mc->mc_fid.fid.context = context; + coll_mc->mc_fid.fid.ops = &sharp_mc_fid_ops; + coll_mc->mc_fid.fi_addr = (uintptr_t) coll_mc; + + ofi_atomic_inc32(&av_set->ref); + coll_mc->av_set = av_set; + + return coll_mc; +} + +static void sharp_progress_work(struct util_ep *util_ep, + struct util_coll_operation *coll_op) +{ + struct util_coll_work_item *next_ready = NULL; + struct util_coll_work_item *cur_item = NULL; + struct util_coll_work_item *prev_item = NULL; + struct dlist_entry *tmp = NULL; + int previous_is_head; + + /* clean up any completed items while searching for the next ready */ + dlist_foreach_container_safe(&coll_op->work_queue, + struct util_coll_work_item, + cur_item, waiting_entry, tmp) { + + previous_is_head = (cur_item->waiting_entry.prev == + &cur_item->coll_op->work_queue); + if (!previous_is_head) { + prev_item = container_of(cur_item->waiting_entry.prev, + struct util_coll_work_item, + waiting_entry); + } + + if (cur_item->state == UTIL_COLL_COMPLETE) { + /* + * If there is work before cur and cur is fencing, + * we can't complete. + */ + if (cur_item->fence && !previous_is_head) + continue; + + FI_DBG(coll_op->mc->av_set->av->prov, FI_LOG_CQ, + "Removing Completed Work item: %p \n", cur_item); + dlist_remove(&cur_item->waiting_entry); + free(cur_item); + + /* if the work queue is empty, we're done */ + if (dlist_empty(&coll_op->work_queue)) { + free(coll_op); + return; + } + continue; + } + + /* we can't progress if prior work is fencing */ + if (!previous_is_head && prev_item && prev_item->fence) { + FI_DBG(coll_op->mc->av_set->av->prov, FI_LOG_CQ, + "%p fenced by: %p \n", cur_item, prev_item); + return; + } + + /* + * If the current item isn't waiting, it's not the next + * ready item. + */ + if (cur_item->state != UTIL_COLL_WAITING) { + FI_DBG(coll_op->mc->av_set->av->prov, FI_LOG_CQ, + "Work item not waiting: %p [%s]\n", cur_item, + log_util_coll_state[cur_item->state]); + continue; + } + + FI_DBG(coll_op->mc->av_set->av->prov, FI_LOG_CQ, + "Ready item: %p \n", cur_item); + next_ready = cur_item; + break; + } + + if (!next_ready) + return; + + //XXcoll_log_work(coll_op); + + next_ready->state = UTIL_COLL_PROCESSING; + slist_insert_tail(&next_ready->ready_entry, &util_ep->coll_ready_queue); +} + +void sharp_ep_progress(struct util_ep *util_ep) +{ + struct util_coll_work_item *work_item; + struct util_coll_operation *coll_op; + + while (!slist_empty(&util_ep->coll_ready_queue)) { + slist_remove_head_container(&util_ep->coll_ready_queue, + struct util_coll_work_item, + work_item, ready_entry); + coll_op = work_item->coll_op; + switch (work_item->type) { + case UTIL_COLL_COMP: + if (work_item->coll_op->comp_fn) + work_item->coll_op->comp_fn(work_item->coll_op); + + work_item->state = UTIL_COLL_COMPLETE; + break; + + default: + goto out; + } + + sharp_progress_work(util_ep, coll_op); + } + +out: + return; + +} + +static struct util_coll_operation * +sharp_create_op(struct fid_ep *ep, struct sharp_coll_mc *coll_mc, + enum util_coll_op_type type, uint64_t flags, + void *context, util_coll_comp_fn_t comp_fn) +{ + struct util_coll_operation *coll_op; + + coll_op = calloc(1, sizeof(*coll_op)); + if (!coll_op) + return NULL; + + coll_op->ep = ep; + coll_op->cid = 1; //XXX coll_get_next_id(coll_mc); + coll_op->mc = (struct util_coll_mc*) coll_mc; + coll_op->type = type; + coll_op->flags = flags; + coll_op->context = context; + coll_op->comp_fn = comp_fn; + dlist_init(&coll_op->work_queue); + + return coll_op; +} + +static void sharp_join_comp(struct util_coll_operation *coll_op) +{ + struct fi_eq_entry entry; + struct sharp_ep *ep; + struct ofi_coll_eq *eq; + uint64_t flags; + + ep = container_of(coll_op->ep, struct sharp_ep, util_ep.ep_fid); + eq = container_of(ep->util_ep.eq, struct ofi_coll_eq, util_eq.eq_fid); + + coll_op->data.join.new_mc->seq = 0; + coll_op->data.join.new_mc->group_id = + (uint16_t) ofi_bitmask_get_lsbset(coll_op->data.join.data); + + /* mark the local mask bit */ + ofi_bitmask_unset(ep->util_ep.coll_cid_mask, + coll_op->data.join.new_mc->group_id); + + /* write to the eq */ + memset(&entry, 0, sizeof(entry)); + entry.fid = &coll_op->mc->mc_fid.fid; + entry.context = coll_op->context; + + flags = FI_COLLECTIVE; + if (coll_op->data.join.new_mc->peer_mc) + flags |= FI_PEER; + if (fi_eq_write(eq->peer_eq, FI_JOIN_COMPLETE, &entry, + sizeof(struct fi_eq_entry), flags) < 0) + FI_WARN(ep->util_ep.domain->fabric->prov, FI_LOG_DOMAIN, + "join collective - eq write failed\n"); + + ofi_bitmask_free(&coll_op->data.join.data); + ofi_bitmask_free(&coll_op->data.join.tmp); +} + +/* XXX to be replaced with ofi_coll_find_local_rank implementation*/ +int coll_find_local_rank(struct fid_ep *ep, struct util_coll_mc *coll_mc); + +/* reused from coll_bind_work */ +static void sharp_bind_work(struct util_coll_operation *coll_op, + struct util_coll_work_item *item) +{ + item->coll_op = coll_op; + dlist_insert_tail(&item->waiting_entry, &coll_op->work_queue); +} +/* reused from coll_sched_comp */ +static int sharp_sched_comp(struct util_coll_operation *coll_op) +{ + struct util_coll_work_item *comp_item; + + comp_item = calloc(1, sizeof(*comp_item)); + if (!comp_item) + return -FI_ENOMEM; + + comp_item->type = UTIL_COLL_COMP; + comp_item->state = UTIL_COLL_WAITING; + comp_item->fence = 1; + + sharp_bind_work(coll_op, comp_item); + return FI_SUCCESS; +} + +int sharp_join_collective(struct fid_ep *ep, const void *addr, + uint64_t flags, struct fid_mc **mc, void *context) +{ + struct fi_peer_mc_context *peer_context; + struct sharp_coll_mc *new_coll_mc; + struct util_av_set *av_set; + struct sharp_coll_mc *coll_mc; + struct util_coll_operation *join_op; + struct util_ep *util_ep; + struct fi_collective_addr *c_addr; + fi_addr_t coll_addr; + const struct fid_av_set *set; + int ret; + + if (!(flags & FI_COLLECTIVE)) + return -FI_ENOSYS; + + if (flags & FI_PEER) { + peer_context = context; + context = peer_context->mc_fid; + } + + c_addr = (struct fi_collective_addr *)addr; + coll_addr = c_addr->coll_addr; + set = c_addr->set; + + av_set = container_of(set, struct util_av_set, av_set_fid); + + if (coll_addr == FI_ADDR_NOTAVAIL) { + assert(av_set->av->av_set); + coll_mc = (struct sharp_coll_mc *) &av_set->av->av_set->coll_mc; + } else { + coll_mc = (struct sharp_coll_mc*) ((uintptr_t) coll_addr); + } + + new_coll_mc = sharp_create_mc(av_set, context); + if (!new_coll_mc) + return -FI_ENOMEM; + + if (flags & FI_PEER) + new_coll_mc->peer_mc = context; + + /* get the rank */ + coll_find_local_rank(ep, (struct util_coll_mc *)new_coll_mc); + coll_find_local_rank(ep, (struct util_coll_mc *)coll_mc); + + join_op = sharp_create_op(ep, coll_mc, UTIL_COLL_JOIN_OP, flags, + context, sharp_join_comp); + if (!join_op) { + ret = -FI_ENOMEM; + goto err1; + } + + join_op->data.join.new_mc = (struct util_coll_mc*)new_coll_mc; + + ret = ofi_bitmask_create(&join_op->data.join.data, OFI_MAX_GROUP_ID); + if (ret) + goto err2; + + ret = ofi_bitmask_create(&join_op->data.join.tmp, OFI_MAX_GROUP_ID); + if (ret) + goto err3; + + util_ep = container_of(ep, struct util_ep, ep_fid); + + ret = sharp_sched_comp(join_op); + if (ret) + goto err4; + + sharp_progress_work(util_ep, join_op); + + *mc = &new_coll_mc->mc_fid; + return FI_SUCCESS; + +err4: + ofi_bitmask_free(&join_op->data.join.tmp); +err3: + ofi_bitmask_free(&join_op->data.join.data); +err2: + free(join_op); +err1: + fi_close(&new_coll_mc->mc_fid.fid); + return ret; +} + +#if 0 int sharp_join_collective(struct fid_ep *fid, const void *addr, uint64_t flags, struct fid_mc **mc_fid, void *context) { @@ -134,6 +442,7 @@ int sharp_join_collective(struct fid_ep *fid, const void *addr, uint64_t flags, } return FI_SUCCESS; } +#endif ssize_t sharp_ep_barrier2(struct fid_ep *fid, fi_addr_t coll_addr, uint64_t flags, void *context) diff --git a/prov/sharp/src/sharp_ep.c b/prov/sharp/src/sharp_ep.c index 910ee214b70..8bec0b366ff 100644 --- a/prov/sharp/src/sharp_ep.c +++ b/prov/sharp/src/sharp_ep.c @@ -167,10 +167,6 @@ fid_ep_init(struct fid_ep **ep_fid, (*ep_fid)->atomic = atomic; (*ep_fid)->collective = collective; } -void sharp_ep_progress(struct util_ep *util_ep) -{ - ; -} static struct fi_ops_transfer_peer sharp_ep_peer_xfer_ops = { .size = sizeof(struct fi_ops_transfer_peer), From 2c9b031fc241e65923b915b5673a1ba535f24f12 Mon Sep 17 00:00:00 2001 From: Tomasz Gromadzki Date: Thu, 15 Dec 2022 09:18:40 +0100 Subject: [PATCH 6/8] prov/sharp SHARP coll driver access API scaffolding Signed-off-by: Tomasz Gromadzki --- prov/sharp/src/mocks/api/sharp.h | 680 +++++++++++++++++++++++++++++++ prov/sharp/src/sharp.h | 46 +++ 2 files changed, 726 insertions(+) create mode 100644 prov/sharp/src/mocks/api/sharp.h diff --git a/prov/sharp/src/mocks/api/sharp.h b/prov/sharp/src/mocks/api/sharp.h new file mode 100644 index 00000000000..039b9f41d62 --- /dev/null +++ b/prov/sharp/src/mocks/api/sharp.h @@ -0,0 +1,680 @@ +/** + * Copyright (c) 2015-2017 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * + * See file LICENSE for terms. + */ + +#ifndef _SHARP_COLL_API_H +#define _SHARP_COLL_API_H +#include +#include +#include + + +/** + * @brief SHARP coll supported data types + * + * The enumeration list describes the data types supported by SHARP coll + */ +#ifdef __cplusplus +extern "C" { +#endif + +enum sharp_datatype { + SHARP_DTYPE_UNSIGNED, /**< 32-bit unsigned integer. */ + SHARP_DTYPE_INT, /**< 32-bit integer. */ + SHARP_DTYPE_UNSIGNED_LONG, /**< 64-bit unsigned integer. */ + SHARP_DTYPE_LONG, /**< 64-bit integer. */ + SHARP_DTYPE_FLOAT, /**< 32-bit long floating point number */ + SHARP_DTYPE_DOUBLE, /**< 64-bit long floating point number. */ + SHARP_DTYPE_UNSIGNED_SHORT, /**< 16-bit unsigned short integer. */ + SHARP_DTYPE_SHORT, /**< 16-bit short integer. */ + SHARP_DTYPE_FLOAT_SHORT, /**< 16-bit floating point number. */ + SHARP_DTYPE_BFLOAT16, /**< 16-bit Bfloat. */ + SHARP_DTYPE_UINT8, /**< 8-bit unsigned integer. */ + SHARP_DTYPE_INT8, /**< 8-bit integer. */ + SHARP_DTYPE_NULL /**< NULL data type */ +}; + +/** + * @brief SHARP coll supported aggregation operations + * + * The enumeration list describes the aggregation operations supported by SHARP coll + */ +enum sharp_reduce_op { + SHARP_OP_MAX, /**< maximum. */ + SHARP_OP_MIN, /**< minimum. */ + SHARP_OP_SUM, /**< sum. */ + SHARP_OP_PROD, /**< product. */ + SHARP_OP_LAND, /**< logical and.*/ + SHARP_OP_BAND, /**< bit-wise and. */ + SHARP_OP_LOR, /**< logical or. */ + SHARP_OP_BOR, /**< bit-wise or. */ + SHARP_OP_LXOR, /**< logical xor. */ + SHARP_OP_BXOR, /**< bit-wise xor. */ + SHARP_OP_MAXLOC, /**< max value and location. */ + SHARP_OP_MINLOC, /**< min value and location. */ + SHARP_OP_NULL +}; + +/** + * @brief SHARP coll status code + * + * The enumeration list describes the error codes returned by SHARP coll + */ +enum sharp_error_no { + SHARP_COLL_SUCCESS = 0, /**< Success. */ + SHARP_COLL_ERROR = -1, /**< Error. */ + SHARP_COLL_ENOT_SUPP = -2, /**< Collective operation not supported. */ + SHARP_COLL_ENOMEM = -3, /**< No memory. */ + SHARP_COLL_EGROUP_ALLOC = -4, /**< SHARP Group alloc error. */ + SHARP_COLL_ECONN_TREE = -5, /**< No connection to sharp tree. */ + SHARP_COLL_EGROUP_JOIN = -6, /**< Not able to join sharp grou.*/ + SHARP_COLL_EQUOTA = -7, /**< SHARP resource quota error. */ + SHARP_COLL_ESESS_INIT = -8, /**< Cannot connect to SHARPD. */ + SHARP_COLL_EDEV = -9, /**< SHARP device error. */ + SHARP_COLL_EINVAL = -10, /**< Invalid value. */ + SHARP_COLL_EJOB_CREATE = -11, /**< Cannot create SHARP job. */ + SHARP_COLL_ETREE_INFO = -12, /**< SHARP tree info not found. */ + SHARP_COLL_ENOTREE = -13, /**< No available SHARP trees. */ + SHARP_COLL_EGROUP_ID = -14, /**< Wrong SHARP group ID. */ + SHARP_COLL_EOOB = -15, /**< Out-Of-Band collective error. */ + SHARP_COLL_EGROUP_MCAST = -16, /**< Multicast target error. */ + SHARP_COLL_EGROUP_TRIM = -17, /**< Group trim failed. */ + SHARP_COLL_ELOCK_FAILED = -18, /**< SAT lock failed (can retry) */ + SHARP_COLL_ELOCK_DENIED = -19, /**< SAT lock operation not permitted */ + SHARP_COLL_ENO_RESOURCE = -20, /**< Resource not available */ +}; + +/** + * @brief SHARP feature mask + * + * The enumeration list of sharp job features + */ +enum sharp_job_features { + SHARP_FEATURE_LLT = 1 << 0, + SHARP_FEATURE_REPRODUCIBLE = 1 << 1, + SHARP_FEATURE_SAT = 1 << 2, + SHARP_FEATURE_SAT_EXCLUSIVE_LOCK = 1 << 3, +}; + +enum sharp_aggregation_mode { + SHARP_AGGREGATION_NONE = 0, /**< Optimal mode is determined internally */ + SHARP_AGGREGATION_DATAGRAM, /**< Force datagram aggregation for relevant collectives. */ + SHARP_AGGREGATION_STREAMING, /**< Force streaming aggregation for relevant collectives. */ +}; + +/* Forward declarations */ +struct sharp_coll_context; +struct sharp_coll_comm; + +/* + * @brief SHARP coll configuration descriptor + * + * This descriptor defines the configuration for SHARP coll initialization + */ +struct sharp_coll_config { + const char *ib_dev_list; /**< IB device name, port list. */ + int user_progress_num_polls; /**< Number of polls to do before calling user progress. */ + int coll_timeout; /**< Timeout (msec) for collective operation, -1 - infinite */ + int reserved[4]; /**< Reserved */ +}; + +/** + * Default SHARP COLL configuration. + */ +extern const struct sharp_coll_config sharp_coll_default_config; + +/* + * @brief SHARP coll Out-Of-Band collectives descriptor + * + * This descriptor defines list of OOB collectives application must implement + * and provide for SHARP coll initialization + */ +struct sharp_coll_out_of_band_colls { + /** + * @brief out-of-band broadcast + * + * The pointer refers to application defined out-of-band bcast collective. + * + * @param [in] context User-defined context or NULL. + * @param [in] buffer Buffer to send/recv. + * @param [in] len Size of the buffer. + * @param [in] root Root of the broadcast. + */ + int (*bcast) (void* context, void* buffer, int len, int root); + + /** + * @brief out-of-band barrier + * + * The pointer refers to application defined out-of-band barrier collective. + * + * @param [in] context User-defined context or NULL. + */ + int (*barrier) (void* context); + + /** + * @brief out-of-band gather + * + * The pointer refers to application defined out-of-band gather collective. + * + * @param [in] context User-defined context or NULL. + * @param [in] root Root of the broadcast. + * @param [in] sbuf Buffer to send. + * @param [in] rbuf Buffer to recv. + * @param [in] len Size of the buffer. + */ + int (*gather) (void * context, int root, void *sbuf, void *rbuf, int len); +}; + +/* + * @brief SHARP coll group initialization spec descriptor + * + * This descriptor defines the list of application specification to create SHARP group. + * + */ +struct sharp_coll_comm_init_spec { + int rank; /**< Unique process id in the group. */ + int size; /**< Size of the SHARP group. */ + void *oob_ctx; /**< External group context for OOB functions. */ + const uint32_t *group_world_ranks; /**< List of Global unique process ids of group members. */ + int reserved[2]; /**< Reserved */ +}; + +/* + * @brief SHARP coll initialization spec descriptor + * + * This descriptor defines the list of application specification to initialize SHARP coll. + * + */ +struct sharp_coll_init_spec { + uint64_t job_id; /**< Job unique ID */ + int world_rank; /**< Global unique process id. */ + int world_size; /**< Num of processes in the job. */ + int (*progress_func)(void); /**< External progress function. */ + int group_channel_idx; /**< local group channel index(0 .. (max - 1))*/ + struct sharp_coll_config config; /**< @ref sharp_coll_config "SHARP COLL Configuration". */ + struct sharp_coll_out_of_band_colls oob_colls; /**< @ref sharp_coll_out_of_band_colls "List of OOB collectives". */ + int world_local_rank; /**< relative rank of this process on this node within its job. */ + int enable_thread_support; /**< enable multi threaded support. */ + void *oob_ctx; /**< context for OOB functions in sharp_coll_init */ + int reserved[4]; /**< Reserved */ +}; + +/** + * @brief SHARP coll context capabilities. + * + * This descriptor defines the list of capabilities supported by a given SHARP group. + */ +struct sharp_coll_caps { + int sharp_pkt_version; /**< Sharp packet version */ + uint64_t reserved[2]; /**< Reserved */ + struct { + uint64_t dtypes; /**< Flags supported from @ref sharp_datatype */ + uint64_t tag_dtypes; /**< Flags supported from @ref sharp_datatype for MIN/MAX_LOC tag */ + uint64_t reduce_ops; /**< Flags supported from @ref sharp_reduce_op */ + uint64_t feature_mask; /**< Supported feature mask */ + uint64_t reserved[4]; /**< Reserved */ + } support_mask; + + struct { + int max_osts; /**< OSTs per tree */ + int user_data_per_ost; /**< Payload per OST */ + int max_groups; /**< Groups per tree */ + int max_group_channels; /**< Group channels per */ + int osts_per_group; /**< OSTs per group */ + } resources; +}; + + +/** + * @brief SHARP coll buffer types + * + * The enumeration list describes the buffer types supported in collective calls. + * @note Only SHARP_DATA_BUFFER is implemented. + */ +enum sharp_data_buffer_type { + SHARP_DATA_BUFFER, /**< Contiguous buffer. */ + SHARP_DATA_STREAM, /**< Data stream. */ + SHARP_DATA_IOV /**< Vector input. */ +}; + +/** + * Maximal number of IOV entries in a vector + */ +#define SHARP_COLL_DATA_MAX_IOV 15 + +/** + * @brief SHARP coll memory types + * + * The enumeration list describes the memory types based on its location + */ +enum sharp_data_memory_type { + SHARP_MEM_TYPE_HOST, /**< Default system memory */ + SHARP_MEM_TYPE_CUDA, /**< NVIDIA CUDA memory */ + SHARP_MEM_TYPE_LAST +}; + +/** + * @brief SHARP coll structure for scatter-gather I/O. + */ +struct sharp_data_iov { + void *ptr; /**< Pointer to a data buffer */ + size_t length; /**< Length of the buffer in bytes */ + void *mem_handle; /**< memory handle returned from @ref sharp_coll_reg_mr */ +}; + +/** + * @brief stream callback + * + * Streaming writer callback function. + * + * @param buffer Buffer to read or write the data + * @param length Max. number of bytes to copy. + * @param offset Offset in the data stream. First time called with offset = 0, + * and it's incremented by the return value. + * @param context User-define context, from stream.cb_context; + * + * @return Number of bytes processed from the buffer. + * For writers - if it's smaller than `length', it means to end the + * fragment prematurely, and the callback will be called again until + * total length is processed. + * For readers, the callback must process the entire buffer, if it returns + * a smaller value it means the message is truncated. + * + * @note It's guaranteed that (offset + length) is not larger than the declared + * stream size (stream.length). + * + */ +typedef size_t (*sharp_stream_cb)(void *buffer, size_t length, + size_t offset, void *context); + +/* + * @brief SHARP coll input buffer description + * + * This descriptor defines the buffer description for SHARP coll operations + * + */ +struct sharp_coll_data_desc { + enum sharp_data_buffer_type type; + enum sharp_data_memory_type mem_type; + int reserved[2]; + union { + + /* contiguous buffer */ + struct { + void *ptr; /**< contiguous data buffer. */ + size_t length; /**< Buffer len. */ + void *mem_handle; /**< memory handle returned from @ref sharp_coll_reg_mr */ + } buffer; + + /* Streaming data */ + struct { + sharp_stream_cb cb; /**< Streaming callback. */ + void *cb_context; /**< Context for stream callback. */ + size_t length; /**< Total data length. */ + } stream; + + /* Scatter/gather list */ + struct { + unsigned count; /**< Number of IOV entries. */ + struct sharp_data_iov *vector; /**< IOV entries. */ + } iov; + }; +}; + +/* + * @brief SHARP coll reduce collective specification + * + * This descriptor defines the input parameters for SHARP coll reduce operation + * + */ +struct sharp_coll_reduce_spec { + int root; /**< [in] root process id (ignored for allreduce) */ + struct sharp_coll_data_desc sbuf_desc; /**< [in] source data buffer desc */ + struct sharp_coll_data_desc rbuf_desc; /**< [out] destination data buffer desc */ + enum sharp_datatype dtype; /**< [in] data type @ref sharp_datatype */ + size_t length; /**< [in] reduce operation size */ + enum sharp_reduce_op op; /**< [in] reduce operator @ref sharp_reduce_op */ + enum sharp_datatype tag_dtype; /**< [in] Tag datatype for MIN-LOC/MAX-LOC op */ + enum sharp_aggregation_mode aggr_mode; /**< [in] Requested Aggregation mode @ref sharp_aggregation_mode */ + int stream_lock_batch_size; /**< [in] Acquire the lock and retain for next #ops. lock/#ops/unlock optimization*/ + int reserved[4]; /**< Reserved */ +}; + +/* + * @brief SHARP coll broadcast collective specification + * + * This descriptor defines the input paramaters for SHARP coll broadcast operation + * + */ +struct sharp_coll_bcast_spec { + int root; /**< [in] root process id */ + struct sharp_coll_data_desc buf_desc; /**< [in,out] buffer desc to send/recv bcast data */ + size_t size; /**< [in] bcast size */ + int reserved[4]; /**< Reserved */ +}; + +/** + * @brief SHARP coll context initialization + * + * This routine is initialize SHARP coll library and create @ref sharp_coll_context "SHARP coll context". + * This is a collective, called from all processes of the job. + * + * @warning An application cannot call any SHARP coll routine before sharp_coll_init + * + * @param [in] sharp_coll_spec SHARP coll specification descriptor. + * @param [out] sharp_coll_context Initialized @ref sharp_coll_context "SHARP coll context". + * + * @return Error code as defined by @ref sharp_error_no + */ +int sharp_coll_init(struct sharp_coll_init_spec *sharp_coll_spec, + struct sharp_coll_context **sharp_coll_context); + +/** + * @brief SHARP coll context finalize + * + * This routine finalizes and releases the resources associated with + * @ref sharp_coll_context "SHARP coll context". typically done once, just before the process ends. + * + * @warning An application cannot call any SHARP coll routine after sharp_coll_finalize + * + * @param [in] context SHARP coll context to cleanup. + * + * @return Error code as defined by @ref sharp_error_no + */ +int sharp_coll_finalize(struct sharp_coll_context *context); + +/** + * @brief SHARP caps initialization + * + * This routine is initialize SHARP capabilities description. + * + * @param [in] context SHARP coll context to query. + * @param [out] sharp_caps Initialized @ref sharp_caps "SHARP capabilities". + * + * @return Error code as defined by @ref sharp_error_no + */ +int sharp_coll_caps_query(struct sharp_coll_context *context, + struct sharp_coll_caps *sharp_caps); + +/** + * @brief Progress SHARP coll communication operations. + * + * This routine explicitly progresses all SHARP communication operation. + * For example, this typically called from MPI progress context for MPI case. + * + * @param [in] context SHARP coll context to progress. + * + * @return Error code as defined by @ref sharp_error_no + */ +int sharp_coll_progress(struct sharp_coll_context *context); + +/** + * @brief SHARP coll communicator(group) initialization + * + * This routine creates @ref sharp_coll_comm "SHARP coll group". + * This is a collective, called from all processes of the SHARP group. + * + * @param [in] context Handle to SHARP coll context. + * @param [in] spec Input @ref sharp_coll_comm_init_spec "SHARP coll group specification". + * @param [out] sharp_coll_comm Handle to SHARP coll communicator(group) + * + * @return Error code as defined by @ref sharp_error_no + */ +int sharp_coll_comm_init(struct sharp_coll_context *context, + struct sharp_coll_comm_init_spec *spec, + struct sharp_coll_comm **sharp_coll_comm); + +/** + * @brief SHARP coll communicator cleanup + * + * This routine cleanup SHARP coll communicator handle returned from @ref sharp_coll_comm_init. + * + * @param [in] comm SHARP coll communicator to destroy. + * + * @return Error code as defined by @ref sharp_error_no + */ +int sharp_coll_comm_destroy(struct sharp_coll_comm *comm); + +/** + * @brief SHARP coll barrier collective + * + * This routine is collective operation blocks until all processes call this routine . + * + * @param [in] comm SHARP coll communicator to run the barrier. + * + * @return Error code as defined by @ref sharp_error_no + */ +int sharp_coll_do_barrier(struct sharp_coll_comm *comm); + +/** + * @brief SHARP coll non-blocking barrier collective + * + * This routine is non blocking version of @ref sharp_coll_do_barrier "SHARP coll barrier". + * The progress of this operation is tracked with return request handle + * + * @param [in] comm SHARP coll communicator to run the barrier. + * @param [out] handle Handle representing the communication operation. + * + * @return Error code as defined by @ref sharp_error_no + * + */ +int sharp_coll_do_barrier_nb(struct sharp_coll_comm *comm, void **handle); + +/** + * @brief SHARP coll allreduce collective + * + * This routine aggregates the data from all processes of the group and + * distributes the result back to all processes. + * + * @param [in] comm SHARP coll communicator to run the allreduce collective. + * @param [in] spec Allreduce operation specification. + * + * @return Error code as defined by @ref sharp_error_no + */ +int sharp_coll_do_allreduce(struct sharp_coll_comm *comm, + struct sharp_coll_reduce_spec *spec); + +/** + * @brief SHARP coll non-blocking allreduce collective + * + * This routine is non blocking version of @ref sharp_coll_do_allreduce "SHARP coll allreduce". + * The progress of this operation is tracked with return request handle + * + * @param [in] comm SHARP coll communicator to run the allreduce collective. + * @param [in] spec Allreduce operation specification. + * @param [out] handle Handle representing the communication operation. + * + * @return Error code as defined by @ref sharp_error_no + * + */ +int sharp_coll_do_allreduce_nb(struct sharp_coll_comm *comm, + struct sharp_coll_reduce_spec *spec, void **handle); + +/** + * @brief SHARP coll reduce collective + * + * This routine aggregates the data from all processes of the group to a specific process + * + * @param [in] comm SHARP coll communicator to run the reduce collective. + * @param [in] spec Reduce operation specification. + * + * @return Error code as defined by @ref sharp_error_no + * + * @note Not implemented. + */ +int sharp_coll_do_reduce(struct sharp_coll_comm *comm, + struct sharp_coll_reduce_spec *spec); + +/** + * @brief SHARP coll non-blocking reduce collective + * + * This routine is non blocking version of @ref sharp_coll_do_reduce "SHARP coll Reduce". + * The progress of this operation is tracked with return request handle + * + * @param [in] comm SHARP coll communicator to run the reduce collective. + * @param [in] spec Allreduce operation specification. + * @param [out] handle Handle representing the communication operation. + * + * @return Error code as defined by @ref sharp_error_no + * + * @note Not implemented. + */ +int sharp_coll_do_reduce_nb(struct sharp_coll_comm *comm, + struct sharp_coll_reduce_spec *spec, + void **handle); +/** + * @brief SHARP coll broadcast collective + * + * This routine broadcast data from single process to all processes of the group + * + * @param [in] comm SHARP coll communicator to run the bcast collective. + * @param [in] spec Bcast operation specification. + * + * @return Error code as defined by @ref sharp_error_no + * + * @note Not implemented. + */ +int sharp_coll_do_bcast(struct sharp_coll_comm *comm, + struct sharp_coll_bcast_spec *spec); + +/** + * @brief SHARP coll non blocking broadcast collective + * + * This routine is non-blocking version of @ref sharp_coll_do_bcast "SHARP coll Bcast". + * The progress of this operation is tracked with return request handle + * + * @param [in] comm SHARP coll communicator to run the bcast collective. + * @param [in] spec Bcast operation specification. + * @param [out] handle Handle representing the communication operation. + * + * @return Error code as defined by @ref sharp_error_no + * + * @note Not implemented. + */ +int sharp_coll_do_bcast_nb(struct sharp_coll_comm *comm, + struct sharp_coll_bcast_spec *spec, + void **handle); + +/** + * @brief SHARP coll request test + * + * This routine tests for the completion of a specific non-blocking coll operation + * + * @param [in] req SHARP coll request handle + * + * @return Non-zero if request is complete, 0 otherwise + */ +int sharp_coll_req_test(void *handle); + +/** + * @brief SHARP coll request wait + * + * This routine returns when the operation identified by non-blocking collective request is complete. + * The request object is deallocated by the call to sharp_coll_req_wait and the request handle is set to NULL. + * + * @param [in] req SHARP coll request handle + * + * @return Error code as defined by @ref sharp_error_no + */ + +int sharp_coll_req_wait(void *handle); + +/** + * @brief SHARP coll request deallocate + * + * This routine deallocates request handle + * + * @param [in] req SHARP coll request handle + * + * @return Error code as defined by @ref sharp_error_no + */ +int sharp_coll_req_free(void *handle); + +/** + * @brief SHARP coll memory registration. + * + * This routine registers external mem buffer + * + * @param [in] context SHARP coll context to progress. + * @param [in] buf Buffer to register + * @param [in] size length of the buffer in bytes + * @param [out] mr memory registration handle. + * + * @return Error code as defined by @ref sharp_error_no + * + * @note Only one outstanding registration supported. no registration cache. + * + */ +int sharp_coll_reg_mr(struct sharp_coll_context *context, + void *buf, size_t size, void **mr); + +/** + * @brief SHARP coll memory de-registration. + * + * This routine de-registers the MR. + * + * @param [in] context SHARP coll context to progress. + * @param [in] mr memory registration handle. + * + * @return Error code as defined by @ref sharp_error_no + */ +int sharp_coll_dereg_mr(struct sharp_coll_context *context, void *mr); + +/** + * @brief SHARP coll print config flags + * + * The enumeration list describes bit masks for different options to print config flags + */ +enum config_print_flags { + SHARP_COLL_CONFIG_PRINT_CONFIG = 1, /**< basic configuration. */ + SHARP_COLL_CONFIG_PRINT_HEADER = 2, /**< Print header. */ + SHARP_COLL_CONFIG_PRINT_DOC = 4, /**< full description. */ + SHARP_COLL_CONFIG_PRINT_HIDDEN = 8 /**< hidden options. */ +}; + +/** + * @brief SHARP coll print configuration + * + * This routine prints SHARP coll configuration to a stream. + * + * @param [in] stream Output stream to print to. + * @param [in] print_flags Controls how the configuration is printed. + * + * @return Error code as defined by @ref sharp_error_no + */ + +int sharp_coll_print_config(FILE *stream, enum config_print_flags print_flags); + +/** + * @brief SHARP coll print error string + * + * This routine returns error string for a given @ref sharp_error_no "SHARP coll error code". + * + * @param [in] error SHARP coll error code. + * + * @return Error string + */ +const char *sharp_coll_strerror(int error); + +/** + * @brief SHARP coll print statistics + * + * This routine dumps SHARP coll usage statistics + * + * @param [in] context SHARP coll context to progress. + * + * @return Error code as defined by @ref sharp_error_no + * + * @note It is expected to Out-Of_Band collectives are operational valid to get + * accumulated stats dumps (SHARP_COLL_STATS_DUMP_MODE=2) during the finalize process. + * + */ +int sharp_coll_dump_stats(struct sharp_coll_context *context); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/prov/sharp/src/sharp.h b/prov/sharp/src/sharp.h index 53f7f2a15a0..99ebbbbc0c5 100644 --- a/prov/sharp/src/sharp.h +++ b/prov/sharp/src/sharp.h @@ -198,4 +198,50 @@ ssize_t sharp_peer_xfer_complete(struct fid_ep *ep, ssize_t sharp_peer_xfer_error(struct fid_ep *ep, struct fi_cq_err_entry *cqerr); + +int sharp_oob_bcast(void* context, void* buffer, int len, int root); + +int sharp_oob_barrier(void* context); + +int sharp_oob_gather(void * context, int root, void *sbuf, void *rbuf, int len); + +/* +int sharp_coll_init(struct sharp_coll_init_spec *sharp_coll_spec, + struct sharp_coll_context **sharp_coll_context); +*/ +ssize_t sharp_do_sharp_coll_init(struct sharp_domain *domain); + +/* +int sharp_coll_finalize(struct sharp_coll_context *context); +*/ +size_t sharp_do_sharp_coll_finalize(struct sharp_domain *domain); + +/* +int sharp_coll_comm_init(struct sharp_coll_context *context, + struct sharp_coll_comm_init_spec *spec, + struct sharp_coll_comm **sharp_coll_comm); +*/ +int sharp_do_coll_comm_init(struct sharp_mc *mc); + +/* +int sharp_coll_comm_destroy(struct sharp_coll_comm *comm); +*/ +size_t sharp_do_coll_comm_destroy(struct sharp_mc *mc); + +/* +int sharp_coll_do_barrier_nb(struct sharp_coll_comm *comm, void **handle); +*/ +size_t sharp_do_coll_do_barrier(struct sharp_mc *mc, uint64_t flags, + void *context, void **handle); + +/* +int sharp_coll_do_allreduce_nb(struct sharp_coll_comm *comm, + struct sharp_coll_reduce_spec *spec, + void **handle); +*/ +int sharp_do_coll_do_allreduce(struct sharp_mc *mc, const void *buf, + size_t count, void *desc, void *result, + void *result_desc, enum fi_datatype datatype, + enum fi_op op, uint64_t flags, void *context, + void **handle); #endif From 30079e015a3f92084190f2ec4657aec504ec4ee7 Mon Sep 17 00:00:00 2001 From: Lukasz Dorau Date: Fri, 16 Dec 2022 11:52:13 +0100 Subject: [PATCH 7/8] prov/sharp: Add mocks for sharp_coll_init and sharp_coll_finalize Add mocks for sharp_coll_init and sharp_coll_finalize. Signed-off-by: Lukasz Dorau --- prov/sharp/Makefile.include | 2 + prov/sharp/src/mocks/api/sharp_mocks.c | 89 ++++++++++++++++++++++++++ 2 files changed, 91 insertions(+) create mode 100644 prov/sharp/src/mocks/api/sharp_mocks.c diff --git a/prov/sharp/Makefile.include b/prov/sharp/Makefile.include index b8a9e3b3c02..2c1ed0128de 100644 --- a/prov/sharp/Makefile.include +++ b/prov/sharp/Makefile.include @@ -1,5 +1,7 @@ if HAVE_SHARP _sharp_files = \ + prov/sharp/src/mocks/api/sharp.h \ + prov/sharp/src/mocks/api/sharp_mocks.c \ include/ofi_sharp.h \ prov/sharp/src/sharp.h \ prov/sharp/src/sharp_attr.c \ diff --git a/prov/sharp/src/mocks/api/sharp_mocks.c b/prov/sharp/src/mocks/api/sharp_mocks.c new file mode 100644 index 00000000000..36d5cff1451 --- /dev/null +++ b/prov/sharp/src/mocks/api/sharp_mocks.c @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2022 Intel Corporation. All rights reserved. + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL) Version 2, available from the file + * COPYING in the main directory of this source tree, or the + * BSD license below: + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include +#include +#include + +#include "./sharp.h" + +/* mock of struct sharp_coll_context */ +struct sharp_coll_context { + struct sharp_coll_init_spec mock_content; +}; + +/** + * @brief SHARP coll context initialization + * + * This routine is initialize SHARP coll library and create @ref sharp_coll_context "SHARP coll context". + * This is a collective, called from all processes of the job. + * + * @warning An application cannot call any SHARP coll routine before sharp_coll_init + * + * @param [in] sharp_coll_spec SHARP coll specification descriptor. + * @param [out] sharp_coll_context Initialized @ref sharp_coll_context "SHARP coll context". + * + * @return Error code as defined by @ref sharp_error_no + */ +int sharp_coll_init(struct sharp_coll_init_spec *sharp_coll_spec, + struct sharp_coll_context **sharp_coll_context) +{ + struct sharp_coll_context *context; + context = calloc(1, sizeof(*context)); + if (!context) + return -FI_ENOMEM; + + memcpy(&context->mock_content, sharp_coll_spec, sizeof(context->mock_content)); + + *sharp_coll_context = context; + + return 0; +} + +/** + * @brief SHARP coll context finalize + * + * This routine finalizes and releases the resources associated with + * @ref sharp_coll_context "SHARP coll context". typically done once, just before the process ends. + * + * @warning An application cannot call any SHARP coll routine after sharp_coll_finalize + * + * @param [in] context SHARP coll context to cleanup. + * + * @return Error code as defined by @ref sharp_error_no + */ +int sharp_coll_finalize(struct sharp_coll_context *context) +{ + free(context); + + return 0; +} From 7770931af1066a0dc110cfbf08e8712e9fdf99c7 Mon Sep 17 00:00:00 2001 From: Lukasz Dorau Date: Wed, 21 Dec 2022 11:53:20 +0100 Subject: [PATCH 8/8] prov/sharp: sharp provider can be mocked In order to mock SHARP functions run: $ ./configure --enable-sharp=mocked or $ ./configure --enable-sharp=auto Running: $ ./configure --enable-sharp=yes make use of SHARP libraries instead of mocks. Signed-off-by: Lukasz Dorau --- config/fi_provider.m4 | 7 ++++++- include/ofi_prov.h | 3 +++ prov/sharp/Makefile.include | 10 ++++++++-- prov/sharp/configure.m4 | 9 +++++++++ 4 files changed, 26 insertions(+), 3 deletions(-) diff --git a/config/fi_provider.m4 b/config/fi_provider.m4 index eae2d8a39af..5f74a396940 100644 --- a/config/fi_provider.m4 +++ b/config/fi_provider.m4 @@ -85,10 +85,12 @@ dnl # Check the --enable-<$1> value $1_dl=0 + $1_mocked=0 AS_CASE([$enable_$1], [yes|no], [], [dl], [enable_$1=yes $1_dl=1], - [auto], [], + [mocked], [enable_$1=yes $1_mocked=1], + [auto], [$1_mocked=1], [dl:*], [FI_CHECK_PREFIX_DIR([${enable_$1:3}], [$1]) enable_$1=yes $1_dl=1], [FI_CHECK_PREFIX_DIR([$enable_$1], [$1]) @@ -130,6 +132,7 @@ dnl AC_DEFINE_UNQUOTED([HAVE_]m4_translit([$1], [a-z], [A-Z]), $$1_happy, [$1 provider is built]) AC_DEFINE_UNQUOTED([HAVE_]m4_translit([$1], [a-z], [A-Z])[_DL], $$1_dl, [$1 provider is built as DSO]) + AC_DEFINE_UNQUOTED([HAVE_]m4_translit([$1], [a-z], [A-Z])[_MOCKED], $$1_mocked, [$1 provider is mocked]) # Set AM conditionals for HAVE_ and HAVE__DL # as well as AC defines @@ -137,6 +140,8 @@ dnl [test $$1_happy -eq 1]) AM_CONDITIONAL([HAVE_]m4_translit([$1], [a-z], [A-Z])[_DL], [test $$1_dl -eq 1]) + AM_CONDITIONAL([HAVE_]m4_translit([$1], [a-z], [A-Z])[_MOCKED], + [test $$1_mocked -eq 1]) # If this provider was specifically requested but we can't # build it, error. diff --git a/include/ofi_prov.h b/include/ofi_prov.h index be949834163..6a324ae65e5 100644 --- a/include/ofi_prov.h +++ b/include/ofi_prov.h @@ -334,6 +334,9 @@ OPX_INI ; #define COLL_INIT fi_coll_ini() COLL_INI ; +#ifndef HAVE_SHARP +#define HAVE_SHARP 0 +#endif #if (HAVE_SHARP) && (HAVE_SHARP_DL) # define SHARP_INI FI_EXT_INI # define SHARP_INIT NULL diff --git a/prov/sharp/Makefile.include b/prov/sharp/Makefile.include index 2c1ed0128de..9edc811c4cf 100644 --- a/prov/sharp/Makefile.include +++ b/prov/sharp/Makefile.include @@ -1,7 +1,5 @@ if HAVE_SHARP _sharp_files = \ - prov/sharp/src/mocks/api/sharp.h \ - prov/sharp/src/mocks/api/sharp_mocks.c \ include/ofi_sharp.h \ prov/sharp/src/sharp.h \ prov/sharp/src/sharp_attr.c \ @@ -14,6 +12,14 @@ _sharp_files = \ prov/sharp/src/sharp_coll.c \ prov/sharp/src/sharp_progress.c +if HAVE_SHARP_MOCKED +_sharp_files += \ + prov/sharp/src/mocks/api/sharp.h \ + prov/sharp/src/mocks/api/sharp_mocks.c +else !HAVE_SHARP_MOCKED +sharp_LIBS = -lsharp -lsharp_coll +endif !HAVE_SHARP_MOCKED + if HAVE_SHARP_DL pkglib_LTLIBRARIES += libsharp-fi.la libsharp_fi_la_SOURCES = $(_sharp_files) $(common_srcs) diff --git a/prov/sharp/configure.m4 b/prov/sharp/configure.m4 index 539ba929d9d..5de0956cb9f 100644 --- a/prov/sharp/configure.m4 +++ b/prov/sharp/configure.m4 @@ -11,5 +11,14 @@ AC_DEFUN([FI_SHARP_CONFIGURE],[ # Determine if we can support the sharp provider sharp_happy=0 AS_IF([test x"$enable_sharp" != x"no"], [sharp_happy=1]) + + AS_IF([test $sharp_happy -eq 1 && test $sharp_mocked -eq 0], + [AC_CHECK_LIB(sharp_coll, sharp_coll_init, [], + AC_MSG_ERROR([The libsharp_coll library not found (set LDFLAGS to point the location)]), [])]) + + AS_IF([test $sharp_happy -eq 1 && test $sharp_mocked -eq 0], + [AC_CHECK_LIB(sharp, sharp_init_session, [], + AC_MSG_ERROR([The libsharp library not found (set LDFLAGS to point the location)]), [])]) + AS_IF([test $sharp_happy -eq 1], [$1], [$2]) ])