#ifndef _FI_H_
#define _FI_H_
#include "config.h"
#include <assert.h>
#include <pthread.h>
#include <stdlib.h>
#include <string.h>
#include <sys/param.h>
#include <netinet/in.h>
#include <fi_abi.h>
#include <fi_file.h>
#include <fi_lock.h>
#include <fi_atom.h>
#include <fi_mem.h>
#include <rdma/providers/fi_prov.h>
#include <rdma/providers/fi_log.h>
#include <rdma/fabric.h>
#include <rdma/fi_atomic.h>
#include <fi_osd.h>
#ifdef __cplusplus
extern "C" {
#endif
#define OFI_CORE_PROV_ONLY (1ULL << 59)
#if !defined(BYTE_ORDER)
# if defined(__BYTE_ORDER) && \
defined(__LITTLE_ENDIAN) && \
defined(__BIG_ENDIAN)
# define BYTE_ORDER __BYTE_ORDER
# define LITTLE_ENDIAN __LITTLE_ENDIAN
# define BIG_ENDIAN __BIG_ENDIAN
# else
# error "cannot determine endianness!"
# endif
#endif
#if BYTE_ORDER == LITTLE_ENDIAN
#ifndef htonll
static inline uint64_t htonll(uint64_t x) { return bswap_64(x); }
#endif
#ifndef ntohll
static inline uint64_t ntohll(uint64_t x) { return bswap_64(x); }
#endif
#else
#ifndef htonll
static inline uint64_t htonll(uint64_t x) { return x; }
#endif
#ifndef ntohll
static inline uint64_t ntohll(uint64_t x) { return x; }
#endif
#endif
#define sizeof_field(type, field) sizeof(((type *)0)->field)
#ifndef MIN
#define MIN(a, b) \
({ typeof (a) _a = (a); \
typeof (b) _b = (b); \
_a < _b ? _a : _b; })
#endif
#ifndef MAX
#define MAX(a, b) \
({ typeof (a) _a = (a); \
typeof (b) _b = (b); \
_a > _b ? _a : _b; })
#endif
struct fi_prov_context {
int disable_logging;
int is_util_prov;
};
struct fi_filter {
char **names;
int negated;
};
extern struct fi_filter prov_log_filter;
extern struct fi_provider core_prov;
int ofi_is_util_prov(struct fi_provider *provider);
void ofi_create_filter(struct fi_filter *filter, const char *env_name);
void ofi_free_filter(struct fi_filter *filter);
int ofi_apply_filter(struct fi_filter *filter, const char *name);
void fi_util_init(void);
void fi_util_fini(void);
void fi_log_init(void);
void fi_log_fini(void);
void fi_param_init(void);
void fi_param_fini(void);
void fi_param_undefine(const struct fi_provider *provider);
const char *ofi_hex_str(const uint8_t *data, size_t len);
static inline uint64_t roundup_power_of_two(uint64_t n)
{
if (!n || !(n & (n - 1)))
return n;
n--;
n |= n >> 1;
n |= n >> 2;
n |= n >> 4;
n |= n >> 8;
n |= n >> 16;
n |= n >> 32;
n++;
return n;
}
static inline size_t fi_get_aligned_sz(size_t size, size_t alignment)
{
return ((size % alignment) == 0) ?
size : ((size / alignment) + 1) * alignment;
}
#define FI_TAG_GENERIC 0xAAAAAAAAAAAAAAAAULL
size_t fi_datatype_size(enum fi_datatype datatype);
uint64_t fi_tag_bits(uint64_t mem_tag_format);
uint64_t fi_tag_format(uint64_t tag_bits);
int fi_size_bits(uint64_t num);
int ofi_send_allowed(uint64_t caps);
int ofi_recv_allowed(uint64_t caps);
int ofi_rma_initiate_allowed(uint64_t caps);
int ofi_rma_target_allowed(uint64_t caps);
int ofi_ep_bind_valid(struct fi_provider *prov, struct fid *bfid, uint64_t flags);
uint64_t fi_gettime_ms(void);
uint64_t fi_gettime_us(void);
#ifndef AF_IB
#define AF_IB 27
#endif
static inline size_t ofi_sizeofaddr(struct sockaddr *address)
{
return (address->sa_family == AF_INET ?
sizeof(struct sockaddr_in) :
sizeof(struct sockaddr_in6));
}
static inline int ofi_equals_ipaddr(struct sockaddr_in *addr1,
struct sockaddr_in *addr2)
{
return (addr1->sin_addr.s_addr == addr2->sin_addr.s_addr);
}
static inline int ofi_equals_sockaddr(struct sockaddr_in *addr1,
struct sockaddr_in *addr2)
{
return (ofi_equals_ipaddr(addr1, addr2) &&
(addr1->sin_port == addr2->sin_port));
}
static inline int ofi_translate_addr_format(int family)
{
switch (family) {
case AF_INET:
return FI_SOCKADDR_IN;
case AF_INET6:
return FI_SOCKADDR_IN6;
case AF_IB:
return FI_SOCKADDR_IB;
default:
return FI_FORMAT_UNSPEC;
}
}
struct ofi_key_idx {
uint64_t seq_no;
uint8_t idx_bits;
};
static inline void ofi_key_idx_init(struct ofi_key_idx *key_idx, uint8_t idx_bits)
{
key_idx->seq_no = 0;
key_idx->idx_bits = idx_bits;
}
static inline uint64_t ofi_idx2key(struct ofi_key_idx *key_idx, uint64_t idx)
{
return ((++(key_idx->seq_no)) << key_idx->idx_bits) | idx;
}
static inline uint64_t ofi_key2idx(struct ofi_key_idx *key_idx, uint64_t key)
{
return key & ((1ULL << key_idx->idx_bits) - 1);
}
#ifdef __cplusplus
}
#endif
#endif