Skip to content

Commit

Permalink
Add rma_pingpong test
Browse files Browse the repository at this point in the history
Signed-off-by: Eric Raut <[email protected]>
  • Loading branch information
rauteric committed Nov 22, 2023
1 parent c9f6b45 commit 9d613d9
Show file tree
Hide file tree
Showing 8 changed files with 334 additions and 2 deletions.
6 changes: 6 additions & 0 deletions fabtests/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ bin_PROGRAMS = \
benchmarks/fi_rdm_cntr_pingpong \
benchmarks/fi_dgram_pingpong \
benchmarks/fi_rdm_pingpong \
benchmarks/fi_rma_pingpong \
benchmarks/fi_rdm_tagged_pingpong \
benchmarks/fi_rdm_tagged_bw \
unit/fi_eq_test \
Expand Down Expand Up @@ -401,6 +402,11 @@ benchmarks_fi_rdm_pingpong_SOURCES = \
$(benchmarks_srcs)
benchmarks_fi_rdm_pingpong_LDADD = libfabtests.la

benchmarks_fi_rma_pingpong_SOURCES = \
benchmarks/rma_pingpong.c \
$(benchmarks_srcs)
benchmarks_fi_rma_pingpong_LDADD = libfabtests.la

benchmarks_fi_rdm_tagged_pingpong_SOURCES = \
benchmarks/rdm_tagged_pingpong.c \
$(benchmarks_srcs)
Expand Down
4 changes: 3 additions & 1 deletion fabtests/Makefile.win
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ all: benchmarks functional unit multinode

benchmarks: $(outdir)\dgram_pingpong.exe $(outdir)\msg_bw.exe \
$(outdir)\msg_pingpong.exe $(outdir)\rdm_cntr_pingpong.exe \
$(outdir)\rdm_pingpong.exe $(outdir)\rdm_tagged_bw.exe \
$(outdir)\rdm_pingpong.exe $(outdir)\rma_pingpong.exe $(outdir)\rdm_tagged_bw.exe \
$(outdir)\rdm_tagged_pingpong.exe $(outdir)\rma_bw.exe

functional: $(outdir)\av_xfer.exe $(outdir)\bw.exe $(outdir)\cm_data.exe $(outdir)\cq_data.exe \
Expand Down Expand Up @@ -107,6 +107,8 @@ $(outdir)\rdm_cntr_pingpong.exe: {benchmarks}rdm_cntr_pingpong.c $(basedeps) {be

$(outdir)\rdm_pingpong.exe: {benchmarks}rdm_pingpong.c $(basedeps) {benchmarks}benchmark_shared.c

$(outdir)\rma_pingpong.exe: {benchmarks}rma_pingpong.c $(basedeps) {benchmarks}benchmark_shared.c

$(outdir)\rdm_tagged_bw.exe: {benchmarks}rdm_tagged_bw.c $(basedeps) {benchmarks}benchmark_shared.c

$(outdir)\rdm_tagged_pingpong.exe: {benchmarks}rdm_tagged_pingpong.c $(basedeps) {benchmarks}benchmark_shared.c
Expand Down
78 changes: 78 additions & 0 deletions fabtests/benchmarks/benchmark_shared.c
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,84 @@ int pingpong(void)
return 0;
}

int pingpong_rma(enum ft_rma_opcodes rma_op, struct fi_rma_iov *remote)
{
int ret, i, inject_size;

inject_size = inject_size_set ?
hints->tx_attr->inject_size : fi->tx_attr->inject_size;

if (ft_check_opts(FT_OPT_ENABLE_HMEM))
inject_size = 0;

/* for FT_OPT_VERIFY_DATA, we cannot use inject, as we require
* completions to indicate delivery has completed. */
if (ft_check_opts(FT_OPT_VERIFY_DATA))
inject_size = 0;

ret = ft_sync();
if (ret)
return ret;

if (opts.transfer_size == 0) {
FT_ERR("Zero-sized transfers not supported");
return EXIT_FAILURE;
}

/* Init rx_buf for test */
*(rx_buf + opts.transfer_size-1) = (char)-1;

if (opts.dst_addr) {
for (i = 0; i < opts.iterations + opts.warmup_iterations; i++) {

if (i == opts.warmup_iterations)
ft_start();

/* Init tx_buf for test */
*(tx_buf + opts.transfer_size-1) = (char)i;

if (opts.transfer_size <= inject_size)
ret = ft_inject_rma(rma_op, remote, ep, remote_fi_addr, opts.transfer_size);
else
ret = ft_tx_rma(rma_op, remote, ep, remote_fi_addr, opts.transfer_size, &tx_ctx);
if (ret)
return ret;

ret = ft_rx_rma(i, rma_op, ep, opts.transfer_size);
if (ret)
return ret;
}
} else {
for (i = 0; i < opts.iterations + opts.warmup_iterations; i++) {
if (i == opts.warmup_iterations)
ft_start();

ret = ft_rx_rma(i, rma_op, ep, opts.transfer_size);
if (ret)
return ret;

/* Init tx_buf for test */
*(tx_buf + opts.transfer_size-1) = (char)i;

if (opts.transfer_size <= inject_size)
ret = ft_inject_rma(rma_op, remote, ep, remote_fi_addr, opts.transfer_size);
else
ret = ft_tx_rma(rma_op, remote, ep, remote_fi_addr, opts.transfer_size, &tx_ctx);
if (ret)
return ret;
}
}
ft_stop();

if (opts.machr)
show_perf_mr(opts.transfer_size, opts.iterations, &start, &end, 2,
opts.argc, opts.argv);
else
show_perf(NULL, opts.transfer_size, opts.iterations, &start, &end, 2);

return 0;
}

static int bw_tx_comp()
{
int ret;
Expand Down
1 change: 1 addition & 0 deletions fabtests/benchmarks/benchmark_shared.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ void ft_parse_benchmark_opts(int op, char *optarg);
void ft_benchmark_usage(void);
int pingpong(void);
int bandwidth(void);
int pingpong_rma(enum ft_rma_opcodes rma_op, struct fi_rma_iov *remote);
int bandwidth_rma(enum ft_rma_opcodes op, struct fi_rma_iov *remote);

#ifdef __cplusplus
Expand Down
137 changes: 137 additions & 0 deletions fabtests/benchmarks/rma_pingpong.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
/*
* Copyright (c) 2013-2016 Intel Corporation. All rights reserved.
*
* This software is available to you under 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 <stdio.h>
#include <stdlib.h>
#include <getopt.h>

#include <rdma/fi_errno.h>

#include <shared.h>
#include "benchmark_shared.h"

static int run(void)
{
int i, ret;

ret = ft_init_fabric();

if (ret)
return ret;

ret = ft_exchange_keys(&remote);
if (ret)
return ret;

if (!(opts.options & FT_OPT_SIZE)) {
for (i = 0; i < TEST_CNT; i++) {
if (!ft_use_size(i, opts.sizes_enabled))
continue;
opts.transfer_size = test_size[i].size;
init_test(&opts, test_name, sizeof(test_name));
ret = pingpong_rma(opts.rma_op, &remote);
if (ret)
goto out;
}
} else {
init_test(&opts, test_name, sizeof(test_name));
ret = pingpong_rma(opts.rma_op, &remote);
if (ret)
goto out;
}

ft_finalize();
out:
return ret;
}

int main(int argc, char **argv)
{
int op, ret;

opts = INIT_OPTS;

hints = fi_allocinfo();
if (!hints)
return EXIT_FAILURE;

hints->caps = FI_MSG | FI_RMA | FI_WRITE | FI_REMOTE_WRITE;
hints->domain_attr->resource_mgmt = FI_RM_ENABLED;
hints->mode = FI_CONTEXT;
hints->domain_attr->threading = FI_THREAD_DOMAIN;
hints->addr_format = opts.address_format;

while ((op = getopt_long(argc, argv, "Uh" CS_OPTS INFO_OPTS API_OPTS
BENCHMARK_OPTS, long_opts, &lopt_idx)) != -1) {
switch (op) {
default:
if (!ft_parse_long_opts(op, optarg))
continue;
ft_parse_benchmark_opts(op, optarg);
ft_parseinfo(op, optarg, hints, &opts);
ft_parsecsopts(op, optarg, &opts);
ret = ft_parse_api_opts(op, optarg, hints, &opts);
if (ret)
return ret;
break;
case 'U':
hints->tx_attr->op_flags |= FI_DELIVERY_COMPLETE;
break;
case '?':
case 'h':
ft_csusage(argv[0], "Pingpong test using RMA operations.");
ft_benchmark_usage();
FT_PRINT_OPTS_USAGE("-o <op>", "rma op type: write|writedata (default: write)\n");
ft_longopts_usage();
return EXIT_FAILURE;
}
}

/* We only support write and writedata verbs */
if (opts.rma_op != FT_RMA_WRITE && opts.rma_op != FT_RMA_WRITEDATA) {
FT_ERR("Only write and writedata verbs are supported by rma_pingpong");
return EXIT_FAILURE;
}

/* data validation on read and write ops requires delivery_complete semantics. */
if (opts.rma_op != FT_RMA_WRITEDATA && ft_check_opts(FT_OPT_VERIFY_DATA))
hints->tx_attr->op_flags |= FI_DELIVERY_COMPLETE;

if (optind < argc)
opts.dst_addr = argv[optind];

hints->ep_attr->type = FI_EP_RDM;
hints->domain_attr->mr_mode = opts.mr_mode;
hints->tx_attr->tclass = FI_TC_LOW_LATENCY;

ret = run();

ft_free_res();
return -ret;
}
102 changes: 102 additions & 0 deletions fabtests/common/shared.c
Original file line number Diff line number Diff line change
Expand Up @@ -2170,6 +2170,25 @@ ssize_t ft_tx(struct fid_ep *ep, fi_addr_t fi_addr, size_t size, void *ctx)
return ret;
}

ssize_t ft_tx_rma(enum ft_rma_opcodes rma_op, struct fi_rma_iov *remote, struct fid_ep *ep, fi_addr_t fi_addr, size_t size, void *ctx)
{
ssize_t ret;

if (ft_check_opts(FT_OPT_VERIFY_DATA | FT_OPT_ACTIVE)) {
/* Fill data. Last byte reserved for iteration number */
ret = ft_fill_buf((char *) tx_buf, size-1);
if (ret)
return ret;
}

ret = ft_post_rma(rma_op, tx_buf, size, remote, ctx);
if (ret)
return ret;

ret = ft_get_tx_comp(tx_seq);
return ret;
}

ssize_t ft_post_inject_buf(struct fid_ep *ep, fi_addr_t fi_addr, size_t size,
void *op_buf, uint64_t op_tag)
{
Expand Down Expand Up @@ -2209,6 +2228,24 @@ ssize_t ft_inject(struct fid_ep *ep, fi_addr_t fi_addr, size_t size)
return ret;
}

ssize_t ft_inject_rma(enum ft_rma_opcodes rma_op, struct fi_rma_iov *remote, struct fid_ep *ep, fi_addr_t fi_addr, size_t size)
{
ssize_t ret;

if (ft_check_opts(FT_OPT_VERIFY_DATA | FT_OPT_ACTIVE)) {
/* Fill data. Last byte reserved for iteration number */
ret = ft_fill_buf((char *) tx_buf, size-1);
if (ret)
return ret;
}

ret = ft_post_rma_inject(rma_op, tx_buf, size, remote);
if (ret)
return ret;

return ret;
}

static size_t ft_remote_write_offset(const char *buf)
{
assert(buf >= tx_buf && buf < (tx_buf + tx_buf_size));
Expand Down Expand Up @@ -2423,6 +2460,49 @@ ssize_t ft_rx(struct fid_ep *ep, size_t size)
return ret;
}

ssize_t ft_rx_rma(int iter, enum ft_rma_opcodes rma_op, struct fid_ep *ep, size_t size)
{
ssize_t ret;

switch (rma_op) {
case FT_RMA_WRITE:
/* In this case, there will be no completion on the remote side. Instead, poll the recv buff. */
ret = ft_rma_poll_buf(rx_buf, iter, size);
if (ret)
return ret;
break;
case FT_RMA_WRITEDATA:
/* In this case, a completion will be generated on the remote side, so wait for it. */
ret = ft_get_rx_comp(rx_seq);
if (ret)
return ret;
break;
default:
FT_ERR("Unsupported RMA op type");
return EXIT_FAILURE;
}

if (ft_check_opts(FT_OPT_VERIFY_DATA | FT_OPT_ACTIVE)) {
ret = ft_check_buf((char *) rx_buf, size-1);
if (ret)
return ret;
}

/* TODO: verify CQ data, if available */

if (rma_op == FT_RMA_WRITEDATA) {
if (fi->rx_attr->mode & FI_RX_CQ_DATA) {
/* In this mode, the next RDMA write op will consume a receive, so post one here. */
ret = ft_post_rx(ep, 0, &rx_ctx);
} else {
/* Just increment seq counter */
rx_seq++;
}
}

return ret;
}

/*
* Received messages match tagged buffers in order, but the completions can be
* reported out of order. A tag is valid if it's within the current window.
Expand Down Expand Up @@ -3565,6 +3645,28 @@ int ft_check_buf(void *buf, size_t size)
return ret;
}

int ft_rma_poll_buf(void *buf, int iter, size_t size)
{
volatile char *recv_data;

if (opts.iface != FI_HMEM_SYSTEM) {
/* Not supported */
FT_ERR("FI_HMEM not supported for writedata latency test");
return EXIT_FAILURE;
} else {
recv_data = (char *)buf + size - 1;
}

char expected_val = (char)iter;
while (*recv_data != expected_val) {
/* Although not expecting a completion, we must process the completion queue
* to make progress */
ft_force_progress();
}

return 0;
}

uint64_t ft_init_cq_data(struct fi_info *info)
{
if (info->domain_attr->cq_data_size >= sizeof(uint64_t)) {
Expand Down
Loading

0 comments on commit 9d613d9

Please sign in to comment.